ASTMatchers: Make AST_POLYMORPHIC_SUPPORTED_TYPES a variadic macro

C++11 finally allows us to use this C99 feature.

llvm-svn: 231575
This commit is contained in:
Benjamin Kramer 2015-03-07 20:38:15 +00:00
parent 1a666e0f69
commit 57dd9bd5cc
5 changed files with 68 additions and 72 deletions

View File

@ -163,7 +163,7 @@ def act_on_decl(declaration, comment, allowed_types):
m = re.match(""".*AST_TYPE(LOC)?_TRAVERSE_MATCHER\(
\s*([^\s,]+\s*),
\s*(?:[^\s,]+\s*),
\s*AST_POLYMORPHIC_SUPPORTED_TYPES_([^(]*)\(([^)]*)\)
\s*AST_POLYMORPHIC_SUPPORTED_TYPES\(([^)]*)\)
\)\s*;\s*$""", declaration, flags=re.X)
if m:
loc, name, n_results, results = m.groups()[0:4]
@ -182,7 +182,7 @@ def act_on_decl(declaration, comment, allowed_types):
m = re.match(r"""^\s*AST_POLYMORPHIC_MATCHER(_P)?(.?)(?:_OVERLOAD)?\(
\s*([^\s,]+)\s*,
\s*AST_POLYMORPHIC_SUPPORTED_TYPES_([^(]*)\(([^)]*)\)
\s*AST_POLYMORPHIC_SUPPORTED_TYPES\(([^)]*)\)
(?:,\s*([^\s,]+)\s*
,\s*([^\s,]+)\s*)?
(?:,\s*([^\s,]+)\s*

View File

@ -181,8 +181,7 @@ const internal::VariadicDynCastAllOfMatcher<Decl, TypedefDecl> typedefDecl;
///
/// Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc>
AST_POLYMORPHIC_MATCHER(isExpansionInMainFile,
AST_POLYMORPHIC_SUPPORTED_TYPES_3(Decl, Stmt,
TypeLoc)) {
AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Stmt, TypeLoc)) {
auto &SourceManager = Finder->getASTContext().getSourceManager();
return SourceManager.isInMainFile(
SourceManager.getExpansionLoc(Node.getLocStart()));
@ -203,8 +202,7 @@ AST_POLYMORPHIC_MATCHER(isExpansionInMainFile,
///
/// Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc>
AST_POLYMORPHIC_MATCHER(isExpansionInSystemHeader,
AST_POLYMORPHIC_SUPPORTED_TYPES_3(Decl, Stmt,
TypeLoc)) {
AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Stmt, TypeLoc)) {
auto &SourceManager = Finder->getASTContext().getSourceManager();
auto ExpansionLoc = SourceManager.getExpansionLoc(Node.getLocStart());
if (ExpansionLoc.isInvalid()) {
@ -229,8 +227,7 @@ AST_POLYMORPHIC_MATCHER(isExpansionInSystemHeader,
///
/// Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc>
AST_POLYMORPHIC_MATCHER_P(isExpansionInFileMatching,
AST_POLYMORPHIC_SUPPORTED_TYPES_3(Decl, Stmt,
TypeLoc),
AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Stmt, TypeLoc),
std::string, RegExp) {
auto &SourceManager = Finder->getASTContext().getSourceManager();
auto ExpansionLoc = SourceManager.getExpansionLoc(Node.getLocStart());
@ -456,8 +453,8 @@ AST_MATCHER(Decl, isImplicit) {
/// matches the specialization \c A<int>
AST_POLYMORPHIC_MATCHER_P(
hasAnyTemplateArgument,
AST_POLYMORPHIC_SUPPORTED_TYPES_2(ClassTemplateSpecializationDecl,
TemplateSpecializationType),
AST_POLYMORPHIC_SUPPORTED_TYPES(ClassTemplateSpecializationDecl,
TemplateSpecializationType),
internal::Matcher<TemplateArgument>, InnerMatcher) {
ArrayRef<TemplateArgument> List =
internal::getTemplateSpecializationArgs(Node);
@ -556,8 +553,8 @@ AST_MATCHER_P(Expr, ignoringParenImpCasts,
/// matches the specialization \c A<bool, int>
AST_POLYMORPHIC_MATCHER_P2(
hasTemplateArgument,
AST_POLYMORPHIC_SUPPORTED_TYPES_2(ClassTemplateSpecializationDecl,
TemplateSpecializationType),
AST_POLYMORPHIC_SUPPORTED_TYPES(ClassTemplateSpecializationDecl,
TemplateSpecializationType),
unsigned, N, internal::Matcher<TemplateArgument>, InnerMatcher) {
ArrayRef<TemplateArgument> List =
internal::getTemplateSpecializationArgs(Node);
@ -577,8 +574,8 @@ AST_POLYMORPHIC_MATCHER_P2(
/// matches C<int>.
AST_POLYMORPHIC_MATCHER_P(
templateArgumentCountIs,
AST_POLYMORPHIC_SUPPORTED_TYPES_2(ClassTemplateSpecializationDecl,
TemplateSpecializationType),
AST_POLYMORPHIC_SUPPORTED_TYPES(ClassTemplateSpecializationDecl,
TemplateSpecializationType),
unsigned, N) {
return internal::getTemplateSpecializationArgs(Node).size() == N;
}
@ -1753,12 +1750,11 @@ AST_MATCHER_P(NamedDecl, matchesName, std::string, RegExp) {
/// Usable as: Matcher<CXXOperatorCallExpr>, Matcher<FunctionDecl>
inline internal::PolymorphicMatcherWithParam1<
internal::HasOverloadedOperatorNameMatcher, StringRef,
AST_POLYMORPHIC_SUPPORTED_TYPES_2(CXXOperatorCallExpr, FunctionDecl)>
AST_POLYMORPHIC_SUPPORTED_TYPES(CXXOperatorCallExpr, FunctionDecl)>
hasOverloadedOperatorName(StringRef Name) {
return internal::PolymorphicMatcherWithParam1<
internal::HasOverloadedOperatorNameMatcher, StringRef,
AST_POLYMORPHIC_SUPPORTED_TYPES_2(CXXOperatorCallExpr, FunctionDecl)>(
Name);
AST_POLYMORPHIC_SUPPORTED_TYPES(CXXOperatorCallExpr, FunctionDecl)>(Name);
}
/// \brief Matches C++ classes that are directly or indirectly derived from
@ -2057,7 +2053,7 @@ AST_MATCHER_P_OVERLOAD(CallExpr, callee, internal::Matcher<Decl>, InnerMatcher,
/// void y(X &x) { x; X z; }
/// \endcode
AST_POLYMORPHIC_MATCHER_P_OVERLOAD(
hasType, AST_POLYMORPHIC_SUPPORTED_TYPES_2(Expr, ValueDecl),
hasType, AST_POLYMORPHIC_SUPPORTED_TYPES(Expr, ValueDecl),
internal::Matcher<QualType>, InnerMatcher, 0) {
return InnerMatcher.matches(Node.getType(), Finder, Builder);
}
@ -2079,9 +2075,10 @@ AST_POLYMORPHIC_MATCHER_P_OVERLOAD(
/// \endcode
///
/// Usable as: Matcher<Expr>, Matcher<ValueDecl>
AST_POLYMORPHIC_MATCHER_P_OVERLOAD(
hasType, AST_POLYMORPHIC_SUPPORTED_TYPES_2(Expr, ValueDecl),
internal::Matcher<Decl>, InnerMatcher, 1) {
AST_POLYMORPHIC_MATCHER_P_OVERLOAD(hasType,
AST_POLYMORPHIC_SUPPORTED_TYPES(Expr,
ValueDecl),
internal::Matcher<Decl>, InnerMatcher, 1) {
return qualType(hasDeclaration(InnerMatcher))
.matches(Node.getType(), Finder, Builder);
}
@ -2317,8 +2314,9 @@ AST_MATCHER(VarDecl, hasGlobalStorage) {
/// void f(int x, int y);
/// f(0, 0);
/// \endcode
AST_POLYMORPHIC_MATCHER_P(argumentCountIs, AST_POLYMORPHIC_SUPPORTED_TYPES_2(
CallExpr, CXXConstructExpr),
AST_POLYMORPHIC_MATCHER_P(argumentCountIs,
AST_POLYMORPHIC_SUPPORTED_TYPES(CallExpr,
CXXConstructExpr),
unsigned, N) {
return Node.getNumArgs() == N;
}
@ -2331,10 +2329,10 @@ AST_POLYMORPHIC_MATCHER_P(argumentCountIs, AST_POLYMORPHIC_SUPPORTED_TYPES_2(
/// \code
/// void x(int) { int y; x(y); }
/// \endcode
AST_POLYMORPHIC_MATCHER_P2(
hasArgument,
AST_POLYMORPHIC_SUPPORTED_TYPES_2(CallExpr, CXXConstructExpr),
unsigned, N, internal::Matcher<Expr>, InnerMatcher) {
AST_POLYMORPHIC_MATCHER_P2(hasArgument,
AST_POLYMORPHIC_SUPPORTED_TYPES(CallExpr,
CXXConstructExpr),
unsigned, N, internal::Matcher<Expr>, InnerMatcher) {
return (N < Node.getNumArgs() &&
InnerMatcher.matches(
*Node.getArg(N)->IgnoreParenImpCasts(), Finder, Builder));
@ -2474,8 +2472,9 @@ AST_MATCHER(CXXCtorInitializer, isWritten) {
/// the argument before applying the inner matcher. We'll want to remove
/// this to allow for greater control by the user once \c ignoreImplicit()
/// has been implemented.
AST_POLYMORPHIC_MATCHER_P(hasAnyArgument, AST_POLYMORPHIC_SUPPORTED_TYPES_2(
CallExpr, CXXConstructExpr),
AST_POLYMORPHIC_MATCHER_P(hasAnyArgument,
AST_POLYMORPHIC_SUPPORTED_TYPES(CallExpr,
CXXConstructExpr),
internal::Matcher<Expr>, InnerMatcher) {
for (const Expr *Arg : Node.arguments()) {
BoundNodesTreeBuilder Result(*Builder);
@ -2588,10 +2587,11 @@ AST_MATCHER(FunctionDecl, isDeleted) {
/// \code
/// if (true) {}
/// \endcode
AST_POLYMORPHIC_MATCHER_P(
hasCondition, AST_POLYMORPHIC_SUPPORTED_TYPES_5(
IfStmt, ForStmt, WhileStmt, DoStmt, ConditionalOperator),
internal::Matcher<Expr>, InnerMatcher) {
AST_POLYMORPHIC_MATCHER_P(hasCondition,
AST_POLYMORPHIC_SUPPORTED_TYPES(IfStmt, ForStmt,
WhileStmt, DoStmt,
ConditionalOperator),
internal::Matcher<Expr>, InnerMatcher) {
const Expr *const Condition = Node.getCond();
return (Condition != nullptr &&
InnerMatcher.matches(*Condition, Finder, Builder));
@ -2642,8 +2642,9 @@ AST_MATCHER_P(IfStmt, hasElse, internal::Matcher<Stmt>, InnerMatcher) {
/// forEachDescendant(declRefExpr(to(decl(equalsBoundNode("d"))))))
/// will trigger a match for each combination of variable declaration
/// and reference to that variable declaration within a compound statement.
AST_POLYMORPHIC_MATCHER_P(equalsBoundNode, AST_POLYMORPHIC_SUPPORTED_TYPES_4(
Stmt, Decl, Type, QualType),
AST_POLYMORPHIC_MATCHER_P(equalsBoundNode,
AST_POLYMORPHIC_SUPPORTED_TYPES(Stmt, Decl, Type,
QualType),
std::string, ID) {
// FIXME: Figure out whether it makes sense to allow this
// on any other node types.
@ -2718,9 +2719,9 @@ AST_MATCHER_P(ArraySubscriptExpr, hasBase,
/// with compoundStmt()
/// matching '{}'
AST_POLYMORPHIC_MATCHER_P(hasBody,
AST_POLYMORPHIC_SUPPORTED_TYPES_4(DoStmt, ForStmt,
WhileStmt,
CXXForRangeStmt),
AST_POLYMORPHIC_SUPPORTED_TYPES(DoStmt, ForStmt,
WhileStmt,
CXXForRangeStmt),
internal::Matcher<Stmt>, InnerMatcher) {
const Stmt *const Statement = Node.getBody();
return (Statement != nullptr &&
@ -2782,8 +2783,9 @@ equals(const ValueT &Value) {
/// \code
/// !(a || b)
/// \endcode
AST_POLYMORPHIC_MATCHER_P(hasOperatorName, AST_POLYMORPHIC_SUPPORTED_TYPES_2(
BinaryOperator, UnaryOperator),
AST_POLYMORPHIC_MATCHER_P(hasOperatorName,
AST_POLYMORPHIC_SUPPORTED_TYPES(BinaryOperator,
UnaryOperator),
std::string, Name) {
return Name == Node.getOpcodeStr(Node.getOpcode());
}
@ -2906,8 +2908,9 @@ AST_MATCHER_P(ConditionalOperator, hasFalseExpression,
/// \endcode
///
/// Usable as: Matcher<TagDecl>, Matcher<VarDecl>, Matcher<FunctionDecl>
AST_POLYMORPHIC_MATCHER(isDefinition, AST_POLYMORPHIC_SUPPORTED_TYPES_3(
TagDecl, VarDecl, FunctionDecl)) {
AST_POLYMORPHIC_MATCHER(isDefinition,
AST_POLYMORPHIC_SUPPORTED_TYPES(TagDecl, VarDecl,
FunctionDecl)) {
return Node.isThisDeclarationADefinition();
}
@ -3154,9 +3157,9 @@ AST_MATCHER_P(UsingShadowDecl, hasTargetDecl,
/// does not match, as X<A> is an explicit template specialization.
///
/// Usable as: Matcher<FunctionDecl>, Matcher<VarDecl>, Matcher<CXXRecordDecl>
AST_POLYMORPHIC_MATCHER(
isTemplateInstantiation,
AST_POLYMORPHIC_SUPPORTED_TYPES_3(FunctionDecl, VarDecl, CXXRecordDecl)) {
AST_POLYMORPHIC_MATCHER(isTemplateInstantiation,
AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl, VarDecl,
CXXRecordDecl)) {
return (Node.getTemplateSpecializationKind() == TSK_ImplicitInstantiation ||
Node.getTemplateSpecializationKind() ==
TSK_ExplicitInstantiationDefinition);
@ -3211,9 +3214,9 @@ AST_MATCHER_FUNCTION(internal::Matcher<Stmt>, isInTemplateInstantiation) {
/// matches the specialization A<int>().
///
/// Usable as: Matcher<FunctionDecl>, Matcher<VarDecl>, Matcher<CXXRecordDecl>
AST_POLYMORPHIC_MATCHER(
isExplicitTemplateSpecialization,
AST_POLYMORPHIC_SUPPORTED_TYPES_3(FunctionDecl, VarDecl, CXXRecordDecl)) {
AST_POLYMORPHIC_MATCHER(isExplicitTemplateSpecialization,
AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl, VarDecl,
CXXRecordDecl)) {
return (Node.getTemplateSpecializationKind() == TSK_ExplicitSpecialization);
}
@ -3286,9 +3289,9 @@ AST_TYPE_MATCHER(ComplexType, complexType);
/// matches "int b[7]"
///
/// Usable as: Matcher<ArrayType>, Matcher<ComplexType>
AST_TYPELOC_TRAVERSE_MATCHER(
hasElementType, getElement,
AST_POLYMORPHIC_SUPPORTED_TYPES_2(ArrayType, ComplexType));
AST_TYPELOC_TRAVERSE_MATCHER(hasElementType, getElement,
AST_POLYMORPHIC_SUPPORTED_TYPES(ArrayType,
ComplexType));
/// \brief Matches C arrays with a specified constant size.
///
@ -3397,7 +3400,7 @@ AST_TYPE_MATCHER(AtomicType, atomicType);
///
/// Usable as: Matcher<AtomicType>
AST_TYPELOC_TRAVERSE_MATCHER(hasValueType, getValue,
AST_POLYMORPHIC_SUPPORTED_TYPES_1(AtomicType));
AST_POLYMORPHIC_SUPPORTED_TYPES(AtomicType));
/// \brief Matches types nodes representing C++11 auto types.
///
@ -3426,7 +3429,7 @@ AST_TYPE_MATCHER(AutoType, autoType);
///
/// Usable as: Matcher<AutoType>
AST_TYPE_TRAVERSE_MATCHER(hasDeducedType, getDeducedType,
AST_POLYMORPHIC_SUPPORTED_TYPES_1(AutoType));
AST_POLYMORPHIC_SUPPORTED_TYPES(AutoType));
/// \brief Matches \c FunctionType nodes.
///
@ -3464,7 +3467,7 @@ AST_TYPE_MATCHER(ParenType, parenType);
///
/// Usable as: Matcher<ParenType>
AST_TYPE_TRAVERSE_MATCHER(innerType, getInnerType,
AST_POLYMORPHIC_SUPPORTED_TYPES_1(ParenType));
AST_POLYMORPHIC_SUPPORTED_TYPES(ParenType));
/// \brief Matches block pointer types, i.e. types syntactically represented as
/// "void (^)(int)".
@ -3558,10 +3561,11 @@ AST_TYPE_MATCHER(RValueReferenceType, rValueReferenceType);
///
/// Usable as: Matcher<BlockPointerType>, Matcher<MemberPointerType>,
/// Matcher<PointerType>, Matcher<ReferenceType>
AST_TYPELOC_TRAVERSE_MATCHER(
pointee, getPointee,
AST_POLYMORPHIC_SUPPORTED_TYPES_4(BlockPointerType, MemberPointerType,
PointerType, ReferenceType));
AST_TYPELOC_TRAVERSE_MATCHER(pointee, getPointee,
AST_POLYMORPHIC_SUPPORTED_TYPES(BlockPointerType,
MemberPointerType,
PointerType,
ReferenceType));
/// \brief Matches typedef types.
///

View File

@ -887,7 +887,7 @@ typedef TypeList<Decl, Stmt, NestedNameSpecifier, NestedNameSpecifierLoc,
/// \brief Helper meta-function to extract the argument out of a function of
/// type void(Arg).
///
/// See AST_POLYMORPHIC_SUPPORTED_TYPES_* for details.
/// See AST_POLYMORPHIC_SUPPORTED_TYPES for details.
template <class T> struct ExtractFunctionArgMeta;
template <class T> struct ExtractFunctionArgMeta<void(T)> {
typedef T type;

View File

@ -193,15 +193,8 @@
/// \c void(TypeList<Foo, Bar>), which works thanks to the parenthesis.
/// The \c PolymorphicMatcherWithParam* classes will unpack the function type to
/// extract the TypeList object.
#define AST_POLYMORPHIC_SUPPORTED_TYPES_1(t1) void(internal::TypeList<t1>)
#define AST_POLYMORPHIC_SUPPORTED_TYPES_2(t1, t2) \
void(internal::TypeList<t1, t2>)
#define AST_POLYMORPHIC_SUPPORTED_TYPES_3(t1, t2, t3) \
void(internal::TypeList<t1, t2, t3>)
#define AST_POLYMORPHIC_SUPPORTED_TYPES_4(t1, t2, t3, t4) \
void(internal::TypeList<t1, t2, t3, t4>)
#define AST_POLYMORPHIC_SUPPORTED_TYPES_5(t1, t2, t3, t4, t5) \
void(internal::TypeList<t1, t2, t3, t4, t5>)
#define AST_POLYMORPHIC_SUPPORTED_TYPES(...) \
void(internal::TypeList<__VA_ARGS__>)
/// \brief AST_POLYMORPHIC_MATCHER(DefineMatcher) { ... }
/// defines a single-parameter function named DefineMatcher() that is

View File

@ -2541,10 +2541,9 @@ TEST(AstMatcherPMacro, Works) {
HasClassB, new VerifyIdIsBoundTo<Decl>("b")));
}
AST_POLYMORPHIC_MATCHER_P(
polymorphicHas,
AST_POLYMORPHIC_SUPPORTED_TYPES_2(Decl, Stmt),
internal::Matcher<Decl>, AMatcher) {
AST_POLYMORPHIC_MATCHER_P(polymorphicHas,
AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Stmt),
internal::Matcher<Decl>, AMatcher) {
return Finder->matchesChildOf(
Node, AMatcher, Builder,
ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses,