modern objc translator: support for default property

synthesis translation. // rdar://11374235 - wip.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@156125 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Fariborz Jahanian 2012-05-03 22:52:13 +00:00
Родитель b9e05f1b32
Коммит 301e2e40f9
2 изменённых файлов: 91 добавлений и 15 удалений

Просмотреть файл

@ -781,19 +781,34 @@ static std::string getIvarAccessString(ObjCIvarDecl *OID) {
return S;
}
/// mustSynthesizeSetterGetterMethod - returns true if setter or getter has not
/// been found in the class implementation. In this case, it must be synthesized.
static bool mustSynthesizeSetterGetterMethod(ObjCImplementationDecl *IMP,
ObjCPropertyDecl *PD,
bool getter) {
return getter ? !IMP->getInstanceMethod(PD->getGetterName())
: !IMP->getInstanceMethod(PD->getSetterName());
}
void RewriteModernObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID,
ObjCImplementationDecl *IMD,
ObjCCategoryImplDecl *CID) {
static bool objcGetPropertyDefined = false;
static bool objcSetPropertyDefined = false;
SourceLocation startLoc = PID->getLocStart();
InsertText(startLoc, "// ");
const char *startBuf = SM->getCharacterData(startLoc);
assert((*startBuf == '@') && "bogus @synthesize location");
const char *semiBuf = strchr(startBuf, ';');
assert((*semiBuf == ';') && "@synthesize: can't find ';'");
SourceLocation onePastSemiLoc =
startLoc.getLocWithOffset(semiBuf-startBuf+1);
SourceLocation startGetterSetterLoc;
if (PID->getLocStart().isValid()) {
SourceLocation startLoc = PID->getLocStart();
InsertText(startLoc, "// ");
const char *startBuf = SM->getCharacterData(startLoc);
assert((*startBuf == '@') && "bogus @synthesize location");
const char *semiBuf = strchr(startBuf, ';');
assert((*semiBuf == ';') && "@synthesize: can't find ';'");
startGetterSetterLoc = startLoc.getLocWithOffset(semiBuf-startBuf+1);
}
else
startGetterSetterLoc = IMD ? IMD->getLocEnd() : CID->getLocEnd();
if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
return; // FIXME: is this correct?
@ -805,7 +820,7 @@ void RewriteModernObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID,
if (!OID)
return;
unsigned Attributes = PD->getPropertyAttributes();
if (!PD->getGetterMethodDecl()->isDefined()) {
if (mustSynthesizeSetterGetterMethod(IMD, PD, true /*getter*/)) {
bool GenGetProperty = !(Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) &&
(Attributes & (ObjCPropertyDecl::OBJC_PR_retain |
ObjCPropertyDecl::OBJC_PR_copy));
@ -857,10 +872,11 @@ void RewriteModernObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID,
else
Getr += "return " + getIvarAccessString(OID);
Getr += "; }";
InsertText(onePastSemiLoc, Getr);
InsertText(startGetterSetterLoc, Getr);
}
if (PD->isReadOnly() || PD->getSetterMethodDecl()->isDefined())
if (PD->isReadOnly() ||
!mustSynthesizeSetterGetterMethod(IMD, PD, false /*setter*/))
return;
// Generate the 'setter' function.
@ -898,8 +914,8 @@ void RewriteModernObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID,
Setr += getIvarAccessString(OID) + " = ";
Setr += PD->getName();
}
Setr += "; }";
InsertText(onePastSemiLoc, Setr);
Setr += "; }\n";
InsertText(startGetterSetterLoc, Setr);
}
static void RewriteOneForwardClassDecl(ObjCInterfaceDecl *ForwardDecl,
@ -6837,12 +6853,12 @@ void RewriteModernObjC::RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl,
if (!PD)
continue;
if (ObjCMethodDecl *Getter = PD->getGetterMethodDecl())
if (!Getter->isDefined())
if (mustSynthesizeSetterGetterMethod(IDecl, PD, true /*getter*/))
InstanceMethods.push_back(Getter);
if (PD->isReadOnly())
continue;
if (ObjCMethodDecl *Setter = PD->getSetterMethodDecl())
if (!Setter->isDefined())
if (mustSynthesizeSetterGetterMethod(IDecl, PD, false /*setter*/))
InstanceMethods.push_back(Setter);
}

Просмотреть файл

@ -0,0 +1,60 @@
// RUN: %clang_cc1 -x objective-c++ -fms-extensions -fobjc-default-synthesize-properties -rewrite-objc %s -o %t-rw.cpp
// RUN: %clang_cc1 -fsyntax-only -DSEL="void *" -Did="struct objc_object *" -Wno-attributes -Wno-address-of-temporary -D"__declspec(X)=" %t-rw.cpp
// rdar://11374235
extern "C" void *sel_registerName(const char *);
@interface NSObject
- (void) release;
- (id) retain;
@end
@class NSString;
@interface SynthItAll : NSObject
@property int howMany;
@property (retain) NSString* what;
@end
@implementation SynthItAll
@end
@interface SynthSetter : NSObject
@property (nonatomic) int howMany;
@property (nonatomic, retain) NSString* what;
@end
@implementation SynthSetter
- (int) howMany {
return _howMany;
}
// - (void) setHowMany: (int) value
- (NSString*) what {
return _what;
}
// - (void) setWhat: (NSString*) value
@end
@interface SynthGetter : NSObject
@property (nonatomic) int howMany;
@property (nonatomic, retain) NSString* what;
@end
@implementation SynthGetter
// - (int) howMany
- (void) setHowMany: (int) value {
_howMany = value;
}
// - (NSString*) what
- (void) setWhat: (NSString*) value {
if (_what != value) {
[_what release];
_what = [value retain];
}
}
@end