From 254611bd301854cf32036597ac25fd7018a48bdb Mon Sep 17 00:00:00 2001 From: David Blaikie Date: Tue, 21 Nov 2017 01:09:18 +0000 Subject: [PATCH] ASTMatchers{,Macros}.h: Add some extra macros to use for decl/def of matchers Fix ODR violations caused by using internal linkage variables in non-internal inline functions. (also removes duplicate definitions, etc) git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@318720 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/ASTMatchers/ASTMatchers.h | 19 ++++---- include/clang/ASTMatchers/ASTMatchersMacros.h | 45 +++++++++++++++++++ lib/ASTMatchers/ASTMatchersInternal.cpp | 9 ++++ 3 files changed, 63 insertions(+), 10 deletions(-) diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h index e4dafece78..5f5d350ced 100644 --- a/include/clang/ASTMatchers/ASTMatchers.h +++ b/include/clang/ASTMatchers/ASTMatchers.h @@ -4803,9 +4803,9 @@ AST_MATCHER(Type, realFloatingPointType) { /// matches "int b[7]" /// /// Usable as: Matcher, Matcher -AST_TYPELOC_TRAVERSE_MATCHER(hasElementType, getElement, - AST_POLYMORPHIC_SUPPORTED_TYPES(ArrayType, - ComplexType)); +AST_TYPELOC_TRAVERSE_MATCHER_DECL(hasElementType, getElement, + AST_POLYMORPHIC_SUPPORTED_TYPES(ArrayType, + ComplexType)); /// \brief Matches C arrays with a specified constant size. /// @@ -4921,8 +4921,8 @@ extern const AstTypeMatcher atomicType; /// matches "_Atomic(int) i" /// /// Usable as: Matcher -AST_TYPELOC_TRAVERSE_MATCHER(hasValueType, getValue, - AST_POLYMORPHIC_SUPPORTED_TYPES(AtomicType)); +AST_TYPELOC_TRAVERSE_MATCHER_DECL(hasValueType, getValue, + AST_POLYMORPHIC_SUPPORTED_TYPES(AtomicType)); /// \brief Matches types nodes representing C++11 auto types. /// @@ -5115,11 +5115,10 @@ extern const AstTypeMatcher rValueReferenceType; /// /// Usable as: Matcher, Matcher, /// Matcher, Matcher -AST_TYPELOC_TRAVERSE_MATCHER(pointee, getPointee, - AST_POLYMORPHIC_SUPPORTED_TYPES(BlockPointerType, - MemberPointerType, - PointerType, - ReferenceType)); +AST_TYPELOC_TRAVERSE_MATCHER_DECL( + pointee, getPointee, + AST_POLYMORPHIC_SUPPORTED_TYPES(BlockPointerType, MemberPointerType, + PointerType, ReferenceType)); /// \brief Matches typedef types. /// diff --git a/include/clang/ASTMatchers/ASTMatchersMacros.h b/include/clang/ASTMatchers/ASTMatchersMacros.h index ddc48378e7..6a48da821a 100644 --- a/include/clang/ASTMatchers/ASTMatchersMacros.h +++ b/include/clang/ASTMatchers/ASTMatchersMacros.h @@ -367,6 +367,27 @@ // FIXME: add a matcher for TypeLoc derived classes using its custom casting // API (no longer dyn_cast) if/when we need such matching +#define AST_TYPE_TRAVERSE_MATCHER_DECL(MatcherName, FunctionName, \ + ReturnTypesF) \ + namespace internal { \ + template struct TypeMatcher##MatcherName##Getter { \ + static QualType (T::*value())() const { return &T::FunctionName; } \ + }; \ + } \ + extern const ::clang::ast_matchers::internal:: \ + TypeTraversePolymorphicMatcher< \ + QualType, \ + ::clang::ast_matchers::internal::TypeMatcher##MatcherName##Getter, \ + ::clang::ast_matchers::internal::TypeTraverseMatcher, \ + ReturnTypesF>::Func MatcherName + +#define AST_TYPE_TRAVERSE_MATCHER_DEF(MatcherName, ReturnTypesF) \ + const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher< \ + QualType, \ + ::clang::ast_matchers::internal::TypeMatcher##MatcherName##Getter, \ + ::clang::ast_matchers::internal::TypeTraverseMatcher, \ + ReturnTypesF>::Func MatcherName + /// \brief AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName) defines /// the matcher \c MatcherName that can be used to traverse from one \c Type /// to another. @@ -386,6 +407,30 @@ ::clang::ast_matchers::internal::TypeTraverseMatcher, \ ReturnTypesF>::Func MatcherName +#define AST_TYPELOC_TRAVERSE_MATCHER_DECL(MatcherName, FunctionName, \ + ReturnTypesF) \ + namespace internal { \ + template struct TypeLocMatcher##MatcherName##Getter { \ + static TypeLoc (T::*value())() const { return &T::FunctionName##Loc; } \ + }; \ + } \ + extern const ::clang::ast_matchers::internal:: \ + TypeTraversePolymorphicMatcher< \ + TypeLoc, \ + ::clang::ast_matchers::internal:: \ + TypeLocMatcher##MatcherName##Getter, \ + ::clang::ast_matchers::internal::TypeLocTraverseMatcher, \ + ReturnTypesF>::Func MatcherName##Loc; \ + AST_TYPE_TRAVERSE_MATCHER_DECL(MatcherName, FunctionName##Type, ReturnTypesF) + +#define AST_TYPELOC_TRAVERSE_MATCHER_DEF(MatcherName, ReturnTypesF) \ + const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher< \ + TypeLoc, \ + ::clang::ast_matchers::internal::TypeLocMatcher##MatcherName##Getter, \ + ::clang::ast_matchers::internal::TypeLocTraverseMatcher, \ + ReturnTypesF>::Func MatcherName##Loc; \ + AST_TYPE_TRAVERSE_MATCHER_DEF(MatcherName, ReturnTypesF) + /// \brief AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName) works /// identical to \c AST_TYPE_TRAVERSE_MATCHER but operates on \c TypeLocs. #define AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName, ReturnTypesF) \ diff --git a/lib/ASTMatchers/ASTMatchersInternal.cpp b/lib/ASTMatchers/ASTMatchersInternal.cpp index a8a7572596..0bcdd8e328 100644 --- a/lib/ASTMatchers/ASTMatchersInternal.cpp +++ b/lib/ASTMatchers/ASTMatchersInternal.cpp @@ -793,6 +793,15 @@ const AstTypeMatcher substTemplateTypeParmType; const AstTypeMatcher templateTypeParmType; const AstTypeMatcher injectedClassNameType; const AstTypeMatcher decayedType; +AST_TYPELOC_TRAVERSE_MATCHER_DEF(hasElementType, + AST_POLYMORPHIC_SUPPORTED_TYPES(ArrayType, + ComplexType)); +AST_TYPELOC_TRAVERSE_MATCHER_DEF(hasValueType, + AST_POLYMORPHIC_SUPPORTED_TYPES(AtomicType)); +AST_TYPELOC_TRAVERSE_MATCHER_DEF( + pointee, + AST_POLYMORPHIC_SUPPORTED_TYPES(BlockPointerType, MemberPointerType, + PointerType, ReferenceType)); } // end namespace ast_matchers } // end namespace clang -- 2.40.0