Hello Everyone.

This is LLVM part of patch, which enable function aliases for LLVM. The
syntax is pretty simple: it just "mimics" the "section" keyword. I'm
currently working on gcc part of the patch. Please note, that patch
breaks bytecode format (llvm-dev message will follow).

Documentation updates & testcases will be added just after this patch
landed.

-- 
With best regards, Anton Korobeynikov.

Faculty of Mathematics & Mechanics, Saint Petersburg State University.

diff -r 958b34c32d47 include/llvm/CodeGen/AsmPrinter.h
--- a/include/llvm/CodeGen/AsmPrinter.h	Tue Apr 17 21:09:00 2007 +0400
+++ b/include/llvm/CodeGen/AsmPrinter.h	Thu Apr 19 03:17:46 2007 +0400
@@ -24,6 +24,7 @@ namespace llvm {
   class Constant;
   class ConstantArray;
   class GlobalVariable;
+  class FunctionAlias;
   class MachineConstantPoolEntry;
   class MachineConstantPoolValue;
   class Mangler;
@@ -43,6 +44,8 @@ namespace llvm {
   protected:
     // Necessary for external weak linkage support
     std::set<const GlobalValue*> ExtWeakSymbols;
+    // Necessary for aliases support
+    std::set<const FunctionAlias*> FunctionAliases;
 
   public:
     /// Output stream on which we're printing assembly code.
diff -r 958b34c32d47 include/llvm/Function.h
--- a/include/llvm/Function.h	Tue Apr 17 21:09:00 2007 +0400
+++ b/include/llvm/Function.h	Thu Apr 19 01:09:49 2007 +0400
@@ -87,7 +87,8 @@ public:
   /// the module.
   ///
   Function(const FunctionType *Ty, LinkageTypes Linkage,
-           const std::string &N = "", Module *M = 0);
+           const std::string &N = "", Module *M = 0,
+           ValueTy vty = Value::FunctionVal);
   ~Function();
 
   const Type *getReturnType() const;           // Return the type of the ret val
@@ -227,7 +228,8 @@ public:
   /// Methods for support type inquiry through isa, cast, and dyn_cast:
   static inline bool classof(const Function *) { return true; }
   static inline bool classof(const Value *V) {
-    return V->getValueID() == Value::FunctionVal;
+    return V->getValueID() == Value::FunctionVal ||
+           V->getValueID() == Value::FunctionAliasVal;
   }
 
   /// dropAllReferences() - This method causes all the subinstructions to "let
@@ -254,6 +256,27 @@ public:
   }
 };
 
+class FunctionAlias : public Function {
+private:
+  std::string Target;
+public:
+  FunctionAlias(const FunctionType *Ty, LinkageTypes Linkage,
+                const std::string &name, const std::string &target,
+                Module *ParentModule = 0,
+                ValueTy vty = Value::FunctionAliasVal):
+    Function(Ty, Linkage, name, ParentModule, vty), Target(target) {  };
+    
+  std::string getTarget() const { return Target; }
+  void setTarget(const std::string &T) { Target = T; }
+
+  /// Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const FunctionAlias *) { return true; }
+  static inline bool classof(const Value *V) {
+    return V->getValueID() == Value::FunctionAliasVal;
+  }
+
+};
+  
 inline ValueSymbolTable *
 ilist_traits<BasicBlock>::getSymTab(Function *F) {
   return F ? &F->getValueSymbolTable() : 0;
diff -r 958b34c32d47 include/llvm/GlobalValue.h
--- a/include/llvm/GlobalValue.h	Tue Apr 17 21:09:00 2007 +0400
+++ b/include/llvm/GlobalValue.h	Thu Apr 19 01:08:54 2007 +0400
@@ -134,7 +134,8 @@ public:
   static inline bool classof(const GlobalValue *) { return true; }
   static inline bool classof(const Value *V) {
     return V->getValueID() == Value::FunctionVal ||
-           V->getValueID() == Value::GlobalVariableVal;
+           V->getValueID() == Value::GlobalVariableVal ||
+           V->getValueID() == Value::FunctionAliasVal;
   }
 };
 
diff -r 958b34c32d47 include/llvm/Value.h
--- a/include/llvm/Value.h	Tue Apr 17 21:09:00 2007 +0400
+++ b/include/llvm/Value.h	Thu Apr 19 00:34:57 2007 +0400
@@ -29,6 +29,7 @@ class BasicBlock;
 class BasicBlock;
 class GlobalValue;
 class Function;
