forked from OSchip/llvm-project
Starting patch to generate more specific API for objc's
GC. Currently, new API will be generated under clang-cc's -fobjc-newgc-api flag which will eventually become the default. WIP. llvm-svn: 82082
This commit is contained in:
parent
ca968cf1f0
commit
a7fa6beb2e
|
@ -88,6 +88,7 @@ public:
|
|||
|
||||
unsigned ElideConstructors : 1; // Whether C++ copy constructors should be
|
||||
// elided if possible.
|
||||
unsigned ObjCNewGCAPI : 1; // Generate objective-c's new GC API
|
||||
private:
|
||||
unsigned GC : 2; // Objective-C Garbage Collection modes. We
|
||||
// declare this enum as unsigned because MSVC
|
||||
|
@ -146,6 +147,7 @@ public:
|
|||
|
||||
OverflowChecking = 0;
|
||||
ObjCGCBitmapPrint = 0;
|
||||
ObjCNewGCAPI = 0;
|
||||
|
||||
InstantiationDepth = 99;
|
||||
|
||||
|
|
|
@ -694,6 +694,37 @@ void CodeGenFunction::EmitStoreThroughExtVectorComponentLValue(RValue Src,
|
|||
Builder.CreateStore(Vec, Dst.getExtVectorAddr(), Dst.isVolatileQualified());
|
||||
}
|
||||
|
||||
// setObjCGCLValueClass - sets class of he lvalue for the purpose of
|
||||
// generating write-barries API. It is currently a global, ivar,
|
||||
// or neither.
|
||||
static
|
||||
void setObjCGCLValueClass(const ASTContext &Ctx, const Expr *E, LValue &LV) {
|
||||
if (Ctx.getLangOptions().getGCMode() == LangOptions::NonGC ||
|
||||
!Ctx.getLangOptions().ObjCNewGCAPI)
|
||||
return;
|
||||
|
||||
if (const DeclRefExpr *Exp = dyn_cast<DeclRefExpr>(E)) {
|
||||
if (const VarDecl *VD = dyn_cast<VarDecl>(Exp->getDecl())) {
|
||||
if ((VD->isBlockVarDecl() && !VD->hasLocalStorage()) ||
|
||||
VD->isFileVarDecl())
|
||||
LV.SetGlobalObjCRef(LV, true);
|
||||
}
|
||||
}
|
||||
else if (const UnaryOperator *Exp = dyn_cast<UnaryOperator>(E))
|
||||
setObjCGCLValueClass(Ctx, Exp->getSubExpr(), LV);
|
||||
else if (const ParenExpr *Exp = dyn_cast<ParenExpr>(E))
|
||||
setObjCGCLValueClass(Ctx, Exp->getSubExpr(), LV);
|
||||
else if (const ImplicitCastExpr *Exp = dyn_cast<ImplicitCastExpr>(E))
|
||||
setObjCGCLValueClass(Ctx, Exp->getSubExpr(), LV);
|
||||
else if (const CStyleCastExpr *Exp = dyn_cast<CStyleCastExpr>(E))
|
||||
setObjCGCLValueClass(Ctx, Exp->getSubExpr(), LV);
|
||||
else if (const ArraySubscriptExpr *Exp = dyn_cast<ArraySubscriptExpr>(E))
|
||||
setObjCGCLValueClass(Ctx, Exp->getBase(), LV);
|
||||
else if (const MemberExpr *Exp = dyn_cast<MemberExpr>(E)) {
|
||||
setObjCGCLValueClass(Ctx, Exp->getBase(), LV);
|
||||
}
|
||||
}
|
||||
|
||||
LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
|
||||
const VarDecl *VD = dyn_cast<VarDecl>(E->getDecl());
|
||||
|
||||
|
@ -729,6 +760,7 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
|
|||
E->getType().getAddressSpace());
|
||||
}
|
||||
LValue::SetObjCNonGC(LV, NonGCable);
|
||||
setObjCGCLValueClass(getContext(), E, LV);
|
||||
return LV;
|
||||
} else if (VD && VD->isFileVarDecl()) {
|
||||
llvm::Value *V = CGM.GetAddrOfGlobalVar(VD);
|
||||
|
@ -737,7 +769,7 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
|
|||
LValue LV = LValue::MakeAddr(V, E->getType().getCVRQualifiers(),
|
||||
getContext().getObjCGCAttrKind(E->getType()),
|
||||
E->getType().getAddressSpace());
|
||||
LV.SetGlobalObjCRef(LV, true);
|
||||
setObjCGCLValueClass(getContext(), E, LV);
|
||||
return LV;
|
||||
} else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(E->getDecl())) {
|
||||
llvm::Value* V = CGM.GetAddrOfFunction(FD);
|
||||
|
@ -937,8 +969,10 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E) {
|
|||
getContext().getObjCGCAttrKind(T),
|
||||
E->getBase()->getType().getAddressSpace());
|
||||
if (getContext().getLangOptions().ObjC1 &&
|
||||
getContext().getLangOptions().getGCMode() != LangOptions::NonGC)
|
||||
getContext().getLangOptions().getGCMode() != LangOptions::NonGC) {
|
||||
LValue::SetObjCNonGC(LV, !E->isOBJCGCCandidate(getContext()));
|
||||
setObjCGCLValueClass(getContext(), E, LV);
|
||||
}
|
||||
return LV;
|
||||
}
|
||||
|
||||
|
@ -1042,6 +1076,7 @@ LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) {
|
|||
CVRQualifiers);
|
||||
LValue::SetObjCIvar(MemExpLV, isIvar);
|
||||
LValue::SetObjCNonGC(MemExpLV, isNonGC);
|
||||
setObjCGCLValueClass(getContext(), E, MemExpLV);
|
||||
return MemExpLV;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,82 @@
|
|||
// RUN: clang-cc -fnext-runtime -fobjc-gc -emit-llvm -o %t %s &&
|
||||
// RUN: grep -F '@objc_assign_global' %t | count 2 &&
|
||||
// RUN: clang-cc -fnext-runtime -fobjc-gc -fobjc-newgc-api -emit-llvm -o %t %s &&
|
||||
// RUN: grep -F '@objc_assign_global' %t | count 26 &&
|
||||
// RUN: true
|
||||
id a;
|
||||
|
||||
@class NSObject;
|
||||
typedef const struct __CFDictionary * CFDictionaryRef;
|
||||
typedef struct {
|
||||
id element;
|
||||
id elementArray[10];
|
||||
__strong CFDictionaryRef cfElement;
|
||||
__strong CFDictionaryRef cfElementArray[10];
|
||||
} struct_with_ids_t;
|
||||
|
||||
|
||||
// assignments to these should generate objc_assign_global
|
||||
@interface A
|
||||
@end
|
||||
|
||||
typedef struct s0 {
|
||||
A *a[4];
|
||||
} T;
|
||||
|
||||
T g0;
|
||||
|
||||
extern id FileExternID;
|
||||
static id FileStaticID;
|
||||
id GlobalId;
|
||||
id GlobalArray[20];
|
||||
NSObject *GlobalObject;
|
||||
NSObject *GlobalObjectArray[20];
|
||||
__strong CFDictionaryRef Gdict;
|
||||
__strong CFDictionaryRef Gdictarray[10];
|
||||
struct_with_ids_t GlobalStruct;
|
||||
struct_with_ids_t GlobalStructArray[10];
|
||||
|
||||
#define ASSIGNTEST(expr, global) expr = rhs
|
||||
void *rhs = 0;
|
||||
|
||||
int main() {
|
||||
a = 0;
|
||||
static id staticGlobalId;
|
||||
static id staticGlobalArray[20];
|
||||
static NSObject *staticGlobalObject;
|
||||
static NSObject *staticGlobalObjectArray[20];
|
||||
static __strong CFDictionaryRef staticGdict;
|
||||
static __strong CFDictionaryRef staticGdictarray[10];
|
||||
static struct_with_ids_t staticGlobalStruct;
|
||||
static struct_with_ids_t staticGlobalStructArray[10];
|
||||
extern id ExID;
|
||||
id localID;
|
||||
|
||||
ASSIGNTEST(GlobalId, GlobalAssigns); // objc_assign_global
|
||||
ASSIGNTEST(GlobalArray[0], GlobalAssigns); // objc_assign_global
|
||||
ASSIGNTEST(GlobalObject, GlobalAssigns); // objc_assign_global
|
||||
ASSIGNTEST(GlobalObjectArray[0], GlobalAssigns); // objc_assign_global
|
||||
ASSIGNTEST(Gdict, GlobalAssigns); // objc_assign_global
|
||||
ASSIGNTEST(Gdictarray[1], GlobalAssigns); // objc_assign_global
|
||||
|
||||
ASSIGNTEST(GlobalStruct.element, GlobalAssigns); // objc_assign_global
|
||||
ASSIGNTEST(GlobalStruct.elementArray[0], GlobalAssigns); // objc_assign_global
|
||||
ASSIGNTEST(GlobalStruct.cfElement, GlobalAssigns); // objc_assign_global
|
||||
ASSIGNTEST(GlobalStruct.cfElementArray[0], GlobalAssigns); // objc_assign_global
|
||||
|
||||
ASSIGNTEST(staticGlobalId, GlobalAssigns); // objc_assign_global
|
||||
ASSIGNTEST(staticGlobalArray[0], GlobalAssigns); // objc_assign_global
|
||||
ASSIGNTEST(staticGlobalObject, GlobalAssigns); // objc_assign_global
|
||||
ASSIGNTEST(staticGlobalObjectArray[0], GlobalAssigns); // objc_assign_global
|
||||
ASSIGNTEST(staticGdict, GlobalAssigns); // objc_assign_global
|
||||
ASSIGNTEST(staticGdictarray[1], GlobalAssigns); // objc_assign_global
|
||||
|
||||
ASSIGNTEST(staticGlobalStruct.element, GlobalAssigns); // objc_assign_global
|
||||
ASSIGNTEST(staticGlobalStruct.elementArray[0], GlobalAssigns); // objc_assign_global
|
||||
ASSIGNTEST(staticGlobalStruct.cfElement, GlobalAssigns); // objc_assign_global
|
||||
ASSIGNTEST(staticGlobalStruct.cfElementArray[0], GlobalAssigns); // objc_assign_global
|
||||
|
||||
ExID = 0;
|
||||
localID = 0;
|
||||
FileStaticID = 0;
|
||||
FileExternID=0;
|
||||
g0.a[0] = 0;
|
||||
((T*) &g0)->a[0] = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -371,6 +371,10 @@ static llvm::cl::opt<bool>
|
|||
ObjCEnableGC("fobjc-gc",
|
||||
llvm::cl::desc("Enable Objective-C garbage collection"));
|
||||
|
||||
static llvm::cl::opt<bool>
|
||||
ObjCEnableNewGCAPI("fobjc-newgc-api",
|
||||
llvm::cl::desc("Enable Objective-C garbage collection's new API"));
|
||||
|
||||
static llvm::cl::opt<bool>
|
||||
ObjCEnableGCBitmapPrint("print-ivar-layout",
|
||||
llvm::cl::desc("Enable Objective-C Ivar layout bitmap print trace"));
|
||||
|
@ -508,6 +512,9 @@ static void InitializeLangOptions(LangOptions &Options, LangKind LK){
|
|||
else if (ObjCEnableGC)
|
||||
Options.setGCMode(LangOptions::HybridGC);
|
||||
|
||||
if (ObjCEnableNewGCAPI)
|
||||
Options.ObjCNewGCAPI = 1;
|
||||
|
||||
if (ObjCEnableGCBitmapPrint)
|
||||
Options.ObjCGCBitmapPrint = 1;
|
||||
|
||||
|
|
Loading…
Reference in New Issue