pull "runtime globals" into the same framework as other functions/global variables.
No intended functionality change. llvm-svn: 67478
This commit is contained in:
parent
d6a7b72944
commit
d480892445
|
@ -422,9 +422,8 @@ void CodeGenFunction::EmitObjCPropertySet(const Expr *Exp,
|
|||
assert (0 && "bad expression node in EmitObjCPropertySet");
|
||||
}
|
||||
|
||||
void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S)
|
||||
{
|
||||
llvm::Function *EnumerationMutationFn =
|
||||
void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){
|
||||
llvm::Constant *EnumerationMutationFn =
|
||||
CGM.getObjCRuntime().EnumerationMutationFunction();
|
||||
llvm::Value *DeclAddress;
|
||||
QualType ElementTy;
|
||||
|
|
|
@ -84,33 +84,33 @@ public:
|
|||
/// CachePtrTy - LLVM type for struct objc_cache *.
|
||||
const llvm::Type *CachePtrTy;
|
||||
|
||||
llvm::Function *GetPropertyFn, *SetPropertyFn;
|
||||
llvm::Constant *GetPropertyFn, *SetPropertyFn;
|
||||
|
||||
llvm::Function *EnumerationMutationFn;
|
||||
llvm::Constant *EnumerationMutationFn;
|
||||
|
||||
/// GcReadWeakFn -- LLVM objc_read_weak (id *src) function.
|
||||
llvm::Function *GcReadWeakFn;
|
||||
llvm::Constant *GcReadWeakFn;
|
||||
|
||||
/// GcAssignWeakFn -- LLVM objc_assign_weak function.
|
||||
llvm::Function *GcAssignWeakFn;
|
||||
llvm::Constant *GcAssignWeakFn;
|
||||
|
||||
/// GcAssignGlobalFn -- LLVM objc_assign_global function.
|
||||
llvm::Function *GcAssignGlobalFn;
|
||||
llvm::Constant *GcAssignGlobalFn;
|
||||
|
||||
/// GcAssignIvarFn -- LLVM objc_assign_ivar function.
|
||||
llvm::Function *GcAssignIvarFn;
|
||||
llvm::Constant *GcAssignIvarFn;
|
||||
|
||||
/// GcAssignStrongCastFn -- LLVM objc_assign_strongCast function.
|
||||
llvm::Function *GcAssignStrongCastFn;
|
||||
llvm::Constant *GcAssignStrongCastFn;
|
||||
|
||||
/// ExceptionThrowFn - LLVM objc_exception_throw function.
|
||||
llvm::Function *ExceptionThrowFn;
|
||||
llvm::Constant *ExceptionThrowFn;
|
||||
|
||||
/// SyncEnterFn - LLVM object_sync_enter function.
|
||||
llvm::Function *SyncEnterFn;
|
||||
llvm::Constant *SyncEnterFn;
|
||||
|
||||
/// SyncExitFn - LLVM object_sync_exit function.
|
||||
llvm::Function *SyncExitFn;
|
||||
llvm::Constant *SyncExitFn;
|
||||
|
||||
ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm);
|
||||
~ObjCCommonTypesHelper(){}
|
||||
|
@ -121,8 +121,8 @@ public:
|
|||
class ObjCTypesHelper : public ObjCCommonTypesHelper {
|
||||
private:
|
||||
|
||||
llvm::Function *MessageSendFn, *MessageSendStretFn, *MessageSendFpretFn;
|
||||
llvm::Function *MessageSendSuperFn, *MessageSendSuperStretFn,
|
||||
llvm::Constant *MessageSendFn, *MessageSendStretFn, *MessageSendFpretFn;
|
||||
llvm::Constant *MessageSendSuperFn, *MessageSendSuperStretFn,
|
||||
*MessageSendSuperFpretFn;
|
||||
|
||||
public:
|
||||
|
@ -181,34 +181,34 @@ public:
|
|||
const llvm::Type *ExceptionDataTy;
|
||||
|
||||
/// ExceptionTryEnterFn - LLVM objc_exception_try_enter function.
|
||||
llvm::Function *ExceptionTryEnterFn;
|
||||
llvm::Constant *ExceptionTryEnterFn;
|
||||
|
||||
/// ExceptionTryExitFn - LLVM objc_exception_try_exit function.
|
||||
llvm::Function *ExceptionTryExitFn;
|
||||
llvm::Constant *ExceptionTryExitFn;
|
||||
|
||||
/// ExceptionExtractFn - LLVM objc_exception_extract function.
|
||||
llvm::Function *ExceptionExtractFn;
|
||||
llvm::Constant *ExceptionExtractFn;
|
||||
|
||||
/// ExceptionMatchFn - LLVM objc_exception_match function.
|
||||
llvm::Function *ExceptionMatchFn;
|
||||
llvm::Constant *ExceptionMatchFn;
|
||||
|
||||
/// SetJmpFn - LLVM _setjmp function.
|
||||
llvm::Function *SetJmpFn;
|
||||
llvm::Constant *SetJmpFn;
|
||||
|
||||
public:
|
||||
ObjCTypesHelper(CodeGen::CodeGenModule &cgm);
|
||||
~ObjCTypesHelper() {}
|
||||
|
||||
|
||||
llvm::Function *getSendFn(bool IsSuper) {
|
||||
llvm::Constant *getSendFn(bool IsSuper) {
|
||||
return IsSuper ? MessageSendSuperFn : MessageSendFn;
|
||||
}
|
||||
|
||||
llvm::Function *getSendStretFn(bool IsSuper) {
|
||||
llvm::Constant *getSendStretFn(bool IsSuper) {
|
||||
return IsSuper ? MessageSendSuperStretFn : MessageSendStretFn;
|
||||
}
|
||||
|
||||
llvm::Function *getSendFpretFn(bool IsSuper) {
|
||||
llvm::Constant *getSendFpretFn(bool IsSuper) {
|
||||
return IsSuper ? MessageSendSuperFpretFn : MessageSendFpretFn;
|
||||
}
|
||||
};
|
||||
|
@ -217,7 +217,7 @@ public:
|
|||
/// modern abi
|
||||
class ObjCNonFragileABITypesHelper : public ObjCCommonTypesHelper {
|
||||
public:
|
||||
llvm::Function *MessageSendFixupFn, *MessageSendFpretFixupFn,
|
||||
llvm::Constant *MessageSendFixupFn, *MessageSendFpretFixupFn,
|
||||
*MessageSendStretFixupFn, *MessageSendIdFixupFn,
|
||||
*MessageSendIdStretFixupFn, *MessageSendSuper2FixupFn,
|
||||
*MessageSendSuper2StretFixupFn;
|
||||
|
@ -297,7 +297,7 @@ public:
|
|||
/// exception personality function.
|
||||
llvm::Value *EHPersonalityPtr;
|
||||
|
||||
llvm::Function *UnwindResumeOrRethrowFn, *ObjCBeginCatchFn, *ObjCEndCatchFn;
|
||||
llvm::Constant *UnwindResumeOrRethrowFn, *ObjCBeginCatchFn, *ObjCEndCatchFn;
|
||||
|
||||
const llvm::StructType *EHTypeTy;
|
||||
const llvm::Type *EHTypePtrTy;
|
||||
|
@ -652,9 +652,9 @@ private:
|
|||
virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder,
|
||||
const ObjCProtocolDecl *PD);
|
||||
|
||||
virtual llvm::Function *GetPropertyGetFunction();
|
||||
virtual llvm::Function *GetPropertySetFunction();
|
||||
virtual llvm::Function *EnumerationMutationFunction();
|
||||
virtual llvm::Constant *GetPropertyGetFunction();
|
||||
virtual llvm::Constant *GetPropertySetFunction();
|
||||
virtual llvm::Constant *EnumerationMutationFunction();
|
||||
|
||||
virtual void EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
|
||||
const Stmt &S);
|
||||
|
@ -817,13 +817,13 @@ public:
|
|||
virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder,
|
||||
const ObjCProtocolDecl *PD);
|
||||
|
||||
virtual llvm::Function *GetPropertyGetFunction(){
|
||||
virtual llvm::Constant *GetPropertyGetFunction() {
|
||||
return ObjCTypes.GetPropertyFn;
|
||||
}
|
||||
virtual llvm::Function *GetPropertySetFunction(){
|
||||
virtual llvm::Constant *GetPropertySetFunction() {
|
||||
return ObjCTypes.SetPropertyFn;
|
||||
}
|
||||
virtual llvm::Function *EnumerationMutationFunction() {
|
||||
virtual llvm::Constant *EnumerationMutationFunction() {
|
||||
return ObjCTypes.EnumerationMutationFn;
|
||||
}
|
||||
|
||||
|
@ -1879,16 +1879,15 @@ llvm::Function *CGObjCMac::ModuleInitFunction() {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
llvm::Function *CGObjCMac::GetPropertyGetFunction() {
|
||||
llvm::Constant *CGObjCMac::GetPropertyGetFunction() {
|
||||
return ObjCTypes.GetPropertyFn;
|
||||
}
|
||||
|
||||
llvm::Function *CGObjCMac::GetPropertySetFunction() {
|
||||
llvm::Constant *CGObjCMac::GetPropertySetFunction() {
|
||||
return ObjCTypes.SetPropertyFn;
|
||||
}
|
||||
|
||||
llvm::Function *CGObjCMac::EnumerationMutationFunction()
|
||||
{
|
||||
llvm::Constant *CGObjCMac::EnumerationMutationFunction() {
|
||||
return ObjCTypes.EnumerationMutationFn;
|
||||
}
|
||||
|
||||
|
|
|
@ -123,10 +123,10 @@ public:
|
|||
const ObjCContainerDecl *CD) = 0;
|
||||
|
||||
/// Return the runtime function for getting properties.
|
||||
virtual llvm::Function *GetPropertyGetFunction() = 0;
|
||||
virtual llvm::Constant *GetPropertyGetFunction() = 0;
|
||||
|
||||
/// Return the runtime function for setting properties.
|
||||
virtual llvm::Function *GetPropertySetFunction() = 0;
|
||||
virtual llvm::Constant *GetPropertySetFunction() = 0;
|
||||
|
||||
/// GetClass - Return a reference to the class for the given
|
||||
/// interface decl.
|
||||
|
@ -135,7 +135,7 @@ public:
|
|||
|
||||
/// EnumerationMutationFunction - Return the function that's called by the
|
||||
/// compiler when a mutation is detected during foreach iteration.
|
||||
virtual llvm::Function *EnumerationMutationFunction() = 0;
|
||||
virtual llvm::Constant *EnumerationMutationFunction() = 0;
|
||||
|
||||
/// If instance variable addresses are determined at runtime then this should
|
||||
/// return true, otherwise instance variables will be accessed directly from
|
||||
|
|
|
@ -66,53 +66,6 @@ void CodeGenModule::Release() {
|
|||
EmitCtorList(GlobalDtors, "llvm.global_dtors");
|
||||
EmitAnnotations();
|
||||
EmitLLVMUsed();
|
||||
BindRuntimeGlobals();
|
||||
}
|
||||
|
||||
void CodeGenModule::BindRuntimeGlobals() {
|
||||
// Deal with protecting runtime function names.
|
||||
for (unsigned i = 0, e = RuntimeGlobals.size(); i < e; ++i) {
|
||||
llvm::GlobalValue *GV = RuntimeGlobals[i].first;
|
||||
const std::string &Name = RuntimeGlobals[i].second;
|
||||
|
||||
// Discard unused runtime declarations.
|
||||
if (GV->isDeclaration() && GV->use_empty()) {
|
||||
GV->eraseFromParent();
|
||||
continue;
|
||||
}
|
||||
|
||||
// See if there is a conflict against a function by setting the name and
|
||||
// seeing if we got the desired name.
|
||||
GV->setName(Name);
|
||||
if (GV->isName(Name.c_str()))
|
||||
continue; // Yep, it worked!
|
||||
|
||||
GV->setName(""); // Zap the bogus name until we work out the conflict.
|
||||
llvm::GlobalValue *Conflict = TheModule.getNamedValue(Name);
|
||||
assert(Conflict && "Must have conflicted!");
|
||||
|
||||
// Decide which version to take. If the conflict is a definition
|
||||
// we are forced to take that, otherwise assume the runtime
|
||||
// knows best.
|
||||
|
||||
// FIXME: This will fail phenomenally when the conflict is the
|
||||
// wrong type of value. Just bail on it for now. This should
|
||||
// really reuse something inside the LLVM Linker code.
|
||||
assert(GV->getValueID() == Conflict->getValueID() &&
|
||||
"Unable to resolve conflict between globals of different types.");
|
||||
if (!Conflict->isDeclaration()) {
|
||||
llvm::Value *Casted =
|
||||
llvm::ConstantExpr::getBitCast(Conflict, GV->getType());
|
||||
GV->replaceAllUsesWith(Casted);
|
||||
GV->eraseFromParent();
|
||||
} else {
|
||||
GV->takeName(Conflict);
|
||||
llvm::Value *Casted =
|
||||
llvm::ConstantExpr::getBitCast(GV, Conflict->getType());
|
||||
Conflict->replaceAllUsesWith(Casted);
|
||||
Conflict->eraseFromParent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// ErrorUnsupported - Print out an error that codegen doesn't support the
|
||||
|
@ -585,17 +538,17 @@ void CodeGenModule::EmitGlobalDefinition(const ValueDecl *D) {
|
|||
}
|
||||
}
|
||||
|
||||
/// GetAddrOfFunction - Return the address of the given function. If Ty is
|
||||
/// non-null, then this function will use the specified type if it has to
|
||||
/// create it (this occurs when we see a definition of the function).
|
||||
llvm::Constant *CodeGenModule::GetAddrOfFunction(const FunctionDecl *D,
|
||||
const llvm::Type *Ty) {
|
||||
// If there was no specific requested type, just convert it now.
|
||||
if (!Ty)
|
||||
Ty = getTypes().ConvertType(D->getType());
|
||||
|
||||
/// GetOrCreateLLVMFunction - If the specified mangled name is not in the
|
||||
/// module, create and return an llvm Function with the specified type. If there
|
||||
/// is something in the module with the specified name, return it potentially
|
||||
/// bitcasted to the right type.
|
||||
///
|
||||
/// If D is non-null, it specifies a decl that correspond to this. This is used
|
||||
/// to set the attributes on the function when it is first created.
|
||||
llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction(const char *MangledName,
|
||||
const llvm::Type *Ty,
|
||||
const FunctionDecl *D) {
|
||||
// Lookup the entry, lazily creating it if necessary.
|
||||
const char *MangledName = getMangledName(D);
|
||||
llvm::GlobalValue *&Entry = GlobalDeclMap[MangledName];
|
||||
if (Entry) {
|
||||
if (Entry->getType()->getElementType() == Ty)
|
||||
|
@ -610,7 +563,7 @@ llvm::Constant *CodeGenModule::GetAddrOfFunction(const FunctionDecl *D,
|
|||
// deferred decl with this name, remember that we need to emit it at the end
|
||||
// of the file.
|
||||
llvm::DenseMap<const char*, const ValueDecl*>::iterator DDI =
|
||||
DeferredDecls.find(MangledName);
|
||||
DeferredDecls.find(MangledName);
|
||||
if (DDI != DeferredDecls.end()) {
|
||||
// Move the potentially referenced deferred decl to the DeferredDeclsToEmit
|
||||
// list, and remove it from DeferredDecls (since we don't need it anymore).
|
||||
|
@ -618,7 +571,6 @@ llvm::Constant *CodeGenModule::GetAddrOfFunction(const FunctionDecl *D,
|
|||
DeferredDecls.erase(DDI);
|
||||
}
|
||||
|
||||
|
||||
// This function doesn't have a complete type (for example, the return
|
||||
// type is an incomplete struct). Use a fake type instead, and make
|
||||
// sure not to try to set attributes.
|
||||
|
@ -632,35 +584,51 @@ llvm::Constant *CodeGenModule::GetAddrOfFunction(const FunctionDecl *D,
|
|||
llvm::Function::ExternalLinkage,
|
||||
"", &getModule());
|
||||
F->setName(MangledName);
|
||||
if (ShouldSetAttributes)
|
||||
if (D && ShouldSetAttributes)
|
||||
SetFunctionAttributes(D, F);
|
||||
Entry = F;
|
||||
return F;
|
||||
}
|
||||
|
||||
/// GetAddrOfGlobalVar - Return the llvm::Constant for the address of the
|
||||
/// given global variable. If Ty is non-null and if the global doesn't exist,
|
||||
/// then it will be greated with the specified type instead of whatever the
|
||||
/// normal requested type would be.
|
||||
llvm::Constant *CodeGenModule::GetAddrOfGlobalVar(const VarDecl *D,
|
||||
const llvm::Type *Ty) {
|
||||
assert(D->hasGlobalStorage() && "Not a global variable");
|
||||
/// GetAddrOfFunction - Return the address of the given function. If Ty is
|
||||
/// non-null, then this function will use the specified type if it has to
|
||||
/// create it (this occurs when we see a definition of the function).
|
||||
llvm::Constant *CodeGenModule::GetAddrOfFunction(const FunctionDecl *D,
|
||||
const llvm::Type *Ty) {
|
||||
// If there was no specific requested type, just convert it now.
|
||||
if (!Ty)
|
||||
Ty = getTypes().ConvertType(D->getType());
|
||||
return GetOrCreateLLVMFunction(getMangledName(D), Ty, D);
|
||||
}
|
||||
|
||||
QualType ASTTy = D->getType();
|
||||
if (Ty == 0)
|
||||
Ty = getTypes().ConvertTypeForMem(ASTTy);
|
||||
/// CreateRuntimeFunction - Create a new runtime function with the specified
|
||||
/// type and name.
|
||||
llvm::Constant *
|
||||
CodeGenModule::CreateRuntimeFunction(const llvm::FunctionType *FTy,
|
||||
const char *Name) {
|
||||
// Convert Name to be a uniqued string from the IdentifierInfo table.
|
||||
Name = getContext().Idents.get(Name).getName();
|
||||
return GetOrCreateLLVMFunction(Name, FTy, 0);
|
||||
}
|
||||
|
||||
/// GetOrCreateLLVMGlobal - If the specified mangled name is not in the module,
|
||||
/// create and return an llvm GlobalVariable with the specified type. If there
|
||||
/// is something in the module with the specified name, return it potentially
|
||||
/// bitcasted to the right type.
|
||||
///
|
||||
/// If D is non-null, it specifies a decl that correspond to this. This is used
|
||||
/// to set the attributes on the global when it is first created.
|
||||
llvm::Constant *CodeGenModule::GetOrCreateLLVMGlobal(const char *MangledName,
|
||||
const llvm::PointerType*Ty,
|
||||
const VarDecl *D) {
|
||||
// Lookup the entry, lazily creating it if necessary.
|
||||
const char *MangledName = getMangledName(D);
|
||||
llvm::GlobalValue *&Entry = GlobalDeclMap[MangledName];
|
||||
if (Entry) {
|
||||
if (Entry->getType()->getElementType() == Ty &&
|
||||
Entry->getType()->getAddressSpace() == ASTTy.getAddressSpace())
|
||||
if (Entry->getType() == Ty)
|
||||
return Entry;
|
||||
|
||||
// Make sure the result is of the correct type.
|
||||
const llvm::Type *PTy = llvm::PointerType::get(Ty, ASTTy.getAddressSpace());
|
||||
return llvm::ConstantExpr::getBitCast(Entry, PTy);
|
||||
return llvm::ConstantExpr::getBitCast(Entry, Ty);
|
||||
}
|
||||
|
||||
// This is the first use or definition of a mangled name. If there is a
|
||||
|
@ -676,30 +644,56 @@ llvm::Constant *CodeGenModule::GetAddrOfGlobalVar(const VarDecl *D,
|
|||
}
|
||||
|
||||
llvm::GlobalVariable *GV =
|
||||
new llvm::GlobalVariable(Ty, false,
|
||||
new llvm::GlobalVariable(Ty->getElementType(), false,
|
||||
llvm::GlobalValue::ExternalLinkage,
|
||||
0, "", &getModule(),
|
||||
0, ASTTy.getAddressSpace());
|
||||
0, Ty->getAddressSpace());
|
||||
GV->setName(MangledName);
|
||||
|
||||
// Handle things which are present even on external declarations.
|
||||
if (D) {
|
||||
// FIXME: This code is overly simple and should be merged with
|
||||
// other global handling.
|
||||
GV->setConstant(D->getType().isConstant(Context));
|
||||
|
||||
// FIXME: This code is overly simple and should be merged with
|
||||
// other global handling.
|
||||
|
||||
GV->setConstant(D->getType().isConstant(Context));
|
||||
|
||||
// FIXME: Merge with other attribute handling code.
|
||||
|
||||
if (D->getStorageClass() == VarDecl::PrivateExtern)
|
||||
setGlobalVisibility(GV, VisibilityAttr::HiddenVisibility);
|
||||
|
||||
if (D->getAttr<WeakAttr>() || D->getAttr<WeakImportAttr>())
|
||||
GV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
|
||||
// FIXME: Merge with other attribute handling code.
|
||||
if (D->getStorageClass() == VarDecl::PrivateExtern)
|
||||
setGlobalVisibility(GV, VisibilityAttr::HiddenVisibility);
|
||||
|
||||
if (D->getAttr<WeakAttr>() || D->getAttr<WeakImportAttr>())
|
||||
GV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
|
||||
}
|
||||
|
||||
return Entry = GV;
|
||||
}
|
||||
|
||||
|
||||
/// GetAddrOfGlobalVar - Return the llvm::Constant for the address of the
|
||||
/// given global variable. If Ty is non-null and if the global doesn't exist,
|
||||
/// then it will be greated with the specified type instead of whatever the
|
||||
/// normal requested type would be.
|
||||
llvm::Constant *CodeGenModule::GetAddrOfGlobalVar(const VarDecl *D,
|
||||
const llvm::Type *Ty) {
|
||||
assert(D->hasGlobalStorage() && "Not a global variable");
|
||||
QualType ASTTy = D->getType();
|
||||
if (Ty == 0)
|
||||
Ty = getTypes().ConvertTypeForMem(ASTTy);
|
||||
|
||||
const llvm::PointerType *PTy =
|
||||
llvm::PointerType::get(Ty, ASTTy.getAddressSpace());
|
||||
return GetOrCreateLLVMGlobal(getMangledName(D), PTy, D);
|
||||
}
|
||||
|
||||
/// CreateRuntimeVariable - Create a new runtime global variable with the
|
||||
/// specified type and name.
|
||||
llvm::Constant *
|
||||
CodeGenModule::CreateRuntimeVariable(const llvm::Type *Ty,
|
||||
const char *Name) {
|
||||
// Convert Name to be a uniqued string from the IdentifierInfo table.
|
||||
Name = getContext().Idents.get(Name).getName();
|
||||
return GetOrCreateLLVMGlobal(Name, llvm::PointerType::getUnqual(Ty), 0);
|
||||
}
|
||||
|
||||
void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {
|
||||
llvm::Constant *Init = 0;
|
||||
QualType ASTTy = D->getType();
|
||||
|
@ -919,27 +913,6 @@ void CodeGenModule::EmitGlobalFunctionDefinition(const FunctionDecl *D) {
|
|||
AddGlobalDtor(Fn, DA->getPriority());
|
||||
}
|
||||
|
||||
llvm::Function *
|
||||
CodeGenModule::CreateRuntimeFunction(const llvm::FunctionType *FTy,
|
||||
const std::string &Name) {
|
||||
llvm::Function *Fn = llvm::Function::Create(FTy,
|
||||
llvm::Function::ExternalLinkage,
|
||||
"", &TheModule);
|
||||
RuntimeGlobals.push_back(std::make_pair(Fn, Name));
|
||||
return Fn;
|
||||
}
|
||||
|
||||
llvm::GlobalVariable *
|
||||
CodeGenModule::CreateRuntimeVariable(const llvm::Type *Ty,
|
||||
const std::string &Name) {
|
||||
llvm::GlobalVariable *GV =
|
||||
new llvm::GlobalVariable(Ty, /*Constant=*/false,
|
||||
llvm::GlobalValue::ExternalLinkage,
|
||||
0, "", &TheModule);
|
||||
RuntimeGlobals.push_back(std::make_pair(GV, Name));
|
||||
return GV;
|
||||
}
|
||||
|
||||
void CodeGenModule::UpdateCompletedType(const TagDecl *TD) {
|
||||
// Make sure that this type is translated.
|
||||
Types.UpdateCompletedType(TD);
|
||||
|
|
|
@ -82,12 +82,6 @@ class CodeGenModule : public BlockModule {
|
|||
llvm::Function *MemMoveFn;
|
||||
llvm::Function *MemSetFn;
|
||||
|
||||
/// RuntimeGlobal - List of runtime globals whose names must be
|
||||
/// protected from introducing conflicts. These globals should be
|
||||
/// created unnamed, we will name them and patch up conflicts when
|
||||
/// we release the module.
|
||||
std::vector<std::pair<llvm::GlobalValue*, std::string> > RuntimeGlobals;
|
||||
|
||||
/// GlobalDeclMap - Mapping of decl names (represented as unique
|
||||
/// character pointers from either the identifier table or the set
|
||||
/// of mangled names) to global variables we have already
|
||||
|
@ -254,14 +248,14 @@ public:
|
|||
|
||||
void AddAnnotation(llvm::Constant *C) { Annotations.push_back(C); }
|
||||
|
||||
/// CreateRuntimeFunction - Create a new runtime function whose name must be
|
||||
/// protected from collisions.
|
||||
llvm::Function *CreateRuntimeFunction(const llvm::FunctionType *Ty,
|
||||
const std::string &Name);
|
||||
/// CreateRuntimeVariable - Create a new runtime global variable
|
||||
/// whose name must be protected from collisions.
|
||||
llvm::GlobalVariable *CreateRuntimeVariable(const llvm::Type *Ty,
|
||||
const std::string &Name);
|
||||
/// CreateRuntimeFunction - Create a new runtime function with the specified
|
||||
/// type and name.
|
||||
llvm::Constant *CreateRuntimeFunction(const llvm::FunctionType *Ty,
|
||||
const char *Name);
|
||||
/// CreateRuntimeVariable - Create a new runtime global variable with the
|
||||
/// specified type and name.
|
||||
llvm::Constant *CreateRuntimeVariable(const llvm::Type *Ty,
|
||||
const char *Name);
|
||||
|
||||
void UpdateCompletedType(const TagDecl *D);
|
||||
|
||||
|
@ -306,6 +300,13 @@ public:
|
|||
|
||||
|
||||
private:
|
||||
llvm::Constant *GetOrCreateLLVMFunction(const char *MangledName,
|
||||
const llvm::Type *Ty,
|
||||
const FunctionDecl *D);
|
||||
llvm::Constant *GetOrCreateLLVMGlobal(const char *MangledName,
|
||||
const llvm::PointerType *PTy,
|
||||
const VarDecl *D);
|
||||
|
||||
/// SetGlobalValueAttributes - Set attributes for a global decl.
|
||||
void SetGlobalValueAttributes(const Decl *D,
|
||||
bool IsInternal,
|
||||
|
@ -352,8 +353,6 @@ private:
|
|||
/// references to global which may otherwise be optimized out.
|
||||
void EmitLLVMUsed(void);
|
||||
|
||||
void BindRuntimeGlobals();
|
||||
|
||||
/// MayDeferGeneration - Determine if the given decl can be emitted
|
||||
/// lazily; this is only relevant for definitions. The given decl
|
||||
/// must be either a function or var decl.
|
||||
|
|
Loading…
Reference in New Issue