Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
ClingRAII.h
Go to the documentation of this file.
1 // @(#)root/core/meta:$Id$
2 // Author: Axel Naumann November 2016
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2012, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 #include "clang/Sema/Sema.h"
13 #include "cling/Utils/ParserStateRAII.h"
14 #include "clang/Lex/Preprocessor.h"
15 
16 
17 namespace ROOT {
18  namespace Internal {
19 
20  ////////////////////////////////////////////////////////////////////////////////
21  /// RAII used to store Parser, Sema, Preprocessor state for recursive parsing.
22  struct ParsingStateRAII {
23  struct SemaExprCleanupsRAII {
24  decltype(clang::Sema::Cleanup) fCleanup;
25  decltype(clang::Sema::ExprCleanupObjects) fExprCleanupObjects;
26  decltype(clang::Sema::MaybeODRUseExprs) fMaybeODRUseExprs;
27  decltype(clang::Sema::FunctionScopes) fFunctionScopes;
28  decltype(clang::Sema::UndefinedButUsed) fUndefinedButUsed;
29  clang::Sema& fSema;
30  void Swapem() {
31  std::swap(fCleanup, fSema.Cleanup);
32  std::swap(fExprCleanupObjects, fSema.ExprCleanupObjects);
33  std::swap(fMaybeODRUseExprs, fSema.MaybeODRUseExprs);
34  std::swap(fFunctionScopes, fSema.FunctionScopes);
35  std::swap(fUndefinedButUsed, fSema.UndefinedButUsed);
36  }
37  SemaExprCleanupsRAII(clang::Sema& S): fSema(S) {
38  fFunctionScopes.push_back(new clang::sema::FunctionScopeInfo(S.Diags));
39  Swapem();
40  };
41  ~SemaExprCleanupsRAII() {
42  Swapem();
43  assert(fFunctionScopes.size() == 1 && "Expected only my FunctionScopeInfo.");
44  delete fFunctionScopes.back();
45  }
46  };
47 
48  struct SemaParsingInitForAutoVarsRAII {
49  using PIFAV_t = decltype(clang::Sema::ParsingInitForAutoVars);
50  PIFAV_t& fSemaPIFAV;
51  PIFAV_t fSavedPIFAV;
52  SemaParsingInitForAutoVarsRAII(PIFAV_t& PIFAV): fSemaPIFAV(PIFAV) {
53  fSavedPIFAV.swap(PIFAV);
54  }
55  ~SemaParsingInitForAutoVarsRAII() {
56  fSavedPIFAV.swap(fSemaPIFAV);
57  }
58  };
59 
60  clang::Preprocessor::CleanupAndRestoreCacheRAII fCleanupRAII;
61  clang::Parser::ParserCurTokRestoreRAII fSavedCurToken;
62  cling::ParserStateRAII fParserRAII;
63 
64  // Buffer the delayed infos when doing recursive parsing.
65  clang::Sema::DelayedInfoRAII fSemaInfoRAII;
66 
67  SemaExprCleanupsRAII fSemaExprCleanupsRAII;
68 
69  // We can't PushDeclContext, because we go up and the routine that pops
70  // the DeclContext assumes that we drill down always.
71  // We have to be on the global context. At that point we are in a
72  // wrapper function so the parent context must be the global.
73  clang::Sema::ContextAndScopeRAII fPushedDCAndS;
74 
75  SemaParsingInitForAutoVarsRAII fSemaParsingInitForAutoVarsRAII;
76 
77  clang::Sema::SavePendingInstantiationsRAII fPendingInstantiations;
78 
79 
80  ParsingStateRAII(clang::Parser& parser, clang::Sema& sema):
81  fCleanupRAII(sema.getPreprocessor()),
82  fSavedCurToken(parser),
83  fParserRAII(parser, false /*skipToEOF*/),
84  fSemaInfoRAII(sema), fSemaExprCleanupsRAII(sema),
85  fPushedDCAndS(sema, sema.getASTContext().getTranslationUnitDecl(),
86  sema.TUScope),
87  fSemaParsingInitForAutoVarsRAII(sema.ParsingInitForAutoVars),
88  fPendingInstantiations(sema)
89  {
90  // After we have saved the token reset the current one to something which
91  // is safe (semi colon usually means empty decl)
92  clang::Token& Tok = const_cast<clang::Token&>(parser.getCurToken());
93  Tok.setKind(clang::tok::semi);
94  }
95  };
96 
97 }
98 }