forked from OSchip/llvm-project
Implement the _Pragma-style of pragma handling, implementing
test/Preprocessor/_Pragma-poison.c. This unifies the MacroStack and IncludeStack together into IncludeMacroStack. llvm-svn: 38606
This commit is contained in:
parent
0acd4fee90
commit
69772b026e
|
@ -31,8 +31,6 @@
|
|||
//
|
||||
// TODO: Implement the include guard optimization.
|
||||
//
|
||||
// Predefined Macros: _Pragma, ...
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "clang/Lex/Preprocessor.h"
|
||||
|
@ -59,7 +57,7 @@ Preprocessor::Preprocessor(Diagnostic &diags, const LangOptions &opts,
|
|||
NumDirectives = NumIncluded = NumDefined = NumUndefined = NumPragma = 0;
|
||||
NumIf = NumElse = NumEndif = 0;
|
||||
NumEnteredSourceFiles = NumMacroExpanded = NumFastMacroExpanded = 0;
|
||||
MaxIncludeStackDepth = MaxMacroStackDepth = 0;
|
||||
MaxIncludeStackDepth = 0;
|
||||
NumSkipped = 0;
|
||||
|
||||
// Macro expansion is enabled.
|
||||
|
@ -81,9 +79,10 @@ Preprocessor::~Preprocessor() {
|
|||
// Free any active lexers.
|
||||
delete CurLexer;
|
||||
|
||||
while (!IncludeStack.empty()) {
|
||||
delete IncludeStack.back().TheLexer;
|
||||
IncludeStack.pop_back();
|
||||
while (!IncludeMacroStack.empty()) {
|
||||
delete IncludeMacroStack.back().TheLexer;
|
||||
delete IncludeMacroStack.back().TheMacroExpander;
|
||||
IncludeMacroStack.pop_back();
|
||||
}
|
||||
|
||||
// Release pragma information.
|
||||
|
@ -206,8 +205,6 @@ void Preprocessor::PrintStats() {
|
|||
|
||||
std::cerr << NumMacroExpanded << " macros expanded, "
|
||||
<< NumFastMacroExpanded << " on the fast path.\n";
|
||||
if (MaxMacroStackDepth > 1)
|
||||
std::cerr << " " << MaxMacroStackDepth << " max macroexpand stack depth\n";
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -356,22 +353,30 @@ const FileEntry *Preprocessor::LookupFile(const std::string &Filename,
|
|||
/// on failure.
|
||||
void Preprocessor::EnterSourceFile(unsigned FileID,
|
||||
const DirectoryLookup *CurDir) {
|
||||
assert(CurMacroExpander == 0 && "Cannot #include a file inside a macro!");
|
||||
++NumEnteredSourceFiles;
|
||||
|
||||
// Add the current lexer to the include stack.
|
||||
if (CurLexer) {
|
||||
IncludeStack.push_back(IncludeStackInfo(CurLexer, CurDirLookup));
|
||||
} else {
|
||||
assert(CurMacroExpander == 0 && "Cannot #include a file inside a macro!");
|
||||
}
|
||||
if (MaxIncludeStackDepth < IncludeMacroStack.size())
|
||||
MaxIncludeStackDepth = IncludeMacroStack.size();
|
||||
|
||||
if (MaxIncludeStackDepth < IncludeStack.size())
|
||||
MaxIncludeStackDepth = IncludeStack.size();
|
||||
|
||||
const SourceBuffer *Buffer = SourceMgr.getBuffer(FileID);
|
||||
Lexer *TheLexer = new Lexer(Buffer, FileID, *this);
|
||||
EnterSourceFileWithLexer(TheLexer, CurDir);
|
||||
}
|
||||
|
||||
CurLexer = new Lexer(Buffer, FileID, *this);
|
||||
/// EnterSourceFile - Add a source file to the top of the include stack and
|
||||
/// start lexing tokens from it instead of the current buffer.
|
||||
void Preprocessor::EnterSourceFileWithLexer(Lexer *TheLexer,
|
||||
const DirectoryLookup *CurDir) {
|
||||
|
||||
// Add the current lexer to the include stack.
|
||||
if (CurLexer || CurMacroExpander)
|
||||
IncludeMacroStack.push_back(IncludeStackInfo(CurLexer, CurDirLookup,
|
||||
CurMacroExpander));
|
||||
|
||||
CurLexer = TheLexer;
|
||||
CurDirLookup = CurDir;
|
||||
CurMacroExpander = 0;
|
||||
|
||||
// Notify the client, if desired, that we are in a new source file.
|
||||
if (FileChangeHandler) {
|
||||
|
@ -387,21 +392,17 @@ void Preprocessor::EnterSourceFile(unsigned FileID,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// EnterMacro - Add a Macro to the top of the include stack and start lexing
|
||||
/// tokens from it instead of the current buffer.
|
||||
void Preprocessor::EnterMacro(LexerToken &Tok) {
|
||||
IdentifierTokenInfo *Identifier = Tok.getIdentifierInfo();
|
||||
MacroInfo &MI = *Identifier->getMacroInfo();
|
||||
if (CurLexer) {
|
||||
IncludeStack.push_back(IncludeStackInfo(CurLexer, CurDirLookup));
|
||||
CurLexer = 0;
|
||||
CurDirLookup = 0;
|
||||
} else if (CurMacroExpander) {
|
||||
MacroStack.push_back(CurMacroExpander);
|
||||
}
|
||||
|
||||
if (MaxMacroStackDepth < MacroStack.size())
|
||||
MaxMacroStackDepth = MacroStack.size();
|
||||
IncludeMacroStack.push_back(IncludeStackInfo(CurLexer, CurDirLookup,
|
||||
CurMacroExpander));
|
||||
CurLexer = 0;
|
||||
CurDirLookup = 0;
|
||||
|
||||
// TODO: Figure out arguments.
|
||||
|
||||
|
@ -432,18 +433,18 @@ IdentifierTokenInfo *Preprocessor::RegisterBuiltinMacro(const char *Name) {
|
|||
/// RegisterBuiltinMacros - Register builtin macros, such as __LINE__ with the
|
||||
/// identifier table.
|
||||
void Preprocessor::RegisterBuiltinMacros() {
|
||||
// FIXME: implement them all, including _Pragma.
|
||||
Ident__LINE__ = RegisterBuiltinMacro("__LINE__");
|
||||
Ident__FILE__ = RegisterBuiltinMacro("__FILE__");
|
||||
Ident__DATE__ = RegisterBuiltinMacro("__DATE__");
|
||||
Ident__TIME__ = RegisterBuiltinMacro("__TIME__");
|
||||
Ident_Pragma = RegisterBuiltinMacro("_Pragma");
|
||||
|
||||
// GCC Extensions.
|
||||
Ident__BASE_FILE__ = RegisterBuiltinMacro("__BASE_FILE__");
|
||||
Ident__INCLUDE_LEVEL__ = RegisterBuiltinMacro("__INCLUDE_LEVEL__");
|
||||
Ident__TIMESTAMP__ = RegisterBuiltinMacro("__TIMESTAMP__");
|
||||
// _Pragma
|
||||
|
||||
// FIXME: implement them all:
|
||||
//Pseudo #defines.
|
||||
// __STDC__ 1 if !stdc_0_in_system_headers and "std"
|
||||
// __STDC_VERSION__
|
||||
|
@ -457,12 +458,14 @@ void Preprocessor::RegisterBuiltinMacros() {
|
|||
void Preprocessor::HandleMacroExpandedIdentifier(LexerToken &Identifier,
|
||||
MacroInfo *MI) {
|
||||
++NumMacroExpanded;
|
||||
// If we started lexing a macro, enter the macro expansion body.
|
||||
// FIXME: Read/Validate the argument list here!
|
||||
|
||||
// If this is a builtin macro, like __LINE__ or _Pragma, handle it specially.
|
||||
if (MI->isBuiltinMacro())
|
||||
return ExpandBuiltinMacro(Identifier, MI);
|
||||
return ExpandBuiltinMacro(Identifier);
|
||||
|
||||
// If we started lexing a macro, enter the macro expansion body.
|
||||
// FIXME: Read/Validate the argument list here!
|
||||
|
||||
|
||||
// If this macro expands to no tokens, don't bother to push it onto the
|
||||
// expansion stack, only to take it right back off.
|
||||
|
@ -553,13 +556,19 @@ static void ComputeDATE_TIME(SourceLocation &DATELoc, SourceLocation &TIMELoc,
|
|||
|
||||
/// ExpandBuiltinMacro - If an identifier token is read that is to be expanded
|
||||
/// as a builtin macro, handle it and return the next token as 'Tok'.
|
||||
void Preprocessor::ExpandBuiltinMacro(LexerToken &Tok, MacroInfo *MI) {
|
||||
void Preprocessor::ExpandBuiltinMacro(LexerToken &Tok) {
|
||||
// Figure out which token this is.
|
||||
IdentifierTokenInfo *ITI = Tok.getIdentifierInfo();
|
||||
assert(ITI && "Can't be a macro without id info!");
|
||||
|
||||
// If this is an _Pragma directive, expand it, invoke the pragma handler, then
|
||||
// lex the token after it.
|
||||
if (ITI == Ident_Pragma)
|
||||
return Handle_Pragma(Tok);
|
||||
|
||||
char TmpBuffer[100];
|
||||
|
||||
|
||||
|
||||
// Set up the return result.
|
||||
Tok.SetIdentifierInfo(0);
|
||||
Tok.ClearFlag(LexerToken::NeedsCleaning);
|
||||
|
||||
|
@ -621,9 +630,7 @@ void Preprocessor::ExpandBuiltinMacro(LexerToken &Tok, MacroInfo *MI) {
|
|||
// Get the file that we are lexing out of. If we're currently lexing from
|
||||
// a macro, dig into the include stack.
|
||||
const FileEntry *CurFile = 0;
|
||||
Lexer *TheLexer = CurLexer;
|
||||
if (TheLexer == 0 && !IncludeStack.empty())
|
||||
TheLexer = IncludeStack.back().TheLexer;
|
||||
Lexer *TheLexer = getCurrentLexer();
|
||||
|
||||
if (TheLexer)
|
||||
CurFile = SourceMgr.getFileEntryForFileID(TheLexer->getCurFileID());
|
||||
|
@ -703,15 +710,16 @@ void Preprocessor::HandleEndOfFile(LexerToken &Result, bool isEndOfMacro) {
|
|||
|
||||
// If this is a #include'd file, pop it off the include stack and continue
|
||||
// lexing the #includer file.
|
||||
if (!IncludeStack.empty()) {
|
||||
if (!IncludeMacroStack.empty()) {
|
||||
// We're done with the #included file.
|
||||
delete CurLexer;
|
||||
CurLexer = IncludeStack.back().TheLexer;
|
||||
CurDirLookup = IncludeStack.back().TheDirLookup;
|
||||
IncludeStack.pop_back();
|
||||
CurLexer = IncludeMacroStack.back().TheLexer;
|
||||
CurDirLookup = IncludeMacroStack.back().TheDirLookup;
|
||||
CurMacroExpander = IncludeMacroStack.back().TheMacroExpander;
|
||||
IncludeMacroStack.pop_back();
|
||||
|
||||
// Notify the client, if desired, that we are in a new source file.
|
||||
if (FileChangeHandler && !isEndOfMacro) {
|
||||
if (FileChangeHandler && !isEndOfMacro && CurLexer) {
|
||||
DirectoryLookup::DirType FileType = DirectoryLookup::NormalHeaderDir;
|
||||
|
||||
// Get the file entry for the current file.
|
||||
|
@ -746,16 +754,9 @@ void Preprocessor::HandleEndOfMacro(LexerToken &Result) {
|
|||
CurMacroExpander->getMacro().EnableMacro();
|
||||
delete CurMacroExpander;
|
||||
|
||||
if (!MacroStack.empty()) {
|
||||
// In a nested macro invocation, continue lexing from the macro.
|
||||
CurMacroExpander = MacroStack.back();
|
||||
MacroStack.pop_back();
|
||||
return Lex(Result);
|
||||
} else {
|
||||
CurMacroExpander = 0;
|
||||
// Handle this like a #include file being popped off the stack.
|
||||
return HandleEndOfFile(Result, true);
|
||||
}
|
||||
// Handle this like a #include file being popped off the stack.
|
||||
CurMacroExpander = 0;
|
||||
return HandleEndOfFile(Result, true);
|
||||
}
|
||||
|
||||
|
||||
|
@ -831,7 +832,7 @@ void Preprocessor::SkipExcludedConditionalBlock(SourceLocation IfTokenLoc,
|
|||
bool FoundNonSkipPortion,
|
||||
bool FoundElse) {
|
||||
++NumSkipped;
|
||||
assert(MacroStack.empty() && CurMacroExpander == 0 && CurLexer &&
|
||||
assert(CurMacroExpander == 0 && CurLexer &&
|
||||
"Lexing a macro, not a file?");
|
||||
|
||||
CurLexer->pushConditionalLevel(IfTokenLoc, /*isSkipping*/false,
|
||||
|
@ -1059,7 +1060,7 @@ void Preprocessor::HandleDirective(LexerToken &Result) {
|
|||
if (Directive[0] == 'i' && !strcmp(Directive, "import"))
|
||||
return HandleImportDirective(Result);
|
||||
if (Directive[0] == 'p' && !strcmp(Directive, "pragma"))
|
||||
return HandlePragmaDirective(Result);
|
||||
return HandlePragmaDirective();
|
||||
if (Directive[0] == 'a' && !strcmp(Directive, "assert"))
|
||||
isExtension = true; // FIXME: implement #assert
|
||||
break;
|
||||
|
@ -1132,7 +1133,7 @@ void Preprocessor::HandleIncludeDirective(LexerToken &IncludeTok,
|
|||
CheckEndOfDirective("#include");
|
||||
|
||||
// Check that we don't have infinite #include recursion.
|
||||
if (IncludeStack.size() == MaxAllowedIncludeStackDepth-1)
|
||||
if (IncludeMacroStack.size() == MaxAllowedIncludeStackDepth-1)
|
||||
return Diag(FilenameTok, diag::err_pp_include_too_deep);
|
||||
|
||||
// Find out whether the filename is <x> or "x".
|
||||
|
@ -1187,7 +1188,7 @@ void Preprocessor::HandleIncludeNextDirective(LexerToken &IncludeNextTok) {
|
|||
// the current found directory. If we can't do this, issue a
|
||||
// diagnostic.
|
||||
const DirectoryLookup *Lookup = CurDirLookup;
|
||||
if (IncludeStack.empty()) {
|
||||
if (isInPrimaryFile()) {
|
||||
Lookup = 0;
|
||||
Diag(IncludeNextTok, diag::pp_include_next_in_primary);
|
||||
} else if (Lookup == 0) {
|
||||
|
@ -1425,10 +1426,9 @@ void Preprocessor::HandleElifDirective(LexerToken &ElifToken) {
|
|||
// Preprocessor Pragma Directive Handling.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/// HandlePragmaDirective - The "#pragma" directive has been parsed with
|
||||
/// PragmaTok containing the "pragma" identifier. Lex the rest of the pragma,
|
||||
/// passing it to the registered pragma handlers.
|
||||
void Preprocessor::HandlePragmaDirective(LexerToken &PragmaTok) {
|
||||
/// HandlePragmaDirective - The "#pragma" directive has been parsed. Lex the
|
||||
/// rest of the pragma, passing it to the registered pragma handlers.
|
||||
void Preprocessor::HandlePragmaDirective() {
|
||||
++NumPragma;
|
||||
|
||||
// Invoke the first level of pragma handlers which reads the namespace id.
|
||||
|
@ -1440,10 +1440,89 @@ void Preprocessor::HandlePragmaDirective(LexerToken &PragmaTok) {
|
|||
DiscardUntilEndOfDirective();
|
||||
}
|
||||
|
||||
/// Handle_Pragma - Read a _Pragma directive, slice it up, process it, then
|
||||
/// return the first token after the directive. The _Pragma token has just
|
||||
/// been read into 'Tok'.
|
||||
void Preprocessor::Handle_Pragma(LexerToken &Tok) {
|
||||
// Remember the pragma token location.
|
||||
SourceLocation PragmaLoc = Tok.getLocation();
|
||||
|
||||
// Read the '('.
|
||||
Lex(Tok);
|
||||
if (Tok.getKind() != tok::l_paren)
|
||||
return Diag(PragmaLoc, diag::err__Pragma_malformed);
|
||||
|
||||
// Read the '"..."'.
|
||||
Lex(Tok);
|
||||
if (Tok.getKind() != tok::string_literal)
|
||||
return Diag(PragmaLoc, diag::err__Pragma_malformed);
|
||||
|
||||
// Remember the string.
|
||||
std::string StrVal = getSpelling(Tok);
|
||||
SourceLocation StrLoc = Tok.getLocation();
|
||||
|
||||
// Read the ')'.
|
||||
Lex(Tok);
|
||||
if (Tok.getKind() != tok::r_paren)
|
||||
return Diag(PragmaLoc, diag::err__Pragma_malformed);
|
||||
|
||||
// The _Pragma is lexically sound. Destringize according to C99 6.10.9.1.
|
||||
if (StrVal[0] == 'L') // Remove L prefix.
|
||||
StrVal.erase(StrVal.begin());
|
||||
assert(StrVal[0] == '"' && StrVal[StrVal.size()-1] == '"' &&
|
||||
"Invalid string token!");
|
||||
|
||||
// Remove the front quote, replacing it with a space, so that the pragma
|
||||
// contents appear to have a space before them.
|
||||
StrVal[0] = ' ';
|
||||
|
||||
// Replace the terminating quote with a \n\0.
|
||||
StrVal[StrVal.size()-1] = '\n';
|
||||
StrVal += '\0';
|
||||
|
||||
// Remove escaped quotes and escapes.
|
||||
for (unsigned i = 0, e = StrVal.size(); i != e-1; ++i) {
|
||||
if (StrVal[i] == '\\' &&
|
||||
(StrVal[i+1] == '\\' || StrVal[i+1] == '"')) {
|
||||
// \\ -> '\' and \" -> '"'.
|
||||
StrVal.erase(StrVal.begin()+i);
|
||||
--e;
|
||||
}
|
||||
}
|
||||
|
||||
// Plop the string (including the trailing null) into a buffer where we can
|
||||
// lex it.
|
||||
SourceLocation TokLoc = ScratchBuf->getToken(&StrVal[0], StrVal.size());
|
||||
const char *StrData = SourceMgr.getCharacterData(TokLoc);
|
||||
|
||||
// FIXME: Create appropriate mapping info for this FileID, so that we know the
|
||||
// tokens are coming out of the input string (StrLoc).
|
||||
unsigned FileID = TokLoc.getFileID();
|
||||
assert(FileID && "Could not create FileID for predefines?");
|
||||
|
||||
// Make and enter a lexer object so that we lex and expand the tokens just
|
||||
// like any others.
|
||||
Lexer *TL = new Lexer(SourceMgr.getBuffer(FileID), FileID, *this,
|
||||
StrData, StrData+StrVal.size()-1 /* no null */);
|
||||
EnterSourceFileWithLexer(TL, 0);
|
||||
|
||||
// Ensure that the lexer thinks it is inside a directive, so that end \n will
|
||||
// return an EOM token.
|
||||
TL->ParsingPreprocessorDirective = true;
|
||||
|
||||
// With everything set up, lex this as a #pragma directive.
|
||||
HandlePragmaDirective();
|
||||
|
||||
// Finally, return whatever came after the pragma directive.
|
||||
return Lex(Tok);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// HandlePragmaOnce - Handle #pragma once. OnceTok is the 'once'.
|
||||
///
|
||||
void Preprocessor::HandlePragmaOnce(LexerToken &OnceTok) {
|
||||
if (IncludeStack.empty()) {
|
||||
if (isInPrimaryFile()) {
|
||||
Diag(OnceTok, diag::pp_pragma_once_in_main_file);
|
||||
return;
|
||||
}
|
||||
|
@ -1501,7 +1580,7 @@ void Preprocessor::HandlePragmaPoison(LexerToken &PoisonTok) {
|
|||
/// HandlePragmaSystemHeader - Implement #pragma GCC system_header. We know
|
||||
/// that the whole directive has been parsed.
|
||||
void Preprocessor::HandlePragmaSystemHeader(LexerToken &SysHeaderTok) {
|
||||
if (IncludeStack.empty()) {
|
||||
if (isInPrimaryFile()) {
|
||||
Diag(SysHeaderTok, diag::pp_pragma_sysheader_in_main_file);
|
||||
return;
|
||||
}
|
||||
|
@ -1540,11 +1619,7 @@ void Preprocessor::HandlePragmaDependency(LexerToken &DependencyTok) {
|
|||
if (File == 0)
|
||||
return Diag(FilenameTok, diag::err_pp_file_not_found);
|
||||
|
||||
Lexer *TheLexer = CurLexer;
|
||||
if (TheLexer == 0) {
|
||||
assert(!IncludeStack.empty() && "No current lexer?");
|
||||
TheLexer = IncludeStack.back().TheLexer;
|
||||
}
|
||||
Lexer *TheLexer = getCurrentLexer();
|
||||
const FileEntry *CurFile =
|
||||
SourceMgr.getFileEntryForFileID(TheLexer->getCurFileID());
|
||||
|
||||
|
|
|
@ -171,6 +171,8 @@ DIAG(err_pp_invalid_poison, ERROR,
|
|||
"can only poison identifier tokens")
|
||||
DIAG(err_pp_used_poisoned_id, ERROR,
|
||||
"attempt to use a poisoned identifier")
|
||||
DIAG(err__Pragma_malformed, ERROR,
|
||||
"_Pragma takes a parenthesized string literal")
|
||||
|
||||
// Should be a sorry?
|
||||
DIAG(err_pp_I_dash_not_supported, ERROR,
|
||||
|
|
|
@ -98,6 +98,7 @@ class Preprocessor {
|
|||
IdentifierTokenInfo *Ident__INCLUDE_LEVEL__; // __INCLUDE_LEVEL__
|
||||
IdentifierTokenInfo *Ident__BASE_FILE__; // __BASE_FILE__
|
||||
IdentifierTokenInfo *Ident__TIMESTAMP__; // __TIMESTAMP__
|
||||
IdentifierTokenInfo *Ident_Pragma; // _Pragma
|
||||
|
||||
SourceLocation DATELoc, TIMELoc;
|
||||
public:
|
||||
|
@ -138,25 +139,23 @@ private:
|
|||
/// FileEntry, if CurLexer is non-null and if applicable. This allows us to
|
||||
/// implement #include_next and find directory-specific properties.
|
||||
const DirectoryLookup *CurDirLookup;
|
||||
|
||||
/// IncludeStack - This keeps track of the stack of files currently #included,
|
||||
/// not counting CurLexer.
|
||||
struct IncludeStackInfo {
|
||||
Lexer *TheLexer;
|
||||
const DirectoryLookup *TheDirLookup;
|
||||
IncludeStackInfo(Lexer *L, const DirectoryLookup *D)
|
||||
: TheLexer(L), TheDirLookup(D) {
|
||||
}
|
||||
};
|
||||
std::vector<IncludeStackInfo> IncludeStack;
|
||||
|
||||
|
||||
/// CurMacroExpander - This is the current macro we are expanding, if we are
|
||||
/// expanding a macro. One of CurLexer and CurMacroExpander must be null.
|
||||
MacroExpander *CurMacroExpander;
|
||||
|
||||
/// MacroStack - This keeps track of the macros that are recursively being
|
||||
/// expanded.
|
||||
std::vector<MacroExpander*> MacroStack;
|
||||
/// IncludeMacroStack - This keeps track of the stack of files currently
|
||||
/// #included, and macros currently being expanded from, not counting
|
||||
/// CurLexer/CurMacroExpander.
|
||||
struct IncludeStackInfo {
|
||||
Lexer *TheLexer;
|
||||
const DirectoryLookup *TheDirLookup;
|
||||
MacroExpander *TheMacroExpander;
|
||||
IncludeStackInfo(Lexer *L, const DirectoryLookup *D, MacroExpander *M)
|
||||
: TheLexer(L), TheDirLookup(D), TheMacroExpander(M) {
|
||||
}
|
||||
};
|
||||
std::vector<IncludeStackInfo> IncludeMacroStack;
|
||||
|
||||
|
||||
/// PreFileInfo - The preprocessor keeps track of this information for each
|
||||
|
@ -187,7 +186,7 @@ private:
|
|||
unsigned NumDirectives, NumIncluded, NumDefined, NumUndefined, NumPragma;
|
||||
unsigned NumIf, NumElse, NumEndif;
|
||||
unsigned NumEnteredSourceFiles, MaxIncludeStackDepth;
|
||||
unsigned NumMacroExpanded, NumFastMacroExpanded, MaxMacroStackDepth;
|
||||
unsigned NumMacroExpanded, NumFastMacroExpanded;
|
||||
unsigned NumSkipped;
|
||||
public:
|
||||
Preprocessor(Diagnostic &diags, const LangOptions &opts, FileManager &FM,
|
||||
|
@ -211,6 +210,29 @@ public:
|
|||
return CurLexer == L;
|
||||
}
|
||||
|
||||
/// isInPrimaryFile - Return true if we're in the top-level file, not in a
|
||||
/// #include.
|
||||
///
|
||||
bool isInPrimaryFile() const {
|
||||
/// If there are any stacked lexers, we're in a #include.
|
||||
for (unsigned i = 0, e = IncludeMacroStack.size(); i != e; ++i)
|
||||
if (IncludeMacroStack[i].TheLexer)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// getCurrentLexer - Return the current lexer being lexed from. Note that
|
||||
/// this ignores any potentially active macro expansions going on at the time.
|
||||
Lexer *getCurrentLexer() const {
|
||||
if (CurLexer) return CurLexer;
|
||||
|
||||
// Look for a stacked lexer.
|
||||
for (unsigned i = IncludeMacroStack.size(); i != 0; --i)
|
||||
if (IncludeMacroStack[i].TheLexer) // Ignore macro expansions.
|
||||
return IncludeMacroStack[i].TheLexer;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// SetSearchPaths - Interface for setting the file search paths.
|
||||
///
|
||||
void SetSearchPaths(const std::vector<DirectoryLookup> &dirs,
|
||||
|
@ -423,7 +445,17 @@ private:
|
|||
|
||||
/// ExpandBuiltinMacro - If an identifier token is read that is to be expanded
|
||||
/// as a builtin macro, handle it and return the next token as 'Tok'.
|
||||
void ExpandBuiltinMacro(LexerToken &Tok, MacroInfo *MI);
|
||||
void ExpandBuiltinMacro(LexerToken &Tok);
|
||||
|
||||
/// Handle_Pragma - Read a _Pragma directive, slice it up, process it, then
|
||||
/// return the first token after the directive. The _Pragma token has just
|
||||
/// been read into 'Tok'.
|
||||
void Handle_Pragma(LexerToken &Tok);
|
||||
|
||||
|
||||
/// EnterSourceFile - Add a source file to the top of the include stack and
|
||||
/// start lexing tokens from it instead of the current buffer.
|
||||
void EnterSourceFileWithLexer(Lexer *TheLexer, const DirectoryLookup *Dir);
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
/// Handle*Directive - implement the various preprocessor directives. These
|
||||
|
@ -453,7 +485,7 @@ private:
|
|||
void HandleElifDirective(LexerToken &Tok);
|
||||
|
||||
// Pragmas.
|
||||
void HandlePragmaDirective(LexerToken &Result);
|
||||
void HandlePragmaDirective();
|
||||
public:
|
||||
void HandlePragmaOnce(LexerToken &OnceTok);
|
||||
void HandlePragmaPoison(LexerToken &PoisonTok);
|
||||
|
|
Loading…
Reference in New Issue