aboutsummaryrefslogtreecommitdiff
path: root/CodeGen/CodeGenModule.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2008-03-14 17:18:18 +0000
committerChris Lattner <sabre@nondot.org>2008-03-14 17:18:18 +0000
commit6d39760673df2e92d9293f46ff8c66dad6ab5e0a (patch)
tree1997d5fac9dae1aa2a7ed4fba0a5f51831f32647 /CodeGen/CodeGenModule.cpp
parent1121519f279d0e2168dbcb6428f8e274fd46e9be (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.cpp54
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!