]> granicus.if.org Git - clang/commitdiff
Add a ParseAST overload that takes a Sema object, so that the caller
authorDouglas Gregor <dgregor@apple.com>
Thu, 12 Aug 2010 22:51:45 +0000 (22:51 +0000)
committerDouglas Gregor <dgregor@apple.com>
Thu, 12 Aug 2010 22:51:45 +0000 (22:51 +0000)
can create (and hold on to) the Sema object. Also, move Sema-related
initialization/finalization with its various consumers and external
sources into the Sema constructor and destructor, rather than placing
it in ParseAST.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@110973 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Sema/ParseAST.h
include/clang/Sema/Sema.h
lib/Sema/ParseAST.cpp
lib/Sema/Sema.cpp

index f6cff2a023e63392781e273ddf54f32298da5485..57d7d0637f4f6405a6b769ff0bf229d7ea516447 100644 (file)
@@ -38,6 +38,10 @@ namespace clang {
                 bool CompleteTranslationUnit = true,
                 CodeCompleteConsumer *CompletionConsumer = 0);
 
+  /// \brief Parse the main file known to the preprocessor, producing an 
+  /// abstract syntax tree.
+  void ParseAST(Sema &S, bool PrintStats = false);
+  
 }  // end namespace clang
 
 #endif
index f3d15657a17ecf7f856482f330ba88995265bd5e..c2a1ea7b1eaf43e8b8260886862aaa0aa84d12fa 100644 (file)
@@ -635,12 +635,19 @@ public:
        bool CompleteTranslationUnit = true,
        CodeCompleteConsumer *CompletionConsumer = 0);
   ~Sema();
-
+  
+  /// \brief Perform initialization that occurs after the parser has been
+  /// initialized but before it parses anything.
+  void Initialize();
+  
   const LangOptions &getLangOptions() const { return LangOpts; }
   Diagnostic &getDiagnostics() const { return Diags; }
   SourceManager &getSourceManager() const { return SourceMgr; }
   const TargetAttributesSema &getTargetAttributesSema() const;
-
+  Preprocessor &getPreprocessor() const { return PP; }
+  ASTContext &getASTContext() const { return Context; }
+  ASTConsumer &getASTConsumer() const { return Consumer; }
+  
   /// \brief Helper class that creates diagnostics with optional
   /// template instantiation stacks.
   ///
