Modern objective-c translation. Translating default

synthesis of property getter/setters. // rdar://11374235



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@156447 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Fariborz Jahanian 2012-05-08 23:54:35 +00:00
Родитель a8f2362307
Коммит 163d3cef33
2 изменённых файлов: 100 добавлений и 20 удалений

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

@ -307,6 +307,8 @@ namespace {
void RewriteObjCQualifiedInterfaceTypes(Decl *Dcl);
void RewriteTypeOfDecl(VarDecl *VD);
void RewriteObjCQualifiedInterfaceTypes(Expr *E);
std::string getIvarAccessString(ObjCIvarDecl *D);
// Expression Rewriting.
Stmt *RewriteFunctionBodyOrGlobalInitializer(Stmt *S);
@ -771,13 +773,73 @@ void RewriteModernObjC::RewriteInclude() {
}
}
static std::string getIvarAccessString(ObjCIvarDecl *OID) {
const ObjCInterfaceDecl *ClassDecl = OID->getContainingInterface();
std::string S;
S = "((struct ";
S += ClassDecl->getIdentifier()->getName();
S += "_IMPL *)self)->";
S += OID->getName();
static void WriteInternalIvarName(const ObjCInterfaceDecl *IDecl,
ObjCIvarDecl *IvarDecl, std::string &Result) {
Result += "OBJC_IVAR_$_";
Result += IDecl->getName();
Result += "$";
Result += IvarDecl->getName();
}
std::string
RewriteModernObjC::getIvarAccessString(ObjCIvarDecl *D) {
const ObjCInterfaceDecl *ClassDecl = D->getContainingInterface();
// Build name of symbol holding ivar offset.
std::string IvarOffsetName;
WriteInternalIvarName(ClassDecl, D, IvarOffsetName);
std::string S = "(*(";
QualType IvarT = D->getType();
if (!isa<TypedefType>(IvarT) && IvarT->isRecordType()) {
RecordDecl *RD = IvarT->getAs<RecordType>()->getDecl();
RD = RD->getDefinition();
if (RD && !RD->getDeclName().getAsIdentifierInfo()) {
// decltype(((Foo_IMPL*)0)->bar) *
ObjCContainerDecl *CDecl =
dyn_cast<ObjCContainerDecl>(D->getDeclContext());
// ivar in class extensions requires special treatment.
if (ObjCCategoryDecl *CatDecl = dyn_cast<ObjCCategoryDecl>(CDecl))
CDecl = CatDecl->getClassInterface();
std::string RecName = CDecl->getName();
RecName += "_IMPL";
RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
SourceLocation(), SourceLocation(),
&Context->Idents.get(RecName.c_str()));
QualType PtrStructIMPL = Context->getPointerType(Context->getTagDeclType(RD));
unsigned UnsignedIntSize =
static_cast<unsigned>(Context->getTypeSize(Context->UnsignedIntTy));
Expr *Zero = IntegerLiteral::Create(*Context,
llvm::APInt(UnsignedIntSize, 0),
Context->UnsignedIntTy, SourceLocation());
Zero = NoTypeInfoCStyleCastExpr(Context, PtrStructIMPL, CK_BitCast, Zero);
ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(),
Zero);
FieldDecl *FD = FieldDecl::Create(*Context, 0, SourceLocation(),
SourceLocation(),
&Context->Idents.get(D->getNameAsString()),
IvarT, 0,
/*BitWidth=*/0, /*Mutable=*/true,
/*HasInit=*/false);
MemberExpr *ME = new (Context) MemberExpr(PE, true, FD, SourceLocation(),
FD->getType(), VK_LValue,
OK_Ordinary);
IvarT = Context->getDecltypeType(ME, ME->getType());
}
}
convertObjCTypeToCStyleType(IvarT);
QualType castT = Context->getPointerType(IvarT);
std::string TypeString(castT.getAsString(Context->getPrintingPolicy()));
S += TypeString;
S += ")";
// ((char *)self + IVAR_OFFSET_SYMBOL_NAME)
S += "((char *)self + ";
S += IvarOffsetName;
S += "))";
ReferencedIvars[const_cast<ObjCInterfaceDecl *>(ClassDecl)].insert(D);
return S;
}
@ -3721,14 +3783,6 @@ void RewriteModernObjC::RewriteObjCInternalStruct(ObjCInterfaceDecl *CDecl,
llvm_unreachable("struct already synthesize- RewriteObjCInternalStruct");
}
static void WriteInternalIvarName(ObjCInterfaceDecl *IDecl,
ObjCIvarDecl *IvarDecl, std::string &Result) {
Result += "OBJC_IVAR_$_";
Result += IDecl->getName();
Result += "$";
Result += IvarDecl->getName();
}
/// RewriteIvarOffsetSymbols - Rewrite ivar offset symbols of those ivars which
/// have been referenced in an ivar access expression.
void RewriteModernObjC::RewriteIvarOffsetSymbols(ObjCInterfaceDecl *CDecl,
@ -5644,6 +5698,10 @@ void RewriteModernObjC::HandleTranslationUnit(ASTContext &C) {
}
InsertText(SM->getLocForStartOfFile(MainFileID), Preamble, false);
if (ClassImplementation.size() || CategoryImplementation.size())
RewriteImplementations();
for (unsigned i = 0, e = ObjCInterfacesSeen.size(); i < e; i++) {
ObjCInterfaceDecl *CDecl = ObjCInterfacesSeen[i];
// Write struct declaration for the class matching its ivar declarations.
@ -5652,9 +5710,6 @@ void RewriteModernObjC::HandleTranslationUnit(ASTContext &C) {
// private ivars.
RewriteInterfaceDecl(CDecl);
}
if (ClassImplementation.size() || CategoryImplementation.size())
RewriteImplementations();
// Get the buffer corresponding to MainFileID. If we haven't changed it, then
// we are done.
@ -7293,7 +7348,7 @@ Stmt *RewriteModernObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) {
if (BaseExpr->getType()->isObjCObjectPointerType()) {
const ObjCInterfaceType *iFaceDecl =
dyn_cast<ObjCInterfaceType>(BaseExpr->getType()->getPointeeType());
dyn_cast<ObjCInterfaceType>(BaseExpr->getType()->getPointeeType());
assert(iFaceDecl && "RewriteObjCIvarRefExpr - iFaceDecl is null");
// lookup which class implements the instance variable.
ObjCInterfaceDecl *clsDeclared = 0;

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

@ -1,4 +1,6 @@
// RUN: %clang_cc1 -x objective-c++ -fms-extensions -fobjc-default-synthesize-properties -rewrite-objc %s -o %t-rw.cpp
// RUN: %clang_cc1 -E %s -o %t.mm
// RUN: %clang_cc1 -x objective-c++ -fms-extensions -fobjc-default-synthesize-properties -rewrite-objc %t.mm -o %t-rw.cpp
// RUN: FileCheck --input-file=%t-rw.cpp %s
// 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
@ -58,3 +60,26 @@ extern "C" void *sel_registerName(const char *);
}
@end
typedef struct {
int x:1;
int y:1;
} TBAR;
@interface NONAME
{
TBAR _bar;
}
@property TBAR bad;
@end
@implementation NONAME
@end
// CHECK: static int _I_SynthGetter_howMany
// CHECL: return (*(int *)((char *)self + OBJC_IVAR_$_SynthGetter$_howMany));
// CHECK: static NSString * _I_SynthGetter_what
// CHECK: return (*(NSString **)((char *)self + OBJC_IVAR_$_SynthGetter$_what));
// CHECK: static TBAR _I_NONAME_bad
// CHECK: return (*(TBAR *)((char *)self + OBJC_IVAR_$_NONAME$_bad));
// CHECK: static void _I_NONAME_setBad_
// CHECK: (*(TBAR *)((char *)self + OBJC_IVAR_$_NONAME$_bad)) = bad;