forked from OSchip/llvm-project
Add support for dumping Objective C AST declaration nodes to JSON.
llvm-svn: 361652
This commit is contained in:
parent
cebce0d49a
commit
4105882b87
|
@ -218,6 +218,19 @@ public:
|
||||||
void VisitAccessSpecDecl(const AccessSpecDecl *ASD);
|
void VisitAccessSpecDecl(const AccessSpecDecl *ASD);
|
||||||
void VisitFriendDecl(const FriendDecl *FD);
|
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 VisitDeclRefExpr(const DeclRefExpr *DRE);
|
||||||
void VisitPredefinedExpr(const PredefinedExpr *PE);
|
void VisitPredefinedExpr(const PredefinedExpr *PE);
|
||||||
void VisitUnaryOperator(const UnaryOperator *UO);
|
void VisitUnaryOperator(const UnaryOperator *UO);
|
||||||
|
|
|
@ -150,7 +150,15 @@ void JSONNodeDumper::Visit(const CXXCtorInitializer *Init) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void JSONNodeDumper::Visit(const OMPClause *C) {}
|
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) {
|
void JSONNodeDumper::Visit(const GenericSelectionExpr::ConstAssociation &A) {
|
||||||
JOS.attribute("associationKind", A.getTypeSourceInfo() ? "case" : "default");
|
JOS.attribute("associationKind", A.getTypeSourceInfo() ? "case" : "default");
|
||||||
attributeOnlyIfTrue("selected", A.isSelected());
|
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 JSONNodeDumper::createBareDeclRef(const Decl *D) {
|
||||||
llvm::json::Object Ret{
|
llvm::json::Object Ret{{"id", createPointerRepresentation(D)}};
|
||||||
{"id", createPointerRepresentation(D)},
|
if (!D)
|
||||||
{"kind", (llvm::Twine(D->getDeclKindName()) + "Decl").str()}};
|
return Ret;
|
||||||
|
|
||||||
|
Ret["kind"] = (llvm::Twine(D->getDeclKindName()) + "Decl").str();
|
||||||
if (const auto *ND = dyn_cast<NamedDecl>(D))
|
if (const auto *ND = dyn_cast<NamedDecl>(D))
|
||||||
Ret["name"] = ND->getDeclName().getAsString();
|
Ret["name"] = ND->getDeclName().getAsString();
|
||||||
if (const auto *VD = dyn_cast<ValueDecl>(D))
|
if (const auto *VD = dyn_cast<ValueDecl>(D))
|
||||||
|
@ -645,6 +655,147 @@ void JSONNodeDumper::VisitFriendDecl(const FriendDecl *FD) {
|
||||||
JOS.attribute("type", createQualType(T->getType()));
|
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) {
|
void JSONNodeDumper::VisitDeclRefExpr(const DeclRefExpr *DRE) {
|
||||||
JOS.attribute("referencedDecl", createBareDeclRef(DRE->getDecl()));
|
JOS.attribute("referencedDecl", createBareDeclRef(DRE->getDecl()));
|
||||||
if (DRE->getDecl() != DRE->getFoundDecl())
|
if (DRE->getDecl() != DRE->getFoundDecl())
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue