forked from OSchip/llvm-project
Re-arranged some internal functions for coming __has_include changes.
llvm-svn: 85589
This commit is contained in:
parent
305f9f8fed
commit
b535352681
|
@ -194,7 +194,7 @@ def err_pp_expected_eol : Error<
|
|||
"expected end of line in preprocessor expression">;
|
||||
def err_pp_defined_requires_identifier : Error<
|
||||
"operator 'defined' requires an identifier">;
|
||||
def err_pp_missing_rparen : Error<"missing ')' after 'defined'">;
|
||||
def err_pp_missing_rparen : Error<"missing ')' after '%0'">;
|
||||
def err_pp_colon_without_question : Error<"':' without preceding '?'">;
|
||||
def err_pp_division_by_zero : Error<
|
||||
"division by zero in preprocessor expression">;
|
||||
|
|
|
@ -244,7 +244,12 @@ public:
|
|||
return CurPPLexer == L;
|
||||
}
|
||||
|
||||
/// getCurrentLexer - Return the current file lexer being lexed from. Note
|
||||
/// getCurrentLexer - Return the current lexer being lexed from. Note
|
||||
/// that this ignores any potentially active macro expansions and _Pragma
|
||||
/// expansions going on at the time.
|
||||
PreprocessorLexer *getCurrentLexer() const { return CurPPLexer; }
|
||||
|
||||
/// getCurrentFileLexer - 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.
|
||||
PreprocessorLexer *getCurrentFileLexer() const;
|
||||
|
@ -622,6 +627,43 @@ public:
|
|||
/// SourceLocation.
|
||||
MacroInfo* AllocateMacroInfo(SourceLocation L);
|
||||
|
||||
/// GetIncludeFilenameSpelling - Turn the specified lexer token into a fully
|
||||
/// checked and spelled filename, e.g. as an operand of #include. This returns
|
||||
/// true if the input filename was in <>'s or false if it were in ""'s. The
|
||||
/// caller is expected to provide a buffer that is large enough to hold the
|
||||
/// spelling of the filename, but is also expected to handle the case when
|
||||
/// this method decides to use a different buffer.
|
||||
bool GetIncludeFilenameSpelling(SourceLocation Loc,
|
||||
const char *&BufStart, const char *&BufEnd);
|
||||
|
||||
/// LookupFile - Given a "foo" or <foo> reference, look up the indicated file,
|
||||
/// return null on failure. isAngled indicates whether the file reference is
|
||||
/// for system #include's or not (i.e. using <> instead of "").
|
||||
const FileEntry *LookupFile(const char *FilenameStart,const char *FilenameEnd,
|
||||
bool isAngled, const DirectoryLookup *FromDir,
|
||||
const DirectoryLookup *&CurDir);
|
||||
|
||||
/// GetCurLookup - The DirectoryLookup structure used to find the current
|
||||
/// FileEntry, if CurLexer is non-null and if applicable. This allows us to
|
||||
/// implement #include_next and find directory-specific properties.
|
||||
const DirectoryLookup *GetCurDirLookup() { return CurDirLookup; }
|
||||
|
||||
/// isInPrimaryFile - Return true if we're in the top-level file, not in a
|
||||
/// #include.
|
||||
bool isInPrimaryFile() const;
|
||||
|
||||
/// ConcatenateIncludeName - Handle cases where the #include name is expanded
|
||||
/// from a macro as multiple tokens, which need to be glued together. This
|
||||
/// occurs for code like:
|
||||
/// #define FOO <a/b.h>
|
||||
/// #include FOO
|
||||
/// because in this case, "<a/b.h>" is returned as 7 tokens, not one.
|
||||
///
|
||||
/// This code concatenates and consumes tokens up to the '>' token. It returns
|
||||
/// false if the > was found, otherwise it returns true if it finds and consumes
|
||||
/// the EOM marker.
|
||||
bool ConcatenateIncludeName(llvm::SmallVector<char, 128> &FilenameBuffer);
|
||||
|
||||
private:
|
||||
|
||||
void PushIncludeMacroStack() {
|
||||
|
@ -646,10 +688,6 @@ private:
|
|||
/// be reused for allocating new MacroInfo objects.
|
||||
void ReleaseMacroInfo(MacroInfo* MI);
|
||||
|
||||
/// isInPrimaryFile - Return true if we're in the top-level file, not in a
|
||||
/// #include.
|
||||
bool isInPrimaryFile() const;
|
||||
|
||||
/// ReadMacroName - Lex and validate a macro name, which occurs after a
|
||||
/// #define or #undef. This emits a diagnostic, sets the token kind to eom,
|
||||
/// and discards the rest of the macro line if the macro name is invalid.
|
||||
|
@ -722,24 +760,6 @@ private:
|
|||
/// start getting tokens from it using the PTH cache.
|
||||
void EnterSourceFileWithPTH(PTHLexer *PL, const DirectoryLookup *Dir);
|
||||
|
||||
/// GetIncludeFilenameSpelling - Turn the specified lexer token into a fully
|
||||
/// checked and spelled filename, e.g. as an operand of #include. This returns
|
||||
/// true if the input filename was in <>'s or false if it were in ""'s. The
|
||||
/// caller is expected to provide a buffer that is large enough to hold the
|
||||
/// spelling of the filename, but is also expected to handle the case when
|
||||
/// this method decides to use a different buffer.
|
||||
bool GetIncludeFilenameSpelling(SourceLocation Loc,
|
||||
const char *&BufStart, const char *&BufEnd);
|
||||
|
||||
/// LookupFile - Given a "foo" or <foo> reference, look up the indicated file,
|
||||
/// return null on failure. isAngled indicates whether the file reference is
|
||||
/// for system #include's or not (i.e. using <> instead of "").
|
||||
const FileEntry *LookupFile(const char *FilenameStart,const char *FilenameEnd,
|
||||
bool isAngled, const DirectoryLookup *FromDir,
|
||||
const DirectoryLookup *&CurDir);
|
||||
|
||||
|
||||
|
||||
/// IsFileLexer - Returns true if we are lexing from a file and not a
|
||||
/// pragma or a macro.
|
||||
static bool IsFileLexer(const Lexer* L, const PreprocessorLexer* P) {
|
||||
|
|
|
@ -974,11 +974,11 @@ bool Preprocessor::GetIncludeFilenameSpelling(SourceLocation Loc,
|
|||
/// This code concatenates and consumes tokens up to the '>' token. It returns
|
||||
/// false if the > was found, otherwise it returns true if it finds and consumes
|
||||
/// the EOM marker.
|
||||
static bool ConcatenateIncludeName(llvm::SmallVector<char, 128> &FilenameBuffer,
|
||||
Preprocessor &PP) {
|
||||
bool Preprocessor::ConcatenateIncludeName(
|
||||
llvm::SmallVector<char, 128> &FilenameBuffer) {
|
||||
Token CurTok;
|
||||
|
||||
PP.Lex(CurTok);
|
||||
Lex(CurTok);
|
||||
while (CurTok.isNot(tok::eom)) {
|
||||
// Append the spelling of this token to the buffer. If there was a space
|
||||
// before it, add it now.
|
||||
|
@ -990,7 +990,7 @@ static bool ConcatenateIncludeName(llvm::SmallVector<char, 128> &FilenameBuffer,
|
|||
FilenameBuffer.resize(PreAppendSize+CurTok.getLength());
|
||||
|
||||
const char *BufPtr = &FilenameBuffer[PreAppendSize];
|
||||
unsigned ActualLen = PP.getSpelling(CurTok, BufPtr);
|
||||
unsigned ActualLen = getSpelling(CurTok, BufPtr);
|
||||
|
||||
// If the token was spelled somewhere else, copy it into FilenameBuffer.
|
||||
if (BufPtr != &FilenameBuffer[PreAppendSize])
|
||||
|
@ -1004,12 +1004,12 @@ static bool ConcatenateIncludeName(llvm::SmallVector<char, 128> &FilenameBuffer,
|
|||
if (CurTok.is(tok::greater))
|
||||
return false;
|
||||
|
||||
PP.Lex(CurTok);
|
||||
Lex(CurTok);
|
||||
}
|
||||
|
||||
// If we hit the eom marker, emit an error and return true so that the caller
|
||||
// knows the EOM has been read.
|
||||
PP.Diag(CurTok.getLocation(), diag::err_pp_expects_filename);
|
||||
Diag(CurTok.getLocation(), diag::err_pp_expects_filename);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1047,7 +1047,7 @@ void Preprocessor::HandleIncludeDirective(Token &IncludeTok,
|
|||
// This could be a <foo/bar.h> file coming from a macro expansion. In this
|
||||
// case, glue the tokens together into FilenameBuffer and interpret those.
|
||||
FilenameBuffer.push_back('<');
|
||||
if (ConcatenateIncludeName(FilenameBuffer, *this))
|
||||
if (ConcatenateIncludeName(FilenameBuffer))
|
||||
return; // Found <eom> but no ">"? Diagnostic already emitted.
|
||||
FilenameStart = FilenameBuffer.data();
|
||||
FilenameEnd = FilenameStart + FilenameBuffer.size();
|
||||
|
|
|
@ -71,6 +71,61 @@ struct DefinedTracker {
|
|||
IdentifierInfo *TheMacro;
|
||||
};
|
||||
|
||||
/// EvaluateDefined - Process a 'defined(sym)' expression.
|
||||
static bool EvaluateDefined(PPValue &Result, Token &PeekTok,
|
||||
DefinedTracker &DT, bool ValueLive, Preprocessor &PP) {
|
||||
IdentifierInfo *II;
|
||||
Result.setBegin(PeekTok.getLocation());
|
||||
|
||||
// Get the next token, don't expand it.
|
||||
PP.LexUnexpandedToken(PeekTok);
|
||||
|
||||
// Two options, it can either be a pp-identifier or a (.
|
||||
SourceLocation LParenLoc;
|
||||
if (PeekTok.is(tok::l_paren)) {
|
||||
// Found a paren, remember we saw it and skip it.
|
||||
LParenLoc = PeekTok.getLocation();
|
||||
PP.LexUnexpandedToken(PeekTok);
|
||||
}
|
||||
|
||||
// If we don't have a pp-identifier now, this is an error.
|
||||
if ((II = PeekTok.getIdentifierInfo()) == 0) {
|
||||
PP.Diag(PeekTok, diag::err_pp_defined_requires_identifier);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Otherwise, we got an identifier, is it defined to something?
|
||||
Result.Val = II->hasMacroDefinition();
|
||||
Result.Val.setIsUnsigned(false); // Result is signed intmax_t.
|
||||
|
||||
// If there is a macro, mark it used.
|
||||
if (Result.Val != 0 && ValueLive) {
|
||||
MacroInfo *Macro = PP.getMacroInfo(II);
|
||||
Macro->setIsUsed(true);
|
||||
}
|
||||
|
||||
// Consume identifier.
|
||||
Result.setEnd(PeekTok.getLocation());
|
||||
PP.LexNonComment(PeekTok);
|
||||
|
||||
// If we are in parens, ensure we have a trailing ).
|
||||
if (LParenLoc.isValid()) {
|
||||
if (PeekTok.isNot(tok::r_paren)) {
|
||||
PP.Diag(PeekTok.getLocation(), diag::err_pp_missing_rparen) << "defined";
|
||||
PP.Diag(LParenLoc, diag::note_matching) << "(";
|
||||
return true;
|
||||
}
|
||||
// Consume the ).
|
||||
Result.setEnd(PeekTok.getLocation());
|
||||
PP.LexNonComment(PeekTok);
|
||||
}
|
||||
|
||||
// Success, remember that we saw defined(X).
|
||||
DT.State = DefinedTracker::DefinedMacro;
|
||||
DT.TheMacro = II;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// EvaluateValue - Evaluate the token PeekTok (and any others needed) and
|
||||
/// return the computed value in Result. Return true if there was an error
|
||||
/// parsing. This function also returns information about the form of the
|
||||
|
@ -87,10 +142,14 @@ static bool EvaluateValue(PPValue &Result, Token &PeekTok, DefinedTracker &DT,
|
|||
// 'defined' or if it is a macro. Note that we check here because many
|
||||
// keywords are pp-identifiers, so we can't check the kind.
|
||||
if (IdentifierInfo *II = PeekTok.getIdentifierInfo()) {
|
||||
// If this identifier isn't 'defined' and it wasn't macro expanded, it turns
|
||||
// into a simple 0, unless it is the C++ keyword "true", in which case it
|
||||
// turns into "1".
|
||||
if (!II->isStr("defined")) {
|
||||
if (II->isStr("defined")) {
|
||||
// Handle "defined X" and "defined(X)".
|
||||
return(EvaluateDefined(Result, PeekTok, DT, ValueLive, PP));
|
||||
} else {
|
||||
// If this identifier isn't 'defined' or one of the special
|
||||
// preprocessor keywords and it wasn't macro expanded, it turns
|
||||
// into a simple 0, unless it is the C++ keyword "true", in which case it
|
||||
// turns into "1".
|
||||
if (ValueLive)
|
||||
PP.Diag(PeekTok, diag::warn_pp_undef_identifier) << II;
|
||||
Result.Val = II->getTokenID() == tok::kw_true;
|
||||
|
@ -99,57 +158,6 @@ static bool EvaluateValue(PPValue &Result, Token &PeekTok, DefinedTracker &DT,
|
|||
PP.LexNonComment(PeekTok);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Handle "defined X" and "defined(X)".
|
||||
Result.setBegin(PeekTok.getLocation());
|
||||
|
||||
// Get the next token, don't expand it.
|
||||
PP.LexUnexpandedToken(PeekTok);
|
||||
|
||||
// Two options, it can either be a pp-identifier or a (.
|
||||
SourceLocation LParenLoc;
|
||||
if (PeekTok.is(tok::l_paren)) {
|
||||
// Found a paren, remember we saw it and skip it.
|
||||
LParenLoc = PeekTok.getLocation();
|
||||
PP.LexUnexpandedToken(PeekTok);
|
||||
}
|
||||
|
||||
// If we don't have a pp-identifier now, this is an error.
|
||||
if ((II = PeekTok.getIdentifierInfo()) == 0) {
|
||||
PP.Diag(PeekTok, diag::err_pp_defined_requires_identifier);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Otherwise, we got an identifier, is it defined to something?
|
||||
Result.Val = II->hasMacroDefinition();
|
||||
Result.Val.setIsUnsigned(false); // Result is signed intmax_t.
|
||||
|
||||
// If there is a macro, mark it used.
|
||||
if (Result.Val != 0 && ValueLive) {
|
||||
MacroInfo *Macro = PP.getMacroInfo(II);
|
||||
Macro->setIsUsed(true);
|
||||
}
|
||||
|
||||
// Consume identifier.
|
||||
Result.setEnd(PeekTok.getLocation());
|
||||
PP.LexNonComment(PeekTok);
|
||||
|
||||
// If we are in parens, ensure we have a trailing ).
|
||||
if (LParenLoc.isValid()) {
|
||||
if (PeekTok.isNot(tok::r_paren)) {
|
||||
PP.Diag(PeekTok.getLocation(), diag::err_pp_missing_rparen);
|
||||
PP.Diag(LParenLoc, diag::note_matching) << "(";
|
||||
return true;
|
||||
}
|
||||
// Consume the ).
|
||||
Result.setEnd(PeekTok.getLocation());
|
||||
PP.LexNonComment(PeekTok);
|
||||
}
|
||||
|
||||
// Success, remember that we saw defined(X).
|
||||
DT.State = DefinedTracker::DefinedMacro;
|
||||
DT.TheMacro = II;
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (PeekTok.getKind()) {
|
||||
|
|
Loading…
Reference in New Issue