Skip to content

Commit b37d904

Browse files
committed
[PATCH 2/6] [clang] Improve nested name specifier AST representation
Other changes
1 parent 73ffe31 commit b37d904

File tree

104 files changed

+1885
-1931
lines changed

Some content is hidden

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

104 files changed

+1885
-1931
lines changed

clang/include/clang/ASTMatchers/ASTMatchers.h

Lines changed: 34 additions & 83 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

clang/include/clang/ASTMatchers/ASTMatchersInternal.h

Lines changed: 6 additions & 12 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

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/Sema/DeclSpec.h

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -106,21 +106,7 @@ class CXXScopeSpec {
106106
/// \param TL The TypeLoc that describes the type preceding the '::'.
107107
///
108108
/// \param ColonColonLoc The location of the trailing '::'.
109-
void Extend(ASTContext &Context, TypeLoc TL, SourceLocation ColonColonLoc);
110-
111-
/// Extend the current nested-name-specifier by another
112-
/// nested-name-specifier component of the form 'identifier::'.
113-
///
114-
/// \param Context The AST context in which this nested-name-specifier
115-
/// resides.
116-
///
117-
/// \param Identifier The identifier.
118-
///
119-
/// \param IdentifierLoc The location of the identifier.
120-
///
121-
/// \param ColonColonLoc The location of the trailing '::'.
122-
void Extend(ASTContext &Context, IdentifierInfo *Identifier,
123-
SourceLocation IdentifierLoc, SourceLocation ColonColonLoc);
109+
void Make(ASTContext &Context, TypeLoc TL, SourceLocation ColonColonLoc);
124110

125111
/// Extend the current nested-name-specifier by another
126112
/// nested-name-specifier component of the form 'namespace::'.
@@ -189,14 +175,14 @@ class CXXScopeSpec {
189175
SourceLocation getLastQualifierNameLoc() const;
190176

191177
/// No scope specifier.
192-
bool isEmpty() const { return Range.isInvalid() && getScopeRep() == nullptr; }
178+
bool isEmpty() const { return Range.isInvalid() && !getScopeRep(); }
193179
/// A scope specifier is present, but may be valid or invalid.
194180
bool isNotEmpty() const { return !isEmpty(); }
195181

196182
/// An error occurred during parsing of the scope specifier.
197-
bool isInvalid() const { return Range.isValid() && getScopeRep() == nullptr; }
183+
bool isInvalid() const { return Range.isValid() && !getScopeRep(); }
198184
/// A scope specifier is present, and it refers to a real scope.
199-
bool isValid() const { return getScopeRep() != nullptr; }
185+
bool isValid() const { return bool(getScopeRep()); }
200186

201187
/// Indicate that this nested-name-specifier is invalid.
202188
void SetInvalid(SourceRange R) {
@@ -209,7 +195,7 @@ class CXXScopeSpec {
209195

210196
/// Deprecated. Some call sites intend isNotEmpty() while others intend
211197
/// isValid().
212-
bool isSet() const { return getScopeRep() != nullptr; }
198+
bool isSet() const { return bool(getScopeRep()); }
213199

214200
void clear() {
215201
Range = SourceRange();

clang/include/clang/Sema/ParsedTemplate.h

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ namespace clang {
4848
///
4949
/// \param Arg the template type argument or non-type template argument.
5050
/// \param Loc the location of the type.
51-
ParsedTemplateArgument(KindType Kind, void *Arg, SourceLocation Loc)
52-
: Kind(Kind), Arg(Arg), Loc(Loc) { }
51+
ParsedTemplateArgument(KindType Kind, void *Arg, SourceLocation NameLoc)
52+
: Kind(Kind), Arg(Arg), NameLoc(NameLoc) {}
5353

5454
/// Create a template template argument.
5555
///
@@ -60,11 +60,11 @@ namespace clang {
6060
/// argument refers.
6161
///
6262
/// \param TemplateLoc the location of the template name.
63-
ParsedTemplateArgument(const CXXScopeSpec &SS,
64-
ParsedTemplateTy Template,
65-
SourceLocation TemplateLoc)
66-
: Kind(ParsedTemplateArgument::Template),
67-
Arg(Template.getAsOpaquePtr()), SS(SS), Loc(TemplateLoc) {}
63+
ParsedTemplateArgument(SourceLocation TemplateKwLoc, const CXXScopeSpec &SS,
64+
ParsedTemplateTy Template, SourceLocation NameLoc)
65+
: Kind(ParsedTemplateArgument::Template),
66+
Arg(Template.getAsOpaquePtr()), SS(SS), TemplateKwLoc(TemplateKwLoc),
67+
NameLoc(NameLoc) {}
6868

6969
/// Determine whether the given template argument is invalid.
7070
bool isInvalid() const { return Arg == nullptr; }
@@ -91,7 +91,10 @@ namespace clang {
9191
}
9292

9393
/// Retrieve the location of the template argument.
94-
SourceLocation getLocation() const { return Loc; }
94+
SourceLocation getTemplateKwLoc() const { return TemplateKwLoc; }
95+
96+
/// Retrieve the location of the template argument.
97+
SourceLocation getNameLoc() const { return NameLoc; }
9598

9699
/// Retrieve the nested-name-specifier that precedes the template
97100
/// name in a template template argument.
@@ -128,8 +131,11 @@ namespace clang {
128131
/// argument.
129132
CXXScopeSpec SS;
130133

131-
/// the location of the template argument.
132-
SourceLocation Loc;
134+
/// the location of the template keyword.
135+
SourceLocation TemplateKwLoc;
136+
137+
/// the location of the template name.
138+
SourceLocation NameLoc;
133139

134140
/// The ellipsis location that can accompany a template template
135141
/// argument (turning it into a template template argument expansion).

0 commit comments

Comments
 (0)