diff options
Diffstat (limited to 'lib/Frontend')
-rw-r--r-- | lib/Frontend/ASTMerge.cpp | 7 | ||||
-rw-r--r-- | lib/Frontend/ASTUnit.cpp | 28 | ||||
-rw-r--r-- | lib/Frontend/CompilerInstance.cpp | 7 | ||||
-rw-r--r-- | lib/Frontend/VerifyDiagnosticConsumer.cpp | 12 |
4 files changed, 44 insertions, 10 deletions
diff --git a/lib/Frontend/ASTMerge.cpp b/lib/Frontend/ASTMerge.cpp index bfb30836d8..b6c644eba7 100644 --- a/lib/Frontend/ASTMerge.cpp +++ b/lib/Frontend/ASTMerge.cpp @@ -34,7 +34,7 @@ bool ASTMergeAction::BeginSourceFileAction(CompilerInstance &CI, void ASTMergeAction::ExecuteAction() { CompilerInstance &CI = getCompilerInstance(); CI.getDiagnostics().getClient()->BeginSourceFile( - CI.getASTContext().getLangOpts()); + CI.getASTContext().getLangOpts()); CI.getDiagnostics().SetArgToStringFn(&FormatASTNodeDiagnosticArgument, &CI.getASTContext()); IntrusiveRefCntPtr<DiagnosticIDs> @@ -42,8 +42,9 @@ void ASTMergeAction::ExecuteAction() { for (unsigned I = 0, N = ASTFiles.size(); I != N; ++I) { IntrusiveRefCntPtr<DiagnosticsEngine> Diags(new DiagnosticsEngine(DiagIDs, &CI.getDiagnosticOpts(), - CI.getDiagnostics().getClient(), - /*ShouldOwnClient=*/false)); + new ForwardingDiagnosticConsumer( + *CI.getDiagnostics().getClient()), + /*ShouldOwnClient=*/true)); ASTUnit *Unit = ASTUnit::LoadFromASTFile(ASTFiles[I], Diags, CI.getFileSystemOpts(), false); if (!Unit) diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp index c1115aedbf..1b4e5a0b39 100644 --- a/lib/Frontend/ASTUnit.cpp +++ b/lib/Frontend/ASTUnit.cpp @@ -236,6 +236,11 @@ ASTUnit::ASTUnit(bool _MainFileIsAST) } ASTUnit::~ASTUnit() { + // If we loaded from an AST file, balance out the BeginSourceFile call. + if (MainFileIsAST && getDiagnostics().getClient()) { + getDiagnostics().getClient()->EndSourceFile(); + } + clearFileLevelDecls(); // Clean up the temporary files and the preamble file. @@ -581,14 +586,22 @@ private: } }; + /// \brief Diagnostic consumer that saves each diagnostic it is given. class StoredDiagnosticConsumer : public DiagnosticConsumer { SmallVectorImpl<StoredDiagnostic> &StoredDiags; - + SourceManager *SourceMgr; + public: explicit StoredDiagnosticConsumer( SmallVectorImpl<StoredDiagnostic> &StoredDiags) - : StoredDiags(StoredDiags) { } - + : StoredDiags(StoredDiags), SourceMgr(0) { } + + virtual void BeginSourceFile(const LangOptions &LangOpts, + const Preprocessor *PP = 0) { + if (PP) + SourceMgr = &PP->getSourceManager(); + } + virtual void HandleDiagnostic(DiagnosticsEngine::Level Level, const Diagnostic &Info); @@ -635,7 +648,11 @@ void StoredDiagnosticConsumer::HandleDiagnostic(DiagnosticsEngine::Level Level, // Default implementation (Warnings/errors count). DiagnosticConsumer::HandleDiagnostic(Level, Info); - StoredDiags.push_back(StoredDiagnostic(Level, Info)); + // Only record the diagnostic if it's part of the source manager we know + // about. This effectively drops diagnostics from modules we're building. + // FIXME: In the long run, ee don't want to drop source managers from modules. + if (!Info.hasSourceManager() || &Info.getSourceManager() == SourceMgr) + StoredDiags.push_back(StoredDiagnostic(Level, Info)); } ASTDeserializationListener *ASTUnit::getDeserializationListener() { @@ -835,6 +852,9 @@ ASTUnit *ASTUnit::LoadFromASTFile(const std::string &Filename, ReaderPtr->InitializeSema(*AST->TheSema); AST->Reader = ReaderPtr; + // Tell the diagnostic client that we have started a source file. + AST->getDiagnostics().getClient()->BeginSourceFile(Context.getLangOpts(),&PP); + return AST.take(); } diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp index df06a816e8..027e99a29d 100644 --- a/lib/Frontend/CompilerInstance.cpp +++ b/lib/Frontend/CompilerInstance.cpp @@ -868,9 +868,11 @@ static void compileModule(CompilerInstance &ImportingInstance, // module. CompilerInstance Instance; Instance.setInvocation(&*Invocation); - Instance.createDiagnostics(&ImportingInstance.getDiagnosticClient(), + + Instance.createDiagnostics(new ForwardingDiagnosticConsumer( + ImportingInstance.getDiagnosticClient()), /*ShouldOwnClient=*/true, - /*ShouldCloneClient=*/true); + /*ShouldCloneClient=*/false); // Note that this module is part of the module build stack, so that we // can detect cycles in the module graph. @@ -892,6 +894,7 @@ static void compileModule(CompilerInstance &ImportingInstance, llvm::CrashRecoveryContext CRC; CompileModuleMapData Data = { Instance, CreateModuleAction }; CRC.RunSafelyOnThread(&doCompileMapModule, &Data, ThreadStackSize); + // Delete the temporary module map file. // FIXME: Even though we're executing under crash protection, it would still diff --git a/lib/Frontend/VerifyDiagnosticConsumer.cpp b/lib/Frontend/VerifyDiagnosticConsumer.cpp index 4f05aef94f..91aa52b771 100644 --- a/lib/Frontend/VerifyDiagnosticConsumer.cpp +++ b/lib/Frontend/VerifyDiagnosticConsumer.cpp @@ -111,8 +111,13 @@ void VerifyDiagnosticConsumer::EndSourceFile() { void VerifyDiagnosticConsumer::HandleDiagnostic( DiagnosticsEngine::Level DiagLevel, const Diagnostic &Info) { - if (Info.hasSourceManager()) + if (Info.hasSourceManager()) { + // If this diagnostic is for a different source manager, ignore it. + if (SrcManager && &Info.getSourceManager() != SrcManager) + return; + setSourceManager(Info.getSourceManager()); + } #ifndef NDEBUG // Debug build tracks unparsed files for possible @@ -476,6 +481,11 @@ static bool ParseDirective(StringRef S, ExpectedData *ED, SourceManager &SM, bool VerifyDiagnosticConsumer::HandleComment(Preprocessor &PP, SourceRange Comment) { SourceManager &SM = PP.getSourceManager(); + + // If this comment is for a different source manager, ignore it. + if (SrcManager && &SM != SrcManager) + return false; + SourceLocation CommentBegin = Comment.getBegin(); const char *CommentRaw = SM.getCharacterData(CommentBegin); |