+class FunctionAlias;
 class GlobalVariable;
 class InlineAsm;
 class ValueSymbolTable;
@@ -160,6 +161,7 @@ public:
     ArgumentVal,              // This is an instance of Argument
     BasicBlockVal,            // This is an instance of BasicBlock
     FunctionVal,              // This is an instance of Function
+    FunctionAliasVal,         // This is an instance of FunctionAlias
     GlobalVariableVal,        // This is an instance of GlobalVariable
     UndefValueVal,            // This is an instance of UndefValue
     ConstantExprVal,          // This is an instance of ConstantExpr
@@ -248,8 +250,12 @@ template <> inline bool isa_impl<GlobalV
 template <> inline bool isa_impl<GlobalVariable, Value>(const Value &Val) {
   return Val.getValueID() == Value::GlobalVariableVal;
 }
+template <> inline bool isa_impl<FunctionAlias, Value>(const Value &Val) {
+  return Val.getValueID() == Value::FunctionAliasVal;
+}
 template <> inline bool isa_impl<GlobalValue, Value>(const Value &Val) {
-  return isa<GlobalVariable>(Val) || isa<Function>(Val);
+  return isa<GlobalVariable>(Val) || isa<Function>(Val) ||
+         isa<FunctionAlias>(Val);
 }
 
 } // End llvm namespace

diff -r 958b34c32d47 lib/AsmParser/Lexer.l
--- a/lib/AsmParser/Lexer.l	Tue Apr 17 21:09:00 2007 +0400
+++ b/lib/AsmParser/Lexer.l	Wed Apr 18 12:23:11 2007 +0400
@@ -222,6 +222,7 @@ volatile        { return VOLATILE; }
 volatile        { return VOLATILE; }
 align           { return ALIGN;  }
 section         { return SECTION; }
+alias           { return ALIAS; }
 module          { return MODULE; }
 asm             { return ASM_TOK; }
 sideeffect      { return SIDEEFFECT; }

diff -r 958b34c32d47 lib/AsmParser/llvmAsmParser.y
--- a/lib/AsmParser/llvmAsmParser.y	Tue Apr 17 21:09:00 2007 +0400
+++ b/lib/AsmParser/llvmAsmParser.y	Thu Apr 19 01:10:20 2007 +0400
@@ -1038,6 +1038,7 @@ Module *llvm::RunVMAsmParser(const char 
 %type <StrVal> GlobalName OptGlobalAssign
 %type <UIntVal> OptAlign OptCAlign
 %type <StrVal> OptSection SectionString
+%type <StrVal> OptAlias AliasTargetString
 
 %token ZEROINITIALIZER TRUETOK FALSETOK BEGINTOK ENDTOK
 %token DECLARE DEFINE GLOBAL CONSTANT SECTION VOLATILE THREAD_LOCAL
@@ -1046,7 +1047,7 @@ Module *llvm::RunVMAsmParser(const char 
 %token OPAQUE EXTERNAL TARGET TRIPLE ALIGN
 %token DEPLIBS CALL TAIL ASM_TOK MODULE SIDEEFFECT
 %token CC_TOK CCC_TOK FASTCC_TOK COLDCC_TOK X86_STDCALLCC_TOK X86_FASTCALLCC_TOK
-%token DATALAYOUT
+%token DATALAYOUT ALIAS
 %type <UIntVal> OptCallingConv
 %type <ParamAttrs> OptParamAttrs ParamAttr 
 %type <ParamAttrs> OptFuncAttrs  FuncAttr
@@ -1243,6 +1244,17 @@ OptSection : /*empty*/ { $$ = 0; } |
 OptSection : /*empty*/ { $$ = 0; } |
              SectionString { $$ = $1; };
 
+AliasTargetString : ALIAS STRINGCONSTANT {
+  for (unsigned i = 0, e = strlen($2); i != e; ++i)
+    if ($2[i] == '"' || $2[i] == '\\')
+      GEN_ERROR("Invalid character in alias name");
+  $$ = $2;
+  CHECK_FOR_ERROR
+};
+
+OptAlias : /*empty*/         { $$ = 0;  } |
+           AliasTargetString { $$ = $1; };
+
 // GlobalVarAttributes - Used to pass the attributes string on a global.  CurGV
 // is set to be the global we are processing.
 //
@@ -2124,7 +2136,7 @@ ArgList : ArgListH {
   };
 
 FunctionHeaderH : OptCallingConv ResultTypes GlobalName '(' ArgList ')' 
-                  OptFuncAttrs OptSection OptAlign {
+                  OptFuncAttrs OptSection OptAlign OptAlias {
   UnEscapeLexed($3);
   std::string FunctionName($3);
   free($3);  // Free strdup'd memory!
@@ -2133,7 +2145,14 @@ FunctionHeaderH : OptCallingConv ResultT
   // have no abstract types at this point
   if (!CurFun.isDeclare && CurModule.TypeIsUnresolved($2))
     GEN_ERROR("Reference to abstract result: "+ $2->get()->getDescription());
-
+  // Check for alias set. We should allow this only on declarations.
+  if (!CurFun.isDeclare && $10) {
+    std::string Message("Alias illegally set on function definition "
+                        "(allowed only on declarations): ");
+    Message += $10;
+    GEN_ERROR(Message);
+  }
+  
   std::vector<const Type*> ParamTypeList;
   ParamAttrsList ParamAttrs;
   if ($7 != ParamAttr::None)
@@ -2184,20 +2203,31 @@ FunctionHeaderH : OptCallingConv ResultT
       // The existing function doesn't have the same type. This is an overload
       // error.
       GEN_ERROR("Overload of function '" + FunctionName + "' not permitted.");
-    } else if (!CurFun.isDeclare && !Fn->isDeclaration()) {
-      // Neither the existing or the current function is a declaration and they
-      // have the same name and same type. Clearly this is a redefinition.
-      GEN_ERROR("Redefinition of function '" + FunctionName + "'");
-    } if (Fn->isDeclaration()) {
+    } else if (!Fn->isDeclaration()) {
+      if (CurFun.isDeclare) {
+        if ($10)
+          GEN_ERROR("Alias-redefinition of function '" + FunctionName + "'");
+      } else {
+        // Neither the existing or the current function is a declaration and they
+        // have the same name and same type. Clearly this is a redefinition.
+        GEN_ERROR("Redefinition of function '" + FunctionName + "'");
+      }
+    }
+    if (Fn->isDeclaration()) {
       // Make sure to strip off any argument names so we can't get conflicts.
       for (Function::arg_iterator AI = Fn->arg_begin(), AE = Fn->arg_end();
            AI != AE; ++AI)
         AI->setName("");
     }
-  } else  {  // Not already defined?
-    Fn = new Function(FT, GlobalValue::ExternalLinkage, FunctionName,
-                      CurModule.CurrentModule);
-
+  } else {  // Not already defined?
+    if ($10) {
+      Fn = new FunctionAlias(FT, GlobalValue::ExternalLinkage, FunctionName,
+                             $10, CurModule.CurrentModule);
+      free($10);
+    } else
+      Fn = new Function(FT, GlobalValue::ExternalLinkage, FunctionName,
+                        CurModule.CurrentModule);
+    
     InsertValue(Fn, CurModule.Values);
   }
 
@@ -2266,7 +2296,7 @@ FunctionProto : FunctionDeclareLinkage G
     $$ = CurFun.CurrentFunction;
     CurFun.FunctionDone();
     CHECK_FOR_ERROR
-  };
+};
 
 //===----------------------------------------------------------------------===//
 //                        Rules to match Basic Blocks

diff -r 958b34c32d47 lib/Bytecode/Reader/Reader.cpp
--- a/lib/Bytecode/Reader/Reader.cpp	Tue Apr 17 21:09:00 2007 +0400
+++ b/lib/Bytecode/Reader/Reader.cpp	Thu Apr 19 02:19:34 2007 +0400
@@ -1699,7 +1699,11 @@ void BytecodeReader::ParseModuleGlobalIn
   // SectionID - If a global has an explicit section specified, this map
   // remembers the ID until we can translate it into a string.
   std::map<GlobalValue*, unsigned> SectionID;
-  
+
+  // AliasID - If a global has an explicit alias target specified, this map
+  // remembers the ID until we can translate it into a string.
+  std::map<GlobalValue*, unsigned> AliasID;
+
   // Read global variables...
   unsigned VarType = read_vbr_uint();
   while (VarType != Type::VoidTyID) { // List is terminated by Void
@@ -1799,15 +1803,28 @@ void BytecodeReader::ParseModuleGlobalIn
       error("Function not a pointer to function type! Ty = " +
             Ty->getDescription());
     }
-
+    // Check for extension word early in order to distinguish functions and
+    // function aliases
+    unsigned ExtWord = 0;
+    bool hasExtWord = FnSignature & (1 << 31); // Has extension word?
+    bool isAlias = false;
+    if (hasExtWord) {
+      ExtWord = read_vbr_uint();
+      isAlias = ((ExtWord >> 13) & 1);
+    }
+    
     // We create functions by passing the underlying FunctionType to create...
     const FunctionType* FTy =
       cast<FunctionType>(cast<PointerType>(Ty)->getElementType());
 
     // Insert the place holder.
-    Function *Func = new Function(FTy, GlobalValue::ExternalLinkage,
-                                  "", TheModule);
-
+    Function *Func;
+    if (!isAlias)
+      Func = new Function(FTy, GlobalValue::ExternalLinkage, "", TheModule);
+    else
+      Func = new FunctionAlias(FTy, GlobalValue::ExternalLinkage, "", "",
+                               TheModule);
+  
     insertValue(Func, (FnSignature & (~0U >> 1)) >> 5, ModuleValues);
 
     // Flags are not used yet.
@@ -1822,14 +1839,16 @@ void BytecodeReader::ParseModuleGlobalIn
     // Get the calling convention from the low bits.
     unsigned CC = Flags & 15;
     unsigned Alignment = 0;
-    if (FnSignature & (1 << 31)) {  // Has extension word?
-      unsigned ExtWord = read_vbr_uint();
+    if (hasExtWord) {  // Has extension word?
       Alignment = (1 << (ExtWord & 31)) >> 1;
       CC |= ((ExtWord >> 5) & 15) << 4;
       
       if (ExtWord & (1 << 10))  // Has a section ID.
         SectionID[Func] = read_vbr_uint();
 
+      if (isAlias)
+        AliasID[Func] = read_vbr_uint();      
+        
       // Parse external declaration linkage
       switch ((ExtWord >> 11) & 3) {
        case 0: break;
@@ -1856,7 +1875,12 @@ void BytecodeReader::ParseModuleGlobalIn
   /// moduleinfoblock.  Functions and globals with an explicit section index
   /// into this to get their section name.
   std::vector<std::string> SectionNames;
-  
+
+  /// AliasesNames - This contains the list of alias targets encoded in the
+  /// moduleinfoblock.  Functions with an explicit alias index into this to get
+  /// their alias target.
+  std::vector<std::string> AliasesNames;
+
   // Read in the dependent library information.
   unsigned num_dep_libs = read_vbr_uint();
   std::string dep_lib;
@@ -1886,7 +1910,14 @@ void BytecodeReader::ParseModuleGlobalIn
     while (NumSections--)
       SectionNames.push_back(read_str());
   }
-  
+
+  if (At != BlockEnd) {
+    // If the file has aliases info in it, read the aliases now.
+    unsigned NumAliases = read_vbr_uint();
+    while (NumAliases--)
+      AliasesNames.push_back(read_str());
+  }
+
   // If the file has module-level inline asm, read it now.
   if (At != BlockEnd)
     TheModule->setModuleInlineAsm(read_str());
@@ -1898,6 +1929,15 @@ void BytecodeReader::ParseModuleGlobalIn
       if (I->second > SectionID.size())
         error("SectionID out of range for global!");
       I->first->setSection(SectionNames[I->second-1]);
+    }
+
+  // If any globals are in specified alias targets, assign them now.
+  for (std::map<GlobalValue*, unsigned>::iterator I = AliasID.begin(), E =
+       AliasID.end(); I != E; ++I)
+    if (I->second) {
+      if (I->second > AliasID.size())
+        error("SectionID out of range for global!");
+      cast<FunctionAlias>(I->first)->setTarget(AliasesNames[I->second-1]);
     }
 
   // This is for future proofing... in the future extra fields may be added that
diff -r 958b34c32d47 lib/Bytecode/Writer/Writer.cpp
--- a/lib/Bytecode/Writer/Writer.cpp	Tue Apr 17 21:09:00 2007 +0400
+++ b/lib/Bytecode/Writer/Writer.cpp	Thu Apr 19 03:46:56 2007 +0400
@@ -941,6 +941,11 @@ void BytecodeWriter::outputModuleInfoBlo
   std::vector<std::string> SectionNames;
   std::map<std::string, unsigned> SectionID;
   
+  // Give numbers to aliases as we encounter them.
+  unsigned AliasIDCounter = 0;
+  std::vector<std::string> AliasesNames;
+  std::map<std::string, unsigned> AliasID;
+
   // Output the types for the global variables in the module...
   for (Module::const_global_iterator I = M->global_begin(),
          End = M->global_end(); I != End; ++I) {
@@ -1004,9 +1009,9 @@ void BytecodeWriter::outputModuleInfoBlo
       ID |= 1 << 4;
     
     if (I->getAlignment() || I->hasSection() || (CC & ~15) != 0 ||
+        isa<FunctionAlias>(I) ||
         (I->isDeclaration() && I->hasDLLImportLinkage()) ||
-        (I->isDeclaration() && I->hasExternalWeakLinkage())
-       )
+        (I->isDeclaration() && I->hasExternalWeakLinkage()))
       ID |= 1 << 31;       // Do we need an extension word?
     
     output_vbr(ID);
@@ -1025,8 +1030,9 @@ void BytecodeWriter::outputModuleInfoBlo
       }
 
       ID = (Log2_32(I->getAlignment())+1) | ((CC >> 4) << 5) | 
-        (I->hasSection() << 10) |
-        ((extLinkage & 3) << 11);
+        (I->hasSection()       << 10) |
+        ((extLinkage & 3)      << 11) |
+        (isa<FunctionAlias>(I) << 13);
       output_vbr(ID);
       
       // Give section names unique ID's.
@@ -1038,6 +1044,17 @@ void BytecodeWriter::outputModuleInfoBlo
         }
         output_vbr(Entry);
       }
+
+      // Give section names unique ID's.
+      if (const FunctionAlias *FA = dyn_cast<FunctionAlias>(I)) {
+        unsigned &Entry = AliasID[FA->getTarget()];
+        if (Entry == 0) {
+          Entry = ++AliasIDCounter;
+          AliasesNames.push_back(FA->getTarget());
+        }
+        output_vbr(Entry);
+      }
+      
     }
   }
   output_vbr(Table.getTypeSlot(Type::VoidTy) << 5);
@@ -1059,7 +1076,12 @@ void BytecodeWriter::outputModuleInfoBlo
   output_vbr((unsigned)SectionNames.size());
   for (unsigned i = 0, e = SectionNames.size(); i != e; ++i)
     output(SectionNames[i]);
-  
+
+  // Emit the table of aliases names.
+  output_vbr((unsigned)AliasesNames.size());
+  for (unsigned i = 0, e = AliasesNames.size(); i != e; ++i)
+    output(AliasesNames[i]);
+
   // Output the inline asm string.
   output(M->getModuleInlineAsm());
 }
diff -r 958b34c32d47 lib/CodeGen/AsmPrinter.cpp
--- a/lib/CodeGen/AsmPrinter.cpp	Tue Apr 17 21:09:00 2007 +0400
+++ b/lib/CodeGen/AsmPrinter.cpp	Thu Apr 19 03:31:27 2007 +0400
@@ -114,6 +114,7 @@ bool AsmPrinter::doFinalization(Module &
     if (ExtWeakSymbols.begin() != ExtWeakSymbols.end())
       SwitchToDataSection("");
 
+    O << "\n";
     for (std::set<const GlobalValue*>::iterator i = ExtWeakSymbols.begin(),
          e = ExtWeakSymbols.end(); i != e; ++i) {
       const GlobalValue *GV = *i;
@@ -122,6 +123,25 @@ bool AsmPrinter::doFinalization(Module &
     }
   }
 
+  if (TAI->getSetDirective()) {
+    if (FunctionAliases.begin() != FunctionAliases.end())
+      SwitchToDataSection("");
+
+    O << "\n";
+    for (std::set<const FunctionAlias*>::iterator I = FunctionAliases.begin(),
+         E = FunctionAliases.end(); I != E; ++I) {
+      const FunctionAlias *FA = *I;
+      std::string Name   = Mang->getValueName(FA);
+      std::string Target = Mang->makeNameProper(FA->getTarget(), "");
+
+      // Aliases with external weak linkage was emitted already
+      if (FA->hasExternalLinkage())
+        O << "\t.globl\t" << Name << "\n";
+      
+      O << TAI->getSetDirective() << Name << ", " << Target << "\n";
+    }    
+  }
+  
   delete Mang; Mang = 0;
   return false;
 }
diff -r 958b34c32d47 lib/Linker/LinkModules.cpp
--- a/lib/Linker/LinkModules.cpp	Tue Apr 17 21:09:00 2007 +0400
+++ b/lib/Linker/LinkModules.cpp	Thu Apr 19 03:43:04 2007 +0400
@@ -376,6 +376,14 @@ static bool GetLinkageResult(GlobalValue
     LinkFromSrc = true;
     LT = Src->getLinkage();
   } else if (Src->isDeclaration()) {
+    // We can link aliases only if they go to the same target
+    FunctionAlias* SA = dyn_cast<FunctionAlias>(Src);
+    if (SA) {
+      FunctionAlias* DA = dyn_cast<FunctionAlias>(Dest);
+      if (!DA || (DA->getTarget() != SA->getTarget()))
+        return Error(Err, "Linking globals named '" + Src->getName() +
+                     "': can only link aliases with the same target!");
+    }
     // If Src is external or if both Src & Drc are external..  Just link the
     // external globals, we aren't adding anything.
     if (Src->hasDLLImportLinkage()) {
diff -r 958b34c32d47 lib/Target/X86/X86ATTAsmPrinter.cpp
--- a/lib/Target/X86/X86ATTAsmPrinter.cpp	Tue Apr 17 21:09:00 2007 +0400
+++ b/lib/Target/X86/X86ATTAsmPrinter.cpp	Thu Apr 19 03:30:02 2007 +0400
@@ -321,6 +321,11 @@ void X86ATTAsmPrinter::printOperand(cons
 
     if (GV->hasExternalWeakLinkage())
       ExtWeakSymbols.insert(GV);
+
+    const FunctionAlias *FA = dyn_cast<FunctionAlias>(GV);
+    // Handle aliases
+    if (FA && GV->isDeclaration())
+      FunctionAliases.insert(FA);
     
     int Offset = MO.getOffset();
     if (Offset > 0)
diff -r 958b34c32d47 lib/Target/X86/X86TargetAsmInfo.cpp
--- a/lib/Target/X86/X86TargetAsmInfo.cpp	Tue Apr 17 21:09:00 2007 +0400
+++ b/lib/Target/X86/X86TargetAsmInfo.cpp	Thu Apr 19 03:27:29 2007 +0400
@@ -108,6 +108,7 @@ X86TargetAsmInfo::X86TargetAsmInfo(const
     ReadOnlySection = "\t.section\t.rodata\n";
     PrivateGlobalPrefix = ".L";
     WeakRefDirective = "\t.weak\t";
+    SetDirective = "\t.set\t";
     DwarfRequiresFrameSection = false;
     DwarfAbbrevSection =  "\t.section\t.debug_abbrev,\"\",@progbits";
     DwarfInfoSection =    "\t.section\t.debug_info,\"\",@progbits";
@@ -137,6 +138,7 @@ X86TargetAsmInfo::X86TargetAsmInfo(const
     AbsoluteSectionOffsets = true;
     PrivateGlobalPrefix = "L";  // Prefix for private global symbols
     WeakRefDirective = "\t.weak\t";
+    SetDirective = "\t.set\t";
     DwarfRequiresFrameSection = false;
     DwarfSectionOffsetDirective = "\t.secrel32\t";
     DwarfAbbrevSection =  "\t.section\t.debug_abbrev,\"dr\"";
diff -r 958b34c32d47 lib/VMCore/AsmWriter.cpp
--- a/lib/VMCore/AsmWriter.cpp	Tue Apr 17 21:09:00 2007 +0400
+++ b/lib/VMCore/AsmWriter.cpp	Thu Apr 19 02:23:20 2007 +0400
@@ -993,6 +993,8 @@ void AssemblyWriter::printFunction(const
     Out << " align " << F->getAlignment();
 
   if (F->isDeclaration()) {
+    if (const FunctionAlias *FA = dyn_cast<FunctionAlias>(F))
+      Out << " alias \"" << FA->getTarget() << '"';
     Out << "\n";
   } else {
     Out << " {";
diff -r 958b34c32d47 lib/VMCore/Function.cpp
--- a/lib/VMCore/Function.cpp	Tue Apr 17 21:09:00 2007 +0400
+++ b/lib/VMCore/Function.cpp	Thu Apr 19 01:15:56 2007 +0400
@@ -139,8 +139,8 @@ ParamAttrsList::removeAttributes(uint16_
 //===----------------------------------------------------------------------===//
 
 Function::Function(const FunctionType *Ty, LinkageTypes Linkage,
-                   const std::string &name, Module *ParentModule)
-  : GlobalValue(PointerType::get(Ty), Value::FunctionVal, 0, 0, Linkage, name) {
+                   const std::string &name, Module *ParentModule, ValueTy vty)
+  : GlobalValue(PointerType::get(Ty), vty, 0, 0, Linkage, name) {
   ParamAttrs = 0;
   SymTab = new ValueSymbolTable();
 
_______________________________________________
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits

Reply via email to