forked from OSchip/llvm-project
Implement synthesizing properties by default.
This is a non-fragile-abi feature only. Since it breaks existing code, it is currently placed under -fobjc-nonfragile-abi2 option for test purposes only until further notice. WIP. llvm-svn: 95685
This commit is contained in:
parent
f3a499ad88
commit
4587803919
|
@ -109,6 +109,10 @@ def warn_pch_objective_c2 : Error<
|
|||
def warn_pch_nonfragile_abi : Error<
|
||||
"PCH file was compiled with the %select{32-bit|non-fragile}0 Objective-C "
|
||||
"ABI but the %select{32-bit|non-fragile}1 Objective-C ABI is selected">;
|
||||
def warn_pch_nonfragile_abi2 : Error<
|
||||
"PCH file was compiled with the %select{32-bit|enhanced non-fragile}0 "
|
||||
"Objective-C ABI but the %select{32-bit|enhanced non-fragile}1 "
|
||||
"Objective-C ABI is selected">;
|
||||
def warn_pch_extensions : Error<
|
||||
"extensions were %select{enabled|disabled}0 in PCH file but are "
|
||||
"currently %select{enabled|disabled}1">;
|
||||
|
|
|
@ -40,6 +40,7 @@ public:
|
|||
unsigned ObjC1 : 1; // Objective-C 1 support enabled.
|
||||
unsigned ObjC2 : 1; // Objective-C 2 support enabled.
|
||||
unsigned ObjCNonFragileABI : 1; // Objective-C modern abi enabled
|
||||
unsigned ObjCNonFragileABI2 : 1; // Objective-C enhanced modern abi enabled
|
||||
|
||||
unsigned PascalStrings : 1; // Allow Pascal strings
|
||||
unsigned WritableStrings : 1; // Allow writable strings
|
||||
|
@ -124,7 +125,7 @@ public:
|
|||
Trigraphs = BCPLComment = Bool = DollarIdents = AsmPreprocessor = 0;
|
||||
GNUMode = ImplicitInt = Digraphs = 0;
|
||||
HexFloats = 0;
|
||||
GC = ObjC1 = ObjC2 = ObjCNonFragileABI = 0;
|
||||
GC = ObjC1 = ObjC2 = ObjCNonFragileABI = ObjCNonFragileABI2 = 0;
|
||||
C99 = Microsoft = CPlusPlus = CPlusPlus0x = 0;
|
||||
CXXOperatorNames = PascalStrings = WritableStrings = 0;
|
||||
Exceptions = Freestanding = NoBuiltin = 0;
|
||||
|
|
|
@ -360,6 +360,8 @@ def print_ivar_layout : Flag<"-print-ivar-layout">,
|
|||
HelpText<"Enable Objective-C Ivar layout bitmap print trace">;
|
||||
def fobjc_nonfragile_abi : Flag<"-fobjc-nonfragile-abi">,
|
||||
HelpText<"enable objective-c's nonfragile abi">;
|
||||
def fobjc_nonfragile_abi2 : Flag<"-fobjc-nonfragile-abi2">,
|
||||
HelpText<"enable objective-c's enhanced nonfragile abi">;
|
||||
def ftrapv : Flag<"-ftrapv">,
|
||||
HelpText<"Trap on integer overflow">;
|
||||
def pic_level : Separate<"-pic-level">,
|
||||
|
|
|
@ -323,6 +323,7 @@ def fobjc_gc : Flag<"-fobjc-gc">, Group<f_Group>;
|
|||
def fobjc_legacy_dispatch : Flag<"-fobjc-legacy-dispatch">, Group<f_Group>;
|
||||
def fobjc_new_property : Flag<"-fobjc-new-property">, Group<clang_ignored_f_Group>;
|
||||
def fobjc_nonfragile_abi : Flag<"-fobjc-nonfragile-abi">, Group<f_Group>;
|
||||
def fobjc_nonfragile_abi2 : Flag<"-fobjc-nonfragile-abi2">, Group<f_Group>;
|
||||
def fobjc_sender_dependent_dispatch : Flag<"-fobjc-sender-dependent-dispatch">, Group<f_Group>;
|
||||
def fobjc : Flag<"-fobjc">, Group<f_Group>;
|
||||
def fomit_frame_pointer : Flag<"-fomit-frame-pointer">, Group<f_Group>;
|
||||
|
|
|
@ -459,6 +459,8 @@ static void LangOptsToArgs(const LangOptions &Opts,
|
|||
Res.push_back("-fms-extensions");
|
||||
if (Opts.ObjCNonFragileABI)
|
||||
Res.push_back("-fobjc-nonfragile-abi");
|
||||
if (Opts.ObjCNonFragileABI2)
|
||||
Res.push_back("-fobjc-nonfragile-abi2");
|
||||
// NoInline is implicit.
|
||||
if (!Opts.CXXOperatorNames)
|
||||
Res.push_back("-fno-operator-names");
|
||||
|
@ -1181,6 +1183,9 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args,
|
|||
Opts.ObjCConstantStringClass = getLastArgValue(Args,
|
||||
OPT_fconstant_string_class);
|
||||
Opts.ObjCNonFragileABI = Args.hasArg(OPT_fobjc_nonfragile_abi);
|
||||
Opts.ObjCNonFragileABI2 = Args.hasArg(OPT_fobjc_nonfragile_abi2);
|
||||
if (Opts.ObjCNonFragileABI2)
|
||||
Opts.ObjCNonFragileABI = true;
|
||||
Opts.CatchUndefined = Args.hasArg(OPT_fcatch_undefined_behavior);
|
||||
Opts.EmitAllDecls = Args.hasArg(OPT_femit_all_decls);
|
||||
Opts.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0, Diags);
|
||||
|
|
|
@ -72,6 +72,7 @@ PCHValidator::ReadLanguageOptions(const LangOptions &LangOpts) {
|
|||
PARSE_LANGOPT_IMPORTANT(ObjC1, diag::warn_pch_objective_c);
|
||||
PARSE_LANGOPT_IMPORTANT(ObjC2, diag::warn_pch_objective_c2);
|
||||
PARSE_LANGOPT_IMPORTANT(ObjCNonFragileABI, diag::warn_pch_nonfragile_abi);
|
||||
PARSE_LANGOPT_IMPORTANT(ObjCNonFragileABI2, diag::warn_pch_nonfragile_abi2);
|
||||
PARSE_LANGOPT_BENIGN(PascalStrings);
|
||||
PARSE_LANGOPT_BENIGN(WritableStrings);
|
||||
PARSE_LANGOPT_IMPORTANT(LaxVectorConversions,
|
||||
|
@ -1740,6 +1741,7 @@ bool PCHReader::ParseLanguageOptions(
|
|||
PARSE_LANGOPT(ObjC1);
|
||||
PARSE_LANGOPT(ObjC2);
|
||||
PARSE_LANGOPT(ObjCNonFragileABI);
|
||||
PARSE_LANGOPT(ObjCNonFragileABI2);
|
||||
PARSE_LANGOPT(PascalStrings);
|
||||
PARSE_LANGOPT(WritableStrings);
|
||||
PARSE_LANGOPT(LaxVectorConversions);
|
||||
|
|
|
@ -748,7 +748,10 @@ void PCHWriter::WriteLanguageOptions(const LangOptions &LangOpts) {
|
|||
|
||||
Record.push_back(LangOpts.ObjC1); // Objective-C 1 support enabled.
|
||||
Record.push_back(LangOpts.ObjC2); // Objective-C 2 support enabled.
|
||||
Record.push_back(LangOpts.ObjCNonFragileABI); // Objective-C modern abi enabled
|
||||
Record.push_back(LangOpts.ObjCNonFragileABI); // Objective-C
|
||||
// modern abi enabled.
|
||||
Record.push_back(LangOpts.ObjCNonFragileABI2); // Objective-C enhanced
|
||||
// modern abi enabled.
|
||||
|
||||
Record.push_back(LangOpts.PascalStrings); // Allow Pascal strings
|
||||
Record.push_back(LangOpts.WritableStrings); // Allow writable strings
|
||||
|
|
|
@ -1358,6 +1358,11 @@ public:
|
|||
void CollectImmediateProperties(ObjCContainerDecl *CDecl,
|
||||
llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& PropMap);
|
||||
|
||||
/// LookupPropertyDecl - Looks up a property in the current class and all
|
||||
/// its protocols.
|
||||
ObjCPropertyDecl *LookupPropertyDecl(const ObjCContainerDecl *CDecl,
|
||||
IdentifierInfo *II);
|
||||
|
||||
/// AtomicPropertySetterGetterRules - This routine enforces the rule (via
|
||||
/// warning) when atomic property has one but not the other user-declared
|
||||
/// setter or getter.
|
||||
|
|
|
@ -1127,6 +1127,46 @@ void Sema::CollectImmediateProperties(ObjCContainerDecl *CDecl,
|
|||
}
|
||||
}
|
||||
|
||||
/// LookupPropertyDecl - Looks up a property in the current class and all
|
||||
/// its protocols.
|
||||
ObjCPropertyDecl *Sema::LookupPropertyDecl(const ObjCContainerDecl *CDecl,
|
||||
IdentifierInfo *II) {
|
||||
if (const ObjCInterfaceDecl *IDecl =
|
||||
dyn_cast<ObjCInterfaceDecl>(CDecl)) {
|
||||
for (ObjCContainerDecl::prop_iterator P = IDecl->prop_begin(),
|
||||
E = IDecl->prop_end(); P != E; ++P) {
|
||||
ObjCPropertyDecl *Prop = (*P);
|
||||
if (Prop->getIdentifier() == II)
|
||||
return Prop;
|
||||
}
|
||||
// scan through class's protocols.
|
||||
for (ObjCInterfaceDecl::protocol_iterator PI = IDecl->protocol_begin(),
|
||||
E = IDecl->protocol_end(); PI != E; ++PI) {
|
||||
ObjCPropertyDecl *Prop = LookupPropertyDecl((*PI), II);
|
||||
if (Prop)
|
||||
return Prop;
|
||||
}
|
||||
}
|
||||
else if (const ObjCProtocolDecl *PDecl =
|
||||
dyn_cast<ObjCProtocolDecl>(CDecl)) {
|
||||
for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(),
|
||||
E = PDecl->prop_end(); P != E; ++P) {
|
||||
ObjCPropertyDecl *Prop = (*P);
|
||||
if (Prop->getIdentifier() == II)
|
||||
return Prop;
|
||||
}
|
||||
// scan through protocol's protocols.
|
||||
for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(),
|
||||
E = PDecl->protocol_end(); PI != E; ++PI) {
|
||||
ObjCPropertyDecl *Prop = LookupPropertyDecl((*PI), II);
|
||||
if (Prop)
|
||||
return Prop;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void Sema::DiagnoseUnimplementedProperties(ObjCImplDecl* IMPDecl,
|
||||
ObjCContainerDecl *CDecl,
|
||||
const llvm::DenseSet<Selector>& InsMap) {
|
||||
|
@ -1149,7 +1189,14 @@ void Sema::DiagnoseUnimplementedProperties(ObjCImplDecl* IMPDecl,
|
|||
Prop->getPropertyImplementation() == ObjCPropertyDecl::Optional ||
|
||||
PropImplMap.count(Prop))
|
||||
continue;
|
||||
|
||||
if (LangOpts.ObjCNonFragileABI2) {
|
||||
ActOnPropertyImplDecl(IMPDecl->getLocation(),
|
||||
SourceLocation(),
|
||||
true, DeclPtrTy::make(IMPDecl),
|
||||
Prop->getIdentifier(),
|
||||
Prop->getIdentifier());
|
||||
continue;
|
||||
}
|
||||
if (!InsMap.count(Prop->getGetterName())) {
|
||||
Diag(Prop->getLocation(),
|
||||
isa<ObjCCategoryDecl>(CDecl) ?
|
||||
|
|
|
@ -1271,9 +1271,9 @@ Sema::LookupInObjCMethod(LookupResult &Lookup, Scope *S,
|
|||
else
|
||||
LookForIvars = (Lookup.isSingleResult() &&
|
||||
Lookup.getFoundDecl()->isDefinedOutsideFunctionOrMethod());
|
||||
|
||||
ObjCInterfaceDecl *IFace = 0;
|
||||
if (LookForIvars) {
|
||||
ObjCInterfaceDecl *IFace = getCurMethodDecl()->getClassInterface();
|
||||
IFace = getCurMethodDecl()->getClassInterface();
|
||||
ObjCInterfaceDecl *ClassDeclared;
|
||||
if (ObjCIvarDecl *IV = IFace->lookupInstanceVariable(II, ClassDeclared)) {
|
||||
// Diagnose using an ivar in a class method.
|
||||
|
@ -1342,6 +1342,24 @@ Sema::LookupInObjCMethod(LookupResult &Lookup, Scope *S,
|
|||
}
|
||||
}
|
||||
}
|
||||
if (LangOpts.ObjCNonFragileABI2 && LookForIvars && Lookup.empty()) {
|
||||
// Find property name matching variable name.
|
||||
ObjCPropertyDecl *Prop = LookupPropertyDecl(IFace, II);
|
||||
if (Prop && !Prop->isInvalidDecl()) {
|
||||
DeclContext *EnclosingContext = cast_or_null<DeclContext>(IFace);
|
||||
QualType PropType = Context.getCanonicalType(Prop->getType());
|
||||
assert(EnclosingContext &&
|
||||
"null DeclContext for synthesized ivar - LookupInObjCMethod");
|
||||
ObjCIvarDecl *Ivar = ObjCIvarDecl::Create(Context, EnclosingContext,
|
||||
Prop->getLocation(),
|
||||
II, PropType, /*Dinfo=*/0,
|
||||
ObjCIvarDecl::Public,
|
||||
(Expr *)0);
|
||||
Ivar->setLexicalDeclContext(IFace);
|
||||
IFace->addDecl(Ivar);
|
||||
return LookupInObjCMethod(Lookup, S, II, AllowBuiltinCreation);
|
||||
}
|
||||
}
|
||||
// Sentinel value saying that we didn't do anything special.
|
||||
return Owned((Expr*) 0);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue