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
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits