зеркало из https://github.com/microsoft/clang-1.git
Make a significant change to invert the control flow handling
predefined macros. Previously, these were handled by the driver, now they are handled by the preprocessor. Some fallout of this: 1. Instead of preprocessing two buffers (the predefines, then the main source file) we now start preprocessing the main source file and inject the predefines as a "psuedo #include" from the main source file. 2. #1 allows us to nuke the Lexer::IsMainFile flag and simplify Preprocessor::isInPrimaryFile. 3. The driver doesn't have to know about standard #defines, the preprocessor knows, which is nice for people wanting to define their own drivers. 4. This allows us to put normal tokens in the predefine buffer, for example a definition for __builtin_va_list that is target-specific, and a typedef for id in objc. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@42818 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
b216c8861c
Коммит
53b0dabbe5
|
@ -91,7 +91,7 @@ static void FindExpectedDiags(Preprocessor &PP, unsigned MainFileID,
|
|||
PP.SetCommentRetentionState(true, true);
|
||||
|
||||
// Enter the cave.
|
||||
PP.EnterSourceFile(MainFileID, 0, true);
|
||||
PP.EnterMainSourceFile(MainFileID);
|
||||
|
||||
// Turn off all warnings from relexing or preprocessing.
|
||||
PP.getDiagnostics().setWarnOnExtensions(false);
|
||||
|
|
|
@ -534,7 +534,7 @@ void clang::DoPrintPreprocessedInput(unsigned MainFileID, Preprocessor &PP,
|
|||
// After we have configured the preprocessor, enter the main file.
|
||||
|
||||
// Start parsing the specified input file.
|
||||
PP.EnterSourceFile(MainFileID, 0, true);
|
||||
PP.EnterMainSourceFile(MainFileID);
|
||||
|
||||
do {
|
||||
PrevTok = Tok;
|
||||
|
|
178
Driver/clang.cpp
178
Driver/clang.cpp
|
@ -394,76 +394,56 @@ static void DefineBuiltinMacro(std::vector<char> &Buf, const char *Macro,
|
|||
Buf.push_back('\n');
|
||||
}
|
||||
|
||||
static void InitializePredefinedMacros(Preprocessor &PP,
|
||||
std::vector<char> &Buf) {
|
||||
// FIXME: Implement magic like cpp_init_builtins for things like __STDC__
|
||||
// and __DATE__ etc.
|
||||
#if 0
|
||||
/* __STDC__ has the value 1 under normal circumstances.
|
||||
However, if (a) we are in a system header, (b) the option
|
||||
stdc_0_in_system_headers is true (set by target config), and
|
||||
(c) we are not in strictly conforming mode, then it has the
|
||||
value 0. (b) and (c) are already checked in cpp_init_builtins. */
|
||||
//case BT_STDC:
|
||||
if (cpp_in_system_header (pfile))
|
||||
number = 0;
|
||||
else
|
||||
number = 1;
|
||||
break;
|
||||
#endif
|
||||
// These should all be defined in the preprocessor according to the
|
||||
// current language configuration.
|
||||
DefineBuiltinMacro(Buf, "__STDC__=1");
|
||||
//DefineBuiltinMacro(Buf, "__ASSEMBLER__=1");
|
||||
if (PP.getLangOptions().C99 && !PP.getLangOptions().CPlusPlus)
|
||||
DefineBuiltinMacro(Buf, "__STDC_VERSION__=199901L");
|
||||
else if (0) // STDC94 ?
|
||||
DefineBuiltinMacro(Buf, "__STDC_VERSION__=199409L");
|
||||
|
||||
DefineBuiltinMacro(Buf, "__STDC_HOSTED__=1");
|
||||
if (PP.getLangOptions().ObjC1)
|
||||
DefineBuiltinMacro(Buf, "__OBJC__=1");
|
||||
if (PP.getLangOptions().ObjC2)
|
||||
DefineBuiltinMacro(Buf, "__OBJC2__=1");
|
||||
|
||||
// Get the target #defines.
|
||||
PP.getTargetInfo().getTargetDefines(Buf);
|
||||
/// InitializePreprocessor - Initialize the preprocessor getting it and the
|
||||
/// environment ready to process a single file. This returns the file ID for the
|
||||
/// input file. If a failure happens, it returns 0.
|
||||
///
|
||||
static unsigned InitializePreprocessor(Preprocessor &PP,
|
||||
const std::string &InFile,
|
||||
SourceManager &SourceMgr,
|
||||
HeaderSearch &HeaderInfo,
|
||||
const LangOptions &LangInfo,
|
||||
std::vector<char> &PredefineBuffer) {
|
||||
|
||||
// Compiler set macros.
|
||||
DefineBuiltinMacro(Buf, "__APPLE_CC__=5250");
|
||||
DefineBuiltinMacro(Buf, "__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__=1030");
|
||||
DefineBuiltinMacro(Buf, "__GNUC_MINOR__=0");
|
||||
DefineBuiltinMacro(Buf, "__GNUC_PATCHLEVEL__=1");
|
||||
DefineBuiltinMacro(Buf, "__GNUC__=4");
|
||||
DefineBuiltinMacro(Buf, "__GXX_ABI_VERSION=1002");
|
||||
DefineBuiltinMacro(Buf, "__VERSION__=\"4.0.1 (Apple Computer, Inc. "
|
||||
"build 5250)\"");
|
||||
|
||||
// Build configuration options.
|
||||
DefineBuiltinMacro(Buf, "__DYNAMIC__=1");
|
||||
DefineBuiltinMacro(Buf, "__FINITE_MATH_ONLY__=0");
|
||||
DefineBuiltinMacro(Buf, "__NO_INLINE__=1");
|
||||
DefineBuiltinMacro(Buf, "__PIC__=1");
|
||||
|
||||
FileManager &FileMgr = HeaderInfo.getFileMgr();
|
||||
|
||||
if (PP.getLangOptions().CPlusPlus) {
|
||||
DefineBuiltinMacro(Buf, "__DEPRECATED=1");
|
||||
DefineBuiltinMacro(Buf, "__EXCEPTIONS=1");
|
||||
DefineBuiltinMacro(Buf, "__GNUG__=4");
|
||||
DefineBuiltinMacro(Buf, "__GXX_WEAK__=1");
|
||||
DefineBuiltinMacro(Buf, "__cplusplus=1");
|
||||
DefineBuiltinMacro(Buf, "__private_extern__=extern");
|
||||
// Figure out where to get and map in the main file.
|
||||
unsigned MainFileID = 0;
|
||||
if (InFile != "-") {
|
||||
const FileEntry *File = FileMgr.getFile(InFile);
|
||||
if (File) MainFileID = SourceMgr.createFileID(File, SourceLocation());
|
||||
if (MainFileID == 0) {
|
||||
fprintf(stderr, "Error reading '%s'!\n",InFile.c_str());
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
llvm::MemoryBuffer *SB = llvm::MemoryBuffer::getSTDIN();
|
||||
if (SB) MainFileID = SourceMgr.createFileIDForMemBuffer(SB);
|
||||
if (MainFileID == 0) {
|
||||
fprintf(stderr, "Error reading standard input! Empty?\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: Should emit a #line directive here.
|
||||
|
||||
// Add macros from the command line.
|
||||
// FIXME: Should traverse the #define/#undef lists in parallel.
|
||||
for (unsigned i = 0, e = D_macros.size(); i != e; ++i)
|
||||
DefineBuiltinMacro(Buf, D_macros[i].c_str());
|
||||
DefineBuiltinMacro(PredefineBuffer, D_macros[i].c_str());
|
||||
for (unsigned i = 0, e = U_macros.size(); i != e; ++i)
|
||||
DefineBuiltinMacro(Buf, U_macros[i].c_str(), "#undef ");
|
||||
DefineBuiltinMacro(PredefineBuffer, U_macros[i].c_str(), "#undef ");
|
||||
|
||||
// FIXME: Read any files specified by -imacros or -include.
|
||||
|
||||
// Null terminate PredefinedBuffer and add it.
|
||||
PredefineBuffer.push_back(0);
|
||||
PP.setPredefines(&PredefineBuffer[0]);
|
||||
|
||||
// Once we've read this, we're done.
|
||||
return MainFileID;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Preprocessor include path information.
|
||||
|
@ -712,18 +692,13 @@ static void InitializeIncludePaths(HeaderSearch &Headers, FileManager &FM,
|
|||
}
|
||||
|
||||
|
||||
// Read any files specified by -imacros or -include.
|
||||
static void ReadPrologFiles(Preprocessor &PP, std::vector<char> &Buf) {
|
||||
// FIXME: IMPLEMENT
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Basic Parser driver
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
static void ParseFile(Preprocessor &PP, MinimalAction *PA, unsigned MainFileID){
|
||||
Parser P(PP, *PA);
|
||||
PP.EnterSourceFile(MainFileID, 0, true);
|
||||
PP.EnterMainSourceFile(MainFileID);
|
||||
|
||||
// Parsing the specified input file.
|
||||
P.ParseTranslationUnit();
|
||||
|
@ -734,69 +709,6 @@ static void ParseFile(Preprocessor &PP, MinimalAction *PA, unsigned MainFileID){
|
|||
// Main driver
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/// InitializePreprocessor - Initialize the preprocessor getting it and the
|
||||
/// environment ready to process a single file. This returns the file ID for the
|
||||
/// input file. If a failure happens, it returns 0.
|
||||
///
|
||||
static unsigned InitializePreprocessor(Preprocessor &PP,
|
||||
const std::string &InFile,
|
||||
SourceManager &SourceMgr,
|
||||
HeaderSearch &HeaderInfo,
|
||||
const LangOptions &LangInfo,
|
||||
std::vector<char> &PrologMacros) {
|
||||
PrologMacros.reserve(4080);
|
||||
|
||||
FileManager &FileMgr = HeaderInfo.getFileMgr();
|
||||
|
||||
// Install things like __POWERPC__, __GNUC__, etc into the macro table.
|
||||
InitializePredefinedMacros(PP, PrologMacros);
|
||||
|
||||
// Read any files specified by -imacros or -include.
|
||||
ReadPrologFiles(PP, PrologMacros);
|
||||
|
||||
// Figure out where to get and map in the main file.
|
||||
unsigned MainFileID = 0;
|
||||
if (InFile != "-") {
|
||||
const FileEntry *File = FileMgr.getFile(InFile);
|
||||
if (File) MainFileID = SourceMgr.createFileID(File, SourceLocation());
|
||||
if (MainFileID == 0) {
|
||||
fprintf(stderr, "Error reading '%s'!\n",InFile.c_str());
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
llvm::MemoryBuffer *SB = llvm::MemoryBuffer::getSTDIN();
|
||||
if (SB) MainFileID = SourceMgr.createFileIDForMemBuffer(SB);
|
||||
if (MainFileID == 0) {
|
||||
fprintf(stderr, "Error reading standard input! Empty?\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Now that we have emitted the predefined macros, #includes, etc into
|
||||
// PrologMacros, preprocess it to populate the initial preprocessor state.
|
||||
|
||||
// Memory buffer must end with a null byte!
|
||||
PrologMacros.push_back(0);
|
||||
|
||||
llvm::MemoryBuffer *SB =
|
||||
llvm::MemoryBuffer::getMemBuffer(&PrologMacros.front(),&PrologMacros.back(),
|
||||
"<predefines>");
|
||||
assert(SB && "Cannot fail to create predefined source buffer");
|
||||
unsigned FileID = SourceMgr.createFileIDForMemBuffer(SB);
|
||||
assert(FileID && "Could not create FileID for predefines?");
|
||||
|
||||
// Start parsing the predefines.
|
||||
PP.EnterSourceFile(FileID, 0);
|
||||
|
||||
// Lex the file, which will read all the macros.
|
||||
Token Tok;
|
||||
PP.Lex(Tok);
|
||||
assert(Tok.is(tok::eof) && "Didn't read entire file!");
|
||||
|
||||
// Once we've read this, we're done.
|
||||
return MainFileID;
|
||||
}
|
||||
|
||||
/// ProcessInputFile - Process a single input file with the specified state.
|
||||
///
|
||||
static void ProcessInputFile(Preprocessor &PP, unsigned MainFileID,
|
||||
|
@ -816,7 +728,7 @@ static void ProcessInputFile(Preprocessor &PP, unsigned MainFileID,
|
|||
case DumpTokens: { // Token dump mode.
|
||||
Token Tok;
|
||||
// Start parsing the specified input file.
|
||||
PP.EnterSourceFile(MainFileID, 0, true);
|
||||
PP.EnterMainSourceFile(MainFileID);
|
||||
do {
|
||||
PP.Lex(Tok);
|
||||
PP.DumpToken(Tok, true);
|
||||
|
@ -828,7 +740,7 @@ static void ProcessInputFile(Preprocessor &PP, unsigned MainFileID,
|
|||
case RunPreprocessorOnly: { // Just lex as fast as we can, no output.
|
||||
Token Tok;
|
||||
// Start parsing the specified input file.
|
||||
PP.EnterSourceFile(MainFileID, 0, true);
|
||||
PP.EnterMainSourceFile(MainFileID);
|
||||
do {
|
||||
PP.Lex(Tok);
|
||||
} while (Tok.isNot(tok::eof));
|
||||
|
@ -982,10 +894,10 @@ int main(int argc, char **argv) {
|
|||
Preprocessor PP(Diags, LangInfo, *Target, SourceMgr, HeaderInfo);
|
||||
DiagClient->setPreprocessor(PP);
|
||||
const std::string &InFile = InputFilenames[i];
|
||||
std::vector<char> PrologMacros;
|
||||
std::vector<char> PredefineBuffer;
|
||||
unsigned MainFileID = InitializePreprocessor(PP, InFile, SourceMgr,
|
||||
HeaderInfo, LangInfo,
|
||||
PrologMacros);
|
||||
PredefineBuffer);
|
||||
|
||||
if (!MainFileID) continue;
|
||||
|
||||
|
|
|
@ -65,7 +65,6 @@ Lexer::Lexer(SourceLocation fileloc, Preprocessor &pp,
|
|||
const llvm::MemoryBuffer *InputFile = SourceMgr.getBuffer(InputFileID);
|
||||
|
||||
Is_PragmaLexer = false;
|
||||
IsMainFile = false;
|
||||
InitCharacterInfo();
|
||||
|
||||
// BufferStart must always be InputFile->getBufferStart().
|
||||
|
|
|
@ -73,6 +73,8 @@ Preprocessor::Preprocessor(Diagnostic &diags, const LangOptions &opts,
|
|||
// This gets unpoisoned where it is allowed.
|
||||
(Ident__VA_ARGS__ = getIdentifierInfo("__VA_ARGS__"))->setIsPoisoned();
|
||||
|
||||
Predefines = 0;
|
||||
|
||||
// Initialize the pragma handlers.
|
||||
PragmaHandlers = new PragmaNamespace(0);
|
||||
RegisterBuiltinPragmas();
|
||||
|
@ -311,6 +313,127 @@ SourceLocation Preprocessor::AdvanceToTokenCharacter(SourceLocation TokStart,
|
|||
}
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Preprocessor Initialization Methods
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Append a #define line to Buf for Macro. Macro should be of the form XXX,
|
||||
// in which case we emit "#define XXX 1" or "XXX=Y z W" in which case we emit
|
||||
// "#define XXX Y z W". To get a #define with no value, use "XXX=".
|
||||
static void DefineBuiltinMacro(std::vector<char> &Buf, const char *Macro,
|
||||
const char *Command = "#define ") {
|
||||
Buf.insert(Buf.end(), Command, Command+strlen(Command));
|
||||
if (const char *Equal = strchr(Macro, '=')) {
|
||||
// Turn the = into ' '.
|
||||
Buf.insert(Buf.end(), Macro, Equal);
|
||||
Buf.push_back(' ');
|
||||
Buf.insert(Buf.end(), Equal+1, Equal+strlen(Equal));
|
||||
} else {
|
||||
// Push "macroname 1".
|
||||
Buf.insert(Buf.end(), Macro, Macro+strlen(Macro));
|
||||
Buf.push_back(' ');
|
||||
Buf.push_back('1');
|
||||
}
|
||||
Buf.push_back('\n');
|
||||
}
|
||||
|
||||
|
||||
static void InitializePredefinedMacros(Preprocessor &PP,
|
||||
std::vector<char> &Buf) {
|
||||
// FIXME: Implement magic like cpp_init_builtins for things like __STDC__
|
||||
// and __DATE__ etc.
|
||||
#if 0
|
||||
/* __STDC__ has the value 1 under normal circumstances.
|
||||
However, if (a) we are in a system header, (b) the option
|
||||
stdc_0_in_system_headers is true (set by target config), and
|
||||
(c) we are not in strictly conforming mode, then it has the
|
||||
value 0. (b) and (c) are already checked in cpp_init_builtins. */
|
||||
//case BT_STDC:
|
||||
if (cpp_in_system_header (pfile))
|
||||
number = 0;
|
||||
else
|
||||
number = 1;
|
||||
break;
|
||||
#endif
|
||||
// These should all be defined in the preprocessor according to the
|
||||
// current language configuration.
|
||||
DefineBuiltinMacro(Buf, "__STDC__=1");
|
||||
//DefineBuiltinMacro(Buf, "__ASSEMBLER__=1");
|
||||
if (PP.getLangOptions().C99 && !PP.getLangOptions().CPlusPlus)
|
||||
DefineBuiltinMacro(Buf, "__STDC_VERSION__=199901L");
|
||||
else if (0) // STDC94 ?
|
||||
DefineBuiltinMacro(Buf, "__STDC_VERSION__=199409L");
|
||||
|
||||
DefineBuiltinMacro(Buf, "__STDC_HOSTED__=1");
|
||||
if (PP.getLangOptions().ObjC1)
|
||||
DefineBuiltinMacro(Buf, "__OBJC__=1");
|
||||
if (PP.getLangOptions().ObjC2)
|
||||
DefineBuiltinMacro(Buf, "__OBJC2__=1");
|
||||
|
||||
// Get the target #defines.
|
||||
PP.getTargetInfo().getTargetDefines(Buf);
|
||||
|
||||
// Compiler set macros.
|
||||
DefineBuiltinMacro(Buf, "__APPLE_CC__=5250");
|
||||
DefineBuiltinMacro(Buf, "__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__=1030");
|
||||
DefineBuiltinMacro(Buf, "__GNUC_MINOR__=0");
|
||||
DefineBuiltinMacro(Buf, "__GNUC_PATCHLEVEL__=1");
|
||||
DefineBuiltinMacro(Buf, "__GNUC__=4");
|
||||
DefineBuiltinMacro(Buf, "__GXX_ABI_VERSION=1002");
|
||||
DefineBuiltinMacro(Buf, "__VERSION__=\"4.0.1 (Apple Computer, Inc. "
|
||||
"build 5250)\"");
|
||||
|
||||
// Build configuration options.
|
||||
DefineBuiltinMacro(Buf, "__DYNAMIC__=1");
|
||||
DefineBuiltinMacro(Buf, "__FINITE_MATH_ONLY__=0");
|
||||
DefineBuiltinMacro(Buf, "__NO_INLINE__=1");
|
||||
DefineBuiltinMacro(Buf, "__PIC__=1");
|
||||
|
||||
|
||||
if (PP.getLangOptions().CPlusPlus) {
|
||||
DefineBuiltinMacro(Buf, "__DEPRECATED=1");
|
||||
DefineBuiltinMacro(Buf, "__EXCEPTIONS=1");
|
||||
DefineBuiltinMacro(Buf, "__GNUG__=4");
|
||||
DefineBuiltinMacro(Buf, "__GXX_WEAK__=1");
|
||||
DefineBuiltinMacro(Buf, "__cplusplus=1");
|
||||
DefineBuiltinMacro(Buf, "__private_extern__=extern");
|
||||
}
|
||||
|
||||
// FIXME: Should emit a #line directive here.
|
||||
}
|
||||
|
||||
|
||||
/// EnterMainSourceFile - Enter the specified FileID as the main source file,
|
||||
/// which implicitly adds the builting defines etc.
|
||||
void Preprocessor::EnterMainSourceFile(unsigned MainFileID) {
|
||||
// Enter the main file source buffer.
|
||||
EnterSourceFile(MainFileID, 0);
|
||||
|
||||
|
||||
std::vector<char> PrologFile;
|
||||
PrologFile.reserve(4080);
|
||||
|
||||
// Install things like __POWERPC__, __GNUC__, etc into the macro table.
|
||||
InitializePredefinedMacros(*this, PrologFile);
|
||||
|
||||
// Add on the predefines from the driver.
|
||||
PrologFile.insert(PrologFile.end(), Predefines,Predefines+strlen(Predefines));
|
||||
|
||||
// Memory buffer must end with a null byte!
|
||||
PrologFile.push_back(0);
|
||||
|
||||
// Now that we have emitted the predefined macros, #includes, etc into
|
||||
// PrologFile, preprocess it to populate the initial preprocessor state.
|
||||
llvm::MemoryBuffer *SB =
|
||||
llvm::MemoryBuffer::getMemBufferCopy(&PrologFile.front(),&PrologFile.back(),
|
||||
"<predefines>");
|
||||
assert(SB && "Cannot fail to create predefined source buffer");
|
||||
unsigned FileID = SourceMgr.createFileIDForMemBuffer(SB);
|
||||
assert(FileID && "Could not create FileID for predefines?");
|
||||
|
||||
// Start parsing the predefines.
|
||||
EnterSourceFile(FileID, 0);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Source File Location Methods.
|
||||
|
@ -367,14 +490,17 @@ const FileEntry *Preprocessor::LookupFile(const char *FilenameStart,
|
|||
/// #include.
|
||||
bool Preprocessor::isInPrimaryFile() const {
|
||||
if (CurLexer && !CurLexer->Is_PragmaLexer)
|
||||
return CurLexer->isMainFile();
|
||||
return IncludeMacroStack.empty();
|
||||
|
||||
// If there are any stacked lexers, we're in a #include.
|
||||
for (unsigned i = 0, e = IncludeMacroStack.size(); i != e; ++i)
|
||||
assert(IncludeMacroStack[0].TheLexer &&
|
||||
!IncludeMacroStack[0].TheLexer->Is_PragmaLexer &&
|
||||
"Top level include stack isn't our primary lexer?");
|
||||
for (unsigned i = 1, e = IncludeMacroStack.size(); i != e; ++i)
|
||||
if (IncludeMacroStack[i].TheLexer &&
|
||||
!IncludeMacroStack[i].TheLexer->Is_PragmaLexer)
|
||||
return IncludeMacroStack[i].TheLexer->isMainFile();
|
||||
return false;
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// getCurrentLexer - Return the current file lexer being lexed from. Note
|
||||
|
@ -397,8 +523,7 @@ Lexer *Preprocessor::getCurrentFileLexer() const {
|
|||
/// start lexing tokens from it instead of the current buffer. Return true
|
||||
/// on failure.
|
||||
void Preprocessor::EnterSourceFile(unsigned FileID,
|
||||
const DirectoryLookup *CurDir,
|
||||
bool isMainFile) {
|
||||
const DirectoryLookup *CurDir) {
|
||||
assert(CurMacroExpander == 0 && "Cannot #include a file inside a macro!");
|
||||
++NumEnteredSourceFiles;
|
||||
|
||||
|
@ -406,7 +531,6 @@ void Preprocessor::EnterSourceFile(unsigned FileID,
|
|||
MaxIncludeStackDepth = IncludeMacroStack.size();
|
||||
|
||||
Lexer *TheLexer = new Lexer(SourceLocation::getFileLoc(FileID, 0), *this);
|
||||
if (isMainFile) TheLexer->setIsMainFile();
|
||||
EnterSourceFileWithLexer(TheLexer, CurDir);
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ namespace {
|
|||
public:
|
||||
ASTStreamer(Preprocessor &pp, ASTContext &ctxt, unsigned MainFileID)
|
||||
: P(pp, *new Sema(pp, ctxt, LastInGroupList)) {
|
||||
pp.EnterSourceFile(MainFileID, 0, true);
|
||||
pp.EnterMainSourceFile(MainFileID);
|
||||
|
||||
// Initialize the parser.
|
||||
P.Initialize();
|
||||
|
|
|
@ -39,7 +39,6 @@ class Lexer {
|
|||
Preprocessor &PP; // Preprocessor object controlling lexing.
|
||||
LangOptions Features; // Features enabled by this language (cache).
|
||||
bool Is_PragmaLexer; // True if lexer for _Pragma handling.
|
||||
bool IsMainFile; // True if top-level file.
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Context-specific lexing flags set by the preprocessor.
|
||||
|
@ -112,16 +111,6 @@ public:
|
|||
/// from. Currently this is only used by _Pragma handling.
|
||||
SourceLocation getFileLoc() const { return FileLoc; }
|
||||
|
||||
/// setIsMainFile - Mark this lexer as being the lexer for the top-level
|
||||
/// source file.
|
||||
void setIsMainFile() {
|
||||
IsMainFile = true;
|
||||
}
|
||||
|
||||
/// isMainFile - Return true if this is the top-level file.
|
||||
///
|
||||
bool isMainFile() const { return IsMainFile; }
|
||||
|
||||
/// Lex - Return the next token in the file. If this is the end of file, it
|
||||
/// return the tok::eof token. Return true if an error occurred and
|
||||
/// compilation should terminate, false if normal. This implicitly involves
|
||||
|
|
|
@ -129,6 +129,10 @@ class Preprocessor {
|
|||
unsigned NumFastMacroExpanded, NumTokenPaste, NumFastTokenPaste;
|
||||
unsigned NumSkipped;
|
||||
|
||||
/// Predefines - This pointer, if non-null, are the predefined macros that
|
||||
/// preprocessor should use from the command line etc.
|
||||
const char *Predefines;
|
||||
|
||||
/// MacroExpanderCache - Cache macro expanders to reduce malloc traffic.
|
||||
enum { MacroExpanderCacheSize = 8 };
|
||||
unsigned NumCachedMacroExpanders;
|
||||
|
@ -163,10 +167,6 @@ public:
|
|||
return CurLexer == L;
|
||||
}
|
||||
|
||||
/// isInPrimaryFile - Return true if we're in the top-level file, not in a
|
||||
/// #include.
|
||||
bool isInPrimaryFile() const;
|
||||
|
||||
/// getCurrentLexer - Return the current file lexer being lexed from. Note
|
||||
/// that this ignores any potentially active macro expansions and _Pragma
|
||||
/// expansions going on at the time.
|
||||
|
@ -189,6 +189,10 @@ public:
|
|||
///
|
||||
void setMacroInfo(IdentifierInfo *II, MacroInfo *MI);
|
||||
|
||||
void setPredefines(const char *P) {
|
||||
Predefines = P;
|
||||
}
|
||||
|
||||
/// getIdentifierInfo - Return information about the specified preprocessor
|
||||
/// identifier token. The version of this method that takes two character
|
||||
/// pointers is preferred unless the identifier is already available as a
|
||||
|
@ -207,11 +211,15 @@ public:
|
|||
/// pragma line before the pragma string starts, e.g. "STDC" or "GCC".
|
||||
void AddPragmaHandler(const char *Namespace, PragmaHandler *Handler);
|
||||
|
||||
/// EnterMainSourceFile - Enter the specified FileID as the main source file,
|
||||
/// which implicitly adds the builting defines etc.
|
||||
void EnterMainSourceFile(unsigned CurFileID);
|
||||
|
||||
|
||||
/// EnterSourceFile - Add a source file to the top of the include stack and
|
||||
/// start lexing tokens from it instead of the current buffer. If isMainFile
|
||||
/// is true, this is the main file for the translation unit.
|
||||
void EnterSourceFile(unsigned CurFileID, const DirectoryLookup *Dir,
|
||||
bool isMainFile = false);
|
||||
void EnterSourceFile(unsigned CurFileID, const DirectoryLookup *Dir);
|
||||
|
||||
/// EnterMacro - Add a Macro to the top of the include stack and start lexing
|
||||
/// tokens from it instead of the current buffer. Args specifies the
|
||||
|
@ -358,7 +366,10 @@ public:
|
|||
/// not, emit a diagnostic and consume up until the eom.
|
||||
void CheckEndOfDirective(const char *Directive);
|
||||
private:
|
||||
|
||||
/// isInPrimaryFile - Return true if we're in the top-level file, not in a
|
||||
/// #include.
|
||||
bool isInPrimaryFile() const;
|
||||
|
||||
/// DiscardUntilEndOfDirective - Read and discard all tokens remaining on the
|
||||
/// current line until the tok::eom token is found.
|
||||
void DiscardUntilEndOfDirective();
|
||||
|
|
Загрузка…
Ссылка в новой задаче