Early-exitify ClangASTContext::AddObjCClassProperty() (NFC)

This commit is contained in:
Adrian Prantl 2019-11-21 15:40:50 -08:00
parent 7bf721e59c
commit bc8e88e974
1 changed files with 146 additions and 162 deletions

View File

@ -8339,189 +8339,173 @@ bool ClangASTContext::AddObjCClassProperty(
clang::ASTContext *clang_ast = ast->getASTContext();
clang::ObjCInterfaceDecl *class_interface_decl = GetAsObjCInterfaceDecl(type);
if (!class_interface_decl)
return false;
if (class_interface_decl) {
CompilerType property_clang_type_to_access;
CompilerType property_clang_type_to_access;
if (property_clang_type.IsValid())
property_clang_type_to_access = property_clang_type;
else if (ivar_decl)
property_clang_type_to_access =
CompilerType(ast, ivar_decl->getType().getAsOpaquePtr());
if (property_clang_type.IsValid())
property_clang_type_to_access = property_clang_type;
else if (ivar_decl)
property_clang_type_to_access =
CompilerType(ast, ivar_decl->getType().getAsOpaquePtr());
if (class_interface_decl && property_clang_type_to_access.IsValid()) {
clang::TypeSourceInfo *prop_type_source;
if (ivar_decl)
prop_type_source =
clang_ast->getTrivialTypeSourceInfo(ivar_decl->getType());
else
prop_type_source = clang_ast->getTrivialTypeSourceInfo(
ClangUtil::GetQualType(property_clang_type));
if (!class_interface_decl || !property_clang_type_to_access.IsValid())
return false;
clang::ObjCPropertyDecl *property_decl = clang::ObjCPropertyDecl::Create(
*clang_ast, class_interface_decl,
clang::SourceLocation(), // Source Location
&clang_ast->Idents.get(property_name),
clang::SourceLocation(), // Source Location for AT
clang::SourceLocation(), // Source location for (
ivar_decl ? ivar_decl->getType()
: ClangUtil::GetQualType(property_clang_type),
prop_type_source);
clang::TypeSourceInfo *prop_type_source;
if (ivar_decl)
prop_type_source =
clang_ast->getTrivialTypeSourceInfo(ivar_decl->getType());
else
prop_type_source = clang_ast->getTrivialTypeSourceInfo(
ClangUtil::GetQualType(property_clang_type));
if (property_decl) {
if (metadata)
ClangASTContext::SetMetadata(clang_ast, property_decl, *metadata);
clang::ObjCPropertyDecl *property_decl = clang::ObjCPropertyDecl::Create(
*clang_ast, class_interface_decl,
clang::SourceLocation(), // Source Location
&clang_ast->Idents.get(property_name),
clang::SourceLocation(), // Source Location for AT
clang::SourceLocation(), // Source location for (
ivar_decl ? ivar_decl->getType()
: ClangUtil::GetQualType(property_clang_type),
prop_type_source);
class_interface_decl->addDecl(property_decl);
if (!property_decl)
return false;
clang::Selector setter_sel, getter_sel;
if (metadata)
ClangASTContext::SetMetadata(clang_ast, property_decl, *metadata);
if (property_setter_name != nullptr) {
std::string property_setter_no_colon(
property_setter_name, strlen(property_setter_name) - 1);
clang::IdentifierInfo *setter_ident =
&clang_ast->Idents.get(property_setter_no_colon);
setter_sel = clang_ast->Selectors.getSelector(1, &setter_ident);
} else if (!(property_attributes & DW_APPLE_PROPERTY_readonly)) {
std::string setter_sel_string("set");
setter_sel_string.push_back(::toupper(property_name[0]));
setter_sel_string.append(&property_name[1]);
clang::IdentifierInfo *setter_ident =
&clang_ast->Idents.get(setter_sel_string);
setter_sel = clang_ast->Selectors.getSelector(1, &setter_ident);
}
property_decl->setSetterName(setter_sel);
property_decl->setPropertyAttributes(
clang::ObjCPropertyDecl::OBJC_PR_setter);
class_interface_decl->addDecl(property_decl);
if (property_getter_name != nullptr) {
clang::IdentifierInfo *getter_ident =
&clang_ast->Idents.get(property_getter_name);
getter_sel = clang_ast->Selectors.getSelector(0, &getter_ident);
} else {
clang::IdentifierInfo *getter_ident =
&clang_ast->Idents.get(property_name);
getter_sel = clang_ast->Selectors.getSelector(0, &getter_ident);
}
property_decl->setGetterName(getter_sel);
property_decl->setPropertyAttributes(
clang::ObjCPropertyDecl::OBJC_PR_getter);
clang::Selector setter_sel, getter_sel;
if (ivar_decl)
property_decl->setPropertyIvarDecl(ivar_decl);
if (property_setter_name) {
std::string property_setter_no_colon(property_setter_name,
strlen(property_setter_name) - 1);
clang::IdentifierInfo *setter_ident =
&clang_ast->Idents.get(property_setter_no_colon);
setter_sel = clang_ast->Selectors.getSelector(1, &setter_ident);
} else if (!(property_attributes & DW_APPLE_PROPERTY_readonly)) {
std::string setter_sel_string("set");
setter_sel_string.push_back(::toupper(property_name[0]));
setter_sel_string.append(&property_name[1]);
clang::IdentifierInfo *setter_ident =
&clang_ast->Idents.get(setter_sel_string);
setter_sel = clang_ast->Selectors.getSelector(1, &setter_ident);
}
property_decl->setSetterName(setter_sel);
property_decl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_setter);
if (property_attributes & DW_APPLE_PROPERTY_readonly)
property_decl->setPropertyAttributes(
clang::ObjCPropertyDecl::OBJC_PR_readonly);
if (property_attributes & DW_APPLE_PROPERTY_readwrite)
property_decl->setPropertyAttributes(
clang::ObjCPropertyDecl::OBJC_PR_readwrite);
if (property_attributes & DW_APPLE_PROPERTY_assign)
property_decl->setPropertyAttributes(
clang::ObjCPropertyDecl::OBJC_PR_assign);
if (property_attributes & DW_APPLE_PROPERTY_retain)
property_decl->setPropertyAttributes(
clang::ObjCPropertyDecl::OBJC_PR_retain);
if (property_attributes & DW_APPLE_PROPERTY_copy)
property_decl->setPropertyAttributes(
clang::ObjCPropertyDecl::OBJC_PR_copy);
if (property_attributes & DW_APPLE_PROPERTY_nonatomic)
property_decl->setPropertyAttributes(
clang::ObjCPropertyDecl::OBJC_PR_nonatomic);
if (property_attributes & clang::ObjCPropertyDecl::OBJC_PR_nullability)
property_decl->setPropertyAttributes(
clang::ObjCPropertyDecl::OBJC_PR_nullability);
if (property_attributes &
clang::ObjCPropertyDecl::OBJC_PR_null_resettable)
property_decl->setPropertyAttributes(
clang::ObjCPropertyDecl::OBJC_PR_null_resettable);
if (property_attributes & clang::ObjCPropertyDecl::OBJC_PR_class)
property_decl->setPropertyAttributes(
clang::ObjCPropertyDecl::OBJC_PR_class);
if (property_getter_name != nullptr) {
clang::IdentifierInfo *getter_ident =
&clang_ast->Idents.get(property_getter_name);
getter_sel = clang_ast->Selectors.getSelector(0, &getter_ident);
} else {
clang::IdentifierInfo *getter_ident = &clang_ast->Idents.get(property_name);
getter_sel = clang_ast->Selectors.getSelector(0, &getter_ident);
}
property_decl->setGetterName(getter_sel);
property_decl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_getter);
const bool isInstance =
(property_attributes & clang::ObjCPropertyDecl::OBJC_PR_class) == 0;
if (ivar_decl)
property_decl->setPropertyIvarDecl(ivar_decl);
if (!getter_sel.isNull() &&
!(isInstance
? class_interface_decl->lookupInstanceMethod(getter_sel)
: class_interface_decl->lookupClassMethod(getter_sel))) {
const bool isVariadic = false;
const bool isPropertyAccessor = false;
const bool isSynthesizedAccessorStub = false;
const bool isImplicitlyDeclared = true;
const bool isDefined = false;
const clang::ObjCMethodDecl::ImplementationControl impControl =
clang::ObjCMethodDecl::None;
const bool HasRelatedResultType = false;
if (property_attributes & DW_APPLE_PROPERTY_readonly)
property_decl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readonly);
if (property_attributes & DW_APPLE_PROPERTY_readwrite)
property_decl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readwrite);
if (property_attributes & DW_APPLE_PROPERTY_assign)
property_decl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_assign);
if (property_attributes & DW_APPLE_PROPERTY_retain)
property_decl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_retain);
if (property_attributes & DW_APPLE_PROPERTY_copy)
property_decl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_copy);
if (property_attributes & DW_APPLE_PROPERTY_nonatomic)
property_decl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_nonatomic);
if (property_attributes & ObjCPropertyDecl::OBJC_PR_nullability)
property_decl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_nullability);
if (property_attributes & ObjCPropertyDecl::OBJC_PR_null_resettable)
property_decl->setPropertyAttributes(
ObjCPropertyDecl::OBJC_PR_null_resettable);
if (property_attributes & ObjCPropertyDecl::OBJC_PR_class)
property_decl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_class);
clang::ObjCMethodDecl *getter = clang::ObjCMethodDecl::Create(
*clang_ast, clang::SourceLocation(), clang::SourceLocation(),
getter_sel, ClangUtil::GetQualType(property_clang_type_to_access),
nullptr, class_interface_decl, isInstance, isVariadic,
isPropertyAccessor, isSynthesizedAccessorStub,
isImplicitlyDeclared, isDefined, impControl,
HasRelatedResultType);
const bool isInstance =
(property_attributes & ObjCPropertyDecl::OBJC_PR_class) == 0;
if (getter && metadata)
ClangASTContext::SetMetadata(clang_ast, getter, *metadata);
if (!getter_sel.isNull() &&
!(isInstance ? class_interface_decl->lookupInstanceMethod(getter_sel)
: class_interface_decl->lookupClassMethod(getter_sel))) {
const bool isVariadic = false;
const bool isPropertyAccessor = false;
const bool isSynthesizedAccessorStub = false;
const bool isImplicitlyDeclared = true;
const bool isDefined = false;
const clang::ObjCMethodDecl::ImplementationControl impControl =
clang::ObjCMethodDecl::None;
const bool HasRelatedResultType = false;
if (getter) {
getter->setMethodParams(*clang_ast,
llvm::ArrayRef<clang::ParmVarDecl *>(),
llvm::ArrayRef<clang::SourceLocation>());
clang::ObjCMethodDecl *getter = clang::ObjCMethodDecl::Create(
*clang_ast, clang::SourceLocation(), clang::SourceLocation(),
getter_sel, ClangUtil::GetQualType(property_clang_type_to_access),
nullptr, class_interface_decl, isInstance, isVariadic,
isPropertyAccessor, isSynthesizedAccessorStub, isImplicitlyDeclared,
isDefined, impControl, HasRelatedResultType);
class_interface_decl->addDecl(getter);
}
}
if (getter && metadata)
ClangASTContext::SetMetadata(clang_ast, getter, *metadata);
if (!setter_sel.isNull() &&
!(isInstance
? class_interface_decl->lookupInstanceMethod(setter_sel)
: class_interface_decl->lookupClassMethod(setter_sel))) {
clang::QualType result_type = clang_ast->VoidTy;
const bool isVariadic = false;
const bool isPropertyAccessor = true;
const bool isSynthesizedAccessorStub = false;
const bool isImplicitlyDeclared = true;
const bool isDefined = false;
const clang::ObjCMethodDecl::ImplementationControl impControl =
clang::ObjCMethodDecl::None;
const bool HasRelatedResultType = false;
if (getter) {
getter->setMethodParams(*clang_ast,
llvm::ArrayRef<clang::ParmVarDecl *>(),
llvm::ArrayRef<clang::SourceLocation>());
clang::ObjCMethodDecl *setter = clang::ObjCMethodDecl::Create(
*clang_ast, clang::SourceLocation(), clang::SourceLocation(),
setter_sel, result_type, nullptr, class_interface_decl,
isInstance, isVariadic, isPropertyAccessor,
isSynthesizedAccessorStub, isImplicitlyDeclared, isDefined,
impControl, HasRelatedResultType);
if (setter && metadata)
ClangASTContext::SetMetadata(clang_ast, setter, *metadata);
llvm::SmallVector<clang::ParmVarDecl *, 1> params;
params.push_back(clang::ParmVarDecl::Create(
*clang_ast, setter, clang::SourceLocation(),
clang::SourceLocation(),
nullptr, // anonymous
ClangUtil::GetQualType(property_clang_type_to_access), nullptr,
clang::SC_Auto, nullptr));
if (setter) {
setter->setMethodParams(
*clang_ast, llvm::ArrayRef<clang::ParmVarDecl *>(params),
llvm::ArrayRef<clang::SourceLocation>());
class_interface_decl->addDecl(setter);
}
}
return true;
}
class_interface_decl->addDecl(getter);
}
}
return false;
if (!setter_sel.isNull() &&
!(isInstance ? class_interface_decl->lookupInstanceMethod(setter_sel)
: class_interface_decl->lookupClassMethod(setter_sel))) {
clang::QualType result_type = clang_ast->VoidTy;
const bool isVariadic = false;
const bool isPropertyAccessor = true;
const bool isSynthesizedAccessorStub = false;
const bool isImplicitlyDeclared = true;
const bool isDefined = false;
const clang::ObjCMethodDecl::ImplementationControl impControl =
clang::ObjCMethodDecl::None;
const bool HasRelatedResultType = false;
clang::ObjCMethodDecl *setter = clang::ObjCMethodDecl::Create(
*clang_ast, clang::SourceLocation(), clang::SourceLocation(),
setter_sel, result_type, nullptr, class_interface_decl, isInstance,
isVariadic, isPropertyAccessor, isSynthesizedAccessorStub,
isImplicitlyDeclared, isDefined, impControl, HasRelatedResultType);
if (setter && metadata)
ClangASTContext::SetMetadata(clang_ast, setter, *metadata);
llvm::SmallVector<clang::ParmVarDecl *, 1> params;
params.push_back(clang::ParmVarDecl::Create(
*clang_ast, setter, clang::SourceLocation(), clang::SourceLocation(),
nullptr, // anonymous
ClangUtil::GetQualType(property_clang_type_to_access), nullptr,
clang::SC_Auto, nullptr));
if (setter) {
setter->setMethodParams(*clang_ast,
llvm::ArrayRef<clang::ParmVarDecl *>(params),
llvm::ArrayRef<clang::SourceLocation>());
class_interface_decl->addDecl(setter);
}
}
return true;
}
bool ClangASTContext::IsObjCClassTypeAndHasIVars(const CompilerType &type,