Rename macroformalargs -> MacroArgs, as it represents the actual arguments,

not the formal arguments, to a macro.

llvm-svn: 38716
This commit is contained in:
Chris Lattner 2006-07-15 07:42:55 +00:00
parent c653246bfb
commit ee8760b21b
4 changed files with 85 additions and 60 deletions

View File

@ -20,20 +20,39 @@ using namespace llvm;
using namespace clang;
//===----------------------------------------------------------------------===//
// MacroFormalArgs Implementation
// MacroArgs Implementation
//===----------------------------------------------------------------------===//
MacroFormalArgs::MacroFormalArgs(const MacroInfo *MI) {
MacroArgs::MacroArgs(const MacroInfo *MI) {
assert(MI->isFunctionLike() &&
"Can't have formal args for an object-like macro!");
"Can't have 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);
UnexpArgTokens.reserve(NumArgs);
}
/// addArgument - Add an argument for this invocation. This method destroys
/// the vector passed in to avoid extraneous memory copies. This adds the EOF
/// token to the end of the argument list as a marker. 'Loc' specifies a
/// location at the end of the argument, e.g. the ',' token or the ')'.
void MacroArgs::addArgument(std::vector<LexerToken> &ArgToks,
SourceLocation Loc) {
UnexpArgTokens.push_back(std::vector<LexerToken>());
UnexpArgTokens.back().swap(ArgToks);
// Add a marker EOF token to the end of the argument list, useful for handling
// empty arguments and macro pre-expansion.
LexerToken EOFTok;
EOFTok.StartToken();
EOFTok.SetKind(tok::eof);
EOFTok.SetLocation(Loc);
UnexpArgTokens.back().push_back(EOFTok);
}
/// StringifyArgument - Implement C99 6.10.3.2p2, converting a sequence of
/// tokens into the literal string token that should be produced by the C #
/// preprocessor operator.
@ -111,15 +130,16 @@ static LexerToken StringifyArgument(const std::vector<LexerToken> &Toks,
/// getStringifiedArgument - Compute, cache, and return the specified argument
/// that has been 'stringified' as required by the # operator.
const LexerToken &MacroFormalArgs::getStringifiedArgument(unsigned ArgNo,
Preprocessor &PP) {
assert(ArgNo < ArgTokens.size() && "Invalid argument number!");
const LexerToken &MacroArgs::getStringifiedArgument(unsigned ArgNo,
Preprocessor &PP) {
assert(ArgNo < ExpArgTokens.size() && "Invalid argument number!");
if (StringifiedArgs.empty()) {
StringifiedArgs.resize(ArgTokens.size());
memset(&StringifiedArgs[0], 0, sizeof(StringifiedArgs[0])*ArgTokens.size());
StringifiedArgs.resize(ExpArgTokens.size());
memset(&StringifiedArgs[0], 0,
sizeof(StringifiedArgs[0])*getNumArguments());
}
if (StringifiedArgs[ArgNo].getKind() != tok::string_literal)
StringifiedArgs[ArgNo] = StringifyArgument(ArgTokens[ArgNo], PP);
StringifiedArgs[ArgNo] = StringifyArgument(ExpArgTokens[ArgNo], PP);
return StringifiedArgs[ArgNo];
}
@ -127,10 +147,10 @@ const LexerToken &MacroFormalArgs::getStringifiedArgument(unsigned ArgNo,
// MacroExpander Implementation
//===----------------------------------------------------------------------===//
MacroExpander::MacroExpander(LexerToken &Tok, MacroFormalArgs *Formals,
MacroExpander::MacroExpander(LexerToken &Tok, MacroArgs *Actuals,
Preprocessor &pp)
: Macro(*Tok.getIdentifierInfo()->getMacroInfo()),
FormalArgs(Formals), PP(pp), CurToken(0),
ActualArgs(Actuals), PP(pp), CurToken(0),
InstantiateLoc(Tok.getLocation()),
AtStartOfLine(Tok.isAtStartOfLine()),
HasLeadingSpace(Tok.hasLeadingSpace()) {
@ -149,9 +169,11 @@ MacroExpander::~MacroExpander() {
delete MacroTokens;
// MacroExpander owns its formal arguments.
delete FormalArgs;
delete ActualArgs;
}
/// Expand the arguments of a function-like macro so that we can quickly
/// return preexpanded tokens from MacroTokens.
void MacroExpander::ExpandFunctionArguments() {
@ -171,11 +193,11 @@ void MacroExpander::ExpandFunctionArguments() {
assert(ArgNo != -1 && "Token following # is not an argument?");
if (CurTok.getKind() == tok::hash) // Stringify
ResultToks.push_back(FormalArgs->getStringifiedArgument(ArgNo, PP));
ResultToks.push_back(ActualArgs->getStringifiedArgument(ArgNo, PP));
else {
// 'charify': don't bother caching these.
ResultToks.push_back(StringifyArgument(
FormalArgs->getUnexpArgument(ArgNo), PP, true));
ActualArgs->getUnexpArgument(ArgNo), PP, true));
}
// The stringified/charified string leading space flag gets set to match

View File

@ -57,7 +57,7 @@ Preprocessor::Preprocessor(Diagnostic &diags, const LangOptions &opts,
// Macro expansion is enabled.
DisableMacroExpansion = false;
InMacroFormalArgs = false;
InMacroArgs = false;
// There is no file-change handler yet.
FileChangeHandler = 0;
@ -442,7 +442,7 @@ void Preprocessor::EnterSourceFileWithLexer(Lexer *TheLexer,
/// 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, MacroFormalArgs *Formals) {
void Preprocessor::EnterMacro(LexerToken &Tok, MacroArgs *Args) {
IdentifierInfo *Identifier = Tok.getIdentifierInfo();
MacroInfo &MI = *Identifier->getMacroInfo();
IncludeMacroStack.push_back(IncludeStackInfo(CurLexer, CurDirLookup,
@ -453,7 +453,7 @@ void Preprocessor::EnterMacro(LexerToken &Tok, MacroFormalArgs *Formals) {
// Mark the macro as currently disabled, so that it is not recursively
// expanded.
MI.DisableMacro();
CurMacroExpander = new MacroExpander(Tok, Formals, *this);
CurMacroExpander = new MacroExpander(Tok, Args, *this);
}
//===----------------------------------------------------------------------===//
@ -565,10 +565,10 @@ bool Preprocessor::HandleMacroExpandedIdentifier(LexerToken &Identifier,
return false;
}
/// FormalArgs - If this is a function-like macro expansion, this contains,
/// Args - 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;
MacroArgs *Args = 0;
// If this is a function-like macro, read the arguments.
if (MI->isFunctionLike()) {
@ -580,14 +580,14 @@ bool Preprocessor::HandleMacroExpandedIdentifier(LexerToken &Identifier,
// 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);
InMacroArgs = true;
Args = ReadFunctionLikeMacroArgs(Identifier, MI);
// Finished parsing args.
InMacroFormalArgs = false;
InMacroArgs = false;
// If there was an error parsing the arguments, bail out.
if (FormalArgs == 0) return false;
if (Args == 0) return false;
++NumFnMacroExpanded;
} else {
@ -603,7 +603,7 @@ bool Preprocessor::HandleMacroExpandedIdentifier(LexerToken &Identifier,
// expansion stack, only to take it right back off.
if (MI->getNumTokens() == 0) {
// No need for formal arg info.
delete FormalArgs;
delete Args;
// Ignore this macro use, just return the next token in the current
// buffer.
@ -657,7 +657,7 @@ bool Preprocessor::HandleMacroExpandedIdentifier(LexerToken &Identifier,
}
// Start expanding the macro.
EnterMacro(Identifier, FormalArgs);
EnterMacro(Identifier, Args);
// Now that the macro is at the top of the include stack, ask the
// preprocessor to read the next token from it.
@ -665,14 +665,14 @@ bool Preprocessor::HandleMacroExpandedIdentifier(LexerToken &Identifier,
return false;
}
/// ReadFunctionLikeMacroFormalArgs - After reading "MACRO(", this method is
/// ReadFunctionLikeMacroArgs - 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
MacroArgs *Preprocessor::ReadFunctionLikeMacroArgs(LexerToken &MacroName,
MacroInfo *MI) {
// Use an auto_ptr here so that the MacroArgs object is deleted on
// all error paths.
std::auto_ptr<MacroFormalArgs> Args(new MacroFormalArgs(MI));
std::auto_ptr<MacroArgs> Args(new MacroArgs(MI));
// The number of fixed arguments to parse.
unsigned NumFixedArgsLeft = MI->getNumArgs();
@ -734,7 +734,7 @@ ReadFunctionLikeMacroFormalArgs(LexerToken &MacroName, MacroInfo *MI) {
Diag(Tok, diag::ext_empty_fnmacro_arg);
// Remember the tokens that make up this argument. This destroys ArgTokens.
Args->addArgument(ArgTokens);
Args->addArgument(ArgTokens, Tok.getLocation());
--NumFixedArgsLeft;
};
@ -760,7 +760,7 @@ ReadFunctionLikeMacroFormalArgs(LexerToken &MacroName, MacroInfo *MI) {
// A()
// is ok because it is an empty argument. Add it explicitly.
std::vector<LexerToken> ArgTokens;
Args->addArgument(ArgTokens);
Args->addArgument(ArgTokens, Tok.getLocation());
// Empty arguments are standard in C99 and supported as an extension in
// other modes.
@ -1341,7 +1341,7 @@ void Preprocessor::HandleDirective(LexerToken &Result) {
// #warning blah
// def)
// If so, the user is relying on non-portable behavior, emit a diagnostic.
if (InMacroFormalArgs)
if (InMacroArgs)
Diag(Result, diag::ext_embedded_directive);
switch (Result.getKind()) {

View File

@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
//
// This file defines the MacroExpander interface.
// This file defines the MacroExpander and MacroArgs interfaces.
//
//===----------------------------------------------------------------------===//
@ -23,29 +23,34 @@ namespace clang {
class Preprocessor;
class LexerToken;
/// MacroFormalArgs - An instance of this class captures information about
/// MacroArgs - 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;
class MacroArgs {
/// UnexpArgTokens - Raw, unexpanded tokens for the arguments. This includes
/// an 'EOF' marker at the end of each argument.
std::vector<std::vector<LexerToken> > UnexpArgTokens;
/// ExpArgTokens - Pre-expanded tokens for arguments that need them. Empty if
/// not yet computed. This includes the EOF marker at the end of the stream.
std::vector<std::vector<LexerToken> > ExpArgTokens;
/// StringifiedArgs - This contains arguments in 'stringified' form. If the
/// stringified form of an argument has not yet been computed, this is empty.
std::vector<LexerToken> StringifiedArgs;
public:
MacroFormalArgs(const MacroInfo *MI);
MacroArgs(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);
}
/// the vector passed in to avoid extraneous memory copies. This adds the EOF
/// token to the end of the argument list as a marker. 'Loc' specifies a
/// location at the end of the argument, e.g. the ',' token or the ')'.
void addArgument(std::vector<LexerToken> &ArgToks, SourceLocation Loc);
/// getUnexpArgument - Return the unexpanded tokens for the specified formal.
///
const std::vector<LexerToken> &getUnexpArgument(unsigned Arg) const {
assert(Arg < ArgTokens.size() && "Invalid ArgNo");
return ArgTokens[Arg];
assert(Arg < UnexpArgTokens.size() && "Invalid ArgNo");
return UnexpArgTokens[Arg];
}
/// getStringifiedArgument - Compute, cache, and return the specified argument
@ -54,7 +59,7 @@ public:
/// getNumArguments - Return the number of arguments passed into this macro
/// invocation.
unsigned getNumArguments() const { return ArgTokens.size(); }
unsigned getNumArguments() const { return UnexpArgTokens.size(); }
};
@ -66,9 +71,9 @@ class MacroExpander {
///
MacroInfo &Macro;
/// FormalArgs - The formal arguments specified for a function-like macro, or
/// ActualArgs - The actual arguments specified for a function-like macro, or
/// null. The MacroExpander owns the pointed-to object.
MacroFormalArgs *FormalArgs;
MacroArgs *ActualArgs;
/// PP - The current preprocessor object we are expanding for.
///
@ -93,10 +98,9 @@ class MacroExpander {
MacroExpander(const MacroExpander&); // DO NOT IMPLEMENT
void operator=(const MacroExpander&); // DO NOT IMPLEMENT
public:
/// 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);
/// Create a macro expander of the specified macro with the specified actual
/// arguments. Note that this ctor takes ownership of the ActualArgs pointer.
MacroExpander(LexerToken &Tok, MacroArgs *ActualArgs, Preprocessor &PP);
~MacroExpander();
/// isNextTokenLParen - If the next token lexed will pop this macro off the

View File

@ -129,7 +129,7 @@ private:
// State that changes while the preprocessor runs:
bool DisableMacroExpansion; // True if macro expansion is disabled.
bool InMacroFormalArgs; // True if parsing fn macro invocation args.
bool InMacroArgs; // True if parsing fn macro invocation args.
/// Identifiers - This is mapping/lookup information for all identifiers in
/// the program, including program keywords.
@ -321,9 +321,9 @@ public:
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. Formals specifies the
/// tokens from it instead of the current buffer. Args specifies the
/// tokens input to a function-like macro.
void EnterMacro(LexerToken &Identifier, MacroFormalArgs *Formals);
void EnterMacro(LexerToken &Identifier, MacroArgs *Args);
/// Lex - To lex a token from the preprocessor, just pull a token from the
@ -478,11 +478,10 @@ private:
/// method should have no observable side-effect on the lexed tokens.
bool isNextPPTokenLParen();
/// ReadFunctionLikeMacroFormalArgs - After reading "MACRO(", this method is
/// ReadFunctionLikeMacroArgs - 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);
MacroArgs *ReadFunctionLikeMacroArgs(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'.