#include "LLParser.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/AsmParser/SlotMapping.h"
#include "llvm/IR/AutoUpgrade.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/IR/Constants.h"
+#include "llvm/IR/DebugInfo.h"
+#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Operator.h"
#include "llvm/IR/ValueSymbolTable.h"
+#include "llvm/Support/Dwarf.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/SaveAndRestore.h"
#include "llvm/Support/raw_ostream.h"
ValidateEndOfModule();
}
+bool LLParser::parseStandaloneConstantValue(Constant *&C) {
+ Lex.Lex();
+
+ Type *Ty = nullptr;
+ if (ParseType(Ty) || parseConstantValue(Ty, C))
+ return true;
+ if (Lex.getKind() != lltok::Eof)
+ return Error(Lex.getLoc(), "expected end of string");
+ return false;
+}
+
/// 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] == nullptr)
- return Error(MDList[i].Loc, "use of undefined metadata '!" +
- Twine(SlotNo) + "'");
- assert(!NumberedMetadata[SlotNo]->isFunctionLocal() &&
- "Unexpected function-local metadata");
- Inst->setMetadata(MDList[i].MDKind, NumberedMetadata[SlotNo]);
- }
- }
- ForwardRefInstMetadata.clear();
- }
-
for (unsigned I = 0, E = InstsWithTBAATag.size(); I < E; I++)
UpgradeInstWithTBAATag(InstsWithTBAATag[I]);
return Error(ForwardRefBlockAddresses.begin()->first.Loc,
"expected function name in blockaddress");
- for (unsigned i = 0, e = NumberedTypes.size(); i != e; ++i)
- if (NumberedTypes[i].second.isValid())
- return Error(NumberedTypes[i].second,
- "use of undefined type '%" + Twine(i) + "'");
+ for (const auto &NT : NumberedTypes)
+ if (NT.second.second.isValid())
+ return Error(NT.second.second,
+ "use of undefined type '%" + Twine(NT.first) + "'");
for (StringMap<std::pair<Type*, LocTy> >::iterator I =
NamedTypes.begin(), E = NamedTypes.end(); I != E; ++I)
"use of undefined metadata '!" +
Twine(ForwardRefMDNodes.begin()->first) + "'");
+ // Resolve metadata cycles.
+ for (auto &N : NumberedMetadata) {
+ if (N.second && !N.second->isResolved())
+ N.second->resolveCycles();
+ }
// Look for intrinsic functions and CallInst that need to be upgraded
for (Module::iterator FI = M->begin(), FE = M->end(); FI != FE; )
UpgradeDebugInfo(*M);
+ if (!Slots)
+ return false;
+ // Initialize the slot mapping.
+ // Because by this point we've parsed and validated everything, we can "steal"
+ // the mapping from LLParser as it doesn't need it anymore.
+ Slots->GlobalValues = std::move(NumberedVals);
+ Slots->MetadataNodes = std::move(NumberedMetadata);
+
return false;
}
// The Global variable production with no name can have many different
// optional leading prefixes, the production is:
// GlobalVar ::= OptionalLinkage OptionalVisibility OptionalDLLStorageClass
- // OptionalThreadLocal OptionalAddrSpace OptionalUnNammedAddr
+ // OptionalThreadLocal OptionalAddrSpace OptionalUnnamedAddr
// ('constant'|'global') ...
case lltok::kw_private: // OptionalLinkage
case lltok::kw_internal: // OptionalLinkage
ParseToken(lltok::kw_type, "expected 'type' after '='"))
return true;
- if (TypeID >= NumberedTypes.size())
- NumberedTypes.resize(TypeID+1);
-
Type *Result = nullptr;
if (ParseStructDefinition(TypeLoc, "",
NumberedTypes[TypeID], Result)) return true;
}
/// toplevelentity
-/// ::= 'define' FunctionHeader '{' ...
+/// ::= 'define' FunctionHeader (!dbg !56)* '{' ...
bool LLParser::ParseDefine() {
assert(Lex.getKind() == lltok::kw_define);
Lex.Lex();
Function *F;
return ParseFunctionHeader(F, true) ||
+ ParseOptionalFunctionMetadata(*F) ||
ParseFunctionBody(*F);
}
// MDNode:
// ::= '!' MDNodeNumber
-//
-/// 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, ... }
- if (ParseUInt32(SlotNo)) return true;
-
- // Check existing MDNode.
- if (SlotNo < NumberedMetadata.size() && NumberedMetadata[SlotNo] != nullptr)
- Result = NumberedMetadata[SlotNo];
- else
- Result = nullptr;
- return false;
-}
-
bool LLParser::ParseMDNodeID(MDNode *&Result) {
// !{ ..., !42, ... }
unsigned MID = 0;
- if (ParseMDNodeID(Result, MID)) return true;
+ if (ParseUInt32(MID))
+ return true;
// If not a forward reference, just return it now.
- if (Result) return false;
+ if (NumberedMetadata.count(MID)) {
+ Result = NumberedMetadata[MID];
+ return false;
+ }
// Otherwise, create MDNode forward reference.
- MDNode *FwdNode = MDNode::getTemporary(Context, None);
- ForwardRefMDNodes[MID] = std::make_pair(FwdNode, Lex.getLoc());
+ auto &FwdRef = ForwardRefMDNodes[MID];
+ FwdRef = std::make_pair(MDTuple::getTemporary(Context, None), Lex.getLoc());
- if (NumberedMetadata.size() <= MID)
- NumberedMetadata.resize(MID+1);
- NumberedMetadata[MID] = FwdNode;
- Result = FwdNode;
+ Result = FwdRef.first.get();
+ NumberedMetadata[MID].reset(Result);
return false;
}
NMD->addOperand(N);
} while (EatIfPresent(lltok::comma));
- if (ParseToken(lltok::rbrace, "expected end of metadata node"))
- return true;
-
- return false;
+ return ParseToken(lltok::rbrace, "expected end of metadata node");
}
/// ParseStandaloneMetadata:
Lex.Lex();
unsigned MetadataID = 0;
- LocTy TyLoc;
- Type *Ty = nullptr;
- SmallVector<Value *, 16> Elts;
+ MDNode *Init;
if (ParseUInt32(MetadataID) ||
- ParseToken(lltok::equal, "expected '=' here") ||
- ParseType(Ty, TyLoc) ||
- ParseToken(lltok::exclaim, "Expected '!' here") ||
- ParseToken(lltok::lbrace, "Expected '{' here") ||
- ParseMDNodeVector(Elts, nullptr) ||
- ParseToken(lltok::rbrace, "expected end of metadata node"))
+ ParseToken(lltok::equal, "expected '=' here"))
return true;
- MDNode *Init = MDNode::get(Context, Elts);
+ // Detect common error, from old metadata syntax.
+ if (Lex.getKind() == lltok::Type)
+ return TokError("unexpected type in metadata definition");
+
+ bool IsDistinct = EatIfPresent(lltok::kw_distinct);
+ if (Lex.getKind() == lltok::MetadataVar) {
+ if (ParseSpecializedMDNode(Init, IsDistinct))
+ return true;
+ } else if (ParseToken(lltok::exclaim, "Expected '!' here") ||
+ ParseMDTuple(Init, IsDistinct))
+ return true;
// See if this was forward referenced, if so, handle it.
- std::map<unsigned, std::pair<TrackingVH<MDNode>, LocTy> >::iterator
- FI = ForwardRefMDNodes.find(MetadataID);
+ auto FI = ForwardRefMDNodes.find(MetadataID);
if (FI != ForwardRefMDNodes.end()) {
- MDNode *Temp = FI->second.first;
- Temp->replaceAllUsesWith(Init);
- MDNode::deleteTemporary(Temp);
+ 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] != nullptr)
+ if (NumberedMetadata.count(MetadataID))
return TokError("Metadata id is already used");
- NumberedMetadata[MetadataID] = Init;
+ NumberedMetadata[MetadataID].reset(Init);
}
return false;
/// ParseAlias:
/// ::= GlobalVar '=' OptionalLinkage OptionalVisibility
/// OptionalDLLStorageClass OptionalThreadLocal
-/// OptionalUnNammedAddr 'alias' Aliasee
+/// OptionalUnnamedAddr 'alias' Aliasee
///
/// Aliasee
/// ::= TypeAndValue
///
-/// Everything through OptionalUnNammedAddr has already been parsed.
+/// Everything through OptionalUnnamedAddr has already been parsed.
///
bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc, unsigned L,
unsigned Visibility, unsigned DLLStorageClass,
auto *PTy = dyn_cast<PointerType>(AliaseeType);
if (!PTy)
return Error(AliaseeLoc, "An alias must have pointer type");
- Type *Ty = PTy->getElementType();
- unsigned AddrSpace = PTy->getAddressSpace();
// Okay, create the alias but do not insert it into the module yet.
std::unique_ptr<GlobalAlias> GA(
- GlobalAlias::create(Ty, AddrSpace, (GlobalValue::LinkageTypes)Linkage,
- Name, Aliasee, /*Parent*/ nullptr));
+ GlobalAlias::create(PTy, (GlobalValue::LinkageTypes)Linkage, Name,
+ Aliasee, /*Parent*/ nullptr));
GA->setThreadLocalMode(TLM);
GA->setVisibility((GlobalValue::VisibilityTypes)Visibility);
GA->setDLLStorageClass((GlobalValue::DLLStorageClassTypes)DLLStorageClass);
GA->setUnnamedAddr(UnnamedAddr);
+ if (Name.empty())
+ NumberedVals.push_back(GA.get());
+
// See if this value already exists in the symbol table. If so, it is either
// a redefinition or a definition of a forward reference.
if (GlobalValue *Val = M->getNamedValue(Name)) {
/// ParseGlobal
/// ::= GlobalVar '=' OptionalLinkage OptionalVisibility OptionalDLLStorageClass
-/// OptionalThreadLocal OptionalUnNammedAddr OptionalAddrSpace
+/// OptionalThreadLocal OptionalUnnamedAddr OptionalAddrSpace
/// OptionalExternallyInitialized GlobalType Type Const
/// ::= OptionalLinkage OptionalVisibility OptionalDLLStorageClass
-/// OptionalThreadLocal OptionalUnNammedAddr OptionalAddrSpace
+/// OptionalThreadLocal OptionalUnnamedAddr OptionalAddrSpace
/// OptionalExternallyInitialized GlobalType Type Const
///
-/// Everything up to and including OptionalUnNammedAddr has been parsed
+/// Everything up to and including OptionalUnnamedAddr has been parsed
/// already.
///
bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc,
return true;
}
- if (Ty->isFunctionTy() || Ty->isLabelTy())
+ if (Ty->isFunctionTy() || !PointerType::isValidElementType(Ty))
return Error(TyLoc, "invalid type for global variable");
GlobalValue *GVal = nullptr;
Name, nullptr, GlobalVariable::NotThreadLocal,
AddrSpace);
} else {
- if (GVal->getType()->getElementType() != Ty)
+ if (GVal->getValueType() != Ty)
return Error(TyLoc,
"forward reference and definition of global have different types");
GV->setAlignment(Alignment);
} else {
Comdat *C;
- if (parseOptionalComdat(C))
+ if (parseOptionalComdat(Name, C))
return true;
if (C)
GV->setComdat(C);
LocTy AttrGrpLoc = Lex.getLoc();
Lex.Lex();
- assert(Lex.getKind() == lltok::AttrGrpID);
+ if (Lex.getKind() != lltok::AttrGrpID)
+ return TokError("expected attribute group id");
+
unsigned VarID = Lex.getUIntVal();
std::vector<unsigned> unused;
LocTy BuiltinLoc;
B.addStackAlignmentAttr(Alignment);
continue;
}
- case lltok::kw_alwaysinline: B.addAttribute(Attribute::AlwaysInline); break;
- case lltok::kw_builtin: B.addAttribute(Attribute::Builtin); break;
- case lltok::kw_cold: B.addAttribute(Attribute::Cold); break;
- case lltok::kw_inlinehint: B.addAttribute(Attribute::InlineHint); break;
- case lltok::kw_jumptable: B.addAttribute(Attribute::JumpTable); break;
- case lltok::kw_minsize: B.addAttribute(Attribute::MinSize); break;
- case lltok::kw_naked: B.addAttribute(Attribute::Naked); break;
- case lltok::kw_nobuiltin: B.addAttribute(Attribute::NoBuiltin); break;
- case lltok::kw_noduplicate: B.addAttribute(Attribute::NoDuplicate); break;
- case lltok::kw_noimplicitfloat: B.addAttribute(Attribute::NoImplicitFloat); break;
- case lltok::kw_noinline: B.addAttribute(Attribute::NoInline); break;
- case lltok::kw_nonlazybind: B.addAttribute(Attribute::NonLazyBind); break;
- case lltok::kw_noredzone: B.addAttribute(Attribute::NoRedZone); break;
- case lltok::kw_noreturn: B.addAttribute(Attribute::NoReturn); break;
- case lltok::kw_nounwind: B.addAttribute(Attribute::NoUnwind); break;
- case lltok::kw_optnone: B.addAttribute(Attribute::OptimizeNone); break;
- case lltok::kw_optsize: B.addAttribute(Attribute::OptimizeForSize); break;
- case lltok::kw_readnone: B.addAttribute(Attribute::ReadNone); break;
- case lltok::kw_readonly: B.addAttribute(Attribute::ReadOnly); break;
- case lltok::kw_returns_twice: B.addAttribute(Attribute::ReturnsTwice); break;
- case lltok::kw_ssp: B.addAttribute(Attribute::StackProtect); break;
- case lltok::kw_sspreq: B.addAttribute(Attribute::StackProtectReq); break;
- case lltok::kw_sspstrong: B.addAttribute(Attribute::StackProtectStrong); break;
- case lltok::kw_sanitize_address: B.addAttribute(Attribute::SanitizeAddress); break;
- case lltok::kw_sanitize_thread: B.addAttribute(Attribute::SanitizeThread); break;
- case lltok::kw_sanitize_memory: B.addAttribute(Attribute::SanitizeMemory); break;
- case lltok::kw_uwtable: B.addAttribute(Attribute::UWTable); break;
+ case lltok::kw_alwaysinline: B.addAttribute(Attribute::AlwaysInline); break;
+ case lltok::kw_argmemonly: B.addAttribute(Attribute::ArgMemOnly); break;
+ case lltok::kw_builtin: B.addAttribute(Attribute::Builtin); break;
+ case lltok::kw_cold: B.addAttribute(Attribute::Cold); break;
+ case lltok::kw_convergent: B.addAttribute(Attribute::Convergent); break;
+ case lltok::kw_inlinehint: B.addAttribute(Attribute::InlineHint); break;
+ case lltok::kw_jumptable: B.addAttribute(Attribute::JumpTable); break;
+ case lltok::kw_minsize: B.addAttribute(Attribute::MinSize); break;
+ case lltok::kw_naked: B.addAttribute(Attribute::Naked); break;
+ case lltok::kw_nobuiltin: B.addAttribute(Attribute::NoBuiltin); break;
+ case lltok::kw_noduplicate: B.addAttribute(Attribute::NoDuplicate); break;
+ case lltok::kw_noimplicitfloat:
+ B.addAttribute(Attribute::NoImplicitFloat); break;
+ case lltok::kw_noinline: B.addAttribute(Attribute::NoInline); break;
+ case lltok::kw_nonlazybind: B.addAttribute(Attribute::NonLazyBind); break;
+ case lltok::kw_noredzone: B.addAttribute(Attribute::NoRedZone); break;
+ case lltok::kw_noreturn: B.addAttribute(Attribute::NoReturn); break;
+ case lltok::kw_nounwind: B.addAttribute(Attribute::NoUnwind); break;
+ case lltok::kw_optnone: B.addAttribute(Attribute::OptimizeNone); break;
+ case lltok::kw_optsize: B.addAttribute(Attribute::OptimizeForSize); break;
+ case lltok::kw_readnone: B.addAttribute(Attribute::ReadNone); break;
+ case lltok::kw_readonly: B.addAttribute(Attribute::ReadOnly); break;
+ case lltok::kw_returns_twice:
+ B.addAttribute(Attribute::ReturnsTwice); break;
+ case lltok::kw_ssp: B.addAttribute(Attribute::StackProtect); break;
+ case lltok::kw_sspreq: B.addAttribute(Attribute::StackProtectReq); break;
+ case lltok::kw_sspstrong:
+ B.addAttribute(Attribute::StackProtectStrong); break;
+ case lltok::kw_safestack: B.addAttribute(Attribute::SafeStack); break;
+ case lltok::kw_sanitize_address:
+ B.addAttribute(Attribute::SanitizeAddress); break;
+ case lltok::kw_sanitize_thread:
+ B.addAttribute(Attribute::SanitizeThread); break;
+ case lltok::kw_sanitize_memory:
+ B.addAttribute(Attribute::SanitizeMemory); break;
+ case lltok::kw_uwtable: B.addAttribute(Attribute::UWTable); break;
// Error handling.
case lltok::kw_inreg:
break;
case lltok::kw_byval:
case lltok::kw_dereferenceable:
+ case lltok::kw_dereferenceable_or_null:
case lltok::kw_inalloca:
case lltok::kw_nest:
case lltok::kw_noalias:
case lltok::kw_byval: B.addAttribute(Attribute::ByVal); break;
case lltok::kw_dereferenceable: {
uint64_t Bytes;
- if (ParseOptionalDereferenceableBytes(Bytes))
+ if (ParseOptionalDerefAttrBytes(lltok::kw_dereferenceable, Bytes))
return true;
B.addDereferenceableAttr(Bytes);
continue;
}
+ case lltok::kw_dereferenceable_or_null: {
+ uint64_t Bytes;
+ if (ParseOptionalDerefAttrBytes(lltok::kw_dereferenceable_or_null, Bytes))
+ return true;
+ B.addDereferenceableOrNullAttr(Bytes);
+ continue;
+ }
case lltok::kw_inalloca: B.addAttribute(Attribute::InAlloca); break;
case lltok::kw_inreg: B.addAttribute(Attribute::InReg); break;
case lltok::kw_nest: B.addAttribute(Attribute::Nest); break;
case lltok::kw_alignstack:
case lltok::kw_alwaysinline:
+ case lltok::kw_argmemonly:
case lltok::kw_builtin:
case lltok::kw_inlinehint:
case lltok::kw_jumptable:
case lltok::kw_ssp:
case lltok::kw_sspreq:
case lltok::kw_sspstrong:
+ case lltok::kw_safestack:
case lltok::kw_uwtable:
HaveError |= Error(Lex.getLoc(), "invalid use of function-only attribute");
break;
return HaveError;
case lltok::kw_dereferenceable: {
uint64_t Bytes;
- if (ParseOptionalDereferenceableBytes(Bytes))
+ if (ParseOptionalDerefAttrBytes(lltok::kw_dereferenceable, Bytes))
return true;
B.addDereferenceableAttr(Bytes);
continue;
}
+ case lltok::kw_dereferenceable_or_null: {
+ uint64_t Bytes;
+ if (ParseOptionalDerefAttrBytes(lltok::kw_dereferenceable_or_null, Bytes))
+ return true;
+ B.addDereferenceableOrNullAttr(Bytes);
+ continue;
+ }
case lltok::kw_inreg: B.addAttribute(Attribute::InReg); break;
case lltok::kw_noalias: B.addAttribute(Attribute::NoAlias); break;
case lltok::kw_nonnull: B.addAttribute(Attribute::NonNull); break;
case lltok::kw_alignstack:
case lltok::kw_alwaysinline:
+ case lltok::kw_argmemonly:
case lltok::kw_builtin:
case lltok::kw_cold:
case lltok::kw_inlinehint:
case lltok::kw_ssp:
case lltok::kw_sspreq:
case lltok::kw_sspstrong:
+ case lltok::kw_safestack:
case lltok::kw_uwtable:
HaveError |= Error(Lex.getLoc(), "invalid use of function-only attribute");
break;
return false;
}
+/// ParseMetadataAttachment
+/// ::= !dbg !42
+bool LLParser::ParseMetadataAttachment(unsigned &Kind, MDNode *&MD) {
+ assert(Lex.getKind() == lltok::MetadataVar && "Expected metadata attachment");
+
+ std::string Name = Lex.getStrVal();
+ Kind = M->getMDKindID(Name);
+ Lex.Lex();
+
+ return ParseMDNode(MD);
+}
+
/// ParseInstructionMetadata
/// ::= !dbg !42 (',' !dbg !57)*
-bool LLParser::ParseInstructionMetadata(Instruction *Inst,
- PerFunctionState *PFS) {
+bool LLParser::ParseInstructionMetadata(Instruction &Inst) {
do {
if (Lex.getKind() != lltok::MetadataVar)
return TokError("expected metadata after comma");
- std::string Name = Lex.getStrVal();
- unsigned MDK = M->getMDKindID(Name);
- Lex.Lex();
-
- MDNode *Node;
- SMLoc Loc = Lex.getLoc();
-
- if (ParseToken(lltok::exclaim, "expected '!' here"))
+ unsigned MDK;
+ MDNode *N;
+ if (ParseMetadataAttachment(MDK, N))
return true;
- // This code is similar to that of ParseMetadataValue, however it needs to
- // have special-case code for a forward reference; see the comments on
- // ForwardRefInstMetadata for details. Also, MDStrings are not supported
- // at the top level here.
- if (Lex.getKind() == lltok::lbrace) {
- ValID ID;
- if (ParseMetadataListValue(ID, PFS))
- return true;
- assert(ID.Kind == ValID::t_MDNode);
- if (ID.MDNodeVal->isFunctionLocal())
- return Error(Loc, "unexpected function-local metadata");
- Inst->setMetadata(MDK, ID.MDNodeVal);
- } else {
- unsigned NodeID = 0;
- if (ParseMDNodeID(Node, NodeID))
- return true;
- 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);
- }
- }
-
+ Inst.setMetadata(MDK, N);
if (MDK == LLVMContext::MD_tbaa)
- InstsWithTBAATag.push_back(Inst);
+ InstsWithTBAATag.push_back(&Inst);
// If this is the end of the list, we're done.
} while (EatIfPresent(lltok::comma));
return false;
}
+/// ParseOptionalFunctionMetadata
+/// ::= (!dbg !57)*
+bool LLParser::ParseOptionalFunctionMetadata(Function &F) {
+ while (Lex.getKind() == lltok::MetadataVar) {
+ unsigned MDK;
+ MDNode *N;
+ if (ParseMetadataAttachment(MDK, N))
+ return true;
+
+ F.setMetadata(MDK, N);
+ }
+ return false;
+}
+
/// ParseOptionalAlignment
/// ::= /* empty */
/// ::= 'align' 4
return false;
}
-/// ParseOptionalDereferenceableBytes
+/// ParseOptionalDerefAttrBytes
/// ::= /* empty */
-/// ::= 'dereferenceable' '(' 4 ')'
-bool LLParser::ParseOptionalDereferenceableBytes(uint64_t &Bytes) {
+/// ::= AttrKind '(' 4 ')'
+///
+/// where AttrKind is either 'dereferenceable' or 'dereferenceable_or_null'.
+bool LLParser::ParseOptionalDerefAttrBytes(lltok::Kind AttrKind,
+ uint64_t &Bytes) {
+ assert((AttrKind == lltok::kw_dereferenceable ||
+ AttrKind == lltok::kw_dereferenceable_or_null) &&
+ "contract!");
+
Bytes = 0;
- if (!EatIfPresent(lltok::kw_dereferenceable))
+ if (!EatIfPresent(AttrKind))
return false;
LocTy ParenLoc = Lex.getLoc();
if (!EatIfPresent(lltok::lparen))
while (EatIfPresent(lltok::comma)) {
if (Lex.getKind() == lltok::MetadataVar) {
+ if (Indices.empty()) return TokError("expected index");
AteExtraComma = true;
return false;
}
//===----------------------------------------------------------------------===//
/// ParseType - Parse a type.
-bool LLParser::ParseType(Type *&Result, bool AllowVoid) {
+bool LLParser::ParseType(Type *&Result, const Twine &Msg, bool AllowVoid) {
SMLoc TypeLoc = Lex.getLoc();
switch (Lex.getKind()) {
default:
- return TokError("expected type");
+ return TokError(Msg);
case lltok::Type:
// Type ::= 'float' | 'void' (etc)
Result = Lex.getTyVal();
case lltok::LocalVarID: {
// Type ::= %4
- if (Lex.getUIntVal() >= NumberedTypes.size())
- NumberedTypes.resize(Lex.getUIntVal()+1);
std::pair<Type*, LocTy> &Entry = NumberedTypes[Lex.getUIntVal()];
// If the type hasn't been defined yet, create a forward definition and
if (ParseType(ArgTy, ArgLoc))
return true;
- // Otherwise, handle normal operands.
- if (ParseOptionalParamAttrs(ArgAttrs) || ParseValue(ArgTy, V, PFS))
- return true;
+ if (ArgTy->isMetadataTy()) {
+ if (ParseMetadataAsValue(V, PFS))
+ return true;
+ } else {
+ // Otherwise, handle normal operands.
+ if (ParseOptionalParamAttrs(ArgAttrs) || ParseValue(ArgTy, V, PFS))
+ return true;
+ }
ArgList.push_back(ParamInfo(ArgLoc, V, AttributeSet::get(V->getContext(),
AttrIndex++,
ArgAttrs)));
return Error(TypeLoc, "invalid type for function argument");
unsigned AttrIndex = 1;
- ArgList.push_back(ArgInfo(TypeLoc, ArgTy,
- AttributeSet::get(ArgTy->getContext(),
- AttrIndex++, Attrs), Name));
+ ArgList.emplace_back(TypeLoc, ArgTy, AttributeSet::get(ArgTy->getContext(),
+ AttrIndex++, Attrs),
+ std::move(Name));
while (EatIfPresent(lltok::comma)) {
// Handle ... at end of arg list.
if (!ArgTy->isFirstClassType())
return Error(TypeLoc, "invalid type for function argument");
- ArgList.push_back(ArgInfo(TypeLoc, ArgTy,
- AttributeSet::get(ArgTy->getContext(),
- AttrIndex++, Attrs),
- Name));
+ ArgList.emplace_back(
+ TypeLoc, ArgTy,
+ AttributeSet::get(ArgTy->getContext(), AttrIndex++, Attrs),
+ std::move(Name));
}
}
/// forward reference record if needed.
BasicBlock *LLParser::PerFunctionState::GetBB(const std::string &Name,
LocTy Loc) {
- return cast_or_null<BasicBlock>(GetVal(Name,
- Type::getLabelTy(F.getContext()), Loc));
+ return dyn_cast_or_null<BasicBlock>(GetVal(Name,
+ Type::getLabelTy(F.getContext()), Loc));
}
BasicBlock *LLParser::PerFunctionState::GetBB(unsigned ID, LocTy Loc) {
- return cast_or_null<BasicBlock>(GetVal(ID,
- Type::getLabelTy(F.getContext()), Loc));
+ return dyn_cast_or_null<BasicBlock>(GetVal(ID,
+ Type::getLabelTy(F.getContext()), Loc));
}
/// DefineBB - Define the specified basic block, which is either named or
ID.StrVal = Lex.getStrVal();
ID.Kind = ValID::t_LocalName;
break;
- case lltok::exclaim: // !42, !{...}, or !"foo"
- return ParseMetadataValue(ID, PFS);
case lltok::APSInt:
ID.APSIntVal = Lex.getAPSIntVal();
ID.Kind = ValID::t_APSInt;
ParseToken(lltok::rbrace, "expected end of struct constant"))
return true;
- ID.ConstantStructElts = new Constant*[Elts.size()];
+ ID.ConstantStructElts = make_unique<Constant *[]>(Elts.size());
ID.UIntVal = Elts.size();
- memcpy(ID.ConstantStructElts, Elts.data(), Elts.size()*sizeof(Elts[0]));
+ memcpy(ID.ConstantStructElts.get(), Elts.data(),
+ Elts.size() * sizeof(Elts[0]));
ID.Kind = ValID::t_ConstantStruct;
return false;
}
return true;
if (isPackedStruct) {
- ID.ConstantStructElts = new Constant*[Elts.size()];
- memcpy(ID.ConstantStructElts, Elts.data(), Elts.size()*sizeof(Elts[0]));
+ ID.ConstantStructElts = make_unique<Constant *[]>(Elts.size());
+ memcpy(ID.ConstantStructElts.get(), Elts.data(),
+ Elts.size() * sizeof(Elts[0]));
ID.UIntVal = Elts.size();
ID.Kind = ValID::t_PackedConstantStruct;
return false;
if (!F) {
// Make a global variable as a placeholder for this reference.
- GlobalValue *&FwdRef = ForwardRefBlockAddresses[Fn][Label];
+ GlobalValue *&FwdRef =
+ ForwardRefBlockAddresses.insert(std::make_pair(
+ std::move(Fn),
+ std::map<ValID, GlobalValue *>()))
+ .first->second.insert(std::make_pair(std::move(Label), nullptr))
+ .first->second;
if (!FwdRef)
FwdRef = new GlobalVariable(*M, Type::getInt8Ty(Context), false,
GlobalValue::InternalLinkage, nullptr, "");
return true;
if (!Val0->getType()->isAggregateType())
return Error(ID.Loc, "insertvalue operand must be aggregate type");
- if (!ExtractValueInst::getIndexedType(Val0->getType(), Indices))
+ Type *IndexedType =
+ ExtractValueInst::getIndexedType(Val0->getType(), Indices);
+ if (!IndexedType)
return Error(ID.Loc, "invalid indices for insertvalue");
+ if (IndexedType != Val1->getType())
+ return Error(ID.Loc, "insertvalue operand and field disagree in type: '" +
+ getTypeString(Val1->getType()) +
+ "' instead of '" + getTypeString(IndexedType) +
+ "'");
ID.ConstantVal = ConstantExpr::getInsertValue(Val0, Val1, Indices);
ID.Kind = ValID::t_Constant;
return false;
unsigned Opc = Lex.getUIntVal();
SmallVector<Constant*, 16> Elts;
bool InBounds = false;
+ Type *Ty;
Lex.Lex();
+
if (Opc == Instruction::GetElementPtr)
InBounds = EatIfPresent(lltok::kw_inbounds);
- if (ParseToken(lltok::lparen, "expected '(' in constantexpr") ||
- ParseGlobalValueVector(Elts) ||
+
+ if (ParseToken(lltok::lparen, "expected '(' in constantexpr"))
+ return true;
+
+ LocTy ExplicitTypeLoc = Lex.getLoc();
+ if (Opc == Instruction::GetElementPtr) {
+ if (ParseType(Ty) ||
+ ParseToken(lltok::comma, "expected comma after getelementptr's type"))
+ return true;
+ }
+
+ if (ParseGlobalValueVector(Elts) ||
ParseToken(lltok::rparen, "expected ')' in constantexpr"))
return true;
if (Opc == Instruction::GetElementPtr) {
if (Elts.size() == 0 ||
!Elts[0]->getType()->getScalarType()->isPointerTy())
- return Error(ID.Loc, "getelementptr requires pointer operand");
+ return Error(ID.Loc, "base of getelementptr must be a pointer");
+
+ Type *BaseType = Elts[0]->getType();
+ auto *BasePointerType = cast<PointerType>(BaseType->getScalarType());
+ if (Ty != BasePointerType->getElementType())
+ return Error(
+ ExplicitTypeLoc,
+ "explicit pointee type doesn't match operand's pointee type");
ArrayRef<Constant *> Indices(Elts.begin() + 1, Elts.end());
- if (!GetElementPtrInst::getIndexedType(Elts[0]->getType(), Indices))
- return Error(ID.Loc, "invalid indices for getelementptr");
- ID.ConstantVal = ConstantExpr::getGetElementPtr(Elts[0], Indices,
- InBounds);
+ for (Constant *Val : Indices) {
+ Type *ValTy = Val->getType();
+ if (!ValTy->getScalarType()->isIntegerTy())
+ return Error(ID.Loc, "getelementptr index must be an integer");
+ if (ValTy->isVectorTy() != BaseType->isVectorTy())
+ return Error(ID.Loc, "getelementptr index type missmatch");
+ if (ValTy->isVectorTy()) {
+ unsigned ValNumEl = ValTy->getVectorNumElements();
+ unsigned PtrNumEl = BaseType->getVectorNumElements();
+ if (ValNumEl != PtrNumEl)
+ return Error(
+ ID.Loc,
+ "getelementptr vector index has a wrong number of elements");
+ }
+ }
+
+ SmallPtrSet<const Type*, 4> Visited;
+ if (!Indices.empty() && !Ty->isSized(&Visited))
+ return Error(ID.Loc, "base element of getelementptr must be sized");
+
+ if (!GetElementPtrInst::getIndexedType(Ty, Indices))
+ return Error(ID.Loc, "invalid getelementptr indices");
+ ID.ConstantVal =
+ ConstantExpr::getGetElementPtr(Ty, Elts[0], Indices, InBounds);
} else if (Opc == Instruction::Select) {
if (Elts.size() != 3)
return Error(ID.Loc, "expected three operands to select");
ParseGlobalValue(Ty, V);
}
-bool LLParser::parseOptionalComdat(Comdat *&C) {
+bool LLParser::parseOptionalComdat(StringRef GlobalName, Comdat *&C) {
C = nullptr;
+
+ LocTy KwLoc = Lex.getLoc();
if (!EatIfPresent(lltok::kw_comdat))
return false;
- if (Lex.getKind() != lltok::ComdatVar)
- return TokError("expected comdat variable");
- LocTy Loc = Lex.getLoc();
- StringRef Name = Lex.getStrVal();
- C = getComdat(Name, Loc);
- Lex.Lex();
+
+ if (EatIfPresent(lltok::lparen)) {
+ if (Lex.getKind() != lltok::ComdatVar)
+ return TokError("expected comdat variable");
+ C = getComdat(Lex.getStrVal(), Lex.getLoc());
+ Lex.Lex();
+ if (ParseToken(lltok::rparen, "expected ')' after comdat var"))
+ return true;
+ } else {
+ if (GlobalName.empty())
+ return TokError("comdat cannot be unnamed");
+ C = getComdat(GlobalName, KwLoc);
+ }
+
return false;
}
return false;
}
-bool LLParser::ParseMetadataListValue(ValID &ID, PerFunctionState *PFS) {
- assert(Lex.getKind() == lltok::lbrace);
- Lex.Lex();
-
- SmallVector<Value*, 16> Elts;
- if (ParseMDNodeVector(Elts, PFS) ||
- ParseToken(lltok::rbrace, "expected end of metadata node"))
+bool LLParser::ParseMDTuple(MDNode *&MD, bool IsDistinct) {
+ SmallVector<Metadata *, 16> Elts;
+ if (ParseMDNodeVector(Elts))
return true;
- ID.MDNodeVal = MDNode::get(Context, Elts);
- ID.Kind = ValID::t_MDNode;
+ MD = (IsDistinct ? MDTuple::getDistinct : MDTuple::get)(Context, Elts);
return false;
}
-/// ParseMetadataValue
-/// ::= !42
-/// ::= !{...}
-/// ::= !"string"
-bool LLParser::ParseMetadataValue(ValID &ID, PerFunctionState *PFS) {
- assert(Lex.getKind() == lltok::exclaim);
- Lex.Lex();
+/// MDNode:
+/// ::= !{ ... }
+/// ::= !7
+/// ::= !DILocation(...)
+bool LLParser::ParseMDNode(MDNode *&N) {
+ if (Lex.getKind() == lltok::MetadataVar)
+ return ParseSpecializedMDNode(N);
- // MDNode:
+ return ParseToken(lltok::exclaim, "expected '!' here") ||
+ ParseMDNodeTail(N);
+}
+
+bool LLParser::ParseMDNodeTail(MDNode *&N) {
// !{ ... }
if (Lex.getKind() == lltok::lbrace)
- return ParseMetadataListValue(ID, PFS);
+ return ParseMDTuple(N);
- // Standalone metadata reference
// !42
- if (Lex.getKind() == lltok::APSInt) {
- if (ParseMDNodeID(ID.MDNodeVal)) return true;
- ID.Kind = ValID::t_MDNode;
+ return ParseMDNodeID(N);
+}
+
+namespace {
+
+/// Structure to represent an optional metadata field.
+template <class FieldTy> struct MDFieldImpl {
+ typedef MDFieldImpl ImplTy;
+ FieldTy Val;
+ bool Seen;
+
+ void assign(FieldTy Val) {
+ Seen = true;
+ this->Val = std::move(Val);
+ }
+
+ explicit MDFieldImpl(FieldTy Default)
+ : Val(std::move(Default)), Seen(false) {}
+};
+
+struct MDUnsignedField : public MDFieldImpl<uint64_t> {
+ uint64_t Max;
+
+ MDUnsignedField(uint64_t Default = 0, uint64_t Max = UINT64_MAX)
+ : ImplTy(Default), Max(Max) {}
+};
+struct LineField : public MDUnsignedField {
+ LineField() : MDUnsignedField(0, UINT32_MAX) {}
+};
+struct ColumnField : public MDUnsignedField {
+ ColumnField() : MDUnsignedField(0, UINT16_MAX) {}
+};
+struct DwarfTagField : public MDUnsignedField {
+ DwarfTagField() : MDUnsignedField(0, dwarf::DW_TAG_hi_user) {}
+ DwarfTagField(dwarf::Tag DefaultTag)
+ : MDUnsignedField(DefaultTag, dwarf::DW_TAG_hi_user) {}
+};
+struct DwarfAttEncodingField : public MDUnsignedField {
+ DwarfAttEncodingField() : MDUnsignedField(0, dwarf::DW_ATE_hi_user) {}
+};
+struct DwarfVirtualityField : public MDUnsignedField {
+ DwarfVirtualityField() : MDUnsignedField(0, dwarf::DW_VIRTUALITY_max) {}
+};
+struct DwarfLangField : public MDUnsignedField {
+ DwarfLangField() : MDUnsignedField(0, dwarf::DW_LANG_hi_user) {}
+};
+
+struct DIFlagField : public MDUnsignedField {
+ DIFlagField() : MDUnsignedField(0, UINT32_MAX) {}
+};
+
+struct MDSignedField : public MDFieldImpl<int64_t> {
+ int64_t Min;
+ int64_t Max;
+
+ MDSignedField(int64_t Default = 0)
+ : ImplTy(Default), Min(INT64_MIN), Max(INT64_MAX) {}
+ MDSignedField(int64_t Default, int64_t Min, int64_t Max)
+ : ImplTy(Default), Min(Min), Max(Max) {}
+};
+
+struct MDBoolField : public MDFieldImpl<bool> {
+ MDBoolField(bool Default = false) : ImplTy(Default) {}
+};
+struct MDField : public MDFieldImpl<Metadata *> {
+ bool AllowNull;
+
+ MDField(bool AllowNull = true) : ImplTy(nullptr), AllowNull(AllowNull) {}
+};
+struct MDConstant : public MDFieldImpl<ConstantAsMetadata *> {
+ MDConstant() : ImplTy(nullptr) {}
+};
+struct MDStringField : public MDFieldImpl<MDString *> {
+ bool AllowEmpty;
+ MDStringField(bool AllowEmpty = true)
+ : ImplTy(nullptr), AllowEmpty(AllowEmpty) {}
+};
+struct MDFieldList : public MDFieldImpl<SmallVector<Metadata *, 4>> {
+ MDFieldList() : ImplTy(SmallVector<Metadata *, 4>()) {}
+};
+
+} // end namespace
+
+namespace llvm {
+
+template <>
+bool LLParser::ParseMDField(LocTy Loc, StringRef Name,
+ MDUnsignedField &Result) {
+ if (Lex.getKind() != lltok::APSInt || Lex.getAPSIntVal().isSigned())
+ return TokError("expected unsigned integer");
+
+ auto &U = Lex.getAPSIntVal();
+ if (U.ugt(Result.Max))
+ return TokError("value for '" + Name + "' too large, limit is " +
+ Twine(Result.Max));
+ Result.assign(U.getZExtValue());
+ assert(Result.Val <= Result.Max && "Expected value in range");
+ Lex.Lex();
+ return false;
+}
+
+template <>
+bool LLParser::ParseMDField(LocTy Loc, StringRef Name, LineField &Result) {
+ return ParseMDField(Loc, Name, static_cast<MDUnsignedField &>(Result));
+}
+template <>
+bool LLParser::ParseMDField(LocTy Loc, StringRef Name, ColumnField &Result) {
+ return ParseMDField(Loc, Name, static_cast<MDUnsignedField &>(Result));
+}
+
+template <>
+bool LLParser::ParseMDField(LocTy Loc, StringRef Name, DwarfTagField &Result) {
+ if (Lex.getKind() == lltok::APSInt)
+ return ParseMDField(Loc, Name, static_cast<MDUnsignedField &>(Result));
+
+ if (Lex.getKind() != lltok::DwarfTag)
+ return TokError("expected DWARF tag");
+
+ unsigned Tag = dwarf::getTag(Lex.getStrVal());
+ if (Tag == dwarf::DW_TAG_invalid)
+ return TokError("invalid DWARF tag" + Twine(" '") + Lex.getStrVal() + "'");
+ assert(Tag <= Result.Max && "Expected valid DWARF tag");
+
+ Result.assign(Tag);
+ Lex.Lex();
+ return false;
+}
+
+template <>
+bool LLParser::ParseMDField(LocTy Loc, StringRef Name,
+ DwarfVirtualityField &Result) {
+ if (Lex.getKind() == lltok::APSInt)
+ return ParseMDField(Loc, Name, static_cast<MDUnsignedField &>(Result));
+
+ if (Lex.getKind() != lltok::DwarfVirtuality)
+ return TokError("expected DWARF virtuality code");
+
+ unsigned Virtuality = dwarf::getVirtuality(Lex.getStrVal());
+ if (!Virtuality)
+ return TokError("invalid DWARF virtuality code" + Twine(" '") +
+ Lex.getStrVal() + "'");
+ assert(Virtuality <= Result.Max && "Expected valid DWARF virtuality code");
+ Result.assign(Virtuality);
+ Lex.Lex();
+ return false;
+}
+
+template <>
+bool LLParser::ParseMDField(LocTy Loc, StringRef Name, DwarfLangField &Result) {
+ if (Lex.getKind() == lltok::APSInt)
+ return ParseMDField(Loc, Name, static_cast<MDUnsignedField &>(Result));
+
+ if (Lex.getKind() != lltok::DwarfLang)
+ return TokError("expected DWARF language");
+
+ unsigned Lang = dwarf::getLanguage(Lex.getStrVal());
+ if (!Lang)
+ return TokError("invalid DWARF language" + Twine(" '") + Lex.getStrVal() +
+ "'");
+ assert(Lang <= Result.Max && "Expected valid DWARF language");
+ Result.assign(Lang);
+ Lex.Lex();
+ return false;
+}
+
+template <>
+bool LLParser::ParseMDField(LocTy Loc, StringRef Name,
+ DwarfAttEncodingField &Result) {
+ if (Lex.getKind() == lltok::APSInt)
+ return ParseMDField(Loc, Name, static_cast<MDUnsignedField &>(Result));
+
+ if (Lex.getKind() != lltok::DwarfAttEncoding)
+ return TokError("expected DWARF type attribute encoding");
+
+ unsigned Encoding = dwarf::getAttributeEncoding(Lex.getStrVal());
+ if (!Encoding)
+ return TokError("invalid DWARF type attribute encoding" + Twine(" '") +
+ Lex.getStrVal() + "'");
+ assert(Encoding <= Result.Max && "Expected valid DWARF language");
+ Result.assign(Encoding);
+ Lex.Lex();
+ return false;
+}
+
+/// DIFlagField
+/// ::= uint32
+/// ::= DIFlagVector
+/// ::= DIFlagVector '|' DIFlagFwdDecl '|' uint32 '|' DIFlagPublic
+template <>
+bool LLParser::ParseMDField(LocTy Loc, StringRef Name, DIFlagField &Result) {
+ assert(Result.Max == UINT32_MAX && "Expected only 32-bits");
+
+ // Parser for a single flag.
+ auto parseFlag = [&](unsigned &Val) {
+ if (Lex.getKind() == lltok::APSInt && !Lex.getAPSIntVal().isSigned())
+ return ParseUInt32(Val);
+
+ if (Lex.getKind() != lltok::DIFlag)
+ return TokError("expected debug info flag");
+
+ Val = DINode::getFlag(Lex.getStrVal());
+ if (!Val)
+ return TokError(Twine("invalid debug info flag flag '") +
+ Lex.getStrVal() + "'");
+ Lex.Lex();
+ return false;
+ };
+
+ // Parse the flags and combine them together.
+ unsigned Combined = 0;
+ do {
+ unsigned Val;
+ if (parseFlag(Val))
+ return true;
+ Combined |= Val;
+ } while (EatIfPresent(lltok::bar));
+
+ Result.assign(Combined);
+ return false;
+}
+
+template <>
+bool LLParser::ParseMDField(LocTy Loc, StringRef Name,
+ MDSignedField &Result) {
+ if (Lex.getKind() != lltok::APSInt)
+ return TokError("expected signed integer");
+
+ auto &S = Lex.getAPSIntVal();
+ if (S < Result.Min)
+ return TokError("value for '" + Name + "' too small, limit is " +
+ Twine(Result.Min));
+ if (S > Result.Max)
+ return TokError("value for '" + Name + "' too large, limit is " +
+ Twine(Result.Max));
+ Result.assign(S.getExtValue());
+ assert(Result.Val >= Result.Min && "Expected value in range");
+ assert(Result.Val <= Result.Max && "Expected value in range");
+ Lex.Lex();
+ return false;
+}
+
+template <>
+bool LLParser::ParseMDField(LocTy Loc, StringRef Name, MDBoolField &Result) {
+ switch (Lex.getKind()) {
+ default:
+ return TokError("expected 'true' or 'false'");
+ case lltok::kw_true:
+ Result.assign(true);
+ break;
+ case lltok::kw_false:
+ Result.assign(false);
+ break;
+ }
+ Lex.Lex();
+ return false;
+}
+
+template <>
+bool LLParser::ParseMDField(LocTy Loc, StringRef Name, MDField &Result) {
+ if (Lex.getKind() == lltok::kw_null) {
+ if (!Result.AllowNull)
+ return TokError("'" + Name + "' cannot be null");
+ Lex.Lex();
+ Result.assign(nullptr);
+ return false;
+ }
+
+ Metadata *MD;
+ if (ParseMetadata(MD, nullptr))
+ return true;
+
+ Result.assign(MD);
+ return false;
+}
+
+template <>
+bool LLParser::ParseMDField(LocTy Loc, StringRef Name, MDConstant &Result) {
+ Metadata *MD;
+ if (ParseValueAsMetadata(MD, "expected constant", nullptr))
+ return true;
+
+ Result.assign(cast<ConstantAsMetadata>(MD));
+ return false;
+}
+
+template <>
+bool LLParser::ParseMDField(LocTy Loc, StringRef Name, MDStringField &Result) {
+ LocTy ValueLoc = Lex.getLoc();
+ std::string S;
+ if (ParseStringConstant(S))
+ return true;
+
+ if (!Result.AllowEmpty && S.empty())
+ return Error(ValueLoc, "'" + Name + "' cannot be empty");
+
+ Result.assign(S.empty() ? nullptr : MDString::get(Context, S));
+ return false;
+}
+
+template <>
+bool LLParser::ParseMDField(LocTy Loc, StringRef Name, MDFieldList &Result) {
+ SmallVector<Metadata *, 4> MDs;
+ if (ParseMDNodeVector(MDs))
+ return true;
+
+ Result.assign(std::move(MDs));
+ return false;
+}
+
+} // end namespace llvm
+
+template <class ParserTy>
+bool LLParser::ParseMDFieldsImplBody(ParserTy parseField) {
+ do {
+ if (Lex.getKind() != lltok::LabelStr)
+ return TokError("expected field label here");
+
+ if (parseField())
+ return true;
+ } while (EatIfPresent(lltok::comma));
+
+ return false;
+}
+
+template <class ParserTy>
+bool LLParser::ParseMDFieldsImpl(ParserTy parseField, LocTy &ClosingLoc) {
+ assert(Lex.getKind() == lltok::MetadataVar && "Expected metadata type name");
+ Lex.Lex();
+
+ if (ParseToken(lltok::lparen, "expected '(' here"))
+ return true;
+ if (Lex.getKind() != lltok::rparen)
+ if (ParseMDFieldsImplBody(parseField))
+ return true;
+
+ ClosingLoc = Lex.getLoc();
+ return ParseToken(lltok::rparen, "expected ')' here");
+}
+
+template <class FieldTy>
+bool LLParser::ParseMDField(StringRef Name, FieldTy &Result) {
+ if (Result.Seen)
+ return TokError("field '" + Name + "' cannot be specified more than once");
+
+ LocTy Loc = Lex.getLoc();
+ Lex.Lex();
+ return ParseMDField(Loc, Name, Result);
+}
+
+bool LLParser::ParseSpecializedMDNode(MDNode *&N, bool IsDistinct) {
+ assert(Lex.getKind() == lltok::MetadataVar && "Expected metadata type name");
+
+#define HANDLE_SPECIALIZED_MDNODE_LEAF(CLASS) \
+ if (Lex.getStrVal() == #CLASS) \
+ return Parse##CLASS(N, IsDistinct);
+#include "llvm/IR/Metadata.def"
+
+ return TokError("expected metadata type");
+}
+
+#define DECLARE_FIELD(NAME, TYPE, INIT) TYPE NAME INIT
+#define NOP_FIELD(NAME, TYPE, INIT)
+#define REQUIRE_FIELD(NAME, TYPE, INIT) \
+ if (!NAME.Seen) \
+ return Error(ClosingLoc, "missing required field '" #NAME "'");
+#define PARSE_MD_FIELD(NAME, TYPE, DEFAULT) \
+ if (Lex.getStrVal() == #NAME) \
+ return ParseMDField(#NAME, NAME);
+#define PARSE_MD_FIELDS() \
+ VISIT_MD_FIELDS(DECLARE_FIELD, DECLARE_FIELD) \
+ do { \
+ LocTy ClosingLoc; \
+ if (ParseMDFieldsImpl([&]() -> bool { \
+ VISIT_MD_FIELDS(PARSE_MD_FIELD, PARSE_MD_FIELD) \
+ return TokError(Twine("invalid field '") + Lex.getStrVal() + "'"); \
+ }, ClosingLoc)) \
+ return true; \
+ VISIT_MD_FIELDS(NOP_FIELD, REQUIRE_FIELD) \
+ } while (false)
+#define GET_OR_DISTINCT(CLASS, ARGS) \
+ (IsDistinct ? CLASS::getDistinct ARGS : CLASS::get ARGS)
+
+/// ParseDILocationFields:
+/// ::= !DILocation(line: 43, column: 8, scope: !5, inlinedAt: !6)
+bool LLParser::ParseDILocation(MDNode *&Result, bool IsDistinct) {
+#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
+ OPTIONAL(line, LineField, ); \
+ OPTIONAL(column, ColumnField, ); \
+ REQUIRED(scope, MDField, (/* AllowNull */ false)); \
+ OPTIONAL(inlinedAt, MDField, );
+ PARSE_MD_FIELDS();
+#undef VISIT_MD_FIELDS
+
+ Result = GET_OR_DISTINCT(
+ DILocation, (Context, line.Val, column.Val, scope.Val, inlinedAt.Val));
+ return false;
+}
+
+/// ParseGenericDINode:
+/// ::= !GenericDINode(tag: 15, header: "...", operands: {...})
+bool LLParser::ParseGenericDINode(MDNode *&Result, bool IsDistinct) {
+#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
+ REQUIRED(tag, DwarfTagField, ); \
+ OPTIONAL(header, MDStringField, ); \
+ OPTIONAL(operands, MDFieldList, );
+ PARSE_MD_FIELDS();
+#undef VISIT_MD_FIELDS
+
+ Result = GET_OR_DISTINCT(GenericDINode,
+ (Context, tag.Val, header.Val, operands.Val));
+ return false;
+}
+
+/// ParseDISubrange:
+/// ::= !DISubrange(count: 30, lowerBound: 2)
+bool LLParser::ParseDISubrange(MDNode *&Result, bool IsDistinct) {
+#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
+ REQUIRED(count, MDSignedField, (-1, -1, INT64_MAX)); \
+ OPTIONAL(lowerBound, MDSignedField, );
+ PARSE_MD_FIELDS();
+#undef VISIT_MD_FIELDS
+
+ Result = GET_OR_DISTINCT(DISubrange, (Context, count.Val, lowerBound.Val));
+ return false;
+}
+
+/// ParseDIEnumerator:
+/// ::= !DIEnumerator(value: 30, name: "SomeKind")
+bool LLParser::ParseDIEnumerator(MDNode *&Result, bool IsDistinct) {
+#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
+ REQUIRED(name, MDStringField, ); \
+ REQUIRED(value, MDSignedField, );
+ PARSE_MD_FIELDS();
+#undef VISIT_MD_FIELDS
+
+ Result = GET_OR_DISTINCT(DIEnumerator, (Context, value.Val, name.Val));
+ return false;
+}
+
+/// ParseDIBasicType:
+/// ::= !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32)
+bool LLParser::ParseDIBasicType(MDNode *&Result, bool IsDistinct) {
+#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
+ OPTIONAL(tag, DwarfTagField, (dwarf::DW_TAG_base_type)); \
+ OPTIONAL(name, MDStringField, ); \
+ OPTIONAL(size, MDUnsignedField, (0, UINT64_MAX)); \
+ OPTIONAL(align, MDUnsignedField, (0, UINT64_MAX)); \
+ OPTIONAL(encoding, DwarfAttEncodingField, );
+ PARSE_MD_FIELDS();
+#undef VISIT_MD_FIELDS
+
+ Result = GET_OR_DISTINCT(DIBasicType, (Context, tag.Val, name.Val, size.Val,
+ align.Val, encoding.Val));
+ return false;
+}
+
+/// ParseDIDerivedType:
+/// ::= !DIDerivedType(tag: DW_TAG_pointer_type, name: "int", file: !0,
+/// line: 7, scope: !1, baseType: !2, size: 32,
+/// align: 32, offset: 0, flags: 0, extraData: !3)
+bool LLParser::ParseDIDerivedType(MDNode *&Result, bool IsDistinct) {
+#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
+ REQUIRED(tag, DwarfTagField, ); \
+ OPTIONAL(name, MDStringField, ); \
+ OPTIONAL(file, MDField, ); \
+ OPTIONAL(line, LineField, ); \
+ OPTIONAL(scope, MDField, ); \
+ REQUIRED(baseType, MDField, ); \
+ OPTIONAL(size, MDUnsignedField, (0, UINT64_MAX)); \
+ OPTIONAL(align, MDUnsignedField, (0, UINT64_MAX)); \
+ OPTIONAL(offset, MDUnsignedField, (0, UINT64_MAX)); \
+ OPTIONAL(flags, DIFlagField, ); \
+ OPTIONAL(extraData, MDField, );
+ PARSE_MD_FIELDS();
+#undef VISIT_MD_FIELDS
+
+ Result = GET_OR_DISTINCT(DIDerivedType,
+ (Context, tag.Val, name.Val, file.Val, line.Val,
+ scope.Val, baseType.Val, size.Val, align.Val,
+ offset.Val, flags.Val, extraData.Val));
+ return false;
+}
+
+bool LLParser::ParseDICompositeType(MDNode *&Result, bool IsDistinct) {
+#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
+ REQUIRED(tag, DwarfTagField, ); \
+ OPTIONAL(name, MDStringField, ); \
+ OPTIONAL(file, MDField, ); \
+ OPTIONAL(line, LineField, ); \
+ OPTIONAL(scope, MDField, ); \
+ OPTIONAL(baseType, MDField, ); \
+ OPTIONAL(size, MDUnsignedField, (0, UINT64_MAX)); \
+ OPTIONAL(align, MDUnsignedField, (0, UINT64_MAX)); \
+ OPTIONAL(offset, MDUnsignedField, (0, UINT64_MAX)); \
+ OPTIONAL(flags, DIFlagField, ); \
+ OPTIONAL(elements, MDField, ); \
+ OPTIONAL(runtimeLang, DwarfLangField, ); \
+ OPTIONAL(vtableHolder, MDField, ); \
+ OPTIONAL(templateParams, MDField, ); \
+ OPTIONAL(identifier, MDStringField, );
+ PARSE_MD_FIELDS();
+#undef VISIT_MD_FIELDS
+
+ Result = GET_OR_DISTINCT(
+ DICompositeType,
+ (Context, tag.Val, name.Val, file.Val, line.Val, scope.Val, baseType.Val,
+ size.Val, align.Val, offset.Val, flags.Val, elements.Val,
+ runtimeLang.Val, vtableHolder.Val, templateParams.Val, identifier.Val));
+ return false;
+}
+
+bool LLParser::ParseDISubroutineType(MDNode *&Result, bool IsDistinct) {
+#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
+ OPTIONAL(flags, DIFlagField, ); \
+ REQUIRED(types, MDField, );
+ PARSE_MD_FIELDS();
+#undef VISIT_MD_FIELDS
+
+ Result = GET_OR_DISTINCT(DISubroutineType, (Context, flags.Val, types.Val));
+ return false;
+}
+
+/// ParseDIFileType:
+/// ::= !DIFileType(filename: "path/to/file", directory: "/path/to/dir")
+bool LLParser::ParseDIFile(MDNode *&Result, bool IsDistinct) {
+#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
+ REQUIRED(filename, MDStringField, ); \
+ REQUIRED(directory, MDStringField, );
+ PARSE_MD_FIELDS();
+#undef VISIT_MD_FIELDS
+
+ Result = GET_OR_DISTINCT(DIFile, (Context, filename.Val, directory.Val));
+ return false;
+}
+
+/// ParseDICompileUnit:
+/// ::= !DICompileUnit(language: DW_LANG_C99, file: !0, producer: "clang",
+/// isOptimized: true, flags: "-O2", runtimeVersion: 1,
+/// splitDebugFilename: "abc.debug", emissionKind: 1,
+/// enums: !1, retainedTypes: !2, subprograms: !3,
+/// globals: !4, imports: !5, dwoId: 0x0abcd)
+bool LLParser::ParseDICompileUnit(MDNode *&Result, bool IsDistinct) {
+#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
+ REQUIRED(language, DwarfLangField, ); \
+ REQUIRED(file, MDField, (/* AllowNull */ false)); \
+ OPTIONAL(producer, MDStringField, ); \
+ OPTIONAL(isOptimized, MDBoolField, ); \
+ OPTIONAL(flags, MDStringField, ); \
+ OPTIONAL(runtimeVersion, MDUnsignedField, (0, UINT32_MAX)); \
+ OPTIONAL(splitDebugFilename, MDStringField, ); \
+ OPTIONAL(emissionKind, MDUnsignedField, (0, UINT32_MAX)); \
+ OPTIONAL(enums, MDField, ); \
+ OPTIONAL(retainedTypes, MDField, ); \
+ OPTIONAL(subprograms, MDField, ); \
+ OPTIONAL(globals, MDField, ); \
+ OPTIONAL(imports, MDField, ); \
+ OPTIONAL(dwoId, MDUnsignedField, );
+ PARSE_MD_FIELDS();
+#undef VISIT_MD_FIELDS
+
+ Result = GET_OR_DISTINCT(DICompileUnit,
+ (Context, language.Val, file.Val, producer.Val,
+ isOptimized.Val, flags.Val, runtimeVersion.Val,
+ splitDebugFilename.Val, emissionKind.Val, enums.Val,
+ retainedTypes.Val, subprograms.Val, globals.Val,
+ imports.Val, dwoId.Val));
+ return false;
+}
+
+/// ParseDISubprogram:
+/// ::= !DISubprogram(scope: !0, name: "foo", linkageName: "_Zfoo",
+/// file: !1, line: 7, type: !2, isLocal: false,
+/// isDefinition: true, scopeLine: 8, containingType: !3,
+/// virtuality: DW_VIRTUALTIY_pure_virtual,
+/// virtualIndex: 10, flags: 11,
+/// isOptimized: false, function: void ()* @_Z3foov,
+/// templateParams: !4, declaration: !5, variables: !6)
+bool LLParser::ParseDISubprogram(MDNode *&Result, bool IsDistinct) {
+#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
+ OPTIONAL(scope, MDField, ); \
+ OPTIONAL(name, MDStringField, ); \
+ OPTIONAL(linkageName, MDStringField, ); \
+ OPTIONAL(file, MDField, ); \
+ OPTIONAL(line, LineField, ); \
+ OPTIONAL(type, MDField, ); \
+ OPTIONAL(isLocal, MDBoolField, ); \
+ OPTIONAL(isDefinition, MDBoolField, (true)); \
+ OPTIONAL(scopeLine, LineField, ); \
+ OPTIONAL(containingType, MDField, ); \
+ OPTIONAL(virtuality, DwarfVirtualityField, ); \
+ OPTIONAL(virtualIndex, MDUnsignedField, (0, UINT32_MAX)); \
+ OPTIONAL(flags, DIFlagField, ); \
+ OPTIONAL(isOptimized, MDBoolField, ); \
+ OPTIONAL(function, MDConstant, ); \
+ OPTIONAL(templateParams, MDField, ); \
+ OPTIONAL(declaration, MDField, ); \
+ OPTIONAL(variables, MDField, );
+ PARSE_MD_FIELDS();
+#undef VISIT_MD_FIELDS
+
+ Result = GET_OR_DISTINCT(
+ DISubprogram, (Context, scope.Val, name.Val, linkageName.Val, file.Val,
+ line.Val, type.Val, isLocal.Val, isDefinition.Val,
+ scopeLine.Val, containingType.Val, virtuality.Val,
+ virtualIndex.Val, flags.Val, isOptimized.Val, function.Val,
+ templateParams.Val, declaration.Val, variables.Val));
+ return false;
+}
+
+/// ParseDILexicalBlock:
+/// ::= !DILexicalBlock(scope: !0, file: !2, line: 7, column: 9)
+bool LLParser::ParseDILexicalBlock(MDNode *&Result, bool IsDistinct) {
+#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
+ REQUIRED(scope, MDField, (/* AllowNull */ false)); \
+ OPTIONAL(file, MDField, ); \
+ OPTIONAL(line, LineField, ); \
+ OPTIONAL(column, ColumnField, );
+ PARSE_MD_FIELDS();
+#undef VISIT_MD_FIELDS
+
+ Result = GET_OR_DISTINCT(
+ DILexicalBlock, (Context, scope.Val, file.Val, line.Val, column.Val));
+ return false;
+}
+
+/// ParseDILexicalBlockFile:
+/// ::= !DILexicalBlockFile(scope: !0, file: !2, discriminator: 9)
+bool LLParser::ParseDILexicalBlockFile(MDNode *&Result, bool IsDistinct) {
+#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
+ REQUIRED(scope, MDField, (/* AllowNull */ false)); \
+ OPTIONAL(file, MDField, ); \
+ REQUIRED(discriminator, MDUnsignedField, (0, UINT32_MAX));
+ PARSE_MD_FIELDS();
+#undef VISIT_MD_FIELDS
+
+ Result = GET_OR_DISTINCT(DILexicalBlockFile,
+ (Context, scope.Val, file.Val, discriminator.Val));
+ return false;
+}
+
+/// ParseDINamespace:
+/// ::= !DINamespace(scope: !0, file: !2, name: "SomeNamespace", line: 9)
+bool LLParser::ParseDINamespace(MDNode *&Result, bool IsDistinct) {
+#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
+ REQUIRED(scope, MDField, ); \
+ OPTIONAL(file, MDField, ); \
+ OPTIONAL(name, MDStringField, ); \
+ OPTIONAL(line, LineField, );
+ PARSE_MD_FIELDS();
+#undef VISIT_MD_FIELDS
+
+ Result = GET_OR_DISTINCT(DINamespace,
+ (Context, scope.Val, file.Val, name.Val, line.Val));
+ return false;
+}
+
+/// ParseDIModule:
+/// ::= !DIModule(scope: !0, name: "SomeModule", configMacros: "-DNDEBUG",
+/// includePath: "/usr/include", isysroot: "/")
+bool LLParser::ParseDIModule(MDNode *&Result, bool IsDistinct) {
+#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
+ REQUIRED(scope, MDField, ); \
+ REQUIRED(name, MDStringField, ); \
+ OPTIONAL(configMacros, MDStringField, ); \
+ OPTIONAL(includePath, MDStringField, ); \
+ OPTIONAL(isysroot, MDStringField, );
+ PARSE_MD_FIELDS();
+#undef VISIT_MD_FIELDS
+
+ Result = GET_OR_DISTINCT(DIModule, (Context, scope.Val, name.Val,
+ configMacros.Val, includePath.Val, isysroot.Val));
+ return false;
+}
+
+/// ParseDITemplateTypeParameter:
+/// ::= !DITemplateTypeParameter(name: "Ty", type: !1)
+bool LLParser::ParseDITemplateTypeParameter(MDNode *&Result, bool IsDistinct) {
+#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
+ OPTIONAL(name, MDStringField, ); \
+ REQUIRED(type, MDField, );
+ PARSE_MD_FIELDS();
+#undef VISIT_MD_FIELDS
+
+ Result =
+ GET_OR_DISTINCT(DITemplateTypeParameter, (Context, name.Val, type.Val));
+ return false;
+}
+
+/// ParseDITemplateValueParameter:
+/// ::= !DITemplateValueParameter(tag: DW_TAG_template_value_parameter,
+/// name: "V", type: !1, value: i32 7)
+bool LLParser::ParseDITemplateValueParameter(MDNode *&Result, bool IsDistinct) {
+#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
+ OPTIONAL(tag, DwarfTagField, (dwarf::DW_TAG_template_value_parameter)); \
+ OPTIONAL(name, MDStringField, ); \
+ OPTIONAL(type, MDField, ); \
+ REQUIRED(value, MDField, );
+ PARSE_MD_FIELDS();
+#undef VISIT_MD_FIELDS
+
+ Result = GET_OR_DISTINCT(DITemplateValueParameter,
+ (Context, tag.Val, name.Val, type.Val, value.Val));
+ return false;
+}
+
+/// ParseDIGlobalVariable:
+/// ::= !DIGlobalVariable(scope: !0, name: "foo", linkageName: "foo",
+/// file: !1, line: 7, type: !2, isLocal: false,
+/// isDefinition: true, variable: i32* @foo,
+/// declaration: !3)
+bool LLParser::ParseDIGlobalVariable(MDNode *&Result, bool IsDistinct) {
+#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
+ REQUIRED(name, MDStringField, (/* AllowEmpty */ false)); \
+ OPTIONAL(scope, MDField, ); \
+ OPTIONAL(linkageName, MDStringField, ); \
+ OPTIONAL(file, MDField, ); \
+ OPTIONAL(line, LineField, ); \
+ OPTIONAL(type, MDField, ); \
+ OPTIONAL(isLocal, MDBoolField, ); \
+ OPTIONAL(isDefinition, MDBoolField, (true)); \
+ OPTIONAL(variable, MDConstant, ); \
+ OPTIONAL(declaration, MDField, );
+ PARSE_MD_FIELDS();
+#undef VISIT_MD_FIELDS
+
+ Result = GET_OR_DISTINCT(DIGlobalVariable,
+ (Context, scope.Val, name.Val, linkageName.Val,
+ file.Val, line.Val, type.Val, isLocal.Val,
+ isDefinition.Val, variable.Val, declaration.Val));
+ return false;
+}
+
+/// ParseDILocalVariable:
+/// ::= !DILocalVariable(arg: 7, scope: !0, name: "foo",
+/// file: !1, line: 7, type: !2, arg: 2, flags: 7)
+/// ::= !DILocalVariable(scope: !0, name: "foo",
+/// file: !1, line: 7, type: !2, arg: 2, flags: 7)
+bool LLParser::ParseDILocalVariable(MDNode *&Result, bool IsDistinct) {
+#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
+ REQUIRED(scope, MDField, (/* AllowNull */ false)); \
+ OPTIONAL(name, MDStringField, ); \
+ OPTIONAL(arg, MDUnsignedField, (0, UINT16_MAX)); \
+ OPTIONAL(file, MDField, ); \
+ OPTIONAL(line, LineField, ); \
+ OPTIONAL(type, MDField, ); \
+ OPTIONAL(flags, DIFlagField, );
+ PARSE_MD_FIELDS();
+#undef VISIT_MD_FIELDS
+
+ Result = GET_OR_DISTINCT(DILocalVariable,
+ (Context, scope.Val, name.Val, file.Val, line.Val,
+ type.Val, arg.Val, flags.Val));
+ return false;
+}
+
+/// ParseDIExpression:
+/// ::= !DIExpression(0, 7, -1)
+bool LLParser::ParseDIExpression(MDNode *&Result, bool IsDistinct) {
+ assert(Lex.getKind() == lltok::MetadataVar && "Expected metadata type name");
+ Lex.Lex();
+
+ if (ParseToken(lltok::lparen, "expected '(' here"))
+ return true;
+
+ SmallVector<uint64_t, 8> Elements;
+ if (Lex.getKind() != lltok::rparen)
+ do {
+ if (Lex.getKind() == lltok::DwarfOp) {
+ if (unsigned Op = dwarf::getOperationEncoding(Lex.getStrVal())) {
+ Lex.Lex();
+ Elements.push_back(Op);
+ continue;
+ }
+ return TokError(Twine("invalid DWARF op '") + Lex.getStrVal() + "'");
+ }
+
+ if (Lex.getKind() != lltok::APSInt || Lex.getAPSIntVal().isSigned())
+ return TokError("expected unsigned integer");
+
+ auto &U = Lex.getAPSIntVal();
+ if (U.ugt(UINT64_MAX))
+ return TokError("element too large, limit is " + Twine(UINT64_MAX));
+ Elements.push_back(U.getZExtValue());
+ Lex.Lex();
+ } while (EatIfPresent(lltok::comma));
+
+ if (ParseToken(lltok::rparen, "expected ')' here"))
+ return true;
+
+ Result = GET_OR_DISTINCT(DIExpression, (Context, Elements));
+ return false;
+}
+
+/// ParseDIObjCProperty:
+/// ::= !DIObjCProperty(name: "foo", file: !1, line: 7, setter: "setFoo",
+/// getter: "getFoo", attributes: 7, type: !2)
+bool LLParser::ParseDIObjCProperty(MDNode *&Result, bool IsDistinct) {
+#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
+ OPTIONAL(name, MDStringField, ); \
+ OPTIONAL(file, MDField, ); \
+ OPTIONAL(line, LineField, ); \
+ OPTIONAL(setter, MDStringField, ); \
+ OPTIONAL(getter, MDStringField, ); \
+ OPTIONAL(attributes, MDUnsignedField, (0, UINT32_MAX)); \
+ OPTIONAL(type, MDField, );
+ PARSE_MD_FIELDS();
+#undef VISIT_MD_FIELDS
+
+ Result = GET_OR_DISTINCT(DIObjCProperty,
+ (Context, name.Val, file.Val, line.Val, setter.Val,
+ getter.Val, attributes.Val, type.Val));
+ return false;
+}
+
+/// ParseDIImportedEntity:
+/// ::= !DIImportedEntity(tag: DW_TAG_imported_module, scope: !0, entity: !1,
+/// line: 7, name: "foo")
+bool LLParser::ParseDIImportedEntity(MDNode *&Result, bool IsDistinct) {
+#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
+ REQUIRED(tag, DwarfTagField, ); \
+ REQUIRED(scope, MDField, ); \
+ OPTIONAL(entity, MDField, ); \
+ OPTIONAL(line, LineField, ); \
+ OPTIONAL(name, MDStringField, );
+ PARSE_MD_FIELDS();
+#undef VISIT_MD_FIELDS
+
+ Result = GET_OR_DISTINCT(DIImportedEntity, (Context, tag.Val, scope.Val,
+ entity.Val, line.Val, name.Val));
+ return false;
+}
+
+#undef PARSE_MD_FIELD
+#undef NOP_FIELD
+#undef REQUIRE_FIELD
+#undef DECLARE_FIELD
+
+/// ParseMetadataAsValue
+/// ::= metadata i32 %local
+/// ::= metadata i32 @global
+/// ::= metadata i32 7
+/// ::= metadata !0
+/// ::= metadata !{...}
+/// ::= metadata !"string"
+bool LLParser::ParseMetadataAsValue(Value *&V, PerFunctionState &PFS) {
+ // Note: the type 'metadata' has already been parsed.
+ Metadata *MD;
+ if (ParseMetadata(MD, &PFS))
+ return true;
+
+ V = MetadataAsValue::get(Context, MD);
+ return false;
+}
+
+/// ParseValueAsMetadata
+/// ::= i32 %local
+/// ::= i32 @global
+/// ::= i32 7
+bool LLParser::ParseValueAsMetadata(Metadata *&MD, const Twine &TypeMsg,
+ PerFunctionState *PFS) {
+ Type *Ty;
+ LocTy Loc;
+ if (ParseType(Ty, TypeMsg, Loc))
+ return true;
+ if (Ty->isMetadataTy())
+ return Error(Loc, "invalid metadata-value-metadata roundtrip");
+
+ Value *V;
+ if (ParseValue(Ty, V, PFS))
+ return true;
+
+ MD = ValueAsMetadata::get(V);
+ return false;
+}
+
+/// ParseMetadata
+/// ::= i32 %local
+/// ::= i32 @global
+/// ::= i32 7
+/// ::= !42
+/// ::= !{...}
+/// ::= !"string"
+/// ::= !DILocation(...)
+bool LLParser::ParseMetadata(Metadata *&MD, PerFunctionState *PFS) {
+ if (Lex.getKind() == lltok::MetadataVar) {
+ MDNode *N;
+ if (ParseSpecializedMDNode(N))
+ return true;
+ MD = N;
return false;
}
+ // ValueAsMetadata:
+ // <type> <value>
+ if (Lex.getKind() != lltok::exclaim)
+ return ParseValueAsMetadata(MD, "expected metadata operand", PFS);
+
+ // '!'.
+ assert(Lex.getKind() == lltok::exclaim && "Expected '!' here");
+ Lex.Lex();
+
// MDString:
// ::= '!' STRINGCONSTANT
- if (ParseMDString(ID.MDStringVal)) return true;
- ID.Kind = ValID::t_MDString;
+ if (Lex.getKind() == lltok::StringConstant) {
+ MDString *S;
+ if (ParseMDString(S))
+ return true;
+ MD = S;
+ return false;
+ }
+
+ // MDNode:
+ // !{ ... }
+ // !7
+ MDNode *N;
+ if (ParseMDNodeTail(N))
+ return true;
+ MD = N;
return false;
}
V = PFS->GetVal(ID.StrVal, Ty, ID.Loc);
return V == nullptr;
case ValID::t_InlineAsm: {
- PointerType *PTy = dyn_cast<PointerType>(Ty);
- FunctionType *FTy =
- PTy ? dyn_cast<FunctionType>(PTy->getElementType()) : nullptr;
- if (!FTy || !InlineAsm::Verify(FTy, ID.StrVal2))
+ assert(ID.FTy);
+ if (!InlineAsm::Verify(ID.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)&1, (InlineAsm::AsmDialect(ID.UIntVal>>2)));
+ V = InlineAsm::get(ID.FTy, ID.StrVal, ID.StrVal2, ID.UIntVal & 1,
+ (ID.UIntVal >> 1) & 1,
+ (InlineAsm::AsmDialect(ID.UIntVal >> 2)));
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 == nullptr;
return Error(ID.Loc, "element " + Twine(i) +
" of struct initializer doesn't match struct element type");
- V = ConstantStruct::get(ST, makeArrayRef(ID.ConstantStructElts,
- ID.UIntVal));
+ V = ConstantStruct::get(
+ ST, makeArrayRef(ID.ConstantStructElts.get(), ID.UIntVal));
} else
return Error(ID.Loc, "constant expression type mismatch");
return false;
llvm_unreachable("Invalid ValID");
}
+bool LLParser::parseConstantValue(Type *Ty, Constant *&C) {
+ C = nullptr;
+ ValID ID;
+ auto Loc = Lex.getLoc();
+ if (ParseValID(ID, /*PFS=*/nullptr))
+ return true;
+ switch (ID.Kind) {
+ case ValID::t_APSInt:
+ case ValID::t_APFloat:
+ case ValID::t_Constant:
+ case ValID::t_ConstantStruct:
+ case ValID::t_PackedConstantStruct: {
+ Value *V;
+ if (ConvertValIDToValue(Ty, ID, V, /*PFS=*/nullptr))
+ return true;
+ assert(isa<Constant>(V) && "Expected a constant value");
+ C = cast<Constant>(V);
+ return false;
+ }
+ default:
+ return Error(Loc, "expected a constant value");
+ }
+}
+
bool LLParser::ParseValue(Type *Ty, Value *&V, PerFunctionState *PFS) {
V = nullptr;
ValID ID;
/// FunctionHeader
/// ::= OptionalLinkage OptionalVisibility OptionalCallingConv OptRetAttrs
/// OptUnnamedAddr Type GlobalName '(' ArgList ')' OptFuncAttrs OptSection
-/// OptionalAlign OptGC OptionalPrefix OptionalPrologue
+/// OptionalAlign OptGC OptionalPrefix OptionalPrologue OptPersonalityFn
bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
// Parse the linkage.
LocTy LinkageLoc = Lex.getLoc();
LocTy UnnamedAddrLoc;
Constant *Prefix = nullptr;
Constant *Prologue = nullptr;
+ Constant *PersonalityFn = nullptr;
Comdat *C;
if (ParseArgumentList(ArgList, isVarArg) ||
BuiltinLoc) ||
(EatIfPresent(lltok::kw_section) &&
ParseStringConstant(Section)) ||
- parseOptionalComdat(C) ||
+ parseOptionalComdat(FunctionName, C) ||
ParseOptionalAlignment(Alignment) ||
(EatIfPresent(lltok::kw_gc) &&
ParseStringConstant(GC)) ||
(EatIfPresent(lltok::kw_prefix) &&
ParseGlobalTypeAndValue(Prefix)) ||
(EatIfPresent(lltok::kw_prologue) &&
- ParseGlobalTypeAndValue(Prologue)))
+ ParseGlobalTypeAndValue(Prologue)) ||
+ (EatIfPresent(lltok::kw_personality) &&
+ ParseGlobalTypeAndValue(PersonalityFn)))
return true;
if (FuncAttrs.contains(Attribute::Builtin))
Fn->setAlignment(Alignment);
Fn->setSection(Section);
Fn->setComdat(C);
+ Fn->setPersonalityFn(PersonalityFn);
if (!GC.empty()) Fn->setGC(GC.c_str());
Fn->setPrefixData(Prefix);
Fn->setPrologueData(Prologue);
}
BasicBlock *BB = PFS.DefineBB(Name, NameLoc);
- if (!BB) return true;
+ if (!BB)
+ return Error(NameLoc,
+ "unable to create block named '" + Name + "'");
std::string NameStr;
// 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, &PFS))
+ 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, &PFS))
+ if (ParseInstructionMetadata(*Inst))
return true;
break;
}
case lltok::kw_indirectbr: return ParseIndirectBr(Inst, PFS);
case lltok::kw_invoke: return ParseInvoke(Inst, PFS);
case lltok::kw_resume: return ParseResume(Inst, PFS);
+ case lltok::kw_cleanupret: return ParseCleanupRet(Inst, PFS);
+ case lltok::kw_catchret: return ParseCatchRet(Inst, PFS);
+ case lltok::kw_catchpad: return ParseCatchPad(Inst, PFS);
+ case lltok::kw_terminatepad: return ParseTerminatePad(Inst, PFS);
+ case lltok::kw_cleanuppad: return ParseCleanupPad(Inst, PFS);
+ case lltok::kw_catchendpad: return ParseCatchEndPad(Inst, PFS);
// Binary Operators.
case lltok::kw_add:
case lltok::kw_sub:
case lltok::kw_and:
case lltok::kw_or:
case lltok::kw_xor: return ParseLogical(Inst, PFS, KeywordVal);
- case lltok::kw_icmp:
- case lltok::kw_fcmp: return ParseCompare(Inst, PFS, KeywordVal);
+ case lltok::kw_icmp: return ParseCompare(Inst, PFS, KeywordVal);
+ case lltok::kw_fcmp: {
+ FastMathFlags FMF = EatFastMathFlagsIfPresent();
+ int Res = ParseCompare(Inst, PFS, KeywordVal);
+ if (Res != 0)
+ return Res;
+ if (FMF.any())
+ Inst->setFastMathFlags(FMF);
+ return 0;
+ }
+
// Casts.
case lltok::kw_trunc:
case lltok::kw_zext:
// 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.
- PointerType *PFTy = nullptr;
- FunctionType *Ty = nullptr;
- if (!(PFTy = dyn_cast<PointerType>(RetType)) ||
- !(Ty = dyn_cast<FunctionType>(PFTy->getElementType()))) {
+ FunctionType *Ty = dyn_cast<FunctionType>(RetType);
+ if (!Ty) {
// Pull out the types of all of the arguments...
std::vector<Type*> ParamTypes;
for (unsigned i = 0, e = ArgList.size(); i != e; ++i)
return Error(RetTypeLoc, "Invalid result type for LLVM function");
Ty = FunctionType::get(RetType, ParamTypes, false);
- PFTy = PointerType::getUnqual(Ty);
}
+ CalleeID.FTy = Ty;
+
// Look up the callee.
Value *Callee;
- if (ConvertValIDToValue(PFTy, CalleeID, Callee, &PFS)) return true;
+ if (ConvertValIDToValue(PointerType::getUnqual(Ty), CalleeID, Callee, &PFS))
+ return true;
// Set up the Attribute for the function.
SmallVector<AttributeSet, 8> Attrs;
if (I != E)
return Error(CallLoc, "not enough parameters specified for call");
- if (FnAttrs.hasAttributes())
+ if (FnAttrs.hasAttributes()) {
+ if (FnAttrs.hasAlignmentAttr())
+ return Error(CallLoc, "invoke instructions may not have an alignment");
+
Attrs.push_back(AttributeSet::get(RetType->getContext(),
AttributeSet::FunctionIndex,
FnAttrs));
+ }
// Finish off the Attribute and check them
AttributeSet PAL = AttributeSet::get(Context, Attrs);
- InvokeInst *II = InvokeInst::Create(Callee, NormalBB, UnwindBB, Args);
+ InvokeInst *II = InvokeInst::Create(Ty, Callee, NormalBB, UnwindBB, Args);
II->setCallingConv(CC);
II->setAttributes(PAL);
ForwardRefAttrGroups[II] = FwdRefAttrGrps;
return false;
}
+bool LLParser::ParseExceptionArgs(SmallVectorImpl<Value *> &Args,
+ PerFunctionState &PFS) {
+ if (ParseToken(lltok::lsquare, "expected '[' in cleanuppad"))
+ return true;
+
+ while (Lex.getKind() != lltok::rsquare) {
+ // If this isn't the first argument, we need a comma.
+ if (!Args.empty() &&
+ ParseToken(lltok::comma, "expected ',' in argument list"))
+ return true;
+
+ // Parse the argument.
+ LocTy ArgLoc;
+ Type *ArgTy = nullptr;
+ if (ParseType(ArgTy, ArgLoc))
+ return true;
+
+ Value *V;
+ if (ArgTy->isMetadataTy()) {
+ if (ParseMetadataAsValue(V, PFS))
+ return true;
+ } else {
+ if (ParseValue(ArgTy, V, PFS))
+ return true;
+ }
+ Args.push_back(V);
+ }
+
+ Lex.Lex(); // Lex the ']'.
+ return false;
+}
+
+/// ParseCleanupRet
+/// ::= 'cleanupret' ('void' | TypeAndValue) unwind ('to' 'caller' | TypeAndValue)
+bool LLParser::ParseCleanupRet(Instruction *&Inst, PerFunctionState &PFS) {
+ Type *RetTy = nullptr;
+ Value *RetVal = nullptr;
+ if (ParseType(RetTy, /*AllowVoid=*/true))
+ return true;
+
+ if (!RetTy->isVoidTy())
+ if (ParseValue(RetTy, RetVal, PFS))
+ return true;
+
+ if (ParseToken(lltok::kw_unwind, "expected 'unwind' in cleanupret"))
+ return true;
+
+ BasicBlock *UnwindBB = nullptr;
+ if (Lex.getKind() == lltok::kw_to) {
+ Lex.Lex();
+ if (ParseToken(lltok::kw_caller, "expected 'caller' in cleanupret"))
+ return true;
+ } else {
+ if (ParseTypeAndBasicBlock(UnwindBB, PFS)) {
+ return true;
+ }
+ }
+
+ Inst = CleanupReturnInst::Create(Context, RetVal, UnwindBB);
+ return false;
+}
+
+/// ParseCatchRet
+/// ::= 'catchret' TypeAndValue
+bool LLParser::ParseCatchRet(Instruction *&Inst, PerFunctionState &PFS) {
+ BasicBlock *BB;
+ if (ParseTypeAndBasicBlock(BB, PFS))
+ return true;
+
+ Inst = CatchReturnInst::Create(BB);
+ return false;
+}
+
+/// ParseCatchPad
+/// ::= 'catchpad' Type ParamList 'to' TypeAndValue 'unwind' TypeAndValue
+bool LLParser::ParseCatchPad(Instruction *&Inst, PerFunctionState &PFS) {
+ Type *RetType = nullptr;
+
+ SmallVector<Value *, 8> Args;
+ if (ParseType(RetType, /*AllowVoid=*/true) || ParseExceptionArgs(Args, PFS))
+ return true;
+
+ BasicBlock *NormalBB, *UnwindBB;
+ if (ParseToken(lltok::kw_to, "expected 'to' in catchpad") ||
+ ParseTypeAndBasicBlock(NormalBB, PFS) ||
+ ParseToken(lltok::kw_unwind, "expected 'unwind' in catchpad") ||
+ ParseTypeAndBasicBlock(UnwindBB, PFS))
+ return true;
+
+ Inst = CatchPadInst::Create(RetType, NormalBB, UnwindBB, Args);
+ return false;
+}
+
+/// ParseTerminatePad
+/// ::= 'terminatepad' ParamList 'to' TypeAndValue
+bool LLParser::ParseTerminatePad(Instruction *&Inst, PerFunctionState &PFS) {
+ SmallVector<Value *, 8> Args;
+ if (ParseExceptionArgs(Args, PFS))
+ return true;
+
+ if (ParseToken(lltok::kw_unwind, "expected 'unwind' in terminatepad"))
+ return true;
+
+ BasicBlock *UnwindBB = nullptr;
+ if (Lex.getKind() == lltok::kw_to) {
+ Lex.Lex();
+ if (ParseToken(lltok::kw_caller, "expected 'caller' in terminatepad"))
+ return true;
+ } else {
+ if (ParseTypeAndBasicBlock(UnwindBB, PFS)) {
+ return true;
+ }
+ }
+
+ Inst = TerminatePadInst::Create(Context, UnwindBB, Args);
+ return false;
+}
+
+/// ParseCleanupPad
+/// ::= 'cleanuppad' ParamList
+bool LLParser::ParseCleanupPad(Instruction *&Inst, PerFunctionState &PFS) {
+ Type *RetType = nullptr;
+
+ SmallVector<Value *, 8> Args;
+ if (ParseType(RetType, /*AllowVoid=*/true) || ParseExceptionArgs(Args, PFS))
+ return true;
+
+ Inst = CleanupPadInst::Create(RetType, Args);
+ return false;
+}
+
+/// ParseCatchEndPad
+/// ::= 'catchendpad' unwind ('to' 'caller' | TypeAndValue)
+bool LLParser::ParseCatchEndPad(Instruction *&Inst, PerFunctionState &PFS) {
+ if (ParseToken(lltok::kw_unwind, "expected 'unwind' in catchendpad"))
+ return true;
+
+ BasicBlock *UnwindBB = nullptr;
+ if (Lex.getKind() == lltok::kw_to) {
+ Lex.Lex();
+ if (Lex.getKind() == lltok::kw_caller) {
+ Lex.Lex();
+ } else {
+ return true;
+ }
+ } else {
+ if (ParseTypeAndBasicBlock(UnwindBB, PFS)) {
+ return true;
+ }
+ }
+
+ Inst = CatchEndPadInst::Create(Context, UnwindBB);
+ return false;
+}
+
//===----------------------------------------------------------------------===//
// Binary Operators.
//===----------------------------------------------------------------------===//
/// ::= 'filter' TypeAndValue ( ',' TypeAndValue )*
bool LLParser::ParseLandingPad(Instruction *&Inst, PerFunctionState &PFS) {
Type *Ty = nullptr; LocTy TyLoc;
- Value *PersFn; LocTy PersFnLoc;
- if (ParseType(Ty, TyLoc) ||
- ParseToken(lltok::kw_personality, "expected 'personality'") ||
- ParseTypeAndValue(PersFn, PersFnLoc, PFS))
+ if (ParseType(Ty, TyLoc))
return true;
- LandingPadInst *LP = LandingPadInst::Create(Ty, PersFn, 0);
+ std::unique_ptr<LandingPadInst> LP(LandingPadInst::Create(Ty, 0));
LP->setCleanup(EatIfPresent(lltok::kw_cleanup));
while (Lex.getKind() == lltok::kw_catch || Lex.getKind() == lltok::kw_filter){
Value *V;
LocTy VLoc;
- if (ParseTypeAndValue(V, VLoc, PFS)) {
- delete LP;
+ if (ParseTypeAndValue(V, VLoc, PFS))
return true;
- }
// A 'catch' type expects a non-array constant. A filter clause expects an
// array constant.
Error(VLoc, "'filter' clause has an invalid type");
}
- LP->addClause(cast<Constant>(V));
+ Constant *CV = dyn_cast<Constant>(V);
+ if (!CV)
+ return Error(VLoc, "clause argument must be a constant");
+ LP->addClause(CV);
}
- Inst = LP;
+ Inst = LP.release();
return false;
}
// 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.
- PointerType *PFTy = nullptr;
- FunctionType *Ty = nullptr;
- if (!(PFTy = dyn_cast<PointerType>(RetType)) ||
- !(Ty = dyn_cast<FunctionType>(PFTy->getElementType()))) {
+ FunctionType *Ty = dyn_cast<FunctionType>(RetType);
+ if (!Ty) {
// Pull out the types of all of the arguments...
std::vector<Type*> ParamTypes;
for (unsigned i = 0, e = ArgList.size(); i != e; ++i)
return Error(RetTypeLoc, "Invalid result type for LLVM function");
Ty = FunctionType::get(RetType, ParamTypes, false);
- PFTy = PointerType::getUnqual(Ty);
}
+ CalleeID.FTy = Ty;
+
// Look up the callee.
Value *Callee;
- if (ConvertValIDToValue(PFTy, CalleeID, Callee, &PFS)) return true;
+ if (ConvertValIDToValue(PointerType::getUnqual(Ty), CalleeID, Callee, &PFS))
+ return true;
// Set up the Attribute for the function.
SmallVector<AttributeSet, 8> Attrs;
if (I != E)
return Error(CallLoc, "not enough parameters specified for call");
- if (FnAttrs.hasAttributes())
+ if (FnAttrs.hasAttributes()) {
+ if (FnAttrs.hasAlignmentAttr())
+ return Error(CallLoc, "call instructions may not have an alignment");
+
Attrs.push_back(AttributeSet::get(RetType->getContext(),
AttributeSet::FunctionIndex,
FnAttrs));
+ }
// Finish off the Attribute and check them
AttributeSet PAL = AttributeSet::get(Context, Attrs);
- CallInst *CI = CallInst::Create(Callee, Args);
+ CallInst *CI = CallInst::Create(Ty, Callee, Args);
CI->setTailCallKind(TCK);
CI->setCallingConv(CC);
CI->setAttributes(PAL);
/// ::= 'alloca' 'inalloca'? Type (',' TypeAndValue)? (',' 'align' i32)?
int LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS) {
Value *Size = nullptr;
- LocTy SizeLoc;
+ LocTy SizeLoc, TyLoc;
unsigned Alignment = 0;
Type *Ty = nullptr;
bool IsInAlloca = EatIfPresent(lltok::kw_inalloca);
- if (ParseType(Ty)) return true;
+ if (ParseType(Ty, TyLoc)) return true;
+
+ if (Ty->isFunctionTy() || !PointerType::isValidElementType(Ty))
+ return Error(TyLoc, "invalid type for alloca");
bool AteExtraComma = false;
if (EatIfPresent(lltok::comma)) {
Lex.Lex();
}
- if (ParseTypeAndValue(Val, Loc, PFS) ||
+ Type *Ty;
+ LocTy ExplicitTypeLoc = Lex.getLoc();
+ if (ParseType(Ty) ||
+ ParseToken(lltok::comma, "expected comma after load's type") ||
+ ParseTypeAndValue(Val, Loc, PFS) ||
ParseScopeAndOrdering(isAtomic, Scope, Ordering) ||
ParseOptionalCommaAlign(Alignment, AteExtraComma))
return true;
- if (!Val->getType()->isPointerTy() ||
- !cast<PointerType>(Val->getType())->getElementType()->isFirstClassType())
+ if (!Val->getType()->isPointerTy() || !Ty->isFirstClassType())
return Error(Loc, "load operand must be a pointer to a first class type");
if (isAtomic && !Alignment)
return Error(Loc, "atomic load must have explicit non-zero alignment");
if (Ordering == Release || Ordering == AcquireRelease)
return Error(Loc, "atomic load cannot use Release ordering");
- Inst = new LoadInst(Val, "", isVolatile, Alignment, Ordering, Scope);
+ if (Ty != cast<PointerType>(Val->getType())->getElementType())
+ return Error(ExplicitTypeLoc,
+ "explicit pointee type doesn't match operand's pointee type");
+
+ Inst = new LoadInst(Ty, Val, "", isVolatile, Alignment, Ordering, Scope);
return AteExtraComma ? InstExtraComma : InstNormal;
}
bool InBounds = EatIfPresent(lltok::kw_inbounds);
- if (ParseTypeAndValue(Ptr, Loc, PFS)) return true;
+ Type *Ty = nullptr;
+ LocTy ExplicitTypeLoc = Lex.getLoc();
+ if (ParseType(Ty) ||
+ ParseToken(lltok::comma, "expected comma after getelementptr's type") ||
+ ParseTypeAndValue(Ptr, Loc, PFS))
+ return true;
Type *BaseType = Ptr->getType();
PointerType *BasePointerType = dyn_cast<PointerType>(BaseType->getScalarType());
if (!BasePointerType)
return Error(Loc, "base of getelementptr must be a pointer");
+ if (Ty != BasePointerType->getElementType())
+ return Error(ExplicitTypeLoc,
+ "explicit pointee type doesn't match operand's pointee type");
+
SmallVector<Value*, 16> Indices;
bool AteExtraComma = false;
+ // GEP returns a vector of pointers if at least one of parameters is a vector.
+ // All vector parameters should have the same vector width.
+ unsigned GEPWidth = BaseType->isVectorTy() ?
+ BaseType->getVectorNumElements() : 0;
+
while (EatIfPresent(lltok::comma)) {
if (Lex.getKind() == lltok::MetadataVar) {
AteExtraComma = true;
if (ParseTypeAndValue(Val, EltLoc, PFS)) return true;
if (!Val->getType()->getScalarType()->isIntegerTy())
return Error(EltLoc, "getelementptr index must be an integer");
- if (Val->getType()->isVectorTy() != Ptr->getType()->isVectorTy())
- return Error(EltLoc, "getelementptr index type missmatch");
+
if (Val->getType()->isVectorTy()) {
- unsigned ValNumEl = cast<VectorType>(Val->getType())->getNumElements();
- unsigned PtrNumEl = cast<VectorType>(Ptr->getType())->getNumElements();
- if (ValNumEl != PtrNumEl)
+ unsigned ValNumEl = Val->getType()->getVectorNumElements();
+ if (GEPWidth && GEPWidth != ValNumEl)
return Error(EltLoc,
"getelementptr vector index has a wrong number of elements");
+ GEPWidth = ValNumEl;
}
Indices.push_back(Val);
}
- if (!Indices.empty() && !BasePointerType->getElementType()->isSized())
+ SmallPtrSet<const Type*, 4> Visited;
+ if (!Indices.empty() && !Ty->isSized(&Visited))
return Error(Loc, "base element of getelementptr must be sized");
- if (!GetElementPtrInst::getIndexedType(BaseType, Indices))
+ if (!GetElementPtrInst::getIndexedType(Ty, Indices))
return Error(Loc, "invalid getelementptr indices");
- Inst = GetElementPtrInst::Create(Ptr, Indices);
+ Inst = GetElementPtrInst::Create(Ty, Ptr, Indices);
if (InBounds)
cast<GetElementPtrInst>(Inst)->setIsInBounds(true);
return AteExtraComma ? InstExtraComma : InstNormal;
if (!Val0->getType()->isAggregateType())
return Error(Loc0, "insertvalue operand must be aggregate type");
- if (!ExtractValueInst::getIndexedType(Val0->getType(), Indices))
+ Type *IndexedType = ExtractValueInst::getIndexedType(Val0->getType(), Indices);
+ if (!IndexedType)
return Error(Loc0, "invalid indices for insertvalue");
+ if (IndexedType != Val1->getType())
+ return Error(Loc1, "insertvalue operand and field disagree in type: '" +
+ getTypeString(Val1->getType()) + "' instead of '" +
+ getTypeString(IndexedType) + "'");
Inst = InsertValueInst::Create(Val0, Val1, Indices);
return AteExtraComma ? InstExtraComma : InstNormal;
}
//===----------------------------------------------------------------------===//
/// ParseMDNodeVector
-/// ::= Element (',' Element)*
+/// ::= { Element (',' Element)* }
/// Element
/// ::= 'null' | TypeAndValue
-bool LLParser::ParseMDNodeVector(SmallVectorImpl<Value*> &Elts,
- PerFunctionState *PFS) {
+bool LLParser::ParseMDNodeVector(SmallVectorImpl<Metadata *> &Elts) {
+ if (ParseToken(lltok::lbrace, "expected '{' here"))
+ return true;
+
// Check for an empty list.
- if (Lex.getKind() == lltok::rbrace)
+ if (EatIfPresent(lltok::rbrace))
return false;
- bool IsLocal = false;
do {
- if (IsLocal)
- return TokError("unexpected operand after function-local metadata");
-
// Null is a special case since it is typeless.
if (EatIfPresent(lltok::kw_null)) {
Elts.push_back(nullptr);
continue;
}
- Value *V = nullptr;
- if (ParseTypeAndValue(V, PFS)) return true;
- Elts.push_back(V);
-
- if (isa<MDNode>(V) && cast<MDNode>(V)->isFunctionLocal())
- return TokError("unexpected nested function-local metadata");
- if (!V->getType()->isMetadataTy() && !isa<Constant>(V)) {
- assert(PFS && "Unexpected function-local metadata without PFS");
- if (Elts.size() > 1)
- return TokError("unexpected function-local metadata");
- IsLocal = true;
- }
+ Metadata *MD;
+ if (ParseMetadata(MD, nullptr))
+ return true;
+ Elts.push_back(MD);
} while (EatIfPresent(lltok::comma));
- return false;
+ return ParseToken(lltok::rbrace, "expected end of metadata node");
}
//===----------------------------------------------------------------------===//