diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2013-04-08 18:45:10 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2013-04-08 18:45:10 +0000 | 
| commit | 809500fc2c13c8173a16b052304d983864e4a1e1 (patch) | |
| tree | 4fc2f184c499d106f29a386c452b49e5197bf63d /lib/Basic/SourceManager.cpp | |
| parent | be7c9ec198dcdb5bf73a35bfbb00b3333cb87909 (diff) | |
Notes
Diffstat (limited to 'lib/Basic/SourceManager.cpp')
| -rw-r--r-- | lib/Basic/SourceManager.cpp | 90 | 
1 files changed, 70 insertions, 20 deletions
diff --git a/lib/Basic/SourceManager.cpp b/lib/Basic/SourceManager.cpp index cd0284a18e5de..1b8383bc42612 100644 --- a/lib/Basic/SourceManager.cpp +++ b/lib/Basic/SourceManager.cpp @@ -12,20 +12,20 @@  //===----------------------------------------------------------------------===//  #include "clang/Basic/SourceManager.h" -#include "clang/Basic/SourceManagerInternals.h"  #include "clang/Basic/Diagnostic.h"  #include "clang/Basic/FileManager.h" -#include "llvm/ADT/StringSwitch.h" +#include "clang/Basic/SourceManagerInternals.h"  #include "llvm/ADT/Optional.h"  #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringSwitch.h" +#include "llvm/Support/Capacity.h"  #include "llvm/Support/Compiler.h"  #include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/raw_ostream.h"  #include "llvm/Support/Path.h" -#include "llvm/Support/Capacity.h" +#include "llvm/Support/raw_ostream.h"  #include <algorithm> -#include <string>  #include <cstring> +#include <string>  #include <sys/stat.h>  using namespace clang; @@ -721,7 +721,7 @@ FileID SourceManager::getFileIDLocal(unsigned SLocOffset) const {    // See if this is near the file point - worst case we start scanning from the    // most newly created FileID. -  std::vector<SrcMgr::SLocEntry>::const_iterator I; +  const SrcMgr::SLocEntry *I;    if (LastFileIDLookup.ID < 0 ||        LocalSLocEntryTable[LastFileIDLookup.ID].getOffset() < SLocOffset) { @@ -840,10 +840,17 @@ FileID SourceManager::getFileIDLoaded(unsigned SLocOffset) const {      ++NumProbes;      unsigned MiddleIndex = (LessIndex - GreaterIndex) / 2 + GreaterIndex;      const SrcMgr::SLocEntry &E = getLoadedSLocEntry(MiddleIndex); +    if (E.getOffset() == 0) +      return FileID(); // invalid entry.      ++NumProbes;      if (E.getOffset() > SLocOffset) { +      // Sanity checking, otherwise a bug may lead to hanging in release build. +      if (GreaterIndex == MiddleIndex) { +        assert(0 && "binary search missed the entry"); +        return FileID(); +      }        GreaterIndex = MiddleIndex;        continue;      } @@ -856,6 +863,11 @@ FileID SourceManager::getFileIDLoaded(unsigned SLocOffset) const {        return Res;      } +    // Sanity checking, otherwise a bug may lead to hanging in release build. +    if (LessIndex == MiddleIndex) { +      assert(0 && "binary search missed the entry"); +      return FileID(); +    }      LessIndex = MiddleIndex;    }  } @@ -974,11 +986,18 @@ bool SourceManager::isMacroArgExpansion(SourceLocation Loc) const {    if (!Loc.isMacroID()) return false;    FileID FID = getFileID(Loc); -  const SrcMgr::SLocEntry *E = &getSLocEntry(FID); -  const SrcMgr::ExpansionInfo &Expansion = E->getExpansion(); +  const SrcMgr::ExpansionInfo &Expansion = getSLocEntry(FID).getExpansion();    return Expansion.isMacroArgExpansion();  } +bool SourceManager::isMacroBodyExpansion(SourceLocation Loc) const { +  if (!Loc.isMacroID()) return false; + +  FileID FID = getFileID(Loc); +  const SrcMgr::ExpansionInfo &Expansion = getSLocEntry(FID).getExpansion(); +  return Expansion.isMacroBodyExpansion(); +} +  //===----------------------------------------------------------------------===//  // Queries about the code at a SourceLocation. @@ -1032,7 +1051,8 @@ unsigned SourceManager::getColumnNumber(FileID FID, unsigned FilePos,    // See if we just calculated the line number for this FilePos and can use    // that to lookup the start of the line instead of searching for it.    if (LastLineNoFileIDQuery == FID && -      LastLineNoContentCache->SourceLineCache != 0) { +      LastLineNoContentCache->SourceLineCache != 0 && +      LastLineNoResult < LastLineNoContentCache->NumLines) {      unsigned *SourceLineCache = LastLineNoContentCache->SourceLineCache;      unsigned LineStart = SourceLineCache[LastLineNoResult - 1];      unsigned LineEnd = SourceLineCache[LastLineNoResult]; @@ -1361,7 +1381,8 @@ const char *SourceManager::getBufferName(SourceLocation Loc,  ///  /// Note that a presumed location is always given as the expansion point of an  /// expansion location, not at the spelling location. -PresumedLoc SourceManager::getPresumedLoc(SourceLocation Loc) const { +PresumedLoc SourceManager::getPresumedLoc(SourceLocation Loc, +                                          bool UseLineDirectives) const {    if (Loc.isInvalid()) return PresumedLoc();    // Presumed locations are always for expansion points. @@ -1395,7 +1416,7 @@ PresumedLoc SourceManager::getPresumedLoc(SourceLocation Loc) const {    // If we have #line directives in this file, update and overwrite the physical    // location info if appropriate. -  if (FI.hasLineDirectives()) { +  if (UseLineDirectives && FI.hasLineDirectives()) {      assert(LineTable && "Can't have linetable entries without a LineTable!");      // See if there is a #line directive before this.  If so, get it.      if (const LineEntry *Entry = @@ -1451,13 +1472,13 @@ unsigned SourceManager::getFileIDSize(FileID FID) const {  ///  /// This routine involves a system call, and therefore should only be used  /// in non-performance-critical code. -static llvm::Optional<ino_t> getActualFileInode(const FileEntry *File) { +static Optional<ino_t> getActualFileInode(const FileEntry *File) {    if (!File) -    return llvm::Optional<ino_t>(); +    return None;    struct stat StatBuf;    if (::stat(File->getName(), &StatBuf)) -    return llvm::Optional<ino_t>(); +    return None;    return StatBuf.st_ino;  } @@ -1488,8 +1509,8 @@ FileID SourceManager::translateFile(const FileEntry *SourceFile) const {    // First, check the main file ID, since it is common to look for a    // location in the main file. -  llvm::Optional<ino_t> SourceFileInode; -  llvm::Optional<StringRef> SourceFileName; +  Optional<ino_t> SourceFileInode; +  Optional<StringRef> SourceFileName;    if (!MainFileID.isInvalid()) {      bool Invalid = false;      const SLocEntry &MainSLoc = getSLocEntry(MainFileID, &Invalid); @@ -1511,8 +1532,7 @@ FileID SourceManager::translateFile(const FileEntry *SourceFile) const {          if (*SourceFileName == llvm::sys::path::filename(MainFile->getName())) {            SourceFileInode = getActualFileInode(SourceFile);            if (SourceFileInode) { -            if (llvm::Optional<ino_t> MainFileInode  -                                               = getActualFileInode(MainFile)) { +            if (Optional<ino_t> MainFileInode = getActualFileInode(MainFile)) {                if (*SourceFileInode == *MainFileInode) {                  FirstFID = MainFileID;                  SourceFile = MainFile; @@ -1576,7 +1596,7 @@ FileID SourceManager::translateFile(const FileEntry *SourceFile) const {        const FileEntry *Entry =FileContentCache? FileContentCache->OrigEntry : 0;          if (Entry &&               *SourceFileName == llvm::sys::path::filename(Entry->getName())) { -          if (llvm::Optional<ino_t> EntryInode = getActualFileInode(Entry)) { +          if (Optional<ino_t> EntryInode = getActualFileInode(Entry)) {              if (*SourceFileInode == *EntryInode) {                FirstFID = FileID::get(I);                SourceFile = Entry; @@ -1847,7 +1867,32 @@ static bool MoveUpIncludeHierarchy(std::pair<FileID, unsigned> &Loc,    Loc = SM.getDecomposedLoc(UpperLoc);    return false;  } -   + +/// Return the cache entry for comparing the given file IDs +/// for isBeforeInTranslationUnit. +InBeforeInTUCacheEntry &SourceManager::getInBeforeInTUCache(FileID LFID, +                                                            FileID RFID) const { +  // This is a magic number for limiting the cache size.  It was experimentally +  // derived from a small Objective-C project (where the cache filled +  // out to ~250 items).  We can make it larger if necessary. +  enum { MagicCacheSize = 300 }; +  IsBeforeInTUCacheKey Key(LFID, RFID); + +  // If the cache size isn't too large, do a lookup and if necessary default +  // construct an entry.  We can then return it to the caller for direct +  // use.  When they update the value, the cache will get automatically +  // updated as well. +  if (IBTUCache.size() < MagicCacheSize) +    return IBTUCache[Key]; + +  // Otherwise, do a lookup that will not construct a new value. +  InBeforeInTUCache::iterator I = IBTUCache.find(Key); +  if (I != IBTUCache.end()) +    return I->second; + +  // Fall back to the overflow value. +  return IBTUCacheOverflow; +}  /// \brief Determines the order of 2 source locations in the translation unit.  /// @@ -1867,6 +1912,11 @@ bool SourceManager::isBeforeInTranslationUnit(SourceLocation LHS,    // 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); + +  // 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);  | 
