steveire updated this revision to Diff 338049. steveire added a comment. Update
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D100516/new/ https://reviews.llvm.org/D100516 Files: clang/include/clang/Tooling/NodeIntrospection.h clang/lib/Tooling/CMakeLists.txt clang/lib/Tooling/DumpTool/APIData.h clang/lib/Tooling/DumpTool/ASTSrcLocProcessor.cpp clang/lib/Tooling/DumpTool/ASTSrcLocProcessor.h 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 @@ -26,25 +26,27 @@ using ::testing::Pair; using ::testing::UnorderedElementsAre; -template<typename T, typename MapType> -std::map<std::string, T> +template <typename T, typename MapType> +std::vector<std::pair<std::string, T>> FormatExpected(const MapType &Accessors) { - std::map<std::string, T> Result; + std::vector<std::pair<std::string, T>> Result; 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(LocationCallFormatterCpp::format( - *Accessor.second.get()), - Accessor.first); + std::back_inserter(Result), [](const auto &Accessor) { + return std::make_pair( + LocationCallFormatterCpp::format(*Accessor.second), + Accessor.first); }); return Result; } #define STRING_LOCATION_PAIR(INSTANCE, LOC) Pair(#LOC, INSTANCE->LOC) +#define STRING_LOCATION_STDPAIR(INSTANCE, LOC) \ + std::make_pair(std::string(#LOC), INSTANCE->LOC) + /** A test formatter for a hypothetical language which needs neither casts nor '->'. @@ -200,26 +202,85 @@ auto ExpectedLocations = FormatExpected<SourceLocation>(Result.LocationAccessors); - EXPECT_THAT(ExpectedLocations, - UnorderedElementsAre( - STRING_LOCATION_PAIR(MethodDecl, getBeginLoc()), - STRING_LOCATION_PAIR(MethodDecl, getBodyRBrace()), - STRING_LOCATION_PAIR(MethodDecl, getInnerLocStart()), - STRING_LOCATION_PAIR(MethodDecl, getLocation()), - STRING_LOCATION_PAIR(MethodDecl, getOuterLocStart()), - STRING_LOCATION_PAIR(MethodDecl, getTypeSpecEndLoc()), - STRING_LOCATION_PAIR(MethodDecl, getTypeSpecStartLoc()), - STRING_LOCATION_PAIR(MethodDecl, getEndLoc()))); + llvm::sort(ExpectedLocations); + + // clang-format off + EXPECT_EQ( + ExpectedLocations, + (std::vector<std::pair<std::string, SourceLocation>>{ +STRING_LOCATION_STDPAIR(MethodDecl, getBeginLoc()), +STRING_LOCATION_STDPAIR(MethodDecl, getBodyRBrace()), +STRING_LOCATION_STDPAIR(MethodDecl, getEndLoc()), +STRING_LOCATION_STDPAIR(MethodDecl, getInnerLocStart()), +STRING_LOCATION_STDPAIR(MethodDecl, getLocation()), +STRING_LOCATION_STDPAIR(MethodDecl, getOuterLocStart()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getLParenLoc()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getLocalRangeBegin()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getLocalRangeEnd()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getRParenLoc()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getReturnLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getLAngleLoc()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getReturnLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getRAngleLoc()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getReturnLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getTemplateNameLoc()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getReturnLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getBeginLoc()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getReturnLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getEndLoc()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getReturnLoc().getBeginLoc()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getReturnLoc().getEndLoc()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getReturnLoc().getNextTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getLAngleLoc()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getReturnLoc().getNextTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getRAngleLoc()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getReturnLoc().getNextTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getTemplateNameLoc()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getReturnLoc().getNextTypeLoc().getBeginLoc()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getReturnLoc().getNextTypeLoc().getEndLoc()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getBeginLoc()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getEndLoc()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getLAngleLoc()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getRAngleLoc()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getTemplateNameLoc()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getBeginLoc()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getEndLoc()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getBeginLoc()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getEndLoc()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getNextTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getLAngleLoc()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getNextTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getRAngleLoc()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getNextTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getTemplateNameLoc()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getNextTypeLoc().getBeginLoc()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getNextTypeLoc().getEndLoc()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSpecEndLoc()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSpecStartLoc()) + })); + // clang-format on auto ExpectedRanges = FormatExpected<SourceRange>(Result.RangeAccessors); - EXPECT_THAT( + llvm::sort(ExpectedRanges, [](const auto &LHS, const auto &RHS) { + return LHS.first < RHS.first; + }); + + // clang-format off + EXPECT_EQ( ExpectedRanges, - UnorderedElementsAre( - STRING_LOCATION_PAIR(MethodDecl, getExceptionSpecSourceRange()), - STRING_LOCATION_PAIR(MethodDecl, getParametersSourceRange()), - STRING_LOCATION_PAIR(MethodDecl, getReturnTypeSourceRange()), - STRING_LOCATION_PAIR(MethodDecl, getSourceRange()))); + (std::vector<std::pair<std::string, SourceRange>>{ +STRING_LOCATION_STDPAIR(MethodDecl, getExceptionSpecSourceRange()), +STRING_LOCATION_STDPAIR(MethodDecl, getParametersSourceRange()), +STRING_LOCATION_STDPAIR(MethodDecl, getReturnTypeSourceRange()), +STRING_LOCATION_STDPAIR(MethodDecl, getSourceRange()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getExceptionSpecRange()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getParensRange()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getReturnLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getLocalSourceRange()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getReturnLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getSourceRange()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getReturnLoc().getLocalSourceRange()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getReturnLoc().getNextTypeLoc().getLocalSourceRange()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getReturnLoc().getNextTypeLoc().getSourceRange()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getReturnLoc().getSourceRange()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getLocalSourceRange()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getLocalSourceRange()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getSourceRange()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getLocalSourceRange()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getNextTypeLoc().getLocalSourceRange()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getNextTypeLoc().getSourceRange()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getSourceRange()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getSourceRange()) + })); + // clang-format on } TEST(Introspection, SourceLocations_NNS) { @@ -253,17 +314,25 @@ EXPECT_THAT( ExpectedLocations, - UnorderedElementsAre(STRING_LOCATION_PAIR(NNS, getBeginLoc()), - STRING_LOCATION_PAIR(NNS, getEndLoc()), - STRING_LOCATION_PAIR(NNS, getLocalBeginLoc()), - STRING_LOCATION_PAIR(NNS, getLocalEndLoc()))); + UnorderedElementsAre( + STRING_LOCATION_PAIR(NNS, getBeginLoc()), + STRING_LOCATION_PAIR(NNS, getEndLoc()), + STRING_LOCATION_PAIR(NNS, getLocalBeginLoc()), + STRING_LOCATION_PAIR(NNS, getLocalEndLoc()), + STRING_LOCATION_PAIR( + NNS, getTypeLoc().getAs<clang::TypeSpecTypeLoc>().getNameLoc()), + STRING_LOCATION_PAIR(NNS, getTypeLoc().getBeginLoc()), + STRING_LOCATION_PAIR(NNS, getTypeLoc().getEndLoc()))); auto ExpectedRanges = FormatExpected<SourceRange>(Result.RangeAccessors); EXPECT_THAT( ExpectedRanges, - UnorderedElementsAre(STRING_LOCATION_PAIR(NNS, getLocalSourceRange()), - STRING_LOCATION_PAIR(NNS, getSourceRange()))); + UnorderedElementsAre( + STRING_LOCATION_PAIR(NNS, getLocalSourceRange()), + STRING_LOCATION_PAIR(NNS, getSourceRange()), + STRING_LOCATION_PAIR(NNS, getTypeLoc().getSourceRange()), + STRING_LOCATION_PAIR(NNS, getTypeLoc().getLocalSourceRange()))); } TEST(Introspection, SourceLocations_TA_Type) { @@ -297,13 +366,31 @@ auto ExpectedLocations = FormatExpected<SourceLocation>(Result.LocationAccessors); + // clang-format off EXPECT_THAT(ExpectedLocations, - UnorderedElementsAre(STRING_LOCATION_PAIR(TA, getLocation()))); + UnorderedElementsAre( +STRING_LOCATION_PAIR(TA, getLocation()), +STRING_LOCATION_PAIR(TA, + getTypeSourceInfo()->getTypeLoc().getAs<clang::BuiltinTypeLoc>().getBuiltinLoc()), +STRING_LOCATION_PAIR(TA, + getTypeSourceInfo()->getTypeLoc().getAs<clang::BuiltinTypeLoc>().getNameLoc()), +STRING_LOCATION_PAIR( + TA, getTypeSourceInfo()->getTypeLoc().getBeginLoc()), +STRING_LOCATION_PAIR( + TA, getTypeSourceInfo()->getTypeLoc().getEndLoc()) + )); + // clang-format on auto ExpectedRanges = FormatExpected<SourceRange>(Result.RangeAccessors); - EXPECT_THAT(ExpectedRanges, - UnorderedElementsAre(STRING_LOCATION_PAIR(TA, getSourceRange()))); + EXPECT_THAT( + ExpectedRanges, + UnorderedElementsAre( + STRING_LOCATION_PAIR(TA, getSourceRange()), + STRING_LOCATION_PAIR( + TA, getTypeSourceInfo()->getTypeLoc().getSourceRange()), + STRING_LOCATION_PAIR( + TA, getTypeSourceInfo()->getTypeLoc().getLocalSourceRange()))); } TEST(Introspection, SourceLocations_TA_Decl) { @@ -555,13 +642,31 @@ auto ExpectedLocations = FormatExpected<SourceLocation>(Result.LocationAccessors); + // clang-format off EXPECT_THAT(ExpectedLocations, - UnorderedElementsAre(STRING_LOCATION_PAIR(TA, getLocation()))); + UnorderedElementsAre( +STRING_LOCATION_PAIR(TA, getLocation()), +STRING_LOCATION_PAIR(TA, + getTypeSourceInfo()->getTypeLoc().getAs<clang::BuiltinTypeLoc>().getBuiltinLoc()), +STRING_LOCATION_PAIR(TA, + getTypeSourceInfo()->getTypeLoc().getAs<clang::BuiltinTypeLoc>().getNameLoc()), +STRING_LOCATION_PAIR( + TA, getTypeSourceInfo()->getTypeLoc().getBeginLoc()), +STRING_LOCATION_PAIR( + TA, getTypeSourceInfo()->getTypeLoc().getEndLoc()) + )); + // clang-format on auto ExpectedRanges = FormatExpected<SourceRange>(Result.RangeAccessors); - EXPECT_THAT(ExpectedRanges, - UnorderedElementsAre(STRING_LOCATION_PAIR(TA, getSourceRange()))); + EXPECT_THAT( + ExpectedRanges, + UnorderedElementsAre( + STRING_LOCATION_PAIR(TA, getSourceRange()), + STRING_LOCATION_PAIR( + TA, getTypeSourceInfo()->getTypeLoc().getSourceRange()), + STRING_LOCATION_PAIR( + TA, getTypeSourceInfo()->getTypeLoc().getLocalSourceRange()))); } TEST(Introspection, SourceLocations_CXXCtorInitializer_base) { @@ -594,16 +699,34 @@ 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()))); + // clang-format off + EXPECT_THAT( + ExpectedLocations, + UnorderedElementsAre( +STRING_LOCATION_PAIR(CtorInit, getBaseClassLoc().getAs<clang::TypeSpecTypeLoc>().getNameLoc()), +STRING_LOCATION_PAIR(CtorInit, getBaseClassLoc().getBeginLoc()), +STRING_LOCATION_PAIR(CtorInit, getBaseClassLoc().getEndLoc()), +STRING_LOCATION_PAIR(CtorInit, getLParenLoc()), +STRING_LOCATION_PAIR(CtorInit, getRParenLoc()), +STRING_LOCATION_PAIR(CtorInit, getSourceLocation()), +STRING_LOCATION_PAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getAs<clang::TypeSpecTypeLoc>().getNameLoc()), +STRING_LOCATION_PAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getBeginLoc()), +STRING_LOCATION_PAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getEndLoc()) + )); + // clang-format on auto ExpectedRanges = FormatExpected<SourceRange>(Result.RangeAccessors); - EXPECT_THAT(ExpectedRanges, UnorderedElementsAre(STRING_LOCATION_PAIR( - CtorInit, getSourceRange()))); + // clang-format off + EXPECT_THAT( + ExpectedRanges, + UnorderedElementsAre( + STRING_LOCATION_PAIR(CtorInit, getBaseClassLoc().getLocalSourceRange()), + STRING_LOCATION_PAIR(CtorInit, getBaseClassLoc().getSourceRange()), + STRING_LOCATION_PAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getLocalSourceRange()), + STRING_LOCATION_PAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getSourceRange()), + STRING_LOCATION_PAIR(CtorInit, getSourceRange()))); + // clang-format on } TEST(Introspection, SourceLocations_CXXCtorInitializer_member) { @@ -675,16 +798,33 @@ 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()))); + // clang-format off + EXPECT_THAT( + ExpectedLocations, + UnorderedElementsAre( +STRING_LOCATION_PAIR(CtorInit, getLParenLoc()), +STRING_LOCATION_PAIR(CtorInit, getRParenLoc()), +STRING_LOCATION_PAIR(CtorInit, getSourceLocation()), +STRING_LOCATION_PAIR(CtorInit, + getTypeSourceInfo()->getTypeLoc().getBeginLoc()), +STRING_LOCATION_PAIR(CtorInit, + getTypeSourceInfo()->getTypeLoc().getEndLoc()), +STRING_LOCATION_PAIR(CtorInit, + getTypeSourceInfo()->getTypeLoc().getAs<clang::TypeSpecTypeLoc>().getNameLoc()) + )); + // clang-format on auto ExpectedRanges = FormatExpected<SourceRange>(Result.RangeAccessors); - EXPECT_THAT(ExpectedRanges, UnorderedElementsAre(STRING_LOCATION_PAIR( - CtorInit, getSourceRange()))); + EXPECT_THAT( + ExpectedRanges, + UnorderedElementsAre( + STRING_LOCATION_PAIR(CtorInit, getSourceRange()), + STRING_LOCATION_PAIR( + CtorInit, + getTypeSourceInfo()->getTypeLoc().getLocalSourceRange()), + STRING_LOCATION_PAIR( + CtorInit, getTypeSourceInfo()->getTypeLoc().getSourceRange()))); } TEST(Introspection, SourceLocations_CXXCtorInitializer_pack) { @@ -720,18 +860,44 @@ 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()))); + llvm::sort(ExpectedLocations); + + // clang-format off + EXPECT_EQ( + ExpectedLocations, + (std::vector<std::pair<std::string, SourceLocation>>{ +STRING_LOCATION_STDPAIR(CtorInit, getBaseClassLoc().getAs<clang::TemplateSpecializationTypeLoc>().getLAngleLoc()), +STRING_LOCATION_STDPAIR(CtorInit, getBaseClassLoc().getAs<clang::TemplateSpecializationTypeLoc>().getRAngleLoc()), +STRING_LOCATION_STDPAIR(CtorInit, getBaseClassLoc().getAs<clang::TemplateSpecializationTypeLoc>().getTemplateNameLoc()), +STRING_LOCATION_STDPAIR(CtorInit, getBaseClassLoc().getBeginLoc()), +STRING_LOCATION_STDPAIR(CtorInit, getBaseClassLoc().getEndLoc()), +STRING_LOCATION_STDPAIR(CtorInit, getEllipsisLoc()), +STRING_LOCATION_STDPAIR(CtorInit, getLParenLoc()), +STRING_LOCATION_STDPAIR(CtorInit, getMemberLocation()), +STRING_LOCATION_STDPAIR(CtorInit, getRParenLoc()), +STRING_LOCATION_STDPAIR(CtorInit, getSourceLocation()), +STRING_LOCATION_STDPAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getLAngleLoc()), +STRING_LOCATION_STDPAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getRAngleLoc()), +STRING_LOCATION_STDPAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getTemplateNameLoc()), +STRING_LOCATION_STDPAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getBeginLoc()), +STRING_LOCATION_STDPAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getEndLoc()) + })); + // clang-format on auto ExpectedRanges = FormatExpected<SourceRange>(Result.RangeAccessors); - EXPECT_THAT(ExpectedRanges, UnorderedElementsAre(STRING_LOCATION_PAIR( - CtorInit, getSourceRange()))); + EXPECT_THAT( + ExpectedRanges, + UnorderedElementsAre( + STRING_LOCATION_PAIR(CtorInit, + getBaseClassLoc().getLocalSourceRange()), + STRING_LOCATION_PAIR(CtorInit, getBaseClassLoc().getSourceRange()), + STRING_LOCATION_PAIR(CtorInit, getSourceRange()), + STRING_LOCATION_PAIR( + CtorInit, + getTypeSourceInfo()->getTypeLoc().getLocalSourceRange()), + STRING_LOCATION_PAIR( + CtorInit, getTypeSourceInfo()->getTypeLoc().getSourceRange()))); } TEST(Introspection, SourceLocations_CXXBaseSpecifier_plain) { @@ -760,15 +926,27 @@ auto ExpectedLocations = FormatExpected<SourceLocation>(Result.LocationAccessors); + // clang-format off EXPECT_THAT(ExpectedLocations, - UnorderedElementsAre(STRING_LOCATION_PAIR(Base, getBaseTypeLoc()), - STRING_LOCATION_PAIR(Base, getBeginLoc()), - STRING_LOCATION_PAIR(Base, getEndLoc()))); + UnorderedElementsAre( +STRING_LOCATION_PAIR(Base, getBaseTypeLoc()), +STRING_LOCATION_PAIR(Base, getBeginLoc()), +STRING_LOCATION_PAIR(Base, getEndLoc()), +STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getAs<clang::TypeSpecTypeLoc>().getNameLoc()), +STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getEndLoc()), +STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getBeginLoc()) + )); + // clang-format on auto ExpectedRanges = FormatExpected<SourceRange>(Result.RangeAccessors); - EXPECT_THAT(ExpectedRanges, UnorderedElementsAre(STRING_LOCATION_PAIR( - Base, getSourceRange()))); + // clang-format off + EXPECT_THAT(ExpectedRanges, UnorderedElementsAre( +STRING_LOCATION_PAIR(Base, getSourceRange()), +STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getSourceRange()), +STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getLocalSourceRange()) + )); + // clang-format on } TEST(Introspection, SourceLocations_CXXBaseSpecifier_accessspec) { @@ -797,15 +975,27 @@ auto ExpectedLocations = FormatExpected<SourceLocation>(Result.LocationAccessors); + // clang-format off EXPECT_THAT(ExpectedLocations, - UnorderedElementsAre(STRING_LOCATION_PAIR(Base, getBaseTypeLoc()), - STRING_LOCATION_PAIR(Base, getBeginLoc()), - STRING_LOCATION_PAIR(Base, getEndLoc()))); + UnorderedElementsAre( +STRING_LOCATION_PAIR(Base, getBaseTypeLoc()), +STRING_LOCATION_PAIR(Base, getBeginLoc()), +STRING_LOCATION_PAIR(Base, getEndLoc()), +STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getAs<clang::TypeSpecTypeLoc>().getNameLoc()), +STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getEndLoc()), +STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getBeginLoc()) + )); + // clang-format on auto ExpectedRanges = FormatExpected<SourceRange>(Result.RangeAccessors); - EXPECT_THAT(ExpectedRanges, UnorderedElementsAre(STRING_LOCATION_PAIR( - Base, getSourceRange()))); + // clang-format off + EXPECT_THAT(ExpectedRanges, UnorderedElementsAre( +STRING_LOCATION_PAIR(Base, getSourceRange()), +STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getLocalSourceRange()), +STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getSourceRange()) + )); + // clang-format on } TEST(Introspection, SourceLocations_CXXBaseSpecifier_virtual) { @@ -835,15 +1025,27 @@ auto ExpectedLocations = FormatExpected<SourceLocation>(Result.LocationAccessors); + // clang-format off EXPECT_THAT(ExpectedLocations, - UnorderedElementsAre(STRING_LOCATION_PAIR(Base, getBaseTypeLoc()), - STRING_LOCATION_PAIR(Base, getBeginLoc()), - STRING_LOCATION_PAIR(Base, getEndLoc()))); + UnorderedElementsAre( +STRING_LOCATION_PAIR(Base, getBaseTypeLoc()), +STRING_LOCATION_PAIR(Base, getBeginLoc()), +STRING_LOCATION_PAIR(Base, getEndLoc()), +STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getBeginLoc()), +STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getAs<clang::TypeSpecTypeLoc>().getNameLoc()), +STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getEndLoc()) + )); + // clang-format on auto ExpectedRanges = FormatExpected<SourceRange>(Result.RangeAccessors); - EXPECT_THAT(ExpectedRanges, UnorderedElementsAre(STRING_LOCATION_PAIR( - Base, getSourceRange()))); + // clang-format off + EXPECT_THAT(ExpectedRanges, UnorderedElementsAre( +STRING_LOCATION_PAIR(Base, getSourceRange()), +STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getSourceRange()), +STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getLocalSourceRange()) + )); + // clang-format on } TEST(Introspection, SourceLocations_CXXBaseSpecifier_template_base) { @@ -873,15 +1075,29 @@ auto ExpectedLocations = FormatExpected<SourceLocation>(Result.LocationAccessors); + // clang-format off EXPECT_THAT(ExpectedLocations, - UnorderedElementsAre(STRING_LOCATION_PAIR(Base, getBaseTypeLoc()), - STRING_LOCATION_PAIR(Base, getBeginLoc()), - STRING_LOCATION_PAIR(Base, getEndLoc()))); + UnorderedElementsAre( +STRING_LOCATION_PAIR(Base, getBaseTypeLoc()), +STRING_LOCATION_PAIR(Base, getBeginLoc()), +STRING_LOCATION_PAIR(Base, getEndLoc()), +STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getBeginLoc()), +STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getTemplateNameLoc()), +STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getLAngleLoc()), +STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getEndLoc()), +STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getRAngleLoc()) + )); + // clang-format on auto ExpectedRanges = FormatExpected<SourceRange>(Result.RangeAccessors); - EXPECT_THAT(ExpectedRanges, UnorderedElementsAre(STRING_LOCATION_PAIR( - Base, getSourceRange()))); + // clang-format off + EXPECT_THAT(ExpectedRanges, UnorderedElementsAre( +STRING_LOCATION_PAIR(Base, getSourceRange()), +STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getSourceRange()), +STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getLocalSourceRange()) + )); + // clang-format on } TEST(Introspection, SourceLocations_CXXBaseSpecifier_pack) { @@ -912,14 +1128,203 @@ auto ExpectedLocations = FormatExpected<SourceLocation>(Result.LocationAccessors); + // clang-format off EXPECT_THAT(ExpectedLocations, - UnorderedElementsAre(STRING_LOCATION_PAIR(Base, getBaseTypeLoc()), - STRING_LOCATION_PAIR(Base, getEllipsisLoc()), - STRING_LOCATION_PAIR(Base, getBeginLoc()), - STRING_LOCATION_PAIR(Base, getEndLoc()))); + UnorderedElementsAre( +STRING_LOCATION_PAIR(Base, getBaseTypeLoc()), +STRING_LOCATION_PAIR(Base, getEllipsisLoc()), +STRING_LOCATION_PAIR(Base, getBeginLoc()), +STRING_LOCATION_PAIR(Base, getEndLoc()), +STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getEndLoc()), +STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getAs<clang::TypeSpecTypeLoc>().getNameLoc()), +STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getBeginLoc()) + )); + // clang-format on auto ExpectedRanges = FormatExpected<SourceRange>(Result.RangeAccessors); - EXPECT_THAT(ExpectedRanges, UnorderedElementsAre(STRING_LOCATION_PAIR( - Base, getSourceRange()))); + // clang-format off + EXPECT_THAT(ExpectedRanges, UnorderedElementsAre( +STRING_LOCATION_PAIR(Base, getSourceRange()), +STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getSourceRange()), +STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getLocalSourceRange()) + )); + // clang-format on +} + +TEST(Introspection, SourceLocations_FunctionProtoTypeLoc) { + auto AST = + buildASTFromCode(R"cpp( +int foo(); +)cpp", + "foo.cpp", std::make_shared<PCHContainerOperations>()); + auto &Ctx = AST->getASTContext(); + auto &TU = *Ctx.getTranslationUnitDecl(); + + auto BoundNodes = ast_matchers::match( + decl(hasDescendant(loc(functionProtoType()).bind("tl"))), TU, Ctx); + + EXPECT_EQ(BoundNodes.size(), 1u); + + const auto *TL = BoundNodes[0].getNodeAs<TypeLoc>("tl"); + auto Result = NodeIntrospection::GetLocations(*TL); + + if (Result.LocationAccessors.empty() && Result.RangeAccessors.empty()) { + return; + } + + auto ExpectedLocations = + FormatExpected<SourceLocation>(Result.LocationAccessors); + + llvm::sort(ExpectedLocations); + + // clang-format off + EXPECT_EQ( + ExpectedLocations, + (std::vector<std::pair<std::string, SourceLocation>>{ +STRING_LOCATION_STDPAIR(TL, getAs<clang::FunctionTypeLoc>().getLParenLoc()), +STRING_LOCATION_STDPAIR(TL, getAs<clang::FunctionTypeLoc>().getLocalRangeBegin()), +STRING_LOCATION_STDPAIR(TL, getAs<clang::FunctionTypeLoc>().getLocalRangeEnd()), +STRING_LOCATION_STDPAIR(TL, getAs<clang::FunctionTypeLoc>().getRParenLoc()), +STRING_LOCATION_STDPAIR(TL, getAs<clang::FunctionTypeLoc>().getReturnLoc().getAs<clang::BuiltinTypeLoc>().getBuiltinLoc()), +STRING_LOCATION_STDPAIR(TL, getAs<clang::FunctionTypeLoc>().getReturnLoc().getAs<clang::BuiltinTypeLoc>().getNameLoc()), +STRING_LOCATION_STDPAIR(TL, getAs<clang::FunctionTypeLoc>().getReturnLoc().getBeginLoc()), +STRING_LOCATION_STDPAIR(TL, getAs<clang::FunctionTypeLoc>().getReturnLoc().getEndLoc()), +STRING_LOCATION_STDPAIR(TL, getBeginLoc()), +STRING_LOCATION_STDPAIR(TL, getEndLoc()), +STRING_LOCATION_STDPAIR(TL, getNextTypeLoc().getAs<clang::BuiltinTypeLoc>().getBuiltinLoc()), +STRING_LOCATION_STDPAIR(TL, getNextTypeLoc().getAs<clang::BuiltinTypeLoc>().getNameLoc()), +STRING_LOCATION_STDPAIR(TL, getNextTypeLoc().getBeginLoc()), +STRING_LOCATION_STDPAIR(TL, getNextTypeLoc().getEndLoc()) + })); + // clang-format on + + auto ExpectedRanges = FormatExpected<SourceRange>(Result.RangeAccessors); + + // clang-format off + EXPECT_THAT( + ExpectedRanges, + UnorderedElementsAre( +STRING_LOCATION_PAIR(TL, getAs<clang::FunctionTypeLoc>().getParensRange()), +STRING_LOCATION_PAIR(TL, getAs<clang::FunctionTypeLoc>().getReturnLoc().getLocalSourceRange()), +STRING_LOCATION_PAIR(TL, getAs<clang::FunctionTypeLoc>().getReturnLoc().getSourceRange()), +STRING_LOCATION_PAIR(TL, getLocalSourceRange()), +STRING_LOCATION_PAIR(TL, getNextTypeLoc().getLocalSourceRange()), +STRING_LOCATION_PAIR(TL, getNextTypeLoc().getSourceRange()), +STRING_LOCATION_PAIR(TL, getSourceRange()) + )); + // clang-format on +} + +TEST(Introspection, SourceLocations_PointerTypeLoc) { + auto AST = + buildASTFromCode(R"cpp( +int* i; +)cpp", + "foo.cpp", std::make_shared<PCHContainerOperations>()); + auto &Ctx = AST->getASTContext(); + auto &TU = *Ctx.getTranslationUnitDecl(); + + auto BoundNodes = ast_matchers::match( + decl(hasDescendant( + varDecl(hasName("i"), hasDescendant(loc(pointerType()).bind("tl"))))), + TU, Ctx); + + EXPECT_EQ(BoundNodes.size(), 1u); + + const auto *TL = BoundNodes[0].getNodeAs<TypeLoc>("tl"); + auto Result = NodeIntrospection::GetLocations(*TL); + + if (Result.LocationAccessors.empty() && Result.RangeAccessors.empty()) { + return; + } + + auto ExpectedLocations = + FormatExpected<SourceLocation>(Result.LocationAccessors); + + llvm::sort(ExpectedLocations); + + // clang-format off + EXPECT_EQ( + ExpectedLocations, + (std::vector<std::pair<std::string, SourceLocation>>{ +STRING_LOCATION_STDPAIR(TL, getAs<clang::PointerTypeLoc>().getPointeeLoc().getAs<clang::BuiltinTypeLoc>().getBuiltinLoc()), +STRING_LOCATION_STDPAIR(TL, getAs<clang::PointerTypeLoc>().getPointeeLoc().getAs<clang::BuiltinTypeLoc>().getNameLoc()), +STRING_LOCATION_STDPAIR(TL, getAs<clang::PointerTypeLoc>().getPointeeLoc().getBeginLoc()), +STRING_LOCATION_STDPAIR(TL, getAs<clang::PointerTypeLoc>().getPointeeLoc().getEndLoc()), +STRING_LOCATION_STDPAIR(TL, getAs<clang::PointerTypeLoc>().getSigilLoc()), +STRING_LOCATION_STDPAIR(TL, getAs<clang::PointerTypeLoc>().getStarLoc()), +STRING_LOCATION_STDPAIR(TL, getBeginLoc()), +STRING_LOCATION_STDPAIR(TL, getEndLoc()), +STRING_LOCATION_STDPAIR(TL, getNextTypeLoc().getAs<clang::BuiltinTypeLoc>().getBuiltinLoc()), +STRING_LOCATION_STDPAIR(TL, getNextTypeLoc().getAs<clang::BuiltinTypeLoc>().getNameLoc()), +STRING_LOCATION_STDPAIR(TL, getNextTypeLoc().getBeginLoc()), +STRING_LOCATION_STDPAIR(TL, getNextTypeLoc().getEndLoc()) +})); + // clang-format on + + auto ExpectedRanges = FormatExpected<SourceRange>(Result.RangeAccessors); + + // clang-format off + EXPECT_THAT( + ExpectedRanges, + UnorderedElementsAre( +STRING_LOCATION_PAIR(TL, getAs<clang::PointerTypeLoc>().getPointeeLoc().getLocalSourceRange()), +STRING_LOCATION_PAIR(TL, getAs<clang::PointerTypeLoc>().getPointeeLoc().getSourceRange()), +STRING_LOCATION_PAIR(TL, getLocalSourceRange()), +STRING_LOCATION_PAIR(TL, getNextTypeLoc().getLocalSourceRange()), +STRING_LOCATION_PAIR(TL, getNextTypeLoc().getSourceRange()), +STRING_LOCATION_PAIR(TL, getSourceRange()) + )); + // clang-format on +} + +#ifndef _WIN32 +// This test doesn't work on windows due to use of the typeof extension. +TEST(Introspection, SourceLocations_TypeOfTypeLoc) { + auto AST = + buildASTFromCode(R"cpp( +typeof (static_cast<void *>(0)) i; +)cpp", + "foo.cpp", std::make_shared<PCHContainerOperations>()); + auto &Ctx = AST->getASTContext(); + auto &TU = *Ctx.getTranslationUnitDecl(); + + auto BoundNodes = ast_matchers::match( + decl(hasDescendant( + varDecl(hasName("i"), hasDescendant(loc(type()).bind("tl"))))), + TU, Ctx); + + EXPECT_EQ(BoundNodes.size(), 1u); + + const auto *TL = BoundNodes[0].getNodeAs<TypeLoc>("tl"); + auto Result = NodeIntrospection::GetLocations(*TL); + + if (Result.LocationAccessors.empty() && Result.RangeAccessors.empty()) { + return; + } + + auto ExpectedLocations = + FormatExpected<SourceLocation>(Result.LocationAccessors); + + EXPECT_THAT(ExpectedLocations, + UnorderedElementsAre( + STRING_LOCATION_PAIR(TL, getBeginLoc()), + STRING_LOCATION_PAIR(TL, getEndLoc()), + STRING_LOCATION_PAIR( + TL, getAs<clang::TypeOfExprTypeLoc>().getTypeofLoc()), + STRING_LOCATION_PAIR( + TL, getAs<clang::TypeOfExprTypeLoc>().getLParenLoc()), + STRING_LOCATION_PAIR( + TL, getAs<clang::TypeOfExprTypeLoc>().getRParenLoc()))); + + auto ExpectedRanges = FormatExpected<SourceRange>(Result.RangeAccessors); + + EXPECT_THAT(ExpectedRanges, + UnorderedElementsAre( + STRING_LOCATION_PAIR(TL, getLocalSourceRange()), + STRING_LOCATION_PAIR(TL, getSourceRange()), + STRING_LOCATION_PAIR( + TL, getAs<clang::TypeOfExprTypeLoc>().getParensRange()))); } +#endif 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 @@ -11,6 +11,9 @@ implementationContent = '' + def __init__(self, templateClasses): + self.templateClasses = templateClasses + def GeneratePrologue(self): self.implementationContent += \ @@ -30,25 +33,69 @@ using RangeAndString = SourceRangeMap::value_type; bool NodeIntrospection::hasIntrospectionSupport() { return true; } + +struct RecursionPopper +{ + RecursionPopper(std::vector<clang::TypeLoc> &TypeLocRecursionGuard) + : TLRG(TypeLocRecursionGuard) + { + + } + + ~RecursionPopper() + { + TLRG.pop_back(); + } + +private: +std::vector<clang::TypeLoc> &TLRG; +}; """ def GenerateBaseGetLocationsDeclaration(self, CladeName): + InstanceDecoration = "*" + if CladeName == "TypeLoc": + InstanceDecoration = "&" + self.implementationContent += \ """ void GetLocationsImpl(SharedLocationCall const& Prefix, - clang::{0} const *Object, SourceLocationMap &Locs, - SourceRangeMap &Rngs); -""".format(CladeName) - - def GenerateSrcLocMethod(self, ClassName, ClassData): + clang::{0} const {1}Object, SourceLocationMap &Locs, + SourceRangeMap &Rngs, + std::vector<clang::TypeLoc> &TypeLocRecursionGuard); +""".format(CladeName, InstanceDecoration) + + def GenerateSrcLocMethod(self, + ClassName, ClassData, CreateLocalRecursionGuard): + + NormalClassName = ClassName + RecursionGuardParam = ('' if CreateLocalRecursionGuard else \ + ', std::vector<clang::TypeLoc>& TypeLocRecursionGuard') + + if "templateParms" in ClassData: + TemplatePreamble = "template <typename " + ClassName += "<" + First = True + for TA in ClassData["templateParms"]: + if not First: + ClassName += ", " + TemplatePreamble += ", typename " + + First = False + ClassName += TA + TemplatePreamble += TA + + ClassName += ">" + TemplatePreamble += ">\n"; + self.implementationContent += TemplatePreamble self.implementationContent += \ """ static void GetLocations{0}(SharedLocationCall const& Prefix, - clang::{0} const &Object, - SourceLocationMap &Locs, SourceRangeMap &Rngs) + clang::{1} const &Object, + SourceLocationMap &Locs, SourceRangeMap &Rngs {2}) {{ -""".format(ClassName) +""".format(NormalClassName, ClassName, RecursionGuardParam) if 'sourceLocations' in ClassData: for locName in ClassData['sourceLocations']: @@ -70,6 +117,40 @@ self.implementationContent += '\n' + if 'typeLocs' in ClassData or 'typeSourceInfos' in ClassData: + if CreateLocalRecursionGuard: + self.implementationContent += \ + 'std::vector<clang::TypeLoc> TypeLocRecursionGuard;\n' + + self.implementationContent += '\n' + + if 'typeLocs' in ClassData: + for typeLoc in ClassData['typeLocs']: + + self.implementationContent += \ + """ + if (Object.{0}()) {{ + GetLocationsImpl( + llvm::makeIntrusiveRefCnt<LocationCall>(Prefix, "{0}"), + Object.{0}(), Locs, Rngs, TypeLocRecursionGuard); + }} + """.format(typeLoc) + + self.implementationContent += '\n' + if 'typeSourceInfos' in ClassData: + for tsi in ClassData['typeSourceInfos']: + self.implementationContent += \ + """ + if (Object.{0}()) {{ + GetLocationsImpl(llvm::makeIntrusiveRefCnt<LocationCall>( + llvm::makeIntrusiveRefCnt<LocationCall>(Prefix, "{0}", + LocationCall::ReturnsPointer), "getTypeLoc"), + Object.{0}()->getTypeLoc(), Locs, Rngs, TypeLocRecursionGuard); + }} + """.format(tsi) + + self.implementationContent += '\n' + self.implementationContent += '}\n' def GenerateFiles(self, OutputFile): @@ -77,32 +158,78 @@ OutputFile), 'w') as f: f.write(self.implementationContent) - def GenerateBaseGetLocationsFunction(self, ASTClassNames, CladeName): + def GenerateBaseGetLocationsFunction(self, ASTClassNames, + ClassEntries, CladeName, InheritanceMap, + CreateLocalRecursionGuard): MethodReturnType = 'NodeLocationAccessors' + InstanceDecoration = "*" + if CladeName == "TypeLoc": + InstanceDecoration = "&" Signature = \ - 'GetLocations(clang::{0} const *Object)'.format(CladeName) + 'GetLocations(clang::{0} const {1}Object)'.format( + CladeName, InstanceDecoration) ImplSignature = \ """ -GetLocationsImpl(SharedLocationCall const& Prefix, - clang::{0} const *Object, SourceLocationMap &Locs, - SourceRangeMap &Rngs) -""".format(CladeName) + GetLocationsImpl(SharedLocationCall const& Prefix, + clang::{0} const {1}Object, SourceLocationMap &Locs, + SourceRangeMap &Rngs, + std::vector<clang::TypeLoc> &TypeLocRecursionGuard) + """.format(CladeName, InstanceDecoration) + + self.implementationContent += 'void {0} {{ '.format(ImplSignature) + + if CladeName == "TypeLoc": + self.implementationContent += 'if (Object.isNull()) return;' + + self.implementationContent += \ + """ + if (llvm::find(TypeLocRecursionGuard, Object) != TypeLocRecursionGuard.end()) + return; + TypeLocRecursionGuard.push_back(Object); + RecursionPopper RAII(TypeLocRecursionGuard); + """ + RecursionGuardParam = '' + if not CreateLocalRecursionGuard: + RecursionGuardParam = ', TypeLocRecursionGuard' + + ArgPrefix = '*' + if CladeName == "TypeLoc": + ArgPrefix = '' self.implementationContent += \ - 'void {0} {{ GetLocations{1}(Prefix, *Object, Locs, Rngs);'.format( - ImplSignature, - CladeName) + 'GetLocations{0}(Prefix, {1}Object, Locs, Rngs {2});'.format( + CladeName, ArgPrefix, RecursionGuardParam) + + if CladeName == "TypeLoc": + self.implementationContent += \ + ''' + if (auto QTL = Object.getAs<clang::QualifiedTypeLoc>()) { + auto Dequalified = QTL.getNextTypeLoc(); + return GetLocationsImpl(llvm::makeIntrusiveRefCnt<LocationCall>(Prefix, "getNextTypeLoc"), + Dequalified, + Locs, + Rngs, + TypeLocRecursionGuard); + }''' for ASTClassName in ASTClassNames: - if ASTClassName != CladeName: + if ASTClassName in self.templateClasses: + continue + if ASTClassName == CladeName: + continue + if CladeName != "TypeLoc": self.implementationContent += \ - """ + """ if (auto Derived = llvm::dyn_cast<clang::{0}>(Object)) {{ - GetLocations{0}(Prefix, *Derived, Locs, Rngs); + GetLocations{0}(Prefix, *Derived, Locs, Rngs {1}); }} -""".format(ASTClassName) +""".format(ASTClassName, RecursionGuardParam) + continue + + self.GenerateBaseTypeLocVisit(ASTClassName, ClassEntries, + RecursionGuardParam, InheritanceMap) self.implementationContent += '}' @@ -111,14 +238,43 @@ {0} NodeIntrospection::{1} {{ NodeLocationAccessors Result; SharedLocationCall Prefix; + std::vector<clang::TypeLoc> TypeLocRecursionGuard; GetLocationsImpl(Prefix, Object, Result.LocationAccessors, - Result.RangeAccessors); -""".format(MethodReturnType, - Signature) + Result.RangeAccessors, TypeLocRecursionGuard); +""".format(MethodReturnType, Signature) self.implementationContent += 'return Result; }' + def GenerateBaseTypeLocVisit(self, ASTClassName, ClassEntries, + RecursionGuardParam, InheritanceMap): + CallPrefix = 'Prefix' + if ASTClassName != 'TypeLoc': + CallPrefix = \ + '''llvm::makeIntrusiveRefCnt<LocationCall>(Prefix, + "getAs<clang::{0}>", LocationCall::IsCast) + '''.format(ASTClassName) + + if ASTClassName in ClassEntries: + + self.implementationContent += \ + """ + if (auto ConcreteTL = Object.getAs<clang::{0}>()) + GetLocations{1}({2}, ConcreteTL, Locs, Rngs {3}); + """.format(ASTClassName, ASTClassName, + CallPrefix, RecursionGuardParam) + + if ASTClassName in InheritanceMap: + for baseTemplate in self.templateClasses: + if baseTemplate in InheritanceMap[ASTClassName]: + self.implementationContent += \ + """ + if (auto ConcreteTL = Object.getAs<clang::{0}>()) + GetLocations{1}({2}, ConcreteTL, Locs, Rngs {3}); + """.format(InheritanceMap[ASTClassName], baseTemplate, + CallPrefix, RecursionGuardParam) + + def GenerateDynNodeVisitor(self, CladeNames): MethodReturnType = 'NodeLocationAccessors' @@ -132,7 +288,13 @@ self.implementationContent += \ """ if (const auto *N = Node.get<{0}>()) - return GetLocations(const_cast<{0} *>(N));""".format(CladeName) + """.format(CladeName) + ArgPrefix = "" + if CladeName == "TypeLoc": + ArgPrefix = "*" + self.implementationContent += \ + """ + return GetLocations({0}const_cast<{1} *>(N));""".format(ArgPrefix, CladeName) self.implementationContent += '\nreturn {}; }' @@ -200,6 +362,10 @@ clang::CXXBaseSpecifier const*) { return {}; } +NodeLocationAccessors NodeIntrospection::GetLocations( + clang::TypeLoc const&) { + return {}; +} NodeLocationAccessors NodeIntrospection::GetLocations(clang::DynTypedNode const &) { return {}; @@ -209,19 +375,42 @@ """) sys.exit(0) - g = Generator() + templateClasses = [] + for (ClassName, ClassAccessors) in jsonData['classEntries'].items(): + if "templateParms" in ClassAccessors: + templateClasses.append(ClassName) + + g = Generator(templateClasses) g.GeneratePrologue() for (CladeName, ClassNameData) in jsonData['classesInClade'].items(): g.GenerateBaseGetLocationsDeclaration(CladeName) + def getCladeName(ClassName): + for (CladeName, ClassNameData) in jsonData['classesInClade'].items(): + if ClassName in ClassNameData: + return CladeName + for (ClassName, ClassAccessors) in jsonData['classEntries'].items(): - if ClassAccessors: - g.GenerateSrcLocMethod(ClassName, ClassAccessors) + cladeName = getCladeName(ClassName) + g.GenerateSrcLocMethod( + ClassName, ClassAccessors, + cladeName not in [ + 'NestedNameSpecifierLoc', + 'TemplateArgumentLoc', + 'TypeLoc']) for (CladeName, ClassNameData) in jsonData['classesInClade'].items(): - g.GenerateBaseGetLocationsFunction(ClassNameData, CladeName) + g.GenerateBaseGetLocationsFunction( + ClassNameData, + jsonData['classEntries'], + CladeName, + jsonData["classInheritance"], + CladeName not in [ + 'NestedNameSpecifierLoc', + 'TemplateArgumentLoc', + 'TypeLoc']) g.GenerateDynNodeVisitor(jsonData['classesInClade'].keys()) Index: clang/lib/Tooling/DumpTool/ASTSrcLocProcessor.h =================================================================== --- clang/lib/Tooling/DumpTool/ASTSrcLocProcessor.h +++ clang/lib/Tooling/DumpTool/ASTSrcLocProcessor.h @@ -35,7 +35,7 @@ private: void run(const ast_matchers::MatchFinder::MatchResult &Result) override; - llvm::StringMap<StringRef> ClassInheritance; + llvm::StringMap<std::string> ClassInheritance; llvm::StringMap<std::vector<StringRef>> ClassesInClade; llvm::StringMap<ClassData> ClassEntries; Index: clang/lib/Tooling/DumpTool/ASTSrcLocProcessor.cpp =================================================================== --- clang/lib/Tooling/DumpTool/ASTSrcLocProcessor.cpp +++ clang/lib/Tooling/DumpTool/ASTSrcLocProcessor.cpp @@ -22,18 +22,28 @@ 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")) - .bind("nodeClade")), - optionally(isDerivedFrom(cxxRecordDecl().bind("derivedFrom")))) - .bind("className"), + traverse( + TK_IgnoreUnlessSpelledInSource, + 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")), + this); + Finder->addMatcher( + traverse( + TK_IgnoreUnlessSpelledInSource, + cxxRecordDecl(isDefinition(), hasAnyName("clang::PointerLikeTypeLoc", + "clang::TypeofLikeTypeLoc")) + .bind("templateName")), this); } @@ -53,7 +63,7 @@ return JsonObj; } -llvm::json::Object toJSON(llvm::StringMap<StringRef> const &Obj) { +llvm::json::Object toJSON(llvm::StringMap<std::string> const &Obj) { using llvm::json::toJSON; llvm::json::Object JsonObj; @@ -70,6 +80,12 @@ JsonObj["sourceLocations"] = Obj.ASTClassLocations; if (!Obj.ASTClassRanges.empty()) JsonObj["sourceRanges"] = Obj.ASTClassRanges; + if (!Obj.TemplateParms.empty()) + JsonObj["templateParms"] = Obj.TemplateParms; + if (!Obj.TypeSourceInfos.empty()) + JsonObj["typeSourceInfos"] = Obj.TypeSourceInfos; + if (!Obj.TypeLocs.empty()) + JsonObj["typeLocs"] = Obj.TypeLocs; return JsonObj; } @@ -77,10 +93,8 @@ using llvm::json::toJSON; llvm::json::Object JsonObj; - for (const auto &Item : Obj) { - if (!Item.second.isEmpty()) - JsonObj[Item.first()] = ::toJSON(Item.second); - } + for (const auto &Item : Obj) + JsonObj[Item.first()] = ::toJSON(Item.second); return JsonObj; } @@ -127,28 +141,40 @@ equalsNode(ASTClass), optionally(isDerivedFrom( cxxRecordDecl(hasAnyName("clang::Stmt", "clang::Decl")) - .bind("stmtOrDeclBase"))))), + .bind("stmtOrDeclBase"))), + optionally(isDerivedFrom( + cxxRecordDecl(hasName("clang::Expr")).bind("exprBase"))), + optionally( + isDerivedFrom(cxxRecordDecl(hasName("clang::TypeLoc")) + .bind("typeLocBase"))))), 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. + const auto *StmtOrDeclBase = + BN.getNodeAs<clang::CXXRecordDecl>("stmtOrDeclBase"); + const auto *TypeLocBase = + BN.getNodeAs<clang::CXXRecordDecl>("typeLocBase"); + const auto *ExprBase = BN.getNodeAs<clang::CXXRecordDecl>("exprBase"); + // The clang AST has several methods on base classes which are overriden + // pseudo-virtually by derived classes. + // We record only the pseudo-virtual methods on the base classes to + // avoid duplication. if (StmtOrDeclBase && (Node->getName() == "getBeginLoc" || Node->getName() == "getEndLoc" || 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") { + if (ExprBase && Node->getName() == "getExprLoc") + continue; + if (TypeLocBase && Node->getName() == "getLocalSourceRange") + continue; + if ((ASTClass->getName() == "PointerLikeTypeLoc" || + ASTClass->getName() == "TypeofLikeTypeLoc") && + Node->getName() == "getLocalSourceRange") continue; - } Methods.push_back(Node->getName().str()); } } @@ -160,25 +186,64 @@ const auto *ASTClass = Result.Nodes.getNodeAs<clang::CXXRecordDecl>("className"); + StringRef CladeName; + if (ASTClass) { + if (const auto *NodeClade = + Result.Nodes.getNodeAs<clang::CXXRecordDecl>("nodeClade")) + CladeName = NodeClade->getName(); + } else { + ASTClass = Result.Nodes.getNodeAs<clang::CXXRecordDecl>("templateName"); + CladeName = "TypeLoc"; + } + StringRef ClassName = ASTClass->getName(); ClassData CD; - const auto *NodeClade = - Result.Nodes.getNodeAs<clang::CXXRecordDecl>("nodeClade"); - StringRef CladeName = NodeClade->getName(); - - if (const auto *DerivedFrom = - Result.Nodes.getNodeAs<clang::CXXRecordDecl>("derivedFrom")) - ClassInheritance[ClassName] = DerivedFrom->getName(); - CD.ASTClassLocations = CaptureMethods("class clang::SourceLocation", ASTClass, Result); CD.ASTClassRanges = CaptureMethods("class clang::SourceRange", ASTClass, Result); + CD.TypeSourceInfos = + CaptureMethods("class clang::TypeSourceInfo *", ASTClass, Result); + CD.TypeLocs = CaptureMethods("class clang::TypeLoc", ASTClass, Result); - if (!CD.isEmpty()) { - ClassEntries[ClassName] = CD; - ClassesInClade[CladeName].push_back(ClassName); + if (const auto *DerivedFrom = + Result.Nodes.getNodeAs<clang::CXXRecordDecl>("derivedFrom")) { + + if (const auto *Templ = + llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>( + DerivedFrom)) { + + const auto &TArgs = Templ->getTemplateArgs(); + + std::string TArgsString = (DerivedFrom->getName() + "<").str(); + + for (unsigned I = 0; I < TArgs.size(); ++I) { + if (I > 0) { + TArgsString += ", "; + } + auto Ty = TArgs.get(I).getAsType(); + clang::PrintingPolicy PPol(Result.Context->getLangOpts()); + PPol.TerseOutput = true; + TArgsString += Ty.getAsString(PPol); + } + TArgsString += ">"; + + ClassInheritance[ClassName] = std::move(TArgsString); + } else { + ClassInheritance[ClassName] = DerivedFrom->getName().str(); + } + } + + if (const auto *Templ = ASTClass->getDescribedClassTemplate()) { + if (auto *TParams = Templ->getTemplateParameters()) { + for (const auto &TParam : *TParams) { + CD.TemplateParms.push_back(TParam->getName().str()); + } + } } + + ClassEntries[ClassName] = CD; + ClassesInClade[CladeName].push_back(ClassName); } Index: clang/lib/Tooling/DumpTool/APIData.h =================================================================== --- clang/lib/Tooling/DumpTool/APIData.h +++ clang/lib/Tooling/DumpTool/APIData.h @@ -16,13 +16,11 @@ namespace tooling { struct ClassData { - - bool isEmpty() const { - return ASTClassLocations.empty() && ASTClassRanges.empty(); - } - std::vector<std::string> ASTClassLocations; std::vector<std::string> ASTClassRanges; + std::vector<std::string> TemplateParms; + std::vector<std::string> TypeSourceInfos; + std::vector<std::string> TypeLocs; // TODO: Extend this with locations available via typelocs etc. }; Index: clang/lib/Tooling/CMakeLists.txt =================================================================== --- clang/lib/Tooling/CMakeLists.txt +++ clang/lib/Tooling/CMakeLists.txt @@ -59,6 +59,10 @@ clang::CXXBaseSpecifier const*) { return {}; } +NodeLocationAccessors NodeIntrospection::GetLocations( + clang::TypeLoc 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 @@ -92,6 +92,7 @@ NodeLocationAccessors GetLocations(clang::NestedNameSpecifierLoc const *); NodeLocationAccessors GetLocations(clang::TemplateArgumentLoc const *); NodeLocationAccessors GetLocations(clang::CXXBaseSpecifier const *); +NodeLocationAccessors GetLocations(clang::TypeLoc const &); NodeLocationAccessors GetLocations(clang::DynTypedNode const &Node); } // namespace NodeIntrospection } // namespace tooling
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits