aboutsummaryrefslogtreecommitdiff
path: root/lib/Frontend/DiagnosticRenderer.cpp
diff options
context:
space:
mode:
authorEli Friedman <eli.friedman@gmail.com>2012-11-30 06:19:40 +0000
committerEli Friedman <eli.friedman@gmail.com>2012-11-30 06:19:40 +0000
commitecdc8d3e0fc65610746a4e074491ca0807fca7b2 (patch)
tree1967bda35fe29ef80ab5884b02ae069a19205d1b /lib/Frontend/DiagnosticRenderer.cpp
parent7d04d3a6855bc74d5c1a2213717eb5402b772ae6 (diff)
Fix the computation of highlight ranges so we produce something sane when
the beginning and end of the range are in different macro arguments. PR14399. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@168984 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Frontend/DiagnosticRenderer.cpp')
-rw-r--r--lib/Frontend/DiagnosticRenderer.cpp40
1 files changed, 30 insertions, 10 deletions
diff --git a/lib/Frontend/DiagnosticRenderer.cpp b/lib/Frontend/DiagnosticRenderer.cpp
index 2d156f7022..3143cc7b32 100644
--- a/lib/Frontend/DiagnosticRenderer.cpp
+++ b/lib/Frontend/DiagnosticRenderer.cpp
@@ -242,20 +242,40 @@ static void mapDiagnosticRanges(
SourceLocation Begin = I->getBegin(), End = I->getEnd();
bool IsTokenRange = I->isTokenRange();
- // Search the macro caller chain for the beginning of the range.
- while (Begin.isMacroID() && SM->getFileID(Begin) != CaretLocFileID)
- Begin = SM->getImmediateMacroCallerLoc(Begin);
-
- // Search the macro caller chain for the beginning of the range.
- while (End.isMacroID() && SM->getFileID(End) != CaretLocFileID) {
- // The computation of the next End is an inlined version of
- // getImmediateMacroCallerLoc, except it chooses the end of an
- // expansion range.
- if (SM->isMacroArgExpansion(End)) {
+ FileID BeginFileID = SM->getFileID(Begin);
+ FileID EndFileID = SM->getFileID(End);
+
+ // Find the common parent for the beginning and end of the range.
+
+ // First, crawl the expansion chain for the beginning of the range.
+ llvm::SmallDenseMap<FileID, SourceLocation> BeginLocsMap;
+ while (Begin.isMacroID() && BeginFileID != EndFileID) {
+ BeginLocsMap[BeginFileID] = Begin;
+ Begin = SM->getImmediateExpansionRange(Begin).first;
+ BeginFileID = SM->getFileID(Begin);
+ }
+
+ // Then, crawl the expansion chain for the end of the range.
+ if (BeginFileID != EndFileID) {
+ while (End.isMacroID() && !BeginLocsMap.count(EndFileID)) {
+ End = SM->getImmediateExpansionRange(End).second;
+ EndFileID = SM->getFileID(End);
+ }
+ if (End.isMacroID()) {
+ Begin = BeginLocsMap[EndFileID];
+ BeginFileID = EndFileID;
+ }
+ }
+
+ while (Begin.isMacroID() && BeginFileID != CaretLocFileID) {
+ if (SM->isMacroArgExpansion(Begin)) {
+ Begin = SM->getImmediateSpellingLoc(Begin);
End = SM->getImmediateSpellingLoc(End);
} else {
+ Begin = SM->getImmediateExpansionRange(Begin).first;
End = SM->getImmediateExpansionRange(End).second;
}
+ BeginFileID = SM->getFileID(Begin);
}
// Return the spelling location of the beginning and end of the range.