]> granicus.if.org Git - clang/commitdiff
IRgen support for alias of global variable.
authorDaniel Dunbar <daniel@zuster.org>
Thu, 19 Mar 2009 08:27:24 +0000 (08:27 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Thu, 19 Mar 2009 08:27:24 +0000 (08:27 +0000)
 - PR3818.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67297 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CodeGenModule.cpp
lib/CodeGen/CodeGenModule.h
test/CodeGen/alias.c [new file with mode: 0644]

index aed067617eba89fbad994ad59b177a46dc708875..cc460c595937c1c7d0ced9470e304d98fe57d742 100644 (file)
@@ -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;
index c3a84af0c5be4707214ef07e153ad95fb176edf6..12c103ba62c3a703fde46919aaf1f065d023e2ec 100644 (file)
@@ -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 (file)
index 0000000..a625b6a
--- /dev/null
@@ -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")));