Skip to content

Commit 7ad6252

Browse files
committed
[PATCH 2/4] [clang] Improve nested name specifier AST representation
Other changes
1 parent 4896f42 commit 7ad6252

File tree

171 files changed

+3662
-3352
lines changed

Some content is hidden

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

171 files changed

+3662
-3352
lines changed

clang/include/clang/ASTMatchers/ASTMatchers.h

Lines changed: 67 additions & 92 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
@@ -3740,7 +3753,7 @@ extern const internal::VariadicOperatorMatcherFunc<1, 1> unless;
37403753
/// Matcher<MemberExpr>, Matcher<QualType>, Matcher<RecordType>,
37413754
/// Matcher<TagType>, Matcher<TemplateSpecializationType>,
37423755
/// Matcher<TemplateTypeParmType>, Matcher<TypedefType>,
3743-
/// Matcher<UnresolvedUsingType>
3756+
/// Matcher<UnresolvedUsingType>, Matcher<UsingType>
37443757
inline internal::PolymorphicMatcher<
37453758
internal::HasDeclarationMatcher,
37463759
void(internal::HasDeclarationSupportedTypes), internal::Matcher<Decl>>
@@ -4375,7 +4388,13 @@ AST_POLYMORPHIC_MATCHER_P(throughUsingDecl,
43754388
AST_POLYMORPHIC_SUPPORTED_TYPES(DeclRefExpr,
43764389
UsingType),
43774390
internal::Matcher<UsingShadowDecl>, Inner) {
4378-
const NamedDecl *FoundDecl = Node.getFoundDecl();
4391+
const NamedDecl *FoundDecl;
4392+
if constexpr (std::is_same_v<NodeType, UsingType>) {
4393+
FoundDecl = Node.getDecl();
4394+
} else {
4395+
static_assert(std::is_same_v<NodeType, DeclRefExpr>);
4396+
FoundDecl = Node.getFoundDecl();
4397+
}
43794398
if (const UsingShadowDecl *UsingDecl = dyn_cast<UsingShadowDecl>(FoundDecl))
43804399
return Inner.matches(*UsingDecl, Finder, Builder);
43814400
return false;
@@ -7004,37 +7023,6 @@ AST_POLYMORPHIC_MATCHER_P2(
70047023
InnerMatcher.matches(Args[Index], Finder, Builder);
70057024
}
70067025

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

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

73197310
/// Matches \c FunctionType nodes.
73207311
///
@@ -7593,27 +7584,7 @@ extern const AstTypeMatcher<RecordType> recordType;
75937584
/// and \c c.
75947585
extern const AstTypeMatcher<TagType> tagType;
75957586

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

76367607
return false;
76377608
}
76387609

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

78497804
/// Matches on the prefix of a \c NestedNameSpecifier.
@@ -7858,10 +7813,21 @@ AST_MATCHER_P(NestedNameSpecifierLoc, specifiesTypeLoc,
78587813
AST_MATCHER_P_OVERLOAD(NestedNameSpecifier, hasPrefix,
78597814
internal::Matcher<NestedNameSpecifier>, InnerMatcher,
78607815
0) {
7861-
const NestedNameSpecifier *NextNode = Node.getPrefix();
7816+
NestedNameSpecifier NextNode = std::nullopt;
7817+
switch (Node.getKind()) {
7818+
case NestedNameSpecifier::Kind::Namespace:
7819+
NextNode = Node.getAsNamespaceAndPrefix().Prefix;
7820+
break;
7821+
case NestedNameSpecifier::Kind::Type:
7822+
NextNode = Node.getAsType()->getPrefix();
7823+
break;
7824+
default:
7825+
break;
7826+
}
7827+
78627828
if (!NextNode)
78637829
return false;
7864-
return InnerMatcher.matches(*NextNode, Finder, Builder);
7830+
return InnerMatcher.matches(NextNode, Finder, Builder);
78657831
}
78667832

78677833
/// Matches on the prefix of a \c NestedNameSpecifierLoc.
@@ -7876,7 +7842,12 @@ AST_MATCHER_P_OVERLOAD(NestedNameSpecifier, hasPrefix,
78767842
AST_MATCHER_P_OVERLOAD(NestedNameSpecifierLoc, hasPrefix,
78777843
internal::Matcher<NestedNameSpecifierLoc>, InnerMatcher,
78787844
1) {
7879-
NestedNameSpecifierLoc NextNode = Node.getPrefix();
7845+
NestedNameSpecifierLoc NextNode;
7846+
if (TypeLoc TL = Node.getAsTypeLoc())
7847+
NextNode = TL.getPrefix();
7848+
else
7849+
NextNode = Node.getAsNamespaceAndPrefix().Prefix;
7850+
78807851
if (!NextNode)
78817852
return false;
78827853
return InnerMatcher.matches(NextNode, Finder, Builder);
@@ -7894,9 +7865,13 @@ AST_MATCHER_P_OVERLOAD(NestedNameSpecifierLoc, hasPrefix,
78947865
/// matches "ns::"
78957866
AST_MATCHER_P(NestedNameSpecifier, specifiesNamespace,
78967867
internal::Matcher<NamespaceDecl>, InnerMatcher) {
7897-
if (auto *NS = dyn_cast_if_present<NamespaceDecl>(Node.getAsNamespace()))
7898-
return InnerMatcher.matches(*NS, Finder, Builder);
7899-
return false;
7868+
if (Node.getKind() != NestedNameSpecifier::Kind::Namespace)
7869+
return false;
7870+
const auto *Namespace =
7871+
dyn_cast<NamespaceDecl>(Node.getAsNamespaceAndPrefix().Namespace);
7872+
if (!Namespace)
7873+
return false;
7874+
return InnerMatcher.matches(*Namespace, Finder, Builder);
79007875
}
79017876

79027877
/// Matches attributes.

clang/include/clang/ASTMatchers/ASTMatchersInternal.h

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1017,10 +1017,7 @@ class HasDeclarationMatcher : public MatcherInterface<T> {
10171017
// First, for any types that have a declaration, extract the declaration and
10181018
// match on it.
10191019
if (const auto *S = dyn_cast<TagType>(&Node)) {
1020-
return matchesDecl(S->getDecl(), Finder, Builder);
1021-
}
1022-
if (const auto *S = dyn_cast<InjectedClassNameType>(&Node)) {
1023-
return matchesDecl(S->getDecl(), Finder, Builder);
1020+
return matchesDecl(S->getOriginalDecl(), Finder, Builder);
10241021
}
10251022
if (const auto *S = dyn_cast<TemplateTypeParmType>(&Node)) {
10261023
return matchesDecl(S->getDecl(), Finder, Builder);
@@ -1031,6 +1028,9 @@ class HasDeclarationMatcher : public MatcherInterface<T> {
10311028
if (const auto *S = dyn_cast<UnresolvedUsingType>(&Node)) {
10321029
return matchesDecl(S->getDecl(), Finder, Builder);
10331030
}
1031+
if (const auto *S = dyn_cast<UsingType>(&Node)) {
1032+
return matchesDecl(S->getDecl(), Finder, Builder);
1033+
}
10341034
if (const auto *S = dyn_cast<ObjCObjectType>(&Node)) {
10351035
return matchesDecl(S->getInterface(), Finder, Builder);
10361036
}
@@ -1066,12 +1066,6 @@ class HasDeclarationMatcher : public MatcherInterface<T> {
10661066
Builder);
10671067
}
10681068

1069-
// FIXME: We desugar elaborated types. This makes the assumption that users
1070-
// do never want to match on whether a type is elaborated - there are
1071-
// arguments for both sides; for now, continue desugaring.
1072-
if (const auto *S = dyn_cast<ElaboratedType>(&Node)) {
1073-
return matchesSpecialized(S->desugar(), Finder, Builder);
1074-
}
10751069
// Similarly types found via using declarations.
10761070
// These are *usually* meaningless sugar, and this matches the historical
10771071
// behavior prior to the introduction of UsingType.
@@ -1211,8 +1205,8 @@ using AdaptativeDefaultToTypes =
12111205
/// All types that are supported by HasDeclarationMatcher above.
12121206
using HasDeclarationSupportedTypes =
12131207
TypeList<CallExpr, CXXConstructExpr, CXXNewExpr, DeclRefExpr, EnumType,
1214-
ElaboratedType, InjectedClassNameType, LabelStmt, AddrLabelExpr,
1215-
MemberExpr, QualType, RecordType, TagType,
1208+
InjectedClassNameType, LabelStmt, AddrLabelExpr, MemberExpr,
1209+
QualType, RecordType, TagType, UsingType,
12161210
TemplateSpecializationType, TemplateTypeParmType, TypedefType,
12171211
UnresolvedUsingType, ObjCIvarRefExpr, ObjCInterfaceDecl>;
12181212

@@ -1789,7 +1783,7 @@ class LocMatcher : public MatcherInterface<TLoc> {
17891783

17901784
private:
17911785
static DynTypedNode extract(const NestedNameSpecifierLoc &Loc) {
1792-
return DynTypedNode::create(*Loc.getNestedNameSpecifier());
1786+
return DynTypedNode::create(Loc.getNestedNameSpecifier());
17931787
}
17941788
};
17951789

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);

clang/include/clang/Basic/TypeNodes.td

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ def UnaryTransformType : TypeNode<Type>, NeverCanonicalUnlessDependent;
9090
def TagType : TypeNode<Type, 1>;
9191
def RecordType : TypeNode<TagType>, LeafType;
9292
def EnumType : TypeNode<TagType>, LeafType;
93-
def ElaboratedType : TypeNode<Type>, NeverCanonical;
93+
def InjectedClassNameType : TypeNode<TagType>, AlwaysDependent, LeafType;
9494
def AttributedType : TypeNode<Type>, NeverCanonical;
9595
def BTFTagAttributedType : TypeNode<Type>, NeverCanonical;
9696
def HLSLAttributedResourceType : TypeNode<Type>;
@@ -102,7 +102,6 @@ def TemplateSpecializationType : TypeNode<Type>, NeverCanonicalUnlessDependent;
102102
def DeducedType : TypeNode<Type, 1>;
103103
def AutoType : TypeNode<DeducedType>;
104104
def DeducedTemplateSpecializationType : TypeNode<DeducedType>;
105-
def InjectedClassNameType : TypeNode<Type>, AlwaysDependent, LeafType;
106105
def DependentNameType : TypeNode<Type>, AlwaysDependent;
107106
def DependentTemplateSpecializationType : TypeNode<Type>, AlwaysDependent;
108107
def PackExpansionType : TypeNode<Type>, AlwaysDependent;

clang/include/clang/ExtractAPI/DeclarationFragments.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -440,9 +440,8 @@ class DeclarationFragmentsBuilder {
440440
DeclarationFragments &);
441441

442442
/// Build DeclarationFragments for a NestedNameSpecifier.
443-
static DeclarationFragments getFragmentsForNNS(const NestedNameSpecifier *,
444-
ASTContext &,
445-
DeclarationFragments &);
443+
static DeclarationFragments
444+
getFragmentsForNNS(NestedNameSpecifier, ASTContext &, DeclarationFragments &);
446445

447446
/// Build DeclarationFragments for Qualifiers.
448447
static DeclarationFragments getFragmentsForQualifiers(const Qualifiers quals);

clang/include/clang/Sema/CodeCompleteConsumer.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,8 @@ SimplifiedTypeClass getSimplifiedTypeClass(CanQualType T);
162162

163163
/// Determine the type that this declaration will have if it is used
164164
/// as a type or in an expression.
165-
QualType getDeclUsageType(ASTContext &C, const NamedDecl *ND);
165+
QualType getDeclUsageType(ASTContext &C, NestedNameSpecifier Qualifier,
166+
const NamedDecl *ND);
166167

167168
/// Determine the priority to be given to a macro code completion result
168169
/// with the given name.
@@ -867,7 +868,7 @@ class CodeCompletionResult {
867868
/// If the result should have a nested-name-specifier, this is it.
868869
/// When \c QualifierIsInformative, the nested-name-specifier is
869870
/// informative rather than required.
870-
NestedNameSpecifier *Qualifier = nullptr;
871+
NestedNameSpecifier Qualifier = std::nullopt;
871872

872873
/// If this Decl was unshadowed by using declaration, this can store a
873874
/// pointer to the UsingShadowDecl which was used in the unshadowing process.
@@ -882,7 +883,7 @@ class CodeCompletionResult {
882883

883884
/// Build a result that refers to a declaration.
884885
CodeCompletionResult(const NamedDecl *Declaration, unsigned Priority,
885-
NestedNameSpecifier *Qualifier = nullptr,
886+
NestedNameSpecifier Qualifier = std::nullopt,
886887
bool QualifierIsInformative = false,
887888
bool Accessible = true,
888889
std::vector<FixItHint> FixIts = std::vector<FixItHint>())

0 commit comments

Comments
 (0)