зеркало из https://github.com/microsoft/clang-1.git
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:
Родитель
b9e05f1b32
Коммит
301e2e40f9
|
@ -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
|
||||
|
Загрузка…
Ссылка в новой задаче