forked from OSchip/llvm-project
Refactoring ObjC Next's runtime classes in preparation for
the new ObjC's abi. llvm-svn: 62721
This commit is contained in:
parent
d776b6e51d
commit
279eda6275
|
@ -483,6 +483,9 @@ LaxVectorConversions("flax-vector-conversions",
|
|||
static llvm::cl::opt<bool>
|
||||
EnableBlocks("fblocks", llvm::cl::desc("enable the 'blocks' language feature"));
|
||||
|
||||
static llvm::cl::opt<bool>
|
||||
ObjCModernABI("fobjc-modern-abi", llvm::cl::desc("enable objective-c's modern abi"));
|
||||
|
||||
|
||||
// FIXME: This (and all GCC -f options) really come in -f... and
|
||||
// -fno-... forms, and additionally support automagic behavior when
|
||||
|
@ -614,6 +617,9 @@ static void InitializeLanguageStandard(LangOptions &Options, LangKind LK,
|
|||
Options.NeXTRuntime = 1;
|
||||
else if (GNURuntime)
|
||||
Options.NeXTRuntime = 0;
|
||||
|
||||
if (ObjCModernABI)
|
||||
Options.ObjCModernABI = 1;
|
||||
}
|
||||
|
||||
static llvm::cl::opt<bool>
|
||||
|
|
|
@ -38,6 +38,7 @@ struct LangOptions {
|
|||
|
||||
unsigned ObjC1 : 1; // Objective-C 1 support enabled.
|
||||
unsigned ObjC2 : 1; // Objective-C 2 support enabled.
|
||||
unsigned ObjCModernABI : 1; // Objective-C modern abi enabled
|
||||
|
||||
unsigned PascalStrings : 1; // Allow Pascal strings
|
||||
unsigned Boolean : 1; // Allow bool/true/false
|
||||
|
@ -62,7 +63,7 @@ public:
|
|||
Trigraphs = BCPLComment = DollarIdents = AsmPreprocessor = 0;
|
||||
ImplicitInt = Digraphs = 0;
|
||||
HexFloats = 0;
|
||||
GC = ObjC1 = ObjC2 = 0;
|
||||
GC = ObjC1 = ObjC2 = ObjCModernABI = 0;
|
||||
C99 = Microsoft = CPlusPlus = CPlusPlus0x = NoExtensions = 0;
|
||||
CXXOperatorNames = PascalStrings = Boolean = WritableStrings = 0;
|
||||
LaxVectorConversions = Exceptions = NeXTRuntime = 0;
|
||||
|
|
|
@ -35,20 +35,14 @@ namespace {
|
|||
// FIXME: We should find a nicer way to make the labels for
|
||||
// metadata, string concatenation is lame.
|
||||
|
||||
/// ObjCTypesHelper - Helper class that encapsulates lazy
|
||||
/// construction of varies types used during ObjC generation.
|
||||
class ObjCTypesHelper {
|
||||
private:
|
||||
CodeGen::CodeGenModule &CGM;
|
||||
class ObjCCommonTypesHelper {
|
||||
protected:
|
||||
CodeGen::CodeGenModule &CGM;
|
||||
|
||||
llvm::Function *MessageSendFn, *MessageSendStretFn, *MessageSendFpretFn;
|
||||
llvm::Function *MessageSendSuperFn, *MessageSendSuperStretFn,
|
||||
*MessageSendSuperFpretFn;
|
||||
|
||||
public:
|
||||
const llvm::Type *ShortTy, *IntTy, *LongTy;
|
||||
const llvm::Type *Int8PtrTy;
|
||||
|
||||
|
||||
/// ObjectPtrTy - LLVM type for object handles (typeof(id))
|
||||
const llvm::Type *ObjectPtrTy;
|
||||
|
||||
|
@ -60,17 +54,31 @@ public:
|
|||
/// ProtocolPtrTy - LLVM type for external protocol handles
|
||||
/// (typeof(Protocol))
|
||||
const llvm::Type *ExternalProtocolPtrTy;
|
||||
|
||||
|
||||
// SuperCTy - clang type for struct objc_super.
|
||||
QualType SuperCTy;
|
||||
// SuperPtrCTy - clang type for struct objc_super *.
|
||||
QualType SuperPtrCTy;
|
||||
|
||||
|
||||
/// SuperTy - LLVM type for struct objc_super.
|
||||
const llvm::StructType *SuperTy;
|
||||
/// SuperPtrTy - LLVM type for struct objc_super *.
|
||||
const llvm::Type *SuperPtrTy;
|
||||
|
||||
ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm);
|
||||
~ObjCCommonTypesHelper(){}
|
||||
};
|
||||
|
||||
/// ObjCTypesHelper - Helper class that encapsulates lazy
|
||||
/// construction of varies types used during ObjC generation.
|
||||
class ObjCTypesHelper : public ObjCCommonTypesHelper {
|
||||
private:
|
||||
|
||||
llvm::Function *MessageSendFn, *MessageSendStretFn, *MessageSendFpretFn;
|
||||
llvm::Function *MessageSendSuperFn, *MessageSendSuperStretFn,
|
||||
*MessageSendSuperFpretFn;
|
||||
|
||||
public:
|
||||
/// SymtabTy - LLVM type for struct objc_symtab.
|
||||
const llvm::StructType *SymtabTy;
|
||||
/// SymtabPtrTy - LLVM type for struct objc_symtab *.
|
||||
|
@ -183,7 +191,7 @@ public:
|
|||
|
||||
public:
|
||||
ObjCTypesHelper(CodeGen::CodeGenModule &cgm);
|
||||
~ObjCTypesHelper();
|
||||
~ObjCTypesHelper() {}
|
||||
|
||||
|
||||
llvm::Function *getSendFn(bool IsSuper) {
|
||||
|
@ -199,13 +207,20 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class CGObjCMac : public CodeGen::CGObjCRuntime {
|
||||
private:
|
||||
CodeGen::CodeGenModule &CGM;
|
||||
ObjCTypesHelper ObjCTypes;
|
||||
/// ObjCABI - FIXME: Not sure yet.
|
||||
/// ObjCModernTypesHelper - will have all types needed by objective-c's
|
||||
/// modern abi
|
||||
class ObjCModernTypesHelper : public ObjCCommonTypesHelper {
|
||||
public:
|
||||
ObjCModernTypesHelper(CodeGen::CodeGenModule &cgm);
|
||||
~ObjCModernTypesHelper(){}
|
||||
};
|
||||
|
||||
class CGObjCCommonMac : public CodeGen::CGObjCRuntime {
|
||||
protected:
|
||||
CodeGen::CodeGenModule &CGM;
|
||||
// FIXME! May not be needing this after all.
|
||||
unsigned ObjCABI;
|
||||
|
||||
|
||||
/// LazySymbols - Symbols to generate a lazy reference for. See
|
||||
/// DefinedSymbols and FinishModule().
|
||||
std::set<IdentifierInfo*> LazySymbols;
|
||||
|
@ -215,49 +230,57 @@ private:
|
|||
/// special linker symbols which ensure that Objective-C modules are
|
||||
/// linked properly.
|
||||
std::set<IdentifierInfo*> DefinedSymbols;
|
||||
|
||||
|
||||
/// ClassNames - uniqued class names.
|
||||
llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassNames;
|
||||
|
||||
|
||||
/// MethodVarNames - uniqued method variable names.
|
||||
llvm::DenseMap<Selector, llvm::GlobalVariable*> MethodVarNames;
|
||||
|
||||
|
||||
/// MethodVarTypes - uniqued method type signatures. We have to use
|
||||
/// a StringMap here because have no other unique reference.
|
||||
llvm::StringMap<llvm::GlobalVariable*> MethodVarTypes;
|
||||
|
||||
|
||||
/// MethodDefinitions - map of methods which have been defined in
|
||||
/// this translation unit.
|
||||
llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*> MethodDefinitions;
|
||||
|
||||
|
||||
/// PropertyNames - uniqued method variable names.
|
||||
llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> PropertyNames;
|
||||
|
||||
|
||||
/// ClassReferences - uniqued class references.
|
||||
llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassReferences;
|
||||
|
||||
|
||||
/// SelectorReferences - uniqued selector references.
|
||||
llvm::DenseMap<Selector, llvm::GlobalVariable*> SelectorReferences;
|
||||
|
||||
|
||||
/// Protocols - Protocols for which an objc_protocol structure has
|
||||
/// been emitted. Forward declarations are handled by creating an
|
||||
/// empty structure whose initializer is filled in when/if defined.
|
||||
llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> Protocols;
|
||||
|
||||
|
||||
/// DefinedProtocols - Protocols which have actually been
|
||||
/// defined. We should not need this, see FIXME in GenerateProtocol.
|
||||
llvm::DenseSet<IdentifierInfo*> DefinedProtocols;
|
||||
|
||||
|
||||
/// DefinedClasses - List of defined classes.
|
||||
std::vector<llvm::GlobalValue*> DefinedClasses;
|
||||
|
||||
|
||||
/// DefinedCategories - List of defined categories.
|
||||
std::vector<llvm::GlobalValue*> DefinedCategories;
|
||||
|
||||
|
||||
/// UsedGlobals - List of globals to pack into the llvm.used metadata
|
||||
/// to prevent them from being clobbered.
|
||||
std::vector<llvm::GlobalVariable*> UsedGlobals;
|
||||
|
||||
public:
|
||||
CGObjCCommonMac(CodeGen::CodeGenModule &cgm) : CGM(cgm)
|
||||
{ }
|
||||
};
|
||||
|
||||
class CGObjCMac : public CGObjCCommonMac {
|
||||
private:
|
||||
ObjCTypesHelper ObjCTypes;
|
||||
/// EmitImageInfo - Emit the image info marker used to encode some module
|
||||
/// level information.
|
||||
void EmitImageInfo();
|
||||
|
@ -467,6 +490,14 @@ public:
|
|||
virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
|
||||
llvm::Value *src, llvm::Value *dest);
|
||||
};
|
||||
|
||||
class CGObjCModernMac : public CGObjCCommonMac {
|
||||
private:
|
||||
ObjCModernTypesHelper ObjCTypes;
|
||||
public:
|
||||
CGObjCModernMac(CodeGen::CodeGenModule &cgm);
|
||||
};
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
/* *** Helper Functions *** */
|
||||
|
@ -484,15 +515,10 @@ static llvm::Constant *getConstantGEP(llvm::Constant *C,
|
|||
|
||||
/* *** CGObjCMac Public Interface *** */
|
||||
|
||||
CGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm)
|
||||
: CGM(cgm),
|
||||
ObjCTypes(cgm),
|
||||
ObjCABI(1)
|
||||
CGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm) : CGObjCCommonMac(cgm),
|
||||
ObjCTypes(cgm)
|
||||
{
|
||||
// FIXME: How does this get set in GCC? And what does it even mean?
|
||||
if (ObjCTypes.LongTy != CGM.getTypes().ConvertType(CGM.getContext().IntTy))
|
||||
ObjCABI = 2;
|
||||
|
||||
ObjCABI = 1;
|
||||
EmitImageInfo();
|
||||
}
|
||||
|
||||
|
@ -2229,14 +2255,21 @@ void CGObjCMac::FinishModule() {
|
|||
CGM.getModule().appendModuleInlineAsm(s.str());
|
||||
}
|
||||
|
||||
CGObjCModernMac::CGObjCModernMac(CodeGen::CodeGenModule &cgm)
|
||||
: CGObjCCommonMac(cgm),
|
||||
ObjCTypes(cgm)
|
||||
{
|
||||
ObjCABI = 2;
|
||||
}
|
||||
|
||||
/* *** */
|
||||
|
||||
ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
|
||||
: CGM(cgm)
|
||||
ObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm)
|
||||
: CGM(cgm)
|
||||
{
|
||||
CodeGen::CodeGenTypes &Types = CGM.getTypes();
|
||||
ASTContext &Ctx = CGM.getContext();
|
||||
|
||||
|
||||
ShortTy = Types.ConvertType(Ctx.ShortTy);
|
||||
IntTy = Types.ConvertType(Ctx.IntTy);
|
||||
LongTy = Types.ConvertType(Ctx.LongTy);
|
||||
|
@ -2250,7 +2283,41 @@ ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
|
|||
// that the IR comes out a bit cleaner.
|
||||
const llvm::Type *T = Types.ConvertType(Ctx.getObjCProtoType());
|
||||
ExternalProtocolPtrTy = llvm::PointerType::getUnqual(T);
|
||||
|
||||
// I'm not sure I like this. The implicit coordination is a bit
|
||||
// gross. We should solve this in a reasonable fashion because this
|
||||
// is a pretty common task (match some runtime data structure with
|
||||
// an LLVM data structure).
|
||||
|
||||
// FIXME: This is leaked.
|
||||
// FIXME: Merge with rewriter code?
|
||||
|
||||
// struct _objc_super {
|
||||
// id self;
|
||||
// Class cls;
|
||||
// }
|
||||
RecordDecl *RD = RecordDecl::Create(Ctx, TagDecl::TK_struct, 0,
|
||||
SourceLocation(),
|
||||
&Ctx.Idents.get("_objc_super"));
|
||||
RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), 0,
|
||||
Ctx.getObjCIdType(), 0, false));
|
||||
RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), 0,
|
||||
Ctx.getObjCClassType(), 0, false));
|
||||
RD->completeDefinition(Ctx);
|
||||
|
||||
SuperCTy = Ctx.getTagDeclType(RD);
|
||||
SuperPtrCTy = Ctx.getPointerType(SuperCTy);
|
||||
|
||||
SuperTy = cast<llvm::StructType>(Types.ConvertType(SuperCTy));
|
||||
SuperPtrTy = llvm::PointerType::getUnqual(SuperTy);
|
||||
}
|
||||
|
||||
ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
|
||||
: ObjCCommonTypesHelper(cgm)
|
||||
{
|
||||
CodeGen::CodeGenTypes &Types = CGM.getTypes();
|
||||
ASTContext &Ctx = CGM.getContext();
|
||||
|
||||
// struct _objc_method_description {
|
||||
// SEL name;
|
||||
// char *types;
|
||||
|
@ -2326,10 +2393,11 @@ ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
|
|||
llvm::PATypeHolder ProtocolTyHolder = llvm::OpaqueType::get();
|
||||
llvm::PATypeHolder ProtocolListTyHolder = llvm::OpaqueType::get();
|
||||
|
||||
T = llvm::StructType::get(llvm::PointerType::getUnqual(ProtocolListTyHolder),
|
||||
LongTy,
|
||||
llvm::ArrayType::get(ProtocolTyHolder, 0),
|
||||
NULL);
|
||||
const llvm::Type *T =
|
||||
llvm::StructType::get(llvm::PointerType::getUnqual(ProtocolListTyHolder),
|
||||
LongTy,
|
||||
llvm::ArrayType::get(ProtocolTyHolder, 0),
|
||||
NULL);
|
||||
cast<llvm::OpaqueType>(ProtocolListTyHolder.get())->refineAbstractTypeTo(T);
|
||||
|
||||
// struct _objc_protocol {
|
||||
|
@ -2458,33 +2526,6 @@ ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
|
|||
NULL);
|
||||
CGM.getModule().addTypeName("struct._objc_category", CategoryTy);
|
||||
|
||||
// I'm not sure I like this. The implicit coordination is a bit
|
||||
// gross. We should solve this in a reasonable fashion because this
|
||||
// is a pretty common task (match some runtime data structure with
|
||||
// an LLVM data structure).
|
||||
|
||||
// FIXME: This is leaked.
|
||||
// FIXME: Merge with rewriter code?
|
||||
|
||||
// struct _objc_super {
|
||||
// id self;
|
||||
// Class cls;
|
||||
// }
|
||||
RecordDecl *RD = RecordDecl::Create(Ctx, TagDecl::TK_struct, 0,
|
||||
SourceLocation(),
|
||||
&Ctx.Idents.get("_objc_super"));
|
||||
RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), 0,
|
||||
Ctx.getObjCIdType(), 0, false));
|
||||
RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), 0,
|
||||
Ctx.getObjCClassType(), 0, false));
|
||||
RD->completeDefinition(Ctx);
|
||||
|
||||
SuperCTy = Ctx.getTagDeclType(RD);
|
||||
SuperPtrCTy = Ctx.getPointerType(SuperCTy);
|
||||
|
||||
SuperTy = cast<llvm::StructType>(Types.ConvertType(SuperCTy));
|
||||
SuperPtrTy = llvm::PointerType::getUnqual(SuperTy);
|
||||
|
||||
// Global metadata structures
|
||||
|
||||
// struct _objc_symtab {
|
||||
|
@ -2711,7 +2752,9 @@ ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
|
|||
|
||||
}
|
||||
|
||||
ObjCTypesHelper::~ObjCTypesHelper() {
|
||||
ObjCModernTypesHelper::ObjCModernTypesHelper(CodeGen::CodeGenModule &cgm)
|
||||
: ObjCCommonTypesHelper(cgm)
|
||||
{
|
||||
}
|
||||
|
||||
/* *** */
|
||||
|
@ -2720,3 +2763,9 @@ CodeGen::CGObjCRuntime *
|
|||
CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) {
|
||||
return new CGObjCMac(CGM);
|
||||
}
|
||||
|
||||
CodeGen::CGObjCRuntime *
|
||||
CodeGen::CreateMacModernObjCRuntime(CodeGen::CodeGenModule &CGM) {
|
||||
return 0;
|
||||
// return new CGObjCModernMac(CGM);
|
||||
}
|
||||
|
|
|
@ -161,6 +161,7 @@ public:
|
|||
//TODO: This should include some way of selecting which runtime to target.
|
||||
CGObjCRuntime *CreateGNUObjCRuntime(CodeGenModule &CGM);
|
||||
CGObjCRuntime *CreateMacObjCRuntime(CodeGenModule &CGM);
|
||||
CGObjCRuntime *CreateMacModernObjCRuntime(CodeGenModule &CGM);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -39,7 +39,8 @@ CodeGenModule::CodeGenModule(ASTContext &C, const LangOptions &LO,
|
|||
|
||||
if (Features.ObjC1) {
|
||||
if (Features.NeXTRuntime) {
|
||||
Runtime = CreateMacObjCRuntime(*this);
|
||||
Runtime = Features.ObjCModernABI ? CreateMacModernObjCRuntime(*this)
|
||||
: CreateMacObjCRuntime(*this);
|
||||
} else {
|
||||
Runtime = CreateGNUObjCRuntime(*this);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue