Skip to content

Commit ddaea06

Browse files
committed
[PATCH 2/4] [clang] Improve nested name specifier AST representation
Other changes
1 parent 8da8c53 commit ddaea06

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
@@ -222,6 +222,19 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, TypedefNameDecl>
222222
extern const internal::VariadicDynCastAllOfMatcher<Decl, TypeAliasDecl>
223223
typeAliasDecl;
224224

225+
/// \brief Matches shadow declarations introduced into a scope by a
226+
/// (resolved) using declaration.
227+
///
228+
/// Given
229+
/// \code
230+
/// namespace n { int f; }
231+
/// namespace declToImport { using n::f; }
232+
/// \endcode
233+
/// usingShadowDecl()
234+
/// matches \code f \endcode
235+
extern const internal::VariadicDynCastAllOfMatcher<Decl, UsingShadowDecl>
236+
usingShadowDecl;
237+
225238
/// Matches type alias template declarations.
226239
///
227240
/// typeAliasTemplateDecl() matches
@@ -3739,7 +3752,7 @@ extern const internal::VariadicOperatorMatcherFunc<1, 1> unless;
37393752
/// Matcher<MemberExpr>, Matcher<QualType>, Matcher<RecordType>,
37403753
/// Matcher<TagType>, Matcher<TemplateSpecializationType>,
37413754
/// Matcher<TemplateTypeParmType>, Matcher<TypedefType>,
3742-
/// Matcher<UnresolvedUsingType>
3755+
/// Matcher<UnresolvedUsingType>, Matcher<UsingType>
37433756
inline internal::PolymorphicMatcher<
37443757
internal::HasDeclarationMatcher,
37453758
void(internal::HasDeclarationSupportedTypes), internal::Matcher<Decl>>
@@ -4374,7 +4387,13 @@ AST_POLYMORPHIC_MATCHER_P(throughUsingDecl,
43744387
AST_POLYMORPHIC_SUPPORTED_TYPES(DeclRefExpr,
43754388
UsingType),
43764389
internal::Matcher<UsingShadowDecl>, Inner) {
4377-
const NamedDecl *FoundDecl = Node.getFoundDecl();
4390+
const NamedDecl *FoundDecl;
4391+
if constexpr (std::is_same_v<NodeType, UsingType>) {
4392+
FoundDecl = Node.getDecl();
4393+
} else {
4394+
static_assert(std::is_same_v<NodeType, DeclRefExpr>);
4395+
FoundDecl = Node.getFoundDecl();
4396+
}
43784397
if (const UsingShadowDecl *UsingDecl = dyn_cast<UsingShadowDecl>(FoundDecl))
43794398
return Inner.matches(*UsingDecl, Finder, Builder);
43804399
return false;
@@ -7003,37 +7022,6 @@ AST_POLYMORPHIC_MATCHER_P2(
70037022
InnerMatcher.matches(Args[Index], Finder, Builder);
70047023
}
70057024

7006-
/// Matches C or C++ elaborated `TypeLoc`s.
7007-
///
7008-
/// Given
7009-
/// \code
7010-
/// struct s {};
7011-
/// struct s ss;
7012-
/// \endcode
7013-
/// elaboratedTypeLoc()
7014-
/// matches the `TypeLoc` of the variable declaration of `ss`.
7015-
extern const internal::VariadicDynCastAllOfMatcher<TypeLoc, ElaboratedTypeLoc>
7016-
elaboratedTypeLoc;
7017-
7018-
/// Matches elaborated `TypeLoc`s that have a named `TypeLoc` matching
7019-
/// `InnerMatcher`.
7020-
///
7021-
/// Given
7022-
/// \code
7023-
/// template <typename T>
7024-
/// class C {};
7025-
/// class C<int> c;
7026-
///
7027-
/// class D {};
7028-
/// class D d;
7029-
/// \endcode
7030-
/// elaboratedTypeLoc(hasNamedTypeLoc(templateSpecializationTypeLoc()));
7031-
/// matches the `TypeLoc` of the variable declaration of `c`, but not `d`.
7032-
AST_MATCHER_P(ElaboratedTypeLoc, hasNamedTypeLoc, internal::Matcher<TypeLoc>,
7033-
InnerMatcher) {
7034-
return InnerMatcher.matches(Node.getNamedTypeLoc(), Finder, Builder);
7035-
}
7036-
70377025
/// Matches type \c bool.
70387026
///
70397027
/// Given
@@ -7300,7 +7288,7 @@ extern const AstTypeMatcher<DecltypeType> decltypeType;
73007288
AST_TYPE_TRAVERSE_MATCHER(hasDeducedType, getDeducedType,
73017289
AST_POLYMORPHIC_SUPPORTED_TYPES(AutoType));
73027290

7303-
/// Matches \c DecltypeType or \c UsingType nodes to find the underlying type.
7291+
/// Matches \c QualType nodes to find the underlying type.
73047292
///
73057293
/// Given
73067294
/// \code
@@ -7310,10 +7298,13 @@ AST_TYPE_TRAVERSE_MATCHER(hasDeducedType, getDeducedType,
73107298
/// decltypeType(hasUnderlyingType(isInteger()))
73117299
/// matches the type of "a"
73127300
///
7313-
/// Usable as: Matcher<DecltypeType>, Matcher<UsingType>
7314-
AST_TYPE_TRAVERSE_MATCHER(hasUnderlyingType, getUnderlyingType,
7315-
AST_POLYMORPHIC_SUPPORTED_TYPES(DecltypeType,
7316-
UsingType));
7301+
/// Usable as: Matcher<QualType>
7302+
AST_MATCHER_P(Type, hasUnderlyingType, internal::Matcher<QualType>, Inner) {
7303+
QualType QT = Node.getLocallyUnqualifiedSingleStepDesugaredType();
7304+
if (QT == QualType(&Node, 0))
7305+
return false;
7306+
return Inner.matches(QT, Finder, Builder);
7307+
}
73177308

73187309
/// Matches \c FunctionType nodes.
73197310
///
@@ -7592,27 +7583,7 @@ extern const AstTypeMatcher<RecordType> recordType;
75927583
/// and \c c.
75937584
extern const AstTypeMatcher<TagType> tagType;
75947585

7595-
/// Matches types specified with an elaborated type keyword or with a
7596-
/// qualified name.
7597-
///
7598-
/// Given
7599-
/// \code
7600-
/// namespace N {
7601-
/// namespace M {
7602-
/// class D {};
7603-
/// }
7604-
/// }
7605-
/// class C {};
7606-
///
7607-
/// class C c;
7608-
/// N::M::D d;
7609-
/// \endcode
7610-
///
7611-
/// \c elaboratedType() matches the type of the variable declarations of both
7612-
/// \c c and \c d.
7613-
extern const AstTypeMatcher<ElaboratedType> elaboratedType;
7614-
7615-
/// Matches ElaboratedTypes whose qualifier, a NestedNameSpecifier,
7586+
/// Matches Types whose qualifier, a NestedNameSpecifier,
76167587
/// matches \c InnerMatcher if the qualifier exists.
76177588
///
76187589
/// Given
@@ -7627,34 +7598,14 @@ extern const AstTypeMatcher<ElaboratedType> elaboratedType;
76277598
///
76287599
/// \c elaboratedType(hasQualifier(hasPrefix(specifiesNamespace(hasName("N"))))
76297600
/// matches the type of the variable declaration of \c d.
7630-
AST_MATCHER_P(ElaboratedType, hasQualifier,
7631-
internal::Matcher<NestedNameSpecifier>, InnerMatcher) {
7632-
if (const NestedNameSpecifier *Qualifier = Node.getQualifier())
7633-
return InnerMatcher.matches(*Qualifier, Finder, Builder);
7601+
AST_MATCHER_P(Type, hasQualifier, internal::Matcher<NestedNameSpecifier>,
7602+
InnerMatcher) {
7603+
if (NestedNameSpecifier Qualifier = Node.getPrefix())
7604+
return InnerMatcher.matches(Qualifier, Finder, Builder);
76347605

76357606
return false;
76367607
}
76377608

7638-
/// Matches ElaboratedTypes whose named type matches \c InnerMatcher.
7639-
///
7640-
/// Given
7641-
/// \code
7642-
/// namespace N {
7643-
/// namespace M {
7644-
/// class D {};
7645-
/// }
7646-
/// }
7647-
/// N::M::D d;
7648-
/// \endcode
7649-
///
7650-
/// \c elaboratedType(namesType(recordType(
7651-
/// hasDeclaration(namedDecl(hasName("D")))))) matches the type of the variable
7652-
/// declaration of \c d.
7653-
AST_MATCHER_P(ElaboratedType, namesType, internal::Matcher<QualType>,
7654-
InnerMatcher) {
7655-
return InnerMatcher.matches(Node.getNamedType(), Finder, Builder);
7656-
}
7657-
76587609
/// Matches types specified through a using declaration.
76597610
///
76607611
/// Given
@@ -7823,7 +7774,7 @@ AST_MATCHER_FUNCTION_P_OVERLOAD(
78237774
/// matches "A::"
78247775
AST_MATCHER_P(NestedNameSpecifier, specifiesType,
78257776
internal::Matcher<QualType>, InnerMatcher) {
7826-
if (!Node.getAsType())
7777+
if (Node.getKind() != NestedNameSpecifier::Kind::Type)
78277778
return false;
78287779
return InnerMatcher.matches(QualType(Node.getAsType(), 0), Finder, Builder);
78297780
}
@@ -7841,8 +7792,12 @@ AST_MATCHER_P(NestedNameSpecifier, specifiesType,
78417792
/// matches "A::"
78427793
AST_MATCHER_P(NestedNameSpecifierLoc, specifiesTypeLoc,
78437794
internal::Matcher<TypeLoc>, InnerMatcher) {
7844-
return Node && Node.getNestedNameSpecifier()->getAsType() &&
7845-
InnerMatcher.matches(Node.getTypeLoc(), Finder, Builder);
7795+
if (!Node)
7796+
return false;
7797+
TypeLoc TL = Node.getAsTypeLoc();
7798+
if (!TL)
7799+
return false;
7800+
return InnerMatcher.matches(TL, Finder, Builder);
78467801
}
78477802

78487803
/// Matches on the prefix of a \c NestedNameSpecifier.
@@ -7857,10 +7812,21 @@ AST_MATCHER_P(NestedNameSpecifierLoc, specifiesTypeLoc,
78577812
AST_MATCHER_P_OVERLOAD(NestedNameSpecifier, hasPrefix,
78587813
internal::Matcher<NestedNameSpecifier>, InnerMatcher,
78597814
0) {
7860-
const NestedNameSpecifier *NextNode = Node.getPrefix();
7815+
NestedNameSpecifier NextNode = std::nullopt;
7816+
switch (Node.getKind()) {
7817+
case NestedNameSpecifier::Kind::Namespace:
7818+
NextNode = Node.getAsNamespaceAndPrefix().Prefix;
7819+
break;
7820+
case NestedNameSpecifier::Kind::Type:
7821+
NextNode = Node.getAsType()->getPrefix();
7822+
break;
7823+
default:
7824+
break;
7825+
}
7826+
78617827
if (!NextNode)
78627828
return false;
7863-
return InnerMatcher.matches(*NextNode, Finder, Builder);
7829+
return InnerMatcher.matches(NextNode, Finder, Builder);
78647830
}
78657831

78667832
/// Matches on the prefix of a \c NestedNameSpecifierLoc.
@@ -7875,7 +7841,12 @@ AST_MATCHER_P_OVERLOAD(NestedNameSpecifier, hasPrefix,
78757841
AST_MATCHER_P_OVERLOAD(NestedNameSpecifierLoc, hasPrefix,
78767842
internal::Matcher<NestedNameSpecifierLoc>, InnerMatcher,
78777843
1) {
7878-
NestedNameSpecifierLoc NextNode = Node.getPrefix();
7844+
NestedNameSpecifierLoc NextNode;
7845+
if (TypeLoc TL = Node.getAsTypeLoc())
7846+
NextNode = TL.getPrefix();
7847+
else
7848+
NextNode = Node.getAsNamespaceAndPrefix().Prefix;
7849+
78797850
if (!NextNode)
78807851
return false;
78817852
return InnerMatcher.matches(NextNode, Finder, Builder);
@@ -7893,9 +7864,13 @@ AST_MATCHER_P_OVERLOAD(NestedNameSpecifierLoc, hasPrefix,
78937864
/// matches "ns::"
78947865
AST_MATCHER_P(NestedNameSpecifier, specifiesNamespace,
78957866
internal::Matcher<NamespaceDecl>, InnerMatcher) {
7896-
if (!Node.getAsNamespace())
7867+
if (Node.getKind() != NestedNameSpecifier::Kind::Namespace)
7868+
return false;
7869+
const auto *Namespace =
7870+
dyn_cast<NamespaceDecl>(Node.getAsNamespaceAndPrefix().Namespace);
7871+
if (!Namespace)
78977872
return false;
7898-
return InnerMatcher.matches(*Node.getAsNamespace(), Finder, Builder);
7873+
return InnerMatcher.matches(*Namespace, Finder, Builder);
78997874
}
79007875

79017876
/// 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)