зеркало из 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;
|
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,
|
void RewriteModernObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID,
|
||||||
ObjCImplementationDecl *IMD,
|
ObjCImplementationDecl *IMD,
|
||||||
ObjCCategoryImplDecl *CID) {
|
ObjCCategoryImplDecl *CID) {
|
||||||
static bool objcGetPropertyDefined = false;
|
static bool objcGetPropertyDefined = false;
|
||||||
static bool objcSetPropertyDefined = false;
|
static bool objcSetPropertyDefined = false;
|
||||||
SourceLocation startLoc = PID->getLocStart();
|
SourceLocation startGetterSetterLoc;
|
||||||
InsertText(startLoc, "// ");
|
|
||||||
const char *startBuf = SM->getCharacterData(startLoc);
|
if (PID->getLocStart().isValid()) {
|
||||||
assert((*startBuf == '@') && "bogus @synthesize location");
|
SourceLocation startLoc = PID->getLocStart();
|
||||||
const char *semiBuf = strchr(startBuf, ';');
|
InsertText(startLoc, "// ");
|
||||||
assert((*semiBuf == ';') && "@synthesize: can't find ';'");
|
const char *startBuf = SM->getCharacterData(startLoc);
|
||||||
SourceLocation onePastSemiLoc =
|
assert((*startBuf == '@') && "bogus @synthesize location");
|
||||||
startLoc.getLocWithOffset(semiBuf-startBuf+1);
|
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)
|
if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
|
||||||
return; // FIXME: is this correct?
|
return; // FIXME: is this correct?
|
||||||
|
@ -805,7 +820,7 @@ void RewriteModernObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID,
|
||||||
if (!OID)
|
if (!OID)
|
||||||
return;
|
return;
|
||||||
unsigned Attributes = PD->getPropertyAttributes();
|
unsigned Attributes = PD->getPropertyAttributes();
|
||||||
if (!PD->getGetterMethodDecl()->isDefined()) {
|
if (mustSynthesizeSetterGetterMethod(IMD, PD, true /*getter*/)) {
|
||||||
bool GenGetProperty = !(Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) &&
|
bool GenGetProperty = !(Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) &&
|
||||||
(Attributes & (ObjCPropertyDecl::OBJC_PR_retain |
|
(Attributes & (ObjCPropertyDecl::OBJC_PR_retain |
|
||||||
ObjCPropertyDecl::OBJC_PR_copy));
|
ObjCPropertyDecl::OBJC_PR_copy));
|
||||||
|
@ -857,10 +872,11 @@ void RewriteModernObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID,
|
||||||
else
|
else
|
||||||
Getr += "return " + getIvarAccessString(OID);
|
Getr += "return " + getIvarAccessString(OID);
|
||||||
Getr += "; }";
|
Getr += "; }";
|
||||||
InsertText(onePastSemiLoc, Getr);
|
InsertText(startGetterSetterLoc, Getr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PD->isReadOnly() || PD->getSetterMethodDecl()->isDefined())
|
if (PD->isReadOnly() ||
|
||||||
|
!mustSynthesizeSetterGetterMethod(IMD, PD, false /*setter*/))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Generate the 'setter' function.
|
// Generate the 'setter' function.
|
||||||
|
@ -898,8 +914,8 @@ void RewriteModernObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID,
|
||||||
Setr += getIvarAccessString(OID) + " = ";
|
Setr += getIvarAccessString(OID) + " = ";
|
||||||
Setr += PD->getName();
|
Setr += PD->getName();
|
||||||
}
|
}
|
||||||
Setr += "; }";
|
Setr += "; }\n";
|
||||||
InsertText(onePastSemiLoc, Setr);
|
InsertText(startGetterSetterLoc, Setr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void RewriteOneForwardClassDecl(ObjCInterfaceDecl *ForwardDecl,
|
static void RewriteOneForwardClassDecl(ObjCInterfaceDecl *ForwardDecl,
|
||||||
|
@ -6837,12 +6853,12 @@ void RewriteModernObjC::RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl,
|
||||||
if (!PD)
|
if (!PD)
|
||||||
continue;
|
continue;
|
||||||
if (ObjCMethodDecl *Getter = PD->getGetterMethodDecl())
|
if (ObjCMethodDecl *Getter = PD->getGetterMethodDecl())
|
||||||
if (!Getter->isDefined())
|
if (mustSynthesizeSetterGetterMethod(IDecl, PD, true /*getter*/))
|
||||||
InstanceMethods.push_back(Getter);
|
InstanceMethods.push_back(Getter);
|
||||||
if (PD->isReadOnly())
|
if (PD->isReadOnly())
|
||||||
continue;
|
continue;
|
||||||
if (ObjCMethodDecl *Setter = PD->getSetterMethodDecl())
|
if (ObjCMethodDecl *Setter = PD->getSetterMethodDecl())
|
||||||
if (!Setter->isDefined())
|
if (mustSynthesizeSetterGetterMethod(IDecl, PD, false /*setter*/))
|
||||||
InstanceMethods.push_back(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
|
||||||
|
|
Загрузка…
Ссылка в новой задаче