aboutsummaryrefslogtreecommitdiff
path: root/include/clang/Basic/SourceManager.h
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2011-07-07 03:40:34 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2011-07-07 03:40:34 +0000
commitb73377eeb3eff76be134203aebb6068244b177f3 (patch)
treecc3730d588dda5839f94c4f45f76fa07d1e0aa88 /include/clang/Basic/SourceManager.h
parent8b86ef0b71900c64c0c2cfca54cac08a203a16a4 (diff)
Make the Preprocessor more memory efficient and improve macro instantiation diagnostics.
When a macro instantiation occurs, reserve a SLocEntry chunk with length the full length of the macro definition source. Set the spelling location of this chunk to point to the start of the macro definition and any tokens that are lexed directly from the macro definition will get a location from this chunk with the appropriate offset. For any tokens that come from argument expansion, '##' paste operator, etc. have their instantiation location point at the appropriate place in the instantiated macro definition (the argument identifier and the '##' token respectively). This improves macro instantiation diagnostics: Before: t.c:5:9: error: invalid operands to binary expression ('struct S' and 'int') int y = M(/); ^~~~ t.c:5:11: note: instantiated from: int y = M(/); ^ After: t.c:5:9: error: invalid operands to binary expression ('struct S' and 'int') int y = M(/); ^~~~ t.c:3:20: note: instantiated from: \#define M(op) (foo op 3); ~~~ ^ ~ t.c:5:11: note: instantiated from: int y = M(/); ^ The memory savings for a candidate boost library that abuses the preprocessor are: - 32% less SLocEntries (37M -> 25M) - 30% reduction in PCH file size (900M -> 635M) - 50% reduction in memory usage for the SLocEntry table (1.6G -> 800M) git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@134587 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang/Basic/SourceManager.h')
-rw-r--r--include/clang/Basic/SourceManager.h53
1 files changed, 51 insertions, 2 deletions
diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h
index 05551e5319..33c66e7f7c 100644
--- a/include/clang/Basic/SourceManager.h
+++ b/include/clang/Basic/SourceManager.h
@@ -36,6 +36,7 @@ class SourceManager;
class FileManager;
class FileEntry;
class LineTableInfo;
+class LangOptions;
/// SrcMgr - Public enums and private classes that are part of the
/// SourceManager implementation.
@@ -833,11 +834,46 @@ public:
/// \brief Returns true if the given MacroID location points at the first
/// token of the macro instantiation.
- bool isAtStartOfMacroInstantiation(SourceLocation Loc) const;
+ bool isAtStartOfMacroInstantiation(SourceLocation Loc,
+ const LangOptions &LangOpts) const;
/// \brief Returns true if the given MacroID location points at the last
/// token of the macro instantiation.
- bool isAtEndOfMacroInstantiation(SourceLocation Loc) const;
+ bool isAtEndOfMacroInstantiation(SourceLocation Loc,
+ const LangOptions &LangOpts) const;
+
+ /// \brief Given a specific chunk of a FileID (FileID with offset+length),
+ /// returns true if \arg Loc is inside that chunk and sets relative offset
+ /// (offset of \arg Loc from beginning of chunk) to \arg relativeOffset.
+ bool isInFileID(SourceLocation Loc,
+ FileID FID, unsigned offset, unsigned length,
+ unsigned *relativeOffset = 0) const {
+ assert(!FID.isInvalid());
+ if (Loc.isInvalid())
+ return false;
+
+ unsigned start = getSLocEntry(FID).getOffset() + offset;
+ unsigned end = start + length;
+
+#ifndef NDEBUG
+ // Make sure offset/length describe a chunk inside the given FileID.
+ unsigned NextOffset;
+ if (FID.ID+1 == SLocEntryTable.size())
+ NextOffset = getNextOffset();
+ else
+ NextOffset = getSLocEntry(FID.ID+1).getOffset();
+ assert(start < NextOffset);
+ assert(end < NextOffset);
+#endif
+
+ if (Loc.getOffset() >= start && Loc.getOffset() < end) {
+ if (relativeOffset)
+ *relativeOffset = Loc.getOffset() - start;
+ return true;
+ }
+
+ return false;
+ }
//===--------------------------------------------------------------------===//
// Line Table Manipulation Routines
@@ -899,6 +935,19 @@ public:
/// \returns true if LHS source location comes before RHS, false otherwise.
bool isBeforeInTranslationUnit(SourceLocation LHS, SourceLocation RHS) const;
+ /// \brief Determines the order of 2 source locations in the "source location
+ /// address space".
+ static bool isBeforeInSourceLocationOffset(SourceLocation LHS,
+ SourceLocation RHS) {
+ return isBeforeInSourceLocationOffset(LHS, RHS.getOffset());
+ }
+
+ /// \brief Determines the order of a source location and a source location
+ /// offset in the "source location address space".
+ static bool isBeforeInSourceLocationOffset(SourceLocation LHS, unsigned RHS) {
+ return LHS.getOffset() < RHS;
+ }
+
// Iterators over FileInfos.
typedef llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*>
::const_iterator fileinfo_iterator;