LLVM API Documentation
00001 //===-- ModuleUtils.cpp - Functions to manipulate Modules -----------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This family of functions perform manipulations on Modules. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "llvm/Transforms/Utils/ModuleUtils.h" 00015 #include "llvm/IR/DerivedTypes.h" 00016 #include "llvm/IR/Function.h" 00017 #include "llvm/IR/IRBuilder.h" 00018 #include "llvm/IR/Module.h" 00019 00020 using namespace llvm; 00021 00022 static void appendToGlobalArray(const char *Array, 00023 Module &M, Function *F, int Priority) { 00024 IRBuilder<> IRB(M.getContext()); 00025 FunctionType *FnTy = FunctionType::get(IRB.getVoidTy(), false); 00026 StructType *Ty = StructType::get( 00027 IRB.getInt32Ty(), PointerType::getUnqual(FnTy), NULL); 00028 00029 Constant *RuntimeCtorInit = ConstantStruct::get( 00030 Ty, IRB.getInt32(Priority), F, NULL); 00031 00032 // Get the current set of static global constructors and add the new ctor 00033 // to the list. 00034 SmallVector<Constant *, 16> CurrentCtors; 00035 if (GlobalVariable * GVCtor = M.getNamedGlobal(Array)) { 00036 if (Constant *Init = GVCtor->getInitializer()) { 00037 unsigned n = Init->getNumOperands(); 00038 CurrentCtors.reserve(n + 1); 00039 for (unsigned i = 0; i != n; ++i) 00040 CurrentCtors.push_back(cast<Constant>(Init->getOperand(i))); 00041 } 00042 GVCtor->eraseFromParent(); 00043 } 00044 00045 CurrentCtors.push_back(RuntimeCtorInit); 00046 00047 // Create a new initializer. 00048 ArrayType *AT = ArrayType::get(RuntimeCtorInit->getType(), 00049 CurrentCtors.size()); 00050 Constant *NewInit = ConstantArray::get(AT, CurrentCtors); 00051 00052 // Create the new global variable and replace all uses of 00053 // the old global variable with the new one. 00054 (void)new GlobalVariable(M, NewInit->getType(), false, 00055 GlobalValue::AppendingLinkage, NewInit, Array); 00056 } 00057 00058 void llvm::appendToGlobalCtors(Module &M, Function *F, int Priority) { 00059 appendToGlobalArray("llvm.global_ctors", M, F, Priority); 00060 } 00061 00062 void llvm::appendToGlobalDtors(Module &M, Function *F, int Priority) { 00063 appendToGlobalArray("llvm.global_dtors", M, F, Priority); 00064 }