forked from OSchip/llvm-project
Add the ObjFW runtime. Patch by Jonathan Schleifer!
llvm-svn: 160102
This commit is contained in:
parent
493eb32ff4
commit
775086e67c
|
@ -46,7 +46,10 @@ public:
|
|||
GCC,
|
||||
|
||||
/// 'gnustep' is the modern non-fragile GNUstep runtime.
|
||||
GNUstep
|
||||
GNUstep,
|
||||
|
||||
/// 'objfw' is the Objective-C runtime included in ObjFW
|
||||
ObjFW
|
||||
};
|
||||
|
||||
private:
|
||||
|
@ -76,6 +79,7 @@ public:
|
|||
case GCC: return false;
|
||||
case MacOSX: return true;
|
||||
case GNUstep: return true;
|
||||
case ObjFW: return false;
|
||||
case iOS: return true;
|
||||
}
|
||||
llvm_unreachable("bad kind");
|
||||
|
@ -109,6 +113,7 @@ public:
|
|||
return false;
|
||||
case GCC:
|
||||
case GNUstep:
|
||||
case ObjFW:
|
||||
return true;
|
||||
}
|
||||
llvm_unreachable("bad kind");
|
||||
|
@ -134,6 +139,7 @@ public:
|
|||
|
||||
case GCC: return false;
|
||||
case GNUstep: return getVersion() >= VersionTuple(1, 6);
|
||||
case ObjFW: return false; // XXX: this will change soon
|
||||
}
|
||||
llvm_unreachable("bad kind");
|
||||
}
|
||||
|
@ -159,6 +165,7 @@ public:
|
|||
// should imply a "maximal" runtime or something?
|
||||
case GCC: return true;
|
||||
case GNUstep: return true;
|
||||
case ObjFW: return true;
|
||||
}
|
||||
llvm_unreachable("bad kind");
|
||||
}
|
||||
|
@ -174,6 +181,7 @@ public:
|
|||
case iOS: return getVersion() >= VersionTuple(5);
|
||||
case GCC: return false;
|
||||
case GNUstep: return false;
|
||||
case ObjFW: return false;
|
||||
}
|
||||
llvm_unreachable("bad kind");
|
||||
}
|
||||
|
@ -186,6 +194,7 @@ public:
|
|||
case FragileMacOSX: return false;
|
||||
case GCC: return true;
|
||||
case GNUstep: return true;
|
||||
case ObjFW: return true;
|
||||
}
|
||||
llvm_unreachable("bad kind");
|
||||
}
|
||||
|
@ -197,6 +206,7 @@ public:
|
|||
case FragileMacOSX: return false;
|
||||
case GCC: return true;
|
||||
case GNUstep: return true;
|
||||
case ObjFW: return true;
|
||||
}
|
||||
llvm_unreachable("bad kind");
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ raw_ostream &clang::operator<<(raw_ostream &out, const ObjCRuntime &value) {
|
|||
case ObjCRuntime::iOS: out << "ios"; break;
|
||||
case ObjCRuntime::GNUstep: out << "gnustep"; break;
|
||||
case ObjCRuntime::GCC: out << "gcc"; break;
|
||||
case ObjCRuntime::ObjFW: out << "objfw"; break;
|
||||
}
|
||||
if (value.getVersion() > VersionTuple(0)) {
|
||||
out << '-' << value.getVersion();
|
||||
|
@ -68,6 +69,8 @@ bool ObjCRuntime::tryParse(StringRef input) {
|
|||
kind = ObjCRuntime::GNUstep;
|
||||
} else if (runtimeName == "gcc") {
|
||||
kind = ObjCRuntime::GCC;
|
||||
} else if (runtimeName == "objfw") {
|
||||
kind = ObjCRuntime::ObjFW;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -188,6 +188,7 @@ static const EHPersonality &getObjCPersonality(const LangOptions &L) {
|
|||
return EHPersonality::NeXT_ObjC;
|
||||
case ObjCRuntime::GNUstep:
|
||||
case ObjCRuntime::GCC:
|
||||
case ObjCRuntime::ObjFW:
|
||||
return EHPersonality::GNU_ObjC;
|
||||
}
|
||||
llvm_unreachable("bad runtime kind");
|
||||
|
@ -219,6 +220,7 @@ static const EHPersonality &getObjCXXPersonality(const LangOptions &L) {
|
|||
// The GCC runtime's personality function inherently doesn't support
|
||||
// mixed EH. Use the C++ personality just to avoid returning null.
|
||||
case ObjCRuntime::GCC:
|
||||
case ObjCRuntime::ObjFW: // XXX: this will change soon
|
||||
return EHPersonality::GNU_ObjC;
|
||||
case ObjCRuntime::GNUstep:
|
||||
return EHPersonality::GNU_ObjCXX;
|
||||
|
|
|
@ -99,8 +99,8 @@ class LazyRuntimeFunction {
|
|||
|
||||
|
||||
/// GNU Objective-C runtime code generation. This class implements the parts of
|
||||
/// Objective-C support that are specific to the GNU family of runtimes (GCC and
|
||||
/// GNUstep).
|
||||
/// Objective-C support that are specific to the GNU family of runtimes (GCC,
|
||||
/// GNUstep and ObjFW).
|
||||
class CGObjCGNU : public CGObjCRuntime {
|
||||
protected:
|
||||
/// The LLVM module into which output is inserted
|
||||
|
@ -397,11 +397,11 @@ private:
|
|||
const ObjCIvarDecl *Ivar);
|
||||
/// Emits a reference to a class. This allows the linker to object if there
|
||||
/// is no class of the matching name.
|
||||
protected:
|
||||
void EmitClassRef(const std::string &className);
|
||||
/// Emits a pointer to the named class
|
||||
llvm::Value *GetClassNamed(CGBuilderTy &Builder, const std::string &Name,
|
||||
bool isWeak);
|
||||
protected:
|
||||
virtual llvm::Value *GetClassNamed(CGBuilderTy &Builder,
|
||||
const std::string &Name, bool isWeak);
|
||||
/// Looks up the method for sending a message to the specified object. This
|
||||
/// mechanism differs between the GCC and GNU runtimes, so this method must be
|
||||
/// overridden in subclasses.
|
||||
|
@ -653,6 +653,30 @@ class CGObjCGNUstep : public CGObjCGNU {
|
|||
}
|
||||
};
|
||||
|
||||
/// Class used when targeting the ObjFW runtime.
|
||||
class CGObjCObjFW: public CGObjCGCC {
|
||||
virtual llvm::Value *GetClassNamed(CGBuilderTy &Builder,
|
||||
const std::string &Name, bool isWeak) {
|
||||
if (isWeak)
|
||||
return CGObjCGNU::GetClassNamed(Builder, Name, isWeak);
|
||||
|
||||
EmitClassRef(Name);
|
||||
|
||||
std::string SymbolName = "_OBJC_CLASS_" + Name;
|
||||
|
||||
llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(SymbolName);
|
||||
|
||||
if (!ClassSymbol)
|
||||
ClassSymbol = new llvm::GlobalVariable(TheModule, LongTy, false,
|
||||
llvm::GlobalValue::ExternalLinkage,
|
||||
0, SymbolName);
|
||||
|
||||
return ClassSymbol;
|
||||
}
|
||||
|
||||
public:
|
||||
CGObjCObjFW(CodeGenModule &Mod): CGObjCGCC(Mod) {}
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
|
||||
|
@ -2672,6 +2696,9 @@ clang::CodeGen::CreateGNUObjCRuntime(CodeGenModule &CGM) {
|
|||
case ObjCRuntime::GCC:
|
||||
return new CGObjCGCC(CGM);
|
||||
|
||||
case ObjCRuntime::ObjFW:
|
||||
return new CGObjCObjFW(CGM);
|
||||
|
||||
case ObjCRuntime::FragileMacOSX:
|
||||
case ObjCRuntime::MacOSX:
|
||||
case ObjCRuntime::iOS:
|
||||
|
|
|
@ -6391,6 +6391,7 @@ CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) {
|
|||
|
||||
case ObjCRuntime::GNUstep:
|
||||
case ObjCRuntime::GCC:
|
||||
case ObjCRuntime::ObjFW:
|
||||
llvm_unreachable("these runtimes are not Mac runtimes");
|
||||
}
|
||||
llvm_unreachable("bad runtime");
|
||||
|
|
|
@ -140,6 +140,7 @@ void CodeGenModule::createObjCRuntime() {
|
|||
switch (LangOpts.ObjCRuntime.getKind()) {
|
||||
case ObjCRuntime::GNUstep:
|
||||
case ObjCRuntime::GCC:
|
||||
case ObjCRuntime::ObjFW:
|
||||
ObjCRuntime = CreateGNUObjCRuntime(*this);
|
||||
return;
|
||||
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fobjc-runtime=objfw -emit-llvm -o - %s | FileCheck %s
|
||||
|
||||
// Test the ObjFW runtime.
|
||||
|
||||
@interface Test0
|
||||
+ (void) test;
|
||||
@end
|
||||
void test0(void) {
|
||||
[Test0 test];
|
||||
}
|
||||
// CHECK: define void @test0()
|
||||
// CHECK: [[T0:%.*]] = call i8* (i8*, i8*, ...)* (i8*, i8*)* @objc_msg_lookup(i8* bitcast (i64* @_OBJC_CLASS_Test0 to i8*),
|
||||
// CHECK-NEXT: [[T1:%.*]] = bitcast i8* (i8*, i8*, ...)* [[T0]] to void (i8*, i8*)*
|
||||
// CHECK-NEXT: call void [[T1]](i8* bitcast (i64* @_OBJC_CLASS_Test0 to i8*),
|
||||
// CHECK-NEXT: ret void
|
Loading…
Reference in New Issue