Patch to synthesize property ivars on demand as
part of the new property synthesis by default.
wip.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@108599 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 5f46a97..d798d9d 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -1005,6 +1005,38 @@
return true;
}
+static ObjCIvarDecl *SynthesizeProvisionalIvar(Sema &SemaRef,
+ ASTContext &Context,
+ IdentifierInfo *II,
+ SourceLocation NameLoc) {
+ ObjCMethodDecl *CurMeth = SemaRef.getCurMethodDecl();
+ ObjCInterfaceDecl *IDecl = CurMeth->getClassInterface();
+ if (!IDecl)
+ return 0;
+ ObjCImplementationDecl *ClassImpDecl = IDecl->getImplementation();
+ assert(ClassImpDecl && "Method not inside @implementation");
+ bool DynamicImplSeen = false;
+ ObjCPropertyDecl *property = SemaRef.LookupPropertyDecl(IDecl, II);
+ if (!property)
+ return 0;
+ if (ObjCPropertyImplDecl *PIDecl = ClassImpDecl->FindPropertyImplDecl(II))
+ DynamicImplSeen =
+ (PIDecl->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic);
+ if (!DynamicImplSeen) {
+ QualType PropType = Context.getCanonicalType(property->getType());
+ ObjCIvarDecl *Ivar = ObjCIvarDecl::Create(Context, ClassImpDecl,
+ NameLoc,
+ II, PropType, /*Dinfo=*/0,
+ ObjCIvarDecl::Protected,
+ (Expr *)0, true);
+ ClassImpDecl->addDecl(Ivar);
+ IDecl->makeDeclVisibleInContext(Ivar, false);
+ property->setPropertyIvarDecl(Ivar);
+ return Ivar;
+ }
+ return 0;
+}
+
Sema::OwningExprResult Sema::ActOnIdExpression(Scope *S,
CXXScopeSpec &SS,
UnqualifiedId &Id,
@@ -1070,6 +1102,12 @@
Expr *Ex = E.takeAs<Expr>();
if (Ex) return Owned(Ex);
+ // Synthesize ivars lazily
+ if (getLangOptions().ObjCNonFragileABI2) {
+ if (SynthesizeProvisionalIvar(*this, Context, II, NameLoc))
+ return ActOnIdExpression(S, SS, Id, HasTrailingLParen,
+ isAddressOfOperand);
+ }
}
}
diff --git a/lib/Sema/SemaObjCProperty.cpp b/lib/Sema/SemaObjCProperty.cpp
index ff60599..e7358ed 100644
--- a/lib/Sema/SemaObjCProperty.cpp
+++ b/lib/Sema/SemaObjCProperty.cpp
@@ -372,7 +372,7 @@
Ivar = ObjCIvarDecl::Create(Context, ClassImpDecl, PropertyLoc,
PropertyIvar, PropType, /*Dinfo=*/0,
ObjCIvarDecl::Protected,
- (Expr *)0);
+ (Expr *)0, true);
ClassImpDecl->addDecl(Ivar);
IDecl->makeDeclVisibleInContext(Ivar, false);
property->setPropertyIvarDecl(Ivar);
@@ -517,6 +517,24 @@
return DeclPtrTy();
}
IC->addPropertyImplementation(PIDecl);
+ if (getLangOptions().ObjCNonFragileABI2) {
+ // Diagnose if an ivar was lazily synthesdized due to a previous
+ // use and if 1) property is @dynamic or 2) property is synthesized
+ // but it requires a dirreferently named ivar.
+ ObjCInterfaceDecl *ClassDeclared;
+ ObjCIvarDecl *Ivar = 0;
+ if (!Synthesize)
+ Ivar = IDecl->lookupInstanceVariable(PropertyId, ClassDeclared);
+ else {
+ if (PropertyIvar && PropertyIvar != PropertyId)
+ Ivar = IDecl->lookupInstanceVariable(PropertyId, ClassDeclared);
+ }
+ if (Ivar && Ivar->getSynthesize()) {
+ Diag(Ivar->getLocation(), diag::err_undeclared_var_use)
+ << PropertyId;
+ Ivar->setInvalidDecl();
+ }
+ }
} else {
if (Synthesize)
if (ObjCPropertyImplDecl *PPIDecl =