diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h index ce5d529e813fd..2fed66622850d 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -222,6 +222,19 @@ extern const internal::VariadicDynCastAllOfMatcher extern const internal::VariadicDynCastAllOfMatcher typeAliasDecl; +/// \brief Matches shadow declarations introduced into a scope by a +/// (resolved) using declaration. +/// +/// Given +/// \code +/// namespace n { int f; } +/// namespace declToImport { using n::f; } +/// \endcode +/// usingShadowDecl() +/// matches \code f \endcode +extern const internal::VariadicDynCastAllOfMatcher + usingShadowDecl; + /// Matches type alias template declarations. /// /// typeAliasTemplateDecl() matches @@ -3739,7 +3752,7 @@ extern const internal::VariadicOperatorMatcherFunc<1, 1> unless; /// Matcher, Matcher, Matcher, /// Matcher, Matcher, /// Matcher, Matcher, -/// Matcher +/// Matcher, Matcher inline internal::PolymorphicMatcher< internal::HasDeclarationMatcher, void(internal::HasDeclarationSupportedTypes), internal::Matcher> @@ -4374,7 +4387,13 @@ AST_POLYMORPHIC_MATCHER_P(throughUsingDecl, AST_POLYMORPHIC_SUPPORTED_TYPES(DeclRefExpr, UsingType), internal::Matcher, Inner) { - const NamedDecl *FoundDecl = Node.getFoundDecl(); + const NamedDecl *FoundDecl; + if constexpr (std::is_same_v) { + FoundDecl = Node.getDecl(); + } else { + static_assert(std::is_same_v); + FoundDecl = Node.getFoundDecl(); + } if (const UsingShadowDecl *UsingDecl = dyn_cast(FoundDecl)) return Inner.matches(*UsingDecl, Finder, Builder); return false; @@ -7003,37 +7022,6 @@ AST_POLYMORPHIC_MATCHER_P2( InnerMatcher.matches(Args[Index], Finder, Builder); } -/// Matches C or C++ elaborated `TypeLoc`s. -/// -/// Given -/// \code -/// struct s {}; -/// struct s ss; -/// \endcode -/// elaboratedTypeLoc() -/// matches the `TypeLoc` of the variable declaration of `ss`. -extern const internal::VariadicDynCastAllOfMatcher - elaboratedTypeLoc; - -/// Matches elaborated `TypeLoc`s that have a named `TypeLoc` matching -/// `InnerMatcher`. -/// -/// Given -/// \code -/// template -/// class C {}; -/// class C c; -/// -/// class D {}; -/// class D d; -/// \endcode -/// elaboratedTypeLoc(hasNamedTypeLoc(templateSpecializationTypeLoc())); -/// matches the `TypeLoc` of the variable declaration of `c`, but not `d`. -AST_MATCHER_P(ElaboratedTypeLoc, hasNamedTypeLoc, internal::Matcher, - InnerMatcher) { - return InnerMatcher.matches(Node.getNamedTypeLoc(), Finder, Builder); -} - /// Matches type \c bool. /// /// Given @@ -7300,7 +7288,7 @@ extern const AstTypeMatcher decltypeType; AST_TYPE_TRAVERSE_MATCHER(hasDeducedType, getDeducedType, AST_POLYMORPHIC_SUPPORTED_TYPES(AutoType)); -/// Matches \c DecltypeType or \c UsingType nodes to find the underlying type. +/// Matches \c QualType nodes to find the underlying type. /// /// Given /// \code @@ -7310,10 +7298,13 @@ AST_TYPE_TRAVERSE_MATCHER(hasDeducedType, getDeducedType, /// decltypeType(hasUnderlyingType(isInteger())) /// matches the type of "a" /// -/// Usable as: Matcher, Matcher -AST_TYPE_TRAVERSE_MATCHER(hasUnderlyingType, getUnderlyingType, - AST_POLYMORPHIC_SUPPORTED_TYPES(DecltypeType, - UsingType)); +/// Usable as: Matcher +AST_MATCHER_P(Type, hasUnderlyingType, internal::Matcher, Inner) { + QualType QT = Node.getLocallyUnqualifiedSingleStepDesugaredType(); + if (QT == QualType(&Node, 0)) + return false; + return Inner.matches(QT, Finder, Builder); +} /// Matches \c FunctionType nodes. /// @@ -7592,27 +7583,7 @@ extern const AstTypeMatcher recordType; /// and \c c. extern const AstTypeMatcher tagType; -/// Matches types specified with an elaborated type keyword or with a -/// qualified name. -/// -/// Given -/// \code -/// namespace N { -/// namespace M { -/// class D {}; -/// } -/// } -/// class C {}; -/// -/// class C c; -/// N::M::D d; -/// \endcode -/// -/// \c elaboratedType() matches the type of the variable declarations of both -/// \c c and \c d. -extern const AstTypeMatcher elaboratedType; - -/// Matches ElaboratedTypes whose qualifier, a NestedNameSpecifier, +/// Matches Types whose qualifier, a NestedNameSpecifier, /// matches \c InnerMatcher if the qualifier exists. /// /// Given @@ -7627,34 +7598,14 @@ extern const AstTypeMatcher elaboratedType; /// /// \c elaboratedType(hasQualifier(hasPrefix(specifiesNamespace(hasName("N")))) /// matches the type of the variable declaration of \c d. -AST_MATCHER_P(ElaboratedType, hasQualifier, - internal::Matcher, InnerMatcher) { - if (const NestedNameSpecifier *Qualifier = Node.getQualifier()) - return InnerMatcher.matches(*Qualifier, Finder, Builder); +AST_MATCHER_P(Type, hasQualifier, internal::Matcher, + InnerMatcher) { + if (NestedNameSpecifier Qualifier = Node.getPrefix()) + return InnerMatcher.matches(Qualifier, Finder, Builder); return false; } -/// Matches ElaboratedTypes whose named type matches \c InnerMatcher. -/// -/// Given -/// \code -/// namespace N { -/// namespace M { -/// class D {}; -/// } -/// } -/// N::M::D d; -/// \endcode -/// -/// \c elaboratedType(namesType(recordType( -/// hasDeclaration(namedDecl(hasName("D")))))) matches the type of the variable -/// declaration of \c d. -AST_MATCHER_P(ElaboratedType, namesType, internal::Matcher, - InnerMatcher) { - return InnerMatcher.matches(Node.getNamedType(), Finder, Builder); -} - /// Matches types specified through a using declaration. /// /// Given @@ -7823,7 +7774,7 @@ AST_MATCHER_FUNCTION_P_OVERLOAD( /// matches "A::" AST_MATCHER_P(NestedNameSpecifier, specifiesType, internal::Matcher, InnerMatcher) { - if (!Node.getAsType()) + if (Node.getKind() != NestedNameSpecifier::Kind::Type) return false; return InnerMatcher.matches(QualType(Node.getAsType(), 0), Finder, Builder); } @@ -7841,8 +7792,12 @@ AST_MATCHER_P(NestedNameSpecifier, specifiesType, /// matches "A::" AST_MATCHER_P(NestedNameSpecifierLoc, specifiesTypeLoc, internal::Matcher, InnerMatcher) { - return Node && Node.getNestedNameSpecifier()->getAsType() && - InnerMatcher.matches(Node.getTypeLoc(), Finder, Builder); + if (!Node) + return false; + TypeLoc TL = Node.getAsTypeLoc(); + if (!TL) + return false; + return InnerMatcher.matches(TL, Finder, Builder); } /// Matches on the prefix of a \c NestedNameSpecifier. @@ -7857,10 +7812,21 @@ AST_MATCHER_P(NestedNameSpecifierLoc, specifiesTypeLoc, AST_MATCHER_P_OVERLOAD(NestedNameSpecifier, hasPrefix, internal::Matcher, InnerMatcher, 0) { - const NestedNameSpecifier *NextNode = Node.getPrefix(); + NestedNameSpecifier NextNode = std::nullopt; + switch (Node.getKind()) { + case NestedNameSpecifier::Kind::Namespace: + NextNode = Node.getAsNamespaceAndPrefix().Prefix; + break; + case NestedNameSpecifier::Kind::Type: + NextNode = Node.getAsType()->getPrefix(); + break; + default: + break; + } + if (!NextNode) return false; - return InnerMatcher.matches(*NextNode, Finder, Builder); + return InnerMatcher.matches(NextNode, Finder, Builder); } /// Matches on the prefix of a \c NestedNameSpecifierLoc. @@ -7875,7 +7841,12 @@ AST_MATCHER_P_OVERLOAD(NestedNameSpecifier, hasPrefix, AST_MATCHER_P_OVERLOAD(NestedNameSpecifierLoc, hasPrefix, internal::Matcher, InnerMatcher, 1) { - NestedNameSpecifierLoc NextNode = Node.getPrefix(); + NestedNameSpecifierLoc NextNode; + if (TypeLoc TL = Node.getAsTypeLoc()) + NextNode = TL.getPrefix(); + else + NextNode = Node.getAsNamespaceAndPrefix().Prefix; + if (!NextNode) return false; return InnerMatcher.matches(NextNode, Finder, Builder); @@ -7893,9 +7864,13 @@ AST_MATCHER_P_OVERLOAD(NestedNameSpecifierLoc, hasPrefix, /// matches "ns::" AST_MATCHER_P(NestedNameSpecifier, specifiesNamespace, internal::Matcher, InnerMatcher) { - if (!Node.getAsNamespace()) + if (Node.getKind() != NestedNameSpecifier::Kind::Namespace) + return false; + const auto *Namespace = + dyn_cast(Node.getAsNamespaceAndPrefix().Namespace); + if (!Namespace) return false; - return InnerMatcher.matches(*Node.getAsNamespace(), Finder, Builder); + return InnerMatcher.matches(*Namespace, Finder, Builder); } /// Matches attributes. diff --git a/clang/include/clang/ASTMatchers/ASTMatchersInternal.h b/clang/include/clang/ASTMatchers/ASTMatchersInternal.h index 5df2294792552..1ab6f11a23e12 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchersInternal.h +++ b/clang/include/clang/ASTMatchers/ASTMatchersInternal.h @@ -1017,10 +1017,7 @@ class HasDeclarationMatcher : public MatcherInterface { // First, for any types that have a declaration, extract the declaration and // match on it. if (const auto *S = dyn_cast(&Node)) { - return matchesDecl(S->getDecl(), Finder, Builder); - } - if (const auto *S = dyn_cast(&Node)) { - return matchesDecl(S->getDecl(), Finder, Builder); + return matchesDecl(S->getOriginalDecl(), Finder, Builder); } if (const auto *S = dyn_cast(&Node)) { return matchesDecl(S->getDecl(), Finder, Builder); @@ -1031,6 +1028,9 @@ class HasDeclarationMatcher : public MatcherInterface { if (const auto *S = dyn_cast(&Node)) { return matchesDecl(S->getDecl(), Finder, Builder); } + if (const auto *S = dyn_cast(&Node)) { + return matchesDecl(S->getDecl(), Finder, Builder); + } if (const auto *S = dyn_cast(&Node)) { return matchesDecl(S->getInterface(), Finder, Builder); } @@ -1066,12 +1066,6 @@ class HasDeclarationMatcher : public MatcherInterface { Builder); } - // FIXME: We desugar elaborated types. This makes the assumption that users - // do never want to match on whether a type is elaborated - there are - // arguments for both sides; for now, continue desugaring. - if (const auto *S = dyn_cast(&Node)) { - return matchesSpecialized(S->desugar(), Finder, Builder); - } // Similarly types found via using declarations. // These are *usually* meaningless sugar, and this matches the historical // behavior prior to the introduction of UsingType. @@ -1211,8 +1205,8 @@ using AdaptativeDefaultToTypes = /// All types that are supported by HasDeclarationMatcher above. using HasDeclarationSupportedTypes = TypeList; @@ -1789,7 +1783,7 @@ class LocMatcher : public MatcherInterface { private: static DynTypedNode extract(const NestedNameSpecifierLoc &Loc) { - return DynTypedNode::create(*Loc.getNestedNameSpecifier()); + return DynTypedNode::create(Loc.getNestedNameSpecifier()); } }; diff --git a/clang/include/clang/Analysis/FlowSensitive/ASTOps.h b/clang/include/clang/Analysis/FlowSensitive/ASTOps.h index 8c7ee86d15c06..a404b06cd62ca 100644 --- a/clang/include/clang/Analysis/FlowSensitive/ASTOps.h +++ b/clang/include/clang/Analysis/FlowSensitive/ASTOps.h @@ -112,8 +112,14 @@ class AnalysisASTVisitor : public DynamicRecursiveASTVisitor { // fields that are only used in these. // Note: The operand of the `noexcept` operator is an unevaluated operand, but // nevertheless it appears in the Clang CFG, so we don't exclude it here. - bool TraverseDecltypeTypeLoc(DecltypeTypeLoc) override { return true; } - bool TraverseTypeOfExprTypeLoc(TypeOfExprTypeLoc) override { return true; } + bool TraverseDecltypeTypeLoc(DecltypeTypeLoc, + bool TraverseQualifier) override { + return true; + } + bool TraverseTypeOfExprTypeLoc(TypeOfExprTypeLoc, + bool TraverseQualifier) override { + return true; + } bool TraverseCXXTypeidExpr(CXXTypeidExpr *TIE) override { if (TIE->isPotentiallyEvaluated()) return DynamicRecursiveASTVisitor::TraverseCXXTypeidExpr(TIE); diff --git a/clang/include/clang/Basic/DeclNodes.td b/clang/include/clang/Basic/DeclNodes.td index f1ebaf1db3fc0..b4c02949426a1 100644 --- a/clang/include/clang/Basic/DeclNodes.td +++ b/clang/include/clang/Basic/DeclNodes.td @@ -15,81 +15,80 @@ def PragmaComment : DeclNode; def PragmaDetectMismatch : DeclNode; def ExternCContext : DeclNode, DeclContext; def Named : DeclNode; - def Namespace : DeclNode, DeclContext; - def UsingDirective : DeclNode; - def NamespaceAlias : DeclNode; - def Label : DeclNode; - def Type : DeclNode; - def TypedefName : DeclNode; - def Typedef : DeclNode; - def TypeAlias : DeclNode; - def ObjCTypeParam : DeclNode; - def UnresolvedUsingTypename : DeclNode; - def Tag : DeclNode, DeclContext; - def Enum : DeclNode; - def Record : DeclNode; - def CXXRecord : DeclNode; - def ClassTemplateSpecialization : DeclNode; - def ClassTemplatePartialSpecialization - : DeclNode; - def TemplateTypeParm : DeclNode; - def Value : DeclNode; - def EnumConstant : DeclNode; - def UnresolvedUsingValue : DeclNode; - def IndirectField : DeclNode; - def Binding : DeclNode; - def OMPDeclareReduction : DeclNode, DeclContext; - def OMPDeclareMapper : DeclNode, DeclContext; - def MSGuid : DeclNode; - def UnnamedGlobalConstant : DeclNode; - def TemplateParamObject : DeclNode; - def Declarator : DeclNode; - def Field : DeclNode; - def ObjCIvar : DeclNode; - def ObjCAtDefsField : DeclNode; - def MSProperty : DeclNode; - def Function : DeclNode, DeclContext; - def CXXDeductionGuide : DeclNode; - def CXXMethod : DeclNode; - def CXXConstructor : DeclNode; - def CXXDestructor : DeclNode; - def CXXConversion : DeclNode; - def Var : DeclNode; - def VarTemplateSpecialization : DeclNode; - def VarTemplatePartialSpecialization - : DeclNode; - def ImplicitParam : DeclNode; - def ParmVar : DeclNode; - def Decomposition : DeclNode; - def OMPCapturedExpr : DeclNode; - def NonTypeTemplateParm : DeclNode; - def Template : DeclNode; - def RedeclarableTemplate : DeclNode; - def FunctionTemplate : DeclNode; - def ClassTemplate : DeclNode; - def VarTemplate : DeclNode; - def TypeAliasTemplate : DeclNode; - def TemplateTemplateParm : DeclNode