diff options
Diffstat (limited to 'llvm/lib/AsmParser/LLParser.cpp')
| -rw-r--r-- | llvm/lib/AsmParser/LLParser.cpp | 92 |
1 files changed, 70 insertions, 22 deletions
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index f0fde9ae4df5..21d386097fc6 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -25,6 +25,7 @@ #include "llvm/IR/CallingConv.h" #include "llvm/IR/Comdat.h" #include "llvm/IR/ConstantRange.h" +#include "llvm/IR/ConstantRangeList.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/DerivedTypes.h" @@ -74,23 +75,6 @@ static std::string getTypeString(Type *T) { return Tmp.str(); } -// Whatever debug info format we parsed, we should convert to the expected debug -// info format immediately afterwards. -bool LLParser::finalizeDebugInfoFormat(Module *M) { - // We should have already returned an error if we observed both intrinsics and - // records in this IR. - assert(!(SeenNewDbgInfoFormat && SeenOldDbgInfoFormat) && - "Mixed debug intrinsics/records seen without a parsing error?"); - if (PreserveInputDbgFormat == cl::boolOrDefault::BOU_TRUE) { - UseNewDbgInfoFormat = SeenNewDbgInfoFormat; - WriteNewDbgInfoFormatToBitcode = SeenNewDbgInfoFormat; - WriteNewDbgInfoFormat = SeenNewDbgInfoFormat; - } else if (M) { - M->setIsNewDbgInfoFormat(false); - } - return false; -} - /// Run: module ::= toplevelentity* bool LLParser::Run(bool UpgradeDebugInfo, DataLayoutCallbackTy DataLayoutCallback) { @@ -108,7 +92,7 @@ bool LLParser::Run(bool UpgradeDebugInfo, } return parseTopLevelEntities() || validateEndOfModule(UpgradeDebugInfo) || - validateEndOfIndex() || finalizeDebugInfoFormat(M); + validateEndOfIndex(); } bool LLParser::parseStandaloneConstantValue(Constant *&C, @@ -207,6 +191,18 @@ void LLParser::dropUnknownMetadataReferences() { bool LLParser::validateEndOfModule(bool UpgradeDebugInfo) { if (!M) return false; + + // We should have already returned an error if we observed both intrinsics and + // records in this IR. + assert(!(SeenNewDbgInfoFormat && SeenOldDbgInfoFormat) && + "Mixed debug intrinsics/records seen without a parsing error?"); + if (PreserveInputDbgFormat == cl::boolOrDefault::BOU_TRUE) { + UseNewDbgInfoFormat = SeenNewDbgInfoFormat; + WriteNewDbgInfoFormatToBitcode = SeenNewDbgInfoFormat; + WriteNewDbgInfoFormat = SeenNewDbgInfoFormat; + M->setNewDbgInfoFormatFlag(SeenNewDbgInfoFormat); + } + // Handle any function attribute group forward references. for (const auto &RAG : ForwardRefAttrGroups) { Value *V = RAG.first; @@ -439,6 +435,9 @@ bool LLParser::validateEndOfModule(bool UpgradeDebugInfo) { UpgradeModuleFlags(*M); UpgradeSectionAttributes(*M); + if (PreserveInputDbgFormat != cl::boolOrDefault::BOU_TRUE) + M->setIsNewDbgInfoFormat(UseNewDbgInfoFormat); + if (!Slots) return false; // Initialize the slot mapping. @@ -1628,6 +1627,8 @@ bool LLParser::parseEnumAttribute(Attribute::AttrKind Attr, AttrBuilder &B, } case Attribute::Range: return parseRangeAttr(B); + case Attribute::Initializes: + return parseInitializesAttr(B); default: B.addAttribute(Attr); Lex.Lex(); @@ -3103,6 +3104,52 @@ bool LLParser::parseRangeAttr(AttrBuilder &B) { return false; } +/// parseInitializesAttr +/// ::= initializes((Lo1,Hi1),(Lo2,Hi2),...) +bool LLParser::parseInitializesAttr(AttrBuilder &B) { + Lex.Lex(); + + auto ParseAPSInt = [&](APInt &Val) { + if (Lex.getKind() != lltok::APSInt) + return tokError("expected integer"); + Val = Lex.getAPSIntVal().extend(64); + Lex.Lex(); + return false; + }; + + if (parseToken(lltok::lparen, "expected '('")) + return true; + + SmallVector<ConstantRange, 2> RangeList; + // Parse each constant range. + do { + APInt Lower, Upper; + if (parseToken(lltok::lparen, "expected '('")) + return true; + + if (ParseAPSInt(Lower) || parseToken(lltok::comma, "expected ','") || + ParseAPSInt(Upper)) + return true; + + if (Lower == Upper) + return tokError("the range should not represent the full or empty set!"); + + if (parseToken(lltok::rparen, "expected ')'")) + return true; + + RangeList.push_back(ConstantRange(Lower, Upper)); + } while (EatIfPresent(lltok::comma)); + + if (parseToken(lltok::rparen, "expected ')'")) + return true; + + auto CRLOrNull = ConstantRangeList::getConstantRangeList(RangeList); + if (!CRLOrNull.has_value()) + return tokError("Invalid (unordered or overlapping) range list"); + B.addInitializesAttr(*CRLOrNull); + return false; +} + /// parseOptionalOperandBundles /// ::= /*empty*/ /// ::= '[' OperandBundle [, OperandBundle ]* ']' @@ -3499,7 +3546,7 @@ LLParser::PerFunctionState::~PerFunctionState() { if (isa<BasicBlock>(P.second.first)) continue; P.second.first->replaceAllUsesWith( - UndefValue::get(P.second.first->getType())); + PoisonValue::get(P.second.first->getType())); P.second.first->deleteValue(); } @@ -3507,7 +3554,7 @@ LLParser::PerFunctionState::~PerFunctionState() { if (isa<BasicBlock>(P.second.first)) continue; P.second.first->replaceAllUsesWith( - UndefValue::get(P.second.first->getType())); + PoisonValue::get(P.second.first->getType())); P.second.first->deleteValue(); } } @@ -4159,6 +4206,8 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS, Type *ExpectedTy) { return error(ID.Loc, "lshr constexprs are no longer supported"); case lltok::kw_ashr: return error(ID.Loc, "ashr constexprs are no longer supported"); + case lltok::kw_shl: + return error(ID.Loc, "shl constexprs are no longer supported"); case lltok::kw_fneg: return error(ID.Loc, "fneg constexprs are no longer supported"); case lltok::kw_select: @@ -4188,7 +4237,6 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS, Type *ExpectedTy) { case lltok::kw_add: case lltok::kw_sub: case lltok::kw_mul: - case lltok::kw_shl: case lltok::kw_xor: { bool NUW = false; bool NSW = false; @@ -4196,7 +4244,7 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS, Type *ExpectedTy) { Constant *Val0, *Val1; Lex.Lex(); if (Opc == Instruction::Add || Opc == Instruction::Sub || - Opc == Instruction::Mul || Opc == Instruction::Shl) { + Opc == Instruction::Mul) { if (EatIfPresent(lltok::kw_nuw)) NUW = true; if (EatIfPresent(lltok::kw_nsw)) { |
