]> granicus.if.org Git - clang/commitdiff
Introduce SourceManager::getDecomposedIncludedLoc, that returns the "included/expande...
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Sat, 13 Apr 2013 01:03:57 +0000 (01:03 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Sat, 13 Apr 2013 01:03:57 +0000 (01:03 +0000)
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

include/clang/Basic/SourceManager.h
lib/Basic/SourceManager.cpp

index 00c96c3da0d0fc28a85b531a0555d58891282e08..f82b196929a39f65c85305195b20d109d011206c 100644 (file)
@@ -646,6 +646,13 @@ class SourceManager : public RefCountedBase<SourceManager> {
   // 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<FileID, std::pair<FileID, unsigned> > IncludedLocMap;
+
   /// The key value into the IsBeforeInTUCache table.
   typedef std::pair<FileID, FileID> IsBeforeInTUCacheKey;
 
@@ -1127,6 +1134,10 @@ public:
     return getDecomposedSpellingLocSlowCase(E, Offset);
   }
 
+  /// \brief Returns the "included/expanded in" decomposed location of the given
+  /// FileID.
+  std::pair<FileID, unsigned> getDecomposedIncludedLoc(FileID FID) const;
+
   /// \brief Returns the offset from the start of the file that the
   /// specified SourceLocation represents.
   ///
index 1b8383bc426128546ba83bf986e3c8415f9bfde1..d6dc6d6328af2a342a4b254d11c093ecfa9fd367 100644 (file)
@@ -1848,23 +1848,42 @@ SourceManager::getMacroArgExpandedLocation(SourceLocation Loc) const {
   return Loc;
 }
 
+std::pair<FileID, unsigned>
+SourceManager::getDecomposedIncludedLoc(FileID FID) const {
+  // Uses IncludedLocMap to retrieve/cache the decomposed loc.
+
+  typedef std::pair<FileID, unsigned> DecompTy;
+  typedef llvm::DenseMap<FileID, DecompTy> MapTy;
+  std::pair<MapTy::iterator, bool>
+    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<FileID, unsigned> &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<FileID, unsigned> 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<FileID, unsigned> LocSet;
+  typedef llvm::SmallDenseMap<FileID, unsigned, 16> LocSet;
   LocSet LChain;
   do {
     LChain.insert(LOffs);