summaryrefslogtreecommitdiffstats
path: root/clang/lib/Frontend/ASTUnit.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2013-05-03 22:58:43 +0000
committerDouglas Gregor <dgregor@apple.com>2013-05-03 22:58:43 +0000
commit6b930967e88029e9c7ce1b1c4234042b5983ad63 (patch)
treea222ecff1ec495a9578e294ba8363c778a51b36a /clang/lib/Frontend/ASTUnit.cpp
parentb2a1cb87b1df6bb1881e5da1cd590d241f9807b6 (diff)
downloadbcm5719-llvm-6b930967e88029e9c7ce1b1c4234042b5983ad63.tar.gz
bcm5719-llvm-6b930967e88029e9c7ce1b1c4234042b5983ad63.zip
When building a module, forward diagnostics to the outer diagnostic consumer.
Previously, we would clone the current diagnostic consumer to produce a new diagnostic consumer to use when building a module. The problem here is that we end up losing diagnostics for important diagnostic consumers, such as serialized diagnostics (where we'd end up with two diagnostic consumers writing the same output file). With forwarding, the diagnostics from all of the different modules being built get forwarded to the one serialized-diagnostic consumer and are emitted in a sane way. Fixes <rdar://problem/13663996>. llvm-svn: 181067
Diffstat (limited to 'clang/lib/Frontend/ASTUnit.cpp')
-rw-r--r--clang/lib/Frontend/ASTUnit.cpp28
1 files changed, 24 insertions, 4 deletions
diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp
index c1115aedbf8..1b4e5a0b39a 100644
--- a/clang/lib/Frontend/ASTUnit.cpp
+++ b/clang/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();
}
OpenPOWER on IntegriCloud