From: Argyrios Kyrtzidis Date: Sat, 13 Apr 2013 01:03:57 +0000 (+0000) Subject: Introduce SourceManager::getDecomposedIncludedLoc, that returns the "included/expande... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ecc65238c98ba21d08763da7b7972d617677e908;p=clang Introduce SourceManager::getDecomposedIncludedLoc, that returns the "included/expanded in" decomposed location of the given FileID. The main benefit is to speed-up SourceManager::isBeforeInTranslationUnit which is common to query the included/expanded location of the same FileID multiple times. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179435 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h index 00c96c3da0..f82b196929 100644 --- a/include/clang/Basic/SourceManager.h +++ b/include/clang/Basic/SourceManager.h @@ -646,6 +646,13 @@ class SourceManager : public RefCountedBase { // Statistics for -print-stats. mutable unsigned NumLinearScans, NumBinaryProbes; + /// \brief Associates a FileID with its "included/expanded in" decomposed + /// location. + /// + /// Used to cache results from and speed-up \c getDecomposedIncludedLoc + /// function. + mutable llvm::DenseMap > IncludedLocMap; + /// The key value into the IsBeforeInTUCache table. typedef std::pair IsBeforeInTUCacheKey; @@ -1127,6 +1134,10 @@ public: return getDecomposedSpellingLocSlowCase(E, Offset); } + /// \brief Returns the "included/expanded in" decomposed location of the given + /// FileID. + std::pair getDecomposedIncludedLoc(FileID FID) const; + /// \brief Returns the offset from the start of the file that the /// specified SourceLocation represents. /// diff --git a/lib/Basic/SourceManager.cpp b/lib/Basic/SourceManager.cpp index 1b8383bc42..d6dc6d6328 100644 --- a/lib/Basic/SourceManager.cpp +++ b/lib/Basic/SourceManager.cpp @@ -1848,23 +1848,42 @@ SourceManager::getMacroArgExpandedLocation(SourceLocation Loc) const { return Loc; } +std::pair +SourceManager::getDecomposedIncludedLoc(FileID FID) const { + // Uses IncludedLocMap to retrieve/cache the decomposed loc. + + typedef std::pair DecompTy; + typedef llvm::DenseMap MapTy; + std::pair + InsertOp = IncludedLocMap.insert(std::make_pair(FID, DecompTy())); + DecompTy &DecompLoc = InsertOp.first->second; + if (!InsertOp.second) + return DecompLoc; // already in map. + + SourceLocation UpperLoc; + const SrcMgr::SLocEntry &Entry = getSLocEntry(FID); + if (Entry.isExpansion()) + UpperLoc = Entry.getExpansion().getExpansionLocStart(); + else + UpperLoc = Entry.getFile().getIncludeLoc(); + + if (UpperLoc.isValid()) + DecompLoc = getDecomposedLoc(UpperLoc); + + return DecompLoc; +} + /// Given a decomposed source location, move it up the include/expansion stack /// to the parent source location. If this is possible, return the decomposed /// version of the parent in Loc and return false. If Loc is the top-level /// entry, return true and don't modify it. static bool MoveUpIncludeHierarchy(std::pair &Loc, const SourceManager &SM) { - SourceLocation UpperLoc; - const SrcMgr::SLocEntry &Entry = SM.getSLocEntry(Loc.first); - if (Entry.isExpansion()) - UpperLoc = Entry.getExpansion().getExpansionLocStart(); - else - UpperLoc = Entry.getFile().getIncludeLoc(); - - if (UpperLoc.isInvalid()) + std::pair UpperLoc = SM.getDecomposedIncludedLoc(Loc.first); + if (UpperLoc.first.isInvalid()) return true; // We reached the top. - - Loc = SM.getDecomposedLoc(UpperLoc); + + Loc = UpperLoc; return false; } @@ -1929,7 +1948,7 @@ bool SourceManager::isBeforeInTranslationUnit(SourceLocation LHS, // of the other looking for a match. // We use a map from FileID to Offset to store the chain. Easier than writing // a custom set hash info that only depends on the first part of a pair. - typedef llvm::DenseMap LocSet; + typedef llvm::SmallDenseMap LocSet; LocSet LChain; do { LChain.insert(LOffs);