Skip to content
This repository was archived by the owner on Nov 1, 2021. It is now read-only.

Commit 2b2453a

Browse files
committed
this massive patch introduces a simple new abstraction: it makes
"FileID" a concept that is now enforced by the compiler's type checker instead of yet-another-random-unsigned floating around. This is an important distinction from the "FileID" currently tracked by SourceLocation. *That* FileID may refer to the start of a file or to a chunk within it. The new FileID *only* refers to the file (and its #include stack and eventually #line data), it cannot refer to a chunk. FileID is a completely opaque datatype to all clients, only SourceManager is allowed to poke and prod it. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@62407 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 0581659 commit 2b2453a

34 files changed

+403
-337
lines changed

Driver/ASTConsumers.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -903,10 +903,10 @@ class BuildSerializer : public ASTSerializer {
903903
return;
904904

905905
SourceManager& SourceMgr = TU.getContext().getSourceManager();
906-
unsigned ID = SourceMgr.getMainFileID();
907-
assert (ID && "MainFileID not set!");
906+
FileID ID = SourceMgr.getMainFileID();
907+
assert(!ID.isInvalid() && "MainFileID not set!");
908908
const FileEntry* FE = SourceMgr.getFileEntryForID(ID);
909-
assert (FE && "No FileEntry for main file.");
909+
assert(FE && "No FileEntry for main file.");
910910

911911
// FIXME: This is not portable to Windows.
912912
// FIXME: This logic should probably be moved elsewhere later.

Driver/CacheTokens.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -485,8 +485,8 @@ void PTHWriter::GeneratePTH() {
485485
const llvm::MemoryBuffer *B = C.getBuffer();
486486
if (!B) continue;
487487

488-
unsigned FID = SM.createFileID(FE, SourceLocation(), SrcMgr::C_User);
489-
Lexer L(SourceLocation::getFileLoc(FID, 0), LOpts,
488+
FileID FID = SM.createFileID(FE, SourceLocation(), SrcMgr::C_User);
489+
Lexer L(SM.getLocForStartOfFile(FID), LOpts,
490490
B->getBufferStart(), B->getBufferEnd(), B);
491491
PM[FE] = LexTokens(L);
492492
}

Driver/DiagChecker.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -117,12 +117,12 @@ static void FindExpectedDiags(Preprocessor &PP,
117117
DiagList &ExpectedNotes) {
118118
// Create a raw lexer to pull all the comments out of the main file. We don't
119119
// want to look in #include'd headers for expected-error strings.
120-
unsigned FileID = PP.getSourceManager().getMainFileID();
120+
FileID FID = PP.getSourceManager().getMainFileID();
121121
std::pair<const char*,const char*> File =
122-
PP.getSourceManager().getBufferData(FileID);
122+
PP.getSourceManager().getBufferData(FID);
123123

124124
// Create a lexer to lex all the tokens of the main file in raw mode.
125-
Lexer RawLex(SourceLocation::getFileLoc(FileID, 0),
125+
Lexer RawLex(PP.getSourceManager().getLocForStartOfFile(FID),
126126
PP.getLangOptions(), File.first, File.second);
127127

128128
// Return comments as tokens, this is how we find expected diagnostics.

Driver/HTMLPrint.cpp

+8-8
Original file line numberDiff line numberDiff line change
@@ -60,19 +60,19 @@ HTMLPrinter::~HTMLPrinter() {
6060
return;
6161

6262
// Format the file.
63-
unsigned FileID = R.getSourceMgr().getMainFileID();
64-
const FileEntry* Entry = R.getSourceMgr().getFileEntryForID(FileID);
63+
FileID FID = R.getSourceMgr().getMainFileID();
64+
const FileEntry* Entry = R.getSourceMgr().getFileEntryForID(FID);
6565

66-
html::AddLineNumbers(R, FileID);
67-
html::AddHeaderFooterInternalBuiltinCSS(R, FileID, Entry->getName());
66+
html::AddLineNumbers(R, FID);
67+
html::AddHeaderFooterInternalBuiltinCSS(R, FID, Entry->getName());
6868

6969
// If we have a preprocessor, relex the file and syntax highlight.
7070
// We might not have a preprocessor if we come from a deserialized AST file,
7171
// for example.
7272

73-
if (PP) html::SyntaxHighlight(R, FileID, *PP);
74-
if (PPF) html::HighlightMacros(R, FileID, *PP);
75-
html::EscapeText(R, FileID, false, true);
73+
if (PP) html::SyntaxHighlight(R, FID, *PP);
74+
if (PPF) html::HighlightMacros(R, FID, *PP);
75+
html::EscapeText(R, FID, false, true);
7676

7777
// Open the output.
7878
FILE *OutputFILE;
@@ -87,7 +87,7 @@ HTMLPrinter::~HTMLPrinter() {
8787
}
8888

8989
// Emit the HTML.
90-
const RewriteBuffer &RewriteBuf = R.getEditBuffer(FileID);
90+
const RewriteBuffer &RewriteBuf = R.getEditBuffer(FID);
9191
char *Buffer = (char*)malloc(RewriteBuf.size());
9292
std::copy(RewriteBuf.begin(), RewriteBuf.end(), Buffer);
9393
fwrite(Buffer, 1, RewriteBuf.size(), OutputFILE);

Driver/RewriteBlocks.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class RewriteBlocks : public ASTConsumer {
3737

3838
ASTContext *Context;
3939
SourceManager *SM;
40-
unsigned MainFileID;
40+
FileID MainFileID;
4141
const char *MainFileStart, *MainFileEnd;
4242

4343
// Block expressions.
@@ -223,7 +223,7 @@ void RewriteBlocks::Initialize(ASTContext &context) {
223223
Preamble += "__OBJC_RW_EXTERN void *_NSConcreteStackBlock;\n";
224224
Preamble += "#endif\n";
225225

226-
InsertText(SourceLocation::getFileLoc(MainFileID, 0),
226+
InsertText(SM->getLocForStartOfFile(MainFileID),
227227
Preamble.c_str(), Preamble.size());
228228
}
229229

Driver/RewriteMacros.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ static void LexRawTokensFromMainFile(Preprocessor &PP,
6565

6666
// Create a lexer to lex all the tokens of the main file in raw mode. Even
6767
// though it is in raw mode, it will not return comments.
68-
Lexer RawLex(SourceLocation::getFileLoc(SM.getMainFileID(), 0),
68+
Lexer RawLex(SM.getLocForStartOfFile(SM.getMainFileID()),
6969
PP.getLangOptions(), File.first, File.second);
7070

7171
// Switch on comment lexing because we really do want them.

Driver/RewriteObjC.cpp

+5-5
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ namespace {
4747
ASTContext *Context;
4848
SourceManager *SM;
4949
TranslationUnitDecl *TUDecl;
50-
unsigned MainFileID;
50+
FileID MainFileID;
5151
const char *MainFileStart, *MainFileEnd;
5252
SourceLocation LastIncLoc;
5353

@@ -597,7 +597,7 @@ void RewriteObjC::HandleTopLevelDecl(Decl *D) {
597597
//===----------------------------------------------------------------------===//
598598

599599
void RewriteObjC::RewriteInclude() {
600-
SourceLocation LocStart = SourceLocation::getFileLoc(MainFileID, 0);
600+
SourceLocation LocStart = SM->getLocForStartOfFile(MainFileID);
601601
std::pair<const char*, const char*> MainBuf = SM->getBufferData(MainFileID);
602602
const char *MainBufStart = MainBuf.first;
603603
const char *MainBufEnd = MainBuf.second;
@@ -645,8 +645,8 @@ void RewriteObjC::RewriteTabs() {
645645
unsigned Spaces = 8-(VCol & 7);
646646

647647
// Get the location of the tab.
648-
SourceLocation TabLoc =
649-
SourceLocation::getFileLoc(MainFileID, BufPtr-MainBufStart);
648+
SourceLocation TabLoc = SM->getLocForStartOfFile(MainFileID);
649+
TabLoc = TabLoc.getFileLocWithOffset(BufPtr-MainBufStart);
650650

651651
// Rewrite the single tab character into a sequence of spaces.
652652
ReplaceText(TabLoc, 1, " ", Spaces);
@@ -4501,7 +4501,7 @@ void RewriteObjC::HandleTranslationUnit(TranslationUnit& TU) {
45014501

45024502
RewriteInclude();
45034503

4504-
InsertText(SourceLocation::getFileLoc(MainFileID, 0),
4504+
InsertText(SM->getLocForStartOfFile(MainFileID),
45054505
Preamble.c_str(), Preamble.size(), false);
45064506

45074507
if (ClassImplementation.size() || CategoryImplementation.size())

Driver/clang.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -919,14 +919,14 @@ static bool InitializePreprocessor(Preprocessor &PP,
919919
if (InFile != "-") {
920920
const FileEntry *File = FileMgr.getFile(InFile);
921921
if (File) SourceMgr.createMainFileID(File, SourceLocation());
922-
if (SourceMgr.getMainFileID() == 0) {
922+
if (SourceMgr.getMainFileID().isInvalid()) {
923923
fprintf(stderr, "Error reading '%s'!\n",InFile.c_str());
924924
return true;
925925
}
926926
} else {
927927
llvm::MemoryBuffer *SB = llvm::MemoryBuffer::getSTDIN();
928928
if (SB) SourceMgr.createMainFileIDForMemBuffer(SB);
929-
if (SourceMgr.getMainFileID() == 0) {
929+
if (SourceMgr.getMainFileID().isInvalid()) {
930930
fprintf(stderr, "Error reading standard input! Empty?\n");
931931
return true;
932932
}
@@ -1335,7 +1335,7 @@ static void ProcessInputFile(Preprocessor &PP, PreprocessorFactory &PPF,
13351335
std::pair<const char*,const char*> File =
13361336
SM.getBufferData(SM.getMainFileID());
13371337
// Start lexing the specified input file.
1338-
Lexer RawLex(SourceLocation::getFileLoc(SM.getMainFileID(), 0),
1338+
Lexer RawLex(SM.getLocForStartOfFile(SM.getMainFileID()),
13391339
PP.getLangOptions(), File.first, File.second);
13401340
RawLex.SetKeepWhitespaceMode(true);
13411341

include/clang/Basic/SourceLocation.h

+59-1
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,46 @@
1818
#include "llvm/Bitcode/SerializationFwd.h"
1919

2020
namespace llvm {
21-
class MemoryBuffer;
21+
class MemoryBuffer;
22+
template <typename T> struct DenseMapInfo;
2223
}
2324

2425
namespace clang {
2526

2627
class SourceManager;
2728
class FileEntry;
29+
30+
/// FileID - This is an opaque identifier used by SourceManager which refers to
31+
/// a source file (MemoryBuffer) along with its #include path and #line data.
32+
///
33+
class FileID {
34+
/// ID - Opaque identifier, 0 is "invalid".
35+
unsigned ID;
36+
public:
37+
FileID() : ID(0) {}
38+
39+
bool isInvalid() const { return ID == 0; }
40+
41+
bool operator==(const FileID &RHS) const { return ID == RHS.ID; }
42+
bool operator<(const FileID &RHS) const { return ID < RHS.ID; }
43+
bool operator<=(const FileID &RHS) const { return ID <= RHS.ID; }
44+
bool operator!=(const FileID &RHS) const { return !(*this == RHS); }
45+
bool operator>(const FileID &RHS) const { return RHS < *this; }
46+
bool operator>=(const FileID &RHS) const { return RHS <= *this; }
47+
48+
static FileID getSentinel() { return Create(~0U); }
49+
unsigned getHashValue() const { return ID; }
50+
51+
private:
52+
friend class SourceManager;
53+
static FileID Create(unsigned V) {
54+
FileID F;
55+
F.ID = V;
56+
return F;
57+
}
58+
unsigned getOpaqueValue() const { return ID; }
59+
};
60+
2861

2962
/// SourceLocation - This is a carefully crafted 32-bit identifier that encodes
3063
/// a full include stack, line and column number information for a position in
@@ -269,4 +302,29 @@ class FullSourceLoc : public SourceLocation {
269302

270303
} // end namespace clang
271304

305+
namespace llvm {
306+
/// Define DenseMapInfo so that FileID's can be used as keys in DenseMap and
307+
/// DenseSets.
308+
template <>
309+
struct DenseMapInfo<clang::FileID> {
310+
static inline clang::FileID getEmptyKey() {
311+
return clang::FileID();
312+
}
313+
static inline clang::FileID getTombstoneKey() {
314+
return clang::FileID::getSentinel();
315+
}
316+
317+
static unsigned getHashValue(clang::FileID S) {
318+
return S.getHashValue();
319+
}
320+
321+
static bool isEqual(clang::FileID LHS, clang::FileID RHS) {
322+
return LHS == RHS;
323+
}
324+
325+
static bool isPod() { return true; }
326+
};
327+
328+
} // end namespace llvm
329+
272330
#endif

0 commit comments

Comments
 (0)