diff options
author | dim <dim@FreeBSD.org> | 2011-06-12 15:46:16 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2011-06-12 15:46:16 +0000 |
commit | c49018d9cce52d8c9f34b44865ec3ba8e89a1488 (patch) | |
tree | c5e9e10bc189de0058aa763c47b9920a8351b7df /lib/Basic/SourceManager.cpp | |
parent | 110eaaceddcec790f7e6a5e3bf1261c9aa1e73ab (diff) | |
download | FreeBSD-src-c49018d9cce52d8c9f34b44865ec3ba8e89a1488.zip FreeBSD-src-c49018d9cce52d8c9f34b44865ec3ba8e89a1488.tar.gz |
Vendor import of clang trunk r132879:
http://llvm.org/svn/llvm-project/cfe/trunk@132879
Diffstat (limited to 'lib/Basic/SourceManager.cpp')
-rw-r--r-- | lib/Basic/SourceManager.cpp | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/lib/Basic/SourceManager.cpp b/lib/Basic/SourceManager.cpp index c3e0393..2de8ab7 100644 --- a/lib/Basic/SourceManager.cpp +++ b/lib/Basic/SourceManager.cpp @@ -961,6 +961,12 @@ static void ComputeLineNumbers(Diagnostic &Diag, ContentCache *FI, /// about to emit a diagnostic. unsigned SourceManager::getLineNumber(FileID FID, unsigned FilePos, bool *Invalid) const { + if (FID.isInvalid()) { + if (Invalid) + *Invalid = true; + return 1; + } + ContentCache *Content; if (LastLineNoFileIDQuery == FID) Content = LastLineNoContentCache; @@ -1207,6 +1213,73 @@ PresumedLoc SourceManager::getPresumedLoc(SourceLocation Loc) const { return PresumedLoc(Filename, LineNo, ColNo, IncludeLoc); } +/// \brief Returns true if the given MacroID location points at the first +/// token of the macro instantiation. +bool SourceManager::isAtStartOfMacroInstantiation(SourceLocation loc) const { + assert(loc.isValid() && loc.isMacroID() && "Expected a valid macro loc"); + + unsigned FID = getFileID(loc).ID; + assert(FID > 1); + std::pair<SourceLocation, SourceLocation> + instRange = getImmediateInstantiationRange(loc); + + bool invalid = false; + const SrcMgr::SLocEntry &Entry = getSLocEntry(FID-1, &invalid); + if (invalid) + return false; + + // If the FileID immediately before it is a file then this is the first token + // in the macro. + if (Entry.isFile()) + return true; + + // If the FileID immediately before it (which is a macro token) is the + // immediate instantiated macro, check this macro token's location. + if (getFileID(instRange.second).ID == FID-1) + return isAtStartOfMacroInstantiation(instRange.first); + + // If the FileID immediately before it (which is a macro token) came from a + // different instantiation, then this is the first token in the macro. + if (getInstantiationLoc(Entry.getInstantiation().getInstantiationLocStart()) + != getInstantiationLoc(loc)) + return true; + + // It is inside the macro or the last token in the macro. + return false; +} + +/// \brief Returns true if the given MacroID location points at the last +/// token of the macro instantiation. +bool SourceManager::isAtEndOfMacroInstantiation(SourceLocation loc) const { + assert(loc.isValid() && loc.isMacroID() && "Expected a valid macro loc"); + + unsigned FID = getFileID(loc).ID; + assert(FID > 1); + std::pair<SourceLocation, SourceLocation> + instRange = getInstantiationRange(loc); + + // If there's no FileID after it, it is the last token in the macro. + if (FID+1 == sloc_entry_size()) + return true; + + bool invalid = false; + const SrcMgr::SLocEntry &Entry = getSLocEntry(FID+1, &invalid); + if (invalid) + return false; + + // If the FileID immediately after it is a file or a macro token which + // came from a different instantiation, then this is the last token in the + // macro. + if (Entry.isFile()) + return true; + if (getInstantiationLoc(Entry.getInstantiation().getInstantiationLocStart()) + != instRange.first) + return true; + + // It is inside the macro or the first token in the macro. + return false; +} + //===----------------------------------------------------------------------===// // Other miscellaneous methods. //===----------------------------------------------------------------------===// |