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.h217
1 files changed, 99 insertions, 118 deletions
diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h
index 741ca16913..042dda9b67 100644
--- a/include/clang/Basic/SourceManager.h
+++ b/include/clang/Basic/SourceManager.h
@@ -75,69 +75,50 @@ namespace SrcMgr {
/// from MacroTokenFileID.
///
struct FileIDInfo {
- enum FileIDType {
- NormalBuffer,
- MacroExpansion
- };
-
- /// The type of this FileID.
- FileIDType IDType;
-
+ private:
/// IncludeLoc - The location of the #include that brought in this file.
- /// This SourceLocation object has a FileId of 0 for the main file.
+ /// This SourceLocation object has an invalid SLOC for the main file.
SourceLocation IncludeLoc;
- /// This union is discriminated by IDType.
+ /// ChunkNo - Really large buffers are broken up into chunks that are
+ /// each (1 << SourceLocation::FilePosBits) in size. This specifies the
+ /// chunk number of this FileID.
+ unsigned ChunkNo;
+
+ /// FileInfo - Information about the source buffer itself.
///
- union {
- struct NormalBufferInfo {
- /// ChunkNo - Really large buffers are broken up into chunks that are
- /// each (1 << SourceLocation::FilePosBits) in size. This specifies the
- /// chunk number of this FileID.
- unsigned ChunkNo;
-
- /// FileInfo - Information about the source buffer itself.
- ///
- const InfoRec *Info;
- } NormalBuffer;
-
- /// MacroTokenFileID - This is the File ID that contains the characters
- /// that make up the expanded token.
- unsigned MacroTokenFileID;
- } u;
+ const InfoRec *Info;
+ public:
- /// getNormalBuffer - Return a FileIDInfo object for a normal buffer
- /// reference.
- static FileIDInfo getNormalBuffer(SourceLocation IL, unsigned CN,
- const InfoRec *Inf) {
+ /// get - Return a FileIDInfo object.
+ static FileIDInfo get(SourceLocation IL, unsigned CN, const InfoRec *Inf) {
FileIDInfo X;
- X.IDType = NormalBuffer;
X.IncludeLoc = IL;
- X.u.NormalBuffer.ChunkNo = CN;
- X.u.NormalBuffer.Info = Inf;
+ X.ChunkNo = CN;
+ X.Info = Inf;
return X;
}
- /// getMacroExpansion - Return a FileID for a macro expansion. IL specifies
- /// the instantiation location, and MacroFID specifies the FileID that the
- /// token's characters come from.
- static FileIDInfo getMacroExpansion(SourceLocation IL,
- unsigned MacroFID) {
- FileIDInfo X;
- X.IDType = MacroExpansion;
- X.IncludeLoc = IL;
- X.u.MacroTokenFileID = MacroFID;
- return X;
- }
+ SourceLocation getIncludeLoc() const { return IncludeLoc; }
+ unsigned getChunkNo() const { return ChunkNo; }
+ const InfoRec *getInfo() const { return Info; }
+ };
+
+ class MacroIDInfo {
+ SourceLocation InstantiationLoc, PhysicalLoc;
+ public:
+ SourceLocation getInstantiationLoc() const { return InstantiationLoc; }
+ SourceLocation getPhysicalLoc() const { return PhysicalLoc; }
- unsigned getNormalBufferChunkNo() const {
- assert(IDType == NormalBuffer && "Not a normal buffer!");
- return u.NormalBuffer.ChunkNo;
- }
-
- const InfoRec *getNormalBufferInfo() const {
- assert(IDType == NormalBuffer && "Not a normal buffer!");
- return u.NormalBuffer.Info;
+ /// get - Return a MacroID for a macro expansion. IL specifies
+ /// the instantiation location, and PL specifies the physical location
+ /// (where the characters from the token come from). Both IL and PL refer
+ /// to normal File SLocs.
+ static MacroIDInfo get(SourceLocation IL, SourceLocation PL) {
+ MacroIDInfo X;
+ X.InstantiationLoc = IL;
+ X.PhysicalLoc = PL;
+ return X;
}
};
} // end SrcMgr namespace.
@@ -169,6 +150,9 @@ class SourceManager {
/// entries are off by one.
std::vector<SrcMgr::FileIDInfo> FileIDs;
+ /// MacroIDs - Information about each MacroID.
+ std::vector<SrcMgr::MacroIDInfo> MacroIDs;
+
/// LastInstantiationLoc_* - Cache the last instantiation request for fast
/// lookup. Macros often want many tokens instantated at the same location.
SourceLocation LastInstantiationLoc_InstantLoc;
@@ -206,82 +190,76 @@ public:
}
/// getIncludeLoc - Return the location of the #include for the specified
- /// FileID.
- SourceLocation getIncludeLoc(unsigned FileID) const;
-
- /// getFilePos - This (efficient) method returns the offset from the start of
- /// the file that the specified SourceLocation represents. This returns the
- /// location of the physical character data, not the logical file position.
- unsigned getFilePos(SourceLocation Loc) const {
- const SrcMgr::FileIDInfo *FIDInfo = getFIDInfo(Loc.getFileID());
-
- // For Macros, the physical loc is specified by the MacroTokenFileID.
- if (FIDInfo->IDType == SrcMgr::FileIDInfo::MacroExpansion)
- FIDInfo = &FileIDs[FIDInfo->u.MacroTokenFileID-1];
-
- // If this file has been split up into chunks, factor in the chunk number
- // that the FileID references.
- unsigned ChunkNo = FIDInfo->getNormalBufferChunkNo();
- return Loc.getRawFilePos() + (ChunkNo << SourceLocation::FilePosBits);
+ /// SourceLocation. If this is a macro expansion, this transparently figures
+ /// out which file includes the file being expanded into.
+ SourceLocation getIncludeLoc(SourceLocation ID) const {
+ return getFIDInfo(getLogicalLoc(ID).getFileID())->getIncludeLoc();
}
/// getCharacterData - Return a pointer to the start of the specified location
/// in the appropriate MemoryBuffer.
const char *getCharacterData(SourceLocation SL) const;
- /// getColumnNumber - Return the column # for the specified include position.
- /// this is significantly cheaper to compute than the line number. This
- /// returns zero if the column number isn't known.
+ /// getColumnNumber - Return the column # for the specified file position.
+ /// This is significantly cheaper to compute than the line number. This
+ /// returns zero if the column number isn't known. This may only be called on
+ /// a file sloc, so you must choose a physical or logical location before
+ /// calling this method.
unsigned getColumnNumber(SourceLocation Loc) const;
+ unsigned getPhysicalColumnNumber(SourceLocation Loc) const {
+ return getColumnNumber(getPhysicalLoc(Loc));
+ }
+ unsigned getLogicalColumnNumber(SourceLocation Loc) const {
+ return getColumnNumber(getLogicalLoc(Loc));
+ }
+
+
/// getLineNumber - Given a SourceLocation, return the physical line number
/// for the position indicated. This requires building and caching a table of
/// line offsets for the MemoryBuffer, so this is not cheap: use only when
/// about to emit a diagnostic.
unsigned getLineNumber(SourceLocation Loc);
+
+ unsigned getLogicalLineNumber(SourceLocation Loc) {
+ return getLineNumber(getLogicalLoc(Loc));
+ }
+ unsigned getPhysicalLineNumber(SourceLocation Loc) {
+ return getLineNumber(getPhysicalLoc(Loc));
+ }
- /// getSourceFilePos - This method returns the *logical* offset from the start
- /// of the file that the specified SourceLocation represents. This returns
- /// the location of the *logical* character data, not the physical file
- /// position. In the case of macros, for example, this returns where the
- /// macro was instantiated, not where the characters for the macro can be
- /// found.
- unsigned getSourceFilePos(SourceLocation Loc) const;
-
/// getSourceName - This method returns the name of the file or buffer that
/// the SourceLocation specifies. This can be modified with #line directives,
/// etc.
std::string getSourceName(SourceLocation Loc);
- /// getFileEntryForFileID - Return the FileEntry record for the specified
- /// FileID if one exists.
- const FileEntry *getFileEntryForFileID(unsigned FileID) const {
- assert(FileID-1 < FileIDs.size() && "Invalid FileID!");
- return FileIDs[FileID-1].getNormalBufferInfo()->first;
- }
-
/// Given a SourceLocation object, return the logical location referenced by
/// the ID. This logical location is subject to #line directives, etc.
SourceLocation getLogicalLoc(SourceLocation Loc) const {
- if (Loc.getFileID() == 0) return Loc;
-
- const SrcMgr::FileIDInfo *FIDInfo = getFIDInfo(Loc.getFileID());
- if (FIDInfo->IDType == SrcMgr::FileIDInfo::MacroExpansion)
- return FIDInfo->IncludeLoc;
- return Loc;
+ // File locations are both physical and logical.
+ if (Loc.isFileID()) return Loc;
+
+ SourceLocation ILoc = MacroIDs[Loc.getMacroID()].getInstantiationLoc();
+ return ILoc.getFileLocWithOffset(Loc.getMacroLogOffs());
}
/// getPhysicalLoc - Given a SourceLocation object, return the physical
/// location referenced by the ID.
SourceLocation getPhysicalLoc(SourceLocation Loc) const {
- if (Loc.getFileID() == 0) return Loc;
+ // File locations are both physical and logical.
+ if (Loc.isFileID()) return Loc;
- // For Macros, the physical loc is specified by the MacroTokenFileID.
- const SrcMgr::FileIDInfo *FIDInfo = getFIDInfo(Loc.getFileID());
- if (FIDInfo->IDType == SrcMgr::FileIDInfo::MacroExpansion)
- return SourceLocation(FIDInfo->u.MacroTokenFileID,
- Loc.getRawFilePos());
- return Loc;
+ SourceLocation ILoc = MacroIDs[Loc.getMacroID()].getPhysicalLoc();
+ return ILoc.getFileLocWithOffset(Loc.getMacroPhysOffs());
+ }
+
+ /// getFileEntryForLoc - Return the FileEntry record for the physloc of the
+ /// specified SourceLocation, if one exists.
+ const FileEntry *getFileEntryForLoc(SourceLocation Loc) const {
+ Loc = getPhysicalLoc(Loc);
+ unsigned FileID = Loc.getFileID();
+ assert(FileID-1 < FileIDs.size() && "Invalid FileID!");
+ return FileIDs[FileID-1].getInfo()->first;
}
/// PrintStats - Print statistics to stderr.
@@ -305,33 +283,36 @@ private:
assert(FileID-1 < FileIDs.size() && "Invalid FileID!");
return &FileIDs[FileID-1];
}
-
- /// Return the InfoRec structure for the specified FileID. This is always the
- /// physical reference for the ID.
- const SrcMgr::InfoRec *getInfoRec(const SrcMgr::FileIDInfo *FIDInfo) const {
- // For Macros, the physical loc is specified by the MacroTokenFileID.
- if (FIDInfo->IDType == SrcMgr::FileIDInfo::MacroExpansion)
- FIDInfo = &FileIDs[FIDInfo->u.MacroTokenFileID-1];
- return FIDInfo->getNormalBufferInfo();
- }
+
const SrcMgr::InfoRec *getInfoRec(unsigned FileID) const {
return getInfoRec(getFIDInfo(FileID));
}
- SrcMgr::FileInfo *getFileInfo(const SrcMgr::FileIDInfo *FIDInfo) const {
- if (const SrcMgr::InfoRec *IR = getInfoRec(FIDInfo))
- return const_cast<SrcMgr::FileInfo *>(&IR->second);
- return 0;
- }
SrcMgr::FileInfo *getFileInfo(unsigned FileID) const {
if (const SrcMgr::InfoRec *IR = getInfoRec(FileID))
return const_cast<SrcMgr::FileInfo *>(&IR->second);
return 0;
}
- SrcMgr::FileInfo *getFileInfo(const FileEntry *SourceFile) {
- if (const SrcMgr::InfoRec *IR = getInfoRec(SourceFile))
- return const_cast<SrcMgr::FileInfo *>(&IR->second);
- return 0;
+
+ /// Return the InfoRec structure for the specified FileID. This is always the
+ /// physical reference for the ID.
+ const SrcMgr::InfoRec *getInfoRec(const SrcMgr::FileIDInfo *FIDInfo) const {
+ return FIDInfo->getInfo();
+ }
+
+
+ /// getFullFilePos - This (efficient) method returns the offset from the start
+ /// of the file that the specified physical SourceLocation represents. This
+ /// returns the location of the physical character data, not the logical file
+ /// position.
+ unsigned getFullFilePos(SourceLocation PhysLoc) const {
+ // TODO: Add a flag "is first chunk" to SLOC.
+ const SrcMgr::FileIDInfo *FIDInfo = getFIDInfo(PhysLoc.getFileID());
+
+ // If this file has been split up into chunks, factor in the chunk number
+ // that the FileID references.
+ unsigned ChunkNo = FIDInfo->getChunkNo();
+ return PhysLoc.getRawFilePos() + (ChunkNo << SourceLocation::FilePosBits);
}
};