From 37e59a10a7a537428e5997fd5896f5b89fd34e6b Mon Sep 17 00:00:00 2001 From: Argyrios Kyrtzidis Date: Wed, 17 Aug 2011 00:31:18 +0000 Subject: [PATCH] Make SourceManager::isBeforeInTranslationUnit handle macro locations correctly. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@137793 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/SourceManager.h | 22 ++++++++++++++++++++-- lib/Basic/SourceManager.cpp | 10 +++------- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h index 1bf3278434..2ea19ebc4d 100644 --- a/include/clang/Basic/SourceManager.h +++ b/include/clang/Basic/SourceManager.h @@ -367,7 +367,11 @@ class IsBeforeInTranslationUnitCache { /// L/R QueryFID - These are the FID's of the cached query. If these match up /// with a subsequent query, the result can be reused. FileID LQueryFID, RQueryFID; - + + /// \brief True if LQueryFID was created before RQueryFID. This is used + /// to compare macro expansion locations. + bool IsLQFIDBeforeRQFID; + /// CommonFID - This is the file found in common between the two #include /// traces. It is the nearest common ancestor of the #include tree. FileID CommonFID; @@ -392,13 +396,27 @@ public: // use the #include loc in the common file. if (LQueryFID != CommonFID) LOffset = LCommonOffset; if (RQueryFID != CommonFID) ROffset = RCommonOffset; + + // It is common for multiple macro expansions to be "included" from the same + // location (expansion location), in which case use the order of the FileIDs + // to determine which came first. + if (LOffset == ROffset && LQueryFID != CommonFID && RQueryFID != CommonFID) + return IsLQFIDBeforeRQFID; + return LOffset < ROffset; } // Set up a new query. - void setQueryFIDs(FileID LHS, FileID RHS) { + void setQueryFIDs(FileID LHS, FileID RHS, bool isLFIDBeforeRFID) { + assert(LHS != RHS); LQueryFID = LHS; RQueryFID = RHS; + IsLQFIDBeforeRQFID = isLFIDBeforeRFID; + } + + void clear() { + LQueryFID = RQueryFID = FileID(); + IsLQFIDBeforeRQFID = false; } void setCommonLoc(FileID commonFID, unsigned lCommonOffset, diff --git a/lib/Basic/SourceManager.cpp b/lib/Basic/SourceManager.cpp index 4f2922b645..e3106c4a29 100644 --- a/lib/Basic/SourceManager.cpp +++ b/lib/Basic/SourceManager.cpp @@ -1484,11 +1484,6 @@ bool SourceManager::isBeforeInTranslationUnit(SourceLocation LHS, if (LHS == RHS) return false; - // If both locations are macro expansions, the order of their offsets reflect - // the order that the tokens, pointed to by these locations, were expanded - // (during parsing each token that is expanded by a macro, expands the - // SLocEntries). - std::pair LOffs = getDecomposedLoc(LHS); std::pair ROffs = getDecomposedLoc(RHS); @@ -1502,7 +1497,8 @@ bool SourceManager::isBeforeInTranslationUnit(SourceLocation LHS, return IsBeforeInTUCache.getCachedResult(LOffs.second, ROffs.second); // Okay, we missed in the cache, start updating the cache for this query. - IsBeforeInTUCache.setQueryFIDs(LOffs.first, ROffs.first); + IsBeforeInTUCache.setQueryFIDs(LOffs.first, ROffs.first, + /*isLFIDBeforeRFID=*/LOffs.first.ID < ROffs.first.ID); // We need to find the common ancestor. The only way of doing this is to // build the complete include chain for one and then walking up the chain @@ -1534,7 +1530,7 @@ bool SourceManager::isBeforeInTranslationUnit(SourceLocation LHS, // This can happen if a location is in a built-ins buffer. // But see PR5662. // Clear the lookup cache, it depends on a common location. - IsBeforeInTUCache.setQueryFIDs(FileID(), FileID()); + IsBeforeInTUCache.clear(); bool LIsBuiltins = strcmp("", getBuffer(LOffs.first)->getBufferIdentifier()) == 0; bool RIsBuiltins = strcmp("", -- 2.40.0