mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-10 10:01:42 +00:00
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 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);
|
||||
|
@ -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())
|
||||
|
1704
clang/test/AST/ast-dump-decl-json.m
Normal file
1704
clang/test/AST/ast-dump-decl-json.m
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user