aboutsummaryrefslogtreecommitdiff
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
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
-rw-r--r--lib/Frontend/DiagnosticRenderer.cpp40
-rw-r--r--test/Misc/caret-diags-macros.c14
2 files changed, 44 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.
diff --git a/test/Misc/caret-diags-macros.c b/test/Misc/caret-diags-macros.c
index 5faddb65f6..a41816f0ee 100644
--- a/test/Misc/caret-diags-macros.c
+++ b/test/Misc/caret-diags-macros.c
@@ -163,3 +163,17 @@ int y = Y;
// CHECK-NEXT: {{.*}}:134:15: note: expanded from macro 'QMARK'
// CHECK-NEXT: #define QMARK ?
// CHECK-NEXT: {{^ \^}}
+
+// PR14399
+void iequals(int,int,int);
+void foo_aa()
+{
+#define /* */ BARC(c, /* */b, a, ...) (a+b+/* */c + __VA_ARGS__ +0)
+ iequals(__LINE__, BARC(4,3,2,6,8), 8);
+}
+// CHECK: {{.*}}:172:21: warning: expression result unused
+// CHECK-NEXT: iequals(__LINE__, BARC(4,3,2,6,8), 8);
+// CHECK-NEXT: {{^ \^~~~~~~~~~~~~~~}}
+// CHECK-NEXT: {{.*}}:171:51: note: expanded from macro 'BARC'
+// CHECK-NEXT: #define /* */ BARC(c, /* */b, a, ...) (a+b+/* */c + __VA_ARGS__ +0)
+// CHECK-NEXT: {{^ ~~~~~~~~~~ \^}}