diff options
author | Daniel Dunbar <daniel@zuster.org> | 2008-08-11 21:35:06 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2008-08-11 21:35:06 +0000 |
commit | f77ac86f4eca528a04b817d7ad7f045a47d52712 (patch) | |
tree | c029884b8ff18e6436d9e322d5062a4a619e5bec | |
parent | 709c00cf6e88a1acfe2b27e61c9dc5f7a71e49b9 (diff) |
Add LangOptions::NeXTRuntime.
- Wired to -fnext-runtime and -fgnu-runtime options.
- Defaults to GNU, no autoselection for NeXT.
Emit NeXT OBJC_IMAGE_INFO marker.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@54651 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | Driver/clang.cpp | 17 | ||||
-rw-r--r-- | include/clang/Basic/LangOptions.h | 6 | ||||
-rw-r--r-- | lib/Basic/Targets.cpp | 5 | ||||
-rw-r--r-- | lib/CodeGen/CGObjCMac.cpp | 88 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenModule.cpp | 6 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenModule.h | 2 | ||||
-rw-r--r-- | lib/CodeGen/ModuleBuilder.cpp | 3 |
7 files changed, 117 insertions, 10 deletions
diff --git a/Driver/clang.cpp b/Driver/clang.cpp index c55aa17eb2..089faf1255 100644 --- a/Driver/clang.cpp +++ b/Driver/clang.cpp @@ -373,6 +373,14 @@ static llvm::cl::opt<bool> Exceptions("fexceptions", llvm::cl::desc("Enable support for exception handling.")); +static llvm::cl::opt<bool> +GNURuntime("fgnu-runtime", + llvm::cl::desc("Generate output compatible with the standard GNU Objective-C runtime.")); + +static llvm::cl::opt<bool> +NeXTRuntime("fnext-runtime", + llvm::cl::desc("Generate output compatible with the NeXT runtime.")); + // FIXME: add: // -ansi // -trigraphs @@ -439,6 +447,15 @@ static void InitializeLanguageStandard(LangOptions &Options, LangKind LK) { Options.WritableStrings = WritableStrings; Options.LaxVectorConversions = LaxVectorConversions; Options.Exceptions = Exceptions; + + if (NeXTRuntime) { + Options.NeXTRuntime = 1; + } else if (GNURuntime) { + Options.NeXTRuntime = 0; + } else { + // FIXME: Should autoselect based on platform. + Options.NeXTRuntime = 0; + } } static llvm::cl::opt<bool> diff --git a/include/clang/Basic/LangOptions.h b/include/clang/Basic/LangOptions.h index 7756a2ab5b..c07fdfe47c 100644 --- a/include/clang/Basic/LangOptions.h +++ b/include/clang/Basic/LangOptions.h @@ -43,7 +43,9 @@ struct LangOptions { unsigned WritableStrings : 1; // Allow writable strings unsigned LaxVectorConversions : 1; unsigned Exceptions : 1; // Support exception handling. - + + unsigned NeXTRuntime : 1; // Use NeXT runtime. + private: unsigned GC : 2; // Objective-C Garbage Collection modes. We declare // this enum as unsigned because MSVC insists on making enums @@ -58,7 +60,7 @@ public: GC = ObjC1 = ObjC2 = 0; C99 = Microsoft = CPlusPlus = CPlusPlus0x = NoExtensions = 0; CXXOperatorNames = PascalStrings = Boolean = WritableStrings = 0; - LaxVectorConversions = Exceptions = 0; + LaxVectorConversions = Exceptions = NeXTRuntime = 0; } GCMode getGCMode() const { return (GCMode) GC; } diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp index 214dfb16de..bc35d7fe8e 100644 --- a/lib/Basic/Targets.cpp +++ b/lib/Basic/Targets.cpp @@ -53,7 +53,7 @@ public: Define(Defs, "linux"); #endif - if (1) {// -fobjc-gc controls this. + if (1) { // FIXME: -fobjc-gc controls this. Define(Defs, "__weak", ""); Define(Defs, "__strong", ""); } else { @@ -67,6 +67,9 @@ public: if (0) // darwin_pascal_strings Define(Defs, "__PASCAL_STRINGS__"); + + if (0) // FIXME: -fnext-runtime controls this + Define(Defs, "__NEXT_RUNTIME__"); } }; diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index faf6fa94fc..205a8f55e9 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -12,7 +12,11 @@ //===----------------------------------------------------------------------===// #include "CGObjCRuntime.h" + +#include "CodeGenModule.h" #include "clang/AST/Decl.h" +#include "clang/Basic/LangOptions.h" + #include "llvm/Support/IRBuilder.h" using namespace clang; @@ -22,6 +26,18 @@ class CGObjCMac : public CodeGen::CGObjCRuntime { private: CodeGen::CodeGenModule &CGM; + /// UsedGlobals - list of globals to pack into the llvm.used metadata + /// to prevent them from being clobbered. + std::vector<llvm::GlobalValue*> UsedGlobals; + + /// EmitImageInfo - Emit the image info marker used to encode some module + /// level information. + void EmitImageInfo(); + + /// FinishModule - Write out global data structures at the end of + /// processing a translation unit. + void FinishModule(); + public: CGObjCMac(CodeGen::CodeGenModule &cgm); virtual llvm::Constant *GenerateConstantString(const char *String, @@ -94,6 +110,7 @@ public: } // end anonymous namespace CGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm) : CGM(cgm) { + EmitImageInfo(); } // This has to perform the lookup every time, since posing and related @@ -186,6 +203,9 @@ void CGObjCMac::GenerateClass( } llvm::Function *CGObjCMac::ModuleInitFunction() { + // Abuse this interface function as a place to finalize. + FinishModule(); + return NULL; } @@ -203,6 +223,74 @@ llvm::Function *CGObjCMac::MethodPreamble( return 0; } +/* *** Private Interface *** */ + +/// EmitImageInfo - Emit the image info marker used to encode some module +/// level information. +/// +/// See: <rdr://4810609&4810587&4810587> +/// struct IMAGE_INFO { +/// unsigned version; +/// unsigned flags; +/// }; +enum ImageInfoFlags { + eImageInfo_FixAndContinue = (1 << 0), // FIXME: Not sure what this implies + eImageInfo_GarbageCollected = (1 << 1), + eImageInfo_GCOnly = (1 << 2) +}; + +void CGObjCMac::EmitImageInfo() { + unsigned version = 0; // Version is unused? + unsigned flags = 0; + + // FIXME: Fix and continue? + if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC) + flags |= eImageInfo_GarbageCollected; + if (CGM.getLangOptions().getGCMode() == LangOptions::GCOnly) + flags |= eImageInfo_GCOnly; + + fprintf(stderr, "flags: %d (%d)\n", flags, CGM.getLangOptions().getGCMode()); + + // Emitted as int[2]; + llvm::Constant *values[2] = { + llvm::ConstantInt::get(llvm::Type::Int32Ty, version), + llvm::ConstantInt::get(llvm::Type::Int32Ty, flags) + }; + llvm::ArrayType *AT = llvm::ArrayType::get(llvm::Type::Int32Ty, 2); + llvm::GlobalValue *GV = + new llvm::GlobalVariable(AT, true, + llvm::GlobalValue::InternalLinkage, + llvm::ConstantArray::get(AT, values, 2), + "\01L_OBJC_IMAGE_INFO", + &CGM.getModule()); + + GV->setSection("__OBJC, __image_info,regular"); + + UsedGlobals.push_back(GV); +} + +void CGObjCMac::FinishModule() { + std::vector<llvm::Constant*> Used; + + llvm::Type *I8Ptr = llvm::PointerType::getUnqual(llvm::Type::Int8Ty); + for (std::vector<llvm::GlobalValue*>::iterator i = UsedGlobals.begin(), + e = UsedGlobals.end(); i != e; ++i) { + Used.push_back(llvm::ConstantExpr::getBitCast(*i, I8Ptr)); + } + + llvm::ArrayType *AT = llvm::ArrayType::get(I8Ptr, Used.size()); + llvm::GlobalValue *GV = + new llvm::GlobalVariable(AT, false, + llvm::GlobalValue::AppendingLinkage, + llvm::ConstantArray::get(AT, Used), + "llvm.used", + &CGM.getModule()); + + GV->setSection("llvm.metadata"); +} + +/* *** */ + CodeGen::CGObjCRuntime *CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM){ return new CGObjCMac(CGM); } diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 347f4d24f9..fb873c2a67 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -30,15 +30,13 @@ using namespace CodeGen; CodeGenModule::CodeGenModule(ASTContext &C, const LangOptions &LO, llvm::Module &M, const llvm::TargetData &TD, - Diagnostic &diags, bool GenerateDebugInfo, - bool UseMacObjCRuntime) + Diagnostic &diags, bool GenerateDebugInfo) : Context(C), Features(LO), TheModule(M), TheTargetData(TD), Diags(diags), Types(C, M, TD), Runtime(0), MemCpyFn(0), MemMoveFn(0), MemSetFn(0), CFConstantStringClassRef(0) { if (Features.ObjC1) { - // TODO: Make this selectable at runtime - if (UseMacObjCRuntime) { + if (Features.NeXTRuntime) { Runtime = CreateMacObjCRuntime(*this); } else { Runtime = CreateGNUObjCRuntime(*this); diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index 0b313c4205..3f30cd3283 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -105,7 +105,7 @@ class CodeGenModule { public: CodeGenModule(ASTContext &C, const LangOptions &Features, llvm::Module &M, const llvm::TargetData &TD, Diagnostic &Diags, - bool GenerateDebugInfo, bool UseMacObjCRuntime); + bool GenerateDebugInfo); ~CodeGenModule(); diff --git a/lib/CodeGen/ModuleBuilder.cpp b/lib/CodeGen/ModuleBuilder.cpp index 7c43943eac..affef35f28 100644 --- a/lib/CodeGen/ModuleBuilder.cpp +++ b/lib/CodeGen/ModuleBuilder.cpp @@ -59,8 +59,7 @@ namespace { M->setDataLayout(Ctx->Target.getTargetDescription()); TD.reset(new llvm::TargetData(Ctx->Target.getTargetDescription())); Builder.reset(new CodeGen::CodeGenModule(Context, Features, *M, *TD, - Diags, GenerateDebugInfo, - false)); + Diags, GenerateDebugInfo)); } virtual void HandleTopLevelDecl(Decl *D) { |