index 4286b3f7c4ddb7a1fc98a3775fac29e4a896298b..8f2f097ec55e4e246cd188de356c12c67a55793c 100644 (file)
@@ -56,34 +56,29 @@ void clang::ParseAST(Preprocessor &PP, ASTConsumer *Consumer,
                      ASTContext &Ctx, bool PrintStats,
                      bool CompleteTranslationUnit,
                      CodeCompleteConsumer *CompletionConsumer) {
+  Sema S(PP, Ctx, *Consumer, CompleteTranslationUnit, CompletionConsumer);
+  ParseAST(S, PrintStats);
+}
+
+void clang::ParseAST(Sema &S, bool PrintStats) {
   // Collect global stats on Decls/Stmts (until we have a module streamer).
   if (PrintStats) {
     Decl::CollectingStats(true);
     Stmt::CollectingStats(true);
   }
 
-  Sema S(PP, Ctx, *Consumer, CompleteTranslationUnit, CompletionConsumer);
-  Parser P(PP, S);
-  PP.EnterMainSourceFile();
+  ASTConsumer *Consumer = &S.getASTConsumer();
 
-  // Initialize the parser.
+  Parser P(S.getPreprocessor(), S);
+  S.getPreprocessor().EnterMainSourceFile();
   P.Initialize();
-
-  Consumer->Initialize(Ctx);
-
-  if (SemaConsumer *SC = dyn_cast<SemaConsumer>(Consumer))
-    SC->InitializeSema(S);
-
-  if (ExternalASTSource *External = Ctx.getExternalSource()) {
-    if (ExternalSemaSource *ExternalSema =
-          dyn_cast<ExternalSemaSource>(External))
-      ExternalSema->InitializeSema(S);
-
+  S.Initialize();
+  
+  if (ExternalASTSource *External = S.getASTContext().getExternalSource())
     External->StartTranslationUnit(Consumer);
-  }
-
+  
   Parser::DeclGroupPtrTy ADecl;
-
+  
   while (!P.ParseTopLevelDecl(ADecl)) {  // Not end of file.
     // If we got a null return and something *was* parsed, ignore it.  This
     // is due to a top-level semicolon, an action override, or a parse error
@@ -94,30 +89,23 @@ void clang::ParseAST(Preprocessor &PP, ASTConsumer *Consumer,
   // Check for any pending objective-c implementation decl.
   while ((ADecl = P.FinishPendingObjCActions()))
     Consumer->HandleTopLevelDecl(ADecl.getAsVal<DeclGroupRef>());
-
+  
   // Process any TopLevelDecls generated by #pragma weak.
   for (llvm::SmallVector<Decl*,2>::iterator
-        I = S.WeakTopLevelDecls().begin(),
-        E = S.WeakTopLevelDecls().end(); I != E; ++I)
+       I = S.WeakTopLevelDecls().begin(),
+       E = S.WeakTopLevelDecls().end(); I != E; ++I)
     Consumer->HandleTopLevelDecl(DeclGroupRef(*I));
-
+  
   // Dump record layouts, if requested.
-  if (PP.getLangOptions().DumpRecordLayouts)
-    DumpRecordLayouts(Ctx);
-
-  Consumer->HandleTranslationUnit(Ctx);
-
-  if (ExternalSemaSource *ESS =
-        dyn_cast_or_null<ExternalSemaSource>(Ctx.getExternalSource()))
-    ESS->ForgetSema();
-
-  if (SemaConsumer *SC = dyn_cast<SemaConsumer>(Consumer))
-    SC->ForgetSema();
-
+  if (S.getLangOptions().DumpRecordLayouts)
+    DumpRecordLayouts(S.getASTContext());
+  
+  Consumer->HandleTranslationUnit(S.getASTContext());
+  
   if (PrintStats) {
     fprintf(stderr, "\nSTATISTICS:\n");
     P.getActions().PrintStats();
-    Ctx.PrintStats();
+    S.getASTContext().PrintStats();
     Decl::PrintStats();
     Stmt::PrintStats();
     Consumer->PrintStats();
index e7f5bb4317f1c445c0227e0316f9673aead55fd8..0d05b57b8d7ceaf610acdc3a2e73b61a2d09a3e1 100644 (file)
@@ -18,7 +18,7 @@
 #include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/APFloat.h"
 #include "clang/Sema/ExternalSemaSource.h"
-#include "clang/AST/ASTConsumer.h"
+#include "clang/Sema/SemaConsumer.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/ASTDiagnostic.h"
 #include "clang/AST/DeclObjC.h"
@@ -116,7 +116,7 @@ void Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) {
     PushOnScopeChains(ClassTypedef, TUScope);
     Context.setObjCClassType(Context.getTypeDeclType(ClassTypedef));
     Context.ObjCClassRedefinitionType = Context.getObjCClassType();
-  }
+  }  
 }
 
 Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
@@ -142,7 +142,21 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
                                        &Context);
 
   ExprEvalContexts.push_back(
-                  ExpressionEvaluationContextRecord(PotentiallyEvaluated, 0));
+                  ExpressionEvaluationContextRecord(PotentiallyEvaluated, 0));  
+}
+
+void Sema::Initialize() {
+  // Tell the AST consumer about this Sema object.
+  Consumer.Initialize(Context);
+  
+  // FIXME: Isn't this redundant with the initialization above?
+  if (SemaConsumer *SC = dyn_cast<SemaConsumer>(&Consumer))
+    SC->InitializeSema(*this);
+  
+  // Tell the external Sema source about this Sema object.
+  if (ExternalSemaSource *ExternalSema
+      = dyn_cast_or_null<ExternalSemaSource>(Context.getExternalSource()))
+    ExternalSema->InitializeSema(*this);
 }
 
 Sema::~Sema() {
@@ -151,6 +165,15 @@ Sema::~Sema() {
   delete TheTargetAttributesSema;
   while (!FunctionScopes.empty())
     PopFunctionOrBlockScope();
+  
+  // Tell the SemaConsumer to forget about us; we're going out of scope.
+  if (SemaConsumer *SC = dyn_cast<SemaConsumer>(&Consumer))
+    SC->ForgetSema();
+
+  // Detach from the external Sema source.
+  if (ExternalSemaSource *ExternalSema
+      = dyn_cast_or_null<ExternalSemaSource>(Context.getExternalSource()))
+    ExternalSema->ForgetSema();
 }
 
 /// ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast.