diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Frontend/FrontendAction.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Frontend/FrontendAction.cpp | 137 |
1 files changed, 88 insertions, 49 deletions
diff --git a/contrib/llvm/tools/clang/lib/Frontend/FrontendAction.cpp b/contrib/llvm/tools/clang/lib/Frontend/FrontendAction.cpp index ba2d63b..da4bdfa 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/FrontendAction.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/FrontendAction.cpp @@ -14,14 +14,15 @@ #include "clang/Lex/HeaderSearch.h" #include "clang/Lex/Preprocessor.h" #include "clang/Frontend/ASTUnit.h" +#include "clang/Frontend/ChainedIncludesSource.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/FrontendDiagnostic.h" #include "clang/Frontend/FrontendPluginRegistry.h" +#include "clang/Frontend/LayoutOverrideSource.h" #include "clang/Frontend/MultiplexConsumer.h" #include "clang/Parse/ParseAST.h" #include "clang/Serialization/ASTDeserializationListener.h" #include "clang/Serialization/ASTReader.h" -#include "clang/Serialization/ChainedIncludesSource.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Timer.h" #include "llvm/Support/ErrorHandling.h" @@ -30,37 +31,70 @@ using namespace clang; namespace { -/// \brief Dumps deserialized declarations. -class DeserializedDeclsDumper : public ASTDeserializationListener { +class DelegatingDeserializationListener : public ASTDeserializationListener { ASTDeserializationListener *Previous; public: - DeserializedDeclsDumper(ASTDeserializationListener *Previous) + explicit DelegatingDeserializationListener( + ASTDeserializationListener *Previous) : Previous(Previous) { } + virtual void ReaderInitialized(ASTReader *Reader) { + if (Previous) + Previous->ReaderInitialized(Reader); + } + virtual void IdentifierRead(serialization::IdentID ID, + IdentifierInfo *II) { + if (Previous) + Previous->IdentifierRead(ID, II); + } + virtual void TypeRead(serialization::TypeIdx Idx, QualType T) { + if (Previous) + Previous->TypeRead(Idx, T); + } + virtual void DeclRead(serialization::DeclID ID, const Decl *D) { + if (Previous) + Previous->DeclRead(ID, D); + } + virtual void SelectorRead(serialization::SelectorID ID, Selector Sel) { + if (Previous) + Previous->SelectorRead(ID, Sel); + } + virtual void MacroDefinitionRead(serialization::PreprocessedEntityID PPID, + MacroDefinition *MD) { + if (Previous) + Previous->MacroDefinitionRead(PPID, MD); + } +}; + +/// \brief Dumps deserialized declarations. +class DeserializedDeclsDumper : public DelegatingDeserializationListener { +public: + explicit DeserializedDeclsDumper(ASTDeserializationListener *Previous) + : DelegatingDeserializationListener(Previous) { } + virtual void DeclRead(serialization::DeclID ID, const Decl *D) { llvm::outs() << "PCH DECL: " << D->getDeclKindName(); if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) - llvm::outs() << " - " << ND->getNameAsString(); + llvm::outs() << " - " << *ND; llvm::outs() << "\n"; - if (Previous) - Previous->DeclRead(ID, D); + DelegatingDeserializationListener::DeclRead(ID, D); } }; /// \brief Checks deserialized declarations and emits error if a name /// matches one given in command-line using -error-on-deserialized-decl. - class DeserializedDeclsChecker : public ASTDeserializationListener { + class DeserializedDeclsChecker : public DelegatingDeserializationListener { ASTContext &Ctx; std::set<std::string> NamesToCheck; - ASTDeserializationListener *Previous; public: DeserializedDeclsChecker(ASTContext &Ctx, const std::set<std::string> &NamesToCheck, ASTDeserializationListener *Previous) - : Ctx(Ctx), NamesToCheck(NamesToCheck), Previous(Previous) { } + : DelegatingDeserializationListener(Previous), + Ctx(Ctx), NamesToCheck(NamesToCheck) { } virtual void DeclRead(serialization::DeclID ID, const Decl *D) { if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) @@ -72,8 +106,7 @@ public: << ND->getNameAsString(); } - if (Previous) - Previous->DeclRead(ID, D); + DelegatingDeserializationListener::DeclRead(ID, D); } }; @@ -83,10 +116,9 @@ FrontendAction::FrontendAction() : Instance(0) {} FrontendAction::~FrontendAction() {} -void FrontendAction::setCurrentFile(StringRef Value, InputKind Kind, - ASTUnit *AST) { - CurrentFile = Value; - CurrentFileKind = Kind; +void FrontendAction::setCurrentInput(const FrontendInputFile &CurrentInput, + ASTUnit *AST) { + this->CurrentInput = CurrentInput; CurrentASTUnit.reset(AST); } @@ -112,7 +144,7 @@ ASTConsumer* FrontendAction::CreateWrappedASTConsumer(CompilerInstance &CI, ie = FrontendPluginRegistry::end(); it != ie; ++it) { if (it->getName() == CI.getFrontendOpts().AddPluginActions[i]) { - llvm::OwningPtr<PluginASTAction> P(it->instantiate()); + OwningPtr<PluginASTAction> P(it->instantiate()); FrontendAction* c = P.get(); if (P->ParseArgs(CI, CI.getFrontendOpts().AddPluginArgs[i])) Consumers.push_back(c->CreateASTConsumer(CI, InFile)); @@ -124,11 +156,10 @@ ASTConsumer* FrontendAction::CreateWrappedASTConsumer(CompilerInstance &CI, } bool FrontendAction::BeginSourceFile(CompilerInstance &CI, - StringRef Filename, - InputKind InputKind) { + const FrontendInputFile &Input) { assert(!Instance && "Already processing a source file!"); - assert(!Filename.empty() && "Unexpected empty filename!"); - setCurrentFile(Filename, InputKind); + assert(!Input.File.empty() && "Unexpected empty filename!"); + setCurrentInput(Input); setCompilerInstance(&CI); if (!BeginInvocation(CI)) @@ -136,20 +167,20 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI, // AST files follow a very different path, since they share objects via the // AST unit. - if (InputKind == IK_AST) { + if (Input.Kind == IK_AST) { assert(!usesPreprocessorOnly() && "Attempt to pass AST file to preprocessor only action!"); assert(hasASTFileSupport() && "This action does not have AST file support!"); - llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags(&CI.getDiagnostics()); + IntrusiveRefCntPtr<DiagnosticsEngine> Diags(&CI.getDiagnostics()); std::string Error; - ASTUnit *AST = ASTUnit::LoadFromASTFile(Filename, Diags, + ASTUnit *AST = ASTUnit::LoadFromASTFile(Input.File, Diags, CI.getFileSystemOpts()); if (!AST) goto failure; - setCurrentFile(Filename, InputKind, AST); + setCurrentInput(Input, AST); // Set the shared objects, these are reset when we finish processing the // file, otherwise the CompilerInstance will happily destroy them. @@ -159,11 +190,11 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI, CI.setASTContext(&AST->getASTContext()); // Initialize the action. - if (!BeginSourceFileAction(CI, Filename)) + if (!BeginSourceFileAction(CI, Input.File)) goto failure; /// Create the AST consumer. - CI.setASTConsumer(CreateWrappedASTConsumer(CI, Filename)); + CI.setASTConsumer(CreateWrappedASTConsumer(CI, Input.File)); if (!CI.hasASTConsumer()) goto failure; @@ -177,7 +208,7 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI, CI.createSourceManager(CI.getFileManager()); // IR files bypass the rest of initialization. - if (InputKind == IK_LLVM_IR) { + if (Input.Kind == IK_LLVM_IR) { assert(hasIRSupport() && "This action does not have IR file support!"); @@ -185,7 +216,7 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI, CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), 0); // Initialize the action. - if (!BeginSourceFileAction(CI, Filename)) + if (!BeginSourceFileAction(CI, Input.File)) goto failure; return true; @@ -199,7 +230,7 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI, &CI.getPreprocessor()); // Initialize the action. - if (!BeginSourceFileAction(CI, Filename)) + if (!BeginSourceFileAction(CI, Input.File)) goto failure; /// Create the AST context and consumer unless this is a preprocessor only @@ -207,8 +238,8 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI, if (!usesPreprocessorOnly()) { CI.createASTContext(); - llvm::OwningPtr<ASTConsumer> Consumer( - CreateWrappedASTConsumer(CI, Filename)); + OwningPtr<ASTConsumer> Consumer( + CreateWrappedASTConsumer(CI, Input.File)); if (!Consumer) goto failure; @@ -216,7 +247,7 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI, if (!CI.getPreprocessorOpts().ChainedIncludes.empty()) { // Convert headers to PCH and chain them. - llvm::OwningPtr<ExternalASTSource> source; + OwningPtr<ExternalASTSource> source; source.reset(ChainedIncludesSource::create(CI)); if (!source) goto failure; @@ -237,6 +268,7 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI, CI.getPreprocessorOpts().ImplicitPCHInclude, CI.getPreprocessorOpts().DisablePCHValidation, CI.getPreprocessorOpts().DisableStatCache, + CI.getPreprocessorOpts().AllowPCHWithCompilerErrors, DeserialListener); if (!CI.getASTContext().getExternalSource()) goto failure; @@ -252,9 +284,19 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI, if (!CI.hasASTContext() || !CI.getASTContext().getExternalSource()) { Preprocessor &PP = CI.getPreprocessor(); PP.getBuiltinInfo().InitializeBuiltins(PP.getIdentifierTable(), - PP.getLangOptions()); + PP.getLangOpts()); } + // If there is a layout overrides file, attach an external AST source that + // provides the layouts from that file. + if (!CI.getFrontendOpts().OverrideRecordLayoutsFile.empty() && + CI.hasASTContext() && !CI.getASTContext().getExternalSource()) { + OwningPtr<ExternalASTSource> + Override(new LayoutOverrideSource( + CI.getFrontendOpts().OverrideRecordLayoutsFile)); + CI.getASTContext().setExternalSource(Override); + } + return true; // If we failed, reset state since the client will not end up calling the @@ -268,7 +310,7 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI, } CI.getDiagnosticClient().EndSourceFile(); - setCurrentFile("", IK_None); + setCurrentInput(FrontendInputFile()); setCompilerInstance(0); return false; } @@ -278,17 +320,11 @@ void FrontendAction::Execute() { // Initialize the main file entry. This needs to be delayed until after PCH // has loaded. - if (isCurrentFileAST()) { - // Set the main file ID to an empty file. - // - // FIXME: We probably shouldn't need this, but for now this is the - // simplest way to reuse the logic in ParseAST. - const char *EmptyStr = ""; - llvm::MemoryBuffer *SB = - llvm::MemoryBuffer::getMemBuffer(EmptyStr, "<dummy input>"); - CI.getSourceManager().createMainFileIDForMemBuffer(SB); - } else { - if (!CI.InitializeSourceManager(getCurrentFile())) + if (!isCurrentFileAST()) { + if (!CI.InitializeSourceManager(getCurrentFile(), + getCurrentInput().IsSystem + ? SrcMgr::C_System + : SrcMgr::C_User)) return; } @@ -352,7 +388,7 @@ void FrontendAction::EndSourceFile() { } setCompilerInstance(0); - setCurrentFile("", IK_None); + setCurrentInput(FrontendInputFile()); } //===----------------------------------------------------------------------===// @@ -376,9 +412,12 @@ void ASTFrontendAction::ExecuteAction() { if (!CI.hasSema()) CI.createSema(getTranslationUnitKind(), CompletionConsumer); - ParseAST(CI.getSema(), CI.getFrontendOpts().ShowStats); + ParseAST(CI.getSema(), CI.getFrontendOpts().ShowStats, + CI.getFrontendOpts().SkipFunctionBodies); } +void PluginASTAction::anchor() { } + ASTConsumer * PreprocessorFrontendAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { @@ -394,7 +433,7 @@ bool WrapperFrontendAction::BeginInvocation(CompilerInstance &CI) { } bool WrapperFrontendAction::BeginSourceFileAction(CompilerInstance &CI, StringRef Filename) { - WrappedAction->setCurrentFile(getCurrentFile(), getCurrentFileKind()); + WrappedAction->setCurrentInput(getCurrentInput()); WrappedAction->setCompilerInstance(&CI); return WrappedAction->BeginSourceFileAction(CI, Filename); } |