forked from OSchip/llvm-project
Rename macroformalargs -> MacroArgs, as it represents the actual arguments,
not the formal arguments, to a macro. llvm-svn: 38716
This commit is contained in:
parent
c653246bfb
commit
ee8760b21b
|
@ -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
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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'.
|
||||
|
|
Loading…
Reference in New Issue