diff options
Diffstat (limited to 'lib/ASTMatchers')
-rw-r--r-- | lib/ASTMatchers/ASTMatchFinder.cpp | 73 | ||||
-rw-r--r-- | lib/ASTMatchers/Dynamic/Marshallers.h | 14 | ||||
-rw-r--r-- | lib/ASTMatchers/Dynamic/Registry.cpp | 3 |
3 files changed, 77 insertions, 13 deletions
diff --git a/lib/ASTMatchers/ASTMatchFinder.cpp b/lib/ASTMatchers/ASTMatchFinder.cpp index f407e0875ac4..c51fd630e64b 100644 --- a/lib/ASTMatchers/ASTMatchFinder.cpp +++ b/lib/ASTMatchers/ASTMatchFinder.cpp @@ -374,6 +374,12 @@ public: return true; } + bool VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *CAD) { + const ObjCInterfaceDecl *InterfaceDecl = CAD->getClassInterface(); + CompatibleAliases[InterfaceDecl].insert(CAD); + return true; + } + bool TraverseDecl(Decl *DeclNode); bool TraverseStmt(Stmt *StmtNode, DataRecursionQueue *Queue = nullptr); bool TraverseType(QualType TypeNode); @@ -430,7 +436,13 @@ public: bool classIsDerivedFrom(const CXXRecordDecl *Declaration, const Matcher<NamedDecl> &Base, - BoundNodesTreeBuilder *Builder) override; + BoundNodesTreeBuilder *Builder, + bool Directly) override; + + bool objcClassIsDerivedFrom(const ObjCInterfaceDecl *Declaration, + const Matcher<NamedDecl> &Base, + BoundNodesTreeBuilder *Builder, + bool Directly) override; // Implements ASTMatchFinder::matchesChildOf. bool matchesChildOf(const ast_type_traits::DynTypedNode &Node, @@ -762,6 +774,23 @@ private: return false; } + bool + objcClassHasMatchingCompatibilityAlias(const ObjCInterfaceDecl *InterfaceDecl, + const Matcher<NamedDecl> &Matcher, + BoundNodesTreeBuilder *Builder) { + auto Aliases = CompatibleAliases.find(InterfaceDecl); + if (Aliases == CompatibleAliases.end()) + return false; + for (const ObjCCompatibleAliasDecl *Alias : Aliases->second) { + BoundNodesTreeBuilder Result(*Builder); + if (Matcher.matches(*Alias, this, &Result)) { + *Builder = std::move(Result); + return true; + } + } + return false; + } + /// Bucket to record map. /// /// Used to get the appropriate bucket for each matcher. @@ -786,6 +815,11 @@ private: // Maps a canonical type to its TypedefDecls. llvm::DenseMap<const Type*, std::set<const TypedefNameDecl*> > TypeAliases; + // Maps an Objective-C interface to its ObjCCompatibleAliasDecls. + llvm::DenseMap<const ObjCInterfaceDecl *, + llvm::SmallPtrSet<const ObjCCompatibleAliasDecl *, 2>> + CompatibleAliases; + // Maps (matcher, node) -> the match result for memoization. typedef std::map<MatchKey, MemoizedMatchResult> MemoizationMap; MemoizationMap ResultCache; @@ -812,12 +846,13 @@ getAsCXXRecordDeclOrPrimaryTemplate(const Type *TypeNode) { return nullptr; } -// Returns true if the given class is directly or indirectly derived +// Returns true if the given C++ class is directly or indirectly derived // from a base type with the given name. A class is not considered to be // derived from itself. bool MatchASTVisitor::classIsDerivedFrom(const CXXRecordDecl *Declaration, const Matcher<NamedDecl> &Base, - BoundNodesTreeBuilder *Builder) { + BoundNodesTreeBuilder *Builder, + bool Directly) { if (!Declaration->hasDefinition()) return false; for (const auto &It : Declaration->bases()) { @@ -842,12 +877,40 @@ bool MatchASTVisitor::classIsDerivedFrom(const CXXRecordDecl *Declaration, *Builder = std::move(Result); return true; } - if (classIsDerivedFrom(ClassDecl, Base, Builder)) + if (!Directly && classIsDerivedFrom(ClassDecl, Base, Builder, Directly)) return true; } return false; } +// Returns true if the given Objective-C class is directly or indirectly +// derived from a matching base class. A class is not considered to be derived +// from itself. +bool MatchASTVisitor::objcClassIsDerivedFrom( + const ObjCInterfaceDecl *Declaration, const Matcher<NamedDecl> &Base, + BoundNodesTreeBuilder *Builder, bool Directly) { + // Check if any of the superclasses of the class match. + for (const ObjCInterfaceDecl *ClassDecl = Declaration->getSuperClass(); + ClassDecl != nullptr; ClassDecl = ClassDecl->getSuperClass()) { + // Check if there are any matching compatibility aliases. + if (objcClassHasMatchingCompatibilityAlias(ClassDecl, Base, Builder)) + return true; + + // Check if there are any matching type aliases. + const Type *TypeNode = ClassDecl->getTypeForDecl(); + if (typeHasMatchingAlias(TypeNode, Base, Builder)) + return true; + + if (Base.matches(*ClassDecl, this, Builder)) + return true; + + if (Directly) + return false; + } + + return false; +} + bool MatchASTVisitor::TraverseDecl(Decl *DeclNode) { if (!DeclNode) { return true; @@ -1015,7 +1078,7 @@ bool MatchFinder::addDynamicMatcher(const internal::DynTypedMatcher &NodeMatch, } std::unique_ptr<ASTConsumer> MatchFinder::newASTConsumer() { - return llvm::make_unique<internal::MatchASTConsumer>(this, ParsingDone); + return std::make_unique<internal::MatchASTConsumer>(this, ParsingDone); } void MatchFinder::match(const clang::ast_type_traits::DynTypedNode &Node, diff --git a/lib/ASTMatchers/Dynamic/Marshallers.h b/lib/ASTMatchers/Dynamic/Marshallers.h index fac2fc98e09c..9f46108d1848 100644 --- a/lib/ASTMatchers/Dynamic/Marshallers.h +++ b/lib/ASTMatchers/Dynamic/Marshallers.h @@ -729,7 +729,7 @@ std::unique_ptr<MatcherDescriptor> makeMatcherAutoMarshall(ReturnType (*Func)(), StringRef MatcherName) { std::vector<ast_type_traits::ASTNodeKind> RetTypes; BuildReturnTypeVector<ReturnType>::build(RetTypes); - return llvm::make_unique<FixedArgCountMatcherDescriptor>( + return std::make_unique<FixedArgCountMatcherDescriptor>( matcherMarshall0<ReturnType>, reinterpret_cast<void (*)()>(Func), MatcherName, RetTypes, None); } @@ -741,7 +741,7 @@ makeMatcherAutoMarshall(ReturnType (*Func)(ArgType1), StringRef MatcherName) { std::vector<ast_type_traits::ASTNodeKind> RetTypes; BuildReturnTypeVector<ReturnType>::build(RetTypes); ArgKind AK = ArgTypeTraits<ArgType1>::getKind(); - return llvm::make_unique<FixedArgCountMatcherDescriptor>( + return std::make_unique<FixedArgCountMatcherDescriptor>( matcherMarshall1<ReturnType, ArgType1>, reinterpret_cast<void (*)()>(Func), MatcherName, RetTypes, AK); } @@ -755,7 +755,7 @@ makeMatcherAutoMarshall(ReturnType (*Func)(ArgType1, ArgType2), BuildReturnTypeVector<ReturnType>::build(RetTypes); ArgKind AKs[] = { ArgTypeTraits<ArgType1>::getKind(), ArgTypeTraits<ArgType2>::getKind() }; - return llvm::make_unique<FixedArgCountMatcherDescriptor>( + return std::make_unique<FixedArgCountMatcherDescriptor>( matcherMarshall2<ReturnType, ArgType1, ArgType2>, reinterpret_cast<void (*)()>(Func), MatcherName, RetTypes, AKs); } @@ -766,7 +766,7 @@ template <typename ResultT, typename ArgT, std::unique_ptr<MatcherDescriptor> makeMatcherAutoMarshall( ast_matchers::internal::VariadicFunction<ResultT, ArgT, Func> VarFunc, StringRef MatcherName) { - return llvm::make_unique<VariadicFuncMatcherDescriptor>(VarFunc, MatcherName); + return std::make_unique<VariadicFuncMatcherDescriptor>(VarFunc, MatcherName); } /// Overload for VariadicDynCastAllOfMatchers. @@ -778,7 +778,7 @@ std::unique_ptr<MatcherDescriptor> makeMatcherAutoMarshall( ast_matchers::internal::VariadicDynCastAllOfMatcher<BaseT, DerivedT> VarFunc, StringRef MatcherName) { - return llvm::make_unique<DynCastAllOfMatcherDescriptor>(VarFunc, MatcherName); + return std::make_unique<DynCastAllOfMatcherDescriptor>(VarFunc, MatcherName); } /// Argument adaptative overload. @@ -791,7 +791,7 @@ std::unique_ptr<MatcherDescriptor> makeMatcherAutoMarshall( std::vector<std::unique_ptr<MatcherDescriptor>> Overloads; AdaptativeOverloadCollector<ArgumentAdapterT, FromTypes, ToTypes>(MatcherName, Overloads); - return llvm::make_unique<OverloadedMatcherDescriptor>(Overloads); + return std::make_unique<OverloadedMatcherDescriptor>(Overloads); } template <template <typename ToArg, typename FromArg> class ArgumentAdapterT, @@ -810,7 +810,7 @@ std::unique_ptr<MatcherDescriptor> makeMatcherAutoMarshall( ast_matchers::internal::VariadicOperatorMatcherFunc<MinCount, MaxCount> Func, StringRef MatcherName) { - return llvm::make_unique<VariadicOperatorMatcherDescriptor>( + return std::make_unique<VariadicOperatorMatcherDescriptor>( MinCount, MaxCount, Func.Op, MatcherName); } diff --git a/lib/ASTMatchers/Dynamic/Registry.cpp b/lib/ASTMatchers/Dynamic/Registry.cpp index 33058053571a..8c11e069cb05 100644 --- a/lib/ASTMatchers/Dynamic/Registry.cpp +++ b/lib/ASTMatchers/Dynamic/Registry.cpp @@ -71,7 +71,7 @@ void RegistryMaps::registerMatcher( #define REGISTER_MATCHER_OVERLOAD(name) \ registerMatcher(#name, \ - llvm::make_unique<internal::OverloadedMatcherDescriptor>(name##Callbacks)) + std::make_unique<internal::OverloadedMatcherDescriptor>(name##Callbacks)) #define SPECIFIC_MATCHER_OVERLOAD(name, Id) \ static_cast<::clang::ast_matchers::name##_Type##Id>( \ @@ -108,6 +108,7 @@ RegistryMaps::RegistryMaps() { REGISTER_OVERLOADED_2(hasType); REGISTER_OVERLOADED_2(ignoringParens); REGISTER_OVERLOADED_2(isDerivedFrom); + REGISTER_OVERLOADED_2(isDirectlyDerivedFrom); REGISTER_OVERLOADED_2(isSameOrDerivedFrom); REGISTER_OVERLOADED_2(loc); REGISTER_OVERLOADED_2(pointsTo); |