mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-02-04 00:06:50 +00:00
switch function-like macros from using a vector for their arguments to an
explicitly new'd array. The array never mutates once created, so a vector is overkill. llvm-svn: 39862
This commit is contained in:
parent
819f2ef77b
commit
564f478595
@ -23,6 +23,9 @@ MacroInfo::MacroInfo(SourceLocation DefLoc) : Location(DefLoc) {
|
||||
IsTargetSpecific = false;
|
||||
IsDisabled = false;
|
||||
IsUsed = true;
|
||||
|
||||
ArgumentList = 0;
|
||||
NumArguments = 0;
|
||||
}
|
||||
|
||||
/// isIdenticalTo - Return true if the specified macro definition is equal to
|
||||
@ -34,7 +37,7 @@ MacroInfo::MacroInfo(SourceLocation DefLoc) : Location(DefLoc) {
|
||||
bool MacroInfo::isIdenticalTo(const MacroInfo &Other, Preprocessor &PP) const {
|
||||
// Check # tokens in replacement, number of args, and various flags all match.
|
||||
if (ReplacementTokens.size() != Other.ReplacementTokens.size() ||
|
||||
Arguments.size() != Other.Arguments.size() ||
|
||||
getNumArgs() != Other.getNumArgs() ||
|
||||
isFunctionLike() != Other.isFunctionLike() ||
|
||||
isC99Varargs() != Other.isC99Varargs() ||
|
||||
isGNUVarargs() != Other.isGNUVarargs())
|
||||
|
@ -1639,13 +1639,18 @@ void Preprocessor::HandleImportDirective(LexerToken &ImportTok) {
|
||||
/// closing ), updating MI with what we learn. Return true if an error occurs
|
||||
/// parsing the arg list.
|
||||
bool Preprocessor::ReadMacroDefinitionArgList(MacroInfo *MI) {
|
||||
llvm::SmallVector<IdentifierInfo*, 32> Arguments;
|
||||
|
||||
LexerToken Tok;
|
||||
while (1) {
|
||||
LexUnexpandedToken(Tok);
|
||||
switch (Tok.getKind()) {
|
||||
case tok::r_paren:
|
||||
// Found the end of the argument list.
|
||||
if (MI->arg_begin() == MI->arg_end()) return false; // #define FOO()
|
||||
if (Arguments.empty()) { // #define FOO()
|
||||
MI->setArgumentList(Arguments.begin(), Arguments.end());
|
||||
return false;
|
||||
}
|
||||
// Otherwise we have #define FOO(A,)
|
||||
Diag(Tok, diag::err_pp_expected_ident_in_arg_list);
|
||||
return true;
|
||||
@ -1660,8 +1665,9 @@ bool Preprocessor::ReadMacroDefinitionArgList(MacroInfo *MI) {
|
||||
return true;
|
||||
}
|
||||
// Add the __VA_ARGS__ identifier as an argument.
|
||||
MI->addArgument(Ident__VA_ARGS__);
|
||||
Arguments.push_back(Ident__VA_ARGS__);
|
||||
MI->setIsC99Varargs();
|
||||
MI->setArgumentList(Arguments.begin(), Arguments.end());
|
||||
return false;
|
||||
case tok::eom: // #define X(
|
||||
Diag(Tok, diag::err_pp_missing_rparen_in_macro_def);
|
||||
@ -1678,13 +1684,14 @@ bool Preprocessor::ReadMacroDefinitionArgList(MacroInfo *MI) {
|
||||
|
||||
// If this is already used as an argument, it is used multiple times (e.g.
|
||||
// #define X(A,A.
|
||||
if (MI->getArgumentNum(II) != -1) { // C99 6.10.3p6
|
||||
if (std::find(Arguments.begin(), Arguments.end(), II) !=
|
||||
Arguments.end()) { // C99 6.10.3p6
|
||||
Diag(Tok, diag::err_pp_duplicate_name_in_arg_list, II->getName());
|
||||
return true;
|
||||
}
|
||||
|
||||
// Add the argument to the macro info.
|
||||
MI->addArgument(II);
|
||||
Arguments.push_back(II);
|
||||
|
||||
// Lex the token after the identifier.
|
||||
LexUnexpandedToken(Tok);
|
||||
@ -1694,6 +1701,7 @@ bool Preprocessor::ReadMacroDefinitionArgList(MacroInfo *MI) {
|
||||
Diag(Tok, diag::err_pp_expected_comma_in_arg_list);
|
||||
return true;
|
||||
case tok::r_paren: // #define X(A)
|
||||
MI->setArgumentList(Arguments.begin(), Arguments.end());
|
||||
return false;
|
||||
case tok::comma: // #define X(A,
|
||||
break;
|
||||
@ -1709,6 +1717,7 @@ bool Preprocessor::ReadMacroDefinitionArgList(MacroInfo *MI) {
|
||||
}
|
||||
|
||||
MI->setIsGNUVarargs();
|
||||
MI->setArgumentList(Arguments.begin(), Arguments.end());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -34,7 +34,8 @@ class MacroInfo {
|
||||
/// Arguments - The list of arguments for a function-like macro. This can be
|
||||
/// empty, for, e.g. "#define X()". In a C99-style variadic macro, this
|
||||
/// includes the __VA_ARGS__ identifier on the list.
|
||||
std::vector<IdentifierInfo*> Arguments;
|
||||
IdentifierInfo **ArgumentList;
|
||||
unsigned NumArguments;
|
||||
|
||||
/// ReplacementTokens - This is the list of tokens that the macro is defined
|
||||
/// to.
|
||||
@ -77,6 +78,10 @@ private:
|
||||
public:
|
||||
MacroInfo(SourceLocation DefLoc);
|
||||
|
||||
~MacroInfo() {
|
||||
delete[] ArgumentList;
|
||||
}
|
||||
|
||||
/// getDefinitionLoc - Return the location that the macro was defined at.
|
||||
///
|
||||
SourceLocation getDefinitionLoc() const { return Location; }
|
||||
@ -105,26 +110,33 @@ public:
|
||||
IsUsed = Val;
|
||||
}
|
||||
|
||||
/// addArgument - Add an argument to the list of formal arguments for this
|
||||
/// function-like macro.
|
||||
void addArgument(IdentifierInfo *Arg) {
|
||||
Arguments.push_back(Arg);
|
||||
/// setArgumentList - Set the specified list of identifiers as the argument
|
||||
/// list for this macro.
|
||||
template<typename ItTy>
|
||||
void setArgumentList(ItTy ArgBegin, ItTy ArgEnd) {
|
||||
assert(ArgumentList == 0 && "Argument list already set!");
|
||||
unsigned NumArgs = ArgEnd-ArgBegin;
|
||||
if (NumArgs == 0) return;
|
||||
NumArguments = NumArgs;
|
||||
ArgumentList = new IdentifierInfo*[NumArgs];
|
||||
for (unsigned i = 0; ArgBegin != ArgEnd; ++i, ++ArgBegin)
|
||||
ArgumentList[i] = *ArgBegin;
|
||||
}
|
||||
|
||||
/// Arguments - The list of arguments for a function-like macro. This can be
|
||||
/// empty, for, e.g. "#define X()".
|
||||
typedef IdentifierInfo* const *arg_iterator;
|
||||
arg_iterator arg_begin() const { return ArgumentList; }
|
||||
arg_iterator arg_end() const { return ArgumentList+NumArguments; }
|
||||
unsigned getNumArgs() const { return NumArguments; }
|
||||
|
||||
/// getArgumentNum - Return the argument number of the specified identifier,
|
||||
/// or -1 if the identifier is not a formal argument identifier.
|
||||
int getArgumentNum(IdentifierInfo *Arg) {
|
||||
for (unsigned i = 0, e = Arguments.size(); i != e; ++i)
|
||||
if (Arguments[i] == Arg) return i;
|
||||
int getArgumentNum(IdentifierInfo *Arg) const {
|
||||
for (arg_iterator I = arg_begin(), E = arg_end(); I != E; ++I)
|
||||
if (*I == Arg) return I-arg_begin();
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// Arguments - The list of arguments for a function-like macro. This can be
|
||||
/// empty, for, e.g. "#define X()".
|
||||
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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user