diff options
-rw-r--r-- | lib/CodeGen/CodeGenModule.cpp | 20 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenModule.h | 2 | ||||
-rw-r--r-- | test/CodeGen/alias.c | 13 |
3 files changed, 23 insertions, 12 deletions
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index aed067617e..cc460c5959 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -369,7 +369,7 @@ void CodeGenModule::SetFunctionAttributes(const FunctionDecl *FD, void CodeGenModule::EmitAliases() { for (unsigned i = 0, e = Aliases.size(); i != e; ++i) { - const FunctionDecl *D = Aliases[i]; + const ValueDecl *D = Aliases[i]; const AliasAttr *AA = D->getAttr<AliasAttr>(); // This is something of a hack, if the FunctionDecl got overridden @@ -380,7 +380,7 @@ void CodeGenModule::EmitAliases() { continue; const std::string& aliaseeName = AA->getAliasee(); - llvm::Function *aliasee = getModule().getFunction(aliaseeName); + llvm::GlobalValue *aliasee = getModule().getNamedValue(aliaseeName); if (!aliasee) { // FIXME: This isn't unsupported, this is just an error, which // sema should catch, but... @@ -539,16 +539,14 @@ bool CodeGenModule::MayDeferGeneration(const ValueDecl *Global) { } void CodeGenModule::EmitGlobal(const ValueDecl *Global) { - if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(Global)) { - // Aliases are deferred until code for everything else has been - // emitted. - if (FD->getAttr<AliasAttr>()) { - assert(!FD->isThisDeclarationADefinition() && - "Function alias cannot have a definition!"); - Aliases.push_back(FD); - return; - } + // Aliases are deferred until code for everything else has been + // emitted. + if (Global->getAttr<AliasAttr>()) { + Aliases.push_back(Global); + return; + } + if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(Global)) { // Forward declarations are emitted lazily on first use. if (!FD->isThisDeclarationADefinition()) return; diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index c3a84af0c5..12c103ba62 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -109,7 +109,7 @@ class CodeGenModule : public BlockModule { /// Aliases - List of aliases in module. These cannot be emitted until all the /// code has been seen, as they reference things by name instead of directly /// and may reference forward. - std::vector<const FunctionDecl*> Aliases; + std::vector<const ValueDecl*> Aliases; /// DeferredDecls - List of decls for which code generation has been /// deferred. When the translation unit has been fully processed we diff --git a/test/CodeGen/alias.c b/test/CodeGen/alias.c new file mode 100644 index 0000000000..a625b6aea1 --- /dev/null +++ b/test/CodeGen/alias.c @@ -0,0 +1,13 @@ +// RUN: clang -triple i386-pc-linux-gnu -emit-llvm -o %t %s && +// RUN: grep '@g0 = common global i32 0' %t && +// RUN: grep '@f1 = alias void ()\* @f0' %t && +// RUN: grep '@g1 = alias i32\* @g0' %t && +// RUN: grep 'define void @f0() nounwind {' %t + +void f0(void) { } +extern void f1(void); +extern void f1(void) __attribute((alias("f0"))); + +int g0; +extern int g1; +extern int g1 __attribute((alias("g0"))); |