]> granicus.if.org Git - clang/commitdiff
make alias definition logic more similar to functions/globals.
authorChris Lattner <sabre@nondot.org>
Sun, 22 Mar 2009 21:39:12 +0000 (21:39 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 22 Mar 2009 21:39:12 +0000 (21:39 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67481 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CodeGenModule.cpp
test/CodeGen/alias.c

index f5ce056046d36882388d5a5f11a3e7ca6e0056b8..21f67901d12e1bd5e506f04b9469b314ed864969 100644 (file)
@@ -343,8 +343,8 @@ void CodeGenModule::EmitAliases() {
     const char *AliaseeName = AA->getAliasee().c_str();
     AliaseeName = getContext().Idents.get(AliaseeName).getName();
 
-    
-    
+    // Create a reference to the named value.  This ensures that it is emitted
+    // if a deferred decl.
     llvm::Constant *Aliasee;
     if (isa<llvm::FunctionType>(DeclTy))
       Aliasee = GetOrCreateLLVMFunction(AliaseeName, DeclTy, 0);
@@ -352,24 +352,41 @@ void CodeGenModule::EmitAliases() {
       Aliasee = GetOrCreateLLVMGlobal(AliaseeName,
                                       llvm::PointerType::getUnqual(DeclTy), 0);
 
-    const char *MangledName = getMangledName(D);
+    // Create the new alias itself, but don't set a name yet.
     llvm::GlobalValue *GA = 
       new llvm::GlobalAlias(Aliasee->getType(),
                             llvm::Function::ExternalLinkage,
-                            MangledName, Aliasee, &getModule());
+                            "", Aliasee, &getModule());
     
+    // See if there is already something with the alias' name in the module.
+    const char *MangledName = getMangledName(D);
     llvm::GlobalValue *&Entry = GlobalDeclMap[MangledName];
+    
+    if (Entry && !Entry->isDeclaration()) {
+      // If there is a definition in the module, then it wins over the alias.
+      // This is dubious, but allow it to be safe.  Just ignore the alias.
+      delete GA;
+      continue;
+    }
+    
     if (Entry) {
-      // If we created a dummy function for this then replace it.
-      GA->takeName(Entry);
-            
-      llvm::Value *Casted = 
-        llvm::ConstantExpr::getBitCast(GA, Entry->getType());
-      Entry->replaceAllUsesWith(Casted);
+      // If there is a declaration in the module, then we had an extern followed
+      // by the alias, as in:
+      //   extern int test6();
+      //   ...
+      //   int test6() __attribute__((alias("test7")));
+      //
+      // Remove it and replace uses of it with the alias.
+      
+      Entry->replaceAllUsesWith(llvm::ConstantExpr::getBitCast(GA,
+                                                            Entry->getType()));
+      // FIXME: What if it was attribute used?  Dangling pointer from LLVMUsed.
       Entry->eraseFromParent();
-
-      Entry = GA;
     }
+    
+    // Now we know that there is no conflict, set the name.
+    Entry = GA;
+    GA->setName(MangledName);
 
     // Alias should never be internal or inline.
     SetGlobalValueAttributes(D, false, false, GA, true);
index 9de1676f4d0dc766efb1c59096bc37348e1c128f..8fa788a6a216fc97dafb84e6082a07fa0ec6cbb5 100644 (file)
@@ -23,3 +23,10 @@ int foo() __attribute__((alias("foo1")));
 static inline int bar1 = 42;
 int bar() __attribute__((alias("bar1")));
 
+
+extern int test6();
+void test7() { test6(); }  // test6 is emitted as extern.
+
+// test6 changes to alias.
+int test6() __attribute__((alias("test7")));
+