diff --git a/clang/include/clang/Tooling/NodeIntrospection.h b/clang/include/clang/Tooling/NodeIntrospection.h --- a/clang/include/clang/Tooling/NodeIntrospection.h +++ b/clang/include/clang/Tooling/NodeIntrospection.h @@ -86,6 +86,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 diff --git a/clang/lib/Tooling/CMakeLists.txt b/clang/lib/Tooling/CMakeLists.txt --- a/clang/lib/Tooling/CMakeLists.txt +++ b/clang/lib/Tooling/CMakeLists.txt @@ -58,6 +58,10 @@ clang::CXXBaseSpecifier const*) { return {}; } +NodeLocationAccessors NodeIntrospection::GetLocations( + clang::TypeLoc const&) { + return {}; +} NodeLocationAccessors NodeIntrospection::GetLocations(clang::DynTypedNode const &) { return {}; diff --git a/clang/lib/Tooling/DumpTool/APIData.h b/clang/lib/Tooling/DumpTool/APIData.h --- a/clang/lib/Tooling/DumpTool/APIData.h +++ b/clang/lib/Tooling/DumpTool/APIData.h @@ -16,13 +16,11 @@ namespace tooling { struct ClassData { - - bool isEmpty() const { - return ASTClassLocations.empty() && ASTClassRanges.empty(); - } - std::vector ASTClassLocations; std::vector ASTClassRanges; + std::vector TemplateParms; + std::vector TypeSourceInfos; + std::vector TypeLocs; // TODO: Extend this with locations available via typelocs etc. }; diff --git a/clang/lib/Tooling/DumpTool/ASTSrcLocProcessor.h b/clang/lib/Tooling/DumpTool/ASTSrcLocProcessor.h --- a/clang/lib/Tooling/DumpTool/ASTSrcLocProcessor.h +++ b/clang/lib/Tooling/DumpTool/ASTSrcLocProcessor.h @@ -35,7 +35,11 @@ private: void run(const ast_matchers::MatchFinder::MatchResult &Result) override; - llvm::StringMap ClassInheritance; + llvm::Optional getCheckTraversalKind() const override { + return TK_IgnoreUnlessSpelledInSource; + } + + llvm::StringMap ClassInheritance; llvm::StringMap> ClassesInClade; llvm::StringMap ClassEntries; diff --git a/clang/lib/Tooling/DumpTool/ASTSrcLocProcessor.cpp b/clang/lib/Tooling/DumpTool/ASTSrcLocProcessor.cpp --- a/clang/lib/Tooling/DumpTool/ASTSrcLocProcessor.cpp +++ b/clang/lib/Tooling/DumpTool/ASTSrcLocProcessor.cpp @@ -22,18 +22,24 @@ Finder = std::make_unique(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"), + 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( + cxxRecordDecl(isDefinition(), hasAnyName("clang::PointerLikeTypeLoc", + "clang::TypeofLikeTypeLoc")) + .bind("templateName"), this); } @@ -53,7 +59,7 @@ return JsonObj; } -llvm::json::Object toJSON(llvm::StringMap const &Obj) { +llvm::json::Object toJSON(llvm::StringMap const &Obj) { using llvm::json::toJSON; llvm::json::Object JsonObj; @@ -70,6 +76,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 +89,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 +137,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 Methods; for (const auto &BN : BoundNodesVec) { - const auto *StmtOrDeclBase = - BN.getNodeAs("stmtOrDeclBase"); if (const auto *Node = BN.getNodeAs("classMethod")) { - // Only record the getBeginLoc etc on Stmt etc, because it will call - // more-derived implementations pseudo-virtually. + const auto *StmtOrDeclBase = + BN.getNodeAs("stmtOrDeclBase"); + const auto *TypeLocBase = + BN.getNodeAs("typeLocBase"); + const auto *ExprBase = BN.getNodeAs("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 +182,64 @@ const auto *ASTClass = Result.Nodes.getNodeAs("className"); + StringRef CladeName; + if (ASTClass) { + if (const auto *NodeClade = + Result.Nodes.getNodeAs("nodeClade")) + CladeName = NodeClade->getName(); + } else { + ASTClass = Result.Nodes.getNodeAs("templateName"); + CladeName = "TypeLoc"; + } + StringRef ClassName = ASTClass->getName(); ClassData CD; - const auto *NodeClade = - Result.Nodes.getNodeAs("nodeClade"); - StringRef CladeName = NodeClade->getName(); - - if (const auto *DerivedFrom = - Result.Nodes.getNodeAs("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("derivedFrom")) { + + if (const auto *Templ = + llvm::dyn_cast( + 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); } diff --git a/clang/lib/Tooling/DumpTool/generate_cxx_src_locs.py b/clang/lib/Tooling/DumpTool/generate_cxx_src_locs.py --- a/clang/lib/Tooling/DumpTool/generate_cxx_src_locs.py +++ b/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 &TypeLocRecursionGuard) + : TLRG(TypeLocRecursionGuard) + { + + } + + ~RecursionPopper() + { + TLRG.pop_back(); + } + +private: +std::vector &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 &TypeLocRecursionGuard); +""".format(CladeName, InstanceDecoration) + + def GenerateSrcLocMethod(self, + ClassName, ClassData, CreateLocalRecursionGuard): + + NormalClassName = ClassName + RecursionGuardParam = ('' if CreateLocalRecursionGuard else \ + ', std::vector& TypeLocRecursionGuard') + + if "templateParms" in ClassData: + TemplatePreamble = "template TypeLocRecursionGuard;\n' + + self.implementationContent += '\n' + + if 'typeLocs' in ClassData: + for typeLoc in ClassData['typeLocs']: + + self.implementationContent += \ + """ + if (Object.{0}()) {{ + GetLocationsImpl( + llvm::makeIntrusiveRefCnt(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( + llvm::makeIntrusiveRefCnt(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 &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()) { + auto Dequalified = QTL.getNextTypeLoc(); + return GetLocationsImpl(llvm::makeIntrusiveRefCnt(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(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 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(Prefix, + "getAs", LocationCall::IsCast) + '''.format(ASTClassName) + + if ASTClassName in ClassEntries: + + self.implementationContent += \ + """ + if (auto ConcreteTL = Object.getAs()) + 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()) + 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()) diff --git a/clang/unittests/Introspection/IntrospectionTest.cpp b/clang/unittests/Introspection/IntrospectionTest.cpp --- a/clang/unittests/Introspection/IntrospectionTest.cpp +++ b/clang/unittests/Introspection/IntrospectionTest.cpp @@ -26,25 +26,27 @@ using ::testing::Pair; using ::testing::UnorderedElementsAre; -template -std::map +template +std::vector> FormatExpected(const MapType &Accessors) { - std::map Result; + std::vector> 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 '->'. @@ -191,26 +193,85 @@ auto ExpectedLocations = FormatExpected(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( + llvm::makeArrayRef(ExpectedLocations), + (ArrayRef>{ +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().getLParenLoc()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs().getLocalRangeBegin()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs().getLocalRangeEnd()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs().getRParenLoc()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs().getReturnLoc().getAs().getNamedTypeLoc().getAs().getLAngleLoc()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs().getReturnLoc().getAs().getNamedTypeLoc().getAs().getRAngleLoc()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs().getReturnLoc().getAs().getNamedTypeLoc().getAs().getTemplateNameLoc()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs().getReturnLoc().getAs().getNamedTypeLoc().getBeginLoc()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs().getReturnLoc().getAs().getNamedTypeLoc().getEndLoc()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs().getReturnLoc().getBeginLoc()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs().getReturnLoc().getEndLoc()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs().getReturnLoc().getNextTypeLoc().getAs().getLAngleLoc()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs().getReturnLoc().getNextTypeLoc().getAs().getRAngleLoc()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs().getReturnLoc().getNextTypeLoc().getAs().getTemplateNameLoc()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs().getReturnLoc().getNextTypeLoc().getBeginLoc()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs().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().getNamedTypeLoc().getAs().getLAngleLoc()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getAs().getNamedTypeLoc().getAs().getRAngleLoc()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getAs().getNamedTypeLoc().getAs().getTemplateNameLoc()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getAs().getNamedTypeLoc().getBeginLoc()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getAs().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().getLAngleLoc()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getNextTypeLoc().getAs().getRAngleLoc()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getNextTypeLoc().getAs().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(Result.RangeAccessors); - EXPECT_THAT( - ExpectedRanges, - UnorderedElementsAre( - STRING_LOCATION_PAIR(MethodDecl, getExceptionSpecSourceRange()), - STRING_LOCATION_PAIR(MethodDecl, getParametersSourceRange()), - STRING_LOCATION_PAIR(MethodDecl, getReturnTypeSourceRange()), - STRING_LOCATION_PAIR(MethodDecl, getSourceRange()))); + llvm::sort(ExpectedRanges, [](const auto &LHS, const auto &RHS) { + return LHS.first < RHS.first; + }); + + // clang-format off + EXPECT_EQ( + llvm::makeArrayRef(ExpectedRanges), + (ArrayRef>{ +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().getExceptionSpecRange()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs().getParensRange()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs().getReturnLoc().getAs().getNamedTypeLoc().getLocalSourceRange()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs().getReturnLoc().getAs().getNamedTypeLoc().getSourceRange()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs().getReturnLoc().getLocalSourceRange()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs().getReturnLoc().getNextTypeLoc().getLocalSourceRange()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs().getReturnLoc().getNextTypeLoc().getSourceRange()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs().getReturnLoc().getSourceRange()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getLocalSourceRange()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getAs().getNamedTypeLoc().getLocalSourceRange()), +STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getAs().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) { @@ -244,17 +305,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().getNameLoc()), + STRING_LOCATION_PAIR(NNS, getTypeLoc().getBeginLoc()), + STRING_LOCATION_PAIR(NNS, getTypeLoc().getEndLoc()))); auto ExpectedRanges = FormatExpected(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) { @@ -288,13 +357,31 @@ auto ExpectedLocations = FormatExpected(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().getBuiltinLoc()), +STRING_LOCATION_PAIR(TA, + getTypeSourceInfo()->getTypeLoc().getAs().getNameLoc()), +STRING_LOCATION_PAIR( + TA, getTypeSourceInfo()->getTypeLoc().getBeginLoc()), +STRING_LOCATION_PAIR( + TA, getTypeSourceInfo()->getTypeLoc().getEndLoc()) + )); + // clang-format on auto ExpectedRanges = FormatExpected(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) { @@ -546,13 +633,31 @@ auto ExpectedLocations = FormatExpected(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().getBuiltinLoc()), +STRING_LOCATION_PAIR(TA, + getTypeSourceInfo()->getTypeLoc().getAs().getNameLoc()), +STRING_LOCATION_PAIR( + TA, getTypeSourceInfo()->getTypeLoc().getBeginLoc()), +STRING_LOCATION_PAIR( + TA, getTypeSourceInfo()->getTypeLoc().getEndLoc()) + )); + // clang-format on auto ExpectedRanges = FormatExpected(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) { @@ -585,16 +690,34 @@ auto ExpectedLocations = FormatExpected(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().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().getNameLoc()), +STRING_LOCATION_PAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getBeginLoc()), +STRING_LOCATION_PAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getEndLoc()) + )); + // clang-format on auto ExpectedRanges = FormatExpected(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) { @@ -666,16 +789,33 @@ auto ExpectedLocations = FormatExpected(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().getNameLoc()) + )); + // clang-format on auto ExpectedRanges = FormatExpected(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) { @@ -711,18 +851,44 @@ auto ExpectedLocations = FormatExpected(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( + llvm::makeArrayRef(ExpectedLocations), + (ArrayRef>{ +STRING_LOCATION_STDPAIR(CtorInit, getBaseClassLoc().getAs().getLAngleLoc()), +STRING_LOCATION_STDPAIR(CtorInit, getBaseClassLoc().getAs().getRAngleLoc()), +STRING_LOCATION_STDPAIR(CtorInit, getBaseClassLoc().getAs().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().getLAngleLoc()), +STRING_LOCATION_STDPAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getAs().getRAngleLoc()), +STRING_LOCATION_STDPAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getAs().getTemplateNameLoc()), +STRING_LOCATION_STDPAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getBeginLoc()), +STRING_LOCATION_STDPAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getEndLoc()) + })); + // clang-format on auto ExpectedRanges = FormatExpected(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) { @@ -751,15 +917,27 @@ auto ExpectedLocations = FormatExpected(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().getNameLoc()), +STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getEndLoc()), +STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getBeginLoc()) + )); + // clang-format on auto ExpectedRanges = FormatExpected(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) { @@ -788,15 +966,27 @@ auto ExpectedLocations = FormatExpected(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().getNameLoc()), +STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getEndLoc()), +STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getBeginLoc()) + )); + // clang-format on auto ExpectedRanges = FormatExpected(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) { @@ -826,15 +1016,27 @@ auto ExpectedLocations = FormatExpected(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().getNameLoc()), +STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getEndLoc()) + )); + // clang-format on auto ExpectedRanges = FormatExpected(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) { @@ -864,15 +1066,29 @@ auto ExpectedLocations = FormatExpected(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().getTemplateNameLoc()), +STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getAs().getLAngleLoc()), +STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getEndLoc()), +STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getAs().getRAngleLoc()) + )); + // clang-format on auto ExpectedRanges = FormatExpected(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) { @@ -903,14 +1119,203 @@ auto ExpectedLocations = FormatExpected(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().getNameLoc()), +STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getBeginLoc()) + )); + // clang-format on auto ExpectedRanges = FormatExpected(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()); + 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("tl"); + auto Result = NodeIntrospection::GetLocations(*TL); + + if (Result.LocationAccessors.empty() && Result.RangeAccessors.empty()) { + return; + } + + auto ExpectedLocations = + FormatExpected(Result.LocationAccessors); + + llvm::sort(ExpectedLocations); + + // clang-format off + EXPECT_EQ( + llvm::makeArrayRef(ExpectedLocations), + (ArrayRef>{ +STRING_LOCATION_STDPAIR(TL, getAs().getLParenLoc()), +STRING_LOCATION_STDPAIR(TL, getAs().getLocalRangeBegin()), +STRING_LOCATION_STDPAIR(TL, getAs().getLocalRangeEnd()), +STRING_LOCATION_STDPAIR(TL, getAs().getRParenLoc()), +STRING_LOCATION_STDPAIR(TL, getAs().getReturnLoc().getAs().getBuiltinLoc()), +STRING_LOCATION_STDPAIR(TL, getAs().getReturnLoc().getAs().getNameLoc()), +STRING_LOCATION_STDPAIR(TL, getAs().getReturnLoc().getBeginLoc()), +STRING_LOCATION_STDPAIR(TL, getAs().getReturnLoc().getEndLoc()), +STRING_LOCATION_STDPAIR(TL, getBeginLoc()), +STRING_LOCATION_STDPAIR(TL, getEndLoc()), +STRING_LOCATION_STDPAIR(TL, getNextTypeLoc().getAs().getBuiltinLoc()), +STRING_LOCATION_STDPAIR(TL, getNextTypeLoc().getAs().getNameLoc()), +STRING_LOCATION_STDPAIR(TL, getNextTypeLoc().getBeginLoc()), +STRING_LOCATION_STDPAIR(TL, getNextTypeLoc().getEndLoc()) + })); + // clang-format on + + auto ExpectedRanges = FormatExpected(Result.RangeAccessors); + + // clang-format off + EXPECT_THAT( + ExpectedRanges, + UnorderedElementsAre( +STRING_LOCATION_PAIR(TL, getAs().getParensRange()), +STRING_LOCATION_PAIR(TL, getAs().getReturnLoc().getLocalSourceRange()), +STRING_LOCATION_PAIR(TL, getAs().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()); + 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("tl"); + auto Result = NodeIntrospection::GetLocations(*TL); + + if (Result.LocationAccessors.empty() && Result.RangeAccessors.empty()) { + return; + } + + auto ExpectedLocations = + FormatExpected(Result.LocationAccessors); + + llvm::sort(ExpectedLocations); + + // clang-format off + EXPECT_EQ( + llvm::makeArrayRef(ExpectedLocations), + (ArrayRef>{ +STRING_LOCATION_STDPAIR(TL, getAs().getPointeeLoc().getAs().getBuiltinLoc()), +STRING_LOCATION_STDPAIR(TL, getAs().getPointeeLoc().getAs().getNameLoc()), +STRING_LOCATION_STDPAIR(TL, getAs().getPointeeLoc().getBeginLoc()), +STRING_LOCATION_STDPAIR(TL, getAs().getPointeeLoc().getEndLoc()), +STRING_LOCATION_STDPAIR(TL, getAs().getSigilLoc()), +STRING_LOCATION_STDPAIR(TL, getAs().getStarLoc()), +STRING_LOCATION_STDPAIR(TL, getBeginLoc()), +STRING_LOCATION_STDPAIR(TL, getEndLoc()), +STRING_LOCATION_STDPAIR(TL, getNextTypeLoc().getAs().getBuiltinLoc()), +STRING_LOCATION_STDPAIR(TL, getNextTypeLoc().getAs().getNameLoc()), +STRING_LOCATION_STDPAIR(TL, getNextTypeLoc().getBeginLoc()), +STRING_LOCATION_STDPAIR(TL, getNextTypeLoc().getEndLoc()) +})); + // clang-format on + + auto ExpectedRanges = FormatExpected(Result.RangeAccessors); + + // clang-format off + EXPECT_THAT( + ExpectedRanges, + UnorderedElementsAre( +STRING_LOCATION_PAIR(TL, getAs().getPointeeLoc().getLocalSourceRange()), +STRING_LOCATION_PAIR(TL, getAs().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(0)) i; +)cpp", + "foo.cpp", std::make_shared()); + 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("tl"); + auto Result = NodeIntrospection::GetLocations(*TL); + + if (Result.LocationAccessors.empty() && Result.RangeAccessors.empty()) { + return; + } + + auto ExpectedLocations = + FormatExpected(Result.LocationAccessors); + + EXPECT_THAT(ExpectedLocations, + UnorderedElementsAre( + STRING_LOCATION_PAIR(TL, getBeginLoc()), + STRING_LOCATION_PAIR(TL, getEndLoc()), + STRING_LOCATION_PAIR( + TL, getAs().getTypeofLoc()), + STRING_LOCATION_PAIR( + TL, getAs().getLParenLoc()), + STRING_LOCATION_PAIR( + TL, getAs().getRParenLoc()))); + + auto ExpectedRanges = FormatExpected(Result.RangeAccessors); + + EXPECT_THAT(ExpectedRanges, + UnorderedElementsAre( + STRING_LOCATION_PAIR(TL, getLocalSourceRange()), + STRING_LOCATION_PAIR(TL, getSourceRange()), + STRING_LOCATION_PAIR( + TL, getAs().getParensRange()))); } +#endif