aboutsummaryrefslogtreecommitdiff
path: root/lib/AsmParser
diff options
context:
space:
mode:
Diffstat (limited to 'lib/AsmParser')
-rw-r--r--lib/AsmParser/LLLexer.cpp21
-rw-r--r--lib/AsmParser/LLParser.cpp732
-rw-r--r--lib/AsmParser/LLParser.h59
-rw-r--r--lib/AsmParser/LLToken.h16
-rw-r--r--lib/AsmParser/Parser.cpp12
5 files changed, 668 insertions, 172 deletions
diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp
index 5c4bab734b2b..26eca230bb31 100644
--- a/lib/AsmParser/LLLexer.cpp
+++ b/lib/AsmParser/LLLexer.cpp
@@ -105,7 +105,7 @@ void LLLexer::FP80HexToIntPair(const char *Buffer, const char *End,
Pair[1] += hexDigitValue(*Buffer);
}
Pair[0] = 0;
- for (int i=0; i<16; i++, Buffer++) {
+ for (int i = 0; i < 16 && Buffer != End; i++, Buffer++) {
Pair[0] *= 16;
Pair[0] += hexDigitValue(*Buffer);
}
@@ -523,9 +523,14 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(zeroinitializer);
KEYWORD(undef);
KEYWORD(null);
+ KEYWORD(none);
KEYWORD(to);
+ KEYWORD(caller);
+ KEYWORD(within);
+ KEYWORD(from);
KEYWORD(tail);
KEYWORD(musttail);
+ KEYWORD(notail);
KEYWORD(target);
KEYWORD(triple);
KEYWORD(unwind);
@@ -586,6 +591,10 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(preserve_mostcc);
KEYWORD(preserve_allcc);
KEYWORD(ghccc);
+ KEYWORD(x86_intrcc);
+ KEYWORD(hhvmcc);
+ KEYWORD(hhvm_ccc);
+ KEYWORD(cxx_fast_tlscc);
KEYWORD(cc);
KEYWORD(c);
@@ -601,6 +610,8 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(convergent);
KEYWORD(dereferenceable);
KEYWORD(dereferenceable_or_null);
+ KEYWORD(inaccessiblememonly);
+ KEYWORD(inaccessiblemem_or_argmemonly);
KEYWORD(inlinehint);
KEYWORD(inreg);
KEYWORD(jumptable);
@@ -613,6 +624,7 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(noduplicate);
KEYWORD(noimplicitfloat);
KEYWORD(noinline);
+ KEYWORD(norecurse);
KEYWORD(nonlazybind);
KEYWORD(nonnull);
KEYWORD(noredzone);
@@ -690,6 +702,7 @@ lltok::Kind LLLexer::LexIdentifier() {
TYPEKEYWORD("label", Type::getLabelTy(Context));
TYPEKEYWORD("metadata", Type::getMetadataTy(Context));
TYPEKEYWORD("x86_mmx", Type::getX86_MMXTy(Context));
+ TYPEKEYWORD("token", Type::getTokenTy(Context));
#undef TYPEKEYWORD
// Keywords for instructions.
@@ -749,6 +762,11 @@ lltok::Kind LLLexer::LexIdentifier() {
INSTKEYWORD(extractvalue, ExtractValue);
INSTKEYWORD(insertvalue, InsertValue);
INSTKEYWORD(landingpad, LandingPad);
+ INSTKEYWORD(cleanupret, CleanupRet);
+ INSTKEYWORD(catchret, CatchRet);
+ INSTKEYWORD(catchswitch, CatchSwitch);
+ INSTKEYWORD(catchpad, CatchPad);
+ INSTKEYWORD(cleanuppad, CleanupPad);
#undef INSTKEYWORD
#define DWKEYWORD(TYPE, TOKEN) \
@@ -763,6 +781,7 @@ lltok::Kind LLLexer::LexIdentifier() {
DWKEYWORD(VIRTUALITY, DwarfVirtuality);
DWKEYWORD(LANG, DwarfLang);
DWKEYWORD(OP, DwarfOp);
+ DWKEYWORD(MACINFO, DwarfMacinfo);
#undef DWKEYWORD
if (Keyword.startswith("DIFlag")) {
diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp
index 1c6e7bd18d0e..3471a2dbd05c 100644
--- a/lib/AsmParser/LLParser.cpp
+++ b/lib/AsmParser/LLParser.cpp
@@ -13,6 +13,7 @@
#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"
@@ -48,6 +49,32 @@ bool LLParser::Run() {
ValidateEndOfModule();
}
+bool LLParser::parseStandaloneConstantValue(Constant *&C,
+ const SlotMapping *Slots) {
+ restoreParsingState(Slots);
+ 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;
+}
+
+void LLParser::restoreParsingState(const SlotMapping *Slots) {
+ if (!Slots)
+ return;
+ NumberedVals = Slots->GlobalValues;
+ NumberedMetadata = Slots->MetadataNodes;
+ for (const auto &I : Slots->NamedTypes)
+ NamedTypes.insert(
+ std::make_pair(I.getKey(), std::make_pair(I.second, LocTy())));
+ for (const auto &I : Slots->Types)
+ NumberedTypes.insert(
+ std::make_pair(I.first, std::make_pair(I.second, LocTy())));
+}
+
/// ValidateEndOfModule - Do final validity and sanity checks at the end of the
/// module.
bool LLParser::ValidateEndOfModule() {
@@ -158,7 +185,7 @@ bool LLParser::ValidateEndOfModule() {
// Look for intrinsic functions and CallInst that need to be upgraded
for (Module::iterator FI = M->begin(), FE = M->end(); FI != FE; )
- UpgradeCallsToIntrinsic(FI++); // must be post-increment, as we remove
+ UpgradeCallsToIntrinsic(&*FI++); // must be post-increment, as we remove
UpgradeDebugInfo(*M);
@@ -169,6 +196,10 @@ bool LLParser::ValidateEndOfModule() {
// the mapping from LLParser as it doesn't need it anymore.
Slots->GlobalValues = std::move(NumberedVals);
Slots->MetadataNodes = std::move(NumberedMetadata);
+ for (const auto &I : NamedTypes)
+ Slots->NamedTypes.insert(std::make_pair(I.getKey(), I.second.first));
+ for (const auto &I : NumberedTypes)
+ Slots->Types.insert(std::make_pair(I.first, I.second.first));
return false;
}
@@ -647,6 +678,12 @@ bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc, unsigned L,
return Error(NameLoc,
"symbol with local linkage must have default visibility");
+ Type *Ty;
+ LocTy ExplicitTypeLoc = Lex.getLoc();
+ if (ParseType(Ty) ||
+ ParseToken(lltok::comma, "expected comma after alias's type"))
+ return true;
+
Constant *Aliasee;
LocTy AliaseeLoc = Lex.getLoc();
if (Lex.getKind() != lltok::kw_bitcast &&
@@ -669,11 +706,35 @@ bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc, unsigned L,
auto *PTy = dyn_cast<PointerType>(AliaseeType);
if (!PTy)
return Error(AliaseeLoc, "An alias must have pointer type");
+ unsigned AddrSpace = PTy->getAddressSpace();
+
+ if (Ty != PTy->getElementType())
+ return Error(
+ ExplicitTypeLoc,
+ "explicit pointee type doesn't match operand's pointee type");
+
+ GlobalValue *GVal = nullptr;
+
+ // See if the alias was forward referenced, if so, prepare to replace the
+ // forward reference.
+ if (!Name.empty()) {
+ GVal = M->getNamedValue(Name);
+ if (GVal) {
+ if (!ForwardRefVals.erase(Name))
+ return Error(NameLoc, "redefinition of global '@" + Name + "'");
+ }
+ } else {
+ auto I = ForwardRefValIDs.find(NumberedVals.size());
+ if (I != ForwardRefValIDs.end()) {
+ GVal = I->second.first;
+ ForwardRefValIDs.erase(I);
+ }
+ }
// Okay, create the alias but do not insert it into the module yet.
std::unique_ptr<GlobalAlias> GA(
- GlobalAlias::create(PTy, (GlobalValue::LinkageTypes)Linkage, Name,
- Aliasee, /*Parent*/ nullptr));
+ GlobalAlias::create(Ty, AddrSpace, (GlobalValue::LinkageTypes)Linkage,
+ Name, Aliasee, /*Parent*/ nullptr));
GA->setThreadLocalMode(TLM);
GA->setVisibility((GlobalValue::VisibilityTypes)Visibility);
GA->setDLLStorageClass((GlobalValue::DLLStorageClassTypes)DLLStorageClass);
@@ -682,27 +743,17 @@ bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc, unsigned L,
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)) {
- // See if this was a redefinition. If so, there is no entry in
- // ForwardRefVals.
- std::map<std::string, std::pair<GlobalValue*, LocTy> >::iterator
- I = ForwardRefVals.find(Name);
- if (I == ForwardRefVals.end())
- return Error(NameLoc, "redefinition of global named '@" + Name + "'");
-
- // Otherwise, this was a definition of forward ref. Verify that types
- // agree.
- if (Val->getType() != GA->getType())
- return Error(NameLoc,
- "forward reference and definition of alias have different types");
+ if (GVal) {
+ // Verify that types agree.
+ if (GVal->getType() != GA->getType())
+ return Error(
+ ExplicitTypeLoc,
+ "forward reference and definition of alias have different types");
// If they agree, just RAUW the old value with the alias and remove the
// forward ref info.
- Val->replaceAllUsesWith(GA.get());
- Val->eraseFromParent();
- ForwardRefVals.erase(I);
+ GVal->replaceAllUsesWith(GA.get());
+ GVal->eraseFromParent();
}
// Insert into the module, we know its name won't collide now.
@@ -767,12 +818,11 @@ bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc,
if (!Name.empty()) {
GVal = M->getNamedValue(Name);
if (GVal) {
- if (!ForwardRefVals.erase(Name) || !isa<GlobalValue>(GVal))
+ if (!ForwardRefVals.erase(Name))
return Error(NameLoc, "redefinition of global '@" + Name + "'");
}
} else {
- std::map<unsigned, std::pair<GlobalValue*, LocTy> >::iterator
- I = ForwardRefValIDs.find(NumberedVals.size());
+ auto I = ForwardRefValIDs.find(NumberedVals.size());
if (I != ForwardRefValIDs.end()) {
GVal = I->second.first;
ForwardRefValIDs.erase(I);
@@ -903,14 +953,8 @@ bool LLParser::ParseFnAttributeValuePairs(AttrBuilder &B,
}
// Target-dependent attributes:
case lltok::StringConstant: {
- std::string Attr = Lex.getStrVal();
- Lex.Lex();
- std::string Val;
- if (EatIfPresent(lltok::equal) &&
- ParseStringConstant(Val))
+ if (ParseStringAttribute(B))
return true;
-
- B.addAttribute(Attr, Val);
continue;
}
@@ -951,6 +995,10 @@ bool LLParser::ParseFnAttributeValuePairs(AttrBuilder &B,
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_inaccessiblememonly:
+ B.addAttribute(Attribute::InaccessibleMemOnly); break;
+ case lltok::kw_inaccessiblemem_or_argmemonly:
+ B.addAttribute(Attribute::InaccessibleMemOrArgMemOnly); 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;
@@ -963,6 +1011,7 @@ bool LLParser::ParseFnAttributeValuePairs(AttrBuilder &B,
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_norecurse: B.addAttribute(Attribute::NoRecurse); 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;
@@ -1015,6 +1064,17 @@ bool LLParser::ParseFnAttributeValuePairs(AttrBuilder &B,
// GlobalValue Reference/Resolution Routines.
//===----------------------------------------------------------------------===//
+static inline GlobalValue *createGlobalFwdRef(Module *M, PointerType *PTy,
+ const std::string &Name) {
+ if (auto *FT = dyn_cast<FunctionType>(PTy->getElementType()))
+ return Function::Create(FT, GlobalValue::ExternalWeakLinkage, Name, M);
+ else
+ return new GlobalVariable(*M, PTy->getElementType(), false,
+ GlobalValue::ExternalWeakLinkage, nullptr, Name,
+ nullptr, GlobalVariable::NotThreadLocal,
+ PTy->getAddressSpace());
+}
+
/// GetGlobalVal - Get a value with the specified name or ID, creating a
/// forward reference record if needed. This can return null if the value
/// exists but does not have the right type.
@@ -1033,8 +1093,7 @@ GlobalValue *LLParser::GetGlobalVal(const std::string &Name, Type *Ty,
// If this is a forward reference for the value, see if we already created a
// forward ref record.
if (!Val) {
- std::map<std::string, std::pair<GlobalValue*, LocTy> >::iterator
- I = ForwardRefVals.find(Name);
+ auto I = ForwardRefVals.find(Name);
if (I != ForwardRefVals.end())
Val = I->second.first;
}
@@ -1048,15 +1107,7 @@ GlobalValue *LLParser::GetGlobalVal(const std::string &Name, Type *Ty,
}
// Otherwise, create a new forward reference for this value and remember it.
- GlobalValue *FwdVal;
- if (FunctionType *FT = dyn_cast<FunctionType>(PTy->getElementType()))
- FwdVal = Function::Create(FT, GlobalValue::ExternalWeakLinkage, Name, M);
- else
- FwdVal = new GlobalVariable(*M, PTy->getElementType(), false,
- GlobalValue::ExternalWeakLinkage, nullptr, Name,
- nullptr, GlobalVariable::NotThreadLocal,
- PTy->getAddressSpace());
-
+ GlobalValue *FwdVal = createGlobalFwdRef(M, PTy, Name);
ForwardRefVals[Name] = std::make_pair(FwdVal, Loc);
return FwdVal;
}
@@ -1073,8 +1124,7 @@ GlobalValue *LLParser::GetGlobalVal(unsigned ID, Type *Ty, LocTy Loc) {
// If this is a forward reference for the value, see if we already created a
// forward ref record.
if (!Val) {
- std::map<unsigned, std::pair<GlobalValue*, LocTy> >::iterator
- I = ForwardRefValIDs.find(ID);
+ auto I = ForwardRefValIDs.find(ID);
if (I != ForwardRefValIDs.end())
Val = I->second.first;
}
@@ -1088,13 +1138,7 @@ GlobalValue *LLParser::GetGlobalVal(unsigned ID, Type *Ty, LocTy Loc) {
}
// Otherwise, create a new forward reference for this value and remember it.
- GlobalValue *FwdVal;
- if (FunctionType *FT = dyn_cast<FunctionType>(PTy->getElementType()))
- FwdVal = Function::Create(FT, GlobalValue::ExternalWeakLinkage, "", M);
- else
- FwdVal = new GlobalVariable(*M, PTy->getElementType(), false,
- GlobalValue::ExternalWeakLinkage, nullptr, "");
-
+ GlobalValue *FwdVal = createGlobalFwdRef(M, PTy, "");
ForwardRefValIDs[ID] = std::make_pair(FwdVal, Loc);
return FwdVal;
}
@@ -1217,6 +1261,19 @@ bool LLParser::ParseOptionalAddrSpace(unsigned &AddrSpace) {
ParseToken(lltok::rparen, "expected ')' in address space");
}
+/// ParseStringAttribute
+/// := StringConstant
+/// := StringConstant '=' StringConstant
+bool LLParser::ParseStringAttribute(AttrBuilder &B) {
+ std::string Attr = Lex.getStrVal();
+ Lex.Lex();
+ std::string Val;
+ if (EatIfPresent(lltok::equal) && ParseStringConstant(Val))
+ return true;
+ B.addAttribute(Attr, Val);
+ return false;
+}
+
/// ParseOptionalParamAttrs - Parse a potentially empty list of parameter attributes.
bool LLParser::ParseOptionalParamAttrs(AttrBuilder &B) {
bool HaveError = false;
@@ -1228,6 +1285,11 @@ bool LLParser::ParseOptionalParamAttrs(AttrBuilder &B) {
switch (Token) {
default: // End of attributes.
return HaveError;
+ case lltok::StringConstant: {
+ if (ParseStringAttribute(B))
+ return true;
+ continue;
+ }
case lltok::kw_align: {
unsigned Alignment;
if (ParseOptionalAlignment(Alignment))
@@ -1309,6 +1371,11 @@ bool LLParser::ParseOptionalReturnAttrs(AttrBuilder &B) {
switch (Token) {
default: // End of attributes.
return HaveError;
+ case lltok::StringConstant: {
+ if (ParseStringAttribute(B))
+ return true;
+ continue;
+ }
case lltok::kw_dereferenceable: {
uint64_t Bytes;
if (ParseOptionalDerefAttrBytes(lltok::kw_dereferenceable, Bytes))
@@ -1323,6 +1390,13 @@ bool LLParser::ParseOptionalReturnAttrs(AttrBuilder &B) {
B.addDereferenceableOrNullAttr(Bytes);
continue;
}
+ case lltok::kw_align: {
+ unsigned Alignment;
+ if (ParseOptionalAlignment(Alignment))
+ return true;
+ B.addAlignmentAttr(Alignment);
+ 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;
@@ -1330,7 +1404,6 @@ bool LLParser::ParseOptionalReturnAttrs(AttrBuilder &B) {
case lltok::kw_zeroext: B.addAttribute(Attribute::ZExt); break;
// Error handling.
- case lltok::kw_align:
case lltok::kw_byval:
case lltok::kw_inalloca:
case lltok::kw_nest:
@@ -1473,6 +1546,10 @@ bool LLParser::ParseOptionalDLLStorageClass(unsigned &Res) {
/// ::= 'preserve_mostcc'
/// ::= 'preserve_allcc'
/// ::= 'ghccc'
+/// ::= 'x86_intrcc'
+/// ::= 'hhvmcc'
+/// ::= 'hhvm_ccc'
+/// ::= 'cxx_fast_tlscc'
/// ::= 'cc' UINT
///
bool LLParser::ParseOptionalCallingConv(unsigned &CC) {
@@ -1501,6 +1578,10 @@ bool LLParser::ParseOptionalCallingConv(unsigned &CC) {
case lltok::kw_preserve_mostcc:CC = CallingConv::PreserveMost; break;
case lltok::kw_preserve_allcc: CC = CallingConv::PreserveAll; break;
case lltok::kw_ghccc: CC = CallingConv::GHC; break;
+ case lltok::kw_x86_intrcc: CC = CallingConv::X86_INTR; break;
+ case lltok::kw_hhvmcc: CC = CallingConv::HHVM; break;
+ case lltok::kw_hhvm_ccc: CC = CallingConv::HHVM_C; break;
+ case lltok::kw_cxx_fast_tlscc: CC = CallingConv::CXX_FAST_TLS; break;
case lltok::kw_cc: {
Lex.Lex();
return ParseUInt32(CC);
@@ -1883,7 +1964,59 @@ bool LLParser::ParseParameterList(SmallVectorImpl<ParamInfo> &ArgList,
return false;
}
+/// ParseOptionalOperandBundles
+/// ::= /*empty*/
+/// ::= '[' OperandBundle [, OperandBundle ]* ']'
+///
+/// OperandBundle
+/// ::= bundle-tag '(' ')'
+/// ::= bundle-tag '(' Type Value [, Type Value ]* ')'
+///
+/// bundle-tag ::= String Constant
+bool LLParser::ParseOptionalOperandBundles(
+ SmallVectorImpl<OperandBundleDef> &BundleList, PerFunctionState &PFS) {
+ LocTy BeginLoc = Lex.getLoc();
+ if (!EatIfPresent(lltok::lsquare))
+ return false;
+
+ while (Lex.getKind() != lltok::rsquare) {
+ // If this isn't the first operand bundle, we need a comma.
+ if (!BundleList.empty() &&
+ ParseToken(lltok::comma, "expected ',' in input list"))
+ return true;
+ std::string Tag;
+ if (ParseStringConstant(Tag))
+ return true;
+
+ if (ParseToken(lltok::lparen, "expected '(' in operand bundle"))
+ return true;
+
+ std::vector<Value *> Inputs;
+ while (Lex.getKind() != lltok::rparen) {
+ // If this isn't the first input, we need a comma.
+ if (!Inputs.empty() &&
+ ParseToken(lltok::comma, "expected ',' in input list"))
+ return true;
+
+ Type *Ty = nullptr;
+ Value *Input = nullptr;
+ if (ParseType(Ty) || ParseValue(Ty, Input, PFS))
+ return true;
+ Inputs.push_back(Input);
+ }
+
+ BundleList.emplace_back(std::move(Tag), std::move(Inputs));
+
+ Lex.Lex(); // Lex the ')'.
+ }
+
+ if (BundleList.empty())
+ return Error(BeginLoc, "operand bundle set must not be empty");
+
+ Lex.Lex(); // Lex the ']'.
+ return false;
+}
/// ParseArgumentList - Parse the argument list for a function type or function
/// prototype.
@@ -2146,31 +2279,29 @@ LLParser::PerFunctionState::PerFunctionState(LLParser &p, Function &f,
: 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();
- AI != E; ++AI)
- if (!AI->hasName())
- NumberedVals.push_back(AI);
+ for (Argument &A : F.args())
+ if (!A.hasName())
+ NumberedVals.push_back(&A);
}
LLParser::PerFunctionState::~PerFunctionState() {
// If there were any forward referenced non-basicblock values, delete them.
- for (std::map<std::string, std::pair<Value*, LocTy> >::iterator
- I = ForwardRefVals.begin(), E = ForwardRefVals.end(); I != E; ++I)
- if (!isa<BasicBlock>(I->second.first)) {
- I->second.first->replaceAllUsesWith(
- UndefValue::get(I->second.first->getType()));
- delete I->second.first;
- I->second.first = nullptr;
- }
- for (std::map<unsigned, std::pair<Value*, LocTy> >::iterator
- I = ForwardRefValIDs.begin(), E = ForwardRefValIDs.end(); I != E; ++I)
- if (!isa<BasicBlock>(I->second.first)) {
- I->second.first->replaceAllUsesWith(
- UndefValue::get(I->second.first->getType()));
- delete I->second.first;
- I->second.first = nullptr;
- }
+ for (const auto &P : ForwardRefVals) {
+ if (isa<BasicBlock>(P.second.first))
+ continue;
+ P.second.first->replaceAllUsesWith(
+ UndefValue::get(P.second.first->getType()));
+ delete P.second.first;
+ }
+
+ for (const auto &P : ForwardRefValIDs) {
+ if (isa<BasicBlock>(P.second.first))
+ continue;
+ P.second.first->replaceAllUsesWith(
+ UndefValue::get(P.second.first->getType()));
+ delete P.second.first;
+ }
}
bool LLParser::PerFunctionState::FinishFunction() {
@@ -2189,16 +2320,15 @@ bool LLParser::PerFunctionState::FinishFunction() {
/// GetVal - Get a value with the specified name or ID, creating a
/// forward reference record if needed. This can return null if the value
/// exists but does not have the right type.
-Value *LLParser::PerFunctionState::GetVal(const std::string &Name,
- Type *Ty, LocTy Loc) {
+Value *LLParser::PerFunctionState::GetVal(const std::string &Name, Type *Ty,
+ LocTy Loc) {
// Look this name up in the normal function symbol table.
Value *Val = F.getValueSymbolTable().lookup(Name);
// If this is a forward reference for the value, see if we already created a
// forward ref record.
if (!Val) {
- std::map<std::string, std::pair<Value*, LocTy> >::iterator
- I = ForwardRefVals.find(Name);
+ auto I = ForwardRefVals.find(Name);
if (I != ForwardRefVals.end())
Val = I->second.first;
}
@@ -2222,25 +2352,24 @@ Value *LLParser::PerFunctionState::GetVal(const std::string &Name,
// Otherwise, create a new forward reference for this value and remember it.
Value *FwdVal;
- if (Ty->isLabelTy())
+ if (Ty->isLabelTy()) {
FwdVal = BasicBlock::Create(F.getContext(), Name, &F);
- else
+ } else {
FwdVal = new Argument(Ty, Name);
+ }
ForwardRefVals[Name] = std::make_pair(FwdVal, Loc);
return FwdVal;
}
-Value *LLParser::PerFunctionState::GetVal(unsigned ID, Type *Ty,
- LocTy Loc) {
+Value *LLParser::PerFunctionState::GetVal(unsigned ID, Type *Ty, LocTy Loc) {
// Look this name up in the normal function symbol table.
Value *Val = ID < NumberedVals.size() ? NumberedVals[ID] : nullptr;
// If this is a forward reference for the value, see if we already created a
// forward ref record.
if (!Val) {
- std::map<unsigned, std::pair<Value*, LocTy> >::iterator
- I = ForwardRefValIDs.find(ID);
+ auto I = ForwardRefValIDs.find(ID);
if (I != ForwardRefValIDs.end())
Val = I->second.first;
}
@@ -2263,10 +2392,11 @@ Value *LLParser::PerFunctionState::GetVal(unsigned ID, Type *Ty,
// Otherwise, create a new forward reference for this value and remember it.
Value *FwdVal;
- if (Ty->isLabelTy())
+ if (Ty->isLabelTy()) {
FwdVal = BasicBlock::Create(F.getContext(), "", &F);
- else
+ } else {
FwdVal = new Argument(Ty);
+ }
ForwardRefValIDs[ID] = std::make_pair(FwdVal, Loc);
return FwdVal;
@@ -2295,14 +2425,15 @@ bool LLParser::PerFunctionState::SetInstName(int NameID,
return P.Error(NameLoc, "instruction expected to be numbered '%" +
Twine(NumberedVals.size()) + "'");
- std::map<unsigned, std::pair<Value*, LocTy> >::iterator FI =
- ForwardRefValIDs.find(NameID);
+ auto FI = ForwardRefValIDs.find(NameID);
if (FI != ForwardRefValIDs.end()) {
- if (FI->second.first->getType() != Inst->getType())
+ Value *Sentinel = FI->second.first;
+ if (Sentinel->getType() != Inst->getType())
return P.Error(NameLoc, "instruction forward referenced with type '" +
getTypeString(FI->second.first->getType()) + "'");
- FI->second.first->replaceAllUsesWith(Inst);
- delete FI->second.first;
+
+ Sentinel->replaceAllUsesWith(Inst);
+ delete Sentinel;
ForwardRefValIDs.erase(FI);
}
@@ -2311,14 +2442,15 @@ bool LLParser::PerFunctionState::SetInstName(int NameID,
}
// Otherwise, the instruction had a name. Resolve forward refs and set it.
- std::map<std::string, std::pair<Value*, LocTy> >::iterator
- FI = ForwardRefVals.find(NameStr);
+ auto FI = ForwardRefVals.find(NameStr);
if (FI != ForwardRefVals.end()) {
- if (FI->second.first->getType() != Inst->getType())
+ Value *Sentinel = FI->second.first;
+ if (Sentinel->getType() != Inst->getType())
return P.Error(NameLoc, "instruction forward referenced with type '" +
getTypeString(FI->second.first->getType()) + "'");
- FI->second.first->replaceAllUsesWith(Inst);
- delete FI->second.first;
+
+ Sentinel->replaceAllUsesWith(Inst);
+ delete Sentinel;
ForwardRefVals.erase(FI);
}
@@ -2421,6 +2553,7 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) {
case lltok::kw_null: ID.Kind = ValID::t_Null; break;
case lltok::kw_undef: ID.Kind = ValID::t_Undef; break;
case lltok::kw_zeroinitializer: ID.Kind = ValID::t_Zero; break;
+ case lltok::kw_none: ID.Kind = ValID::t_None; break;
case lltok::lbrace: {
// ValID ::= '{' ConstVector '}'
@@ -2430,9 +2563,10 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) {
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;
}
@@ -2451,8 +2585,9 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) {
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;
@@ -2891,7 +3026,7 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) {
}
}
- SmallPtrSet<const Type*, 4> Visited;
+ SmallPtrSet<Type*, 4> Visited;
if (!Indices.empty() && !Ty->isSized(&Visited))
return Error(ID.Loc, "base element of getelementptr must be sized");
@@ -3066,6 +3201,11 @@ struct DwarfTagField : public MDUnsignedField {
DwarfTagField(dwarf::Tag DefaultTag)
: MDUnsignedField(DefaultTag, dwarf::DW_TAG_hi_user) {}
};
+struct DwarfMacinfoTypeField : public MDUnsignedField {
+ DwarfMacinfoTypeField() : MDUnsignedField(0, dwarf::DW_MACINFO_vendor_ext) {}
+ DwarfMacinfoTypeField(dwarf::MacinfoRecordType DefaultType)
+ : MDUnsignedField(DefaultType, dwarf::DW_MACINFO_vendor_ext) {}
+};
struct DwarfAttEncodingField : public MDUnsignedField {
DwarfAttEncodingField() : MDUnsignedField(0, dwarf::DW_ATE_hi_user) {}
};
@@ -3159,6 +3299,26 @@ bool LLParser::ParseMDField(LocTy Loc, StringRef Name, DwarfTagField &Result) {
template <>
bool LLParser::ParseMDField(LocTy Loc, StringRef Name,
+ DwarfMacinfoTypeField &Result) {
+ if (Lex.getKind() == lltok::APSInt)
+ return ParseMDField(Loc, Name, static_cast<MDUnsignedField &>(Result));
+
+ if (Lex.getKind() != lltok::DwarfMacinfo)
+ return TokError("expected DWARF macinfo type");
+
+ unsigned Macinfo = dwarf::getMacinfo(Lex.getStrVal());
+ if (Macinfo == dwarf::DW_MACINFO_invalid)
+ return TokError(
+ "invalid DWARF macinfo type" + Twine(" '") + Lex.getStrVal() + "'");
+ assert(Macinfo <= Result.Max && "Expected valid DWARF macinfo type");
+
+ Result.assign(Macinfo);
+ 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));
@@ -3569,8 +3729,11 @@ bool LLParser::ParseDIFile(MDNode *&Result, bool IsDistinct) {
/// isOptimized: true, flags: "-O2", runtimeVersion: 1,
/// splitDebugFilename: "abc.debug", emissionKind: 1,
/// enums: !1, retainedTypes: !2, subprograms: !3,
-/// globals: !4, imports: !5, dwoId: 0x0abcd)
+/// globals: !4, imports: !5, macros: !6, dwoId: 0x0abcd)
bool LLParser::ParseDICompileUnit(MDNode *&Result, bool IsDistinct) {
+ if (!IsDistinct)
+ return Lex.Error("missing 'distinct', required for !DICompileUnit");
+
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
REQUIRED(language, DwarfLangField, ); \
REQUIRED(file, MDField, (/* AllowNull */ false)); \
@@ -3585,16 +3748,16 @@ bool LLParser::ParseDICompileUnit(MDNode *&Result, bool IsDistinct) {
OPTIONAL(subprograms, MDField, ); \
OPTIONAL(globals, MDField, ); \
OPTIONAL(imports, MDField, ); \
+ OPTIONAL(macros, 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));
+ Result = DICompileUnit::getDistinct(
+ 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, macros.Val,
+ dwoId.Val);
return false;
}
@@ -3604,9 +3767,10 @@ bool LLParser::ParseDICompileUnit(MDNode *&Result, bool IsDistinct) {
/// 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)
+/// isOptimized: false, templateParams: !4, declaration: !5,
+/// variables: !6)
bool LLParser::ParseDISubprogram(MDNode *&Result, bool IsDistinct) {
+ auto Loc = Lex.getLoc();
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
OPTIONAL(scope, MDField, ); \
OPTIONAL(name, MDStringField, ); \
@@ -3622,19 +3786,23 @@ bool LLParser::ParseDISubprogram(MDNode *&Result, bool IsDistinct) {
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
+ if (isDefinition.Val && !IsDistinct)
+ return Lex.Error(
+ Loc,
+ "missing 'distinct', required for !DISubprogram when 'isDefinition'");
+
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));
+ 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, templateParams.Val, declaration.Val, variables.Val));
return false;
}
@@ -3685,6 +3853,39 @@ bool LLParser::ParseDINamespace(MDNode *&Result, bool IsDistinct) {
return false;
}
+/// ParseDIMacro:
+/// ::= !DIMacro(macinfo: type, line: 9, name: "SomeMacro", value: "SomeValue")
+bool LLParser::ParseDIMacro(MDNode *&Result, bool IsDistinct) {
+#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
+ REQUIRED(type, DwarfMacinfoTypeField, ); \
+ REQUIRED(line, LineField, ); \
+ REQUIRED(name, MDStringField, ); \
+ OPTIONAL(value, MDStringField, );
+ PARSE_MD_FIELDS();
+#undef VISIT_MD_FIELDS
+
+ Result = GET_OR_DISTINCT(DIMacro,
+ (Context, type.Val, line.Val, name.Val, value.Val));
+ return false;
+}
+
+/// ParseDIMacroFile:
+/// ::= !DIMacroFile(line: 9, file: !2, nodes: !3)
+bool LLParser::ParseDIMacroFile(MDNode *&Result, bool IsDistinct) {
+#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
+ OPTIONAL(type, DwarfMacinfoTypeField, (dwarf::DW_MACINFO_start_file)); \
+ REQUIRED(line, LineField, ); \
+ REQUIRED(file, MDField, ); \
+ OPTIONAL(nodes, MDField, );
+ PARSE_MD_FIELDS();
+#undef VISIT_MD_FIELDS
+
+ Result = GET_OR_DISTINCT(DIMacroFile,
+ (Context, type.Val, line.Val, file.Val, nodes.Val));
+ return false;
+}
+
+
/// ParseDIModule:
/// ::= !DIModule(scope: !0, name: "SomeModule", configMacros: "-DNDEBUG",
/// includePath: "/usr/include", isysroot: "/")
@@ -3762,24 +3963,25 @@ bool LLParser::ParseDIGlobalVariable(MDNode *&Result, bool IsDistinct) {
}
/// ParseDILocalVariable:
-/// ::= !DILocalVariable(tag: DW_TAG_arg_variable, scope: !0, name: "foo",
+/// ::= !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(tag, DwarfTagField, ); \
REQUIRED(scope, MDField, (/* AllowNull */ false)); \
OPTIONAL(name, MDStringField, ); \
+ OPTIONAL(arg, MDUnsignedField, (0, UINT16_MAX)); \
OPTIONAL(file, MDField, ); \
OPTIONAL(line, LineField, ); \
OPTIONAL(type, MDField, ); \
- OPTIONAL(arg, MDUnsignedField, (0, UINT16_MAX)); \
OPTIONAL(flags, DIFlagField, );
PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS
Result = GET_OR_DISTINCT(DILocalVariable,
- (Context, tag.Val, scope.Val, name.Val, file.Val,
- line.Val, type.Val, arg.Val, flags.Val));
+ (Context, scope.Val, name.Val, file.Val, line.Val,
+ type.Val, arg.Val, flags.Val));
return false;
}
@@ -3969,13 +4171,11 @@ bool LLParser::ConvertValIDToValue(Type *Ty, ValID &ID, Value *&V,
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))
+ if (!ID.FTy || !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_GlobalName:
@@ -4035,6 +4235,11 @@ bool LLParser::ConvertValIDToValue(Type *Ty, ValID &ID, Value *&V,
return Error(ID.Loc, "invalid type for null constant");
V = Constant::getNullValue(Ty);
return false;
+ case ValID::t_None:
+ if (!Ty->isTokenTy())
+ return Error(ID.Loc, "invalid type for none constant");
+ V = Constant::getNullValue(Ty);
+ return false;
case ValID::t_Constant:
if (ID.ConstantVal->getType() != Ty)
return Error(ID.Loc, "constant expression type mismatch");
@@ -4056,8 +4261,8 @@ bool LLParser::ConvertValIDToValue(Type *Ty, ValID &ID, Value *&V,
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;
@@ -4065,11 +4270,35 @@ bool LLParser::ConvertValIDToValue(Type *Ty, ValID &ID, Value *&V,
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_Undef:
+ 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;
- return ParseValID(ID, PFS) ||
- ConvertValIDToValue(Ty, ID, V, PFS);
+ return ParseValID(ID, PFS) || ConvertValIDToValue(Ty, ID, V, PFS);
}
bool LLParser::ParseTypeAndValue(Value *&V, PerFunctionState *PFS) {
@@ -4242,8 +4471,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
if (!FunctionName.empty()) {
// If this was a definition of a forward reference, remove the definition
// from the forward reference table and fill in the forward ref.
- std::map<std::string, std::pair<GlobalValue*, LocTy> >::iterator FRVI =
- ForwardRefVals.find(FunctionName);
+ auto FRVI = ForwardRefVals.find(FunctionName);
if (FRVI != ForwardRefVals.end()) {
Fn = M->getFunction(FunctionName);
if (!Fn)
@@ -4265,8 +4493,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
} else {
// If this is a definition of a forward referenced function, make sure the
// types agree.
- std::map<unsigned, std::pair<GlobalValue*, LocTy> >::iterator I
- = ForwardRefValIDs.find(NumberedVals.size());
+ auto I = ForwardRefValIDs.find(NumberedVals.size());
if (I != ForwardRefValIDs.end()) {
Fn = cast<Function>(I->second.first);
if (Fn->getType() != PFT)
@@ -4498,6 +4725,11 @@ int LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB,
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_catchswitch: return ParseCatchSwitch(Inst, PFS);
+ case lltok::kw_catchpad: return ParseCatchPad(Inst, PFS);
+ case lltok::kw_cleanuppad: return ParseCleanupPad(Inst, PFS);
// Binary Operators.
case lltok::kw_add:
case lltok::kw_sub:
@@ -4580,6 +4812,7 @@ int LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB,
case lltok::kw_call: return ParseCall(Inst, PFS, CallInst::TCK_None);
case lltok::kw_tail: return ParseCall(Inst, PFS, CallInst::TCK_Tail);
case lltok::kw_musttail: return ParseCall(Inst, PFS, CallInst::TCK_MustTail);
+ case lltok::kw_notail: return ParseCall(Inst, PFS, CallInst::TCK_NoTail);
// Memory.
case lltok::kw_alloca: return ParseAlloc(Inst, PFS);
case lltok::kw_load: return ParseLoad(Inst, PFS);
@@ -4798,15 +5031,15 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) {
LocTy RetTypeLoc;
ValID CalleeID;
SmallVector<ParamInfo, 16> ArgList;
+ SmallVector<OperandBundleDef, 2> BundleList;
BasicBlock *NormalBB, *UnwindBB;
- if (ParseOptionalCallingConv(CC) ||
- ParseOptionalReturnAttrs(RetAttrs) ||
+ if (ParseOptionalCallingConv(CC) || ParseOptionalReturnAttrs(RetAttrs) ||
ParseType(RetType, RetTypeLoc, true /*void allowed*/) ||
- ParseValID(CalleeID) ||
- ParseParameterList(ArgList, PFS) ||
+ ParseValID(CalleeID) || ParseParameterList(ArgList, PFS) ||
ParseFnAttributeValuePairs(FnAttrs, FwdRefAttrGrps, false,
NoBuiltinLoc) ||
+ ParseOptionalOperandBundles(BundleList, PFS) ||
ParseToken(lltok::kw_to, "expected 'to' in invoke") ||
ParseTypeAndBasicBlock(NormalBB, PFS) ||
ParseToken(lltok::kw_unwind, "expected 'unwind' in invoke") ||
@@ -4829,6 +5062,8 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) {
Ty = FunctionType::get(RetType, ParamTypes, false);
}
+ CalleeID.FTy = Ty;
+
// Look up the callee.
Value *Callee;
if (ConvertValIDToValue(PointerType::getUnqual(Ty), CalleeID, Callee, &PFS))
@@ -4880,7 +5115,8 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) {
// Finish off the Attribute and check them
AttributeSet PAL = AttributeSet::get(Context, Attrs);
- InvokeInst *II = InvokeInst::Create(Ty, Callee, NormalBB, UnwindBB, Args);
+ InvokeInst *II =
+ InvokeInst::Create(Ty, Callee, NormalBB, UnwindBB, Args, BundleList);
II->setCallingConv(CC);
II->setAttributes(PAL);
ForwardRefAttrGroups[II] = FwdRefAttrGrps;
@@ -4900,6 +5136,183 @@ bool LLParser::ParseResume(Instruction *&Inst, PerFunctionState &PFS) {
return false;
}
+bool LLParser::ParseExceptionArgs(SmallVectorImpl<Value *> &Args,
+ PerFunctionState &PFS) {
+ if (ParseToken(lltok::lsquare, "expected '[' in catchpad/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' from Value unwind ('to' 'caller' | TypeAndValue)
+bool LLParser::ParseCleanupRet(Instruction *&Inst, PerFunctionState &PFS) {
+ Value *CleanupPad = nullptr;
+
+ if (ParseToken(lltok::kw_from, "expected 'from' after cleanupret"))
+ return true;
+
+ if (ParseValue(Type::getTokenTy(Context), CleanupPad, 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(CleanupPad, UnwindBB);
+ return false;
+}
+
+/// ParseCatchRet
+/// ::= 'catchret' from Parent Value 'to' TypeAndValue
+bool LLParser::ParseCatchRet(Instruction *&Inst, PerFunctionState &PFS) {
+ Value *CatchPad = nullptr;
+
+ if (ParseToken(lltok::kw_from, "expected 'from' after catchret"))
+ return true;
+
+ if (ParseValue(Type::getTokenTy(Context), CatchPad, PFS))
+ return true;
+
+ BasicBlock *BB;
+ if (ParseToken(lltok::kw_to, "expected 'to' in catchret") ||
+ ParseTypeAndBasicBlock(BB, PFS))
+ return true;
+
+ Inst = CatchReturnInst::Create(CatchPad, BB);
+ return false;
+}
+
+/// ParseCatchSwitch
+/// ::= 'catchswitch' within Parent
+bool LLParser::ParseCatchSwitch(Instruction *&Inst, PerFunctionState &PFS) {
+ Value *ParentPad;
+ LocTy BBLoc;
+
+ if (ParseToken(lltok::kw_within, "expected 'within' after catchswitch"))
+ return true;
+
+ if (Lex.getKind() != lltok::kw_none && Lex.getKind() != lltok::LocalVar &&
+ Lex.getKind() != lltok::LocalVarID)
+ return TokError("expected scope value for catchswitch");
+
+ if (ParseValue(Type::getTokenTy(Context), ParentPad, PFS))
+ return true;
+
+ if (ParseToken(lltok::lsquare, "expected '[' with catchswitch labels"))
+ return true;
+
+ SmallVector<BasicBlock *, 32> Table;
+ do {
+ BasicBlock *DestBB;
+ if (ParseTypeAndBasicBlock(DestBB, PFS))
+ return true;
+ Table.push_back(DestBB);
+ } while (EatIfPresent(lltok::comma));
+
+ if (ParseToken(lltok::rsquare, "expected ']' after catchswitch labels"))
+ return true;
+
+ if (ParseToken(lltok::kw_unwind,
+ "expected 'unwind' after catchswitch scope"))
+ return true;
+
+ BasicBlock *UnwindBB = nullptr;
+ if (EatIfPresent(lltok::kw_to)) {
+ if (ParseToken(lltok::kw_caller, "expected 'caller' in catchswitch"))
+ return true;
+ } else {
+ if (ParseTypeAndBasicBlock(UnwindBB, PFS))
+ return true;
+ }
+
+ auto *CatchSwitch =
+ CatchSwitchInst::Create(ParentPad, UnwindBB, Table.size());
+ for (BasicBlock *DestBB : Table)
+ CatchSwitch->addHandler(DestBB);
+ Inst = CatchSwitch;
+ return false;
+}
+
+/// ParseCatchPad
+/// ::= 'catchpad' ParamList 'to' TypeAndValue 'unwind' TypeAndValue
+bool LLParser::ParseCatchPad(Instruction *&Inst, PerFunctionState &PFS) {
+ Value *CatchSwitch = nullptr;
+
+ if (ParseToken(lltok::kw_within, "expected 'within' after catchpad"))
+ return true;
+
+ if (Lex.getKind() != lltok::LocalVar && Lex.getKind() != lltok::LocalVarID)
+ return TokError("expected scope value for catchpad");
+
+ if (ParseValue(Type::getTokenTy(Context), CatchSwitch, PFS))
+ return true;
+
+ SmallVector<Value *, 8> Args;
+ if (ParseExceptionArgs(Args, PFS))
+ return true;
+
+ Inst = CatchPadInst::Create(CatchSwitch, Args);
+ return false;
+}
+
+/// ParseCleanupPad
+/// ::= 'cleanuppad' within Parent ParamList
+bool LLParser::ParseCleanupPad(Instruction *&Inst, PerFunctionState &PFS) {
+ Value *ParentPad = nullptr;
+
+ if (ParseToken(lltok::kw_within, "expected 'within' after cleanuppad"))
+ return true;
+
+ if (Lex.getKind() != lltok::kw_none && Lex.getKind() != lltok::LocalVar &&
+ Lex.getKind() != lltok::LocalVarID)
+ return TokError("expected scope value for cleanuppad");
+
+ if (ParseValue(Type::getTokenTy(Context), ParentPad, PFS))
+ return true;
+
+ SmallVector<Value *, 8> Args;
+ if (ParseExceptionArgs(Args, PFS))
+ return true;
+
+ Inst = CleanupPadInst::Create(ParentPad, Args);
+ return false;
+}
+
//===----------------------------------------------------------------------===//
// Binary Operators.
//===----------------------------------------------------------------------===//
@@ -5196,12 +5609,14 @@ bool LLParser::ParseLandingPad(Instruction *&Inst, PerFunctionState &PFS) {
}
/// ParseCall
-/// ::= 'call' OptionalCallingConv OptionalAttrs Type Value
-/// ParameterList OptionalAttrs
-/// ::= 'tail' 'call' OptionalCallingConv OptionalAttrs Type Value
-/// ParameterList OptionalAttrs
-/// ::= 'musttail' 'call' OptionalCallingConv OptionalAttrs Type Value
-/// ParameterList OptionalAttrs
+/// ::= 'call' OptionalFastMathFlags OptionalCallingConv
+/// OptionalAttrs Type Value ParameterList OptionalAttrs
+/// ::= 'tail' 'call' OptionalFastMathFlags OptionalCallingConv
+/// OptionalAttrs Type Value ParameterList OptionalAttrs
+/// ::= 'musttail' 'call' OptionalFastMathFlags OptionalCallingConv
+/// OptionalAttrs Type Value ParameterList OptionalAttrs
+/// ::= 'notail' 'call' OptionalFastMathFlags OptionalCallingConv
+/// OptionalAttrs Type Value ParameterList OptionalAttrs
bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS,
CallInst::TailCallKind TCK) {
AttrBuilder RetAttrs, FnAttrs;
@@ -5212,20 +5627,29 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS,
LocTy RetTypeLoc;
ValID CalleeID;
SmallVector<ParamInfo, 16> ArgList;
+ SmallVector<OperandBundleDef, 2> BundleList;
LocTy CallLoc = Lex.getLoc();
- if ((TCK != CallInst::TCK_None &&
- ParseToken(lltok::kw_call, "expected 'tail call'")) ||
- ParseOptionalCallingConv(CC) ||
- ParseOptionalReturnAttrs(RetAttrs) ||
+ if (TCK != CallInst::TCK_None &&
+ ParseToken(lltok::kw_call,
+ "expected 'tail call', 'musttail call', or 'notail call'"))
+ return true;
+
+ FastMathFlags FMF = EatFastMathFlagsIfPresent();
+
+ if (ParseOptionalCallingConv(CC) || ParseOptionalReturnAttrs(RetAttrs) ||
ParseType(RetType, RetTypeLoc, true /*void allowed*/) ||
ParseValID(CalleeID) ||
ParseParameterList(ArgList, PFS, TCK == CallInst::TCK_MustTail,
PFS.getFunction().isVarArg()) ||
- ParseFnAttributeValuePairs(FnAttrs, FwdRefAttrGrps, false,
- BuiltinLoc))
+ ParseFnAttributeValuePairs(FnAttrs, FwdRefAttrGrps, false, BuiltinLoc) ||
+ ParseOptionalOperandBundles(BundleList, PFS))
return true;
+ if (FMF.any() && !RetType->isFPOrFPVectorTy())
+ return Error(CallLoc, "fast-math-flags specified for call without "
+ "floating-point scalar or vector return type");
+
// 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.
@@ -5242,6 +5666,8 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS,
Ty = FunctionType::get(RetType, ParamTypes, false);
}
+ CalleeID.FTy = Ty;
+
// Look up the callee.
Value *Callee;
if (ConvertValIDToValue(PointerType::getUnqual(Ty), CalleeID, Callee, &PFS))
@@ -5293,9 +5719,11 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS,
// Finish off the Attribute and check them
AttributeSet PAL = AttributeSet::get(Context, Attrs);
- CallInst *CI = CallInst::Create(Ty, Callee, Args);
+ CallInst *CI = CallInst::Create(Ty, Callee, Args, BundleList);
CI->setTailCallKind(TCK);
CI->setCallingConv(CC);
+ if (FMF.any())
+ CI->setFastMathFlags(FMF);
CI->setAttributes(PAL);
ForwardRefAttrGroups[CI] = FwdRefAttrGrps;
Inst = CI;
@@ -5614,7 +6042,7 @@ int LLParser::ParseGetElementPtr(Instruction *&Inst, PerFunctionState &PFS) {
Indices.push_back(Val);
}
- SmallPtrSet<const Type*, 4> Visited;
+ SmallPtrSet<Type*, 4> Visited;
if (!Indices.empty() && !Ty->isSized(&Visited))
return Error(Loc, "base element of getelementptr must be sized");
diff --git a/lib/AsmParser/LLParser.h b/lib/AsmParser/LLParser.h
index 6e57b3e0667d..f61a5e5e3a38 100644
--- a/lib/AsmParser/LLParser.h
+++ b/lib/AsmParser/LLParser.h
@@ -46,29 +46,32 @@ namespace llvm {
/// 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_ConstantStruct, // Value in ConstantStructElts.
- t_PackedConstantStruct // Value in ConstantStructElts.
- } Kind;
+ 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, t_None, // No value.
+ t_EmptyArray, // No value: []
+ t_Constant, // Value in ConstantVal.
+ t_InlineAsm, // Value in FTy/StrVal/StrVal2/UIntVal.
+ t_ConstantStruct, // Value in ConstantStructElts.
+ t_PackedConstantStruct // Value in ConstantStructElts.
+ } Kind = t_LocalID;
LLLexer::LocTy Loc;
unsigned UIntVal;
+ FunctionType *FTy = nullptr;
std::string StrVal, StrVal2;
APSInt APSIntVal;
- APFloat APFloatVal;
+ APFloat APFloatVal{0.0};
Constant *ConstantVal;
- Constant **ConstantStructElts;
-
- ValID() : Kind(t_LocalID), APFloatVal(0.0) {}
- ~ValID() {
- if (Kind == t_ConstantStruct || Kind == t_PackedConstantStruct)
- delete [] ConstantStructElts;
+ std::unique_ptr<Constant *[]> ConstantStructElts;
+
+ ValID() = default;
+ ValID(const ValID &RHS)
+ : Kind(RHS.Kind), Loc(RHS.Loc), UIntVal(RHS.UIntVal), FTy(RHS.FTy),
+ StrVal(RHS.StrVal), StrVal2(RHS.StrVal2), APSIntVal(RHS.APSIntVal),
+ APFloatVal(RHS.APFloatVal), ConstantVal(RHS.ConstantVal) {
+ assert(!RHS.ConstantStructElts);
}
bool operator<(const ValID &RHS) const {
@@ -143,6 +146,8 @@ namespace llvm {
Slots(Slots), BlockAddressPFS(nullptr) {}
bool Run();
+ bool parseStandaloneConstantValue(Constant *&C, const SlotMapping *Slots);
+
LLVMContext &getContext() { return Context; }
private:
@@ -154,6 +159,10 @@ namespace llvm {
return Error(Lex.getLoc(), Msg);
}
+ /// Restore the internal name and slot mappings using the mappings that
+ /// were created at an earlier parsing stage.
+ void restoreParsingState(const SlotMapping *Slots);
+
/// GetGlobalVal - Get a value with the specified name or ID, creating a
/// forward reference record if needed. This can return null if the value
/// exists but does not have the right type.
@@ -210,6 +219,8 @@ namespace llvm {
return ParseUInt64(Val);
}
+ bool ParseStringAttribute(AttrBuilder &B);
+
bool ParseTLSModel(GlobalVariable::ThreadLocalMode &TLM);
bool ParseOptionalThreadLocal(GlobalVariable::ThreadLocalMode &TLM);
bool parseOptionalUnnamedAddr(bool &UnnamedAddr) {
@@ -343,10 +354,12 @@ namespace llvm {
bool ConvertValIDToValue(Type *Ty, ValID &ID, Value *&V,
PerFunctionState *PFS);
+ bool parseConstantValue(Type *Ty, Constant *&C);
bool ParseValue(Type *Ty, Value *&V, PerFunctionState *PFS);
bool ParseValue(Type *Ty, Value *&V, PerFunctionState &PFS) {
return ParseValue(Ty, V, &PFS);
}
+
bool ParseValue(Type *Ty, Value *&V, LocTy &Loc,
PerFunctionState &PFS) {
Loc = Lex.getLoc();
@@ -381,6 +394,13 @@ namespace llvm {
bool IsMustTailCall = false,
bool InVarArgsFunc = false);
+ bool
+ ParseOptionalOperandBundles(SmallVectorImpl<OperandBundleDef> &BundleList,
+ PerFunctionState &PFS);
+
+ bool ParseExceptionArgs(SmallVectorImpl<Value *> &Args,
+ PerFunctionState &PFS);
+
// Constant Parsing.
bool ParseValID(ValID &ID, PerFunctionState *PFS = nullptr);
bool ParseGlobalValue(Type *Ty, Constant *&V);
@@ -441,6 +461,11 @@ namespace llvm {
bool ParseIndirectBr(Instruction *&Inst, PerFunctionState &PFS);
bool ParseInvoke(Instruction *&Inst, PerFunctionState &PFS);
bool ParseResume(Instruction *&Inst, PerFunctionState &PFS);
+ bool ParseCleanupRet(Instruction *&Inst, PerFunctionState &PFS);
+ bool ParseCatchRet(Instruction *&Inst, PerFunctionState &PFS);
+ bool ParseCatchSwitch(Instruction *&Inst, PerFunctionState &PFS);
+ bool ParseCatchPad(Instruction *&Inst, PerFunctionState &PFS);
+ bool ParseCleanupPad(Instruction *&Inst, PerFunctionState &PFS);
bool ParseArithmetic(Instruction *&I, PerFunctionState &PFS, unsigned Opc,
unsigned OperandType);
diff --git a/lib/AsmParser/LLToken.h b/lib/AsmParser/LLToken.h
index 691f085f0c9f..29a7f16d3c20 100644
--- a/lib/AsmParser/LLToken.h
+++ b/lib/AsmParser/LLToken.h
@@ -49,10 +49,14 @@ namespace lltok {
kw_external, kw_thread_local,
kw_localdynamic, kw_initialexec, kw_localexec,
kw_zeroinitializer,
- kw_undef, kw_null,
+ kw_undef, kw_null, kw_none,
kw_to,
+ kw_caller,
+ kw_within,
+ kw_from,
kw_tail,
kw_musttail,
+ kw_notail,
kw_target,
kw_triple,
kw_unwind,
@@ -96,6 +100,9 @@ namespace lltok {
kw_webkit_jscc, kw_anyregcc,
kw_preserve_mostcc, kw_preserve_allcc,
kw_ghccc,
+ kw_x86_intrcc,
+ kw_hhvmcc, kw_hhvm_ccc,
+ kw_cxx_fast_tlscc,
// Attributes:
kw_attributes,
@@ -109,6 +116,8 @@ namespace lltok {
kw_convergent,
kw_dereferenceable,
kw_dereferenceable_or_null,
+ kw_inaccessiblememonly,
+ kw_inaccessiblemem_or_argmemonly,
kw_inlinehint,
kw_inreg,
kw_jumptable,
@@ -121,6 +130,7 @@ namespace lltok {
kw_noduplicate,
kw_noimplicitfloat,
kw_noinline,
+ kw_norecurse,
kw_nonlazybind,
kw_nonnull,
kw_noredzone,
@@ -177,7 +187,8 @@ namespace lltok {
kw_landingpad, kw_personality, kw_cleanup, kw_catch, kw_filter,
kw_ret, kw_br, kw_switch, kw_indirectbr, kw_invoke, kw_resume,
- kw_unreachable,
+ kw_unreachable, kw_cleanupret, kw_catchswitch, kw_catchret, kw_catchpad,
+ kw_cleanuppad,
kw_alloca, kw_load, kw_store, kw_fence, kw_cmpxchg, kw_atomicrmw,
kw_getelementptr,
@@ -209,6 +220,7 @@ namespace lltok {
DwarfLang, // DW_LANG_foo
DwarfOp, // DW_OP_foo
DIFlag, // DIFlagFoo
+ DwarfMacinfo, // DW_MACINFO_foo
// Type valued tokens (TyVal).
Type,
diff --git a/lib/AsmParser/Parser.cpp b/lib/AsmParser/Parser.cpp
index 9145a54f2a7b..4e55e62ecf5c 100644
--- a/lib/AsmParser/Parser.cpp
+++ b/lib/AsmParser/Parser.cpp
@@ -66,3 +66,15 @@ std::unique_ptr<Module> llvm::parseAssemblyString(StringRef AsmString,
MemoryBufferRef F(AsmString, "<string>");
return parseAssembly(F, Err, Context, Slots);
}
+
+Constant *llvm::parseConstantValue(StringRef Asm, SMDiagnostic &Err,
+ const Module &M, const SlotMapping *Slots) {
+ SourceMgr SM;
+ std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Asm);
+ SM.AddNewSourceBuffer(std::move(Buf), SMLoc());
+ Constant *C;
+ if (LLParser(Asm, SM, Err, const_cast<Module *>(&M))
+ .parseStandaloneConstantValue(C, Slots))
+ return nullptr;
+ return C;
+}