diff --git a/lib/Frontend/DiagnosticRenderer.cpp b/lib/Frontend/DiagnosticRenderer.cpp index aeab506b41..89d3867aad 100644 --- a/lib/Frontend/DiagnosticRenderer.cpp +++ b/lib/Frontend/DiagnosticRenderer.cpp @@ -306,56 +306,6 @@ void DiagnosticRenderer::emitModuleBuildStack(const SourceManager &SM) { } } -// Find the common parent for the beginning and end of the range. -static void findCommonParent(SourceLocation &Begin, SourceLocation &End, - const SourceManager *SM) { - if (Begin.isInvalid() || End.isInvalid()) { - Begin = End = SourceLocation(); - return; - } - - FileID BeginFileID = SM->getFileID(Begin); - FileID EndFileID = SM->getFileID(End); - - // First, crawl the expansion chain for the beginning of the range. - llvm::SmallDenseMap BeginLocsMap; - BeginLocsMap[BeginFileID] = Begin; - while (Begin.isMacroID() && BeginFileID != EndFileID) { - if (SM->isMacroArgExpansion(Begin)) { - Begin = SM->getImmediateSpellingLoc(Begin); - if (Begin.isMacroID()) - continue; - Begin = SourceLocation(); - BeginFileID = FileID(); - break; - } - Begin = SM->getImmediateExpansionRange(Begin).first; - BeginFileID = SM->getFileID(Begin); - BeginLocsMap[BeginFileID] = Begin; - } - - // Then, crawl the expansion chain for the end of the range. - if (BeginFileID != EndFileID) { - while (End.isMacroID() && !BeginLocsMap.count(EndFileID)) { - if (SM->isMacroArgExpansion(End)) { - End = SM->getImmediateSpellingLoc(End); - if (End.isMacroID()) - continue; - End = SourceLocation(); - EndFileID = FileID(); - break; - } - End = SM->getImmediateExpansionRange(End).second; - EndFileID = SM->getFileID(End); - } - if (End.isMacroID()) { - Begin = BeginLocsMap[EndFileID]; - BeginFileID = EndFileID; - } - } - assert(Begin.isValid() == End.isValid()); -} - // Helper function to fix up source ranges. It takes in an array of ranges, // and outputs an array of ranges where we want to draw the range highlighting // around the location specified by CaretLoc. @@ -379,38 +329,40 @@ static void mapDiagnosticRanges( SourceLocation Begin = I->getBegin(), End = I->getEnd(); bool IsTokenRange = I->isTokenRange(); - // Compute the common parent; we can't highlight a range where - // the begin and end have different FileIDs. - findCommonParent(Begin, End, SM); - FileID BeginFileID = SM->getFileID(Begin); + FileID EndFileID = SM->getFileID(End); - while (Begin.isMacroID() && BeginFileID != CaretLocFileID) { - if (SM->isMacroArgExpansion(Begin)) { - // We have a macro argument; take the spelling loc, which is - // a step closer to where the argument was written. - Begin = SM->getImmediateSpellingLoc(Begin); - End = SM->getImmediateSpellingLoc(End); - BeginFileID = SM->getFileID(Begin); - assert(BeginFileID == SM->getFileID(End)); - } else { - // Take the next expansion in the expansion chain. - Begin = SM->getImmediateExpansionRange(Begin).first; + // 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 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; - - // Compute the common parent again; the beginning and end might - // come out of different macro expansions. - findCommonParent(Begin, End, SM); - BeginFileID = SM->getFileID(Begin); + EndFileID = SM->getFileID(End); + } + if (End.isMacroID()) { + Begin = BeginLocsMap[EndFileID]; + BeginFileID = EndFileID; } } - // If this is the expansion of a macro argument, point the range at the - // use of the argument in the definition of the macro, not the expansion. - if (SM->isMacroArgExpansion(Begin)) { - assert(SM->isMacroArgExpansion(End)); - Begin = End = SM->getImmediateExpansionRange(Begin).first; - IsTokenRange = true; + 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 8fcfeb070c..ce62425e78 100644 --- a/test/Misc/caret-diags-macros.c +++ b/test/Misc/caret-diags-macros.c @@ -181,10 +181,10 @@ void foo_aa() } // CHECK: {{.*}}:180:21: warning: expression result unused // CHECK-NEXT: iequals(__LINE__, BARC(4,3,2,6,8), 8); -// CHECK-NEXT: {{^ \^ ~}} +// CHECK-NEXT: {{^ \^~~~~~~~~~~~~~~}} // CHECK-NEXT: {{.*}}:179:51: note: expanded from macro 'BARC' // CHECK-NEXT: #define /* */ BARC(c, /* */b, a, ...) (a+b+/* */c + __VA_ARGS__ +0) -// CHECK-NEXT: {{^ \^}} +// CHECK-NEXT: {{^ ~~~~~~~~~~ \^}} #define APPEND2(NUM, SUFF) -1 != NUM ## SUFF #define APPEND(NUM, SUFF) APPEND2(NUM, SUFF) @@ -205,24 +205,3 @@ void foo_aa() // CHECK-NEXT: {{.*}}:189:31: note: expanded from macro 'APPEND2' // CHECK-NEXT: #define APPEND2(NUM, SUFF) -1 != NUM ## SUFF // CHECK-NEXT: {{^ ~~ \^ ~~~~~~~~~~~}} - - -unsigned long strlen_test(const char *s); -#define __darwin_obsz(object) __builtin_object_size (object, 1) -#define sprintf2(str, ...) \ - __builtin___sprintf_chk (str, 0, __darwin_obsz(str), __VA_ARGS__) -#define Cstrlen(a) strlen_test(a) -#define Csprintf sprintf2 -void f(char* pMsgBuf, char* pKeepBuf) { -Csprintf(pMsgBuf,"\nEnter minimum anagram length (2-%1d): ", Cstrlen(pKeepBuf)); -} -// CHECK: {{.*}}:217:62: warning: format specifies type 'int' but the argument has type 'unsigned long' -// CHECK-NEXT: Csprintf(pMsgBuf,"\nEnter minimum anagram length (2-%1d): ", Cstrlen(pKeepBuf)); -// CHECK-NEXT: {{^ ~~~ \^~~~~~~~~~~~~~~~~}} -// CHECK-NEXT: {{^ %1ld}} -// CHECK-NEXT: {{.*}}:214:21: note: expanded from macro 'Cstrlen' -// CHECK-NEXT: #define Cstrlen(a) strlen_test(a) -// CHECK-NEXT: {{^ \^}} -// CHECK-NEXT: {{.*}}:213:56: note: expanded from macro 'sprintf2' -// CHECK-NEXT: __builtin___sprintf_chk (str, 0, __darwin_obsz(str), __VA_ARGS__) -// CHECK-NEXT: {{^ \^}}