steveire created this revision.
steveire added a reviewer: njames93.
Herald added a subscriber: mgrang.
steveire requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D101049
Files:
clang/include/clang/Tooling/NodeIntrospection.h
clang/lib/Tooling/DumpTool/APIData.h
clang/lib/Tooling/DumpTool/ASTSrcLocProcessor.cpp
clang/lib/Tooling/DumpTool/generate_cxx_src_locs.py
clang/lib/Tooling/EmptyNodeIntrospection.inc.in
clang/unittests/Introspection/IntrospectionTest.cpp
Index: clang/unittests/Introspection/IntrospectionTest.cpp
===================================================================
--- clang/unittests/Introspection/IntrospectionTest.cpp
+++ clang/unittests/Introspection/IntrospectionTest.cpp
@@ -216,6 +216,9 @@
STRING_LOCATION_STDPAIR(MethodDecl, getEndLoc()),
STRING_LOCATION_STDPAIR(MethodDecl, getInnerLocStart()),
STRING_LOCATION_STDPAIR(MethodDecl, getLocation()),
+STRING_LOCATION_STDPAIR(MethodDecl, getNameInfo().getBeginLoc()),
+STRING_LOCATION_STDPAIR(MethodDecl, getNameInfo().getEndLoc()),
+STRING_LOCATION_STDPAIR(MethodDecl, getNameInfo().getLoc()),
STRING_LOCATION_STDPAIR(MethodDecl, getOuterLocStart()),
STRING_LOCATION_STDPAIR(MethodDecl, getQualifierLoc().getBeginLoc()),
STRING_LOCATION_STDPAIR(MethodDecl, getQualifierLoc().getEndLoc()),
@@ -305,6 +308,7 @@
llvm::makeArrayRef(ExpectedRanges),
(ArrayRef<std::pair<std::string, SourceRange>>{
STRING_LOCATION_STDPAIR(MethodDecl, getExceptionSpecSourceRange()),
+STRING_LOCATION_STDPAIR(MethodDecl, getNameInfo().getSourceRange()),
STRING_LOCATION_STDPAIR(MethodDecl, getParametersSourceRange()),
STRING_LOCATION_STDPAIR(MethodDecl, getQualifierLoc().getLocalSourceRange()),
STRING_LOCATION_STDPAIR(MethodDecl, getQualifierLoc().getPrefix().getLocalSourceRange()),
@@ -1401,3 +1405,148 @@
TL, getAs<clang::TypeOfExprTypeLoc>().getParensRange())));
}
#endif
+
+TEST(Introspection, SourceLocations_DeclarationNameInfo_Dtor) {
+ auto AST =
+ buildASTFromCode(R"cpp(
+class Foo
+{
+ ~Foo() {}
+};
+)cpp",
+ "foo.cpp", std::make_shared<PCHContainerOperations>());
+ auto &Ctx = AST->getASTContext();
+ auto &TU = *Ctx.getTranslationUnitDecl();
+
+ auto BoundNodes = ast_matchers::match(
+ decl(hasDescendant(cxxDestructorDecl(hasName("~Foo")).bind("dtor"))), TU,
+ Ctx);
+
+ EXPECT_EQ(BoundNodes.size(), 1u);
+
+ const auto *Dtor = BoundNodes[0].getNodeAs<CXXDestructorDecl>("dtor");
+ auto NI = Dtor->getNameInfo();
+ auto Result = NodeIntrospection::GetLocations(NI);
+
+ if (Result.LocationAccessors.empty() && Result.RangeAccessors.empty()) {
+ return;
+ }
+
+ auto ExpectedLocations =
+ FormatExpected<SourceLocation>(Result.LocationAccessors);
+
+ llvm::sort(ExpectedLocations);
+
+ EXPECT_EQ(
+ llvm::makeArrayRef(ExpectedLocations),
+ (ArrayRef<std::pair<std::string, SourceLocation>>{
+ STRING_LOCATION_STDPAIR((&NI), getBeginLoc()),
+ STRING_LOCATION_STDPAIR((&NI), getEndLoc()),
+ STRING_LOCATION_STDPAIR((&NI), getLoc()),
+ STRING_LOCATION_STDPAIR((&NI), getNamedTypeInfo()
+ ->getTypeLoc()
+ .getAs<clang::TypeSpecTypeLoc>()
+ .getNameLoc()),
+ STRING_LOCATION_STDPAIR(
+ (&NI), getNamedTypeInfo()->getTypeLoc().getBeginLoc()),
+ STRING_LOCATION_STDPAIR(
+ (&NI), getNamedTypeInfo()->getTypeLoc().getEndLoc())}));
+
+ auto ExpectedRanges = FormatExpected<SourceRange>(Result.RangeAccessors);
+
+ EXPECT_THAT(
+ ExpectedRanges,
+ UnorderedElementsAre(
+ STRING_LOCATION_PAIR(
+ (&NI), getNamedTypeInfo()->getTypeLoc().getLocalSourceRange()),
+ STRING_LOCATION_PAIR(
+ (&NI), getNamedTypeInfo()->getTypeLoc().getSourceRange()),
+ STRING_LOCATION_PAIR((&NI), getSourceRange())));
+}
+
+TEST(Introspection, SourceLocations_DeclarationNameInfo_ConvOp) {
+ auto AST =
+ buildASTFromCode(R"cpp(
+class Foo
+{
+ bool operator==(const Foo&) const { return false; }
+};
+)cpp",
+ "foo.cpp", std::make_shared<PCHContainerOperations>());
+ auto &Ctx = AST->getASTContext();
+ auto &TU = *Ctx.getTranslationUnitDecl();
+
+ auto BoundNodes = ast_matchers::match(
+ decl(hasDescendant(cxxMethodDecl().bind("opeq"))), TU, Ctx);
+
+ EXPECT_EQ(BoundNodes.size(), 1u);
+
+ const auto *Opeq = BoundNodes[0].getNodeAs<CXXMethodDecl>("opeq");
+ auto NI = Opeq->getNameInfo();
+ auto Result = NodeIntrospection::GetLocations(NI);
+
+ if (Result.LocationAccessors.empty() && Result.RangeAccessors.empty()) {
+ return;
+ }
+
+ auto ExpectedLocations =
+ FormatExpected<SourceLocation>(Result.LocationAccessors);
+
+ llvm::sort(ExpectedLocations);
+
+ EXPECT_EQ(llvm::makeArrayRef(ExpectedLocations),
+ (ArrayRef<std::pair<std::string, SourceLocation>>{
+ STRING_LOCATION_STDPAIR((&NI), getBeginLoc()),
+ STRING_LOCATION_STDPAIR((&NI), getEndLoc()),
+ STRING_LOCATION_STDPAIR((&NI), getLoc())}));
+
+ auto ExpectedRanges = FormatExpected<SourceRange>(Result.RangeAccessors);
+
+ EXPECT_THAT(ExpectedRanges,
+ UnorderedElementsAre(
+ STRING_LOCATION_PAIR((&NI), getSourceRange()),
+ STRING_LOCATION_PAIR((&NI), getCXXOperatorNameRange())));
+}
+
+TEST(Introspection, SourceLocations_DeclarationNameInfo_LitOp) {
+ auto AST =
+ buildASTFromCode(R"cpp(
+long double operator"" _identity ( long double val )
+{
+ return val;
+}
+)cpp",
+ "foo.cpp", std::make_shared<PCHContainerOperations>());
+ auto &Ctx = AST->getASTContext();
+ auto &TU = *Ctx.getTranslationUnitDecl();
+
+ auto BoundNodes = ast_matchers::match(
+ decl(hasDescendant(functionDecl().bind("litop"))), TU, Ctx);
+
+ EXPECT_EQ(BoundNodes.size(), 1u);
+
+ const auto *LitOp = BoundNodes[0].getNodeAs<FunctionDecl>("litop");
+ auto NI = LitOp->getNameInfo();
+ auto Result = NodeIntrospection::GetLocations(NI);
+
+ if (Result.LocationAccessors.empty() && Result.RangeAccessors.empty()) {
+ return;
+ }
+
+ auto ExpectedLocations =
+ FormatExpected<SourceLocation>(Result.LocationAccessors);
+
+ llvm::sort(ExpectedLocations);
+
+ EXPECT_EQ(llvm::makeArrayRef(ExpectedLocations),
+ (ArrayRef<std::pair<std::string, SourceLocation>>{
+ STRING_LOCATION_STDPAIR((&NI), getBeginLoc()),
+ STRING_LOCATION_STDPAIR((&NI), getCXXLiteralOperatorNameLoc()),
+ STRING_LOCATION_STDPAIR((&NI), getEndLoc()),
+ STRING_LOCATION_STDPAIR((&NI), getLoc())}));
+
+ auto ExpectedRanges = FormatExpected<SourceRange>(Result.RangeAccessors);
+
+ EXPECT_THAT(ExpectedRanges, UnorderedElementsAre(STRING_LOCATION_PAIR(
+ (&NI), getSourceRange())));
+}
Index: clang/lib/Tooling/EmptyNodeIntrospection.inc.in
===================================================================
--- clang/lib/Tooling/EmptyNodeIntrospection.inc.in
+++ clang/lib/Tooling/EmptyNodeIntrospection.inc.in
@@ -36,6 +36,10 @@
clang::TypeLoc const&) {
return {};
}
+NodeLocationAccessors NodeIntrospection::GetLocations(
+ clang::DeclarationNameInfo const&) {
+ return {};
+}
NodeLocationAccessors
NodeIntrospection::GetLocations(clang::DynTypedNode const &) {
return {};
Index: clang/lib/Tooling/DumpTool/generate_cxx_src_locs.py
===================================================================
--- clang/lib/Tooling/DumpTool/generate_cxx_src_locs.py
+++ clang/lib/Tooling/DumpTool/generate_cxx_src_locs.py
@@ -12,7 +12,10 @@
implementationContent = ''
- RefClades = {"NestedNameSpecifierLoc", "TemplateArgumentLoc", "TypeLoc"}
+ RefClades = {"DeclarationNameInfo",
+ "NestedNameSpecifierLoc",
+ "TemplateArgumentLoc",
+ "TypeLoc"}
def __init__(self, templateClasses):
self.templateClasses = templateClasses
@@ -121,7 +124,8 @@
self.implementationContent += '\n'
if 'typeLocs' in ClassData or 'typeSourceInfos' in ClassData \
- or 'nestedNameLocs' in ClassData:
+ or 'nestedNameLocs' in ClassData \
+ or 'declNameInfos' in ClassData:
if CreateLocalRecursionGuard:
self.implementationContent += \
'std::vector<clang::TypeLoc> TypeLocRecursionGuard;\n'
@@ -165,6 +169,15 @@
Object.{0}(), Locs, Rngs, TypeLocRecursionGuard);
""".format(NN)
+ if 'declNameInfos' in ClassData:
+ for declName in ClassData['declNameInfos']:
+
+ self.implementationContent += \
+ """
+ GetLocationsImpl(
+ llvm::makeIntrusiveRefCnt<LocationCall>(Prefix, "{0}"),
+ Object.{0}(), Locs, Rngs, TypeLocRecursionGuard);
+ """.format(declName)
self.implementationContent += '}\n'
@@ -300,6 +313,8 @@
+ ' NodeIntrospection::' + Signature + '{'
for CladeName in CladeNames:
+ if CladeName == "DeclarationNameInfo":
+ continue
self.implementationContent += \
"""
if (const auto *N = Node.get<{0}>())
@@ -378,6 +393,7 @@
ClassName, ClassAccessors,
cladeName not in [
'NestedNameSpecifierLoc',
+ 'DeclarationNameInfo',
'TemplateArgumentLoc',
'TypeLoc'])
@@ -389,6 +405,7 @@
jsonData["classInheritance"],
CladeName not in [
'NestedNameSpecifierLoc',
+ 'DeclarationNameInfo',
'TemplateArgumentLoc',
'TypeLoc'])
Index: clang/lib/Tooling/DumpTool/ASTSrcLocProcessor.cpp
===================================================================
--- clang/lib/Tooling/DumpTool/ASTSrcLocProcessor.cpp
+++ clang/lib/Tooling/DumpTool/ASTSrcLocProcessor.cpp
@@ -23,19 +23,19 @@
Finder = std::make_unique<MatchFinder>(std::move(FinderOptions));
Finder->addMatcher(
- cxxRecordDecl(
- isDefinition(),
- isSameOrDerivedFrom(
- // TODO: Extend this with other clades
- namedDecl(hasAnyName("clang::Stmt", "clang::Decl",
- "clang::CXXCtorInitializer",
- "clang::NestedNameSpecifierLoc",
- "clang::TemplateArgumentLoc",
- "clang::CXXBaseSpecifier",
- "clang::TypeLoc"))
- .bind("nodeClade")),
- optionally(isDerivedFrom(cxxRecordDecl().bind("derivedFrom"))))
- .bind("className"),
+ cxxRecordDecl(
+ isDefinition(),
+ isSameOrDerivedFrom(
+ // TODO: Extend this with other clades
+ namedDecl(
+ hasAnyName(
+ "clang::Stmt", "clang::Decl", "clang::CXXCtorInitializer",
+ "clang::NestedNameSpecifierLoc",
+ "clang::TemplateArgumentLoc", "clang::CXXBaseSpecifier",
+ "clang::DeclarationNameInfo", "clang::TypeLoc"))
+ .bind("nodeClade")),
+ optionally(isDerivedFrom(cxxRecordDecl().bind("derivedFrom"))))
+ .bind("className"),
this);
Finder->addMatcher(
cxxRecordDecl(isDefinition(), hasAnyName("clang::PointerLikeTypeLoc",
@@ -85,6 +85,8 @@
JsonObj["typeLocs"] = Obj.TypeLocs;
if (!Obj.NestedNameLocs.empty())
JsonObj["nestedNameLocs"] = Obj.NestedNameLocs;
+ if (!Obj.DeclNameInfos.empty())
+ JsonObj["declNameInfos"] = Obj.DeclNameInfos;
return JsonObj;
}
@@ -222,6 +224,8 @@
CD.TypeLocs = CaptureMethods("class clang::TypeLoc", ASTClass, Result);
CD.NestedNameLocs =
CaptureMethods("class clang::NestedNameSpecifierLoc", ASTClass, Result);
+ CD.DeclNameInfos =
+ CaptureMethods("struct clang::DeclarationNameInfo", ASTClass, Result);
if (const auto *DerivedFrom =
Result.Nodes.getNodeAs<clang::CXXRecordDecl>("derivedFrom")) {
Index: clang/lib/Tooling/DumpTool/APIData.h
===================================================================
--- clang/lib/Tooling/DumpTool/APIData.h
+++ clang/lib/Tooling/DumpTool/APIData.h
@@ -22,6 +22,7 @@
std::vector<std::string> TypeSourceInfos;
std::vector<std::string> TypeLocs;
std::vector<std::string> NestedNameLocs;
+ std::vector<std::string> DeclNameInfos;
// TODO: Extend this with locations available via typelocs etc.
};
Index: clang/include/clang/Tooling/NodeIntrospection.h
===================================================================
--- clang/include/clang/Tooling/NodeIntrospection.h
+++ clang/include/clang/Tooling/NodeIntrospection.h
@@ -26,6 +26,7 @@
class NestedNameSpecifierLoc;
class TemplateArgumentLoc;
class CXXBaseSpecifier;
+class DeclarationNameInfo;
namespace tooling {
@@ -87,6 +88,7 @@
NodeLocationAccessors GetLocations(clang::TemplateArgumentLoc const &);
NodeLocationAccessors GetLocations(clang::CXXBaseSpecifier const *);
NodeLocationAccessors GetLocations(clang::TypeLoc const &);
+NodeLocationAccessors GetLocations(clang::DeclarationNameInfo const &);
NodeLocationAccessors GetLocations(clang::DynTypedNode const &Node);
} // namespace NodeIntrospection
} // namespace tooling
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits