[cfe-commits] r38556 - in /cfe/cfe/trunk: Basic/SourceManager.cpp include/clang/Basic/SourceLocation.h include/clang/Basic/SourceManager.h
sabre at cs.uiuc.edu
sabre at cs.uiuc.edu
Wed Jul 11 09:22:35 PDT 2007
Author: sabre
Date: Wed Jul 11 11:22:35 2007
New Revision: 38556
URL: http://llvm.org/viewvc/llvm-project?rev=38556&view=rev
Log:
Modify SourceManager to make way for future macro locations and #line support
no functionality change yet
Modified:
cfe/cfe/trunk/Basic/SourceManager.cpp
cfe/cfe/trunk/include/clang/Basic/SourceLocation.h
cfe/cfe/trunk/include/clang/Basic/SourceManager.h
Modified: cfe/cfe/trunk/Basic/SourceManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Basic/SourceManager.cpp?rev=38556&r1=38555&r2=38556&view=diff
==============================================================================
--- cfe/cfe/trunk/Basic/SourceManager.cpp (original)
+++ cfe/cfe/trunk/Basic/SourceManager.cpp Wed Jul 11 11:22:35 2007
@@ -19,6 +19,7 @@
#include <iostream>
using namespace llvm;
using namespace clang;
+using namespace SrcMgr;
SourceManager::~SourceManager() {
for (std::map<const FileEntry *, FileInfo>::iterator I = FileInfos.begin(),
@@ -36,7 +37,7 @@
/// getFileInfo - Create or return a cached FileInfo for the specified file.
///
-const SourceManager::InfoRec *
+const InfoRec *
SourceManager::getInfoRec(const FileEntry *FileEnt) {
assert(FileEnt && "Didn't specify a file entry to use?");
// Do we already have information about this file?
@@ -68,7 +69,7 @@
/// createMemBufferInfoRec - Create a new info record for the specified memory
/// buffer. This does no caching.
-const SourceManager::InfoRec *
+const InfoRec *
SourceManager::createMemBufferInfoRec(const SourceBuffer *Buffer) {
// Add a new info record to the MemBufferInfos list and return it.
FileInfo FI;
@@ -91,7 +92,7 @@
// FilePos field.
unsigned FileSize = File->second.Buffer->getBufferSize();
if (FileSize+1 < (1 << SourceLocation::FilePosBits)) {
- FileIDs.push_back(FileIDInfo(IncludePos, 0, File));
+ FileIDs.push_back(FileIDInfo::getNormalBuffer(IncludePos, 0, File));
return FileIDs.size();
}
@@ -100,7 +101,7 @@
unsigned ChunkNo = 0;
while (1) {
- FileIDs.push_back(FileIDInfo(IncludePos, ChunkNo++, File));
+ FileIDs.push_back(FileIDInfo::getNormalBuffer(IncludePos, ChunkNo++, File));
if (FileSize+1 < (1 << SourceLocation::FilePosBits)) break;
FileSize -= (1 << SourceLocation::FilePosBits);
Modified: cfe/cfe/trunk/include/clang/Basic/SourceLocation.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Basic/SourceLocation.h?rev=38556&r1=38555&r2=38556&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/Basic/SourceLocation.h (original)
+++ cfe/cfe/trunk/include/clang/Basic/SourceLocation.h Wed Jul 11 11:22:35 2007
@@ -64,11 +64,25 @@
/// from the start of the file, instead you should use
/// SourceManager::getFilePos. This method will be incorrect for large files.
unsigned getRawFilePos() const { return ID & ((1 << FilePosBits)-1); }
+
+
+ /// getRawEncoding - When a SourceLocation itself cannot be used, this returns
+ /// an (opaque) 32-bit integer encoding for it. This should only be passed
+ /// to SourceLocation::getFromRawEncoding, it should not be inspected
+ /// directly.
+ unsigned getRawEncoding() const { return ID; }
+
+ /// getFromRawEncoding - Turn a raw encoding of a SourceLocation object into
+ /// a real SourceLocation.
+ static SourceLocation getFromRawEncoding(unsigned Encoding) {
+ SourceLocation X;
+ X.ID = Encoding;
+ return X;
+ }
};
inline bool operator==(const SourceLocation &LHS, const SourceLocation &RHS) {
- return LHS.getFileID() == RHS.getFileID() &&
- LHS.getRawFilePos() == RHS.getRawFilePos();
+ return LHS.getRawEncoding() == RHS.getRawEncoding();
}
inline bool operator!=(const SourceLocation &LHS, const SourceLocation &RHS) {
Modified: cfe/cfe/trunk/include/clang/Basic/SourceManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Basic/SourceManager.h?rev=38556&r1=38555&r2=38556&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/Basic/SourceManager.h (original)
+++ cfe/cfe/trunk/include/clang/Basic/SourceManager.h Wed Jul 11 11:22:35 2007
@@ -26,11 +26,10 @@
class SourceManager;
class FileEntry;
class IdentifierTokenInfo;
-
-/// SourceManager - This file handles loading and caching of source files into
-/// memory. This object owns the SourceBuffer objects for all of the loaded
-/// files and assigns unique FileID's for each unique #include chain.
-class SourceManager {
+
+/// SrcMgr - Private classes that are part of the SourceManager implementation.
+///
+namespace SrcMgr {
/// FileInfo - Once instance of this struct is kept for every file loaded or
/// used. This object owns the SourceBuffer object.
struct FileInfo {
@@ -49,39 +48,111 @@
};
typedef std::pair<const FileEntry * const, FileInfo> InfoRec;
-
- /// FileIDInfo - Information about a FileID, basically just the file that it
- /// represents and include stack information.
+
+ /// FileIDInfo - Information about a FileID, basically just the logical file
+ /// that it represents and include stack information. A SourceLocation is a
+ /// byte offset from the start of this.
+ ///
+ /// FileID's are used to compute the location of a character in memory as well
+ /// as the logical source location, which can be differ from the physical
+ /// location. It is different when #line's are active or when macros have
+ /// been expanded.
+ ///
+ /// Each FileID has include stack information, indicating where it came from.
+ /// For the primary translation unit, it comes from SourceLocation() aka 0.
+ ///
+ /// There are three types of FileID's:
+ /// 1. Normal SourceBuffer (file). These are represented by a "InfoRec *",
+ /// describing the source file, and a Chunk number, which factors into
+ /// the SourceLocation's offset from the start of the buffer.
+ /// 2. Macro Expansions. These indicate that the logical location is
+ /// totally different than the physical location. The logical source
+ /// location is specified with an explicit SourceLocation object.
+ ///
struct FileIDInfo {
+ enum FileIDType {
+ NormalBuffer,
+ MacroExpansion
+ };
+
+ /// The type of this FileID.
+ FileIDType IDType : 2;
+
/// IncludeLoc - The location of the #include that brought in this file.
/// This SourceLocation object has a FileId of 0 for the main file.
SourceLocation IncludeLoc;
- /// ChunkNo - Really large files 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 file itself.
+ /// This union is discriminated by IDType.
///
- const InfoRec *Info;
-
- FileIDInfo(SourceLocation IL, unsigned CN, const InfoRec *Inf)
- : IncludeLoc(IL), ChunkNo(CN), Info(Inf) {}
+ 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;
+
+ /// MacroTokenLoc - This is the raw encoding of a SourceLocation which
+ /// indicates the physical location of the macro token.
+ unsigned MacroTokenLoc;
+ } u;
+
+ /// getNormalBuffer - Return a FileIDInfo object for a normal buffer
+ /// reference.
+ static FileIDInfo getNormalBuffer(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;
+ return X;
+ }
+
+ /// getMacroExpansion - Return a FileID for a macro expansion. IL specifies
+ /// the instantiation location,
+ static FileIDInfo getMacroExpansion(SourceLocation IL,
+ SourceLocation TokenLoc) {
+ FileIDInfo X;
+ X.IDType = MacroExpansion;
+ X.IncludeLoc = IL;
+ X.u.MacroTokenLoc = TokenLoc.getRawEncoding();
+ return X;
+ }
+
+ 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;
+ }
};
-
+} // end SrcMgr namespace.
+
+
+/// SourceManager - This file handles loading and caching of source files into
+/// memory. This object owns the SourceBuffer objects for all of the loaded
+/// files and assigns unique FileID's for each unique #include chain.
+class SourceManager {
/// FileInfos - Memoized information about all of the files tracked by this
/// SourceManager.
- std::map<const FileEntry *, FileInfo> FileInfos;
+ std::map<const FileEntry *, SrcMgr::FileInfo> FileInfos;
/// MemBufferInfos - Information about various memory buffers that we have
/// read in. This is a list, instead of a vector, because we need pointers to
/// the FileInfo objects to be stable.
- std::list<InfoRec> MemBufferInfos;
+ std::list<SrcMgr::InfoRec> MemBufferInfos;
/// FileIDs - Information about each FileID. FileID #0 is not valid, so all
/// entries are off by one.
- std::vector<FileIDInfo> FileIDs;
+ std::vector<SrcMgr::FileIDInfo> FileIDs;
public:
~SourceManager();
@@ -89,7 +160,7 @@
/// being #included from the specified IncludePosition. This returns 0 on
/// error and translates NULL into standard input.
unsigned createFileID(const FileEntry *SourceFile, SourceLocation IncludePos){
- const InfoRec *IR = getInfoRec(SourceFile);
+ const SrcMgr::InfoRec *IR = getInfoRec(SourceFile);
if (IR == 0) return 0; // Error opening file?
return createFileID(IR, IncludePos);
}
@@ -98,8 +169,7 @@
/// specified memory buffer. This does no caching of the buffer and takes
/// ownership of the SourceBuffer, so only pass a SourceBuffer to this once.
unsigned createFileIDForMemBuffer(const SourceBuffer *Buffer) {
- const InfoRec *IR = createMemBufferInfoRec(Buffer);
- return createFileID(IR, SourceLocation());
+ return createFileID(createMemBufferInfoRec(Buffer), SourceLocation());
}
@@ -122,7 +192,7 @@
assert(IncludePos.getFileID()-1 < FileIDs.size() && "Invalid FileID!");
// If this file has been split up into chunks, factor in the chunk number
// that the FileID references.
- unsigned ChunkNo = FileIDs[IncludePos.getFileID()-1].ChunkNo;
+ unsigned ChunkNo=FileIDs[IncludePos.getFileID()-1].getNormalBufferChunkNo();
return IncludePos.getRawFilePos() +
(ChunkNo << SourceLocation::FilePosBits);
}
@@ -135,19 +205,19 @@
/// 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.
- unsigned getColumnNumber(SourceLocation IncludePos) const;
+ unsigned getColumnNumber(SourceLocation Loc) const;
/// 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 SourceBuffer, so this is not cheap: use only when
/// about to emit a diagnostic.
- unsigned getLineNumber(SourceLocation IncludePos);
+ unsigned getLineNumber(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].Info->first;
+ return FileIDs[FileID-1].getNormalBufferInfo()->first;
}
/// PrintStats - Print statistics to stderr.
@@ -157,29 +227,29 @@
/// createFileID - Create a new fileID for the specified InfoRec and include
/// position. This works regardless of whether the InfoRec corresponds to a
/// file or some other input source.
- unsigned createFileID(const InfoRec *File, SourceLocation IncludePos);
+ unsigned createFileID(const SrcMgr::InfoRec *File, SourceLocation IncludePos);
/// getFileInfo - Create or return a cached FileInfo for the specified file.
/// This returns null on failure.
- const InfoRec *getInfoRec(const FileEntry *SourceFile);
+ const SrcMgr::InfoRec *getInfoRec(const FileEntry *SourceFile);
/// createMemBufferInfoRec - Create a new info record for the specified memory
/// buffer. This does no caching.
- const InfoRec *createMemBufferInfoRec(const SourceBuffer *Buffer);
+ const SrcMgr::InfoRec *createMemBufferInfoRec(const SourceBuffer *Buffer);
- const InfoRec *getInfoRec(unsigned FileID) const {
+ const SrcMgr::InfoRec *getInfoRec(unsigned FileID) const {
assert(FileID-1 < FileIDs.size() && "Invalid FileID!");
- return FileIDs[FileID-1].Info;
+ return FileIDs[FileID-1].getNormalBufferInfo();
}
- FileInfo *getFileInfo(unsigned FileID) const {
- if (const InfoRec *IR = getInfoRec(FileID))
- return const_cast<FileInfo *>(&IR->second);
+ SrcMgr::FileInfo *getFileInfo(unsigned FileID) const {
+ if (const SrcMgr::InfoRec *IR = getInfoRec(FileID))
+ return const_cast<SrcMgr::FileInfo *>(&IR->second);
return 0;
}
- FileInfo *getFileInfo(const FileEntry *SourceFile) {
- if (const InfoRec *IR = getInfoRec(SourceFile))
- return const_cast<FileInfo *>(&IR->second);
+ SrcMgr::FileInfo *getFileInfo(const FileEntry *SourceFile) {
+ if (const SrcMgr::InfoRec *IR = getInfoRec(SourceFile))
+ return const_cast<SrcMgr::FileInfo *>(&IR->second);
return 0;
}
};
More information about the cfe-commits
mailing list