]> granicus.if.org Git - clang/commitdiff
Fix the computation of highlight ranges so we produce something sane when
authorEli Friedman <eli.friedman@gmail.com>
Fri, 30 Nov 2012 06:19:40 +0000 (06:19 +0000)
committerEli Friedman <eli.friedman@gmail.com>
Fri, 30 Nov 2012 06:19:40 +0000 (06:19 +0000)
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

lib/Frontend/DiagnosticRenderer.cpp
test/Misc/caret-diags-macros.c

index 2d156f702252f0ffb98307be9d5c022b7d664e97..3143cc7b324a4fe0a65b3b4ce3dddaed2f6e28e8 100644 (file)
@@ -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.
index 5faddb65f6e68873a820b43e4a019fafa073a942..a41816f0eedc8e277a817b947b45673f6b0b8cef 100644 (file)
@@ -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: {{^                                       ~~~~~~~~~~ \^}}