[cfe-commits] r108599 - in /cfe/trunk: include/clang/AST/DeclObjC.h lib/AST/DeclObjC.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaObjCProperty.cpp test/SemaObjC/synth-provisional-ivars.m
Fariborz Jahanian
fjahanian at apple.com
Fri Jul 16 17:59:30 PDT 2010
Author: fjahanian
Date: Fri Jul 16 19:59:30 2010
New Revision: 108599
URL: http://llvm.org/viewvc/llvm-project?rev=108599&view=rev
Log:
Patch to synthesize property ivars on demand as
part of the new property synthesis by default.
wip.
Added:
cfe/trunk/test/SemaObjC/synth-provisional-ivars.m
Modified:
cfe/trunk/include/clang/AST/DeclObjC.h
cfe/trunk/lib/AST/DeclObjC.cpp
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/lib/Sema/SemaObjCProperty.cpp
Modified: cfe/trunk/include/clang/AST/DeclObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclObjC.h?rev=108599&r1=108598&r2=108599&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclObjC.h (original)
+++ cfe/trunk/include/clang/AST/DeclObjC.h Fri Jul 16 19:59:30 2010
@@ -650,15 +650,17 @@
private:
ObjCIvarDecl(ObjCContainerDecl *DC, SourceLocation L, IdentifierInfo *Id,
- QualType T, TypeSourceInfo *TInfo, AccessControl ac, Expr *BW)
+ QualType T, TypeSourceInfo *TInfo, AccessControl ac, Expr *BW,
+ bool synthesized)
: FieldDecl(ObjCIvar, DC, L, Id, T, TInfo, BW, /*Mutable=*/false),
- DeclAccess(ac) {}
+ DeclAccess(ac), Synthesized(synthesized) {}
public:
static ObjCIvarDecl *Create(ASTContext &C, ObjCContainerDecl *DC,
SourceLocation L, IdentifierInfo *Id, QualType T,
TypeSourceInfo *TInfo,
- AccessControl ac, Expr *BW = NULL);
+ AccessControl ac, Expr *BW = NULL,
+ bool synthesized=false);
/// \brief Return the class interface that this ivar is logically contained
/// in; this is either the interface where the ivar was declared, or the
@@ -674,6 +676,8 @@
return DeclAccess == None ? Protected : AccessControl(DeclAccess);
}
+ bool getSynthesize() const { return Synthesized; }
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ObjCIvarDecl *D) { return true; }
@@ -681,6 +685,7 @@
private:
// NOTE: VC++ treats enums as signed, avoid using the AccessControl enum
unsigned DeclAccess : 3;
+ unsigned Synthesized : 1;
};
Modified: cfe/trunk/lib/AST/DeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclObjC.cpp?rev=108599&r1=108598&r2=108599&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclObjC.cpp (original)
+++ cfe/trunk/lib/AST/DeclObjC.cpp Fri Jul 16 19:59:30 2010
@@ -575,7 +575,8 @@
ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, ObjCContainerDecl *DC,
SourceLocation L, IdentifierInfo *Id,
QualType T, TypeSourceInfo *TInfo,
- AccessControl ac, Expr *BW) {
+ AccessControl ac, Expr *BW,
+ bool synthesized) {
if (DC) {
// Ivar's can only appear in interfaces, implementations (via synthesized
// properties), and class extensions (via direct declaration, or synthesized
@@ -592,7 +593,7 @@
"Invalid ivar decl context!");
}
- return new (C) ObjCIvarDecl(DC, L, Id, T, TInfo, ac, BW);
+ return new (C) ObjCIvarDecl(DC, L, Id, T, TInfo, ac, BW, synthesized);
}
const ObjCInterfaceDecl *ObjCIvarDecl::getContainingInterface() const {
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=108599&r1=108598&r2=108599&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri Jul 16 19:59:30 2010
@@ -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);
+ }
}
}
Modified: cfe/trunk/lib/Sema/SemaObjCProperty.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaObjCProperty.cpp?rev=108599&r1=108598&r2=108599&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaObjCProperty.cpp (original)
+++ cfe/trunk/lib/Sema/SemaObjCProperty.cpp Fri Jul 16 19:59:30 2010
@@ -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 =
Added: cfe/trunk/test/SemaObjC/synth-provisional-ivars.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/synth-provisional-ivars.m?rev=108599&view=auto
==============================================================================
--- cfe/trunk/test/SemaObjC/synth-provisional-ivars.m (added)
+++ cfe/trunk/test/SemaObjC/synth-provisional-ivars.m Fri Jul 16 19:59:30 2010
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -fsyntax-only -fobjc-nonfragile-abi2 -verify %s
+
+int bar;
+
+ at interface I
+{
+ int _bar;
+}
+ at property int PROP;
+ at property int PROP1;
+ at property int PROP2;
+ at property int PROP3;
+ at property int PROP4;
+
+ at property int bar;
+ at property int bar1;
+
+ at end
+
+ at implementation I
+- (int) Meth { return PROP; } // expected-note {{'PROP' declared here}}
+
+ at dynamic PROP1;
+- (int) Meth1 { return PROP1; } // expected-error {{use of undeclared identifier 'PROP1'}}
+
+- (int) Meth2 { return PROP2; } // expected-error {{use of undeclared identifier 'PROP2'}}
+ at dynamic PROP2;
+
+- (int) Meth3 { return PROP3; } // expected-error {{use of undeclared identifier 'PROP3'}}
+ at synthesize PROP3=IVAR;
+
+- (int) Meth4 { return PROP4; }
+ at synthesize PROP4=PROP4;
+
+- (int) Meth5 { return bar; } // expected-error {{use of undeclared identifier 'bar'}}
+ at synthesize bar = _bar;
+
+- (int) Meth6 { return bar1; }
+
+ at end
More information about the cfe-commits
mailing list