forked from OSchip/llvm-project
[AST] Add DeclarationNameInfo to node introspection
Differential Revision: https://reviews.llvm.org/D101049
This commit is contained in:
parent
2149aa73f6
commit
a9676febb9
|
@ -26,6 +26,7 @@ class CXXCtorInitializer;
|
|||
class NestedNameSpecifierLoc;
|
||||
class TemplateArgumentLoc;
|
||||
class CXXBaseSpecifier;
|
||||
struct DeclarationNameInfo;
|
||||
|
||||
namespace tooling {
|
||||
|
||||
|
@ -92,6 +93,7 @@ NodeLocationAccessors GetLocations(clang::NestedNameSpecifierLoc const &);
|
|||
NodeLocationAccessors GetLocations(clang::TemplateArgumentLoc const &);
|
||||
NodeLocationAccessors GetLocations(clang::CXXBaseSpecifier const *);
|
||||
NodeLocationAccessors GetLocations(clang::TypeLoc const &);
|
||||
NodeLocationAccessors GetLocations(clang::DeclarationNameInfo const &);
|
||||
NodeLocationAccessors GetLocations(clang::DynTypedNode const &Node);
|
||||
} // namespace NodeIntrospection
|
||||
} // namespace tooling
|
||||
|
|
|
@ -22,7 +22,7 @@ struct ClassData {
|
|||
std::vector<std::string> TypeSourceInfos;
|
||||
std::vector<std::string> TypeLocs;
|
||||
std::vector<std::string> NestedNameLocs;
|
||||
// TODO: Extend this with locations available via typelocs etc.
|
||||
std::vector<std::string> DeclNameInfos;
|
||||
};
|
||||
|
||||
} // namespace tooling
|
||||
|
|
|
@ -23,19 +23,18 @@ ASTSrcLocProcessor::ASTSrcLocProcessor(StringRef JsonPath)
|
|||
|
||||
Finder = std::make_unique<MatchFinder>(std::move(FinderOptions));
|
||||
Finder->addMatcher(
|
||||
cxxRecordDecl(
|
||||
isDefinition(),
|
||||
isSameOrDerivedFrom(
|
||||
// TODO: Extend this with other clades
|
||||
namedDecl(hasAnyName("clang::Stmt", "clang::Decl",
|
||||
"clang::CXXCtorInitializer",
|
||||
"clang::NestedNameSpecifierLoc",
|
||||
"clang::TemplateArgumentLoc",
|
||||
"clang::CXXBaseSpecifier",
|
||||
"clang::TypeLoc"))
|
||||
.bind("nodeClade")),
|
||||
optionally(isDerivedFrom(cxxRecordDecl().bind("derivedFrom"))))
|
||||
.bind("className"),
|
||||
cxxRecordDecl(
|
||||
isDefinition(),
|
||||
isSameOrDerivedFrom(
|
||||
namedDecl(
|
||||
hasAnyName(
|
||||
"clang::Stmt", "clang::Decl", "clang::CXXCtorInitializer",
|
||||
"clang::NestedNameSpecifierLoc",
|
||||
"clang::TemplateArgumentLoc", "clang::CXXBaseSpecifier",
|
||||
"clang::DeclarationNameInfo", "clang::TypeLoc"))
|
||||
.bind("nodeClade")),
|
||||
optionally(isDerivedFrom(cxxRecordDecl().bind("derivedFrom"))))
|
||||
.bind("className"),
|
||||
this);
|
||||
Finder->addMatcher(
|
||||
cxxRecordDecl(isDefinition(), hasAnyName("clang::PointerLikeTypeLoc",
|
||||
|
@ -85,6 +84,8 @@ llvm::json::Object toJSON(ClassData const &Obj) {
|
|||
JsonObj["typeLocs"] = Obj.TypeLocs;
|
||||
if (!Obj.NestedNameLocs.empty())
|
||||
JsonObj["nestedNameLocs"] = Obj.NestedNameLocs;
|
||||
if (!Obj.DeclNameInfos.empty())
|
||||
JsonObj["declNameInfos"] = Obj.DeclNameInfos;
|
||||
return JsonObj;
|
||||
}
|
||||
|
||||
|
@ -222,6 +223,8 @@ void ASTSrcLocProcessor::run(const MatchFinder::MatchResult &Result) {
|
|||
CD.TypeLocs = CaptureMethods("class clang::TypeLoc", ASTClass, Result);
|
||||
CD.NestedNameLocs =
|
||||
CaptureMethods("class clang::NestedNameSpecifierLoc", ASTClass, Result);
|
||||
CD.DeclNameInfos =
|
||||
CaptureMethods("struct clang::DeclarationNameInfo", ASTClass, Result);
|
||||
|
||||
if (const auto *DerivedFrom =
|
||||
Result.Nodes.getNodeAs<clang::CXXRecordDecl>("derivedFrom")) {
|
||||
|
|
|
@ -12,7 +12,10 @@ class Generator(object):
|
|||
|
||||
implementationContent = ''
|
||||
|
||||
RefClades = {"NestedNameSpecifierLoc", "TemplateArgumentLoc", "TypeLoc"}
|
||||
RefClades = {"DeclarationNameInfo",
|
||||
"NestedNameSpecifierLoc",
|
||||
"TemplateArgumentLoc",
|
||||
"TypeLoc"}
|
||||
|
||||
def __init__(self, templateClasses):
|
||||
self.templateClasses = templateClasses
|
||||
|
@ -121,7 +124,8 @@ static void GetLocations{0}(SharedLocationCall const& Prefix,
|
|||
self.implementationContent += '\n'
|
||||
|
||||
if 'typeLocs' in ClassData or 'typeSourceInfos' in ClassData \
|
||||
or 'nestedNameLocs' in ClassData:
|
||||
or 'nestedNameLocs' in ClassData \
|
||||
or 'declNameInfos' in ClassData:
|
||||
if CreateLocalRecursionGuard:
|
||||
self.implementationContent += \
|
||||
'std::vector<clang::TypeLoc> TypeLocRecursionGuard;\n'
|
||||
|
@ -165,6 +169,15 @@ static void GetLocations{0}(SharedLocationCall const& Prefix,
|
|||
Object.{0}(), Locs, Rngs, TypeLocRecursionGuard);
|
||||
""".format(NN)
|
||||
|
||||
if 'declNameInfos' in ClassData:
|
||||
for declName in ClassData['declNameInfos']:
|
||||
|
||||
self.implementationContent += \
|
||||
"""
|
||||
GetLocationsImpl(
|
||||
llvm::makeIntrusiveRefCnt<LocationCall>(Prefix, "{0}"),
|
||||
Object.{0}(), Locs, Rngs, TypeLocRecursionGuard);
|
||||
""".format(declName)
|
||||
|
||||
self.implementationContent += '}\n'
|
||||
|
||||
|
@ -300,6 +313,8 @@ if (auto Derived = llvm::dyn_cast<clang::{0}>(Object)) {{
|
|||
+ ' NodeIntrospection::' + Signature + '{'
|
||||
|
||||
for CladeName in CladeNames:
|
||||
if CladeName == "DeclarationNameInfo":
|
||||
continue
|
||||
self.implementationContent += \
|
||||
"""
|
||||
if (const auto *N = Node.get<{0}>())
|
||||
|
@ -376,10 +391,7 @@ def main():
|
|||
cladeName = getCladeName(ClassName)
|
||||
g.GenerateSrcLocMethod(
|
||||
ClassName, ClassAccessors,
|
||||
cladeName not in [
|
||||
'NestedNameSpecifierLoc',
|
||||
'TemplateArgumentLoc',
|
||||
'TypeLoc'])
|
||||
cladeName not in Generator.RefClades)
|
||||
|
||||
for (CladeName, ClassNameData) in jsonData['classesInClade'].items():
|
||||
g.GenerateBaseGetLocationsFunction(
|
||||
|
@ -387,10 +399,7 @@ def main():
|
|||
jsonData['classEntries'],
|
||||
CladeName,
|
||||
jsonData["classInheritance"],
|
||||
CladeName not in [
|
||||
'NestedNameSpecifierLoc',
|
||||
'TemplateArgumentLoc',
|
||||
'TypeLoc'])
|
||||
CladeName not in Generator.RefClades)
|
||||
|
||||
g.GenerateDynNodeVisitor(jsonData['classesInClade'].keys())
|
||||
|
||||
|
|
|
@ -36,6 +36,10 @@ NodeLocationAccessors NodeIntrospection::GetLocations(
|
|||
clang::TypeLoc const&) {
|
||||
return {};
|
||||
}
|
||||
NodeLocationAccessors NodeIntrospection::GetLocations(
|
||||
clang::DeclarationNameInfo const&) {
|
||||
return {};
|
||||
}
|
||||
NodeLocationAccessors
|
||||
NodeIntrospection::GetLocations(clang::DynTypedNode const &) {
|
||||
return {};
|
||||
|
|
|
@ -216,6 +216,9 @@ STRING_LOCATION_STDPAIR(MethodDecl, getBodyRBrace()),
|
|||
STRING_LOCATION_STDPAIR(MethodDecl, getEndLoc()),
|
||||
STRING_LOCATION_STDPAIR(MethodDecl, getInnerLocStart()),
|
||||
STRING_LOCATION_STDPAIR(MethodDecl, getLocation()),
|
||||
STRING_LOCATION_STDPAIR(MethodDecl, getNameInfo().getBeginLoc()),
|
||||
STRING_LOCATION_STDPAIR(MethodDecl, getNameInfo().getEndLoc()),
|
||||
STRING_LOCATION_STDPAIR(MethodDecl, getNameInfo().getLoc()),
|
||||
STRING_LOCATION_STDPAIR(MethodDecl, getOuterLocStart()),
|
||||
STRING_LOCATION_STDPAIR(MethodDecl, getQualifierLoc().getBeginLoc()),
|
||||
STRING_LOCATION_STDPAIR(MethodDecl, getQualifierLoc().getEndLoc()),
|
||||
|
@ -305,6 +308,7 @@ STRING_LOCATION_STDPAIR(MethodDecl, getTypeSpecStartLoc())
|
|||
llvm::makeArrayRef(ExpectedRanges),
|
||||
(ArrayRef<std::pair<std::string, SourceRange>>{
|
||||
STRING_LOCATION_STDPAIR(MethodDecl, getExceptionSpecSourceRange()),
|
||||
STRING_LOCATION_STDPAIR(MethodDecl, getNameInfo().getSourceRange()),
|
||||
STRING_LOCATION_STDPAIR(MethodDecl, getParametersSourceRange()),
|
||||
STRING_LOCATION_STDPAIR(MethodDecl, getQualifierLoc().getLocalSourceRange()),
|
||||
STRING_LOCATION_STDPAIR(MethodDecl, getQualifierLoc().getPrefix().getLocalSourceRange()),
|
||||
|
@ -1395,3 +1399,142 @@ typeof (static_cast<void *>(0)) i;
|
|||
TL, getAs<clang::TypeOfExprTypeLoc>().getParensRange())));
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST(Introspection, SourceLocations_DeclarationNameInfo_Dtor) {
|
||||
if (!NodeIntrospection::hasIntrospectionSupport())
|
||||
return;
|
||||
auto AST =
|
||||
buildASTFromCode(R"cpp(
|
||||
class Foo
|
||||
{
|
||||
~Foo() {}
|
||||
};
|
||||
)cpp",
|
||||
"foo.cpp", std::make_shared<PCHContainerOperations>());
|
||||
auto &Ctx = AST->getASTContext();
|
||||
auto &TU = *Ctx.getTranslationUnitDecl();
|
||||
|
||||
auto BoundNodes = ast_matchers::match(
|
||||
decl(hasDescendant(cxxDestructorDecl(hasName("~Foo")).bind("dtor"))), TU,
|
||||
Ctx);
|
||||
|
||||
EXPECT_EQ(BoundNodes.size(), 1u);
|
||||
|
||||
const auto *Dtor = BoundNodes[0].getNodeAs<CXXDestructorDecl>("dtor");
|
||||
auto NI = Dtor->getNameInfo();
|
||||
auto Result = NodeIntrospection::GetLocations(NI);
|
||||
|
||||
auto ExpectedLocations =
|
||||
FormatExpected<SourceLocation>(Result.LocationAccessors);
|
||||
|
||||
llvm::sort(ExpectedLocations);
|
||||
|
||||
// clang-format off
|
||||
EXPECT_EQ(
|
||||
llvm::makeArrayRef(ExpectedLocations),
|
||||
(ArrayRef<std::pair<std::string, SourceLocation>>{
|
||||
STRING_LOCATION_STDPAIR((&NI), getBeginLoc()),
|
||||
STRING_LOCATION_STDPAIR((&NI), getEndLoc()),
|
||||
STRING_LOCATION_STDPAIR((&NI), getLoc()),
|
||||
STRING_LOCATION_STDPAIR((&NI),
|
||||
getNamedTypeInfo()->getTypeLoc().getAs<clang::TypeSpecTypeLoc>().getNameLoc()),
|
||||
STRING_LOCATION_STDPAIR(
|
||||
(&NI), getNamedTypeInfo()->getTypeLoc().getBeginLoc()),
|
||||
STRING_LOCATION_STDPAIR(
|
||||
(&NI), getNamedTypeInfo()->getTypeLoc().getEndLoc())}));
|
||||
// clang-format on
|
||||
|
||||
auto ExpectedRanges = FormatExpected<SourceRange>(Result.RangeAccessors);
|
||||
|
||||
EXPECT_THAT(
|
||||
ExpectedRanges,
|
||||
UnorderedElementsAre(
|
||||
STRING_LOCATION_PAIR(
|
||||
(&NI), getNamedTypeInfo()->getTypeLoc().getLocalSourceRange()),
|
||||
STRING_LOCATION_PAIR(
|
||||
(&NI), getNamedTypeInfo()->getTypeLoc().getSourceRange()),
|
||||
STRING_LOCATION_PAIR((&NI), getSourceRange())));
|
||||
}
|
||||
|
||||
TEST(Introspection, SourceLocations_DeclarationNameInfo_ConvOp) {
|
||||
if (!NodeIntrospection::hasIntrospectionSupport())
|
||||
return;
|
||||
auto AST =
|
||||
buildASTFromCode(R"cpp(
|
||||
class Foo
|
||||
{
|
||||
bool operator==(const Foo&) const { return false; }
|
||||
};
|
||||
)cpp",
|
||||
"foo.cpp", std::make_shared<PCHContainerOperations>());
|
||||
auto &Ctx = AST->getASTContext();
|
||||
auto &TU = *Ctx.getTranslationUnitDecl();
|
||||
|
||||
auto BoundNodes = ast_matchers::match(
|
||||
decl(hasDescendant(cxxMethodDecl().bind("opeq"))), TU, Ctx);
|
||||
|
||||
EXPECT_EQ(BoundNodes.size(), 1u);
|
||||
|
||||
const auto *Opeq = BoundNodes[0].getNodeAs<CXXMethodDecl>("opeq");
|
||||
auto NI = Opeq->getNameInfo();
|
||||
auto Result = NodeIntrospection::GetLocations(NI);
|
||||
|
||||
auto ExpectedLocations =
|
||||
FormatExpected<SourceLocation>(Result.LocationAccessors);
|
||||
|
||||
llvm::sort(ExpectedLocations);
|
||||
|
||||
EXPECT_EQ(llvm::makeArrayRef(ExpectedLocations),
|
||||
(ArrayRef<std::pair<std::string, SourceLocation>>{
|
||||
STRING_LOCATION_STDPAIR((&NI), getBeginLoc()),
|
||||
STRING_LOCATION_STDPAIR((&NI), getEndLoc()),
|
||||
STRING_LOCATION_STDPAIR((&NI), getLoc())}));
|
||||
|
||||
auto ExpectedRanges = FormatExpected<SourceRange>(Result.RangeAccessors);
|
||||
|
||||
EXPECT_THAT(ExpectedRanges,
|
||||
UnorderedElementsAre(
|
||||
STRING_LOCATION_PAIR((&NI), getSourceRange()),
|
||||
STRING_LOCATION_PAIR((&NI), getCXXOperatorNameRange())));
|
||||
}
|
||||
|
||||
TEST(Introspection, SourceLocations_DeclarationNameInfo_LitOp) {
|
||||
if (!NodeIntrospection::hasIntrospectionSupport())
|
||||
return;
|
||||
auto AST =
|
||||
buildASTFromCode(R"cpp(
|
||||
long double operator"" _identity ( long double val )
|
||||
{
|
||||
return val;
|
||||
}
|
||||
)cpp",
|
||||
"foo.cpp", std::make_shared<PCHContainerOperations>());
|
||||
auto &Ctx = AST->getASTContext();
|
||||
auto &TU = *Ctx.getTranslationUnitDecl();
|
||||
|
||||
auto BoundNodes = ast_matchers::match(
|
||||
decl(hasDescendant(functionDecl().bind("litop"))), TU, Ctx);
|
||||
|
||||
EXPECT_EQ(BoundNodes.size(), 1u);
|
||||
|
||||
const auto *LitOp = BoundNodes[0].getNodeAs<FunctionDecl>("litop");
|
||||
auto NI = LitOp->getNameInfo();
|
||||
auto Result = NodeIntrospection::GetLocations(NI);
|
||||
|
||||
auto ExpectedLocations =
|
||||
FormatExpected<SourceLocation>(Result.LocationAccessors);
|
||||
|
||||
llvm::sort(ExpectedLocations);
|
||||
|
||||
EXPECT_EQ(llvm::makeArrayRef(ExpectedLocations),
|
||||
(ArrayRef<std::pair<std::string, SourceLocation>>{
|
||||
STRING_LOCATION_STDPAIR((&NI), getBeginLoc()),
|
||||
STRING_LOCATION_STDPAIR((&NI), getCXXLiteralOperatorNameLoc()),
|
||||
STRING_LOCATION_STDPAIR((&NI), getEndLoc()),
|
||||
STRING_LOCATION_STDPAIR((&NI), getLoc())}));
|
||||
|
||||
auto ExpectedRanges = FormatExpected<SourceRange>(Result.RangeAccessors);
|
||||
|
||||
EXPECT_THAT(ExpectedRanges, UnorderedElementsAre(STRING_LOCATION_PAIR(
|
||||
(&NI), getSourceRange())));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue