steveire created this revision. steveire added a reviewer: njames93. Herald added a subscriber: mgorny. steveire requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
Replace an assert for a CXXCtorInitializer SourceLocation with a condition, as was done for other locations in commit 54272e5b (NFC: Replace asserts with if() in SourceLocation accessors, 2019-01-07). Fix the logic of detecting pseudo-virtual getBeginLoc etc on Stmt and Decl subclasses. Adjust the test infrastructure to filter out invalid source locations. This makes the tests more clear about which nodes have which locations. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D99231 Files: clang/include/clang/AST/DeclCXX.h clang/include/clang/Tooling/NodeIntrospection.h clang/lib/Tooling/CMakeLists.txt clang/lib/Tooling/DumpTool/ASTSrcLocProcessor.cpp clang/lib/Tooling/DumpTool/generate_cxx_src_locs.py clang/unittests/Introspection/IntrospectionTest.cpp
Index: clang/unittests/Introspection/IntrospectionTest.cpp =================================================================== --- clang/unittests/Introspection/IntrospectionTest.cpp +++ clang/unittests/Introspection/IntrospectionTest.cpp @@ -30,7 +30,10 @@ std::map<std::string, T> FormatExpected(const MapType &Accessors) { std::map<std::string, T> Result; - llvm::transform(Accessors, + llvm::transform(llvm::make_filter_range(Accessors, + [](const auto &Accessor) { + return Accessor.first.isValid(); + }), std::inserter(Result, Result.end()), [](const auto &Accessor) { return std::make_pair( @@ -126,11 +129,9 @@ UnorderedElementsAre( STRING_LOCATION_PAIR(MethodDecl, getBeginLoc()), STRING_LOCATION_PAIR(MethodDecl, getBodyRBrace()), - STRING_LOCATION_PAIR(MethodDecl, getEllipsisLoc()), STRING_LOCATION_PAIR(MethodDecl, getInnerLocStart()), STRING_LOCATION_PAIR(MethodDecl, getLocation()), STRING_LOCATION_PAIR(MethodDecl, getOuterLocStart()), - STRING_LOCATION_PAIR(MethodDecl, getPointOfInstantiation()), STRING_LOCATION_PAIR(MethodDecl, getTypeSpecEndLoc()), STRING_LOCATION_PAIR(MethodDecl, getTypeSpecStartLoc()), STRING_LOCATION_PAIR(MethodDecl, getEndLoc()))); @@ -145,3 +146,538 @@ STRING_LOCATION_PAIR(MethodDecl, getReturnTypeSourceRange()), STRING_LOCATION_PAIR(MethodDecl, getSourceRange()))); } + +TEST(Introspection, SourceLocations_NNS) { + auto AST = + buildASTFromCode(R"cpp( +namespace ns +{ + struct A { + void foo(); +}; +} +void ns::A::foo() {} +)cpp", + "foo.cpp", std::make_shared<PCHContainerOperations>()); + auto &Ctx = AST->getASTContext(); + auto &TU = *Ctx.getTranslationUnitDecl(); + + auto BoundNodes = ast_matchers::match( + decl(hasDescendant(nestedNameSpecifierLoc().bind("nns"))), TU, Ctx); + + EXPECT_EQ(BoundNodes.size(), 1u); + + const auto *NNS = BoundNodes[0].getNodeAs<NestedNameSpecifierLoc>("nns"); + + auto Result = NodeIntrospection::GetLocations(NNS); + + if (Result.LocationAccessors.empty() && Result.RangeAccessors.empty()) { + return; + } + + auto ExpectedLocations = + FormatExpected<SourceLocation>(Result.LocationAccessors); + + EXPECT_THAT( + ExpectedLocations, + UnorderedElementsAre(STRING_LOCATION_PAIR(NNS, getBeginLoc()), + STRING_LOCATION_PAIR(NNS, getEndLoc()), + STRING_LOCATION_PAIR(NNS, getLocalBeginLoc()), + STRING_LOCATION_PAIR(NNS, getLocalEndLoc()))); + + auto ExpectedRanges = FormatExpected<SourceRange>(Result.RangeAccessors); + + EXPECT_THAT( + ExpectedRanges, + UnorderedElementsAre(STRING_LOCATION_PAIR(NNS, getLocalSourceRange()), + STRING_LOCATION_PAIR(NNS, getSourceRange()))); +} + +TEST(Introspection, SourceLocations_TA_Type) { + auto AST = + buildASTFromCode(R"cpp( +template<typename T> + struct A { + void foo(); +}; + +void foo() +{ + A<int> a; +} +)cpp", + "foo.cpp", std::make_shared<PCHContainerOperations>()); + auto &Ctx = AST->getASTContext(); + auto &TU = *Ctx.getTranslationUnitDecl(); + + auto BoundNodes = ast_matchers::match( + decl(hasDescendant(templateArgumentLoc().bind("ta"))), TU, Ctx); + + EXPECT_EQ(BoundNodes.size(), 1u); + + const auto *TA = BoundNodes[0].getNodeAs<TemplateArgumentLoc>("ta"); + + auto Result = NodeIntrospection::GetLocations(TA); + + if (Result.LocationAccessors.empty() && Result.RangeAccessors.empty()) { + return; + } + + auto ExpectedLocations = + FormatExpected<SourceLocation>(Result.LocationAccessors); + + EXPECT_THAT(ExpectedLocations, + UnorderedElementsAre(STRING_LOCATION_PAIR(TA, getLocation()))); + + auto ExpectedRanges = FormatExpected<SourceRange>(Result.RangeAccessors); + + EXPECT_THAT(ExpectedRanges, + UnorderedElementsAre(STRING_LOCATION_PAIR(TA, getSourceRange()))); +} + +TEST(Introspection, SourceLocations_TA_Decl) { + auto AST = + buildASTFromCode(R"cpp( +template<void(*Ty)()> +void test2() {} +void doNothing() {} +void test() { + test2<doNothing>(); +} +)cpp", + "foo.cpp", std::make_shared<PCHContainerOperations>()); + auto &Ctx = AST->getASTContext(); + auto &TU = *Ctx.getTranslationUnitDecl(); + + auto BoundNodes = ast_matchers::match( + decl(hasDescendant(templateArgumentLoc().bind("ta"))), TU, Ctx); + + EXPECT_EQ(BoundNodes.size(), 1u); + + const auto *TA = BoundNodes[0].getNodeAs<TemplateArgumentLoc>("ta"); + + auto Result = NodeIntrospection::GetLocations(TA); + + if (Result.LocationAccessors.empty() && Result.RangeAccessors.empty()) { + return; + } + + auto ExpectedLocations = + FormatExpected<SourceLocation>(Result.LocationAccessors); + + EXPECT_THAT(ExpectedLocations, + UnorderedElementsAre(STRING_LOCATION_PAIR(TA, getLocation()))); + + auto ExpectedRanges = FormatExpected<SourceRange>(Result.RangeAccessors); + + EXPECT_THAT(ExpectedRanges, + UnorderedElementsAre(STRING_LOCATION_PAIR(TA, getSourceRange()))); +} + +TEST(Introspection, SourceLocations_TA_Nullptr) { + auto AST = + buildASTFromCode(R"cpp( +template<void(*Ty)()> +void test2() {} +void doNothing() {} +void test() { + test2<nullptr>(); +} +)cpp", + "foo.cpp", std::make_shared<PCHContainerOperations>()); + auto &Ctx = AST->getASTContext(); + auto &TU = *Ctx.getTranslationUnitDecl(); + + auto BoundNodes = ast_matchers::match( + decl(hasDescendant(templateArgumentLoc().bind("ta"))), TU, Ctx); + + EXPECT_EQ(BoundNodes.size(), 1u); + + const auto *TA = BoundNodes[0].getNodeAs<TemplateArgumentLoc>("ta"); + + auto Result = NodeIntrospection::GetLocations(TA); + + if (Result.LocationAccessors.empty() && Result.RangeAccessors.empty()) { + return; + } + + auto ExpectedLocations = + FormatExpected<SourceLocation>(Result.LocationAccessors); + + EXPECT_THAT(ExpectedLocations, + UnorderedElementsAre(STRING_LOCATION_PAIR(TA, getLocation()))); + + auto ExpectedRanges = FormatExpected<SourceRange>(Result.RangeAccessors); + + EXPECT_THAT(ExpectedRanges, + UnorderedElementsAre(STRING_LOCATION_PAIR(TA, getSourceRange()))); +} + +TEST(Introspection, SourceLocations_TA_Integral) { + auto AST = + buildASTFromCode(R"cpp( +template<int> +void test2() {} +void test() { + test2<42>(); +} +)cpp", + "foo.cpp", std::make_shared<PCHContainerOperations>()); + auto &Ctx = AST->getASTContext(); + auto &TU = *Ctx.getTranslationUnitDecl(); + + auto BoundNodes = ast_matchers::match( + decl(hasDescendant(templateArgumentLoc().bind("ta"))), TU, Ctx); + + EXPECT_EQ(BoundNodes.size(), 1u); + + const auto *TA = BoundNodes[0].getNodeAs<TemplateArgumentLoc>("ta"); + + auto Result = NodeIntrospection::GetLocations(TA); + + if (Result.LocationAccessors.empty() && Result.RangeAccessors.empty()) { + return; + } + + auto ExpectedLocations = + FormatExpected<SourceLocation>(Result.LocationAccessors); + + EXPECT_THAT(ExpectedLocations, + UnorderedElementsAre(STRING_LOCATION_PAIR(TA, getLocation()))); + + auto ExpectedRanges = FormatExpected<SourceRange>(Result.RangeAccessors); + + EXPECT_THAT(ExpectedRanges, + UnorderedElementsAre(STRING_LOCATION_PAIR(TA, getSourceRange()))); +} + +TEST(Introspection, SourceLocations_TA_Template) { + auto AST = + buildASTFromCode(R"cpp( +template<typename T> class A; +template <template <typename> class T> void foo(); +void bar() +{ + foo<A>(); +} +)cpp", + "foo.cpp", std::make_shared<PCHContainerOperations>()); + auto &Ctx = AST->getASTContext(); + auto &TU = *Ctx.getTranslationUnitDecl(); + + auto BoundNodes = ast_matchers::match( + decl(hasDescendant(templateArgumentLoc().bind("ta"))), TU, Ctx); + + EXPECT_EQ(BoundNodes.size(), 1u); + + const auto *TA = BoundNodes[0].getNodeAs<TemplateArgumentLoc>("ta"); + + auto Result = NodeIntrospection::GetLocations(TA); + + if (Result.LocationAccessors.empty() && Result.RangeAccessors.empty()) { + return; + } + + auto ExpectedLocations = + FormatExpected<SourceLocation>(Result.LocationAccessors); + + EXPECT_THAT( + ExpectedLocations, + UnorderedElementsAre(STRING_LOCATION_PAIR(TA, getLocation()), + STRING_LOCATION_PAIR(TA, getTemplateNameLoc()))); + + auto ExpectedRanges = FormatExpected<SourceRange>(Result.RangeAccessors); + + EXPECT_THAT(ExpectedRanges, + UnorderedElementsAre(STRING_LOCATION_PAIR(TA, getSourceRange()))); +} + +TEST(Introspection, SourceLocations_TA_TemplateExpansion) { + auto AST = + buildASTFromCode(R"cpp( +template<template<typename> class ...> class B { }; + template<template<typename> class ...T> class C { + B<T...> testTemplateExpansion; +}; +)cpp", + "foo.cpp", std::make_shared<PCHContainerOperations>()); + auto &Ctx = AST->getASTContext(); + auto &TU = *Ctx.getTranslationUnitDecl(); + + auto BoundNodes = ast_matchers::match( + decl(hasDescendant(templateArgumentLoc().bind("ta"))), TU, Ctx); + + EXPECT_EQ(BoundNodes.size(), 1u); + + const auto *TA = BoundNodes[0].getNodeAs<TemplateArgumentLoc>("ta"); + + auto Result = NodeIntrospection::GetLocations(TA); + + if (Result.LocationAccessors.empty() && Result.RangeAccessors.empty()) { + return; + } + + auto ExpectedLocations = + FormatExpected<SourceLocation>(Result.LocationAccessors); + + EXPECT_THAT( + ExpectedLocations, + UnorderedElementsAre(STRING_LOCATION_PAIR(TA, getLocation()), + STRING_LOCATION_PAIR(TA, getTemplateNameLoc()), + STRING_LOCATION_PAIR(TA, getTemplateEllipsisLoc()))); + + auto ExpectedRanges = FormatExpected<SourceRange>(Result.RangeAccessors); + + EXPECT_THAT(ExpectedRanges, + UnorderedElementsAre(STRING_LOCATION_PAIR(TA, getSourceRange()))); +} + +TEST(Introspection, SourceLocations_TA_Expression) { + auto AST = + buildASTFromCode(R"cpp( +template<int, int = 0> class testExpr; +template<int I> class testExpr<I> { }; +)cpp", + "foo.cpp", std::make_shared<PCHContainerOperations>()); + auto &Ctx = AST->getASTContext(); + auto &TU = *Ctx.getTranslationUnitDecl(); + + auto BoundNodes = ast_matchers::match( + decl(hasDescendant(templateArgumentLoc().bind("ta"))), TU, Ctx); + + EXPECT_EQ(BoundNodes.size(), 1u); + + const auto *TA = BoundNodes[0].getNodeAs<TemplateArgumentLoc>("ta"); + + auto Result = NodeIntrospection::GetLocations(TA); + + if (Result.LocationAccessors.empty() && Result.RangeAccessors.empty()) { + return; + } + + auto ExpectedLocations = + FormatExpected<SourceLocation>(Result.LocationAccessors); + + EXPECT_THAT(ExpectedLocations, + UnorderedElementsAre(STRING_LOCATION_PAIR(TA, getLocation()))); + + auto ExpectedRanges = FormatExpected<SourceRange>(Result.RangeAccessors); + + EXPECT_THAT(ExpectedRanges, + UnorderedElementsAre(STRING_LOCATION_PAIR(TA, getSourceRange()))); +} + +TEST(Introspection, SourceLocations_TA_Pack) { + auto AST = + buildASTFromCode(R"cpp( +template<typename... T> class A {}; +void foo() +{ + A<int> ai; +} +)cpp", + "foo.cpp", std::make_shared<PCHContainerOperations>()); + auto &Ctx = AST->getASTContext(); + auto &TU = *Ctx.getTranslationUnitDecl(); + + auto BoundNodes = ast_matchers::match( + decl(hasDescendant(templateArgumentLoc().bind("ta"))), TU, Ctx); + + EXPECT_EQ(BoundNodes.size(), 1u); + + const auto *TA = BoundNodes[0].getNodeAs<TemplateArgumentLoc>("ta"); + + auto Result = NodeIntrospection::GetLocations(TA); + + if (Result.LocationAccessors.empty() && Result.RangeAccessors.empty()) { + return; + } + + auto ExpectedLocations = + FormatExpected<SourceLocation>(Result.LocationAccessors); + + EXPECT_THAT(ExpectedLocations, + UnorderedElementsAre(STRING_LOCATION_PAIR(TA, getLocation()))); + + auto ExpectedRanges = FormatExpected<SourceRange>(Result.RangeAccessors); + + EXPECT_THAT(ExpectedRanges, + UnorderedElementsAre(STRING_LOCATION_PAIR(TA, getSourceRange()))); +} + +TEST(Introspection, SourceLocations_CXXCtorInitializer_base) { + auto AST = + buildASTFromCode(R"cpp( +struct A { +}; + +struct B : A { + B() : A() {} +}; +)cpp", + "foo.cpp", std::make_shared<PCHContainerOperations>()); + auto &Ctx = AST->getASTContext(); + auto &TU = *Ctx.getTranslationUnitDecl(); + + auto BoundNodes = ast_matchers::match( + decl(hasDescendant(cxxConstructorDecl( + hasAnyConstructorInitializer(cxxCtorInitializer().bind("init"))))), + TU, Ctx); + + EXPECT_EQ(BoundNodes.size(), 1u); + + const auto *CtorInit = BoundNodes[0].getNodeAs<CXXCtorInitializer>("init"); + + auto Result = NodeIntrospection::GetLocations(CtorInit); + + if (Result.LocationAccessors.empty() && Result.RangeAccessors.empty()) { + return; + } + + auto ExpectedLocations = + FormatExpected<SourceLocation>(Result.LocationAccessors); + + EXPECT_THAT(ExpectedLocations, + UnorderedElementsAre( + STRING_LOCATION_PAIR(CtorInit, getLParenLoc()), + STRING_LOCATION_PAIR(CtorInit, getRParenLoc()), + STRING_LOCATION_PAIR(CtorInit, getSourceLocation()))); + + auto ExpectedRanges = FormatExpected<SourceRange>(Result.RangeAccessors); + + EXPECT_THAT(ExpectedRanges, UnorderedElementsAre(STRING_LOCATION_PAIR( + CtorInit, getSourceRange()))); +} + +TEST(Introspection, SourceLocations_CXXCtorInitializer_member) { + auto AST = + buildASTFromCode(R"cpp( +struct A { + int m_i; + A() : m_i(42) {} +}; +)cpp", + "foo.cpp", std::make_shared<PCHContainerOperations>()); + auto &Ctx = AST->getASTContext(); + auto &TU = *Ctx.getTranslationUnitDecl(); + + auto BoundNodes = ast_matchers::match( + decl(hasDescendant(cxxConstructorDecl( + hasAnyConstructorInitializer(cxxCtorInitializer().bind("init"))))), + TU, Ctx); + + EXPECT_EQ(BoundNodes.size(), 1u); + + const auto *CtorInit = BoundNodes[0].getNodeAs<CXXCtorInitializer>("init"); + + auto Result = NodeIntrospection::GetLocations(CtorInit); + + if (Result.LocationAccessors.empty() && Result.RangeAccessors.empty()) { + return; + } + + auto ExpectedLocations = + FormatExpected<SourceLocation>(Result.LocationAccessors); + + EXPECT_THAT(ExpectedLocations, + UnorderedElementsAre( + STRING_LOCATION_PAIR(CtorInit, getLParenLoc()), + STRING_LOCATION_PAIR(CtorInit, getMemberLocation()), + STRING_LOCATION_PAIR(CtorInit, getRParenLoc()), + STRING_LOCATION_PAIR(CtorInit, getSourceLocation()))); + + auto ExpectedRanges = FormatExpected<SourceRange>(Result.RangeAccessors); + + EXPECT_THAT(ExpectedRanges, UnorderedElementsAre(STRING_LOCATION_PAIR( + CtorInit, getSourceRange()))); +} + +TEST(Introspection, SourceLocations_CXXCtorInitializer_ctor) { + auto AST = + buildASTFromCode(R"cpp( +struct C { + C() : C(42) {} + C(int) {} +}; +)cpp", + "foo.cpp", std::make_shared<PCHContainerOperations>()); + auto &Ctx = AST->getASTContext(); + auto &TU = *Ctx.getTranslationUnitDecl(); + + auto BoundNodes = ast_matchers::match( + decl(hasDescendant(cxxConstructorDecl( + hasAnyConstructorInitializer(cxxCtorInitializer().bind("init"))))), + TU, Ctx); + + EXPECT_EQ(BoundNodes.size(), 1u); + + const auto *CtorInit = BoundNodes[0].getNodeAs<CXXCtorInitializer>("init"); + + auto Result = NodeIntrospection::GetLocations(CtorInit); + + if (Result.LocationAccessors.empty() && Result.RangeAccessors.empty()) { + return; + } + + auto ExpectedLocations = + FormatExpected<SourceLocation>(Result.LocationAccessors); + + EXPECT_THAT(ExpectedLocations, + UnorderedElementsAre( + STRING_LOCATION_PAIR(CtorInit, getLParenLoc()), + STRING_LOCATION_PAIR(CtorInit, getRParenLoc()), + STRING_LOCATION_PAIR(CtorInit, getSourceLocation()))); + + auto ExpectedRanges = FormatExpected<SourceRange>(Result.RangeAccessors); + + EXPECT_THAT(ExpectedRanges, UnorderedElementsAre(STRING_LOCATION_PAIR( + CtorInit, getSourceRange()))); +} + +TEST(Introspection, SourceLocations_CXXCtorInitializer_pack) { + auto AST = + buildASTFromCode(R"cpp( +template<typename... T> +struct Templ { +}; + +template<typename... T> +struct D : Templ<T...> { + D(T... t) : Templ<T>(t)... {} +}; +)cpp", + "foo.cpp", std::make_shared<PCHContainerOperations>()); + auto &Ctx = AST->getASTContext(); + auto &TU = *Ctx.getTranslationUnitDecl(); + + auto BoundNodes = ast_matchers::match( + decl(hasDescendant(cxxConstructorDecl( + hasAnyConstructorInitializer(cxxCtorInitializer().bind("init"))))), + TU, Ctx); + + EXPECT_EQ(BoundNodes.size(), 1u); + + const auto *CtorInit = BoundNodes[0].getNodeAs<CXXCtorInitializer>("init"); + + auto Result = NodeIntrospection::GetLocations(CtorInit); + + if (Result.LocationAccessors.empty() && Result.RangeAccessors.empty()) { + return; + } + + auto ExpectedLocations = + FormatExpected<SourceLocation>(Result.LocationAccessors); + + EXPECT_THAT(ExpectedLocations, + UnorderedElementsAre( + STRING_LOCATION_PAIR(CtorInit, getEllipsisLoc()), + STRING_LOCATION_PAIR(CtorInit, getLParenLoc()), + STRING_LOCATION_PAIR(CtorInit, getMemberLocation()), + STRING_LOCATION_PAIR(CtorInit, getRParenLoc()), + STRING_LOCATION_PAIR(CtorInit, getSourceLocation()))); + + auto ExpectedRanges = FormatExpected<SourceRange>(Result.RangeAccessors); + + EXPECT_THAT(ExpectedRanges, UnorderedElementsAre(STRING_LOCATION_PAIR( + CtorInit, getSourceRange()))); +} 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 @@ -180,6 +180,15 @@ NodeLocationAccessors NodeIntrospection::GetLocations(clang::Decl const *) { return {}; } +NodeLocationAccessors NodeIntrospection::GetLocations(clang::CXXCtorInitializer const *) { + return {}; +} +NodeLocationAccessors NodeIntrospection::GetLocations(clang::NestedNameSpecifierLoc const*) { + return {}; +} +NodeLocationAccessors NodeIntrospection::GetLocations(clang::TemplateArgumentLoc const*) { + return {}; +} NodeLocationAccessors NodeIntrospection::GetLocations(clang::DynTypedNode const &) { return {}; Index: clang/lib/Tooling/DumpTool/ASTSrcLocProcessor.cpp =================================================================== --- clang/lib/Tooling/DumpTool/ASTSrcLocProcessor.cpp +++ clang/lib/Tooling/DumpTool/ASTSrcLocProcessor.cpp @@ -26,7 +26,10 @@ isDefinition(), isSameOrDerivedFrom( // TODO: Extend this with other clades - namedDecl(hasAnyName("clang::Stmt", "clang::Decl")) + namedDecl(hasAnyName("clang::Stmt", "clang::Decl", + "clang::CXXCtorInitializer", + "clang::NestedNameSpecifierLoc", + "clang::TemplateArgumentLoc")) .bind("nodeClade")), optionally(isDerivedFrom(cxxRecordDecl().bind("derivedFrom")))) .bind("className"), @@ -116,22 +119,30 @@ InnerMatcher...); }; - auto BoundNodesVec = - match(findAll(publicAccessor(ofClass(equalsNode(ASTClass)), - returns(asString(TypeString))) - .bind("classMethod")), - *ASTClass, *Result.Context); + auto BoundNodesVec = match( + findAll( + publicAccessor( + ofClass(cxxRecordDecl( + equalsNode(ASTClass), + optionally(isDerivedFrom( + cxxRecordDecl(hasAnyName("clang::Stmt", "clang::Decl")) + .bind("stmtOrDeclBase"))))), + returns(asString(TypeString))) + .bind("classMethod")), + *ASTClass, *Result.Context); std::vector<std::string> Methods; for (const auto &BN : BoundNodesVec) { + const auto *StmtOrDeclBase = + BN.getNodeAs<clang::CXXRecordDecl>("stmtOrDeclBase"); if (const auto *Node = BN.getNodeAs<clang::NamedDecl>("classMethod")) { // Only record the getBeginLoc etc on Stmt etc, because it will call // more-derived implementations pseudo-virtually. - if ((ASTClass->getName() != "Stmt" && ASTClass->getName() != "Decl") && + if (StmtOrDeclBase && (Node->getName() == "getBeginLoc" || Node->getName() == "getEndLoc" || - Node->getName() == "getSourceRange")) { + Node->getName() == "getSourceRange")) continue; - } + // Only record the getExprLoc on Expr, because it will call // more-derived implementations pseudo-virtually. if (ASTClass->getName() != "Expr" && Node->getName() == "getExprLoc") { Index: clang/lib/Tooling/CMakeLists.txt =================================================================== --- clang/lib/Tooling/CMakeLists.txt +++ clang/lib/Tooling/CMakeLists.txt @@ -43,6 +43,15 @@ NodeLocationAccessors NodeIntrospection::GetLocations(clang::Decl const *) { return {}; } +NodeLocationAccessors NodeIntrospection::GetLocations(clang::CXXCtorInitializer const *) { + return {}; +} +NodeLocationAccessors NodeIntrospection::GetLocations(clang::NestedNameSpecifierLoc const*) { + return {}; +} +NodeLocationAccessors NodeIntrospection::GetLocations(clang::TemplateArgumentLoc const*) { + return {}; +} NodeLocationAccessors NodeIntrospection::GetLocations(clang::DynTypedNode const &) { return {}; Index: clang/include/clang/Tooling/NodeIntrospection.h =================================================================== --- clang/include/clang/Tooling/NodeIntrospection.h +++ clang/include/clang/Tooling/NodeIntrospection.h @@ -23,6 +23,9 @@ class Stmt; class Decl; +class CXXCtorInitializer; +class NestedNameSpecifierLoc; +class TemplateArgumentLoc; namespace tooling { @@ -80,6 +83,9 @@ namespace NodeIntrospection { NodeLocationAccessors GetLocations(clang::Stmt const *Object); NodeLocationAccessors GetLocations(clang::Decl const *Object); +NodeLocationAccessors GetLocations(clang::CXXCtorInitializer const *Object); +NodeLocationAccessors GetLocations(clang::NestedNameSpecifierLoc const *); +NodeLocationAccessors GetLocations(clang::TemplateArgumentLoc const *); NodeLocationAccessors GetLocations(clang::DynTypedNode const &Node); } // namespace NodeIntrospection } // namespace tooling Index: clang/include/clang/AST/DeclCXX.h =================================================================== --- clang/include/clang/AST/DeclCXX.h +++ clang/include/clang/AST/DeclCXX.h @@ -2267,7 +2267,8 @@ // For a pack expansion, returns the location of the ellipsis. SourceLocation getEllipsisLoc() const { - assert(isPackExpansion() && "Initializer is not a pack expansion"); + if (!isPackExpansion()) + return {}; return MemberOrEllipsisLocation; }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits