зеркало из https://github.com/microsoft/clang-1.git
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:
Родитель
a8f2362307
Коммит
163d3cef33
|
@ -307,6 +307,8 @@ namespace {
|
||||||
void RewriteObjCQualifiedInterfaceTypes(Decl *Dcl);
|
void RewriteObjCQualifiedInterfaceTypes(Decl *Dcl);
|
||||||
void RewriteTypeOfDecl(VarDecl *VD);
|
void RewriteTypeOfDecl(VarDecl *VD);
|
||||||
void RewriteObjCQualifiedInterfaceTypes(Expr *E);
|
void RewriteObjCQualifiedInterfaceTypes(Expr *E);
|
||||||
|
|
||||||
|
std::string getIvarAccessString(ObjCIvarDecl *D);
|
||||||
|
|
||||||
// Expression Rewriting.
|
// Expression Rewriting.
|
||||||
Stmt *RewriteFunctionBodyOrGlobalInitializer(Stmt *S);
|
Stmt *RewriteFunctionBodyOrGlobalInitializer(Stmt *S);
|
||||||
|
@ -771,13 +773,73 @@ void RewriteModernObjC::RewriteInclude() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string getIvarAccessString(ObjCIvarDecl *OID) {
|
static void WriteInternalIvarName(const ObjCInterfaceDecl *IDecl,
|
||||||
const ObjCInterfaceDecl *ClassDecl = OID->getContainingInterface();
|
ObjCIvarDecl *IvarDecl, std::string &Result) {
|
||||||
std::string S;
|
Result += "OBJC_IVAR_$_";
|
||||||
S = "((struct ";
|
Result += IDecl->getName();
|
||||||
S += ClassDecl->getIdentifier()->getName();
|
Result += "$";
|
||||||
S += "_IMPL *)self)->";
|
Result += IvarDecl->getName();
|
||||||
S += OID->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;
|
return S;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3721,14 +3783,6 @@ void RewriteModernObjC::RewriteObjCInternalStruct(ObjCInterfaceDecl *CDecl,
|
||||||
llvm_unreachable("struct already synthesize- RewriteObjCInternalStruct");
|
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
|
/// RewriteIvarOffsetSymbols - Rewrite ivar offset symbols of those ivars which
|
||||||
/// have been referenced in an ivar access expression.
|
/// have been referenced in an ivar access expression.
|
||||||
void RewriteModernObjC::RewriteIvarOffsetSymbols(ObjCInterfaceDecl *CDecl,
|
void RewriteModernObjC::RewriteIvarOffsetSymbols(ObjCInterfaceDecl *CDecl,
|
||||||
|
@ -5644,6 +5698,10 @@ void RewriteModernObjC::HandleTranslationUnit(ASTContext &C) {
|
||||||
}
|
}
|
||||||
|
|
||||||
InsertText(SM->getLocForStartOfFile(MainFileID), Preamble, false);
|
InsertText(SM->getLocForStartOfFile(MainFileID), Preamble, false);
|
||||||
|
|
||||||
|
if (ClassImplementation.size() || CategoryImplementation.size())
|
||||||
|
RewriteImplementations();
|
||||||
|
|
||||||
for (unsigned i = 0, e = ObjCInterfacesSeen.size(); i < e; i++) {
|
for (unsigned i = 0, e = ObjCInterfacesSeen.size(); i < e; i++) {
|
||||||
ObjCInterfaceDecl *CDecl = ObjCInterfacesSeen[i];
|
ObjCInterfaceDecl *CDecl = ObjCInterfacesSeen[i];
|
||||||
// Write struct declaration for the class matching its ivar declarations.
|
// Write struct declaration for the class matching its ivar declarations.
|
||||||
|
@ -5652,9 +5710,6 @@ void RewriteModernObjC::HandleTranslationUnit(ASTContext &C) {
|
||||||
// private ivars.
|
// private ivars.
|
||||||
RewriteInterfaceDecl(CDecl);
|
RewriteInterfaceDecl(CDecl);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ClassImplementation.size() || CategoryImplementation.size())
|
|
||||||
RewriteImplementations();
|
|
||||||
|
|
||||||
// Get the buffer corresponding to MainFileID. If we haven't changed it, then
|
// Get the buffer corresponding to MainFileID. If we haven't changed it, then
|
||||||
// we are done.
|
// we are done.
|
||||||
|
@ -7293,7 +7348,7 @@ Stmt *RewriteModernObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) {
|
||||||
|
|
||||||
if (BaseExpr->getType()->isObjCObjectPointerType()) {
|
if (BaseExpr->getType()->isObjCObjectPointerType()) {
|
||||||
const ObjCInterfaceType *iFaceDecl =
|
const ObjCInterfaceType *iFaceDecl =
|
||||||
dyn_cast<ObjCInterfaceType>(BaseExpr->getType()->getPointeeType());
|
dyn_cast<ObjCInterfaceType>(BaseExpr->getType()->getPointeeType());
|
||||||
assert(iFaceDecl && "RewriteObjCIvarRefExpr - iFaceDecl is null");
|
assert(iFaceDecl && "RewriteObjCIvarRefExpr - iFaceDecl is null");
|
||||||
// lookup which class implements the instance variable.
|
// lookup which class implements the instance variable.
|
||||||
ObjCInterfaceDecl *clsDeclared = 0;
|
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
|
// 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
|
// rdar://11374235
|
||||||
|
|
||||||
|
@ -58,3 +60,26 @@ extern "C" void *sel_registerName(const char *);
|
||||||
}
|
}
|
||||||
@end
|
@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;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче