summaryrefslogtreecommitdiffstats
path: root/clang/lib/Basic/Diagnostic.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2018-02-09 01:15:13 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2018-02-09 01:15:13 +0000
commit6c2b5a8ff0b4ea3a9c5dcaf1ffe80c949845f500 (patch)
tree3ab04e25945e45757936e507b7dbf8cf1fdedb91 /clang/lib/Basic/Diagnostic.cpp
parentfb7b14f70d33225a8299db98bff6e99d79f13ae7 (diff)
downloadbcm5719-llvm-6c2b5a8ff0b4ea3a9c5dcaf1ffe80c949845f500.tar.gz
bcm5719-llvm-6c2b5a8ff0b4ea3a9c5dcaf1ffe80c949845f500.zip
[modules] Fix incorrect diagnostic mapping computation when a module changes
diagnostic settings using _Pragma within a macro. The AST writer had previously been assuming that all diagnostic state transitions would occur within a FileID corresponding to a file. When a diagnostic state change occured within a macro, it was unable to form a location for that state change and would instead corrupt the diagnostic state of the "root" node (and thus that of the main compilation). Also introduce a "#pragma clang __debug diag_mapping" debugging utility that I added to track this issue down. llvm-svn: 324695
Diffstat (limited to 'clang/lib/Basic/Diagnostic.cpp')
-rw-r--r--clang/lib/Basic/Diagnostic.cpp90
1 files changed, 90 insertions, 0 deletions
diff --git a/clang/lib/Basic/Diagnostic.cpp b/clang/lib/Basic/Diagnostic.cpp
index 5903d72ea5e..83e61dd9470 100644
--- a/clang/lib/Basic/Diagnostic.cpp
+++ b/clang/lib/Basic/Diagnostic.cpp
@@ -236,6 +236,96 @@ DiagnosticsEngine::DiagStateMap::getFile(SourceManager &SrcMgr,
return &F;
}
+void DiagnosticsEngine::DiagStateMap::dump(SourceManager &SrcMgr,
+ StringRef DiagName) const {
+ llvm::errs() << "diagnostic state at ";
+ CurDiagStateLoc.dump(SrcMgr);
+ llvm::errs() << ": " << CurDiagState << "\n";
+
+ for (auto &F : Files) {
+ FileID ID = F.first;
+ File &File = F.second;
+
+ bool PrintedOuterHeading = false;
+ auto PrintOuterHeading = [&] {
+ if (PrintedOuterHeading) return;
+ PrintedOuterHeading = true;
+
+ llvm::errs() << "File " << &File << " <FileID " << ID.getHashValue()
+ << ">: " << SrcMgr.getBuffer(ID)->getBufferIdentifier();
+ if (F.second.Parent) {
+ std::pair<FileID, unsigned> Decomp =
+ SrcMgr.getDecomposedIncludedLoc(ID);
+ assert(File.ParentOffset == Decomp.second);
+ llvm::errs() << " parent " << File.Parent << " <FileID "
+ << Decomp.first.getHashValue() << "> ";
+ SrcMgr.getLocForStartOfFile(Decomp.first)
+ .getLocWithOffset(Decomp.second)
+ .dump(SrcMgr);
+ }
+ if (File.HasLocalTransitions)
+ llvm::errs() << " has_local_transitions";
+ llvm::errs() << "\n";
+ };
+
+ if (DiagName.empty())
+ PrintOuterHeading();
+
+ for (DiagStatePoint &Transition : File.StateTransitions) {
+ bool PrintedInnerHeading = false;
+ auto PrintInnerHeading = [&] {
+ if (PrintedInnerHeading) return;
+ PrintedInnerHeading = true;
+
+ PrintOuterHeading();
+ llvm::errs() << " ";
+ SrcMgr.getLocForStartOfFile(ID)
+ .getLocWithOffset(Transition.Offset)
+ .dump(SrcMgr);
+ llvm::errs() << ": state " << Transition.State << ":\n";
+ };
+
+ if (DiagName.empty())
+ PrintInnerHeading();
+
+ for (auto &Mapping : *Transition.State) {
+ StringRef Option =
+ DiagnosticIDs::getWarningOptionForDiag(Mapping.first);
+ if (!DiagName.empty() && DiagName != Option)
+ continue;
+
+ PrintInnerHeading();
+ llvm::errs() << " ";
+ if (Option.empty())
+ llvm::errs() << "<unknown " << Mapping.first << ">";
+ else
+ llvm::errs() << Option;
+ llvm::errs() << ": ";
+
+ switch (Mapping.second.getSeverity()) {
+ case diag::Severity::Ignored: llvm::errs() << "ignored"; break;
+ case diag::Severity::Remark: llvm::errs() << "remark"; break;
+ case diag::Severity::Warning: llvm::errs() << "warning"; break;
+ case diag::Severity::Error: llvm::errs() << "error"; break;
+ case diag::Severity::Fatal: llvm::errs() << "fatal"; break;
+ }
+
+ if (!Mapping.second.isUser())
+ llvm::errs() << " default";
+ if (Mapping.second.isPragma())
+ llvm::errs() << " pragma";
+ if (Mapping.second.hasNoWarningAsError())
+ llvm::errs() << " no-error";
+ if (Mapping.second.hasNoErrorAsFatal())
+ llvm::errs() << " no-fatal";
+ if (Mapping.second.wasUpgradedFromWarning())
+ llvm::errs() << " overruled";
+ llvm::errs() << "\n";
+ }
+ }
+ }
+}
+
void DiagnosticsEngine::PushDiagStatePoint(DiagState *State,
SourceLocation Loc) {
assert(Loc.isValid() && "Adding invalid loc point");
OpenPOWER on IntegriCloud