[cfe-commits] r38685 - in /cfe/cfe/trunk: Lex/MacroExpander.cpp Lex/Preprocessor.cpp include/clang/Basic/DiagnosticKinds.def include/clang/Lex/MacroExpander.h include/clang/Lex/MacroInfo.h include/clang/Lex/Preprocessor.h
sabre at cs.uiuc.edu
sabre at cs.uiuc.edu
Wed Jul 11 09:23:49 PDT 2007
Author: sabre
Date: Wed Jul 11 11:23:48 2007
New Revision: 38685
URL: http://llvm.org/viewvc/llvm-project?rev=38685&view=rev
Log:
Read, remember, and validate the arguments provided the a function-style
macro invocation.
Modified:
cfe/cfe/trunk/Lex/MacroExpander.cpp
cfe/cfe/trunk/Lex/Preprocessor.cpp
cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
cfe/cfe/trunk/include/clang/Lex/MacroExpander.h
cfe/cfe/trunk/include/clang/Lex/MacroInfo.h
cfe/cfe/trunk/include/clang/Lex/Preprocessor.h
Modified: cfe/cfe/trunk/Lex/MacroExpander.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Lex/MacroExpander.cpp?rev=38685&r1=38684&r2=38685&view=diff
==============================================================================
--- cfe/cfe/trunk/Lex/MacroExpander.cpp (original)
+++ cfe/cfe/trunk/Lex/MacroExpander.cpp Wed Jul 11 11:23:48 2007
@@ -18,8 +18,29 @@
using namespace llvm;
using namespace clang;
-MacroExpander::MacroExpander(LexerToken &Tok, Preprocessor &pp)
- : Macro(*Tok.getIdentifierInfo()->getMacroInfo()), PP(pp), CurToken(0),
+//===----------------------------------------------------------------------===//
+// MacroFormalArgs Implementation
+//===----------------------------------------------------------------------===//
+
+MacroFormalArgs::MacroFormalArgs(const MacroInfo *MI) {
+ assert(MI->isFunctionLike() &&
+ "Can't have formal args for an object-like macro!");
+ // Reserve space for arguments to avoid reallocation.
+ unsigned NumArgs = MI->getNumArgs();
+ if (MI->isC99Varargs() || MI->isGNUVarargs())
+ NumArgs += 3; // Varargs can have more than this, just some guess.
+
+ ArgTokens.reserve(NumArgs);
+}
+
+//===----------------------------------------------------------------------===//
+// MacroExpander Implementation
+//===----------------------------------------------------------------------===//
+
+MacroExpander::MacroExpander(LexerToken &Tok, MacroFormalArgs *Formals,
+ Preprocessor &pp)
+ : Macro(*Tok.getIdentifierInfo()->getMacroInfo()), FormalArgs(Formals),
+ PP(pp), CurToken(0),
InstantiateLoc(Tok.getLocation()),
AtStartOfLine(Tok.isAtStartOfLine()),
HasLeadingSpace(Tok.hasLeadingSpace()) {
Modified: cfe/cfe/trunk/Lex/Preprocessor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Lex/Preprocessor.cpp?rev=38685&r1=38684&r2=38685&view=diff
==============================================================================
--- cfe/cfe/trunk/Lex/Preprocessor.cpp (original)
+++ cfe/cfe/trunk/Lex/Preprocessor.cpp Wed Jul 11 11:23:48 2007
@@ -11,10 +11,6 @@
//
//===----------------------------------------------------------------------===//
//
-// TODO: GCC Diagnostics emitted by the lexer:
-//
-// ERROR : __VA_ARGS__ can only appear in the expansion of a C99 variadic macro
-//
// Options to support:
// -H - Print the name of each header file used.
// -C -CC - Do not discard comments for cpp.
@@ -28,8 +24,6 @@
// Messages to emit:
// "Multiple include guards may be useful for:\n"
//
-// TODO: Implement the include guard optimization.
-//
//===----------------------------------------------------------------------===//
#include "clang/Lex/Preprocessor.h"
@@ -55,13 +49,16 @@
// Clear stats.
NumDirectives = NumIncluded = NumDefined = NumUndefined = NumPragma = 0;
NumIf = NumElse = NumEndif = 0;
- NumEnteredSourceFiles = NumMacroExpanded = NumFastMacroExpanded = 0;
+ NumEnteredSourceFiles = 0;
+ NumMacroExpanded = NumFnMacroExpanded = NumBuiltinMacroExpanded = 0;
+ NumFastMacroExpanded = 0;
MaxIncludeStackDepth = 0; NumMultiIncludeFileOptzn = 0;
NumSkipped = 0;
// Macro expansion is enabled.
DisableMacroExpansion = false;
SkippingContents = false;
+ InMacroFormalArgs = false;
// There is no file-change handler yet.
FileChangeHandler = 0;
@@ -199,7 +196,8 @@
std::cerr << " " << NumPragma << " #pragma.\n";
std::cerr << NumSkipped << " #if/#ifndef#ifdef regions skipped\n";
- std::cerr << NumMacroExpanded << " macros expanded, "
+ std::cerr << NumMacroExpanded << "/" << NumFnMacroExpanded << "/"
+ << NumBuiltinMacroExpanded << " obj/fn/builtin macros expanded, "
<< NumFastMacroExpanded << " on the fast path.\n";
}
@@ -433,7 +431,7 @@
/// 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) {
+void Preprocessor::EnterMacro(LexerToken &Tok, MacroFormalArgs *Formals) {
IdentifierInfo *Identifier = Tok.getIdentifierInfo();
MacroInfo &MI = *Identifier->getMacroInfo();
IncludeMacroStack.push_back(IncludeStackInfo(CurLexer, CurDirLookup,
@@ -441,12 +439,10 @@
CurLexer = 0;
CurDirLookup = 0;
- // TODO: Figure out arguments.
-
// Mark the macro as currently disabled, so that it is not recursively
// expanded.
MI.DisableMacro();
- CurMacroExpander = new MacroExpander(Tok, *this);
+ CurMacroExpander = new MacroExpander(Tok, Formals, *this);
}
//===----------------------------------------------------------------------===//
@@ -485,24 +481,63 @@
/// HandleMacroExpandedIdentifier - If an identifier token is read that is to be
/// expanded as a macro, handle it and return the next token as 'Identifier'.
-void Preprocessor::HandleMacroExpandedIdentifier(LexerToken &Identifier,
+bool Preprocessor::HandleMacroExpandedIdentifier(LexerToken &Identifier,
MacroInfo *MI) {
- ++NumMacroExpanded;
+
+ // If this is a builtin macro, like __LINE__ or _Pragma, handle it specially.
+ if (MI->isBuiltinMacro()) {
+ ExpandBuiltinMacro(Identifier);
+ return false;
+ }
+
+ /// FormalArgs - If this is a function-like macro expansion, this contains,
+ /// for each macro argument, the list of tokens that were provided to the
+ /// invocation.
+ MacroFormalArgs *FormalArgs = 0;
+
+ // 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)
+ 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.
+ InMacroFormalArgs = true;
+ FormalArgs = ReadFunctionLikeMacroFormalArgs(Identifier, MI);
+
+ // Finished parsing args.
+ InMacroFormalArgs = false;
+
+ // If there was an error parsing the arguments, bail out.
+ if (FormalArgs == 0) return false;
+
+ ++NumFnMacroExpanded;
+ } else {
+ ++NumMacroExpanded;
+ }
// Notice that this macro has been used.
MI->setIsUsed(true);
-
- // If this is a builtin macro, like __LINE__ or _Pragma, handle it specially.
- if (MI->isBuiltinMacro())
- return ExpandBuiltinMacro(Identifier);
// If we started lexing a macro, enter the macro expansion body.
- // FIXME: Fn-Like Macros: 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.
if (MI->getNumTokens() == 0) {
+ // No need for formal arg info.
+ delete FormalArgs;
+
// Ignore this macro use, just return the next token in the current
// buffer.
bool HadLeadingSpace = Identifier.hasLeadingSpace();
@@ -519,13 +554,14 @@
if (HadLeadingSpace) Identifier.SetFlag(LexerToken::LeadingSpace);
}
++NumFastMacroExpanded;
- return;
+ return false;
} else if (MI->getNumTokens() == 1 &&
+ // FIXME: Fn-Like Macros: Fast if arg not used.
+ FormalArgs == 0 &&
// Don't handle identifiers if they need recursive expansion.
(MI->getReplacementToken(0).getIdentifierInfo() == 0 ||
!MI->getReplacementToken(0).getIdentifierInfo()->getMacroInfo())){
- // FIXME: Fn-Like Macros: Function-style macros only if no arguments?
// Otherwise, if this macro expands into a single trivially-expanded
// token: expand it now. This handles common cases like
@@ -555,15 +591,115 @@
// Since this is not an identifier token, it can't be macro expanded, so
// we're done.
++NumFastMacroExpanded;
- return;
+ return false;
}
- // Start expanding the macro (FIXME: Fn-Like Macros: pass arguments).
- EnterMacro(Identifier);
+ // Start expanding the macro.
+ EnterMacro(Identifier, FormalArgs);
// Now that the macro is at the top of the include stack, ask the
// preprocessor to read the next token from it.
- return Lex(Identifier);
+ Lex(Identifier);
+ return false;
+}
+
+/// ReadFunctionLikeMacroFormalArgs - After reading "MACRO(", this method is
+/// invoked to read all of the formal arguments specified for the macro
+/// invocation. This returns null on error.
+MacroFormalArgs *Preprocessor::
+ReadFunctionLikeMacroFormalArgs(LexerToken &MacroName, MacroInfo *MI) {
+ // Use an auto_ptr here so that the MacroFormalArgs object is deleted on
+ // all error paths.
+ std::auto_ptr<MacroFormalArgs> Args(new MacroFormalArgs(MI));
+
+ // The number of fixed arguments to parse.
+ unsigned NumFixedArgsLeft = MI->getNumArgs();
+ bool isVariadic = MI->isVariadic();
+
+ // If this is a C99-style varargs macro invocation, add an extra expected
+ // argument, which will catch all of the varargs formals in one argument.
+ if (MI->isC99Varargs())
+ ++NumFixedArgsLeft;
+
+ // Outer loop, while there are more arguments, keep reading them.
+ LexerToken Tok;
+ Tok.SetKind(tok::comma);
+ --NumFixedArgsLeft; // Start reading the first arg.
+
+ while (Tok.getKind() == tok::comma) {
+ // ArgTokens - Build up a list of tokens that make up this argument.
+ std::vector<LexerToken> ArgTokens;
+ // C99 6.10.3p11: Keep track of the number of l_parens we have seen.
+ unsigned NumParens = 0;
+
+ while (1) {
+ LexUnexpandedToken(Tok);
+
+ if (Tok.getKind() == tok::eof) {
+ Diag(MacroName, diag::err_unterm_macro_invoc);
+ // Do not lose the EOF. Return it to the client.
+ MacroName = Tok;
+ return 0;
+ } else if (Tok.getKind() == tok::r_paren) {
+ // If we found the ) token, the macro arg list is done.
+ if (NumParens-- == 0)
+ break;
+ } else if (Tok.getKind() == tok::l_paren) {
+ ++NumParens;
+ } else if (Tok.getKind() == tok::comma && NumParens == 0) {
+ // Comma ends this argument if there are more fixed arguments expected.
+ if (NumFixedArgsLeft)
+ break;
+
+ // If this is not a variadic macro, too many formals were specified.
+ if (!isVariadic) {
+ // Emit the diagnostic at the macro name in case there is a missing ).
+ // Emitting it at the , could be far away from the macro name.
+ Diag(MacroName, diag::err_too_many_formals_in_macro_invoc);
+ return 0;
+ }
+ // Otherwise, continue to add the tokens to this variable argument.
+ }
+
+ ArgTokens.push_back(Tok);
+ }
+
+ // Remember the tokens that make up this argument. This destroys ArgTokens.
+ Args->addArgument(ArgTokens);
+ --NumFixedArgsLeft;
+ };
+
+ // Okay, we either found the r_paren. Check to see if we parsed too few
+ // arguments.
+ unsigned NumFormals = Args->getNumArguments();
+ unsigned MinArgsExpected = MI->getNumArgs();
+
+ // C99 expects us to pass at least one vararg arg (but as an extension, we
+ // don't require this).
+ if (MI->isC99Varargs())
+ ++MinArgsExpected;
+
+ if (NumFormals < MinArgsExpected) {
+ // There are several cases where too few arguments is ok, handle them now.
+ if (NumFormals+1 == MinArgsExpected && MI->isVariadic()) {
+ // Varargs where the named vararg parameter is missing: ok as extension.
+ // #define A(x, ...)
+ // A("blah")
+ Diag(Tok, diag::ext_missing_varargs_arg);
+ } else if (MI->getNumArgs() == 1) {
+ // #define A(x)
+ // A()
+ // is ok. Add an empty argument.
+ std::vector<LexerToken> ArgTokens;
+ Args->addArgument(ArgTokens);
+ } else {
+ // Otherwise, emit the error.
+ Diag(Tok, diag::err_too_few_formals_in_macro_invoc);
+ return 0;
+ }
+ }
+
+ return Args.release();
}
/// ComputeDATE_TIME - Compute the current time, enter it into the specified
@@ -599,6 +735,8 @@
if (II == Ident_Pragma)
return Handle_Pragma(Tok);
+ ++NumBuiltinMacroExpanded;
+
char TmpBuffer[100];
// Set up the return result.
@@ -750,9 +888,11 @@
Diag(Identifier, diag::ext_pp_bad_vaargs_use);
}
+ // If this is a macro to be expanded, do it.
if (MacroInfo *MI = II.getMacroInfo())
if (MI->isEnabled() && !DisableMacroExpansion)
- return HandleMacroExpandedIdentifier(Identifier, MI);
+ if (!HandleMacroExpandedIdentifier(Identifier, MI))
+ return;
// Change the kind of this identifier to the appropriate token kind, e.g.
// turning "for" into a keyword.
@@ -1101,7 +1241,7 @@
// We just parsed a # character at the start of a line, so we're in directive
// mode. Tell the lexer this so any newlines we see will be converted into an
- // EOM token (this terminates the macro).
+ // EOM token (which terminates the directive).
CurLexer->ParsingPreprocessorDirective = true;
++NumDirectives;
@@ -1111,9 +1251,19 @@
// pp-directive.
bool ReadAnyTokensBeforeDirective = CurLexer->MIOpt.getHasReadAnyTokensVal();
- // Read the next token, the directive flavor.
+ // Read the next token, the directive flavor. This isn't expanded due to
+ // C99 6.10.3p8.
LexUnexpandedToken(Result);
+ // C99 6.10.3p11: Is this preprocessor directive in macro invocation? e.g.:
+ // #define A(x) #x
+ // A(abc
+ // #warning blah
+ // def)
+ // If so, the user is relying on non-portable behavior, emit a diagnostic.
+ if (InMacroFormalArgs)
+ Diag(Result, diag::ext_embedded_directive);
+
switch (Result.getKind()) {
default: break;
case tok::eom:
@@ -1436,6 +1586,8 @@
LexerToken Tok;
LexUnexpandedToken(Tok);
+ // FIXME: Enable __VA_ARGS__.
+
// If this is a function-like macro definition, parse the argument list,
// marking each of the identifiers as being used as macro arguments. Also,
// check other constraints on the first token of the macro body.
@@ -1503,22 +1655,20 @@
LexUnexpandedToken(Tok);
}
- unsigned NumTokens = MI->getNumTokens();
-
+ // Clear the "isMacroArg" flags from all the macro arguments.
+ MI->SetIdentifierIsMacroArgFlags(false);
+
// Check that there is no paste (##) operator at the begining or end of the
// replacement list.
+ unsigned NumTokens = MI->getNumTokens();
if (NumTokens != 0) {
if (MI->getReplacementToken(0).getKind() == tok::hashhash) {
Diag(MI->getReplacementToken(0), diag::err_paste_at_start);
- // Clear the "isMacroArg" flags from all the macro arguments.
- MI->SetIdentifierIsMacroArgFlags(false);
delete MI;
return;
}
if (MI->getReplacementToken(NumTokens-1).getKind() == tok::hashhash) {
Diag(MI->getReplacementToken(NumTokens-1), diag::err_paste_at_end);
- // Clear the "isMacroArg" flags from all the macro arguments.
- MI->SetIdentifierIsMacroArgFlags(false);
delete MI;
return;
}
@@ -1546,9 +1696,6 @@
}
MacroNameTok.getIdentifierInfo()->setMacroInfo(MI);
-
- // Clear the "isMacroArg" flags from all the macro arguments.
- MI->SetIdentifierIsMacroArgFlags(false);
}
Modified: cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=38685&r1=38684&r2=38685&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def Wed Jul 11 11:23:48 2007
@@ -123,6 +123,10 @@
"variadic macros were introduced in C99")
DIAG(ext_named_variadic_macro, EXTENSION,
"named variadic macros are a GNU extension")
+DIAG(ext_embedded_directive, EXTENSION,
+ "embedding a directive within macro arguments is not portable")
+DIAG(ext_missing_varargs_arg, EXTENSION,
+ "varargs argument missing, but tolerated as an extension")
DIAG(ext_pp_base_file, EXTENSION,
"__BASE_FILE__ is a language extension")
@@ -207,6 +211,13 @@
"\"##\" cannot appear at start of macro expansion")
DIAG(err_paste_at_end, ERROR,
"\"##\" cannot appear at end of macro expansion")
+DIAG(err_unterm_macro_invoc, ERROR,
+ "unterminated function-like macro invocation")
+DIAG(err_too_many_formals_in_macro_invoc, ERROR,
+ "too many arguments provided to function-like macro invocation")
+DIAG(err_too_few_formals_in_macro_invoc, ERROR,
+ "too few arguments provided to function-like macro invocation")
+
// Should be a sorry?
DIAG(err_pp_I_dash_not_supported, ERROR,
Modified: cfe/cfe/trunk/include/clang/Lex/MacroExpander.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Lex/MacroExpander.h?rev=38685&r1=38684&r2=38685&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/Lex/MacroExpander.h (original)
+++ cfe/cfe/trunk/include/clang/Lex/MacroExpander.h Wed Jul 11 11:23:48 2007
@@ -15,6 +15,7 @@
#define LLVM_CLANG_MACROEXPANDER_H
#include "clang/Basic/SourceLocation.h"
+#include <vector>
namespace llvm {
namespace clang {
@@ -22,6 +23,26 @@
class Preprocessor;
class LexerToken;
+/// MacroFormalArgs - An instance of this class captures information about
+/// the formal arguments specified to a function-like macro invocation.
+class MacroFormalArgs {
+ std::vector<std::vector<LexerToken> > ArgTokens;
+public:
+ MacroFormalArgs(const MacroInfo *MI);
+
+ /// addArgument - Add an argument for this invocation. This method destroys
+ /// the vector passed in to avoid extraneous memory copies.
+ void addArgument(std::vector<LexerToken> &ArgToks) {
+ ArgTokens.push_back(std::vector<LexerToken>());
+ ArgTokens.back().swap(ArgToks);
+ }
+
+ /// getNumArguments - Return the number of arguments passed into this macro
+ /// invocation.
+ unsigned getNumArguments() const { return ArgTokens.size(); }
+};
+
+
/// MacroExpander - This implements a lexer that returns token from a macro body
/// instead of lexing from a character buffer.
///
@@ -29,6 +50,10 @@
/// Macro - The macro we are expanding from.
///
MacroInfo &Macro;
+
+ /// FormalArgs - The formal arguments specified for a function-like macro, or
+ /// null. The MacroExpander owns the pointed-to object.
+ MacroFormalArgs *FormalArgs;
/// PP - The current preprocessor object we are expanding for.
///
@@ -45,15 +70,24 @@
/// that the macro expanded from had these properties.
bool AtStartOfLine, HasLeadingSpace;
+ MacroExpander(const MacroExpander&); // DO NOT IMPLEMENT
+ void operator=(const MacroExpander&); // DO NOT IMPLEMENT
public:
- MacroExpander(LexerToken &Tok, Preprocessor &pp);
+ /// Create a macro expander of the specified macro with the specified formal
+ /// arguments. Note that this ctor takes ownership of the FormalArgs pointer.
+ MacroExpander(LexerToken &Tok, MacroFormalArgs *FormalArgs,
+ Preprocessor &pp);
+ ~MacroExpander() {
+ // MacroExpander owns its formal arguments.
+ delete FormalArgs;
+ }
MacroInfo &getMacro() const { return Macro; }
/// Lex - Lex and return a token from this macro stream.
void Lex(LexerToken &Tok);
};
-
+
} // end namespace llvm
} // end namespace clang
Modified: cfe/cfe/trunk/include/clang/Lex/MacroInfo.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Lex/MacroInfo.h?rev=38685&r1=38684&r2=38685&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/Lex/MacroInfo.h (original)
+++ cfe/cfe/trunk/include/clang/Lex/MacroInfo.h Wed Jul 11 11:23:48 2007
@@ -104,7 +104,7 @@
typedef std::vector<IdentifierInfo*>::const_iterator arg_iterator;
arg_iterator arg_begin() const { return Arguments.begin(); }
arg_iterator arg_end() const { return Arguments.end(); }
-
+ unsigned getNumArgs() const { return Arguments.size(); }
/// Function/Object-likeness. Keep track of whether this macro has formal
/// parameters.
@@ -117,6 +117,7 @@
void setIsGNUVarargs() { IsGNUVarargs = true; }
bool isC99Varargs() const { return IsC99Varargs; }
bool isGNUVarargs() const { return IsGNUVarargs; }
+ bool isVariadic() const { return IsC99Varargs | IsGNUVarargs; }
/// isBuiltinMacro - Return true if this macro is a builtin macro, such as
/// __LINE__, which requires processing before expansion.
Modified: cfe/cfe/trunk/include/clang/Lex/Preprocessor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Lex/Preprocessor.h?rev=38685&r1=38684&r2=38685&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/Lex/Preprocessor.h (original)
+++ cfe/cfe/trunk/include/clang/Lex/Preprocessor.h Wed Jul 11 11:23:48 2007
@@ -130,6 +130,7 @@
// State that changes while the preprocessor runs:
bool DisableMacroExpansion; // True if macro expansion is disabled.
bool SkippingContents; // True if in a #if 0 block.
+ bool InMacroFormalArgs; // True if parsing fn macro invocation args.
/// Identifiers - This is mapping/lookup information for all identifiers in
/// the program, including program keywords.
@@ -199,7 +200,8 @@
unsigned NumDirectives, NumIncluded, NumDefined, NumUndefined, NumPragma;
unsigned NumIf, NumElse, NumEndif;
unsigned NumEnteredSourceFiles, MaxIncludeStackDepth,NumMultiIncludeFileOptzn;
- unsigned NumMacroExpanded, NumFastMacroExpanded;
+ unsigned NumMacroExpanded, NumFnMacroExpanded, NumBuiltinMacroExpanded;
+ unsigned NumFastMacroExpanded;
unsigned NumSkipped;
public:
Preprocessor(Diagnostic &diags, const LangOptions &opts, FileManager &FM,
@@ -320,8 +322,9 @@
bool isMainFile = false);
/// EnterMacro - Add a Macro to the top of the include stack and start lexing
- /// tokens from it instead of the current buffer.
- void EnterMacro(LexerToken &Identifier);
+ /// tokens from it instead of the current buffer. Formals specifies the
+ /// tokens input to a function-like macro.
+ void EnterMacro(LexerToken &Identifier, MacroFormalArgs *Formals);
/// Lex - To lex a token from the preprocessor, just pull a token from the
@@ -460,8 +463,15 @@
IdentifierInfo *RegisterBuiltinMacro(const char *Name);
/// HandleMacroExpandedIdentifier - If an identifier token is read that is to
- /// be expanded as a macro, handle it and return the next token as 'Tok'.
- void HandleMacroExpandedIdentifier(LexerToken &Tok, MacroInfo *MI);
+ /// be expanded as a macro, handle it and return the next token as 'Tok'. If
+ /// the macro should not be expanded return true, otherwise return false.
+ bool HandleMacroExpandedIdentifier(LexerToken &Tok, MacroInfo *MI);
+
+ /// ReadFunctionLikeMacroFormalArgs - After reading "MACRO(", this method is
+ /// invoked to read all of the formal arguments specified for the macro
+ /// invocation. This returns null on error.
+ MacroFormalArgs *ReadFunctionLikeMacroFormalArgs(LexerToken &MacroName,
+ MacroInfo *MI);
/// 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'.
More information about the cfe-commits
mailing list