Skip to content

Commit 1aae9f7

Browse files
committed
[PATCH 2/4] [clang] Improve nested name specifier AST representation
Other changes
1 parent 374aefc commit 1aae9f7

File tree

173 files changed

+3741
-3504
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

173 files changed

+3741
-3504
lines changed

clang/include/clang/ASTMatchers/ASTMatchers.h

Lines changed: 66 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,19 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, TypedefNameDecl>
221221
extern const internal::VariadicDynCastAllOfMatcher<Decl, TypeAliasDecl>
222222
typeAliasDecl;
223223

224+
/// \brief Matches shadow declarations introduced into a scope by a
225+
/// (resolved) using declaration.
226+
///
227+
/// Given
228+
/// \code
229+
/// namespace n { int f; }
230+
/// namespace declToImport { using n::f; }
231+
/// \endcode
232+
/// usingShadowDecl()
233+
/// matches \code f \endcode
234+
extern const internal::VariadicDynCastAllOfMatcher<Decl, UsingShadowDecl>
235+
usingShadowDecl;
236+
224237
/// Matches type alias template declarations.
225238
///
226239
/// typeAliasTemplateDecl() matches
@@ -3718,7 +3731,7 @@ extern const internal::VariadicOperatorMatcherFunc<1, 1> unless;
37183731
/// Matcher<MemberExpr>, Matcher<QualType>, Matcher<RecordType>,
37193732
/// Matcher<TagType>, Matcher<TemplateSpecializationType>,
37203733
/// Matcher<TemplateTypeParmType>, Matcher<TypedefType>,
3721-
/// Matcher<UnresolvedUsingType>
3734+
/// Matcher<UnresolvedUsingType>, Matcher<UsingType>
37223735
inline internal::PolymorphicMatcher<
37233736
internal::HasDeclarationMatcher,
37243737
void(internal::HasDeclarationSupportedTypes), internal::Matcher<Decl>>
@@ -4353,7 +4366,13 @@ AST_POLYMORPHIC_MATCHER_P(throughUsingDecl,
43534366
AST_POLYMORPHIC_SUPPORTED_TYPES(DeclRefExpr,
43544367
UsingType),
43554368
internal::Matcher<UsingShadowDecl>, Inner) {
4356-
const NamedDecl *FoundDecl = Node.getFoundDecl();
4369+
const NamedDecl *FoundDecl;
4370+
if constexpr (std::is_same_v<NodeType, UsingType>) {
4371+
FoundDecl = Node.getDecl();
4372+
} else {
4373+
static_assert(std::is_same_v<NodeType, DeclRefExpr>);
4374+
FoundDecl = Node.getFoundDecl();
4375+
}
43574376
if (const UsingShadowDecl *UsingDecl = dyn_cast<UsingShadowDecl>(FoundDecl))
43584377
return Inner.matches(*UsingDecl, Finder, Builder);
43594378
return false;
@@ -6982,37 +7001,6 @@ AST_POLYMORPHIC_MATCHER_P2(
69827001
InnerMatcher.matches(Args[Index], Finder, Builder);
69837002
}
69847003

6985-
/// Matches C or C++ elaborated `TypeLoc`s.
6986-
///
6987-
/// Given
6988-
/// \code
6989-
/// struct s {};
6990-
/// struct s ss;
6991-
/// \endcode
6992-
/// elaboratedTypeLoc()
6993-
/// matches the `TypeLoc` of the variable declaration of `ss`.
6994-
extern const internal::VariadicDynCastAllOfMatcher<TypeLoc, ElaboratedTypeLoc>
6995-
elaboratedTypeLoc;
6996-
6997-
/// Matches elaborated `TypeLoc`s that have a named `TypeLoc` matching
6998-
/// `InnerMatcher`.
6999-
///
7000-
/// Given
7001-
/// \code
7002-
/// template <typename T>
7003-
/// class C {};
7004-
/// class C<int> c;
7005-
///
7006-
/// class D {};
7007-
/// class D d;
7008-
/// \endcode
7009-
/// elaboratedTypeLoc(hasNamedTypeLoc(templateSpecializationTypeLoc()));
7010-
/// matches the `TypeLoc` of the variable declaration of `c`, but not `d`.
7011-
AST_MATCHER_P(ElaboratedTypeLoc, hasNamedTypeLoc, internal::Matcher<TypeLoc>,
7012-
InnerMatcher) {
7013-
return InnerMatcher.matches(Node.getNamedTypeLoc(), Finder, Builder);
7014-
}
7015-
70167004
/// Matches type \c bool.
70177005
///
70187006
/// Given
@@ -7279,7 +7267,7 @@ extern const AstTypeMatcher<DecltypeType> decltypeType;
72797267
AST_TYPE_TRAVERSE_MATCHER(hasDeducedType, getDeducedType,
72807268
AST_POLYMORPHIC_SUPPORTED_TYPES(AutoType));
72817269

7282-
/// Matches \c DecltypeType or \c UsingType nodes to find the underlying type.
7270+
/// Matches \c QualType nodes to find the underlying type.
72837271
///
72847272
/// Given
72857273
/// \code
@@ -7289,10 +7277,13 @@ AST_TYPE_TRAVERSE_MATCHER(hasDeducedType, getDeducedType,
72897277
/// decltypeType(hasUnderlyingType(isInteger()))
72907278
/// matches the type of "a"
72917279
///
7292-
/// Usable as: Matcher<DecltypeType>, Matcher<UsingType>
7293-
AST_TYPE_TRAVERSE_MATCHER(hasUnderlyingType, getUnderlyingType,
7294-
AST_POLYMORPHIC_SUPPORTED_TYPES(DecltypeType,
7295-
UsingType));
7280+
/// Usable as: Matcher<QualType>
7281+
AST_MATCHER_P(Type, hasUnderlyingType, internal::Matcher<QualType>, Inner) {
7282+
QualType QT = Node.getLocallyUnqualifiedSingleStepDesugaredType();
7283+
if (QT == QualType(&Node, 0))
7284+
return false;
7285+
return Inner.matches(QT, Finder, Builder);
7286+
}
72967287

72977288
/// Matches \c FunctionType nodes.
72987289
///
@@ -7571,27 +7562,7 @@ extern const AstTypeMatcher<RecordType> recordType;
75717562
/// and \c c.
75727563
extern const AstTypeMatcher<TagType> tagType;
75737564

7574-
/// Matches types specified with an elaborated type keyword or with a
7575-
/// qualified name.
7576-
///
7577-
/// Given
7578-
/// \code
7579-
/// namespace N {
7580-
/// namespace M {
7581-
/// class D {};
7582-
/// }
7583-
/// }
7584-
/// class C {};
7585-
///
7586-
/// class C c;
7587-
/// N::M::D d;
7588-
/// \endcode
7589-
///
7590-
/// \c elaboratedType() matches the type of the variable declarations of both
7591-
/// \c c and \c d.
7592-
extern const AstTypeMatcher<ElaboratedType> elaboratedType;
7593-
7594-
/// Matches ElaboratedTypes whose qualifier, a NestedNameSpecifier,
7565+
/// Matches Types whose qualifier, a NestedNameSpecifier,
75957566
/// matches \c InnerMatcher if the qualifier exists.
75967567
///
75977568
/// Given
@@ -7606,34 +7577,14 @@ extern const AstTypeMatcher<ElaboratedType> elaboratedType;
76067577
///
76077578
/// \c elaboratedType(hasQualifier(hasPrefix(specifiesNamespace(hasName("N"))))
76087579
/// matches the type of the variable declaration of \c d.
7609-
AST_MATCHER_P(ElaboratedType, hasQualifier,
7610-
internal::Matcher<NestedNameSpecifier>, InnerMatcher) {
7611-
if (const NestedNameSpecifier *Qualifier = Node.getQualifier())
7612-
return InnerMatcher.matches(*Qualifier, Finder, Builder);
7580+
AST_MATCHER_P(Type, hasQualifier, internal::Matcher<NestedNameSpecifier>,
7581+
InnerMatcher) {
7582+
if (NestedNameSpecifier Qualifier = Node.getPrefix())
7583+
return InnerMatcher.matches(Qualifier, Finder, Builder);
76137584

76147585
return false;
76157586
}
76167587

7617-
/// Matches ElaboratedTypes whose named type matches \c InnerMatcher.
7618-
///
7619-
/// Given
7620-
/// \code
7621-
/// namespace N {
7622-
/// namespace M {
7623-
/// class D {};
7624-
/// }
7625-
/// }
7626-
/// N::M::D d;
7627-
/// \endcode
7628-
///
7629-
/// \c elaboratedType(namesType(recordType(
7630-
/// hasDeclaration(namedDecl(hasName("D")))))) matches the type of the variable
7631-
/// declaration of \c d.
7632-
AST_MATCHER_P(ElaboratedType, namesType, internal::Matcher<QualType>,
7633-
InnerMatcher) {
7634-
return InnerMatcher.matches(Node.getNamedType(), Finder, Builder);
7635-
}
7636-
76377588
/// Matches types specified through a using declaration.
76387589
///
76397590
/// Given
@@ -7802,7 +7753,7 @@ AST_MATCHER_FUNCTION_P_OVERLOAD(
78027753
/// matches "A::"
78037754
AST_MATCHER_P(NestedNameSpecifier, specifiesType,
78047755
internal::Matcher<QualType>, InnerMatcher) {
7805-
if (!Node.getAsType())
7756+
if (Node.getKind() != NestedNameSpecifier::Kind::Type)
78067757
return false;
78077758
return InnerMatcher.matches(QualType(Node.getAsType(), 0), Finder, Builder);
78087759
}
@@ -7820,8 +7771,12 @@ AST_MATCHER_P(NestedNameSpecifier, specifiesType,
78207771
/// matches "A::"
78217772
AST_MATCHER_P(NestedNameSpecifierLoc, specifiesTypeLoc,
78227773
internal::Matcher<TypeLoc>, InnerMatcher) {
7823-
return Node && Node.getNestedNameSpecifier()->getAsType() &&
7824-
InnerMatcher.matches(Node.getTypeLoc(), Finder, Builder);
7774+
if (!Node)
7775+
return false;
7776+
TypeLoc TL = Node.getAsTypeLoc();
7777+
if (!TL)
7778+
return false;
7779+
return InnerMatcher.matches(TL, Finder, Builder);
78257780
}
78267781

78277782
/// Matches on the prefix of a \c NestedNameSpecifier.
@@ -7836,10 +7791,21 @@ AST_MATCHER_P(NestedNameSpecifierLoc, specifiesTypeLoc,
78367791
AST_MATCHER_P_OVERLOAD(NestedNameSpecifier, hasPrefix,
78377792
internal::Matcher<NestedNameSpecifier>, InnerMatcher,
78387793
0) {
7839-
const NestedNameSpecifier *NextNode = Node.getPrefix();
7794+
NestedNameSpecifier NextNode = std::nullopt;
7795+
switch (Node.getKind()) {
7796+
case NestedNameSpecifier::Kind::Namespace:
7797+
NextNode = Node.getAsNamespaceAndPrefix().Prefix;
7798+
break;
7799+
case NestedNameSpecifier::Kind::Type:
7800+
NextNode = Node.getAsType()->getPrefix();
7801+
break;
7802+
default:
7803+
break;
7804+
}
7805+
78407806
if (!NextNode)
78417807
return false;
7842-
return InnerMatcher.matches(*NextNode, Finder, Builder);
7808+
return InnerMatcher.matches(NextNode, Finder, Builder);
78437809
}
78447810

78457811
/// Matches on the prefix of a \c NestedNameSpecifierLoc.
@@ -7854,7 +7820,12 @@ AST_MATCHER_P_OVERLOAD(NestedNameSpecifier, hasPrefix,
78547820
AST_MATCHER_P_OVERLOAD(NestedNameSpecifierLoc, hasPrefix,
78557821
internal::Matcher<NestedNameSpecifierLoc>, InnerMatcher,
78567822
1) {
7857-
NestedNameSpecifierLoc NextNode = Node.getPrefix();
7823+
NestedNameSpecifierLoc NextNode;
7824+
if (TypeLoc TL = Node.getAsTypeLoc())
7825+
NextNode = TL.getPrefix();
7826+
else
7827+
NextNode = Node.getAsNamespaceAndPrefix().Prefix;
7828+
78587829
if (!NextNode)
78597830
return false;
78607831
return InnerMatcher.matches(NextNode, Finder, Builder);
@@ -7872,9 +7843,13 @@ AST_MATCHER_P_OVERLOAD(NestedNameSpecifierLoc, hasPrefix,
78727843
/// matches "ns::"
78737844
AST_MATCHER_P(NestedNameSpecifier, specifiesNamespace,
78747845
internal::Matcher<NamespaceDecl>, InnerMatcher) {
7875-
if (!Node.getAsNamespace())
7846+
if (Node.getKind() != NestedNameSpecifier::Kind::Namespace)
7847+
return false;
7848+
const auto *Namespace =
7849+
dyn_cast<NamespaceDecl>(Node.getAsNamespaceAndPrefix().Namespace);
7850+
if (!Namespace)
78767851
return false;
7877-
return InnerMatcher.matches(*Node.getAsNamespace(), Finder, Builder);
7852+
return InnerMatcher.matches(*Namespace, Finder, Builder);
78787853
}
78797854

78807855
/// Matches attributes.

clang/include/clang/ASTMatchers/ASTMatchersInternal.h

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1013,10 +1013,7 @@ class HasDeclarationMatcher : public MatcherInterface<T> {
10131013
// First, for any types that have a declaration, extract the declaration and
10141014
// match on it.
10151015
if (const auto *S = dyn_cast<TagType>(&Node)) {
1016-
return matchesDecl(S->getDecl(), Finder, Builder);
1017-
}
1018-
if (const auto *S = dyn_cast<InjectedClassNameType>(&Node)) {
1019-
return matchesDecl(S->getDecl(), Finder, Builder);
1016+
return matchesDecl(S->getOriginalDecl(), Finder, Builder);
10201017
}
10211018
if (const auto *S = dyn_cast<TemplateTypeParmType>(&Node)) {
10221019
return matchesDecl(S->getDecl(), Finder, Builder);
@@ -1027,6 +1024,9 @@ class HasDeclarationMatcher : public MatcherInterface<T> {
10271024
if (const auto *S = dyn_cast<UnresolvedUsingType>(&Node)) {
10281025
return matchesDecl(S->getDecl(), Finder, Builder);
10291026
}
1027+
if (const auto *S = dyn_cast<UsingType>(&Node)) {
1028+
return matchesDecl(S->getDecl(), Finder, Builder);
1029+
}
10301030
if (const auto *S = dyn_cast<ObjCObjectType>(&Node)) {
10311031
return matchesDecl(S->getInterface(), Finder, Builder);
10321032
}
@@ -1062,12 +1062,6 @@ class HasDeclarationMatcher : public MatcherInterface<T> {
10621062
Builder);
10631063
}
10641064

1065-
// FIXME: We desugar elaborated types. This makes the assumption that users
1066-
// do never want to match on whether a type is elaborated - there are
1067-
// arguments for both sides; for now, continue desugaring.
1068-
if (const auto *S = dyn_cast<ElaboratedType>(&Node)) {
1069-
return matchesSpecialized(S->desugar(), Finder, Builder);
1070-
}
10711065
// Similarly types found via using declarations.
10721066
// These are *usually* meaningless sugar, and this matches the historical
10731067
// behavior prior to the introduction of UsingType.
@@ -1207,8 +1201,8 @@ using AdaptativeDefaultToTypes =
12071201
/// All types that are supported by HasDeclarationMatcher above.
12081202
using HasDeclarationSupportedTypes =
12091203
TypeList<CallExpr, CXXConstructExpr, CXXNewExpr, DeclRefExpr, EnumType,
1210-
ElaboratedType, InjectedClassNameType, LabelStmt, AddrLabelExpr,
1211-
MemberExpr, QualType, RecordType, TagType,
1204+
InjectedClassNameType, LabelStmt, AddrLabelExpr, MemberExpr,
1205+
QualType, RecordType, TagType, UsingType,
12121206
TemplateSpecializationType, TemplateTypeParmType, TypedefType,
12131207
UnresolvedUsingType, ObjCIvarRefExpr, ObjCInterfaceDecl>;
12141208

@@ -1785,7 +1779,7 @@ class LocMatcher : public MatcherInterface<TLoc> {
17851779

17861780
private:
17871781
static DynTypedNode extract(const NestedNameSpecifierLoc &Loc) {
1788-
return DynTypedNode::create(*Loc.getNestedNameSpecifier());
1782+
return DynTypedNode::create(Loc.getNestedNameSpecifier());
17891783
}
17901784
};
17911785

clang/include/clang/Analysis/FlowSensitive/ASTOps.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,14 @@ class AnalysisASTVisitor : public DynamicRecursiveASTVisitor {
112112
// fields that are only used in these.
113113
// Note: The operand of the `noexcept` operator is an unevaluated operand, but
114114
// nevertheless it appears in the Clang CFG, so we don't exclude it here.
115-
bool TraverseDecltypeTypeLoc(DecltypeTypeLoc) override { return true; }
116-
bool TraverseTypeOfExprTypeLoc(TypeOfExprTypeLoc) override { return true; }
115+
bool TraverseDecltypeTypeLoc(DecltypeTypeLoc,
116+
bool TraverseQualifier) override {
117+
return true;
118+
}
119+
bool TraverseTypeOfExprTypeLoc(TypeOfExprTypeLoc,
120+
bool TraverseQualifier) override {
121+
return true;
122+
}
117123
bool TraverseCXXTypeidExpr(CXXTypeidExpr *TIE) override {
118124
if (TIE->isPotentiallyEvaluated())
119125
return DynamicRecursiveASTVisitor::TraverseCXXTypeidExpr(TIE);

0 commit comments

Comments
 (0)