diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2012-11-30 06:19:40 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2012-11-30 06:19:40 +0000 |
commit | ecdc8d3e0fc65610746a4e074491ca0807fca7b2 (patch) | |
tree | 1967bda35fe29ef80ab5884b02ae069a19205d1b /lib/Frontend/DiagnosticRenderer.cpp | |
parent | 7d04d3a6855bc74d5c1a2213717eb5402b772ae6 (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.cpp | 40 |
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. |