This patch deals with Sema Part of Setter/Getter synthesis
of properties which are of C++ objects. Code Gen to follow
(Radar 7468090).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@103123 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index f146c85..45ea09e 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -1528,13 +1528,13 @@
/// ImplMethodsVsClassMethods - This is main routine to warn if any method
/// remains unimplemented in the class or category @implementation.
- void ImplMethodsVsClassMethods(ObjCImplDecl* IMPDecl,
+ void ImplMethodsVsClassMethods(Scope *S, ObjCImplDecl* IMPDecl,
ObjCContainerDecl* IDecl,
bool IncompleteImpl = false);
/// DiagnoseUnimplementedProperties - This routine warns on those properties
/// which must be implemented by this implementation.
- void DiagnoseUnimplementedProperties(ObjCImplDecl* IMPDecl,
+ void DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl,
ObjCContainerDecl *CDecl,
const llvm::DenseSet<Selector>& InsMap);
@@ -3858,7 +3858,7 @@
void MatchOneProtocolPropertiesInClass(Decl *CDecl,
ObjCProtocolDecl *PDecl);
- virtual void ActOnAtEnd(SourceRange AtEnd,
+ virtual void ActOnAtEnd(Scope *S, SourceRange AtEnd,
DeclPtrTy classDecl,
DeclPtrTy *allMethods = 0, unsigned allNum = 0,
DeclPtrTy *allProperties = 0, unsigned pNum = 0,
@@ -3871,7 +3871,8 @@
bool *OverridingProperty,
tok::ObjCKeywordKind MethodImplKind);
- virtual DeclPtrTy ActOnPropertyImplDecl(SourceLocation AtLoc,
+ virtual DeclPtrTy ActOnPropertyImplDecl(Scope *S,
+ SourceLocation AtLoc,
SourceLocation PropertyLoc,
bool ImplKind,DeclPtrTy ClassImplDecl,
IdentifierInfo *PropertyId,
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index d446cc1..b7d7379 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -925,7 +925,7 @@
}
}
-void Sema::ImplMethodsVsClassMethods(ObjCImplDecl* IMPDecl,
+void Sema::ImplMethodsVsClassMethods(Scope *S, ObjCImplDecl* IMPDecl,
ObjCContainerDecl* CDecl,
bool IncompleteImpl) {
llvm::DenseSet<Selector> InsMap;
@@ -939,7 +939,7 @@
// an implementation or 2) there is a @synthesize/@dynamic implementation
// of the property in the @implementation.
if (isa<ObjCInterfaceDecl>(CDecl))
- DiagnoseUnimplementedProperties(IMPDecl, CDecl, InsMap);
+ DiagnoseUnimplementedProperties(S, IMPDecl, CDecl, InsMap);
llvm::DenseSet<Selector> ClsMap;
for (ObjCImplementationDecl::classmeth_iterator
@@ -968,7 +968,7 @@
for (ObjCCategoryDecl *Categories = I->getCategoryList();
Categories; Categories = Categories->getNextClassCategory()) {
if (Categories->IsClassExtension()) {
- ImplMethodsVsClassMethods(IMPDecl, Categories, IncompleteImpl);
+ ImplMethodsVsClassMethods(S, IMPDecl, Categories, IncompleteImpl);
break;
}
}
@@ -990,7 +990,7 @@
I = IMP->instmeth_begin(), E = IMP->instmeth_end(); I!=E; ++I)
InsMap.insert((*I)->getSelector());
}
- DiagnoseUnimplementedProperties(IMPDecl, CDecl, InsMap);
+ DiagnoseUnimplementedProperties(S, IMPDecl, CDecl, InsMap);
}
} else
assert(false && "invalid ObjCContainerDecl type.");
@@ -1326,7 +1326,7 @@
// Note: For class/category implemenations, allMethods/allProperties is
// always null.
-void Sema::ActOnAtEnd(SourceRange AtEnd,
+void Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd,
DeclPtrTy classDecl,
DeclPtrTy *allMethods, unsigned allNum,
DeclPtrTy *allProperties, unsigned pNum,
@@ -1433,7 +1433,7 @@
if (ObjCImplementationDecl *IC=dyn_cast<ObjCImplementationDecl>(ClassDecl)) {
IC->setAtEndRange(AtEnd);
if (ObjCInterfaceDecl* IDecl = IC->getClassInterface()) {
- ImplMethodsVsClassMethods(IC, IDecl);
+ ImplMethodsVsClassMethods(S, IC, IDecl);
AtomicPropertySetterGetterRules(IC, IDecl);
if (LangOpts.ObjCNonFragileABI2)
while (IDecl->getSuperClass()) {
@@ -1452,7 +1452,7 @@
for (ObjCCategoryDecl *Categories = IDecl->getCategoryList();
Categories; Categories = Categories->getNextClassCategory()) {
if (Categories->getIdentifier() == CatImplClass->getIdentifier()) {
- ImplMethodsVsClassMethods(CatImplClass, Categories);
+ ImplMethodsVsClassMethods(S, CatImplClass, Categories);
break;
}
}
diff --git a/lib/Sema/SemaObjCProperty.cpp b/lib/Sema/SemaObjCProperty.cpp
index b73739f..f64ee97 100644
--- a/lib/Sema/SemaObjCProperty.cpp
+++ b/lib/Sema/SemaObjCProperty.cpp
@@ -13,6 +13,8 @@
//===----------------------------------------------------------------------===//
#include "Sema.h"
+#include "SemaInit.h"
+#include "clang/AST/ExprObjC.h"
using namespace clang;
@@ -275,7 +277,8 @@
/// builds the AST node for a property implementation declaration; declared
/// as @synthesize or @dynamic.
///
-Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(SourceLocation AtLoc,
+Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(Scope *S,
+ SourceLocation AtLoc,
SourceLocation PropertyLoc,
bool Synthesize,
DeclPtrTy ClassCatImpDecl,
@@ -427,6 +430,54 @@
ObjCPropertyImplDecl::Synthesize
: ObjCPropertyImplDecl::Dynamic),
Ivar);
+ if (ObjCMethodDecl *getterMethod = property->getGetterMethodDecl()) {
+ getterMethod->createImplicitParams(Context, IDecl);
+ if (getLangOptions().CPlusPlus && Synthesize) {
+ // For Objective-C++, need to synthesize the AST for the IVAR object to be
+ // returned by the getter as it must conform to C++'s copy-return rules.
+ // FIXME. Eventually we want to do this for Objective-C as well.
+ ImplicitParamDecl *SelfDecl = getterMethod->getSelfDecl();
+ DeclRefExpr *SelfExpr =
+ new (Context) DeclRefExpr(SelfDecl,SelfDecl->getType(),
+ SourceLocation());
+ Expr *IvarRefExpr =
+ new (Context) ObjCIvarRefExpr(Ivar, Ivar->getType(), AtLoc,
+ SelfExpr, true, true);
+ OwningExprResult Res =
+ PerformCopyInitialization(InitializedEntity::InitializeResult(
+ SourceLocation(),
+ getterMethod->getResultType()),
+ SourceLocation(),
+ Owned(IvarRefExpr));
+ if (!Res.isInvalid()) {
+ Expr *ResExpr = Res.takeAs<Expr>();
+ if (ResExpr)
+ ResExpr = MaybeCreateCXXExprWithTemporaries(ResExpr);
+ PIDecl->setGetterCXXConstructor(ResExpr);
+ }
+ }
+ }
+ if (ObjCMethodDecl *setterMethod = property->getSetterMethodDecl()) {
+ setterMethod->createImplicitParams(Context, IDecl);
+ if (getLangOptions().CPlusPlus && Synthesize) {
+ // FIXME. Eventually we want to do this for Objective-C as well.
+ ImplicitParamDecl *SelfDecl = setterMethod->getSelfDecl();
+ DeclRefExpr *SelfExpr =
+ new (Context) DeclRefExpr(SelfDecl,SelfDecl->getType(),
+ SourceLocation());
+ Expr *lhs =
+ new (Context) ObjCIvarRefExpr(Ivar, Ivar->getType(), AtLoc,
+ SelfExpr, true, true);
+ ObjCMethodDecl::param_iterator P = setterMethod->param_begin();
+ ParmVarDecl *Param = (*P);
+ Expr *rhs = new (Context) DeclRefExpr(Param,Param->getType(),
+ SourceLocation());
+ OwningExprResult Res = BuildBinOp(S, SourceLocation(),
+ BinaryOperator::Assign, lhs, rhs);
+ PIDecl->setSetterCXXAssignment(Res.takeAs<Expr>());
+ }
+ }
+
if (IC) {
if (Synthesize)
if (ObjCPropertyImplDecl *PPIDecl =
@@ -818,7 +869,7 @@
}
-void Sema::DiagnoseUnimplementedProperties(ObjCImplDecl* IMPDecl,
+void Sema::DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl,
ObjCContainerDecl *CDecl,
const llvm::DenseSet<Selector>& InsMap) {
llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*> PropMap;
@@ -841,7 +892,7 @@
PropImplMap.count(Prop))
continue;
if (LangOpts.ObjCNonFragileABI2 && !isa<ObjCCategoryImplDecl>(IMPDecl)) {
- ActOnPropertyImplDecl(IMPDecl->getLocation(),
+ ActOnPropertyImplDecl(S, IMPDecl->getLocation(),
IMPDecl->getLocation(),
true, DeclPtrTy::make(IMPDecl),
Prop->getIdentifier(),