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 /lib/CodeGen/CGObjCMac.cpp | |
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
Diffstat (limited to 'lib/CodeGen/CGObjCMac.cpp')
-rw-r--r-- | lib/CodeGen/CGObjCMac.cpp | 88 |
1 files changed, 88 insertions, 0 deletions
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); } |