static void convertAliasToDeclaration(GlobalAlias &GA, Module &M) { GlobalValue *GVal = GA.getBaseObject(); GlobalValue *NewGV; if (auto *GVar = dyn_cast<GlobalVariable>(GVal)) { GlobalVariable *NewGVar = new GlobalVariable( M, GVar->getType()->getElementType(), GVar->isConstant(), GVar->getLinkage(), /*init*/ nullptr, GA.getName(), GVar, GVar->getThreadLocalMode(), GVar->getType()->getAddressSpace()); NewGV = NewGVar; NewGV->copyAttributesFrom(GVar); } else { auto *F = dyn_cast<Function>(GVal); assert(F); Function *NewF = Function::Create(F->getFunctionType(), F->getLinkage(), GA.getName(), &M); NewGV = NewF; NewGV->copyAttributesFrom(F); } GA.replaceAllUsesWith(ConstantExpr::getBitCast(NewGV, GA.getType())); GA.eraseFromParent(); }
// emit_alias_to_llvm - Given decl and target emit alias to target. void emit_alias_to_llvm(tree decl, tree target, tree target_decl) { if (errorcount || sorrycount) return; timevar_push(TV_LLVM_GLOBALS); // Get or create LLVM global for our alias. GlobalValue *V = cast<GlobalValue>(DECL_LLVM(decl)); GlobalValue *Aliasee = NULL; if (target_decl) Aliasee = cast<GlobalValue>(DECL_LLVM(target_decl)); else { // This is something insane. Probably only LTHUNKs can be here // Try to grab decl from IDENTIFIER_NODE // Query SymTab for aliasee const char* AliaseeName = IDENTIFIER_POINTER(target); Aliasee = dyn_cast_or_null<GlobalValue>(TheModule-> getValueSymbolTable().lookup(AliaseeName)); // Last resort. Query for name set via __asm__ if (!Aliasee) { std::string starred = std::string("\001") + AliaseeName; Aliasee = dyn_cast_or_null<GlobalValue>(TheModule-> getValueSymbolTable().lookup(starred)); } if (!Aliasee) { error ("%J%qD aliased to undefined symbol %qE", decl, decl, target); timevar_pop(TV_LLVM_GLOBALS); return; } } GlobalValue::LinkageTypes Linkage; // Check for external weak linkage if (DECL_EXTERNAL(decl) && DECL_WEAK(decl)) Linkage = GlobalValue::WeakLinkage; else if (!TREE_PUBLIC(decl)) Linkage = GlobalValue::InternalLinkage; else Linkage = GlobalValue::ExternalLinkage; GlobalAlias* GA = new GlobalAlias(Aliasee->getType(), Linkage, "", Aliasee, TheModule); // Handle visibility style if (TREE_PUBLIC(decl)) { if (DECL_VISIBILITY(decl) == VISIBILITY_HIDDEN) GA->setVisibility(GlobalValue::HiddenVisibility); else if (DECL_VISIBILITY(decl) == VISIBILITY_PROTECTED) GA->setVisibility(GlobalValue::ProtectedVisibility); } if (V->getType() == GA->getType()) V->replaceAllUsesWith(GA); else if (!V->use_empty()) { error ("%J Alias %qD used with invalid type!", decl, decl); timevar_pop(TV_LLVM_GLOBALS); return; } changeLLVMValue(V, GA); GA->takeName(V); if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) GV->eraseFromParent(); else if (GlobalAlias *GA = dyn_cast<GlobalAlias>(V)) GA->eraseFromParent(); else if (Function *F = dyn_cast<Function>(V)) F->eraseFromParent(); else assert(0 && "Unsuported global value"); TREE_ASM_WRITTEN(decl) = 1; timevar_pop(TV_LLVM_GLOBALS); return; }