diff options
author | Chris Lattner <sabre@nondot.org> | 2008-03-14 17:18:18 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2008-03-14 17:18:18 +0000 |
commit | 6d39760673df2e92d9293f46ff8c66dad6ab5e0a (patch) | |
tree | 1997d5fac9dae1aa2a7ed4fba0a5f51831f32647 /CodeGen/CodeGenModule.cpp | |
parent | 1121519f279d0e2168dbcb6428f8e274fd46e9be (diff) |
add initial support for generating an llvm.globalctors list. Patch by David Chisnall
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@48362 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'CodeGen/CodeGenModule.cpp')
-rw-r--r-- | CodeGen/CodeGenModule.cpp | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/CodeGen/CodeGenModule.cpp b/CodeGen/CodeGenModule.cpp index 0b39ca4437..43f399a61f 100644 --- a/CodeGen/CodeGenModule.cpp +++ b/CodeGen/CodeGenModule.cpp @@ -38,6 +38,7 @@ CodeGenModule::CodeGenModule(ASTContext &C, const LangOptions &LO, } CodeGenModule::~CodeGenModule() { + EmitGlobalCtors(); delete Runtime; } @@ -62,6 +63,59 @@ void CodeGenModule::WarnUnsupported(const Decl *D, const char *Type) { &Msg, 1); } +/// AddGlobalCtor - Add a function to the list that will be called before +/// main() runs. +void CodeGenModule::AddGlobalCtor(llvm::Function * Ctor) { + // TODO: Type coercion of void()* types. + GlobalCtors.push_back(Ctor); +} + +void CodeGenModule::EmitGlobalCtors() { + // Get the type of @llvm.global_ctors + std::vector<const llvm::Type*> CtorFields; + CtorFields.push_back(llvm::IntegerType::get(32)); + // Constructor function type + std::vector<const llvm::Type*> VoidArgs; + llvm::FunctionType* CtorFuncTy = llvm::FunctionType::get( + llvm::Type::VoidTy, + VoidArgs, + false); + // i32, function type pair + CtorFields.push_back(llvm::PointerType::getUnqual(CtorFuncTy)); + llvm::StructType* CtorStructTy = llvm::StructType::get(CtorFields, false); + // Array of fields + llvm::ArrayType* GlobalCtorsTy = llvm::ArrayType::get(CtorStructTy, + GlobalCtors.size()); + + const std::string GlobalCtorsVar = std::string("llvm.global_ctors"); + // Define the global variable + llvm::GlobalVariable *GlobalCtorsVal = new llvm::GlobalVariable( + GlobalCtorsTy, + false, + llvm::GlobalValue::AppendingLinkage, + (llvm::Constant*)0, + GlobalCtorsVar, + &TheModule); + + // Populate the array + std::vector<llvm::Constant*> CtorValues; + llvm::Constant *MagicNumber = llvm::ConstantInt::get(llvm::IntegerType::Int32Ty, + 65535, + false); + for (std::vector<llvm::Constant*>::iterator I = GlobalCtors.begin(), + E = GlobalCtors.end(); I != E; ++I) { + std::vector<llvm::Constant*> StructValues; + StructValues.push_back(MagicNumber); + StructValues.push_back(*I); + + llvm::Constant* CtorEntry = llvm::ConstantStruct::get(CtorStructTy, StructValues); + CtorValues.push_back(CtorEntry); + } + llvm::Constant* CtorArray = llvm::ConstantArray::get(GlobalCtorsTy, CtorValues); + GlobalCtorsVal->setInitializer(CtorArray); + +} + /// ReplaceMapValuesWith - This is a really slow and bad function that /// searches for any entries in GlobalDeclMap that point to OldVal, changing /// them to point to NewVal. This is badbadbad, FIXME! |