forked from OSchip/llvm-project
[LLVM-C] Improve Bindings For Aliases
Summary: Add wrappers for a module's alias iterators and a getter and setter for the aliasee value. Reviewers: whitequark, deadalnix Reviewed By: whitequark Subscribers: llvm-commits, harlanhaskins Differential Revision: https://reviews.llvm.org/D46808 llvm-svn: 332826
This commit is contained in:
parent
55b4067350
commit
360d6e35e6
|
@ -2117,6 +2117,56 @@ void LLVMSetExternallyInitialized(LLVMValueRef GlobalVar, LLVMBool IsExtInit);
|
|||
LLVMValueRef LLVMAddAlias(LLVMModuleRef M, LLVMTypeRef Ty, LLVMValueRef Aliasee,
|
||||
const char *Name);
|
||||
|
||||
/**
|
||||
* Obtain a GlobalAlias value from a Module by its name.
|
||||
*
|
||||
* The returned value corresponds to a llvm::GlobalAlias value.
|
||||
*
|
||||
* @see llvm::Module::getNamedAlias()
|
||||
*/
|
||||
LLVMValueRef LLVMGetNamedGlobalAlias(LLVMModuleRef M,
|
||||
const char *Name, size_t NameLen);
|
||||
|
||||
/**
|
||||
* Obtain an iterator to the first GlobalAlias in a Module.
|
||||
*
|
||||
* @see llvm::Module::alias_begin()
|
||||
*/
|
||||
LLVMValueRef LLVMGetFirstGlobalAlias(LLVMModuleRef M);
|
||||
|
||||
/**
|
||||
* Obtain an iterator to the last GlobalAlias in a Module.
|
||||
*
|
||||
* @see llvm::Module::alias_end()
|
||||
*/
|
||||
LLVMValueRef LLVMGetLastGlobalAlias(LLVMModuleRef M);
|
||||
|
||||
/**
|
||||
* Advance a GlobalAlias iterator to the next GlobalAlias.
|
||||
*
|
||||
* Returns NULL if the iterator was already at the end and there are no more
|
||||
* global aliases.
|
||||
*/
|
||||
LLVMValueRef LLVMGetNextGlobalAlias(LLVMValueRef GA);
|
||||
|
||||
/**
|
||||
* Decrement a GlobalAlias iterator to the previous GlobalAlias.
|
||||
*
|
||||
* Returns NULL if the iterator was already at the beginning and there are
|
||||
* no previous global aliases.
|
||||
*/
|
||||
LLVMValueRef LLVMGetPreviousGlobalAlias(LLVMValueRef GA);
|
||||
|
||||
/**
|
||||
* Retrieve the target value of an alias.
|
||||
*/
|
||||
LLVMValueRef LLVMAliasGetAliasee(LLVMValueRef Alias);
|
||||
|
||||
/**
|
||||
* Set the target value of an alias.
|
||||
*/
|
||||
void LLVMAliasSetAliasee(LLVMValueRef Alias, LLVMValueRef Aliasee);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
|
|
@ -1965,6 +1965,51 @@ LLVMValueRef LLVMAddAlias(LLVMModuleRef M, LLVMTypeRef Ty, LLVMValueRef Aliasee,
|
|||
unwrap<Constant>(Aliasee), unwrap(M)));
|
||||
}
|
||||
|
||||
LLVMValueRef LLVMGetNamedGlobalAlias(LLVMModuleRef M,
|
||||
const char *Name, size_t NameLen) {
|
||||
return wrap(unwrap(M)->getNamedAlias(Name));
|
||||
}
|
||||
|
||||
LLVMValueRef LLVMGetFirstGlobalAlias(LLVMModuleRef M) {
|
||||
Module *Mod = unwrap(M);
|
||||
Module::alias_iterator I = Mod->alias_begin();
|
||||
if (I == Mod->alias_end())
|
||||
return nullptr;
|
||||
return wrap(&*I);
|
||||
}
|
||||
|
||||
LLVMValueRef LLVMGetLastGlobalAlias(LLVMModuleRef M) {
|
||||
Module *Mod = unwrap(M);
|
||||
Module::alias_iterator I = Mod->alias_end();
|
||||
if (I == Mod->alias_begin())
|
||||
return nullptr;
|
||||
return wrap(&*--I);
|
||||
}
|
||||
|
||||
LLVMValueRef LLVMGetNextGlobalAlias(LLVMValueRef GA) {
|
||||
GlobalAlias *Alias = unwrap<GlobalAlias>(GA);
|
||||
Module::alias_iterator I(Alias);
|
||||
if (++I == Alias->getParent()->alias_end())
|
||||
return nullptr;
|
||||
return wrap(&*I);
|
||||
}
|
||||
|
||||
LLVMValueRef LLVMGetPreviousGlobalAlias(LLVMValueRef GA) {
|
||||
GlobalAlias *Alias = unwrap<GlobalAlias>(GA);
|
||||
Module::alias_iterator I(Alias);
|
||||
if (I == Alias->getParent()->alias_begin())
|
||||
return nullptr;
|
||||
return wrap(&*--I);
|
||||
}
|
||||
|
||||
LLVMValueRef LLVMAliasGetAliasee(LLVMValueRef Alias) {
|
||||
return wrap(unwrap<GlobalAlias>(Alias)->getAliasee());
|
||||
}
|
||||
|
||||
void LLVMAliasSetAliasee(LLVMValueRef Alias, LLVMValueRef Aliasee) {
|
||||
unwrap<GlobalAlias>(Alias)->setAliasee(unwrap<Constant>(Aliasee));
|
||||
}
|
||||
|
||||
/*--.. Operations on functions .............................................--*/
|
||||
|
||||
LLVMValueRef LLVMAddFunction(LLVMModuleRef M, const char *Name,
|
||||
|
|
|
@ -22,6 +22,12 @@ module asm "classical GAS"
|
|||
@section = global i32 27, section ".custom"
|
||||
@align = global i32 31, align 4
|
||||
|
||||
@aliased1 = alias i32, i32* @var
|
||||
@aliased2 = internal alias i32, i32* @var
|
||||
@aliased3 = external alias i32, i32* @var
|
||||
@aliased4 = weak alias i32, i32* @var
|
||||
@aliased5 = weak_odr alias i32, i32* @var
|
||||
|
||||
define { i64, %S* } @unpackrepack(%S %s) {
|
||||
%1 = extractvalue %S %s, 0
|
||||
%2 = extractvalue %S %s, 1
|
||||
|
|
|
@ -248,10 +248,19 @@ static LLVMValueRef clone_constant_impl(LLVMValueRef Cst, LLVMModuleRef M) {
|
|||
// Try global variable
|
||||
if (LLVMIsAGlobalVariable(Cst)) {
|
||||
check_value_kind(Cst, LLVMGlobalVariableValueKind);
|
||||
LLVMValueRef Dst = LLVMGetNamedGlobal(M, Name);
|
||||
LLVMValueRef Dst = LLVMGetNamedGlobal(M, Name);
|
||||
if (Dst)
|
||||
return Dst;
|
||||
report_fatal_error("Could not find function");
|
||||
report_fatal_error("Could not find variable");
|
||||
}
|
||||
|
||||
// Try global alias
|
||||
if (LLVMIsAGlobalAlias(Cst)) {
|
||||
check_value_kind(Cst, LLVMGlobalAliasValueKind);
|
||||
LLVMValueRef Dst = LLVMGetNamedGlobalAlias(M, Name, NameLen);
|
||||
if (Dst)
|
||||
return Dst;
|
||||
report_fatal_error("Could not find alias");
|
||||
}
|
||||
|
||||
fprintf(stderr, "Could not find @%s\n", Name);
|
||||
|
@ -822,6 +831,8 @@ struct FunCloner {
|
|||
};
|
||||
|
||||
static void declare_symbols(LLVMModuleRef Src, LLVMModuleRef M) {
|
||||
auto Ctx = LLVMGetModuleContext(M);
|
||||
|
||||
LLVMValueRef Begin = LLVMGetFirstGlobal(Src);
|
||||
LLVMValueRef End = LLVMGetLastGlobal(Src);
|
||||
|
||||
|
@ -860,11 +871,9 @@ FunDecl:
|
|||
if (!Begin) {
|
||||
if (End != nullptr)
|
||||
report_fatal_error("Range has an end but no beginning");
|
||||
return;
|
||||
goto AliasDecl;
|
||||
}
|
||||
|
||||
auto Ctx = LLVMGetModuleContext(M);
|
||||
|
||||
Cur = Begin;
|
||||
Next = nullptr;
|
||||
while (true) {
|
||||
|
@ -900,6 +909,40 @@ FunDecl:
|
|||
|
||||
Cur = Next;
|
||||
}
|
||||
|
||||
AliasDecl:
|
||||
Begin = LLVMGetFirstGlobalAlias(Src);
|
||||
End = LLVMGetLastGlobalAlias(Src);
|
||||
if (!Begin) {
|
||||
if (End != nullptr)
|
||||
report_fatal_error("Range has an end but no beginning");
|
||||
return;
|
||||
}
|
||||
|
||||
Cur = Begin;
|
||||
Next = nullptr;
|
||||
while (true) {
|
||||
size_t NameLen;
|
||||
const char *Name = LLVMGetValueName2(Cur, &NameLen);
|
||||
if (LLVMGetNamedGlobalAlias(M, Name, NameLen))
|
||||
report_fatal_error("Global alias already cloned");
|
||||
LLVMTypeRef CurType = TypeCloner(M).Clone(Cur);
|
||||
// FIXME: Allow NULL aliasee.
|
||||
LLVMAddAlias(M, CurType, LLVMGetUndef(CurType), Name);
|
||||
|
||||
Next = LLVMGetNextGlobalAlias(Cur);
|
||||
if (Next == nullptr) {
|
||||
if (Cur != End)
|
||||
report_fatal_error("");
|
||||
break;
|
||||
}
|
||||
|
||||
LLVMValueRef Prev = LLVMGetPreviousGlobalAlias(Next);
|
||||
if (Prev != Cur)
|
||||
report_fatal_error("Next.Previous global is not Current");
|
||||
|
||||
Cur = Next;
|
||||
}
|
||||
}
|
||||
|
||||
static void clone_symbols(LLVMModuleRef Src, LLVMModuleRef M) {
|
||||
|
@ -953,7 +996,7 @@ FunClone:
|
|||
if (!Begin) {
|
||||
if (End != nullptr)
|
||||
report_fatal_error("Range has an end but no beginning");
|
||||
return;
|
||||
goto AliasClone;
|
||||
}
|
||||
|
||||
Cur = Begin;
|
||||
|
@ -991,6 +1034,45 @@ FunClone:
|
|||
|
||||
Cur = Next;
|
||||
}
|
||||
|
||||
AliasClone:
|
||||
Begin = LLVMGetFirstGlobalAlias(Src);
|
||||
End = LLVMGetLastGlobalAlias(Src);
|
||||
if (!Begin) {
|
||||
if (End != nullptr)
|
||||
report_fatal_error("Range has an end but no beginning");
|
||||
return;
|
||||
}
|
||||
|
||||
Cur = Begin;
|
||||
Next = nullptr;
|
||||
while (true) {
|
||||
size_t NameLen;
|
||||
const char *Name = LLVMGetValueName2(Cur, &NameLen);
|
||||
LLVMValueRef Alias = LLVMGetNamedGlobalAlias(M, Name, NameLen);
|
||||
if (!Alias)
|
||||
report_fatal_error("Global alias must have been declared already");
|
||||
|
||||
if (LLVMValueRef Aliasee = LLVMAliasGetAliasee(Cur)) {
|
||||
LLVMAliasSetAliasee(Alias, clone_constant(Aliasee, M));
|
||||
}
|
||||
|
||||
LLVMSetLinkage(Alias, LLVMGetLinkage(Cur));
|
||||
LLVMSetUnnamedAddress(Alias, LLVMGetUnnamedAddress(Cur));
|
||||
|
||||
Next = LLVMGetNextGlobalAlias(Cur);
|
||||
if (Next == nullptr) {
|
||||
if (Cur != End)
|
||||
report_fatal_error("Last global alias does not match End");
|
||||
break;
|
||||
}
|
||||
|
||||
LLVMValueRef Prev = LLVMGetPreviousGlobalAlias(Next);
|
||||
if (Prev != Cur)
|
||||
report_fatal_error("Next.Previous global alias is not Current");
|
||||
|
||||
Cur = Next;
|
||||
}
|
||||
}
|
||||
|
||||
int llvm_echo(void) {
|
||||
|
|
Loading…
Reference in New Issue