aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2011-08-17 00:31:18 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2011-08-17 00:31:18 +0000
commit37e59a10a7a537428e5997fd5896f5b89fd34e6b (patch)
tree458c03e85308a48d74f07bd8525f6dbad3cc3926
parentd21683cdc0ff4217bfd98a9d8d0c1083b642caac (diff)
Make SourceManager::isBeforeInTranslationUnit handle macro locations correctly.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@137793 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Basic/SourceManager.h22
-rw-r--r--lib/Basic/SourceManager.cpp10
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<FileID, unsigned> LOffs = getDecomposedLoc(LHS);
std::pair<FileID, unsigned> 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("<built-in>",
getBuffer(LOffs.first)->getBufferIdentifier()) == 0;
bool RIsBuiltins = strcmp("<built-in>",