[cfe-commits] r38694 - in /cfe/cfe/trunk/Lex: MacroExpander.cpp Preprocessor.cpp
sabre at cs.uiuc.edu
sabre at cs.uiuc.edu
Wed Jul 11 09:23:52 PDT 2007
Author: sabre
Date: Wed Jul 11 11:23:52 2007
New Revision: 38694
URL: http://llvm.org/viewvc/llvm-project?rev=38694&view=rev
Log:
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.
Modified:
cfe/cfe/trunk/Lex/MacroExpander.cpp
cfe/cfe/trunk/Lex/Preprocessor.cpp
Modified: cfe/cfe/trunk/Lex/MacroExpander.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Lex/MacroExpander.cpp?rev=38694&r1=38693&r2=38694&view=diff
==============================================================================
--- cfe/cfe/trunk/Lex/MacroExpander.cpp (original)
+++ cfe/cfe/trunk/Lex/MacroExpander.cpp Wed Jul 11 11:23:52 2007
@@ -78,3 +78,19 @@
// 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;
+}
Modified: cfe/cfe/trunk/Lex/Preprocessor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Lex/Preprocessor.cpp?rev=38694&r1=38693&r2=38694&view=diff
==============================================================================
--- cfe/cfe/trunk/Lex/Preprocessor.cpp (original)
+++ cfe/cfe/trunk/Lex/Preprocessor.cpp Wed Jul 11 11:23:52 2007
@@ -507,6 +507,51 @@
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 @@
// 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 @@
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 @@
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 @@
} 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 @@
}
/// 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!");
More information about the cfe-commits
mailing list