#include "llvm/DerivedTypes.h"
#include "llvm/InlineAsm.h"
#include "llvm/Instructions.h"
+#include "llvm/MDNode.h"
#include "llvm/Module.h"
#include "llvm/ValueSymbolTable.h"
#include "llvm/ADT/SmallPtrSet.h"
case lltok::kw_private: // OptionalLinkage
case lltok::kw_internal: // OptionalLinkage
case lltok::kw_weak: // OptionalLinkage
+ case lltok::kw_weak_odr: // OptionalLinkage
case lltok::kw_linkonce: // OptionalLinkage
+ case lltok::kw_linkonce_odr: // OptionalLinkage
case lltok::kw_appending: // OptionalLinkage
case lltok::kw_dllexport: // OptionalLinkage
case lltok::kw_common: // OptionalLinkage
unsigned TypeID = NumberedTypes.size();
- // We don't allow assigning names to void type
- if (Ty == Type::VoidTy)
- return Error(TypeLoc, "can't assign name to the void type");
-
// See if this type was previously referenced.
std::map<unsigned, std::pair<PATypeHolder, LocTy> >::iterator
FI = ForwardRefTypeIDs.find(TypeID);
ParseType(Ty))
return true;
- // We don't allow assigning names to void type
- if (Ty == Type::VoidTy)
- return Error(NameLoc, "can't assign name '" + Name + "' to the void type");
-
// Set the type name, checking for conflicts as we do so.
bool AlreadyExists = M->addTypeName(Name, Ty);
if (!AlreadyExists) return false;
/// ParseAlias:
/// ::= GlobalVar '=' OptionalVisibility 'alias' OptionalLinkage Aliasee
/// Aliasee
-/// ::= TypeAndValue | 'bitcast' '(' TypeAndValue 'to' Type ')'
+/// ::= TypeAndValue
+/// ::= 'bitcast' '(' TypeAndValue 'to' Type ')'
+/// ::= 'getelementptr' '(' ... ')'
///
/// Everything through visibility has already been parsed.
///
return true;
if (Linkage != GlobalValue::ExternalLinkage &&
- Linkage != GlobalValue::WeakLinkage &&
+ Linkage != GlobalValue::WeakAnyLinkage &&
+ Linkage != GlobalValue::WeakODRLinkage &&
Linkage != GlobalValue::InternalLinkage &&
Linkage != GlobalValue::PrivateLinkage)
return Error(LinkageLoc, "invalid linkage type for alias");
Constant *Aliasee;
LocTy AliaseeLoc = Lex.getLoc();
- if (Lex.getKind() != lltok::kw_bitcast) {
+ if (Lex.getKind() != lltok::kw_bitcast &&
+ Lex.getKind() != lltok::kw_getelementptr) {
if (ParseGlobalTypeAndValue(Aliasee)) return true;
} else {
// The bitcast dest type is not present, it is implied by the dest type.
return true;
}
- if (isa<FunctionType>(Ty) || Ty == Type::LabelTy || Ty == Type::VoidTy)
+ if (isa<FunctionType>(Ty) || Ty == Type::LabelTy)
return Error(TyLoc, "invalid type for global variable");
GlobalVariable *GV = 0;
/// ParseOptionalAttrs - Parse a potentially empty attribute list. AttrKind
/// indicates what kind of attribute list this is: 0: function arg, 1: result,
/// 2: function attr.
+/// 3: function arg after value: FIXME: REMOVE IN LLVM 3.0
bool LLParser::ParseOptionalAttrs(unsigned &Attrs, unsigned AttrKind) {
Attrs = Attribute::None;
LocTy AttrLoc = Lex.getLoc();
switch (Lex.getKind()) {
case lltok::kw_sext:
case lltok::kw_zext:
- // Treat these as signext/zeroext unless they are function attrs.
+ // Treat these as signext/zeroext if they occur in the argument list after
+ // the value, as in "call i8 @foo(i8 10 sext)". If they occur before the
+ // value, as in "call i8 @foo(i8 sext (" then it is part of a constant
+ // expr.
// FIXME: REMOVE THIS IN LLVM 3.0
- if (AttrKind != 2) {
+ if (AttrKind == 3) {
if (Lex.getKind() == lltok::kw_sext)
Attrs |= Attribute::SExt;
else
if (AttrKind != 2 && (Attrs & Attribute::FunctionOnly))
return Error(AttrLoc, "invalid use of function-only attribute");
- if (AttrKind != 0 && (Attrs & Attribute::ParameterOnly))
+ if (AttrKind != 0 && AttrKind != 3 && (Attrs & Attribute::ParameterOnly))
return Error(AttrLoc, "invalid use of parameter-only attribute");
return false;
- case lltok::kw_zeroext: Attrs |= Attribute::ZExt; break;
- case lltok::kw_signext: Attrs |= Attribute::SExt; break;
- case lltok::kw_inreg: Attrs |= Attribute::InReg; break;
- case lltok::kw_sret: Attrs |= Attribute::StructRet; break;
- case lltok::kw_noalias: Attrs |= Attribute::NoAlias; break;
- case lltok::kw_nocapture: Attrs |= Attribute::NoCapture; break;
- case lltok::kw_byval: Attrs |= Attribute::ByVal; break;
- case lltok::kw_nest: Attrs |= Attribute::Nest; break;
-
- case lltok::kw_noreturn: Attrs |= Attribute::NoReturn; break;
- case lltok::kw_nounwind: Attrs |= Attribute::NoUnwind; break;
- case lltok::kw_noinline: Attrs |= Attribute::NoInline; break;
- case lltok::kw_readnone: Attrs |= Attribute::ReadNone; break;
- case lltok::kw_readonly: Attrs |= Attribute::ReadOnly; break;
- case lltok::kw_alwaysinline: Attrs |= Attribute::AlwaysInline; break;
- case lltok::kw_optsize: Attrs |= Attribute::OptimizeForSize; break;
- case lltok::kw_ssp: Attrs |= Attribute::StackProtect; break;
- case lltok::kw_sspreq: Attrs |= Attribute::StackProtectReq; break;
-
+ case lltok::kw_zeroext: Attrs |= Attribute::ZExt; break;
+ case lltok::kw_signext: Attrs |= Attribute::SExt; break;
+ case lltok::kw_inreg: Attrs |= Attribute::InReg; break;
+ case lltok::kw_sret: Attrs |= Attribute::StructRet; break;
+ case lltok::kw_noalias: Attrs |= Attribute::NoAlias; break;
+ case lltok::kw_nocapture: Attrs |= Attribute::NoCapture; break;
+ case lltok::kw_byval: Attrs |= Attribute::ByVal; break;
+ case lltok::kw_nest: Attrs |= Attribute::Nest; break;
+
+ case lltok::kw_noreturn: Attrs |= Attribute::NoReturn; break;
+ case lltok::kw_nounwind: Attrs |= Attribute::NoUnwind; break;
+ case lltok::kw_noinline: Attrs |= Attribute::NoInline; break;
+ case lltok::kw_readnone: Attrs |= Attribute::ReadNone; break;
+ case lltok::kw_readonly: Attrs |= Attribute::ReadOnly; break;
+ case lltok::kw_alwaysinline: Attrs |= Attribute::AlwaysInline; break;
+ case lltok::kw_optsize: Attrs |= Attribute::OptimizeForSize; break;
+ case lltok::kw_ssp: Attrs |= Attribute::StackProtect; break;
+ case lltok::kw_sspreq: Attrs |= Attribute::StackProtectReq; break;
+ case lltok::kw_noredzone: Attrs |= Attribute::NoRedZone; break;
+ case lltok::kw_noimplicitfloat: Attrs |= Attribute::NoImplicitFloat; break;
case lltok::kw_align: {
unsigned Alignment;
/// ::= 'private'
/// ::= 'internal'
/// ::= 'weak'
+/// ::= 'weak_odr'
/// ::= 'linkonce'
+/// ::= 'linkonce_odr'
/// ::= 'appending'
/// ::= 'dllexport'
/// ::= 'common'
bool LLParser::ParseOptionalLinkage(unsigned &Res, bool &HasLinkage) {
HasLinkage = false;
switch (Lex.getKind()) {
- default: Res = GlobalValue::ExternalLinkage; return false;
- case lltok::kw_private: Res = GlobalValue::PrivateLinkage; break;
- case lltok::kw_internal: Res = GlobalValue::InternalLinkage; break;
- case lltok::kw_weak: Res = GlobalValue::WeakLinkage; break;
- case lltok::kw_linkonce: Res = GlobalValue::LinkOnceLinkage; break;
- case lltok::kw_appending: Res = GlobalValue::AppendingLinkage; break;
- case lltok::kw_dllexport: Res = GlobalValue::DLLExportLinkage; break;
- case lltok::kw_common: Res = GlobalValue::CommonLinkage; break;
- case lltok::kw_dllimport: Res = GlobalValue::DLLImportLinkage; break;
- case lltok::kw_extern_weak: Res = GlobalValue::ExternalWeakLinkage; break;
- case lltok::kw_external: Res = GlobalValue::ExternalLinkage; break;
+ default: Res = GlobalValue::ExternalLinkage; return false;
+ case lltok::kw_private: Res = GlobalValue::PrivateLinkage; break;
+ case lltok::kw_internal: Res = GlobalValue::InternalLinkage; break;
+ case lltok::kw_weak: Res = GlobalValue::WeakAnyLinkage; break;
+ case lltok::kw_weak_odr: Res = GlobalValue::WeakODRLinkage; break;
+ case lltok::kw_linkonce: Res = GlobalValue::LinkOnceAnyLinkage; break;
+ case lltok::kw_linkonce_odr: Res = GlobalValue::LinkOnceODRLinkage; break;
+ case lltok::kw_available_externally:
+ Res = GlobalValue::AvailableExternallyLinkage;
+ break;
+ case lltok::kw_appending: Res = GlobalValue::AppendingLinkage; break;
+ case lltok::kw_dllexport: Res = GlobalValue::DLLExportLinkage; break;
+ case lltok::kw_common: Res = GlobalValue::CommonLinkage; break;
+ case lltok::kw_dllimport: Res = GlobalValue::DLLImportLinkage; break;
+ case lltok::kw_extern_weak: Res = GlobalValue::ExternalWeakLinkage; break;
+ case lltok::kw_external: Res = GlobalValue::ExternalLinkage; break;
}
Lex.Lex();
HasLinkage = true;
/// ::= 'coldcc'
/// ::= 'x86_stdcallcc'
/// ::= 'x86_fastcallcc'
+/// ::= 'arm_apcscc'
+/// ::= 'arm_aapcscc'
+/// ::= 'arm_aapcs_vfpcc'
/// ::= 'cc' UINT
-///
+///
bool LLParser::ParseOptionalCallingConv(unsigned &CC) {
switch (Lex.getKind()) {
default: CC = CallingConv::C; return false;
case lltok::kw_coldcc: CC = CallingConv::Cold; break;
case lltok::kw_x86_stdcallcc: CC = CallingConv::X86_StdCall; break;
case lltok::kw_x86_fastcallcc: CC = CallingConv::X86_FastCall; break;
+ case lltok::kw_arm_apcscc: CC = CallingConv::ARM_APCS; break;
+ case lltok::kw_arm_aapcscc: CC = CallingConv::ARM_AAPCS; break;
+ case lltok::kw_arm_aapcs_vfpcc:CC = CallingConv::ARM_AAPCS_VFP; break;
case lltok::kw_cc: Lex.Lex(); return ParseUInt32(CC);
}
Lex.Lex();
//===----------------------------------------------------------------------===//
/// ParseType - Parse and resolve a full type.
-bool LLParser::ParseType(PATypeHolder &Result) {
+bool LLParser::ParseType(PATypeHolder &Result, bool AllowVoid) {
+ LocTy TypeLoc = Lex.getLoc();
if (ParseTypeRec(Result)) return true;
// Verify no unresolved uprefs.
if (!UpRefs.empty())
return Error(UpRefs.back().Loc, "invalid unresolved type up reference");
+ if (!AllowVoid && Result.get() == Type::VoidTy)
+ return Error(TypeLoc, "void type only allowed for function results");
+
return false;
}
return TokError("basic block pointers are invalid");
if (Result.get() == Type::VoidTy)
return TokError("pointers to void are invalid; use i8* instead");
+ if (!PointerType::isValidElementType(Result.get()))
+ return TokError("pointer to this type is invalid");
Result = HandleUpRefs(PointerType::getUnqual(Result.get()));
Lex.Lex();
break;
return TokError("basic block pointers are invalid");
if (Result.get() == Type::VoidTy)
return TokError("pointers to void are invalid; use i8* instead");
+ if (!PointerType::isValidElementType(Result.get()))
+ return TokError("pointer to this type is invalid");
unsigned AddrSpace;
if (ParseOptionalAddrSpace(AddrSpace) ||
ParseToken(lltok::star, "expected '*' in address space"))
ParseValue(ArgTy, V, PFS) ||
// FIXME: Should not allow attributes after the argument, remove this in
// LLVM 3.0.
- ParseOptionalAttrs(ArgAttrs2, 0))
+ ParseOptionalAttrs(ArgAttrs2, 3))
return true;
ArgList.push_back(ParamInfo(ArgLoc, V, ArgAttrs1|ArgAttrs2));
}
if ((inType ? ParseTypeRec(ArgTy) : ParseType(ArgTy)) ||
ParseOptionalAttrs(Attrs, 0)) return true;
+ if (ArgTy == Type::VoidTy)
+ return Error(TypeLoc, "argument can not have void type");
+
if (Lex.getKind() == lltok::LocalVar ||
Lex.getKind() == lltok::StringConstant) { // FIXME: REMOVE IN LLVM 3.0
Name = Lex.getStrVal();
Lex.Lex();
}
- if (!ArgTy->isFirstClassType() && !isa<OpaqueType>(ArgTy))
+ if (!FunctionType::isValidArgumentType(ArgTy))
return Error(TypeLoc, "invalid type for function argument");
ArgList.push_back(ArgInfo(TypeLoc, ArgTy, Attrs, Name));
// Otherwise must be an argument type.
TypeLoc = Lex.getLoc();
- if (ParseTypeRec(ArgTy) ||
+ if ((inType ? ParseTypeRec(ArgTy) : ParseType(ArgTy)) ||
ParseOptionalAttrs(Attrs, 0)) return true;
+ if (ArgTy == Type::VoidTy)
+ return Error(TypeLoc, "argument can not have void type");
+
if (Lex.getKind() == lltok::LocalVar ||
Lex.getKind() == lltok::StringConstant) { // FIXME: REMOVE IN LLVM 3.0
Name = Lex.getStrVal();
}
std::vector<PATypeHolder> ParamsList;
+ LocTy EltTyLoc = Lex.getLoc();
if (ParseTypeRec(Result)) return true;
ParamsList.push_back(Result);
+ if (Result == Type::VoidTy)
+ return Error(EltTyLoc, "struct element can not have void type");
+ if (!StructType::isValidElementType(Result))
+ return Error(EltTyLoc, "invalid element type for struct");
+
while (EatIfPresent(lltok::comma)) {
+ EltTyLoc = Lex.getLoc();
if (ParseTypeRec(Result)) return true;
+
+ if (Result == Type::VoidTy)
+ return Error(EltTyLoc, "struct element can not have void type");
+ if (!StructType::isValidElementType(Result))
+ return Error(EltTyLoc, "invalid element type for struct");
+
ParamsList.push_back(Result);
}
PATypeHolder EltTy(Type::VoidTy);
if (ParseTypeRec(EltTy)) return true;
+ if (EltTy == Type::VoidTy)
+ return Error(TypeLoc, "array and vector element type cannot be void");
+
if (ParseToken(isVector ? lltok::greater : lltok::rsquare,
"expected end of sequential type"))
return true;
return Error(SizeLoc, "zero element vector is illegal");
if ((unsigned)Size != Size)
return Error(SizeLoc, "size too large for vector");
- if (!EltTy->isFloatingPoint() && !EltTy->isInteger())
+ if (!VectorType::isValidElementType(EltTy))
return Error(TypeLoc, "vector element type must be fp or integer");
Result = VectorType::get(EltTy, unsigned(Size));
} else {
- if (!EltTy->isFirstClassType() && !isa<OpaqueType>(EltTy))
+ if (!ArrayType::isValidElementType(EltTy))
return Error(TypeLoc, "invalid array element type");
Result = HandleUpRefs(ArrayType::get(EltTy, Size));
}
ID.StrVal = Lex.getStrVal();
ID.Kind = ValID::t_LocalName;
break;
+ case lltok::Metadata: { // !{...} MDNode, !"foo" MDString
+ ID.Kind = ValID::t_Constant;
+ Lex.Lex();
+ if (Lex.getKind() == lltok::lbrace) {
+ SmallVector<Value*, 16> Elts;
+ if (ParseMDNodeVector(Elts) ||
+ ParseToken(lltok::rbrace, "expected end of metadata node"))
+ return true;
+
+ ID.ConstantVal = MDNode::get(Elts.data(), Elts.size());
+ return false;
+ }
+
+ // MDString:
+ // ::= '!' STRINGCONSTANT
+ std::string Str;
+ if (ParseStringConstant(Str)) return true;
+
+ ID.ConstantVal = MDString::get(Str.data(), Str.data() + Str.size());
+ return false;
+ }
case lltok::APSInt:
ID.APSIntVal = Lex.getAPSIntVal();
ID.Kind = ValID::t_APSInt;
ParseToken(lltok::rbrace, "expected end of struct constant"))
return true;
- ID.ConstantVal = ConstantStruct::get(&Elts[0], Elts.size(), false);
+ ID.ConstantVal = ConstantStruct::get(Elts.data(), Elts.size(), false);
ID.Kind = ValID::t_Constant;
return false;
}
return true;
if (isPackedStruct) {
- ID.ConstantVal = ConstantStruct::get(&Elts[0], Elts.size(), true);
+ ID.ConstantVal = ConstantStruct::get(Elts.data(), Elts.size(), true);
ID.Kind = ValID::t_Constant;
return false;
}
"vector element #" + utostr(i) +
" is not of type '" + Elts[0]->getType()->getDescription());
- ID.ConstantVal = ConstantVector::get(&Elts[0], Elts.size());
+ ID.ConstantVal = ConstantVector::get(Elts.data(), Elts.size());
ID.Kind = ValID::t_Constant;
return false;
}
"array element #" + utostr(i) +
" is not of type '" +Elts[0]->getType()->getDescription());
}
-
- ID.ConstantVal = ConstantArray::get(ATy, &Elts[0], Elts.size());
+
+ ID.ConstantVal = ConstantArray::get(ATy, Elts.data(), Elts.size());
ID.Kind = ValID::t_Constant;
return false;
}
Lex.Lex();
if (ParseToken(lltok::lparen, "expected '(' after constantexpr cast") ||
ParseGlobalTypeAndValue(SrcVal) ||
- ParseToken(lltok::kw_to, "expected 'to' int constantexpr cast") ||
+ ParseToken(lltok::kw_to, "expected 'to' in constantexpr cast") ||
ParseType(DestTy) ||
ParseToken(lltok::rparen, "expected ')' at end of constantexpr cast"))
return true;
if (!ExtractValueInst::getIndexedType(Val->getType(), Indices.begin(),
Indices.end()))
return Error(ID.Loc, "invalid indices for extractvalue");
- ID.ConstantVal = ConstantExpr::getExtractValue(Val,
- &Indices[0], Indices.size());
+ ID.ConstantVal =
+ ConstantExpr::getExtractValue(Val, Indices.data(), Indices.size());
ID.Kind = ValID::t_Constant;
return false;
}
if (!ExtractValueInst::getIndexedType(Val0->getType(), Indices.begin(),
Indices.end()))
return Error(ID.Loc, "invalid indices for insertvalue");
- ID.ConstantVal = ConstantExpr::getInsertValue(Val0, Val1,
- &Indices[0], Indices.size());
+ ID.ConstantVal =
+ ConstantExpr::getInsertValue(Val0, Val1, Indices.data(), Indices.size());
ID.Kind = ValID::t_Constant;
return false;
}
// Binary Operators.
case lltok::kw_add:
+ case lltok::kw_fadd:
case lltok::kw_sub:
+ case lltok::kw_fsub:
case lltok::kw_mul:
+ case lltok::kw_fmul:
case lltok::kw_udiv:
case lltok::kw_sdiv:
case lltok::kw_fdiv:
ParseOptionalVisibility(Visibility) ||
ParseOptionalCallingConv(CC) ||
ParseOptionalAttrs(RetAttrs, 1) ||
- ParseType(RetType, RetTypeLoc))
+ ParseType(RetType, RetTypeLoc, true /*void allowed*/))
return true;
// Verify that the linkage is ok.
break;
case GlobalValue::PrivateLinkage:
case GlobalValue::InternalLinkage:
- case GlobalValue::LinkOnceLinkage:
- case GlobalValue::WeakLinkage:
+ case GlobalValue::AvailableExternallyLinkage:
+ case GlobalValue::LinkOnceAnyLinkage:
+ case GlobalValue::LinkOnceODRLinkage:
+ case GlobalValue::WeakAnyLinkage:
+ case GlobalValue::WeakODRLinkage:
case GlobalValue::DLLExportLinkage:
if (!isDefine)
return Error(LinkageLoc, "invalid linkage for function declaration");
AttrListPtr PAL = AttrListPtr::get(Attrs.begin(), Attrs.end());
+ if (PAL.paramHasAttr(1, Attribute::StructRet) &&
+ RetType != Type::VoidTy)
+ return Error(RetTypeLoc, "functions with 'sret' argument must return void");
+
const FunctionType *FT = FunctionType::get(RetType, ParamTypeList, isVarArg);
const PointerType *PFT = PointerType::getUnqual(FT);
// Binary Operators.
case lltok::kw_add:
case lltok::kw_sub:
- case lltok::kw_mul: return ParseArithmetic(Inst, PFS, KeywordVal, 0);
-
+ case lltok::kw_mul:
+ // API compatibility: Accept either integer or floating-point types.
+ return ParseArithmetic(Inst, PFS, KeywordVal, 0);
+ case lltok::kw_fadd:
+ case lltok::kw_fsub:
+ case lltok::kw_fmul: return ParseArithmetic(Inst, PFS, KeywordVal, 2);
+
case lltok::kw_udiv:
case lltok::kw_sdiv:
case lltok::kw_urem:
bool LLParser::ParseRet(Instruction *&Inst, BasicBlock *BB,
PerFunctionState &PFS) {
PATypeHolder Ty(Type::VoidTy);
- if (ParseType(Ty)) return true;
+ if (ParseType(Ty, true /*void allowed*/)) return true;
if (Ty == Type::VoidTy) {
Inst = ReturnInst::Create();
Value *NormalBB, *UnwindBB;
if (ParseOptionalCallingConv(CC) ||
ParseOptionalAttrs(RetAttrs, 1) ||
- ParseType(RetType, RetTypeLoc) ||
+ ParseType(RetType, RetTypeLoc, true /*void allowed*/) ||
ParseValID(CalleeID) ||
ParseParameterList(ArgList, PFS) ||
ParseOptionalAttrs(FnAttrs, 2) ||
if ((isTail && ParseToken(lltok::kw_call, "expected 'tail call'")) ||
ParseOptionalCallingConv(CC) ||
ParseOptionalAttrs(RetAttrs, 1) ||
- ParseType(RetType, RetTypeLoc) ||
+ ParseType(RetType, RetTypeLoc, true /*void allowed*/) ||
ParseValID(CalleeID) ||
ParseParameterList(ArgList, PFS) ||
ParseOptionalAttrs(FnAttrs, 2))
}
/// ParseLoad
-/// ::= 'volatile'? 'load' TypeAndValue (',' 'align' uint)?
+/// ::= 'volatile'? 'load' TypeAndValue (',' 'align' i32)?
bool LLParser::ParseLoad(Instruction *&Inst, PerFunctionState &PFS,
bool isVolatile) {
Value *Val; LocTy Loc;
}
/// ParseStore
-/// ::= 'volatile'? 'store' TypeAndValue ',' TypeAndValue (',' 'align' uint)?
+/// ::= 'volatile'? 'store' TypeAndValue ',' TypeAndValue (',' 'align' i32)?
bool LLParser::ParseStore(Instruction *&Inst, PerFunctionState &PFS,
bool isVolatile) {
Value *Val, *Ptr; LocTy Loc, PtrLoc;
}
/// ParseGetResult
-/// ::= 'getresult' TypeAndValue ',' uint
+/// ::= 'getresult' TypeAndValue ',' i32
/// FIXME: Remove support for getresult in LLVM 3.0
bool LLParser::ParseGetResult(Instruction *&Inst, PerFunctionState &PFS) {
Value *Val; LocTy ValLoc, EltLoc;
Inst = InsertValueInst::Create(Val0, Val1, Indices.begin(), Indices.end());
return false;
}
+
+//===----------------------------------------------------------------------===//
+// Embedded metadata.
+//===----------------------------------------------------------------------===//
+
+/// ParseMDNodeVector
+/// ::= Element (',' Element)*
+/// Element
+/// ::= 'null' | TypeAndValue
+bool LLParser::ParseMDNodeVector(SmallVectorImpl<Value*> &Elts) {
+ assert(Lex.getKind() == lltok::lbrace);
+ Lex.Lex();
+ do {
+ Value *V;
+ if (Lex.getKind() == lltok::kw_null) {
+ Lex.Lex();
+ V = 0;
+ } else {
+ Constant *C;
+ if (ParseGlobalTypeAndValue(C)) return true;
+ V = C;
+ }
+ Elts.push_back(V);
+ } while (EatIfPresent(lltok::comma));
+
+ return false;
+}