Add support for dumping Objective C AST declaration nodes to JSON.

llvm-svn: 361652
This commit is contained in:
Aaron Ballman 2019-05-24 17:39:55 +00:00
parent cebce0d49a
commit 4105882b87
3 changed files with 1872 additions and 4 deletions

View File

@ -218,6 +218,19 @@ public:
void VisitAccessSpecDecl(const AccessSpecDecl *ASD);
void VisitFriendDecl(const FriendDecl *FD);
void VisitObjCIvarDecl(const ObjCIvarDecl *D);
void VisitObjCMethodDecl(const ObjCMethodDecl *D);
void VisitObjCTypeParamDecl(const ObjCTypeParamDecl *D);
void VisitObjCCategoryDecl(const ObjCCategoryDecl *D);
void VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D);
void VisitObjCProtocolDecl(const ObjCProtocolDecl *D);
void VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D);
void VisitObjCImplementationDecl(const ObjCImplementationDecl *D);
void VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl *D);
void VisitObjCPropertyDecl(const ObjCPropertyDecl *D);
void VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D);
void VisitBlockDecl(const BlockDecl *D);
void VisitDeclRefExpr(const DeclRefExpr *DRE);
void VisitPredefinedExpr(const PredefinedExpr *PE);
void VisitUnaryOperator(const UnaryOperator *UO);

View File

@ -150,7 +150,15 @@ void JSONNodeDumper::Visit(const CXXCtorInitializer *Init) {
}
void JSONNodeDumper::Visit(const OMPClause *C) {}
void JSONNodeDumper::Visit(const BlockDecl::Capture &C) {}
void JSONNodeDumper::Visit(const BlockDecl::Capture &C) {
JOS.attribute("kind", "Capture");
attributeOnlyIfTrue("byref", C.isByRef());
attributeOnlyIfTrue("nested", C.isNested());
if (C.getVariable())
JOS.attribute("var", createBareDeclRef(C.getVariable()));
}
void JSONNodeDumper::Visit(const GenericSelectionExpr::ConstAssociation &A) {
JOS.attribute("associationKind", A.getTypeSourceInfo() ? "case" : "default");
attributeOnlyIfTrue("selected", A.isSelected());
@ -215,9 +223,11 @@ llvm::json::Object JSONNodeDumper::createQualType(QualType QT, bool Desugar) {
}
llvm::json::Object JSONNodeDumper::createBareDeclRef(const Decl *D) {
llvm::json::Object Ret{
{"id", createPointerRepresentation(D)},
{"kind", (llvm::Twine(D->getDeclKindName()) + "Decl").str()}};
llvm::json::Object Ret{{"id", createPointerRepresentation(D)}};
if (!D)
return Ret;
Ret["kind"] = (llvm::Twine(D->getDeclKindName()) + "Decl").str();
if (const auto *ND = dyn_cast<NamedDecl>(D))
Ret["name"] = ND->getDeclName().getAsString();
if (const auto *VD = dyn_cast<ValueDecl>(D))
@ -645,6 +655,147 @@ void JSONNodeDumper::VisitFriendDecl(const FriendDecl *FD) {
JOS.attribute("type", createQualType(T->getType()));
}
void JSONNodeDumper::VisitObjCIvarDecl(const ObjCIvarDecl *D) {
VisitNamedDecl(D);
JOS.attribute("type", createQualType(D->getType()));
attributeOnlyIfTrue("synthesized", D->getSynthesize());
switch (D->getAccessControl()) {
case ObjCIvarDecl::None: JOS.attribute("access", "none"); break;
case ObjCIvarDecl::Private: JOS.attribute("access", "private"); break;
case ObjCIvarDecl::Protected: JOS.attribute("access", "protected"); break;
case ObjCIvarDecl::Public: JOS.attribute("access", "public"); break;
case ObjCIvarDecl::Package: JOS.attribute("access", "package"); break;
}
}
void JSONNodeDumper::VisitObjCMethodDecl(const ObjCMethodDecl *D) {
VisitNamedDecl(D);
JOS.attribute("returnType", createQualType(D->getReturnType()));
JOS.attribute("instance", D->isInstanceMethod());
attributeOnlyIfTrue("variadic", D->isVariadic());
}
void JSONNodeDumper::VisitObjCTypeParamDecl(const ObjCTypeParamDecl *D) {
VisitNamedDecl(D);
JOS.attribute("type", createQualType(D->getUnderlyingType()));
attributeOnlyIfTrue("bounded", D->hasExplicitBound());
switch (D->getVariance()) {
case ObjCTypeParamVariance::Invariant:
break;
case ObjCTypeParamVariance::Covariant:
JOS.attribute("variance", "covariant");
break;
case ObjCTypeParamVariance::Contravariant:
JOS.attribute("variance", "contravariant");
break;
}
}
void JSONNodeDumper::VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
VisitNamedDecl(D);
JOS.attribute("interface", createBareDeclRef(D->getClassInterface()));
JOS.attribute("implementation", createBareDeclRef(D->getImplementation()));
llvm::json::Array Protocols;
for (const auto* P : D->protocols())
Protocols.push_back(createBareDeclRef(P));
if (!Protocols.empty())
JOS.attribute("protocols", std::move(Protocols));
}
void JSONNodeDumper::VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) {
VisitNamedDecl(D);
JOS.attribute("interface", createBareDeclRef(D->getClassInterface()));
JOS.attribute("categoryDecl", createBareDeclRef(D->getCategoryDecl()));
}
void JSONNodeDumper::VisitObjCProtocolDecl(const ObjCProtocolDecl *D) {
VisitNamedDecl(D);
llvm::json::Array Protocols;
for (const auto *P : D->protocols())
Protocols.push_back(createBareDeclRef(P));
if (!Protocols.empty())
JOS.attribute("protocols", std::move(Protocols));
}
void JSONNodeDumper::VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
VisitNamedDecl(D);
JOS.attribute("super", createBareDeclRef(D->getSuperClass()));
JOS.attribute("implementation", createBareDeclRef(D->getImplementation()));
llvm::json::Array Protocols;
for (const auto* P : D->protocols())
Protocols.push_back(createBareDeclRef(P));
if (!Protocols.empty())
JOS.attribute("protocols", std::move(Protocols));
}
void JSONNodeDumper::VisitObjCImplementationDecl(
const ObjCImplementationDecl *D) {
VisitNamedDecl(D);
JOS.attribute("super", createBareDeclRef(D->getSuperClass()));
JOS.attribute("interface", createBareDeclRef(D->getClassInterface()));
}
void JSONNodeDumper::VisitObjCCompatibleAliasDecl(
const ObjCCompatibleAliasDecl *D) {
VisitNamedDecl(D);
JOS.attribute("interface", createBareDeclRef(D->getClassInterface()));
}
void JSONNodeDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
VisitNamedDecl(D);
JOS.attribute("type", createQualType(D->getType()));
switch (D->getPropertyImplementation()) {
case ObjCPropertyDecl::None: break;
case ObjCPropertyDecl::Required: JOS.attribute("control", "required"); break;
case ObjCPropertyDecl::Optional: JOS.attribute("control", "optional"); break;
}
ObjCPropertyDecl::PropertyAttributeKind Attrs = D->getPropertyAttributes();
if (Attrs != ObjCPropertyDecl::OBJC_PR_noattr) {
if (Attrs & ObjCPropertyDecl::OBJC_PR_getter)
JOS.attribute("getter", createBareDeclRef(D->getGetterMethodDecl()));
if (Attrs & ObjCPropertyDecl::OBJC_PR_setter)
JOS.attribute("setter", createBareDeclRef(D->getSetterMethodDecl()));
attributeOnlyIfTrue("readonly", Attrs & ObjCPropertyDecl::OBJC_PR_readonly);
attributeOnlyIfTrue("assign", Attrs & ObjCPropertyDecl::OBJC_PR_assign);
attributeOnlyIfTrue("readwrite",
Attrs & ObjCPropertyDecl::OBJC_PR_readwrite);
attributeOnlyIfTrue("retain", Attrs & ObjCPropertyDecl::OBJC_PR_retain);
attributeOnlyIfTrue("copy", Attrs & ObjCPropertyDecl::OBJC_PR_copy);
attributeOnlyIfTrue("nonatomic",
Attrs & ObjCPropertyDecl::OBJC_PR_nonatomic);
attributeOnlyIfTrue("atomic", Attrs & ObjCPropertyDecl::OBJC_PR_atomic);
attributeOnlyIfTrue("weak", Attrs & ObjCPropertyDecl::OBJC_PR_weak);
attributeOnlyIfTrue("strong", Attrs & ObjCPropertyDecl::OBJC_PR_strong);
attributeOnlyIfTrue("unsafe_unretained",
Attrs & ObjCPropertyDecl::OBJC_PR_unsafe_unretained);
attributeOnlyIfTrue("class", Attrs & ObjCPropertyDecl::OBJC_PR_class);
attributeOnlyIfTrue("nullability",
Attrs & ObjCPropertyDecl::OBJC_PR_nullability);
attributeOnlyIfTrue("null_resettable",
Attrs & ObjCPropertyDecl::OBJC_PR_null_resettable);
}
}
void JSONNodeDumper::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
VisitNamedDecl(D->getPropertyDecl());
JOS.attribute("implKind", D->getPropertyImplementation() ==
ObjCPropertyImplDecl::Synthesize
? "synthesize"
: "dynamic");
JOS.attribute("propertyDecl", createBareDeclRef(D->getPropertyDecl()));
JOS.attribute("ivarDecl", createBareDeclRef(D->getPropertyIvarDecl()));
}
void JSONNodeDumper::VisitBlockDecl(const BlockDecl *D) {
attributeOnlyIfTrue("variadic", D->isVariadic());
attributeOnlyIfTrue("capturesThis", D->capturesCXXThis());
}
void JSONNodeDumper::VisitDeclRefExpr(const DeclRefExpr *DRE) {
JOS.attribute("referencedDecl", createBareDeclRef(DRE->getDecl()));
if (DRE->getDecl() != DRE->getFoundDecl())

File diff suppressed because it is too large Load Diff