aboutsummaryrefslogtreecommitdiff
path: root/include/clang/Basic/SourceManager.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/Basic/SourceManager.h')
-rw-r--r--include/clang/Basic/SourceManager.h61
1 files changed, 57 insertions, 4 deletions
diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h
index beff66e675..1cc02df802 100644
--- a/include/clang/Basic/SourceManager.h
+++ b/include/clang/Basic/SourceManager.h
@@ -23,6 +23,7 @@
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/MemoryBuffer.h"
+#include <map>
#include <vector>
#include <cassert>
@@ -34,6 +35,8 @@ class FileManager;
class FileEntry;
class LineTableInfo;
class LangOptions;
+class ASTWriter;
+class ASTReader;
/// SrcMgr - Public enums and private classes that are part of the
/// SourceManager implementation.
@@ -85,6 +88,11 @@ namespace SrcMgr {
/// if SourceLineCache is non-null.
unsigned NumLines;
+ /// \brief Lazily computed map of macro argument chunks to their expanded
+ /// source location.
+ typedef std::map<unsigned, SourceLocation> MacroArgsMap;
+ MacroArgsMap *MacroArgsCache;
+
/// getBuffer - Returns the memory buffer for the associated content.
///
/// \param Diag Object through which diagnostics will be emitted if the
@@ -142,11 +150,11 @@ namespace SrcMgr {
ContentCache(const FileEntry *Ent = 0)
: Buffer(0, false), OrigEntry(Ent), ContentsEntry(Ent),
- SourceLineCache(0), NumLines(0) {}
+ SourceLineCache(0), NumLines(0), MacroArgsCache(0) {}
ContentCache(const FileEntry *Ent, const FileEntry *contentEnt)
: Buffer(0, false), OrigEntry(Ent), ContentsEntry(contentEnt),
- SourceLineCache(0), NumLines(0) {}
+ SourceLineCache(0), NumLines(0), MacroArgsCache(0) {}
~ContentCache();
@@ -154,12 +162,13 @@ namespace SrcMgr {
/// a non-NULL Buffer or SourceLineCache. Ownership of allocated memory
/// is not transferred, so this is a logical error.
ContentCache(const ContentCache &RHS)
- : Buffer(0, false), SourceLineCache(0)
+ : Buffer(0, false), SourceLineCache(0), MacroArgsCache(0)
{
OrigEntry = RHS.OrigEntry;
ContentsEntry = RHS.ContentsEntry;
- assert (RHS.Buffer.getPointer() == 0 && RHS.SourceLineCache == 0
+ assert (RHS.Buffer.getPointer() == 0 && RHS.SourceLineCache == 0 &&
+ RHS.MacroArgsCache == 0
&& "Passed ContentCache object cannot own a buffer.");
NumLines = RHS.NumLines;
@@ -184,16 +193,26 @@ namespace SrcMgr {
/// This is an invalid SLOC for the main file (top of the #include chain).
unsigned IncludeLoc; // Really a SourceLocation
+ /// \brief Number of FileIDs (files and macros) that were created during
+ /// preprocessing of this #include, including this SLocEntry.
+ /// Zero means the preprocessor didn't provide such info for this SLocEntry.
+ unsigned NumCreatedFIDs;
+
/// Data - This contains the ContentCache* and the bits indicating the
/// characteristic of the file and whether it has #line info, all bitmangled
/// together.
uintptr_t Data;
+
+ friend class SourceManager;
+ friend class ASTWriter;
+ friend class ASTReader;
public:
/// get - Return a FileInfo object.
static FileInfo get(SourceLocation IL, const ContentCache *Con,
CharacteristicKind FileCharacter) {
FileInfo X;
X.IncludeLoc = IL.getRawEncoding();
+ X.NumCreatedFIDs = 0;
X.Data = (uintptr_t)Con;
assert((X.Data & 7) == 0 &&"ContentCache pointer insufficiently aligned");
assert((unsigned)FileCharacter < 4 && "invalid file character");
@@ -711,6 +730,28 @@ public:
/// \param Invalid If non-NULL, will be set true if an error occurred.
StringRef getBufferData(FileID FID, bool *Invalid = 0) const;
+ /// \brief Get the number of FileIDs (files and macros) that were created
+ /// during preprocessing of \arg FID, including it.
+ unsigned getNumCreatedFIDsForFileID(FileID FID) const {
+ bool Invalid = false;
+ const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &Invalid);
+ if (Invalid || !Entry.isFile())
+ return 0;
+
+ return Entry.getFile().NumCreatedFIDs;
+ }
+
+ /// \brief Set the number of FileIDs (files and macros) that were created
+ /// during preprocessing of \arg FID, including it.
+ void setNumCreatedFIDsForFileID(FileID FID, unsigned NumFIDs) const {
+ bool Invalid = false;
+ const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &Invalid);
+ if (Invalid || !Entry.isFile())
+ return;
+
+ assert(Entry.getFile().NumCreatedFIDs == 0 && "Already set!");
+ const_cast<SrcMgr::FileInfo &>(Entry.getFile()).NumCreatedFIDs = NumFIDs;
+ }
//===--------------------------------------------------------------------===//
// SourceLocation manipulation methods.
@@ -743,6 +784,17 @@ public:
return SourceLocation::getFileLoc(FileOffset);
}
+ /// \brief Returns the include location if \arg FID is a #include'd file
+ /// otherwise it returns an invalid location.
+ SourceLocation getIncludeLoc(FileID FID) const {
+ bool Invalid = false;
+ const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &Invalid);
+ if (Invalid || !Entry.isFile())
+ return SourceLocation();
+
+ return Entry.getFile().getIncludeLoc();
+ }
+
/// getExpansionLoc - Given a SourceLocation object, return the expansion
/// location referenced by the ID.
SourceLocation getExpansionLoc(SourceLocation Loc) const {
@@ -1205,6 +1257,7 @@ private:
std::pair<FileID, unsigned>
getDecomposedSpellingLocSlowCase(const SrcMgr::SLocEntry *E,
unsigned Offset) const;
+ void computeMacroArgsCache(SrcMgr::ContentCache *Content, FileID FID);
};