#include "llvm/DerivedTypes.h"
#include "llvm/InlineAsm.h"
#include "llvm/Instructions.h"
-#include "llvm/LLVMContext.h"
-#include "llvm/Metadata.h"
#include "llvm/Module.h"
#include "llvm/Operator.h"
#include "llvm/ValueSymbolTable.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
-namespace llvm {
- /// ValID - Represents a reference of a definition of some sort with no type.
- /// There are several cases where we have to parse the value but where the
- /// type can depend on later context. This may either be a numeric reference
- /// or a symbolic (%var) reference. This is just a discriminated union.
- struct ValID {
- enum {
- t_LocalID, t_GlobalID, // ID in UIntVal.
- t_LocalName, t_GlobalName, // Name in StrVal.
- t_APSInt, t_APFloat, // Value in APSIntVal/APFloatVal.
- t_Null, t_Undef, t_Zero, // No value.
- t_EmptyArray, // No value: []
- t_Constant, // Value in ConstantVal.
- t_InlineAsm, // Value in StrVal/StrVal2/UIntVal.
- t_Metadata // Value in MetadataVal.
- } Kind;
-
- LLParser::LocTy Loc;
- unsigned UIntVal;
- std::string StrVal, StrVal2;
- APSInt APSIntVal;
- APFloat APFloatVal;
- Constant *ConstantVal;
- MetadataBase *MetadataVal;
- ValID() : APFloatVal(0.0) {}
- };
-}
-
/// Run: module ::= toplevelentity*
bool LLParser::Run() {
// Prime the lexer.
/// ValidateEndOfModule - Do final validity and sanity checks at the end of the
/// module.
bool LLParser::ValidateEndOfModule() {
+ // Handle any instruction metadata forward references.
+ if (!ForwardRefInstMetadata.empty()) {
+ for (DenseMap<Instruction*, std::vector<MDRef> >::iterator
+ I = ForwardRefInstMetadata.begin(), E = ForwardRefInstMetadata.end();
+ I != E; ++I) {
+ Instruction *Inst = I->first;
+ const std::vector<MDRef> &MDList = I->second;
+
+ for (unsigned i = 0, e = MDList.size(); i != e; ++i) {
+ unsigned SlotNo = MDList[i].MDSlot;
+
+ if (SlotNo >= NumberedMetadata.size() || NumberedMetadata[SlotNo] == 0)
+ return Error(MDList[i].Loc, "use of undefined metadata '!" +
+ utostr(SlotNo) + "'");
+ Inst->setMetadata(MDList[i].MDKind, NumberedMetadata[SlotNo]);
+ }
+ }
+ ForwardRefInstMetadata.clear();
+ }
+
+
// Update auto-upgraded malloc calls to "malloc".
// FIXME: Remove in LLVM 3.0.
if (MallocF) {
// declaration of "malloc". In that case, iterate over all calls to MallocF
// and get them to call the declared "malloc" instead.
if (MallocF->getName() != "malloc") {
- Constant* RealMallocF = M->getFunction("malloc");
+ Constant *RealMallocF = M->getFunction("malloc");
if (RealMallocF->getType() != MallocF->getType())
RealMallocF = ConstantExpr::getBitCast(RealMallocF, MallocF->getType());
MallocF->replaceAllUsesWith(RealMallocF);
MallocF = NULL;
}
}
-
+
+
+ // If there are entries in ForwardRefBlockAddresses at this point, they are
+ // references after the function was defined. Resolve those now.
+ while (!ForwardRefBlockAddresses.empty()) {
+ // Okay, we are referencing an already-parsed function, resolve them now.
+ Function *TheFn = 0;
+ const ValID &Fn = ForwardRefBlockAddresses.begin()->first;
+ if (Fn.Kind == ValID::t_GlobalName)
+ TheFn = M->getFunction(Fn.StrVal);
+ else if (Fn.UIntVal < NumberedVals.size())
+ TheFn = dyn_cast<Function>(NumberedVals[Fn.UIntVal]);
+
+ if (TheFn == 0)
+ return Error(Fn.Loc, "unknown function referenced by blockaddress");
+
+ // Resolve all these references.
+ if (ResolveForwardRefBlockAddresses(TheFn,
+ ForwardRefBlockAddresses.begin()->second,
+ 0))
+ return true;
+
+ ForwardRefBlockAddresses.erase(ForwardRefBlockAddresses.begin());
+ }
+
+
if (!ForwardRefTypes.empty())
return Error(ForwardRefTypes.begin()->second.second,
"use of undefined type named '" +
return false;
}
+bool LLParser::ResolveForwardRefBlockAddresses(Function *TheFn,
+ std::vector<std::pair<ValID, GlobalValue*> > &Refs,
+ PerFunctionState *PFS) {
+ // Loop over all the references, resolving them.
+ for (unsigned i = 0, e = Refs.size(); i != e; ++i) {
+ BasicBlock *Res;
+ if (PFS) {
+ if (Refs[i].first.Kind == ValID::t_LocalName)
+ Res = PFS->GetBB(Refs[i].first.StrVal, Refs[i].first.Loc);
+ else
+ Res = PFS->GetBB(Refs[i].first.UIntVal, Refs[i].first.Loc);
+ } else if (Refs[i].first.Kind == ValID::t_LocalID) {
+ return Error(Refs[i].first.Loc,
+ "cannot take address of numeric label after the function is defined");
+ } else {
+ Res = dyn_cast_or_null<BasicBlock>(
+ TheFn->getValueSymbolTable().lookup(Refs[i].first.StrVal));
+ }
+
+ if (Res == 0)
+ return Error(Refs[i].first.Loc,
+ "referenced value is not a basic block");
+
+ // Get the BlockAddress for this and update references to use it.
+ BlockAddress *BA = BlockAddress::get(TheFn, Res);
+ Refs[i].second->replaceAllUsesWith(BA);
+ Refs[i].second->eraseFromParent();
+ }
+ return false;
+}
+
+
//===----------------------------------------------------------------------===//
// Top-Level Entities
//===----------------------------------------------------------------------===//
case lltok::LocalVar: if (ParseNamedType()) return true; break;
case lltok::GlobalID: if (ParseUnnamedGlobal()) return true; break;
case lltok::GlobalVar: if (ParseNamedGlobal()) return true; break;
- case lltok::Metadata: if (ParseStandaloneMetadata()) return true; break;
- case lltok::NamedOrCustomMD: if (ParseNamedMetadata()) return true; break;
+ case lltok::exclaim: if (ParseStandaloneMetadata()) return true; break;
+ case lltok::MetadataVar: if (ParseNamedMetadata()) return true; break;
// The Global variable production with no name can have many different
// optional leading prefixes, the production is:
// MDString:
// ::= '!' STRINGCONSTANT
-bool LLParser::ParseMDString(MetadataBase *&MDS) {
+bool LLParser::ParseMDString(MDString *&Result) {
std::string Str;
if (ParseStringConstant(Str)) return true;
- MDS = MDString::get(Context, Str);
+ Result = MDString::get(Context, Str);
return false;
}
// MDNode:
// ::= '!' MDNodeNumber
-bool LLParser::ParseMDNode(MetadataBase *&Node) {
+//
+/// This version of ParseMDNodeID returns the slot number and null in the case
+/// of a forward reference.
+bool LLParser::ParseMDNodeID(MDNode *&Result, unsigned &SlotNo) {
// !{ ..., !42, ... }
- unsigned MID = 0;
- if (ParseUInt32(MID)) return true;
+ if (ParseUInt32(SlotNo)) return true;
// Check existing MDNode.
- std::map<unsigned, MetadataBase *>::iterator I = MetadataCache.find(MID);
- if (I != MetadataCache.end()) {
- Node = I->second;
- return false;
- }
+ if (SlotNo < NumberedMetadata.size() && NumberedMetadata[SlotNo] != 0)
+ Result = NumberedMetadata[SlotNo];
+ else
+ Result = 0;
+ return false;
+}
- // Check known forward references.
- std::map<unsigned, std::pair<MetadataBase *, LocTy> >::iterator
- FI = ForwardRefMDNodes.find(MID);
- if (FI != ForwardRefMDNodes.end()) {
- Node = FI->second.first;
- return false;
- }
+bool LLParser::ParseMDNodeID(MDNode *&Result) {
+ // !{ ..., !42, ... }
+ unsigned MID = 0;
+ if (ParseMDNodeID(Result, MID)) return true;
- // Create MDNode forward reference
- SmallVector<Value *, 1> Elts;
+ // If not a forward reference, just return it now.
+ if (Result) return false;
+
+ // Otherwise, create MDNode forward reference.
+
+ // FIXME: This is not unique enough!
std::string FwdRefName = "llvm.mdnode.fwdref." + utostr(MID);
- Elts.push_back(MDString::get(Context, FwdRefName));
- MDNode *FwdNode = MDNode::get(Context, Elts.data(), Elts.size());
+ Value *V = MDString::get(Context, FwdRefName);
+ MDNode *FwdNode = MDNode::get(Context, &V, 1);
ForwardRefMDNodes[MID] = std::make_pair(FwdNode, Lex.getLoc());
- Node = FwdNode;
+
+ if (NumberedMetadata.size() <= MID)
+ NumberedMetadata.resize(MID+1);
+ NumberedMetadata[MID] = FwdNode;
+ Result = FwdNode;
return false;
}
-///ParseNamedMetadata:
+/// ParseNamedMetadata:
/// !foo = !{ !1, !2 }
bool LLParser::ParseNamedMetadata() {
- assert(Lex.getKind() == lltok::NamedOrCustomMD);
- Lex.Lex();
+ assert(Lex.getKind() == lltok::MetadataVar);
std::string Name = Lex.getStrVal();
+ Lex.Lex();
- if (ParseToken(lltok::equal, "expected '=' here"))
+ if (ParseToken(lltok::equal, "expected '=' here") ||
+ ParseToken(lltok::exclaim, "Expected '!' here") ||
+ ParseToken(lltok::lbrace, "Expected '{' here"))
return true;
- if (Lex.getKind() != lltok::Metadata)
- return TokError("Expected '!' here");
- Lex.Lex();
-
- if (Lex.getKind() != lltok::lbrace)
- return TokError("Expected '{' here");
- Lex.Lex();
- SmallVector<MetadataBase *, 8> Elts;
+ SmallVector<MDNode *, 8> Elts;
do {
- if (Lex.getKind() != lltok::Metadata)
- return TokError("Expected '!' here");
- Lex.Lex();
- MetadataBase *N = 0;
- if (ParseMDNode(N)) return true;
+ // Null is a special case since it is typeless.
+ if (EatIfPresent(lltok::kw_null)) {
+ Elts.push_back(0);
+ continue;
+ }
+
+ if (ParseToken(lltok::exclaim, "Expected '!' here"))
+ return true;
+
+ MDNode *N = 0;
+ if (ParseMDNodeID(N)) return true;
Elts.push_back(N);
} while (EatIfPresent(lltok::comma));
/// ParseStandaloneMetadata:
/// !42 = !{...}
bool LLParser::ParseStandaloneMetadata() {
- assert(Lex.getKind() == lltok::Metadata);
+ assert(Lex.getKind() == lltok::exclaim);
Lex.Lex();
unsigned MetadataID = 0;
- if (ParseUInt32(MetadataID))
- return true;
- if (MetadataCache.find(MetadataID) != MetadataCache.end())
- return TokError("Metadata id is already used");
- if (ParseToken(lltok::equal, "expected '=' here"))
- return true;
LocTy TyLoc;
PATypeHolder Ty(Type::getVoidTy(Context));
- if (ParseType(Ty, TyLoc))
- return true;
-
- if (Lex.getKind() != lltok::Metadata)
- return TokError("Expected metadata here");
-
- Lex.Lex();
- if (Lex.getKind() != lltok::lbrace)
- return TokError("Expected '{' here");
-
SmallVector<Value *, 16> Elts;
- if (ParseMDNodeVector(Elts)
- || ParseToken(lltok::rbrace, "expected end of metadata node"))
+ if (ParseUInt32(MetadataID) ||
+ ParseToken(lltok::equal, "expected '=' here") ||
+ ParseType(Ty, TyLoc) ||
+ ParseToken(lltok::exclaim, "Expected '!' here") ||
+ ParseToken(lltok::lbrace, "Expected '{' here") ||
+ ParseMDNodeVector(Elts, NULL) ||
+ ParseToken(lltok::rbrace, "expected end of metadata node"))
return true;
MDNode *Init = MDNode::get(Context, Elts.data(), Elts.size());
- MetadataCache[MetadataID] = Init;
- std::map<unsigned, std::pair<MetadataBase *, LocTy> >::iterator
+
+ // See if this was forward referenced, if so, handle it.
+ std::map<unsigned, std::pair<TrackingVH<MDNode>, LocTy> >::iterator
FI = ForwardRefMDNodes.find(MetadataID);
if (FI != ForwardRefMDNodes.end()) {
- MDNode *FwdNode = cast<MDNode>(FI->second.first);
- FwdNode->replaceAllUsesWith(Init);
+ FI->second.first->replaceAllUsesWith(Init);
ForwardRefMDNodes.erase(FI);
+
+ assert(NumberedMetadata[MetadataID] == Init && "Tracking VH didn't work");
+ } else {
+ if (MetadataID >= NumberedMetadata.size())
+ NumberedMetadata.resize(MetadataID+1);
+
+ if (NumberedMetadata[MetadataID] != 0)
+ return TokError("Metadata id is already used");
+ NumberedMetadata[MetadataID] = Init;
}
return false;
Aliasee = ID.ConstantVal;
}
- if (!isa<PointerType>(Aliasee->getType()))
+ if (!Aliasee->getType()->isPointerTy())
return Error(AliaseeLoc, "alias must have pointer type");
// Okay, create the alias but do not insert it into the module yet.
return true;
}
- if (isa<FunctionType>(Ty) || Ty->isLabelTy())
+ if (Ty->isFunctionTy() || Ty->isLabelTy())
return Error(TyLoc, "invalid type for global variable");
GlobalVariable *GV = 0;
GlobalValue *FwdVal;
if (const FunctionType *FT = dyn_cast<FunctionType>(PTy->getElementType())) {
// Function types can return opaque but functions can't.
- if (isa<OpaqueType>(FT->getReturnType())) {
+ if (FT->getReturnType()->isOpaqueTy()) {
Error(Loc, "function may not return opaque type");
return 0;
}
GlobalValue *FwdVal;
if (const FunctionType *FT = dyn_cast<FunctionType>(PTy->getElementType())) {
// Function types can return opaque but functions can't.
- if (isa<OpaqueType>(FT->getReturnType())) {
+ if (FT->getReturnType()->isOpaqueTy()) {
Error(Loc, "function may not return opaque type");
return 0;
}
case lltok::kw_noimplicitfloat: Attrs |= Attribute::NoImplicitFloat; break;
case lltok::kw_naked: Attrs |= Attribute::Naked; break;
+ case lltok::kw_alignstack: {
+ unsigned Alignment;
+ if (ParseOptionalStackAlignment(Alignment))
+ return true;
+ Attrs |= Attribute::constructStackAlignmentFromInt(Alignment);
+ continue;
+ }
+
case lltok::kw_align: {
unsigned Alignment;
if (ParseOptionalAlignment(Alignment))
Attrs |= Attribute::constructAlignmentFromInt(Alignment);
continue;
}
+
}
Lex.Lex();
}
/// ::= 'arm_apcscc'
/// ::= 'arm_aapcscc'
/// ::= 'arm_aapcs_vfpcc'
+/// ::= 'msp430_intrcc'
/// ::= 'cc' UINT
///
bool LLParser::ParseOptionalCallingConv(CallingConv::ID &CC) {
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_msp430_intrcc: CC = CallingConv::MSP430_INTR; break;
case lltok::kw_cc: {
unsigned ArbitraryCC;
Lex.Lex();
return false;
}
-/// ParseOptionalCustomMetadata
-/// ::= /* empty */
-/// ::= !dbg !42
-bool LLParser::ParseOptionalCustomMetadata() {
- if (Lex.getKind() != lltok::NamedOrCustomMD)
- return false;
-
- std::string Name = Lex.getStrVal();
- Lex.Lex();
+/// ParseInstructionMetadata
+/// ::= !dbg !42 (',' !dbg !57)*
+bool LLParser::ParseInstructionMetadata(Instruction *Inst) {
+ do {
+ if (Lex.getKind() != lltok::MetadataVar)
+ return TokError("expected metadata after comma");
- if (Lex.getKind() != lltok::Metadata)
- return TokError("Expected '!' here");
- Lex.Lex();
+ std::string Name = Lex.getStrVal();
+ Lex.Lex();
- MetadataBase *Node;
- if (ParseMDNode(Node)) return true;
+ MDNode *Node;
+ unsigned NodeID;
+ SMLoc Loc = Lex.getLoc();
+ if (ParseToken(lltok::exclaim, "expected '!' here") ||
+ ParseMDNodeID(Node, NodeID))
+ return true;
- MetadataContext &TheMetadata = M->getContext().getMetadata();
- unsigned MDK = TheMetadata.getMDKind(Name.c_str());
- if (!MDK)
- MDK = TheMetadata.registerMDKind(Name.c_str());
- MDsOnInst.push_back(std::make_pair(MDK, cast<MDNode>(Node)));
+ unsigned MDK = M->getMDKindID(Name.c_str());
+ if (Node) {
+ // If we got the node, add it to the instruction.
+ Inst->setMetadata(MDK, Node);
+ } else {
+ MDRef R = { Loc, MDK, NodeID };
+ // Otherwise, remember that this should be resolved later.
+ ForwardRefInstMetadata[Inst].push_back(R);
+ }
+ // If this is the end of the list, we're done.
+ } while (EatIfPresent(lltok::comma));
return false;
}
return false;
}
-/// ParseOptionalInfo
-/// ::= OptionalInfo (',' OptionalInfo)+
-bool LLParser::ParseOptionalInfo(unsigned &Alignment) {
-
- // FIXME: Handle customized metadata info attached with an instruction.
- do {
- if (Lex.getKind() == lltok::NamedOrCustomMD) {
- if (ParseOptionalCustomMetadata()) return true;
- } else if (Lex.getKind() == lltok::kw_align) {
+/// ParseOptionalCommaAlign
+/// ::=
+/// ::= ',' align 4
+///
+/// This returns with AteExtraComma set to true if it ate an excess comma at the
+/// end.
+bool LLParser::ParseOptionalCommaAlign(unsigned &Alignment,
+ bool &AteExtraComma) {
+ AteExtraComma = false;
+ while (EatIfPresent(lltok::comma)) {
+ // Metadata at the end is an early exit.
+ if (Lex.getKind() == lltok::MetadataVar) {
+ AteExtraComma = true;
+ return false;
+ }
+
+ if (Lex.getKind() == lltok::kw_align) {
if (ParseOptionalAlignment(Alignment)) return true;
} else
return true;
- } while (EatIfPresent(lltok::comma));
+ }
return false;
}
+/// ParseOptionalStackAlignment
+/// ::= /* empty */
+/// ::= 'alignstack' '(' 4 ')'
+bool LLParser::ParseOptionalStackAlignment(unsigned &Alignment) {
+ Alignment = 0;
+ if (!EatIfPresent(lltok::kw_alignstack))
+ return false;
+ LocTy ParenLoc = Lex.getLoc();
+ if (!EatIfPresent(lltok::lparen))
+ return Error(ParenLoc, "expected '('");
+ LocTy AlignLoc = Lex.getLoc();
+ if (ParseUInt32(Alignment)) return true;
+ ParenLoc = Lex.getLoc();
+ if (!EatIfPresent(lltok::rparen))
+ return Error(ParenLoc, "expected ')'");
+ if (!isPowerOf2_32(Alignment))
+ return Error(AlignLoc, "stack alignment is not a power of two");
+ return false;
+}
+/// ParseIndexList - This parses the index list for an insert/extractvalue
+/// instruction. This sets AteExtraComma in the case where we eat an extra
+/// comma at the end of the line and find that it is followed by metadata.
+/// Clients that don't allow metadata can call the version of this function that
+/// only takes one argument.
+///
/// ParseIndexList
/// ::= (',' uint32)+
-bool LLParser::ParseIndexList(SmallVectorImpl<unsigned> &Indices) {
+///
+bool LLParser::ParseIndexList(SmallVectorImpl<unsigned> &Indices,
+ bool &AteExtraComma) {
+ AteExtraComma = false;
+
if (Lex.getKind() != lltok::comma)
return TokError("expected ',' as start of index list");
while (EatIfPresent(lltok::comma)) {
+ if (Lex.getKind() == lltok::MetadataVar) {
+ AteExtraComma = true;
+ return false;
+ }
unsigned Idx;
if (ParseUInt32(Idx)) return true;
Indices.push_back(Idx);
PATypeHolder Ty(ty);
#if 0
- errs() << "Type '" << Ty->getDescription()
+ dbgs() << "Type '" << Ty->getDescription()
<< "' newly formed. Resolving upreferences.\n"
<< UpRefs.size() << " upreferences active!\n";
#endif
UpRefs[i].LastContainedTy) != Ty->subtype_end();
#if 0
- errs() << " UR#" << i << " - TypeContains(" << Ty->getDescription() << ", "
+ dbgs() << " UR#" << i << " - TypeContains(" << Ty->getDescription() << ", "
<< UpRefs[i].LastContainedTy->getDescription() << ") = "
<< (ContainsType ? "true" : "false")
<< " level=" << UpRefs[i].NestingLevel << "\n";
continue;
#if 0
- errs() << " * Resolving upreference for " << UpRefs[i].UpRefTy << "\n";
+ dbgs() << " * Resolving upreference for " << UpRefs[i].UpRefTy << "\n";
#endif
if (!TypeToResolve)
TypeToResolve = UpRefs[i].UpRefTy;
if (ParseStructType(Result, false))
return true;
break;
+ case lltok::kw_union:
+ // TypeRec ::= 'union' '{' ... '}'
+ if (ParseUnionType(Result))
+ return true;
+ break;
case lltok::lsquare:
// TypeRec ::= '[' ... ']'
Lex.Lex(); // eat the lsquare.
// Parse the argument.
LocTy ArgLoc;
PATypeHolder ArgTy(Type::getVoidTy(Context));
- unsigned ArgAttrs1, ArgAttrs2;
+ unsigned ArgAttrs1 = Attribute::None;
+ unsigned ArgAttrs2 = Attribute::None;
Value *V;
- if (ParseType(ArgTy, ArgLoc) ||
- ParseOptionalAttrs(ArgAttrs1, 0) ||
+ if (ParseType(ArgTy, ArgLoc))
+ return true;
+
+ // Otherwise, handle normal operands.
+ if (ParseOptionalAttrs(ArgAttrs1, 0) ||
ParseValue(ArgTy, V, PFS) ||
- // FIXME: Should not allow attributes after the argument, remove this in
- // LLVM 3.0.
+ // FIXME: Should not allow attributes after the argument, remove this
+ // in LLVM 3.0.
ParseOptionalAttrs(ArgAttrs2, 3))
return true;
ArgList.push_back(ParamInfo(ArgLoc, V, ArgAttrs1|ArgAttrs2));
Name = "";
}
- if (!ArgTy->isFirstClassType() && !isa<OpaqueType>(ArgTy))
+ if (!ArgTy->isFirstClassType() && !ArgTy->isOpaqueTy())
return Error(TypeLoc, "invalid type for function argument");
ArgList.push_back(ArgInfo(TypeLoc, ArgTy, Attrs, Name));
return false;
}
+/// ParseUnionType
+/// TypeRec
+/// ::= 'union' '{' TypeRec (',' TypeRec)* '}'
+bool LLParser::ParseUnionType(PATypeHolder &Result) {
+ assert(Lex.getKind() == lltok::kw_union);
+ Lex.Lex(); // Consume the 'union'
+
+ if (ParseToken(lltok::lbrace, "'{' expected after 'union'")) return true;
+
+ SmallVector<PATypeHolder, 8> ParamsList;
+ do {
+ LocTy EltTyLoc = Lex.getLoc();
+ if (ParseTypeRec(Result)) return true;
+ ParamsList.push_back(Result);
+
+ if (Result->isVoidTy())
+ return Error(EltTyLoc, "union element can not have void type");
+ if (!UnionType::isValidElementType(Result))
+ return Error(EltTyLoc, "invalid element type for union");
+
+ } while (EatIfPresent(lltok::comma)) ;
+
+ if (ParseToken(lltok::rbrace, "expected '}' at end of union"))
+ return true;
+
+ SmallVector<const Type*, 8> ParamsListTy;
+ for (unsigned i = 0, e = ParamsList.size(); i != e; ++i)
+ ParamsListTy.push_back(ParamsList[i].get());
+ Result = HandleUpRefs(UnionType::get(&ParamsListTy[0], ParamsListTy.size()));
+ return false;
+}
+
/// ParseArrayVectorType - Parse an array or vector type, assuming the first
/// token has already been consumed.
/// TypeRec
// Function Semantic Analysis.
//===----------------------------------------------------------------------===//
-LLParser::PerFunctionState::PerFunctionState(LLParser &p, Function &f)
- : P(p), F(f) {
+LLParser::PerFunctionState::PerFunctionState(LLParser &p, Function &f,
+ int functionNumber)
+ : P(p), F(f), FunctionNumber(functionNumber) {
// Insert unnamed arguments into the NumberedVals list.
for (Function::arg_iterator AI = F.arg_begin(), E = F.arg_end();
}
}
-bool LLParser::PerFunctionState::VerifyFunctionComplete() {
+bool LLParser::PerFunctionState::FinishFunction() {
+ // Check to see if someone took the address of labels in this block.
+ if (!P.ForwardRefBlockAddresses.empty()) {
+ ValID FunctionID;
+ if (!F.getName().empty()) {
+ FunctionID.Kind = ValID::t_GlobalName;
+ FunctionID.StrVal = F.getName();
+ } else {
+ FunctionID.Kind = ValID::t_GlobalID;
+ FunctionID.UIntVal = FunctionNumber;
+ }
+
+ std::map<ValID, std::vector<std::pair<ValID, GlobalValue*> > >::iterator
+ FRBAI = P.ForwardRefBlockAddresses.find(FunctionID);
+ if (FRBAI != P.ForwardRefBlockAddresses.end()) {
+ // Resolve all these references.
+ if (P.ResolveForwardRefBlockAddresses(&F, FRBAI->second, this))
+ return true;
+
+ P.ForwardRefBlockAddresses.erase(FRBAI);
+ }
+ }
+
if (!ForwardRefVals.empty())
return P.Error(ForwardRefVals.begin()->second.second,
"use of undefined value '%" + ForwardRefVals.begin()->first +
}
// Don't make placeholders with invalid type.
- if (!Ty->isFirstClassType() && !isa<OpaqueType>(Ty) &&
- Ty != Type::getLabelTy(F.getContext())) {
+ if (!Ty->isFirstClassType() && !Ty->isOpaqueTy() && !Ty->isLabelTy()) {
P.Error(Loc, "invalid use of a non-first-class type");
return 0;
}
return 0;
}
- if (!Ty->isFirstClassType() && !isa<OpaqueType>(Ty) &&
- Ty != Type::getLabelTy(F.getContext())) {
+ if (!Ty->isFirstClassType() && !Ty->isOpaqueTy() && !Ty->isLabelTy()) {
P.Error(Loc, "invalid use of a non-first-class type");
return 0;
}
/// ParseValID - Parse an abstract value that doesn't necessarily have a
/// type implied. For example, if we parse "4" we don't know what integer type
/// it has. The value will later be combined with its type and checked for
-/// sanity.
-bool LLParser::ParseValID(ValID &ID) {
+/// sanity. PFS is used to convert function-local operands of metadata (since
+/// metadata operands are not just parsed here but also converted to values).
+/// PFS can be null when we are not parsing metadata values inside a function.
+bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) {
ID.Loc = Lex.getLoc();
switch (Lex.getKind()) {
default: return TokError("expected value token");
ID.StrVal = Lex.getStrVal();
ID.Kind = ValID::t_LocalName;
break;
- case lltok::Metadata: { // !{...} MDNode, !"foo" MDString
- ID.Kind = ValID::t_Metadata;
+ case lltok::exclaim: // !{...} MDNode, !"foo" MDString
Lex.Lex();
- if (Lex.getKind() == lltok::lbrace) {
+
+ if (EatIfPresent(lltok::lbrace)) {
SmallVector<Value*, 16> Elts;
- if (ParseMDNodeVector(Elts) ||
+ if (ParseMDNodeVector(Elts, PFS) ||
ParseToken(lltok::rbrace, "expected end of metadata node"))
return true;
- ID.MetadataVal = MDNode::get(Context, Elts.data(), Elts.size());
+ ID.MDNodeVal = MDNode::get(Context, Elts.data(), Elts.size());
+ ID.Kind = ValID::t_MDNode;
return false;
}
// Standalone metadata reference
// !{ ..., !42, ... }
- if (!ParseMDNode(ID.MetadataVal))
+ if (Lex.getKind() == lltok::APSInt) {
+ if (ParseMDNodeID(ID.MDNodeVal)) return true;
+ ID.Kind = ValID::t_MDNode;
return false;
-
+ }
+
// MDString:
// ::= '!' STRINGCONSTANT
- if (ParseMDString(ID.MetadataVal)) return true;
- ID.Kind = ValID::t_Metadata;
+ if (ParseMDString(ID.MDStringVal)) return true;
+ ID.Kind = ValID::t_MDString;
return false;
- }
case lltok::APSInt:
ID.APSIntVal = Lex.getAPSIntVal();
ID.Kind = ValID::t_APSInt;
if (Elts.empty())
return Error(ID.Loc, "constant vector must not be empty");
- if (!Elts[0]->getType()->isInteger() &&
- !Elts[0]->getType()->isFloatingPoint())
+ if (!Elts[0]->getType()->isIntegerTy() &&
+ !Elts[0]->getType()->isFloatingPointTy())
return Error(FirstEltLoc,
"vector elements must have integer or floating point type");
ParseToken(lltok::StringConstant, "expected constraint string"))
return true;
ID.StrVal2 = Lex.getStrVal();
- ID.UIntVal = HasSideEffect | ((unsigned)AlignStack<<1);
+ ID.UIntVal = unsigned(HasSideEffect) | (unsigned(AlignStack)<<1);
ID.Kind = ValID::t_InlineAsm;
return false;
}
+ case lltok::kw_blockaddress: {
+ // ValID ::= 'blockaddress' '(' @foo ',' %bar ')'
+ Lex.Lex();
+
+ ValID Fn, Label;
+ LocTy FnLoc, LabelLoc;
+
+ if (ParseToken(lltok::lparen, "expected '(' in block address expression") ||
+ ParseValID(Fn) ||
+ ParseToken(lltok::comma, "expected comma in block address expression")||
+ ParseValID(Label) ||
+ ParseToken(lltok::rparen, "expected ')' in block address expression"))
+ return true;
+
+ if (Fn.Kind != ValID::t_GlobalID && Fn.Kind != ValID::t_GlobalName)
+ return Error(Fn.Loc, "expected function name in blockaddress");
+ if (Label.Kind != ValID::t_LocalID && Label.Kind != ValID::t_LocalName)
+ return Error(Label.Loc, "expected basic block name in blockaddress");
+
+ // Make a global variable as a placeholder for this reference.
+ GlobalVariable *FwdRef = new GlobalVariable(*M, Type::getInt8Ty(Context),
+ false, GlobalValue::InternalLinkage,
+ 0, "");
+ ForwardRefBlockAddresses[Fn].push_back(std::make_pair(Label, FwdRef));
+ ID.ConstantVal = FwdRef;
+ ID.Kind = ValID::t_Constant;
+ return false;
+ }
+
case lltok::kw_trunc:
case lltok::kw_zext:
case lltok::kw_sext:
ParseIndexList(Indices) ||
ParseToken(lltok::rparen, "expected ')' in extractvalue constantexpr"))
return true;
- if (!isa<StructType>(Val->getType()) && !isa<ArrayType>(Val->getType()))
- return Error(ID.Loc, "extractvalue operand must be array or struct");
+
+ if (!Val->getType()->isAggregateType())
+ return Error(ID.Loc, "extractvalue operand must be aggregate type");
if (!ExtractValueInst::getIndexedType(Val->getType(), Indices.begin(),
Indices.end()))
return Error(ID.Loc, "invalid indices for extractvalue");
ParseIndexList(Indices) ||
ParseToken(lltok::rparen, "expected ')' in insertvalue constantexpr"))
return true;
- if (!isa<StructType>(Val0->getType()) && !isa<ArrayType>(Val0->getType()))
- return Error(ID.Loc, "extractvalue operand must be array or struct");
+ if (!Val0->getType()->isAggregateType())
+ return Error(ID.Loc, "insertvalue operand must be aggregate type");
if (!ExtractValueInst::getIndexedType(Val0->getType(), Indices.begin(),
Indices.end()))
return Error(ID.Loc, "invalid indices for insertvalue");
CmpInst::Predicate Pred = (CmpInst::Predicate)PredVal;
if (Opc == Instruction::FCmp) {
- if (!Val0->getType()->isFPOrFPVector())
+ if (!Val0->getType()->isFPOrFPVectorTy())
return Error(ID.Loc, "fcmp requires floating point operands");
ID.ConstantVal = ConstantExpr::getFCmp(Pred, Val0, Val1);
} else {
assert(Opc == Instruction::ICmp && "Unexpected opcode for CmpInst!");
- if (!Val0->getType()->isIntOrIntVector() &&
- !isa<PointerType>(Val0->getType()))
+ if (!Val0->getType()->isIntOrIntVectorTy() &&
+ !Val0->getType()->isPointerTy())
return Error(ID.Loc, "icmp requires pointer or integer operands");
ID.ConstantVal = ConstantExpr::getICmp(Pred, Val0, Val1);
}
return true;
if (Val0->getType() != Val1->getType())
return Error(ID.Loc, "operands of constexpr must have same type");
- if (!Val0->getType()->isIntOrIntVector()) {
+ if (!Val0->getType()->isIntOrIntVectorTy()) {
if (NUW)
return Error(ModifierLoc, "nuw only applies to integer operations");
if (NSW)
}
// API compatibility: Accept either integer or floating-point types with
// add, sub, and mul.
- if (!Val0->getType()->isIntOrIntVector() &&
- !Val0->getType()->isFPOrFPVector())
+ if (!Val0->getType()->isIntOrIntVectorTy() &&
+ !Val0->getType()->isFPOrFPVectorTy())
return Error(ID.Loc,"constexpr requires integer, fp, or vector operands");
unsigned Flags = 0;
if (NUW) Flags |= OverflowingBinaryOperator::NoUnsignedWrap;
return true;
if (Val0->getType() != Val1->getType())
return Error(ID.Loc, "operands of constexpr must have same type");
- if (!Val0->getType()->isIntOrIntVector())
+ if (!Val0->getType()->isIntOrIntVectorTy())
return Error(ID.Loc,
"constexpr requires integer or integer vector operands");
ID.ConstantVal = ConstantExpr::get(Opc, Val0, Val1);
return true;
if (Opc == Instruction::GetElementPtr) {
- if (Elts.size() == 0 || !isa<PointerType>(Elts[0]->getType()))
+ if (Elts.size() == 0 || !Elts[0]->getType()->isPointerTy())
return Error(ID.Loc, "getelementptr requires pointer operand");
if (!GetElementPtrInst::getIndexedType(Elts[0]->getType(),
}
/// ParseGlobalValue - Parse a global value with the specified type.
-bool LLParser::ParseGlobalValue(const Type *Ty, Constant *&V) {
- V = 0;
+bool LLParser::ParseGlobalValue(const Type *Ty, Constant *&C) {
+ C = 0;
ValID ID;
- return ParseValID(ID) ||
- ConvertGlobalValIDToValue(Ty, ID, V);
+ Value *V = NULL;
+ bool Parsed = ParseValID(ID) ||
+ ConvertValIDToValue(Ty, ID, V, NULL);
+ if (V && !(C = dyn_cast<Constant>(V)))
+ return Error(ID.Loc, "global values must be constants");
+ return Parsed;
+}
+
+bool LLParser::ParseGlobalTypeAndValue(Constant *&V) {
+ PATypeHolder Type(Type::getVoidTy(Context));
+ return ParseType(Type) ||
+ ParseGlobalValue(Type, V);
+}
+
+/// ParseGlobalValueVector
+/// ::= /*empty*/
+/// ::= TypeAndValue (',' TypeAndValue)*
+bool LLParser::ParseGlobalValueVector(SmallVectorImpl<Constant*> &Elts) {
+ // Empty list.
+ if (Lex.getKind() == lltok::rbrace ||
+ Lex.getKind() == lltok::rsquare ||
+ Lex.getKind() == lltok::greater ||
+ Lex.getKind() == lltok::rparen)
+ return false;
+
+ Constant *C;
+ if (ParseGlobalTypeAndValue(C)) return true;
+ Elts.push_back(C);
+
+ while (EatIfPresent(lltok::comma)) {
+ if (ParseGlobalTypeAndValue(C)) return true;
+ Elts.push_back(C);
+ }
+
+ return false;
}
-/// ConvertGlobalValIDToValue - Apply a type to a ValID to get a fully resolved
-/// constant.
-bool LLParser::ConvertGlobalValIDToValue(const Type *Ty, ValID &ID,
- Constant *&V) {
- if (isa<FunctionType>(Ty))
+
+//===----------------------------------------------------------------------===//
+// Function Parsing.
+//===----------------------------------------------------------------------===//
+
+bool LLParser::ConvertValIDToValue(const Type *Ty, ValID &ID, Value *&V,
+ PerFunctionState *PFS) {
+ if (Ty->isFunctionTy())
return Error(ID.Loc, "functions are not values, refer to them as pointers");
switch (ID.Kind) {
default: llvm_unreachable("Unknown ValID!");
- case ValID::t_Metadata:
- return Error(ID.Loc, "invalid use of metadata");
case ValID::t_LocalID:
+ if (!PFS) return Error(ID.Loc, "invalid use of function-local name");
+ V = PFS->GetVal(ID.UIntVal, Ty, ID.Loc);
+ return (V == 0);
case ValID::t_LocalName:
- return Error(ID.Loc, "invalid use of function-local name");
- case ValID::t_InlineAsm:
- return Error(ID.Loc, "inline asm can only be an operand of call/invoke");
+ if (!PFS) return Error(ID.Loc, "invalid use of function-local name");
+ V = PFS->GetVal(ID.StrVal, Ty, ID.Loc);
+ return (V == 0);
+ case ValID::t_InlineAsm: {
+ const PointerType *PTy = dyn_cast<PointerType>(Ty);
+ const FunctionType *FTy =
+ PTy ? dyn_cast<FunctionType>(PTy->getElementType()) : 0;
+ if (!FTy || !InlineAsm::Verify(FTy, ID.StrVal2))
+ return Error(ID.Loc, "invalid type for inline asm constraint string");
+ V = InlineAsm::get(FTy, ID.StrVal, ID.StrVal2, ID.UIntVal&1, ID.UIntVal>>1);
+ return false;
+ }
+ case ValID::t_MDNode:
+ if (!Ty->isMetadataTy())
+ return Error(ID.Loc, "metadata value must have metadata type");
+ V = ID.MDNodeVal;
+ return false;
+ case ValID::t_MDString:
+ if (!Ty->isMetadataTy())
+ return Error(ID.Loc, "metadata value must have metadata type");
+ V = ID.MDStringVal;
+ return false;
case ValID::t_GlobalName:
V = GetGlobalVal(ID.StrVal, Ty, ID.Loc);
return V == 0;
V = GetGlobalVal(ID.UIntVal, Ty, ID.Loc);
return V == 0;
case ValID::t_APSInt:
- if (!isa<IntegerType>(Ty))
+ if (!Ty->isIntegerTy())
return Error(ID.Loc, "integer constant must have integer type");
ID.APSIntVal.extOrTrunc(Ty->getPrimitiveSizeInBits());
V = ConstantInt::get(Context, ID.APSIntVal);
return false;
case ValID::t_APFloat:
- if (!Ty->isFloatingPoint() ||
+ if (!Ty->isFloatingPointTy() ||
!ConstantFP::isValueValidForType(Ty, ID.APFloatVal))
return Error(ID.Loc, "floating point constant invalid for type");
return false;
case ValID::t_Null:
- if (!isa<PointerType>(Ty))
+ if (!Ty->isPointerTy())
return Error(ID.Loc, "null must be a pointer type");
V = ConstantPointerNull::get(cast<PointerType>(Ty));
return false;
case ValID::t_Undef:
// FIXME: LabelTy should not be a first-class type.
if ((!Ty->isFirstClassType() || Ty->isLabelTy()) &&
- !isa<OpaqueType>(Ty))
+ !Ty->isOpaqueTy())
return Error(ID.Loc, "invalid type for undef constant");
V = UndefValue::get(Ty);
return false;
case ValID::t_EmptyArray:
- if (!isa<ArrayType>(Ty) || cast<ArrayType>(Ty)->getNumElements() != 0)
+ if (!Ty->isArrayTy() || cast<ArrayType>(Ty)->getNumElements() != 0)
return Error(ID.Loc, "invalid empty array initializer");
V = UndefValue::get(Ty);
return false;
V = Constant::getNullValue(Ty);
return false;
case ValID::t_Constant:
- if (ID.ConstantVal->getType() != Ty)
+ if (ID.ConstantVal->getType() != Ty) {
+ // Allow a constant struct with a single member to be converted
+ // to a union, if the union has a member which is the same type
+ // as the struct member.
+ if (const UnionType* utype = dyn_cast<UnionType>(Ty)) {
+ return ParseUnionValue(utype, ID, V);
+ }
+
return Error(ID.Loc, "constant expression type mismatch");
+ }
+
V = ID.ConstantVal;
return false;
}
}
-bool LLParser::ParseGlobalTypeAndValue(Constant *&V) {
- PATypeHolder Type(Type::getVoidTy(Context));
- return ParseType(Type) ||
- ParseGlobalValue(Type, V);
+bool LLParser::ParseValue(const Type *Ty, Value *&V, PerFunctionState &PFS) {
+ V = 0;
+ ValID ID;
+ return ParseValID(ID, &PFS) ||
+ ConvertValIDToValue(Ty, ID, V, &PFS);
}
-/// ParseGlobalValueVector
-/// ::= /*empty*/
-/// ::= TypeAndValue (',' TypeAndValue)*
-bool LLParser::ParseGlobalValueVector(SmallVectorImpl<Constant*> &Elts) {
- // Empty list.
- if (Lex.getKind() == lltok::rbrace ||
- Lex.getKind() == lltok::rsquare ||
- Lex.getKind() == lltok::greater ||
- Lex.getKind() == lltok::rparen)
- return false;
-
- Constant *C;
- if (ParseGlobalTypeAndValue(C)) return true;
- Elts.push_back(C);
-
- while (EatIfPresent(lltok::comma)) {
- if (ParseGlobalTypeAndValue(C)) return true;
- Elts.push_back(C);
- }
+bool LLParser::ParseTypeAndValue(Value *&V, PerFunctionState &PFS) {
+ PATypeHolder T(Type::getVoidTy(Context));
+ return ParseType(T) ||
+ ParseValue(T, V, PFS);
+}
+bool LLParser::ParseTypeAndBasicBlock(BasicBlock *&BB, LocTy &Loc,
+ PerFunctionState &PFS) {
+ Value *V;
+ Loc = Lex.getLoc();
+ if (ParseTypeAndValue(V, PFS)) return true;
+ if (!isa<BasicBlock>(V))
+ return Error(Loc, "expected a basic block");
+ BB = cast<BasicBlock>(V);
return false;
}
+bool LLParser::ParseUnionValue(const UnionType* utype, ValID &ID, Value *&V) {
+ if (const StructType* stype = dyn_cast<StructType>(ID.ConstantVal->getType())) {
+ if (stype->getNumContainedTypes() != 1)
+ return Error(ID.Loc, "constant expression type mismatch");
+ int index = utype->getElementTypeIndex(stype->getContainedType(0));
+ if (index < 0)
+ return Error(ID.Loc, "initializer type is not a member of the union");
-//===----------------------------------------------------------------------===//
-// Function Parsing.
-//===----------------------------------------------------------------------===//
-
-bool LLParser::ConvertValIDToValue(const Type *Ty, ValID &ID, Value *&V,
- PerFunctionState &PFS) {
- if (ID.Kind == ValID::t_LocalID)
- V = PFS.GetVal(ID.UIntVal, Ty, ID.Loc);
- else if (ID.Kind == ValID::t_LocalName)
- V = PFS.GetVal(ID.StrVal, Ty, ID.Loc);
- else if (ID.Kind == ValID::t_InlineAsm) {
- const PointerType *PTy = dyn_cast<PointerType>(Ty);
- const FunctionType *FTy =
- PTy ? dyn_cast<FunctionType>(PTy->getElementType()) : 0;
- if (!FTy || !InlineAsm::Verify(FTy, ID.StrVal2))
- return Error(ID.Loc, "invalid type for inline asm constraint string");
- V = InlineAsm::get(FTy, ID.StrVal, ID.StrVal2, ID.UIntVal&1, ID.UIntVal>>1);
- return false;
- } else if (ID.Kind == ValID::t_Metadata) {
- V = ID.MetadataVal;
- } else {
- Constant *C;
- if (ConvertGlobalValIDToValue(Ty, ID, C)) return true;
- V = C;
+ V = ConstantUnion::get(
+ utype, cast<Constant>(ID.ConstantVal->getOperand(0)));
return false;
}
- return V == 0;
-}
-
-bool LLParser::ParseValue(const Type *Ty, Value *&V, PerFunctionState &PFS) {
- V = 0;
- ValID ID;
- return ParseValID(ID) ||
- ConvertValIDToValue(Ty, ID, V, PFS);
+ return Error(ID.Loc, "constant expression type mismatch");
}
-bool LLParser::ParseTypeAndValue(Value *&V, PerFunctionState &PFS) {
- PATypeHolder T(Type::getVoidTy(Context));
- return ParseType(T) ||
- ParseValue(T, V, PFS);
-}
/// FunctionHeader
/// ::= OptionalLinkage OptionalVisibility OptionalCallingConv OptRetAttrs
return Error(LinkageLoc, "invalid linkage for function declaration");
break;
case GlobalValue::AppendingLinkage:
- case GlobalValue::GhostLinkage:
case GlobalValue::CommonLinkage:
return Error(LinkageLoc, "invalid function linkage type");
}
if (!FunctionType::isValidReturnType(RetType) ||
- isa<OpaqueType>(RetType))
+ RetType->isOpaqueTy())
return Error(RetTypeLoc, "invalid function return type");
LocTy NameLoc = Lex.getLoc();
AttrListPtr PAL = AttrListPtr::get(Attrs.begin(), Attrs.end());
- if (PAL.paramHasAttr(1, Attribute::StructRet) &&
- RetType != Type::getVoidTy(Context))
+ if (PAL.paramHasAttr(1, Attribute::StructRet) && !RetType->isVoidTy())
return Error(RetTypeLoc, "functions with 'sret' argument must return void");
const FunctionType *FT =
// Add all of the arguments we parsed to the function.
Function::arg_iterator ArgIt = Fn->arg_begin();
for (unsigned i = 0, e = ArgList.size(); i != e; ++i, ++ArgIt) {
+ // If we run out of arguments in the Function prototype, exit early.
+ // FIXME: REMOVE THIS IN LLVM 3.0, this is just for the mismatch case above.
+ if (ArgIt == Fn->arg_end()) break;
+
// If the argument has a name, insert it into the argument symbol table.
if (ArgList[i].Name.empty()) continue;
return TokError("expected '{' in function body");
Lex.Lex(); // eat the {.
- PerFunctionState PFS(*this, Fn);
+ int FunctionNumber = -1;
+ if (!Fn.hasName()) FunctionNumber = NumberedVals.size()-1;
+
+ PerFunctionState PFS(*this, Fn, FunctionNumber);
+ // We need at least one basic block.
+ if (Lex.getKind() == lltok::rbrace || Lex.getKind() == lltok::kw_end)
+ return TokError("function body requires at least one basic block");
+
while (Lex.getKind() != lltok::rbrace && Lex.getKind() != lltok::kw_end)
if (ParseBasicBlock(PFS)) return true;
Lex.Lex();
// Verify function is ok.
- return PFS.VerifyFunctionComplete();
+ return PFS.FinishFunction();
}
/// ParseBasicBlock
// Parse the instructions in this block until we get a terminator.
Instruction *Inst;
+ SmallVector<std::pair<unsigned, MDNode *>, 4> MetadataOnInst;
do {
// This instruction may have three possibilities for a name: a) none
// specified, b) name specified "%foo =", c) number specified: "%4 =".
return true;
}
- if (ParseInstruction(Inst, BB, PFS)) return true;
- if (EatIfPresent(lltok::comma))
- ParseOptionalCustomMetadata();
-
- // Set metadata attached with this instruction.
- MetadataContext &TheMetadata = M->getContext().getMetadata();
- for (SmallVector<std::pair<unsigned, MDNode *>, 2>::iterator
- MDI = MDsOnInst.begin(), MDE = MDsOnInst.end(); MDI != MDE; ++MDI)
- TheMetadata.addMD(MDI->first, MDI->second, Inst);
- MDsOnInst.clear();
+ switch (ParseInstruction(Inst, BB, PFS)) {
+ default: assert(0 && "Unknown ParseInstruction result!");
+ case InstError: return true;
+ case InstNormal:
+ // With a normal result, we check to see if the instruction is followed by
+ // a comma and metadata.
+ if (EatIfPresent(lltok::comma))
+ if (ParseInstructionMetadata(Inst))
+ return true;
+ break;
+ case InstExtraComma:
+ // If the instruction parser ate an extra comma at the end of it, it
+ // *must* be followed by metadata.
+ if (ParseInstructionMetadata(Inst))
+ return true;
+ break;
+ }
BB->getInstList().push_back(Inst);
/// ParseInstruction - Parse one of the many different instructions.
///
-bool LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB,
- PerFunctionState &PFS) {
+int LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB,
+ PerFunctionState &PFS) {
lltok::Kind Token = Lex.getKind();
if (Token == lltok::Eof)
return TokError("found end of file when expecting more instructions");
case lltok::kw_ret: return ParseRet(Inst, BB, PFS);
case lltok::kw_br: return ParseBr(Inst, PFS);
case lltok::kw_switch: return ParseSwitch(Inst, PFS);
+ case lltok::kw_indirectbr: return ParseIndirectBr(Inst, PFS);
case lltok::kw_invoke: return ParseInvoke(Inst, PFS);
// Binary Operators.
case lltok::kw_add:
// API compatibility: Accept either integer or floating-point types.
bool Result = ParseArithmetic(Inst, PFS, KeywordVal, 0);
if (!Result) {
- if (!Inst->getType()->isIntOrIntVector()) {
+ if (!Inst->getType()->isIntOrIntVectorTy()) {
if (NUW)
return Error(ModifierLoc, "nuw only applies to integer operations");
if (NSW)
//===----------------------------------------------------------------------===//
/// ParseRet - Parse a return instruction.
-/// ::= 'ret' void (',' !dbg, !1)
-/// ::= 'ret' TypeAndValue (',' !dbg, !1)
-/// ::= 'ret' TypeAndValue (',' TypeAndValue)+ (',' !dbg, !1)
+/// ::= 'ret' void (',' !dbg, !1)*
+/// ::= 'ret' TypeAndValue (',' !dbg, !1)*
+/// ::= 'ret' TypeAndValue (',' TypeAndValue)+ (',' !dbg, !1)*
/// [[obsolete: LLVM 3.0]]
-bool LLParser::ParseRet(Instruction *&Inst, BasicBlock *BB,
- PerFunctionState &PFS) {
+int LLParser::ParseRet(Instruction *&Inst, BasicBlock *BB,
+ PerFunctionState &PFS) {
PATypeHolder Ty(Type::getVoidTy(Context));
if (ParseType(Ty, true /*void allowed*/)) return true;
Value *RV;
if (ParseValue(Ty, RV, PFS)) return true;
+ bool ExtraComma = false;
if (EatIfPresent(lltok::comma)) {
// Parse optional custom metadata, e.g. !dbg
- if (Lex.getKind() == lltok::NamedOrCustomMD) {
- if (ParseOptionalCustomMetadata()) return true;
+ if (Lex.getKind() == lltok::MetadataVar) {
+ ExtraComma = true;
} else {
// The normal case is one return value.
- // FIXME: LLVM 3.0 remove MRV support for 'ret i32 1, i32 2', requiring use
- // of 'ret {i32,i32} {i32 1, i32 2}'
+ // FIXME: LLVM 3.0 remove MRV support for 'ret i32 1, i32 2', requiring
+ // use of 'ret {i32,i32} {i32 1, i32 2}'
SmallVector<Value*, 8> RVs;
RVs.push_back(RV);
do {
// If optional custom metadata, e.g. !dbg is seen then this is the
// end of MRV.
- if (Lex.getKind() == lltok::NamedOrCustomMD)
+ if (Lex.getKind() == lltok::MetadataVar)
break;
if (ParseTypeAndValue(RV, PFS)) return true;
RVs.push_back(RV);
}
Inst = ReturnInst::Create(Context, RV);
- return false;
+ return ExtraComma ? InstExtraComma : InstNormal;
}
/// ::= 'br' TypeAndValue ',' TypeAndValue ',' TypeAndValue
bool LLParser::ParseBr(Instruction *&Inst, PerFunctionState &PFS) {
LocTy Loc, Loc2;
- Value *Op0, *Op1, *Op2;
+ Value *Op0;
+ BasicBlock *Op1, *Op2;
if (ParseTypeAndValue(Op0, Loc, PFS)) return true;
if (BasicBlock *BB = dyn_cast<BasicBlock>(Op0)) {
return Error(Loc, "branch condition must have 'i1' type");
if (ParseToken(lltok::comma, "expected ',' after branch condition") ||
- ParseTypeAndValue(Op1, Loc, PFS) ||
+ ParseTypeAndBasicBlock(Op1, Loc, PFS) ||
ParseToken(lltok::comma, "expected ',' after true destination") ||
- ParseTypeAndValue(Op2, Loc2, PFS))
+ ParseTypeAndBasicBlock(Op2, Loc2, PFS))
return true;
- if (!isa<BasicBlock>(Op1))
- return Error(Loc, "true destination of branch must be a basic block");
- if (!isa<BasicBlock>(Op2))
- return Error(Loc2, "true destination of branch must be a basic block");
-
- Inst = BranchInst::Create(cast<BasicBlock>(Op1), cast<BasicBlock>(Op2), Op0);
+ Inst = BranchInst::Create(Op1, Op2, Op0);
return false;
}
/// ::= (TypeAndValue ',' TypeAndValue)*
bool LLParser::ParseSwitch(Instruction *&Inst, PerFunctionState &PFS) {
LocTy CondLoc, BBLoc;
- Value *Cond, *DefaultBB;
+ Value *Cond;
+ BasicBlock *DefaultBB;
if (ParseTypeAndValue(Cond, CondLoc, PFS) ||
ParseToken(lltok::comma, "expected ',' after switch condition") ||
- ParseTypeAndValue(DefaultBB, BBLoc, PFS) ||
+ ParseTypeAndBasicBlock(DefaultBB, BBLoc, PFS) ||
ParseToken(lltok::lsquare, "expected '[' with switch table"))
return true;
- if (!isa<IntegerType>(Cond->getType()))
+ if (!Cond->getType()->isIntegerTy())
return Error(CondLoc, "switch condition must have integer type");
- if (!isa<BasicBlock>(DefaultBB))
- return Error(BBLoc, "default destination must be a basic block");
// Parse the jump table pairs.
SmallPtrSet<Value*, 32> SeenCases;
SmallVector<std::pair<ConstantInt*, BasicBlock*>, 32> Table;
while (Lex.getKind() != lltok::rsquare) {
- Value *Constant, *DestBB;
+ Value *Constant;
+ BasicBlock *DestBB;
if (ParseTypeAndValue(Constant, CondLoc, PFS) ||
ParseToken(lltok::comma, "expected ',' after case value") ||
- ParseTypeAndValue(DestBB, BBLoc, PFS))
+ ParseTypeAndBasicBlock(DestBB, PFS))
return true;
-
+
if (!SeenCases.insert(Constant))
return Error(CondLoc, "duplicate case value in switch");
if (!isa<ConstantInt>(Constant))
return Error(CondLoc, "case value is not a constant integer");
- if (!isa<BasicBlock>(DestBB))
- return Error(BBLoc, "case destination is not a basic block");
- Table.push_back(std::make_pair(cast<ConstantInt>(Constant),
- cast<BasicBlock>(DestBB)));
+ Table.push_back(std::make_pair(cast<ConstantInt>(Constant), DestBB));
}
Lex.Lex(); // Eat the ']'.
- SwitchInst *SI = SwitchInst::Create(Cond, cast<BasicBlock>(DefaultBB),
- Table.size());
+ SwitchInst *SI = SwitchInst::Create(Cond, DefaultBB, Table.size());
for (unsigned i = 0, e = Table.size(); i != e; ++i)
SI->addCase(Table[i].first, Table[i].second);
Inst = SI;
return false;
}
+/// ParseIndirectBr
+/// Instruction
+/// ::= 'indirectbr' TypeAndValue ',' '[' LabelList ']'
+bool LLParser::ParseIndirectBr(Instruction *&Inst, PerFunctionState &PFS) {
+ LocTy AddrLoc;
+ Value *Address;
+ if (ParseTypeAndValue(Address, AddrLoc, PFS) ||
+ ParseToken(lltok::comma, "expected ',' after indirectbr address") ||
+ ParseToken(lltok::lsquare, "expected '[' with indirectbr"))
+ return true;
+
+ if (!Address->getType()->isPointerTy())
+ return Error(AddrLoc, "indirectbr address must have pointer type");
+
+ // Parse the destination list.
+ SmallVector<BasicBlock*, 16> DestList;
+
+ if (Lex.getKind() != lltok::rsquare) {
+ BasicBlock *DestBB;
+ if (ParseTypeAndBasicBlock(DestBB, PFS))
+ return true;
+ DestList.push_back(DestBB);
+
+ while (EatIfPresent(lltok::comma)) {
+ if (ParseTypeAndBasicBlock(DestBB, PFS))
+ return true;
+ DestList.push_back(DestBB);
+ }
+ }
+
+ if (ParseToken(lltok::rsquare, "expected ']' at end of block list"))
+ return true;
+
+ IndirectBrInst *IBI = IndirectBrInst::Create(Address, DestList.size());
+ for (unsigned i = 0, e = DestList.size(); i != e; ++i)
+ IBI->addDestination(DestList[i]);
+ Inst = IBI;
+ return false;
+}
+
+
/// ParseInvoke
/// ::= 'invoke' OptionalCallingConv OptionalAttrs Type Value ParamList
/// OptionalAttrs 'to' TypeAndValue 'unwind' TypeAndValue
ValID CalleeID;
SmallVector<ParamInfo, 16> ArgList;
- Value *NormalBB, *UnwindBB;
+ BasicBlock *NormalBB, *UnwindBB;
if (ParseOptionalCallingConv(CC) ||
ParseOptionalAttrs(RetAttrs, 1) ||
ParseType(RetType, RetTypeLoc, true /*void allowed*/) ||
ParseParameterList(ArgList, PFS) ||
ParseOptionalAttrs(FnAttrs, 2) ||
ParseToken(lltok::kw_to, "expected 'to' in invoke") ||
- ParseTypeAndValue(NormalBB, PFS) ||
+ ParseTypeAndBasicBlock(NormalBB, PFS) ||
ParseToken(lltok::kw_unwind, "expected 'unwind' in invoke") ||
- ParseTypeAndValue(UnwindBB, PFS))
+ ParseTypeAndBasicBlock(UnwindBB, PFS))
return true;
- if (!isa<BasicBlock>(NormalBB))
- return Error(CallLoc, "normal destination is not a basic block");
- if (!isa<BasicBlock>(UnwindBB))
- return Error(CallLoc, "unwind destination is not a basic block");
-
// If RetType is a non-function pointer type, then this is the short syntax
// for the call, which means that RetType is just the return type. Infer the
// rest of the function argument types from the arguments that are present.
// Look up the callee.
Value *Callee;
- if (ConvertValIDToValue(PFTy, CalleeID, Callee, PFS)) return true;
+ if (ConvertValIDToValue(PFTy, CalleeID, Callee, &PFS)) return true;
// FIXME: In LLVM 3.0, stop accepting zext, sext and inreg as optional
// function attributes.
// Finish off the Attributes and check them
AttrListPtr PAL = AttrListPtr::get(Attrs.begin(), Attrs.end());
- InvokeInst *II = InvokeInst::Create(Callee, cast<BasicBlock>(NormalBB),
- cast<BasicBlock>(UnwindBB),
+ InvokeInst *II = InvokeInst::Create(Callee, NormalBB, UnwindBB,
Args.begin(), Args.end());
II->setCallingConv(CC);
II->setAttributes(PAL);
switch (OperandType) {
default: llvm_unreachable("Unknown operand type!");
case 0: // int or FP.
- Valid = LHS->getType()->isIntOrIntVector() ||
- LHS->getType()->isFPOrFPVector();
+ Valid = LHS->getType()->isIntOrIntVectorTy() ||
+ LHS->getType()->isFPOrFPVectorTy();
break;
- case 1: Valid = LHS->getType()->isIntOrIntVector(); break;
- case 2: Valid = LHS->getType()->isFPOrFPVector(); break;
+ case 1: Valid = LHS->getType()->isIntOrIntVectorTy(); break;
+ case 2: Valid = LHS->getType()->isFPOrFPVectorTy(); break;
}
if (!Valid)
ParseValue(LHS->getType(), RHS, PFS))
return true;
- if (!LHS->getType()->isIntOrIntVector())
+ if (!LHS->getType()->isIntOrIntVectorTy())
return Error(Loc,"instruction requires integer or integer vector operands");
Inst = BinaryOperator::Create((Instruction::BinaryOps)Opc, LHS, RHS);
return true;
if (Opc == Instruction::FCmp) {
- if (!LHS->getType()->isFPOrFPVector())
+ if (!LHS->getType()->isFPOrFPVectorTy())
return Error(Loc, "fcmp requires floating point operands");
Inst = new FCmpInst(CmpInst::Predicate(Pred), LHS, RHS);
} else {
assert(Opc == Instruction::ICmp && "Unknown opcode for CmpInst!");
- if (!LHS->getType()->isIntOrIntVector() &&
- !isa<PointerType>(LHS->getType()))
+ if (!LHS->getType()->isIntOrIntVectorTy() &&
+ !LHS->getType()->isPointerTy())
return Error(Loc, "icmp requires integer operands");
Inst = new ICmpInst(CmpInst::Predicate(Pred), LHS, RHS);
}
/// ParsePHI
/// ::= 'phi' Type '[' Value ',' Value ']' (',' '[' Value ',' Value ']')*
-bool LLParser::ParsePHI(Instruction *&Inst, PerFunctionState &PFS) {
+int LLParser::ParsePHI(Instruction *&Inst, PerFunctionState &PFS) {
PATypeHolder Ty(Type::getVoidTy(Context));
Value *Op0, *Op1;
LocTy TypeLoc = Lex.getLoc();
ParseToken(lltok::rsquare, "expected ']' in phi value list"))
return true;
+ bool AteExtraComma = false;
SmallVector<std::pair<Value*, BasicBlock*>, 16> PHIVals;
while (1) {
PHIVals.push_back(std::make_pair(Op0, cast<BasicBlock>(Op1)));
if (!EatIfPresent(lltok::comma))
break;
- if (Lex.getKind() == lltok::NamedOrCustomMD)
+ if (Lex.getKind() == lltok::MetadataVar) {
+ AteExtraComma = true;
break;
+ }
if (ParseToken(lltok::lsquare, "expected '[' in phi value list") ||
ParseValue(Ty, Op0, PFS) ||
return true;
}
- if (Lex.getKind() == lltok::NamedOrCustomMD)
- if (ParseOptionalCustomMetadata()) return true;
-
if (!Ty->isFirstClassType())
return Error(TypeLoc, "phi node must have first class type");
for (unsigned i = 0, e = PHIVals.size(); i != e; ++i)
PN->addIncoming(PHIVals[i].first, PHIVals[i].second);
Inst = PN;
- return false;
+ return AteExtraComma ? InstExtraComma : InstNormal;
}
/// ParseCall
// Look up the callee.
Value *Callee;
- if (ConvertValIDToValue(PFTy, CalleeID, Callee, PFS)) return true;
+ if (ConvertValIDToValue(PFTy, CalleeID, Callee, &PFS)) return true;
// FIXME: In LLVM 3.0, stop accepting zext, sext and inreg as optional
// function attributes.
/// ParseAlloc
/// ::= 'malloc' Type (',' TypeAndValue)? (',' OptionalInfo)?
/// ::= 'alloca' Type (',' TypeAndValue)? (',' OptionalInfo)?
-bool LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS,
- BasicBlock* BB, bool isAlloca) {
+int LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS,
+ BasicBlock* BB, bool isAlloca) {
PATypeHolder Ty(Type::getVoidTy(Context));
Value *Size = 0;
LocTy SizeLoc;
unsigned Alignment = 0;
if (ParseType(Ty)) return true;
+ bool AteExtraComma = false;
if (EatIfPresent(lltok::comma)) {
- if (Lex.getKind() == lltok::kw_align
- || Lex.getKind() == lltok::NamedOrCustomMD) {
- if (ParseOptionalInfo(Alignment)) return true;
+ if (Lex.getKind() == lltok::kw_align) {
+ if (ParseOptionalAlignment(Alignment)) return true;
+ } else if (Lex.getKind() == lltok::MetadataVar) {
+ AteExtraComma = true;
} else {
- if (ParseTypeAndValue(Size, SizeLoc, PFS)) return true;
- if (EatIfPresent(lltok::comma))
- if (ParseOptionalInfo(Alignment)) return true;
+ if (ParseTypeAndValue(Size, SizeLoc, PFS) ||
+ ParseOptionalCommaAlign(Alignment, AteExtraComma))
+ return true;
}
}
- if (Size && Size->getType() != Type::getInt32Ty(Context))
+ if (Size && !Size->getType()->isIntegerTy(32))
return Error(SizeLoc, "element count must be i32");
if (isAlloca) {
Inst = new AllocaInst(Ty, Size, Alignment);
- return false;
+ return AteExtraComma ? InstExtraComma : InstNormal;
}
// Autoupgrade old malloc instruction to malloc call.
// FIXME: Remove in LLVM 3.0.
const Type *IntPtrTy = Type::getInt32Ty(Context);
+ Constant *AllocSize = ConstantExpr::getSizeOf(Ty);
+ AllocSize = ConstantExpr::getTruncOrBitCast(AllocSize, IntPtrTy);
if (!MallocF)
// Prototype malloc as "void *(int32)".
// This function is renamed as "malloc" in ValidateEndOfModule().
MallocF = cast<Function>(
M->getOrInsertFunction("", Type::getInt8PtrTy(Context), IntPtrTy, NULL));
- Inst = CallInst::CreateMalloc(BB, IntPtrTy, Ty, Size, MallocF);
- return false;
+ Inst = CallInst::CreateMalloc(BB, IntPtrTy, Ty, AllocSize, Size, MallocF);
+return AteExtraComma ? InstExtraComma : InstNormal;
}
/// ParseFree
BasicBlock* BB) {
Value *Val; LocTy Loc;
if (ParseTypeAndValue(Val, Loc, PFS)) return true;
- if (!isa<PointerType>(Val->getType()))
+ if (!Val->getType()->isPointerTy())
return Error(Loc, "operand to free must be a pointer");
Inst = CallInst::CreateFree(Val, BB);
return false;
/// ParseLoad
/// ::= 'volatile'? 'load' TypeAndValue (',' OptionalInfo)?
-bool LLParser::ParseLoad(Instruction *&Inst, PerFunctionState &PFS,
- bool isVolatile) {
+int LLParser::ParseLoad(Instruction *&Inst, PerFunctionState &PFS,
+ bool isVolatile) {
Value *Val; LocTy Loc;
unsigned Alignment = 0;
- if (ParseTypeAndValue(Val, Loc, PFS)) return true;
-
- if (EatIfPresent(lltok::comma))
- if (ParseOptionalInfo(Alignment)) return true;
+ bool AteExtraComma = false;
+ if (ParseTypeAndValue(Val, Loc, PFS) ||
+ ParseOptionalCommaAlign(Alignment, AteExtraComma))
+ return true;
- if (!isa<PointerType>(Val->getType()) ||
+ if (!Val->getType()->isPointerTy() ||
!cast<PointerType>(Val->getType())->getElementType()->isFirstClassType())
return Error(Loc, "load operand must be a pointer to a first class type");
Inst = new LoadInst(Val, "", isVolatile, Alignment);
- return false;
+ return AteExtraComma ? InstExtraComma : InstNormal;
}
/// ParseStore
/// ::= 'volatile'? 'store' TypeAndValue ',' TypeAndValue (',' 'align' i32)?
-bool LLParser::ParseStore(Instruction *&Inst, PerFunctionState &PFS,
- bool isVolatile) {
+int LLParser::ParseStore(Instruction *&Inst, PerFunctionState &PFS,
+ bool isVolatile) {
Value *Val, *Ptr; LocTy Loc, PtrLoc;
unsigned Alignment = 0;
+ bool AteExtraComma = false;
if (ParseTypeAndValue(Val, Loc, PFS) ||
ParseToken(lltok::comma, "expected ',' after store operand") ||
- ParseTypeAndValue(Ptr, PtrLoc, PFS))
+ ParseTypeAndValue(Ptr, PtrLoc, PFS) ||
+ ParseOptionalCommaAlign(Alignment, AteExtraComma))
return true;
- if (EatIfPresent(lltok::comma))
- if (ParseOptionalInfo(Alignment)) return true;
-
- if (!isa<PointerType>(Ptr->getType()))
+ if (!Ptr->getType()->isPointerTy())
return Error(PtrLoc, "store operand must be a pointer");
if (!Val->getType()->isFirstClassType())
return Error(Loc, "store operand must be a first class value");
return Error(Loc, "stored value and pointer type do not match");
Inst = new StoreInst(Val, Ptr, isVolatile, Alignment);
- return false;
+ return AteExtraComma ? InstExtraComma : InstNormal;
}
/// ParseGetResult
ParseUInt32(Element, EltLoc))
return true;
- if (!isa<StructType>(Val->getType()) && !isa<ArrayType>(Val->getType()))
+ if (!Val->getType()->isStructTy() && !Val->getType()->isArrayTy())
return Error(ValLoc, "getresult inst requires an aggregate operand");
if (!ExtractValueInst::getIndexedType(Val->getType(), Element))
return Error(EltLoc, "invalid getresult index for value");
/// ParseGetElementPtr
/// ::= 'getelementptr' 'inbounds'? TypeAndValue (',' TypeAndValue)*
-bool LLParser::ParseGetElementPtr(Instruction *&Inst, PerFunctionState &PFS) {
+int LLParser::ParseGetElementPtr(Instruction *&Inst, PerFunctionState &PFS) {
Value *Ptr, *Val; LocTy Loc, EltLoc;
bool InBounds = EatIfPresent(lltok::kw_inbounds);
if (ParseTypeAndValue(Ptr, Loc, PFS)) return true;
- if (!isa<PointerType>(Ptr->getType()))
+ if (!Ptr->getType()->isPointerTy())
return Error(Loc, "base of getelementptr must be a pointer");
SmallVector<Value*, 16> Indices;
+ bool AteExtraComma = false;
while (EatIfPresent(lltok::comma)) {
- if (Lex.getKind() == lltok::NamedOrCustomMD)
+ if (Lex.getKind() == lltok::MetadataVar) {
+ AteExtraComma = true;
break;
+ }
if (ParseTypeAndValue(Val, EltLoc, PFS)) return true;
- if (!isa<IntegerType>(Val->getType()))
+ if (!Val->getType()->isIntegerTy())
return Error(EltLoc, "getelementptr index must be an integer");
Indices.push_back(Val);
}
- if (Lex.getKind() == lltok::NamedOrCustomMD)
- if (ParseOptionalCustomMetadata()) return true;
if (!GetElementPtrInst::getIndexedType(Ptr->getType(),
Indices.begin(), Indices.end()))
Inst = GetElementPtrInst::Create(Ptr, Indices.begin(), Indices.end());
if (InBounds)
cast<GetElementPtrInst>(Inst)->setIsInBounds(true);
- return false;
+ return AteExtraComma ? InstExtraComma : InstNormal;
}
/// ParseExtractValue
/// ::= 'extractvalue' TypeAndValue (',' uint32)+
-bool LLParser::ParseExtractValue(Instruction *&Inst, PerFunctionState &PFS) {
+int LLParser::ParseExtractValue(Instruction *&Inst, PerFunctionState &PFS) {
Value *Val; LocTy Loc;
SmallVector<unsigned, 4> Indices;
+ bool AteExtraComma;
if (ParseTypeAndValue(Val, Loc, PFS) ||
- ParseIndexList(Indices))
+ ParseIndexList(Indices, AteExtraComma))
return true;
- if (!isa<StructType>(Val->getType()) && !isa<ArrayType>(Val->getType()))
- return Error(Loc, "extractvalue operand must be array or struct");
+ if (!Val->getType()->isAggregateType())
+ return Error(Loc, "extractvalue operand must be aggregate type");
if (!ExtractValueInst::getIndexedType(Val->getType(), Indices.begin(),
Indices.end()))
return Error(Loc, "invalid indices for extractvalue");
Inst = ExtractValueInst::Create(Val, Indices.begin(), Indices.end());
- return false;
+ return AteExtraComma ? InstExtraComma : InstNormal;
}
/// ParseInsertValue
/// ::= 'insertvalue' TypeAndValue ',' TypeAndValue (',' uint32)+
-bool LLParser::ParseInsertValue(Instruction *&Inst, PerFunctionState &PFS) {
+int LLParser::ParseInsertValue(Instruction *&Inst, PerFunctionState &PFS) {
Value *Val0, *Val1; LocTy Loc0, Loc1;
SmallVector<unsigned, 4> Indices;
+ bool AteExtraComma;
if (ParseTypeAndValue(Val0, Loc0, PFS) ||
ParseToken(lltok::comma, "expected comma after insertvalue operand") ||
ParseTypeAndValue(Val1, Loc1, PFS) ||
- ParseIndexList(Indices))
+ ParseIndexList(Indices, AteExtraComma))
return true;
-
- if (!isa<StructType>(Val0->getType()) && !isa<ArrayType>(Val0->getType()))
- return Error(Loc0, "extractvalue operand must be array or struct");
+
+ if (!Val0->getType()->isAggregateType())
+ return Error(Loc0, "insertvalue operand must be aggregate type");
if (!ExtractValueInst::getIndexedType(Val0->getType(), Indices.begin(),
Indices.end()))
return Error(Loc0, "invalid indices for insertvalue");
Inst = InsertValueInst::Create(Val0, Val1, Indices.begin(), Indices.end());
- return false;
+ return AteExtraComma ? InstExtraComma : InstNormal;
}
//===----------------------------------------------------------------------===//
/// ::= Element (',' Element)*
/// Element
/// ::= 'null' | TypeAndValue
-bool LLParser::ParseMDNodeVector(SmallVectorImpl<Value*> &Elts) {
- assert(Lex.getKind() == lltok::lbrace);
- Lex.Lex();
+bool LLParser::ParseMDNodeVector(SmallVectorImpl<Value*> &Elts,
+ PerFunctionState *PFS) {
do {
- Value *V = 0;
- if (Lex.getKind() == lltok::kw_null) {
- Lex.Lex();
- V = 0;
- } else {
- PATypeHolder Ty(Type::getVoidTy(Context));
- if (ParseType(Ty)) return true;
- if (Lex.getKind() == lltok::Metadata) {
- Lex.Lex();
- MetadataBase *Node = 0;
- if (!ParseMDNode(Node))
- V = Node;
- else {
- MetadataBase *MDS = 0;
- if (ParseMDString(MDS)) return true;
- V = MDS;
- }
- } else {
- Constant *C;
- if (ParseGlobalValue(Ty, C)) return true;
- V = C;
- }
+ // Null is a special case since it is typeless.
+ if (EatIfPresent(lltok::kw_null)) {
+ Elts.push_back(0);
+ continue;
}
+
+ Value *V = 0;
+ PATypeHolder Ty(Type::getVoidTy(Context));
+ ValID ID;
+ if (ParseType(Ty) || ParseValID(ID, PFS) ||
+ ConvertValIDToValue(Ty, ID, V, PFS))
+ return true;
+
Elts.push_back(V);
} while (EatIfPresent(lltok::comma));