Implement scanning-for-( more correctly. This implements

test/Preprocessor/macro_fn_lparen_scan.c, but is not yet complete.

Add some FIXME's about missing diagnostics on empty macro args.  Improve some
comments.

llvm-svn: 38694
This commit is contained in:
Chris Lattner 2006-07-11 04:02:46 +00:00
parent 53ede2a826
commit afe603fa7d
2 changed files with 69 additions and 11 deletions

View File

@ -78,3 +78,19 @@ void MacroExpander::Lex(LexerToken &Tok) {
// Otherwise, return a normal token.
}
/// NextTokenIsKnownNotLParen - If the next token lexed will pop this macro
/// off the expansion stack, return false and set RanOffEnd to true.
/// Otherwise, return true if we know for sure that the next token returned
/// will not be a '(' token. Return false if it is a '(' token or if we are
/// not sure. This is used when determining whether to expand a function-like
/// macro.
bool MacroExpander::NextTokenIsKnownNotLParen(bool &RanOffEnd) const {
// Out of tokens?
if (CurToken == Macro.getNumTokens()) {
RanOffEnd = true;
return false;
}
return Macro.getReplacementToken(CurToken).getKind() != tok::l_paren;
}

View File

@ -507,6 +507,51 @@ static bool isTrivialSingleTokenExpansion(const MacroInfo *MI,
return true;
}
/// isNextPPTokenLParen - Determine whether the next preprocessor token to be
/// lexed is a '('. If so, consume the token and return true, if not, this
/// method should have no observable side-effect on the lexed tokens.
bool Preprocessor::isNextPPTokenLParen() {
bool RanOffEnd = false;
// Do some quick tests for rejection cases.
if (CurLexer) {
#if 0
if (!CurLexer->NextTokenIsKnownNotLParen(RanOffEnd))
return false;
#endif
} else {
assert(CurMacroExpander && "No token source?");
if (CurMacroExpander->NextTokenIsKnownNotLParen(RanOffEnd))
return false;
}
// If we ran off the end of the lexer or macro expander, walk the include
// stack, looking for whatever will return the next token.
for (unsigned i = IncludeMacroStack.size(); RanOffEnd && i != 0; --i) {
IncludeStackInfo &Entry = IncludeMacroStack[i-1];
RanOffEnd = false;
if (Entry.TheLexer) {
#if 0
if (!Entry.TheLexer->NextTokenIsKnownNotLParen(RanOffEnd))
return false;
#endif
} else if (Entry.TheMacroExpander->NextTokenIsKnownNotLParen(RanOffEnd))
return false;
}
// Okay, if we get here we either know that the next token definitely IS a '('
// token, or we don't know what it is. In either case we will speculatively
// read the next token. If it turns out that it isn't a '(', then we create a
// new macro context with just that token on it so that the token gets
// reprocessed.
LexerToken Tok;
LexUnexpandedToken(Tok);
if (Tok.getKind() == tok::l_paren)
return true;
// FIXME: push a fake macro context, push Tok onto it.
assert(0 && "FIXME: implement speculation failure code!");
}
/// HandleMacroExpandedIdentifier - If an identifier token is read that is to be
/// expanded as a macro, handle it and return the next token as 'Identifier'.
@ -526,19 +571,11 @@ bool Preprocessor::HandleMacroExpandedIdentifier(LexerToken &Identifier,
// If this is a function-like macro, read the arguments.
if (MI->isFunctionLike()) {
// FIXME: We need to query to see if the ( exists without reading it.
// C99 6.10.3p10: If the preprocessing token immediately after the the macro
// name isn't a '(', this macro should not be expanded.
bool isFunctionInvocation = true;
if (!isFunctionInvocation)
if (!isNextPPTokenLParen())
return true;
LexerToken Tok;
LexUnexpandedToken(Tok);
assert(Tok.getKind() == tok::l_paren &&
"not a function-like macro invocation!");
// Remember that we are now parsing the arguments to a macro invocation.
// Preprocessor directives used inside macro arguments are not portable, and
// this enables the warning.
@ -657,6 +694,8 @@ ReadFunctionLikeMacroFormalArgs(LexerToken &MacroName, MacroInfo *MI) {
unsigned NumParens = 0;
while (1) {
// Read arguments as unexpanded tokens. This avoids issues, e.g., where
// an argument value in a macro could expand to ',' or '(' or ')'.
LexUnexpandedToken(Tok);
if (Tok.getKind() == tok::eof) {
@ -688,6 +727,8 @@ ReadFunctionLikeMacroFormalArgs(LexerToken &MacroName, MacroInfo *MI) {
ArgTokens.push_back(Tok);
}
// FIXME: If not in C99 mode, empty arguments should be ext-warned about!
// Remember the tokens that make up this argument. This destroys ArgTokens.
Args->addArgument(ArgTokens);
--NumFixedArgsLeft;
@ -713,9 +754,10 @@ ReadFunctionLikeMacroFormalArgs(LexerToken &MacroName, MacroInfo *MI) {
} else if (MI->getNumArgs() == 1) {
// #define A(x)
// A()
// is ok. Add an empty argument.
// is ok because it is an empty argument. Add it explicitly.
std::vector<LexerToken> ArgTokens;
Args->addArgument(ArgTokens);
// FIXME: Ext-Warn in C90 mode.
} else {
// Otherwise, emit the error.
Diag(Tok, diag::err_too_few_formals_in_macro_invoc);
@ -999,7 +1041,7 @@ void Preprocessor::HandleEndOfFile(LexerToken &Result, bool isEndOfMacro) {
}
/// HandleEndOfMacro - This callback is invoked when the lexer hits the end of
/// the current macro line.
/// the current macro expansion.
void Preprocessor::HandleEndOfMacro(LexerToken &Result) {
assert(CurMacroExpander && !CurLexer &&
"Ending a macro when currently in a #include file!");