forked from OSchip/llvm-project
Revert changes from my previous refactoring - will need to fix dependencies in clang's extra tooling (such as clang-tidy etc.).
Sorry about that. llvm-svn: 308158
This commit is contained in:
parent
11746b05e5
commit
0e54e5679e
|
@ -42,14 +42,14 @@ class MacroInfo {
|
||||||
|
|
||||||
/// \brief The list of arguments for a function-like macro.
|
/// \brief The list of arguments for a function-like macro.
|
||||||
///
|
///
|
||||||
/// ParameterList points to the first of NumParameters pointers.
|
/// ArgumentList points to the first of NumArguments pointers.
|
||||||
///
|
///
|
||||||
/// This can be empty, for, e.g. "#define X()". In a C99-style variadic
|
/// This can be empty, for, e.g. "#define X()". In a C99-style variadic
|
||||||
/// macro, this includes the \c __VA_ARGS__ identifier on the list.
|
/// macro, this includes the \c __VA_ARGS__ identifier on the list.
|
||||||
IdentifierInfo **ParameterList;
|
IdentifierInfo **ArgumentList;
|
||||||
|
|
||||||
/// \see ParameterList
|
/// \see ArgumentList
|
||||||
unsigned NumParameters;
|
unsigned NumArguments;
|
||||||
|
|
||||||
/// \brief This is the list of tokens that the macro is defined to.
|
/// \brief This is the list of tokens that the macro is defined to.
|
||||||
SmallVector<Token, 8> ReplacementTokens;
|
SmallVector<Token, 8> ReplacementTokens;
|
||||||
|
@ -153,37 +153,37 @@ public:
|
||||||
/// \brief Set the value of the IsWarnIfUnused flag.
|
/// \brief Set the value of the IsWarnIfUnused flag.
|
||||||
void setIsWarnIfUnused(bool val) { IsWarnIfUnused = val; }
|
void setIsWarnIfUnused(bool val) { IsWarnIfUnused = val; }
|
||||||
|
|
||||||
/// \brief Set the specified list of identifiers as the parameter list for
|
/// \brief Set the specified list of identifiers as the argument list for
|
||||||
/// this macro.
|
/// this macro.
|
||||||
void setParameterList(ArrayRef<IdentifierInfo *> List,
|
void setArgumentList(ArrayRef<IdentifierInfo *> List,
|
||||||
llvm::BumpPtrAllocator &PPAllocator) {
|
llvm::BumpPtrAllocator &PPAllocator) {
|
||||||
assert(ParameterList == nullptr && NumParameters == 0 &&
|
assert(ArgumentList == nullptr && NumArguments == 0 &&
|
||||||
"Parameter list already set!");
|
"Argument list already set!");
|
||||||
if (List.empty())
|
if (List.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
NumParameters = List.size();
|
NumArguments = List.size();
|
||||||
ParameterList = PPAllocator.Allocate<IdentifierInfo *>(List.size());
|
ArgumentList = PPAllocator.Allocate<IdentifierInfo *>(List.size());
|
||||||
std::copy(List.begin(), List.end(), ParameterList);
|
std::copy(List.begin(), List.end(), ArgumentList);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parameters - The list of parameters for a function-like macro. This can
|
/// Arguments - The list of arguments for a function-like macro. This can be
|
||||||
/// be empty, for, e.g. "#define X()".
|
/// empty, for, e.g. "#define X()".
|
||||||
typedef IdentifierInfo *const *param_iterator;
|
typedef IdentifierInfo *const *arg_iterator;
|
||||||
bool param_empty() const { return NumParameters == 0; }
|
bool arg_empty() const { return NumArguments == 0; }
|
||||||
param_iterator param_begin() const { return ParameterList; }
|
arg_iterator arg_begin() const { return ArgumentList; }
|
||||||
param_iterator param_end() const { return ParameterList + NumParameters; }
|
arg_iterator arg_end() const { return ArgumentList + NumArguments; }
|
||||||
unsigned getNumParams() const { return NumParameters; }
|
unsigned getNumArgs() const { return NumArguments; }
|
||||||
ArrayRef<const IdentifierInfo *> params() const {
|
ArrayRef<const IdentifierInfo *> args() const {
|
||||||
return ArrayRef<const IdentifierInfo *>(ParameterList, NumParameters);
|
return ArrayRef<const IdentifierInfo *>(ArgumentList, NumArguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Return the parameter number of the specified identifier,
|
/// \brief Return the argument number of the specified identifier,
|
||||||
/// or -1 if the identifier is not a formal parameter identifier.
|
/// or -1 if the identifier is not a formal argument identifier.
|
||||||
int getParameterNum(const IdentifierInfo *Arg) const {
|
int getArgumentNum(const IdentifierInfo *Arg) const {
|
||||||
for (param_iterator I = param_begin(), E = param_end(); I != E; ++I)
|
for (arg_iterator I = arg_begin(), E = arg_end(); I != E; ++I)
|
||||||
if (*I == Arg)
|
if (*I == Arg)
|
||||||
return I - param_begin();
|
return I - arg_begin();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1813,24 +1813,11 @@ private:
|
||||||
void ReadMacroName(Token &MacroNameTok, MacroUse IsDefineUndef = MU_Other,
|
void ReadMacroName(Token &MacroNameTok, MacroUse IsDefineUndef = MU_Other,
|
||||||
bool *ShadowFlag = nullptr);
|
bool *ShadowFlag = nullptr);
|
||||||
|
|
||||||
/// ReadOptionalMacroParameterListAndBody - This consumes all (i.e. the
|
|
||||||
/// entire line) of the macro's tokens and adds them to MacroInfo, and while
|
|
||||||
/// doing so performs certain validity checks including (but not limited to):
|
|
||||||
/// - # (stringization) is followed by a macro parameter
|
|
||||||
/// \param MacroNameTok - Token that represents the macro name
|
|
||||||
/// \param ImmediatelyAfterHeaderGuard - Macro follows an #ifdef header guard
|
|
||||||
///
|
|
||||||
/// Either returns a pointer to a MacroInfo object OR emits a diagnostic and
|
|
||||||
/// returns a nullptr if an invalid sequence of tokens is encountered.
|
|
||||||
|
|
||||||
MacroInfo *ReadOptionalMacroParameterListAndBody(
|
|
||||||
const Token &MacroNameTok, bool ImmediatelyAfterHeaderGuard);
|
|
||||||
|
|
||||||
/// The ( starting an argument list of a macro definition has just been read.
|
/// The ( starting an argument list of a macro definition has just been read.
|
||||||
/// Lex the rest of the parameters and the closing ), updating \p MI with
|
/// Lex the rest of the arguments and the closing ), updating \p MI with
|
||||||
/// what we learn and saving in \p LastTok the last token read.
|
/// what we learn and saving in \p LastTok the last token read.
|
||||||
/// Return true if an error occurs parsing the arg list.
|
/// Return true if an error occurs parsing the arg list.
|
||||||
bool ReadMacroParameterList(MacroInfo *MI, Token& LastTok);
|
bool ReadMacroDefinitionArgList(MacroInfo *MI, Token& LastTok);
|
||||||
|
|
||||||
/// We just read a \#if or related directive and decided that the
|
/// We just read a \#if or related directive and decided that the
|
||||||
/// subsequent tokens are in the \#if'd out portion of the
|
/// subsequent tokens are in the \#if'd out portion of the
|
||||||
|
@ -1891,7 +1878,7 @@ private:
|
||||||
|
|
||||||
/// After reading "MACRO(", this method is invoked to read all of the formal
|
/// After reading "MACRO(", this method is invoked to read all of the formal
|
||||||
/// arguments specified for the macro invocation. Returns null on error.
|
/// arguments specified for the macro invocation. Returns null on error.
|
||||||
MacroArgs *ReadMacroCallArgumentList(Token &MacroName, MacroInfo *MI,
|
MacroArgs *ReadFunctionLikeMacroArgs(Token &MacroName, MacroInfo *MI,
|
||||||
SourceLocation &ExpansionEnd);
|
SourceLocation &ExpansionEnd);
|
||||||
|
|
||||||
/// \brief If an identifier token is read that is to be expanded
|
/// \brief If an identifier token is read that is to be expanded
|
||||||
|
|
|
@ -26,8 +26,8 @@ void MacroPPCallbacks::writeMacroDefinition(const IdentifierInfo &II,
|
||||||
|
|
||||||
if (MI.isFunctionLike()) {
|
if (MI.isFunctionLike()) {
|
||||||
Name << '(';
|
Name << '(';
|
||||||
if (!MI.param_empty()) {
|
if (!MI.arg_empty()) {
|
||||||
MacroInfo::param_iterator AI = MI.param_begin(), E = MI.param_end();
|
MacroInfo::arg_iterator AI = MI.arg_begin(), E = MI.arg_end();
|
||||||
for (; AI + 1 != E; ++AI) {
|
for (; AI + 1 != E; ++AI) {
|
||||||
Name << (*AI)->getName();
|
Name << (*AI)->getName();
|
||||||
Name << ',';
|
Name << ',';
|
||||||
|
|
|
@ -38,8 +38,8 @@ static void PrintMacroDefinition(const IdentifierInfo &II, const MacroInfo &MI,
|
||||||
|
|
||||||
if (MI.isFunctionLike()) {
|
if (MI.isFunctionLike()) {
|
||||||
OS << '(';
|
OS << '(';
|
||||||
if (!MI.param_empty()) {
|
if (!MI.arg_empty()) {
|
||||||
MacroInfo::param_iterator AI = MI.param_begin(), E = MI.param_end();
|
MacroInfo::arg_iterator AI = MI.arg_begin(), E = MI.arg_end();
|
||||||
for (; AI+1 != E; ++AI) {
|
for (; AI+1 != E; ++AI) {
|
||||||
OS << (*AI)->getName();
|
OS << (*AI)->getName();
|
||||||
OS << ',';
|
OS << ',';
|
||||||
|
|
|
@ -52,14 +52,14 @@ MacroArgs *MacroArgs::create(const MacroInfo *MI,
|
||||||
UnexpArgTokens.size() * sizeof(Token));
|
UnexpArgTokens.size() * sizeof(Token));
|
||||||
// Construct the MacroArgs object.
|
// Construct the MacroArgs object.
|
||||||
new (Result)
|
new (Result)
|
||||||
MacroArgs(UnexpArgTokens.size(), VarargsElided, MI->getNumParams());
|
MacroArgs(UnexpArgTokens.size(), VarargsElided, MI->getNumArgs());
|
||||||
} else {
|
} else {
|
||||||
Result = *ResultEnt;
|
Result = *ResultEnt;
|
||||||
// Unlink this node from the preprocessors singly linked list.
|
// Unlink this node from the preprocessors singly linked list.
|
||||||
*ResultEnt = Result->ArgCache;
|
*ResultEnt = Result->ArgCache;
|
||||||
Result->NumUnexpArgTokens = UnexpArgTokens.size();
|
Result->NumUnexpArgTokens = UnexpArgTokens.size();
|
||||||
Result->VarargsElided = VarargsElided;
|
Result->VarargsElided = VarargsElided;
|
||||||
Result->NumMacroArgs = MI->getNumParams();
|
Result->NumMacroArgs = MI->getNumArgs();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy the actual unexpanded tokens to immediately after the result ptr.
|
// Copy the actual unexpanded tokens to immediately after the result ptr.
|
||||||
|
@ -148,11 +148,11 @@ bool MacroArgs::ArgNeedsPreexpansion(const Token *ArgTok,
|
||||||
const std::vector<Token> &
|
const std::vector<Token> &
|
||||||
MacroArgs::getPreExpArgument(unsigned Arg, const MacroInfo *MI,
|
MacroArgs::getPreExpArgument(unsigned Arg, const MacroInfo *MI,
|
||||||
Preprocessor &PP) {
|
Preprocessor &PP) {
|
||||||
assert(Arg < MI->getNumParams() && "Invalid argument number!");
|
assert(Arg < MI->getNumArgs() && "Invalid argument number!");
|
||||||
|
|
||||||
// If we have already computed this, return it.
|
// If we have already computed this, return it.
|
||||||
if (PreExpArgTokens.size() < MI->getNumParams())
|
if (PreExpArgTokens.size() < MI->getNumArgs())
|
||||||
PreExpArgTokens.resize(MI->getNumParams());
|
PreExpArgTokens.resize(MI->getNumArgs());
|
||||||
|
|
||||||
std::vector<Token> &Result = PreExpArgTokens[Arg];
|
std::vector<Token> &Result = PreExpArgTokens[Arg];
|
||||||
if (!Result.empty()) return Result;
|
if (!Result.empty()) return Result;
|
||||||
|
|
|
@ -17,8 +17,8 @@ using namespace clang;
|
||||||
|
|
||||||
MacroInfo::MacroInfo(SourceLocation DefLoc)
|
MacroInfo::MacroInfo(SourceLocation DefLoc)
|
||||||
: Location(DefLoc),
|
: Location(DefLoc),
|
||||||
ParameterList(nullptr),
|
ArgumentList(nullptr),
|
||||||
NumParameters(0),
|
NumArguments(0),
|
||||||
IsDefinitionLengthCached(false),
|
IsDefinitionLengthCached(false),
|
||||||
IsFunctionLike(false),
|
IsFunctionLike(false),
|
||||||
IsC99Varargs(false),
|
IsC99Varargs(false),
|
||||||
|
@ -74,7 +74,7 @@ bool MacroInfo::isIdenticalTo(const MacroInfo &Other, Preprocessor &PP,
|
||||||
|
|
||||||
// Check # tokens in replacement, number of args, and various flags all match.
|
// Check # tokens in replacement, number of args, and various flags all match.
|
||||||
if (ReplacementTokens.size() != Other.ReplacementTokens.size() ||
|
if (ReplacementTokens.size() != Other.ReplacementTokens.size() ||
|
||||||
getNumParams() != Other.getNumParams() ||
|
getNumArgs() != Other.getNumArgs() ||
|
||||||
isFunctionLike() != Other.isFunctionLike() ||
|
isFunctionLike() != Other.isFunctionLike() ||
|
||||||
isC99Varargs() != Other.isC99Varargs() ||
|
isC99Varargs() != Other.isC99Varargs() ||
|
||||||
isGNUVarargs() != Other.isGNUVarargs())
|
isGNUVarargs() != Other.isGNUVarargs())
|
||||||
|
@ -82,8 +82,7 @@ bool MacroInfo::isIdenticalTo(const MacroInfo &Other, Preprocessor &PP,
|
||||||
|
|
||||||
if (Lexically) {
|
if (Lexically) {
|
||||||
// Check arguments.
|
// Check arguments.
|
||||||
for (param_iterator I = param_begin(), OI = Other.param_begin(),
|
for (arg_iterator I = arg_begin(), OI = Other.arg_begin(), E = arg_end();
|
||||||
E = param_end();
|
|
||||||
I != E; ++I, ++OI)
|
I != E; ++I, ++OI)
|
||||||
if (*I != *OI) return false;
|
if (*I != *OI) return false;
|
||||||
}
|
}
|
||||||
|
@ -110,10 +109,10 @@ bool MacroInfo::isIdenticalTo(const MacroInfo &Other, Preprocessor &PP,
|
||||||
return false;
|
return false;
|
||||||
// With syntactic equivalence the parameter names can be different as long
|
// With syntactic equivalence the parameter names can be different as long
|
||||||
// as they are used in the same place.
|
// as they are used in the same place.
|
||||||
int AArgNum = getParameterNum(A.getIdentifierInfo());
|
int AArgNum = getArgumentNum(A.getIdentifierInfo());
|
||||||
if (AArgNum == -1)
|
if (AArgNum == -1)
|
||||||
return false;
|
return false;
|
||||||
if (AArgNum != Other.getParameterNum(B.getIdentifierInfo()))
|
if (AArgNum != Other.getArgumentNum(B.getIdentifierInfo()))
|
||||||
return false;
|
return false;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -142,12 +141,12 @@ LLVM_DUMP_METHOD void MacroInfo::dump() const {
|
||||||
Out << "\n #define <macro>";
|
Out << "\n #define <macro>";
|
||||||
if (IsFunctionLike) {
|
if (IsFunctionLike) {
|
||||||
Out << "(";
|
Out << "(";
|
||||||
for (unsigned I = 0; I != NumParameters; ++I) {
|
for (unsigned I = 0; I != NumArguments; ++I) {
|
||||||
if (I) Out << ", ";
|
if (I) Out << ", ";
|
||||||
Out << ParameterList[I]->getName();
|
Out << ArgumentList[I]->getName();
|
||||||
}
|
}
|
||||||
if (IsC99Varargs || IsGNUVarargs) {
|
if (IsC99Varargs || IsGNUVarargs) {
|
||||||
if (NumParameters && IsC99Varargs) Out << ", ";
|
if (NumArguments && IsC99Varargs) Out << ", ";
|
||||||
Out << "...";
|
Out << "...";
|
||||||
}
|
}
|
||||||
Out << ")";
|
Out << ")";
|
||||||
|
|
|
@ -2135,11 +2135,11 @@ void Preprocessor::HandleIncludeMacrosDirective(SourceLocation HashLoc,
|
||||||
// Preprocessor Macro Directive Handling.
|
// Preprocessor Macro Directive Handling.
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
/// ReadMacroParameterList - The ( starting an argument list of a macro
|
/// ReadMacroDefinitionArgList - The ( starting an argument list of a macro
|
||||||
/// definition has just been read. Lex the rest of the arguments and the
|
/// definition has just been read. Lex the rest of the arguments and the
|
||||||
/// closing ), updating MI with what we learn. Return true if an error occurs
|
/// closing ), updating MI with what we learn. Return true if an error occurs
|
||||||
/// parsing the arg list.
|
/// parsing the arg list.
|
||||||
bool Preprocessor::ReadMacroParameterList(MacroInfo *MI, Token &Tok) {
|
bool Preprocessor::ReadMacroDefinitionArgList(MacroInfo *MI, Token &Tok) {
|
||||||
SmallVector<IdentifierInfo*, 32> Arguments;
|
SmallVector<IdentifierInfo*, 32> Arguments;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
|
@ -2173,7 +2173,7 @@ bool Preprocessor::ReadMacroParameterList(MacroInfo *MI, Token &Tok) {
|
||||||
// Add the __VA_ARGS__ identifier as an argument.
|
// Add the __VA_ARGS__ identifier as an argument.
|
||||||
Arguments.push_back(Ident__VA_ARGS__);
|
Arguments.push_back(Ident__VA_ARGS__);
|
||||||
MI->setIsC99Varargs();
|
MI->setIsC99Varargs();
|
||||||
MI->setParameterList(Arguments, BP);
|
MI->setArgumentList(Arguments, BP);
|
||||||
return false;
|
return false;
|
||||||
case tok::eod: // #define X(
|
case tok::eod: // #define X(
|
||||||
Diag(Tok, diag::err_pp_missing_rparen_in_macro_def);
|
Diag(Tok, diag::err_pp_missing_rparen_in_macro_def);
|
||||||
|
@ -2207,7 +2207,7 @@ bool Preprocessor::ReadMacroParameterList(MacroInfo *MI, Token &Tok) {
|
||||||
Diag(Tok, diag::err_pp_expected_comma_in_arg_list);
|
Diag(Tok, diag::err_pp_expected_comma_in_arg_list);
|
||||||
return true;
|
return true;
|
||||||
case tok::r_paren: // #define X(A)
|
case tok::r_paren: // #define X(A)
|
||||||
MI->setParameterList(Arguments, BP);
|
MI->setArgumentList(Arguments, BP);
|
||||||
return false;
|
return false;
|
||||||
case tok::comma: // #define X(A,
|
case tok::comma: // #define X(A,
|
||||||
break;
|
break;
|
||||||
|
@ -2223,7 +2223,7 @@ bool Preprocessor::ReadMacroParameterList(MacroInfo *MI, Token &Tok) {
|
||||||
}
|
}
|
||||||
|
|
||||||
MI->setIsGNUVarargs();
|
MI->setIsGNUVarargs();
|
||||||
MI->setParameterList(Arguments, BP);
|
MI->setArgumentList(Arguments, BP);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2272,20 +2272,28 @@ static bool isConfigurationPattern(Token &MacroName, MacroInfo *MI,
|
||||||
MI->getNumTokens() == 0;
|
MI->getNumTokens() == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadOptionalMacroParameterListAndBody - This consumes all (i.e. the
|
/// HandleDefineDirective - Implements \#define. This consumes the entire macro
|
||||||
// entire line) of the macro's tokens and adds them to MacroInfo, and while
|
/// line then lets the caller lex the next real token.
|
||||||
// doing so performs certain validity checks including (but not limited to):
|
void Preprocessor::HandleDefineDirective(Token &DefineTok,
|
||||||
// - # (stringization) is followed by a macro parameter
|
bool ImmediatelyAfterHeaderGuard) {
|
||||||
//
|
++NumDefined;
|
||||||
// Returns a nullptr if an invalid sequence of tokens is encountered or returns
|
|
||||||
// a pointer to a MacroInfo object.
|
|
||||||
|
|
||||||
MacroInfo *Preprocessor::ReadOptionalMacroParameterListAndBody(
|
Token MacroNameTok;
|
||||||
const Token &MacroNameTok, const bool ImmediatelyAfterHeaderGuard) {
|
bool MacroShadowsKeyword;
|
||||||
|
ReadMacroName(MacroNameTok, MU_Define, &MacroShadowsKeyword);
|
||||||
|
|
||||||
|
// Error reading macro name? If so, diagnostic already issued.
|
||||||
|
if (MacroNameTok.is(tok::eod))
|
||||||
|
return;
|
||||||
|
|
||||||
Token LastTok = MacroNameTok;
|
Token LastTok = MacroNameTok;
|
||||||
|
|
||||||
|
// If we are supposed to keep comments in #defines, reenable comment saving
|
||||||
|
// mode.
|
||||||
|
if (CurLexer) CurLexer->SetCommentRetentionState(KeepMacroComments);
|
||||||
|
|
||||||
// Create the new macro.
|
// Create the new macro.
|
||||||
MacroInfo *const MI = AllocateMacroInfo(MacroNameTok.getLocation());
|
MacroInfo *MI = AllocateMacroInfo(MacroNameTok.getLocation());
|
||||||
|
|
||||||
Token Tok;
|
Token Tok;
|
||||||
LexUnexpandedToken(Tok);
|
LexUnexpandedToken(Tok);
|
||||||
|
@ -2307,11 +2315,11 @@ MacroInfo *Preprocessor::ReadOptionalMacroParameterListAndBody(
|
||||||
} else if (Tok.is(tok::l_paren)) {
|
} else if (Tok.is(tok::l_paren)) {
|
||||||
// This is a function-like macro definition. Read the argument list.
|
// This is a function-like macro definition. Read the argument list.
|
||||||
MI->setIsFunctionLike();
|
MI->setIsFunctionLike();
|
||||||
if (ReadMacroParameterList(MI, LastTok)) {
|
if (ReadMacroDefinitionArgList(MI, LastTok)) {
|
||||||
// Throw away the rest of the line.
|
// Throw away the rest of the line.
|
||||||
if (CurPPLexer->ParsingPreprocessorDirective)
|
if (CurPPLexer->ParsingPreprocessorDirective)
|
||||||
DiscardUntilEndOfDirective();
|
DiscardUntilEndOfDirective();
|
||||||
return nullptr;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this is a definition of a variadic C99 function-like macro, not using
|
// If this is a definition of a variadic C99 function-like macro, not using
|
||||||
|
@ -2418,7 +2426,7 @@ MacroInfo *Preprocessor::ReadOptionalMacroParameterListAndBody(
|
||||||
|
|
||||||
// Check for a valid macro arg identifier.
|
// Check for a valid macro arg identifier.
|
||||||
if (Tok.getIdentifierInfo() == nullptr ||
|
if (Tok.getIdentifierInfo() == nullptr ||
|
||||||
MI->getParameterNum(Tok.getIdentifierInfo()) == -1) {
|
MI->getArgumentNum(Tok.getIdentifierInfo()) == -1) {
|
||||||
|
|
||||||
// If this is assembler-with-cpp mode, we accept random gibberish after
|
// If this is assembler-with-cpp mode, we accept random gibberish after
|
||||||
// the '#' because '#' is often a comment character. However, change
|
// the '#' because '#' is often a comment character. However, change
|
||||||
|
@ -2434,7 +2442,7 @@ MacroInfo *Preprocessor::ReadOptionalMacroParameterListAndBody(
|
||||||
|
|
||||||
// Disable __VA_ARGS__ again.
|
// Disable __VA_ARGS__ again.
|
||||||
Ident__VA_ARGS__->setIsPoisoned(true);
|
Ident__VA_ARGS__->setIsPoisoned(true);
|
||||||
return nullptr;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2447,39 +2455,15 @@ MacroInfo *Preprocessor::ReadOptionalMacroParameterListAndBody(
|
||||||
LexUnexpandedToken(Tok);
|
LexUnexpandedToken(Tok);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MI->setDefinitionEndLoc(LastTok.getLocation());
|
|
||||||
// Disable __VA_ARGS__ again.
|
|
||||||
Ident__VA_ARGS__->setIsPoisoned(true);
|
|
||||||
|
|
||||||
return MI;
|
|
||||||
}
|
|
||||||
/// HandleDefineDirective - Implements \#define. This consumes the entire macro
|
|
||||||
/// line then lets the caller lex the next real token.
|
|
||||||
void Preprocessor::HandleDefineDirective(
|
|
||||||
Token &DefineTok, const bool ImmediatelyAfterHeaderGuard) {
|
|
||||||
++NumDefined;
|
|
||||||
|
|
||||||
Token MacroNameTok;
|
|
||||||
bool MacroShadowsKeyword;
|
|
||||||
ReadMacroName(MacroNameTok, MU_Define, &MacroShadowsKeyword);
|
|
||||||
|
|
||||||
// Error reading macro name? If so, diagnostic already issued.
|
|
||||||
if (MacroNameTok.is(tok::eod))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// If we are supposed to keep comments in #defines, reenable comment saving
|
|
||||||
// mode.
|
|
||||||
if (CurLexer) CurLexer->SetCommentRetentionState(KeepMacroComments);
|
|
||||||
|
|
||||||
MacroInfo *const MI = ReadOptionalMacroParameterListAndBody(
|
|
||||||
MacroNameTok, ImmediatelyAfterHeaderGuard);
|
|
||||||
|
|
||||||
if (!MI) return;
|
|
||||||
|
|
||||||
if (MacroShadowsKeyword &&
|
if (MacroShadowsKeyword &&
|
||||||
!isConfigurationPattern(MacroNameTok, MI, getLangOpts())) {
|
!isConfigurationPattern(MacroNameTok, MI, getLangOpts())) {
|
||||||
Diag(MacroNameTok, diag::warn_pp_macro_hides_keyword);
|
Diag(MacroNameTok, diag::warn_pp_macro_hides_keyword);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Disable __VA_ARGS__ again.
|
||||||
|
Ident__VA_ARGS__->setIsPoisoned(true);
|
||||||
|
|
||||||
// Check that there is no paste (##) operator at the beginning or end of the
|
// Check that there is no paste (##) operator at the beginning or end of the
|
||||||
// replacement list.
|
// replacement list.
|
||||||
unsigned NumTokens = MI->getNumTokens();
|
unsigned NumTokens = MI->getNumTokens();
|
||||||
|
@ -2494,7 +2478,7 @@ void Preprocessor::HandleDefineDirective(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MI->setDefinitionEndLoc(LastTok.getLocation());
|
||||||
|
|
||||||
// Finally, if this identifier already had a macro defined for it, verify that
|
// Finally, if this identifier already had a macro defined for it, verify that
|
||||||
// the macro bodies are identical, and issue diagnostics if they are not.
|
// the macro bodies are identical, and issue diagnostics if they are not.
|
||||||
|
|
|
@ -412,7 +412,7 @@ static bool isTrivialSingleTokenExpansion(const MacroInfo *MI,
|
||||||
|
|
||||||
// If this is a function-like macro invocation, it's safe to trivially expand
|
// If this is a function-like macro invocation, it's safe to trivially expand
|
||||||
// as long as the identifier is not a macro argument.
|
// as long as the identifier is not a macro argument.
|
||||||
return std::find(MI->param_begin(), MI->param_end(), II) == MI->param_end();
|
return std::find(MI->arg_begin(), MI->arg_end(), II) == MI->arg_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// isNextPPTokenLParen - Determine whether the next preprocessor token to be
|
/// isNextPPTokenLParen - Determine whether the next preprocessor token to be
|
||||||
|
@ -492,7 +492,7 @@ bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier,
|
||||||
// Preprocessor directives used inside macro arguments are not portable, and
|
// Preprocessor directives used inside macro arguments are not portable, and
|
||||||
// this enables the warning.
|
// this enables the warning.
|
||||||
InMacroArgs = true;
|
InMacroArgs = true;
|
||||||
Args = ReadMacroCallArgumentList(Identifier, MI, ExpansionEnd);
|
Args = ReadFunctionLikeMacroArgs(Identifier, MI, ExpansionEnd);
|
||||||
|
|
||||||
// Finished parsing args.
|
// Finished parsing args.
|
||||||
InMacroArgs = false;
|
InMacroArgs = false;
|
||||||
|
@ -745,11 +745,11 @@ static bool GenerateNewArgTokens(Preprocessor &PP,
|
||||||
/// token is the '(' of the macro, this method is invoked to read all of the
|
/// token is the '(' of the macro, this method is invoked to read all of the
|
||||||
/// actual arguments specified for the macro invocation. This returns null on
|
/// actual arguments specified for the macro invocation. This returns null on
|
||||||
/// error.
|
/// error.
|
||||||
MacroArgs *Preprocessor::ReadMacroCallArgumentList(Token &MacroName,
|
MacroArgs *Preprocessor::ReadFunctionLikeMacroArgs(Token &MacroName,
|
||||||
MacroInfo *MI,
|
MacroInfo *MI,
|
||||||
SourceLocation &MacroEnd) {
|
SourceLocation &MacroEnd) {
|
||||||
// The number of fixed arguments to parse.
|
// The number of fixed arguments to parse.
|
||||||
unsigned NumFixedArgsLeft = MI->getNumParams();
|
unsigned NumFixedArgsLeft = MI->getNumArgs();
|
||||||
bool isVariadic = MI->isVariadic();
|
bool isVariadic = MI->isVariadic();
|
||||||
|
|
||||||
// Outer loop, while there are more arguments, keep reading them.
|
// Outer loop, while there are more arguments, keep reading them.
|
||||||
|
@ -889,7 +889,7 @@ MacroArgs *Preprocessor::ReadMacroCallArgumentList(Token &MacroName,
|
||||||
|
|
||||||
// Okay, we either found the r_paren. Check to see if we parsed too few
|
// Okay, we either found the r_paren. Check to see if we parsed too few
|
||||||
// arguments.
|
// arguments.
|
||||||
unsigned MinArgsExpected = MI->getNumParams();
|
unsigned MinArgsExpected = MI->getNumArgs();
|
||||||
|
|
||||||
// If this is not a variadic macro, and too many args were specified, emit
|
// If this is not a variadic macro, and too many args were specified, emit
|
||||||
// an error.
|
// an error.
|
||||||
|
|
|
@ -67,7 +67,7 @@ void TokenLexer::Init(Token &Tok, SourceLocation ELEnd, MacroInfo *MI,
|
||||||
|
|
||||||
// If this is a function-like macro, expand the arguments and change
|
// If this is a function-like macro, expand the arguments and change
|
||||||
// Tokens to point to the expanded tokens.
|
// Tokens to point to the expanded tokens.
|
||||||
if (Macro->isFunctionLike() && Macro->getNumParams())
|
if (Macro->isFunctionLike() && Macro->getNumArgs())
|
||||||
ExpandFunctionArguments();
|
ExpandFunctionArguments();
|
||||||
|
|
||||||
// Mark the macro as currently disabled, so that it is not recursively
|
// Mark the macro as currently disabled, so that it is not recursively
|
||||||
|
@ -122,7 +122,7 @@ bool TokenLexer::MaybeRemoveCommaBeforeVaArgs(
|
||||||
SmallVectorImpl<Token> &ResultToks, bool HasPasteOperator, MacroInfo *Macro,
|
SmallVectorImpl<Token> &ResultToks, bool HasPasteOperator, MacroInfo *Macro,
|
||||||
unsigned MacroArgNo, Preprocessor &PP) {
|
unsigned MacroArgNo, Preprocessor &PP) {
|
||||||
// Is the macro argument __VA_ARGS__?
|
// Is the macro argument __VA_ARGS__?
|
||||||
if (!Macro->isVariadic() || MacroArgNo != Macro->getNumParams()-1)
|
if (!Macro->isVariadic() || MacroArgNo != Macro->getNumArgs()-1)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// In Microsoft-compatibility mode, a comma is removed in the expansion
|
// In Microsoft-compatibility mode, a comma is removed in the expansion
|
||||||
|
@ -137,7 +137,7 @@ bool TokenLexer::MaybeRemoveCommaBeforeVaArgs(
|
||||||
// with GNU extensions, it is removed regardless of named arguments.
|
// with GNU extensions, it is removed regardless of named arguments.
|
||||||
// Microsoft also appears to support this extension, unofficially.
|
// Microsoft also appears to support this extension, unofficially.
|
||||||
if (PP.getLangOpts().C99 && !PP.getLangOpts().GNUMode
|
if (PP.getLangOpts().C99 && !PP.getLangOpts().GNUMode
|
||||||
&& Macro->getNumParams() < 2)
|
&& Macro->getNumArgs() < 2)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Is a comma available to be removed?
|
// Is a comma available to be removed?
|
||||||
|
@ -193,7 +193,7 @@ void TokenLexer::ExpandFunctionArguments() {
|
||||||
NextTokGetsSpace = true;
|
NextTokGetsSpace = true;
|
||||||
|
|
||||||
if (CurTok.isOneOf(tok::hash, tok::hashat)) {
|
if (CurTok.isOneOf(tok::hash, tok::hashat)) {
|
||||||
int ArgNo = Macro->getParameterNum(Tokens[i+1].getIdentifierInfo());
|
int ArgNo = Macro->getArgumentNum(Tokens[i+1].getIdentifierInfo());
|
||||||
assert(ArgNo != -1 && "Token following # is not an argument?");
|
assert(ArgNo != -1 && "Token following # is not an argument?");
|
||||||
|
|
||||||
SourceLocation ExpansionLocStart =
|
SourceLocation ExpansionLocStart =
|
||||||
|
@ -237,7 +237,7 @@ void TokenLexer::ExpandFunctionArguments() {
|
||||||
// Otherwise, if this is not an argument token, just add the token to the
|
// Otherwise, if this is not an argument token, just add the token to the
|
||||||
// output buffer.
|
// output buffer.
|
||||||
IdentifierInfo *II = CurTok.getIdentifierInfo();
|
IdentifierInfo *II = CurTok.getIdentifierInfo();
|
||||||
int ArgNo = II ? Macro->getParameterNum(II) : -1;
|
int ArgNo = II ? Macro->getArgumentNum(II) : -1;
|
||||||
if (ArgNo == -1) {
|
if (ArgNo == -1) {
|
||||||
// This isn't an argument, just add it.
|
// This isn't an argument, just add it.
|
||||||
ResultToks.push_back(CurTok);
|
ResultToks.push_back(CurTok);
|
||||||
|
@ -330,7 +330,7 @@ void TokenLexer::ExpandFunctionArguments() {
|
||||||
// expansion.
|
// expansion.
|
||||||
if (NonEmptyPasteBefore && ResultToks.size() >= 2 &&
|
if (NonEmptyPasteBefore && ResultToks.size() >= 2 &&
|
||||||
ResultToks[ResultToks.size()-2].is(tok::comma) &&
|
ResultToks[ResultToks.size()-2].is(tok::comma) &&
|
||||||
(unsigned)ArgNo == Macro->getNumParams()-1 &&
|
(unsigned)ArgNo == Macro->getNumArgs()-1 &&
|
||||||
Macro->isVariadic()) {
|
Macro->isVariadic()) {
|
||||||
VaArgsPseudoPaste = true;
|
VaArgsPseudoPaste = true;
|
||||||
// Remove the paste operator, report use of the extension.
|
// Remove the paste operator, report use of the extension.
|
||||||
|
|
|
@ -2738,7 +2738,7 @@ CodeCompletionResult::CreateCodeCompletionString(ASTContext &Ctx,
|
||||||
|
|
||||||
// Format a function-like macro with placeholders for the arguments.
|
// Format a function-like macro with placeholders for the arguments.
|
||||||
Result.AddChunk(CodeCompletionString::CK_LeftParen);
|
Result.AddChunk(CodeCompletionString::CK_LeftParen);
|
||||||
MacroInfo::param_iterator A = MI->param_begin(), AEnd = MI->param_end();
|
MacroInfo::arg_iterator A = MI->arg_begin(), AEnd = MI->arg_end();
|
||||||
|
|
||||||
// C99 variadic macros add __VA_ARGS__ at the end. Skip it.
|
// C99 variadic macros add __VA_ARGS__ at the end. Skip it.
|
||||||
if (MI->isC99Varargs()) {
|
if (MI->isC99Varargs()) {
|
||||||
|
@ -2749,8 +2749,8 @@ CodeCompletionResult::CreateCodeCompletionString(ASTContext &Ctx,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (MacroInfo::param_iterator A = MI->param_begin(); A != AEnd; ++A) {
|
for (MacroInfo::arg_iterator A = MI->arg_begin(); A != AEnd; ++A) {
|
||||||
if (A != MI->param_begin())
|
if (A != MI->arg_begin())
|
||||||
Result.AddChunk(CodeCompletionString::CK_Comma);
|
Result.AddChunk(CodeCompletionString::CK_Comma);
|
||||||
|
|
||||||
if (MI->isVariadic() && (A+1) == AEnd) {
|
if (MI->isVariadic() && (A+1) == AEnd) {
|
||||||
|
|
|
@ -1520,7 +1520,7 @@ MacroInfo *ASTReader::ReadMacroRecord(ModuleFile &F, uint64_t Offset) {
|
||||||
|
|
||||||
Stream.JumpToBit(Offset);
|
Stream.JumpToBit(Offset);
|
||||||
RecordData Record;
|
RecordData Record;
|
||||||
SmallVector<IdentifierInfo*, 16> MacroParams;
|
SmallVector<IdentifierInfo*, 16> MacroArgs;
|
||||||
MacroInfo *Macro = nullptr;
|
MacroInfo *Macro = nullptr;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
|
@ -1571,17 +1571,17 @@ MacroInfo *ASTReader::ReadMacroRecord(ModuleFile &F, uint64_t Offset) {
|
||||||
bool isC99VarArgs = Record[NextIndex++];
|
bool isC99VarArgs = Record[NextIndex++];
|
||||||
bool isGNUVarArgs = Record[NextIndex++];
|
bool isGNUVarArgs = Record[NextIndex++];
|
||||||
bool hasCommaPasting = Record[NextIndex++];
|
bool hasCommaPasting = Record[NextIndex++];
|
||||||
MacroParams.clear();
|
MacroArgs.clear();
|
||||||
unsigned NumArgs = Record[NextIndex++];
|
unsigned NumArgs = Record[NextIndex++];
|
||||||
for (unsigned i = 0; i != NumArgs; ++i)
|
for (unsigned i = 0; i != NumArgs; ++i)
|
||||||
MacroParams.push_back(getLocalIdentifier(F, Record[NextIndex++]));
|
MacroArgs.push_back(getLocalIdentifier(F, Record[NextIndex++]));
|
||||||
|
|
||||||
// Install function-like macro info.
|
// Install function-like macro info.
|
||||||
MI->setIsFunctionLike();
|
MI->setIsFunctionLike();
|
||||||
if (isC99VarArgs) MI->setIsC99Varargs();
|
if (isC99VarArgs) MI->setIsC99Varargs();
|
||||||
if (isGNUVarArgs) MI->setIsGNUVarargs();
|
if (isGNUVarArgs) MI->setIsGNUVarargs();
|
||||||
if (hasCommaPasting) MI->setHasCommaPasting();
|
if (hasCommaPasting) MI->setHasCommaPasting();
|
||||||
MI->setParameterList(MacroParams, PP.getPreprocessorAllocator());
|
MI->setArgumentList(MacroArgs, PP.getPreprocessorAllocator());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remember that we saw this macro last so that we add the tokens that
|
// Remember that we saw this macro last so that we add the tokens that
|
||||||
|
|
|
@ -2521,9 +2521,9 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP, bool IsModule) {
|
||||||
Record.push_back(MI->isC99Varargs());
|
Record.push_back(MI->isC99Varargs());
|
||||||
Record.push_back(MI->isGNUVarargs());
|
Record.push_back(MI->isGNUVarargs());
|
||||||
Record.push_back(MI->hasCommaPasting());
|
Record.push_back(MI->hasCommaPasting());
|
||||||
Record.push_back(MI->getNumParams());
|
Record.push_back(MI->getNumArgs());
|
||||||
for (const IdentifierInfo *Param : MI->params())
|
for (const IdentifierInfo *Arg : MI->args())
|
||||||
AddIdentifierRef(Param, Record);
|
AddIdentifierRef(Arg, Record);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we have a detailed preprocessing record, record the macro definition
|
// If we have a detailed preprocessing record, record the macro definition
|
||||||
|
|
|
@ -8195,7 +8195,7 @@ cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
// Check that the identifier is not one of the macro arguments.
|
// Check that the identifier is not one of the macro arguments.
|
||||||
if (std::find(MI->param_begin(), MI->param_end(), &II) != MI->param_end())
|
if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
|
MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
|
||||||
|
|
|
@ -379,11 +379,11 @@ TEST_F(LexerTest, DontOverallocateStringifyArgs) {
|
||||||
auto PP = CreatePP("\"StrArg\", 5, 'C'", ModLoader);
|
auto PP = CreatePP("\"StrArg\", 5, 'C'", ModLoader);
|
||||||
|
|
||||||
llvm::BumpPtrAllocator Allocator;
|
llvm::BumpPtrAllocator Allocator;
|
||||||
std::array<IdentifierInfo *, 3> ParamList;
|
std::array<IdentifierInfo *, 3> ArgList;
|
||||||
MacroInfo *MI = PP->AllocateMacroInfo({});
|
MacroInfo *MI = PP->AllocateMacroInfo({});
|
||||||
MI->setIsFunctionLike();
|
MI->setIsFunctionLike();
|
||||||
MI->setParameterList(ParamList, Allocator);
|
MI->setArgumentList(ArgList, Allocator);
|
||||||
EXPECT_EQ(3u, MI->getNumParams());
|
EXPECT_EQ(3u, MI->getNumArgs());
|
||||||
EXPECT_TRUE(MI->isFunctionLike());
|
EXPECT_TRUE(MI->isFunctionLike());
|
||||||
|
|
||||||
Token Eof;
|
Token Eof;
|
||||||
|
|
Loading…
Reference in New Issue