xazax.hun updated this revision to Diff 104167. xazax.hun retitled this revision from "Relax an assert in the comparison of source locations" to "Factor out a functionality from `isBeforeInTranslationUnit`". xazax.hun edited the summary of this revision. xazax.hun added a comment.
- New approach to solve the original problem https://reviews.llvm.org/D34506 Files: include/clang/Basic/SourceManager.h lib/Basic/SourceManager.cpp
Index: lib/Basic/SourceManager.cpp =================================================================== --- lib/Basic/SourceManager.cpp +++ lib/Basic/SourceManager.cpp @@ -2055,19 +2055,64 @@ if (LOffs.first == ROffs.first) return LOffs.second < ROffs.second; + std::pair<bool, bool> InSameTU = isInTheSameTranslationUnit(LOffs, ROffs); + if (InSameTU.first) + return InSameTU.second; + + // If we arrived here, the location is either in a built-ins buffer or + // associated with global inline asm. PR5662 and PR22576 are examples. + + StringRef LB = getBuffer(LOffs.first)->getBufferIdentifier(); + StringRef RB = getBuffer(ROffs.first)->getBufferIdentifier(); + bool LIsBuiltins = LB == "<built-in>"; + bool RIsBuiltins = RB == "<built-in>"; + // Sort built-in before non-built-in. + if (LIsBuiltins || RIsBuiltins) { + if (LIsBuiltins != RIsBuiltins) + return LIsBuiltins; + // Both are in built-in buffers, but from different files. We just claim that + // lower IDs come first. + return LOffs.first < ROffs.first; + } + bool LIsAsm = LB == "<inline asm>"; + bool RIsAsm = RB == "<inline asm>"; + // Sort assembler after built-ins, but before the rest. + if (LIsAsm || RIsAsm) { + if (LIsAsm != RIsAsm) + return RIsAsm; + assert(LOffs.first == ROffs.first); + return false; + } + bool LIsScratch = LB == "<scratch space>"; + bool RIsScratch = RB == "<scratch space>"; + // Sort scratch after inline asm, but before the rest. + if (LIsScratch || RIsScratch) { + if (LIsScratch != RIsScratch) + return LIsScratch; + return LOffs.second < ROffs.second; + } + // Source locations from different translation units. + llvm_unreachable("Unsortable locations found"); +} + +std::pair<bool, bool> SourceManager::isInTheSameTranslationUnit( + std::pair<FileID, unsigned> &LOffs, + std::pair<FileID, unsigned> &ROffs) const { // If we are comparing a source location with multiple locations in the same // file, we get a big win by caching the result. InBeforeInTUCacheEntry &IsBeforeInTUCache = - getInBeforeInTUCache(LOffs.first, ROffs.first); + getInBeforeInTUCache(LOffs.first, ROffs.first); // If we are comparing a source location with multiple locations in the same // file, we get a big win by caching the result. if (IsBeforeInTUCache.isCacheValid(LOffs.first, ROffs.first)) - return IsBeforeInTUCache.getCachedResult(LOffs.second, ROffs.second); + return std::make_pair( + true, 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, - /*isLFIDBeforeRFID=*/LOffs.first.ID < ROffs.first.ID); + /*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 @@ -2082,7 +2127,7 @@ // quit early. The other way round unfortunately remains suboptimal. } while (LOffs.first != ROffs.first && !MoveUpIncludeHierarchy(LOffs, *this)); LocSet::iterator I; - while((I = LChain.find(ROffs.first)) == LChain.end()) { + while ((I = LChain.find(ROffs.first)) == LChain.end()) { if (MoveUpIncludeHierarchy(ROffs, *this)) break; // Met at topmost file. } @@ -2093,44 +2138,12 @@ // locations within the common file and cache them. if (LOffs.first == ROffs.first) { IsBeforeInTUCache.setCommonLoc(LOffs.first, LOffs.second, ROffs.second); - return IsBeforeInTUCache.getCachedResult(LOffs.second, ROffs.second); + return std::make_pair( + true, IsBeforeInTUCache.getCachedResult(LOffs.second, ROffs.second)); } - - // If we arrived here, the location is either in a built-ins buffer or - // associated with global inline asm. PR5662 and PR22576 are examples. - // Clear the lookup cache, it depends on a common location. IsBeforeInTUCache.clear(); - StringRef LB = getBuffer(LOffs.first)->getBufferIdentifier(); - StringRef RB = getBuffer(ROffs.first)->getBufferIdentifier(); - bool LIsBuiltins = LB == "<built-in>"; - bool RIsBuiltins = RB == "<built-in>"; - // Sort built-in before non-built-in. - if (LIsBuiltins || RIsBuiltins) { - if (LIsBuiltins != RIsBuiltins) - return LIsBuiltins; - // Both are in built-in buffers, but from different files. We just claim that - // lower IDs come first. - return LOffs.first < ROffs.first; - } - bool LIsAsm = LB == "<inline asm>"; - bool RIsAsm = RB == "<inline asm>"; - // Sort assembler after built-ins, but before the rest. - if (LIsAsm || RIsAsm) { - if (LIsAsm != RIsAsm) - return RIsAsm; - assert(LOffs.first == ROffs.first); - return false; - } - bool LIsScratch = LB == "<scratch space>"; - bool RIsScratch = RB == "<scratch space>"; - // Sort scratch after inline asm, but before the rest. - if (LIsScratch || RIsScratch) { - if (LIsScratch != RIsScratch) - return LIsScratch; - return LOffs.second < ROffs.second; - } - llvm_unreachable("Unsortable locations found"); + return std::make_pair(false, false); } void SourceManager::PrintStats() const { Index: include/clang/Basic/SourceManager.h =================================================================== --- include/clang/Basic/SourceManager.h +++ include/clang/Basic/SourceManager.h @@ -1474,6 +1474,17 @@ /// \returns true if LHS source location comes before RHS, false otherwise. bool isBeforeInTranslationUnit(SourceLocation LHS, SourceLocation RHS) const; + /// \brief Determines whether the two decomposed source location is in the + /// same translation unit. As a byproduct, it also calculates the order + /// of the source locations in case they are in the same TU. + /// + /// \returns Pair of bools the first component is true if the two locations + /// are in the same TU. The second bool is true if the first is true + /// and \p LOffs is before \p ROffs. + std::pair<bool, bool> + isInTheSameTranslationUnit(std::pair<FileID, unsigned> &LOffs, + std::pair<FileID, unsigned> &ROffs) const; + /// \brief Determines the order of 2 source locations in the "source location /// address space". bool isBeforeInSLocAddrSpace(SourceLocation LHS, SourceLocation RHS) const {
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits