diff options
-rw-r--r-- | include/clang/Frontend/ASTUnit.h | 17 | ||||
-rw-r--r-- | lib/Frontend/ASTMerge.cpp | 6 | ||||
-rw-r--r-- | lib/Frontend/ASTUnit.cpp | 17 | ||||
-rw-r--r-- | lib/Frontend/PCHReader.cpp | 20 | ||||
-rw-r--r-- | lib/Sema/Sema.cpp | 2 |
5 files changed, 49 insertions, 13 deletions
diff --git a/include/clang/Frontend/ASTUnit.h b/include/clang/Frontend/ASTUnit.h index 6651743302..d4a351c6b0 100644 --- a/include/clang/Frontend/ASTUnit.h +++ b/include/clang/Frontend/ASTUnit.h @@ -16,6 +16,7 @@ #include "clang/Index/ASTLocation.h" #include "clang/Frontend/PCHBitCodes.h" +#include "clang/Sema/Sema.h" #include "clang/Lex/PreprocessingRecord.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/FileManager.h" @@ -66,10 +67,18 @@ private: llvm::OwningPtr<Preprocessor> PP; llvm::OwningPtr<ASTContext> Ctx; + /// \brief The AST consumer that received information about the translation + /// unit as it was parsed or loaded. + llvm::OwningPtr<ASTConsumer> Consumer; + + /// \brief The semantic analysis object used to type-check the translation + /// unit. + llvm::OwningPtr<Sema> TheSema; + /// Optional owned invocation, just used to make the invocation used in /// LoadFromCommandLine available. llvm::OwningPtr<CompilerInvocation> Invocation; - + // OnlyLocalDecls - when true, walking this AST should only visit declarations // that come from the AST itself, not from included precompiled headers. // FIXME: This is temporary; eventually, CIndex will always do this. @@ -245,6 +254,12 @@ public: const ASTContext &getASTContext() const { return *Ctx.get(); } ASTContext &getASTContext() { return *Ctx.get(); } + bool hasSema() const { return TheSema; } + Sema &getSema() const { + assert(TheSema && "ASTUnit does not have a Sema object!"); + return *TheSema; + } + const FileManager &getFileManager() const { return *FileMgr; } FileManager &getFileManager() { return *FileMgr; } diff --git a/lib/Frontend/ASTMerge.cpp b/lib/Frontend/ASTMerge.cpp index e916e20065..cbaa6a3034 100644 --- a/lib/Frontend/ASTMerge.cpp +++ b/lib/Frontend/ASTMerge.cpp @@ -44,6 +44,12 @@ void ASTMergeAction::ExecuteAction() { if (!Unit) continue; + // Reset the argument -> string function so that it has the AST + // context we want, since the Sema object created by + // LoadFromPCHFile will override it. + CI.getDiagnostics().SetArgToStringFn(&FormatASTNodeDiagnosticArgument, + &CI.getASTContext()); + ASTImporter Importer(CI.getDiagnostics(), CI.getASTContext(), CI.getFileManager(), diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp index bbe2ec5bea..b56a0d83a8 100644 --- a/lib/Frontend/ASTUnit.cpp +++ b/lib/Frontend/ASTUnit.cpp @@ -204,7 +204,7 @@ ASTUnit *ASTUnit::LoadFromPCHFile(const std::string &Filename, AST->FileMgr.reset(new FileManager); AST->SourceMgr.reset(new SourceManager(AST->getDiagnostics())); AST->HeaderInfo.reset(new HeaderSearch(AST->getFileManager())); - + // If requested, capture diagnostics in the ASTUnit. CaptureDroppedDiagnostics Capture(CaptureDiagnostics, AST->getDiagnostics(), AST->StoredDiagnostics); @@ -237,7 +237,6 @@ ASTUnit *ASTUnit::LoadFromPCHFile(const std::string &Filename, unsigned Counter; llvm::OwningPtr<PCHReader> Reader; - llvm::OwningPtr<ExternalASTSource> Source; Reader.reset(new PCHReader(AST->getSourceManager(), AST->getFileManager(), AST->getDiagnostics())); @@ -294,9 +293,18 @@ ASTUnit *ASTUnit::LoadFromPCHFile(const std::string &Filename, // Attach the PCH reader to the AST context as an external AST // source, so that declarations will be deserialized from the // PCH file as needed. - Source.reset(Reader.take()); + PCHReader *ReaderPtr = Reader.get(); + llvm::OwningPtr<ExternalASTSource> Source(Reader.take()); Context.setExternalSource(Source); + // Create an AST consumer, even though it isn't used. + AST->Consumer.reset(new ASTConsumer); + + // Create a semantic analysis object and tell the PCH reader about it. + AST->TheSema.reset(new Sema(PP, Context, *AST->Consumer)); + AST->TheSema->Initialize(); + ReaderPtr->InitializeSema(*AST->TheSema); + return AST.take(); } @@ -458,6 +466,7 @@ bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) { // FIXME: Should we retain the previous file manager? FileMgr.reset(new FileManager); SourceMgr.reset(new SourceManager(getDiagnostics())); + TheSema.reset(); Ctx.reset(); PP.reset(); @@ -513,6 +522,8 @@ bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) { // Steal the created target, context, and preprocessor, and take back the // source and file managers. + TheSema.reset(Clang.takeSema()); + Consumer.reset(Clang.takeASTConsumer()); Ctx.reset(Clang.takeASTContext()); PP.reset(Clang.takePreprocessor()); Clang.takeSourceManager(); diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp index e55605b274..137c2d768e 100644 --- a/lib/Frontend/PCHReader.cpp +++ b/lib/Frontend/PCHReader.cpp @@ -3135,9 +3135,11 @@ void PCHReader::InitializeSema(Sema &S) { // Makes sure any declarations that were deserialized "too early" // still get added to the identifier's declaration chains. - for (unsigned I = 0, N = PreloadedDecls.size(); I != N; ++I) { - SemaObj->TUScope->AddDecl(Action::DeclPtrTy::make(PreloadedDecls[I])); - SemaObj->IdResolver.AddDecl(PreloadedDecls[I]); + if (SemaObj->TUScope) { + for (unsigned I = 0, N = PreloadedDecls.size(); I != N; ++I) { + SemaObj->TUScope->AddDecl(Action::DeclPtrTy::make(PreloadedDecls[I])); + SemaObj->IdResolver.AddDecl(PreloadedDecls[I]); + } } PreloadedDecls.clear(); @@ -3332,11 +3334,13 @@ PCHReader::SetGloballyVisibleDecls(IdentifierInfo *II, for (unsigned I = 0, N = DeclIDs.size(); I != N; ++I) { NamedDecl *D = cast<NamedDecl>(GetDecl(DeclIDs[I])); if (SemaObj) { - // Introduce this declaration into the translation-unit scope - // and add it to the declaration chain for this identifier, so - // that (unqualified) name lookup will find it. - SemaObj->TUScope->AddDecl(Action::DeclPtrTy::make(D)); - SemaObj->IdResolver.AddDeclToIdentifierChain(II, D); + if (SemaObj->TUScope) { + // Introduce this declaration into the translation-unit scope + // and add it to the declaration chain for this identifier, so + // that (unqualified) name lookup will find it. + SemaObj->TUScope->AddDecl(Action::DeclPtrTy::make(D)); + SemaObj->IdResolver.AddDeclToIdentifierChain(II, D); + } } else { // Queue this declaration so that it will be added to the // translation unit scope and identifier's declaration chain diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp index 0d05b57b8d..778bf8c98a 100644 --- a/lib/Sema/Sema.cpp +++ b/lib/Sema/Sema.cpp @@ -172,7 +172,7 @@ Sema::~Sema() { // Detach from the external Sema source. if (ExternalSemaSource *ExternalSema - = dyn_cast_or_null<ExternalSemaSource>(Context.getExternalSource())) + = dyn_cast_or_null<ExternalSemaSource>(Context.getExternalSource())) ExternalSema->ForgetSema(); } |