//===-- LLParser.cpp - Parser Class ---------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
//  This file defines the parser class for .ll files.
//
//===----------------------------------------------------------------------===//

#include "llvm/AsmParser/LLParser.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/AsmParser/LLToken.h"
#include "llvm/AsmParser/SlotMapping.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/IR/Argument.h"
#include "llvm/IR/AutoUpgrade.h"
#include "llvm/IR/BasicBlock.h"
#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"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalIFunc.h"
#include "llvm/IR/GlobalObject.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/InstIterator.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Operator.h"
#include "llvm/IR/Value.h"
#include "llvm/IR/ValueSymbolTable.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/ModRef.h"
#include "llvm/Support/SaveAndRestore.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cassert>
#include <cstring>
#include <optional>
#include <vector>

using namespace llvm;

static cl::opt<bool> AllowIncompleteIR(
    "allow-incomplete-ir", cl::init(false), cl::Hidden,
    cl::desc(
        "Allow incomplete IR on a best effort basis (references to unknown "
        "metadata will be dropped)"));

static std::string getTypeString(Type *T) {
  std::string Result;
  raw_string_ostream Tmp(Result);
  Tmp << *T;
  return Tmp.str();
}

/// Run: module ::= toplevelentity*
bool LLParser::Run(bool UpgradeDebugInfo,
                   DataLayoutCallbackTy DataLayoutCallback) {
  // Prime the lexer.
  Lex.Lex();

  if (Context.shouldDiscardValueNames())
    return error(
        Lex.getLoc(),
        "Can't read textual IR with a Context that discards named Values");

  if (M) {
    if (parseTargetDefinitions(DataLayoutCallback))
      return true;
  }

  return parseTopLevelEntities() || validateEndOfModule(UpgradeDebugInfo) ||
         validateEndOfIndex();
}

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;
}

bool LLParser::parseTypeAtBeginning(Type *&Ty, unsigned &Read,
                                    const SlotMapping *Slots) {
  restoreParsingState(Slots);
  Lex.Lex();

  Read = 0;
  SMLoc Start = Lex.getLoc();
  Ty = nullptr;
  if (parseType(Ty))
    return true;
  SMLoc End = Lex.getLoc();
  Read = End.getPointer() - Start.getPointer();

  return false;
}

bool LLParser::parseDIExpressionBodyAtBeginning(MDNode *&Result, unsigned &Read,
                                                const SlotMapping *Slots) {
  restoreParsingState(Slots);
  Lex.Lex();

  Read = 0;
  SMLoc Start = Lex.getLoc();
  Result = nullptr;
  bool Status = parseDIExpressionBody(Result, /*IsDistinct=*/false);
  SMLoc End = Lex.getLoc();
  Read = End.getPointer() - Start.getPointer();

  return Status;
}

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())));
}

static void dropIntrinsicWithUnknownMetadataArgument(IntrinsicInst *II) {
  // White-list intrinsics that are safe to drop.
  if (!isa<DbgInfoIntrinsic>(II) &&
      II->getIntrinsicID() != Intrinsic::experimental_noalias_scope_decl)
    return;

  SmallVector<MetadataAsValue *> MVs;
  for (Value *V : II->args())
    if (auto *MV = dyn_cast<MetadataAsValue>(V))
      if (auto *MD = dyn_cast<MDNode>(MV->getMetadata()))
        if (MD->isTemporary())
          MVs.push_back(MV);

  if (!MVs.empty()) {
    assert(II->use_empty() && "Cannot have uses");
    II->eraseFromParent();

    // Also remove no longer used MetadataAsValue wrappers.
    for (MetadataAsValue *MV : MVs)
      if (MV->use_empty())
        delete MV;
  }
}

void LLParser::dropUnknownMetadataReferences() {
  auto Pred = [](unsigned MDKind, MDNode *Node) { return Node->isTemporary(); };
  for (Function &F : *M) {
    F.eraseMetadataIf(Pred);
    for (Instruction &I : make_early_inc_range(instructions(F))) {
      I.eraseMetadataIf(Pred);

      if (auto *II = dyn_cast<IntrinsicInst>(&I))
        dropIntrinsicWithUnknownMetadataArgument(II);
    }
  }

  for (GlobalVariable &GV : M->globals())
    GV.eraseMetadataIf(Pred);

  for (const auto &[ID, Info] : make_early_inc_range(ForwardRefMDNodes)) {
    // Check whether there is only a single use left, which would be in our
    // own NumberedMetadata.
    if (Info.first->getNumTemporaryUses() == 1) {
      NumberedMetadata.erase(ID);
      ForwardRefMDNodes.erase(ID);
    }
  }
}

/// validateEndOfModule - Do final validity and basic correctness checks at the
/// end of the module.
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?");

  // Handle any function attribute group forward references.
  for (const auto &RAG : ForwardRefAttrGroups) {
    Value *V = RAG.first;
    const std::vector<unsigned> &Attrs = RAG.second;
    AttrBuilder B(Context);

    for (const auto &Attr : Attrs) {
      auto R = NumberedAttrBuilders.find(Attr);
      if (R != NumberedAttrBuilders.end())
        B.merge(R->second);
    }

    if (Function *Fn = dyn_cast<Function>(V)) {
      AttributeList AS = Fn->getAttributes();
      AttrBuilder FnAttrs(M->getContext(), AS.getFnAttrs());
      AS = AS.removeFnAttributes(Context);

      FnAttrs.merge(B);

      // If the alignment was parsed as an attribute, move to the alignment
      // field.
      if (MaybeAlign A = FnAttrs.getAlignment()) {
        Fn->setAlignment(*A);
        FnAttrs.removeAttribute(Attribute::Alignment);
      }

      AS = AS.addFnAttributes(Context, FnAttrs);
      Fn->setAttributes(AS);
    } else if (CallInst *CI = dyn_cast<CallInst>(V)) {
      AttributeList AS = CI->getAttributes();
      AttrBuilder FnAttrs(M->getContext(), AS.getFnAttrs());
      AS = AS.removeFnAttributes(Context);
      FnAttrs.merge(B);
      AS = AS.addFnAttributes(Context, FnAttrs);
      CI->setAttributes(AS);
    } else if (InvokeInst *II = dyn_cast<InvokeInst>(V)) {
      AttributeList AS = II->getAttributes();
      AttrBuilder FnAttrs(M->getContext(), AS.getFnAttrs());
      AS = AS.removeFnAttributes(Context);
      FnAttrs.merge(B);
      AS = AS.addFnAttributes(Context, FnAttrs);
      II->setAttributes(AS);
    } else if (CallBrInst *CBI = dyn_cast<CallBrInst>(V)) {
      AttributeList AS = CBI->getAttributes();
      AttrBuilder FnAttrs(M->getContext(), AS.getFnAttrs());
      AS = AS.removeFnAttributes(Context);
      FnAttrs.merge(B);
      AS = AS.addFnAttributes(Context, FnAttrs);
      CBI->setAttributes(AS);
    } else if (auto *GV = dyn_cast<GlobalVariable>(V)) {
      AttrBuilder Attrs(M->getContext(), GV->getAttributes());
      Attrs.merge(B);
      GV->setAttributes(AttributeSet::get(Context,Attrs));
    } else {
      llvm_unreachable("invalid object with forward attribute group reference");
    }
  }

  // If there are entries in ForwardRefBlockAddresses at this point, the
  // function was never defined.
  if (!ForwardRefBlockAddresses.empty())
    return error(ForwardRefBlockAddresses.begin()->first.Loc,
                 "expected function name in blockaddress");

  auto ResolveForwardRefDSOLocalEquivalents = [&](const ValID &GVRef,
                                                  GlobalValue *FwdRef) {
    GlobalValue *GV = nullptr;
    if (GVRef.Kind == ValID::t_GlobalName) {
      GV = M->getNamedValue(GVRef.StrVal);
    } else {
      GV = NumberedVals.get(GVRef.UIntVal);
    }

    if (!GV)
      return error(GVRef.Loc, "unknown function '" + GVRef.StrVal +
                                  "' referenced by dso_local_equivalent");

    if (!GV->getValueType()->isFunctionTy())
      return error(GVRef.Loc,
                   "expected a function, alias to function, or ifunc "
                   "in dso_local_equivalent");

    auto *Equiv = DSOLocalEquivalent::get(GV);
    FwdRef->replaceAllUsesWith(Equiv);
    FwdRef->eraseFromParent();
    return false;
  };

  // If there are entries in ForwardRefDSOLocalEquivalentIDs/Names at this
  // point, they are references after the function was defined.  Resolve those
  // now.
  for (auto &Iter : ForwardRefDSOLocalEquivalentIDs) {
    if (ResolveForwardRefDSOLocalEquivalents(Iter.first, Iter.second))
      return true;
  }
  for (auto &Iter : ForwardRefDSOLocalEquivalentNames) {
    if (ResolveForwardRefDSOLocalEquivalents(Iter.first, Iter.second))
      return true;
  }
  ForwardRefDSOLocalEquivalentIDs.clear();
  ForwardRefDSOLocalEquivalentNames.clear();

  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)
    if (I->second.second.isValid())
      return error(I->second.second,
                   "use of undefined type named '" + I->getKey() + "'");

  if (!ForwardRefComdats.empty())
    return error(ForwardRefComdats.begin()->second,
                 "use of undefined comdat '$" +
                     ForwardRefComdats.begin()->first + "'");

  for (const auto &[Name, Info] : make_early_inc_range(ForwardRefVals)) {
    if (StringRef(Name).starts_with("llvm.")) {
      Intrinsic::ID IID = Intrinsic::lookupIntrinsicID(Name);
      if (IID == Intrinsic::not_intrinsic)
        // Don't do anything for unknown intrinsics.
        continue;

      // Automatically create declarations for intrinsics. Intrinsics can only
      // be called directly, so the call function type directly determines the
      // declaration function type.
      //
      // Additionally, automatically add the required mangling suffix to the
      // intrinsic name. This means that we may replace a single forward
      // declaration with multiple functions here.
      for (Use &U : make_early_inc_range(Info.first->uses())) {
        auto *CB = dyn_cast<CallBase>(U.getUser());
        if (!CB || !CB->isCallee(&U))
          return error(Info.second, "intrinsic can only be used as callee");

        SmallVector<Type *> OverloadTys;
        if (!Intrinsic::getIntrinsicSignature(IID, CB->getFunctionType(),
                                              OverloadTys))
          return error(Info.second, "invalid intrinsic signature");

        U.set(Intrinsic::getOrInsertDeclaration(M, IID, OverloadTys));
      }

      Info.first->eraseFromParent();
      ForwardRefVals.erase(Name);
      continue;
    }

    // If incomplete IR is allowed, also add declarations for
    // non-intrinsics.
    if (!AllowIncompleteIR)
      continue;

    auto GetCommonFunctionType = [](Value *V) -> FunctionType * {
      FunctionType *FTy = nullptr;
      for (Use &U : V->uses()) {
        auto *CB = dyn_cast<CallBase>(U.getUser());
        if (!CB || !CB->isCallee(&U) || (FTy && FTy != CB->getFunctionType()))
          return nullptr;
        FTy = CB->getFunctionType();
      }
      return FTy;
    };

    // First check whether this global is only used in calls with the same
    // type, in which case we'll insert a function. Otherwise, fall back to
    // using a dummy i8 type.
    Type *Ty = GetCommonFunctionType(Info.first);
    if (!Ty)
      Ty = Type::getInt8Ty(Context);

    GlobalValue *GV;
    if (auto *FTy = dyn_cast<FunctionType>(Ty))
      GV = Function::Create(FTy, GlobalValue::ExternalLinkage, Name, M);
    else
      GV = new GlobalVariable(*M, Ty, /*isConstant*/ false,
                              GlobalValue::ExternalLinkage,
                              /*Initializer*/ nullptr, Name);
    Info.first->replaceAllUsesWith(GV);
    Info.first->eraseFromParent();
    ForwardRefVals.erase(Name);
  }

  if (!ForwardRefVals.empty())
    return error(ForwardRefVals.begin()->second.second,
                 "use of undefined value '@" + ForwardRefVals.begin()->first +
                     "'");

  if (!ForwardRefValIDs.empty())
    return error(ForwardRefValIDs.begin()->second.second,
                 "use of undefined value '@" +
                     Twine(ForwardRefValIDs.begin()->first) + "'");

  if (AllowIncompleteIR && !ForwardRefMDNodes.empty())
    dropUnknownMetadataReferences();

  if (!ForwardRefMDNodes.empty())
    return error(ForwardRefMDNodes.begin()->second.second,
                 "use of undefined metadata '!" +
                     Twine(ForwardRefMDNodes.begin()->first) + "'");

  // Resolve metadata cycles.
  for (auto &N : NumberedMetadata) {
    if (N.second && !N.second->isResolved())
      N.second->resolveCycles();
  }

  for (auto *Inst : InstsWithTBAATag) {
    MDNode *MD = Inst->getMetadata(LLVMContext::MD_tbaa);
    // With incomplete IR, the tbaa metadata may have been dropped.
    if (!AllowIncompleteIR)
      assert(MD && "UpgradeInstWithTBAATag should have a TBAA tag");
    if (MD) {
      auto *UpgradedMD = UpgradeTBAANode(*MD);
      if (MD != UpgradedMD)
        Inst->setMetadata(LLVMContext::MD_tbaa, UpgradedMD);
    }
  }

  // Look for intrinsic functions and CallInst that need to be upgraded.  We use
  // make_early_inc_range here because we may remove some functions.
  for (Function &F : llvm::make_early_inc_range(*M))
    UpgradeCallsToIntrinsic(&F);

  if (UpgradeDebugInfo)
    llvm::UpgradeDebugInfo(*M);

  UpgradeModuleFlags(*M);
  UpgradeNVVMAnnotations(*M);
  UpgradeSectionAttributes(*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);
  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;
}

/// Do final validity and basic correctness checks at the end of the index.
bool LLParser::validateEndOfIndex() {
  if (!Index)
    return false;

  if (!ForwardRefValueInfos.empty())
    return error(ForwardRefValueInfos.begin()->second.front().second,
                 "use of undefined summary '^" +
                     Twine(ForwardRefValueInfos.begin()->first) + "'");

  if (!ForwardRefAliasees.empty())
    return error(ForwardRefAliasees.begin()->second.front().second,
                 "use of undefined summary '^" +
                     Twine(ForwardRefAliasees.begin()->first) + "'");

  if (!ForwardRefTypeIds.empty())
    return error(ForwardRefTypeIds.begin()->second.front().second,
                 "use of undefined type id summary '^" +
                     Twine(ForwardRefTypeIds.begin()->first) + "'");

  return false;
}

//===----------------------------------------------------------------------===//
// Top-Level Entities
//===----------------------------------------------------------------------===//

bool LLParser::parseTargetDefinitions(DataLayoutCallbackTy DataLayoutCallback) {
  // Delay parsing of the data layout string until the target triple is known.
  // Then, pass both the the target triple and the tentative data layout string
  // to DataLayoutCallback, allowing to override the DL string.
  // This enables importing modules with invalid DL strings.
  std::string TentativeDLStr = M->getDataLayoutStr();
  LocTy DLStrLoc;

  bool Done = false;
  while (!Done) {
    switch (Lex.getKind()) {
    case lltok::kw_target:
      if (parseTargetDefinition(TentativeDLStr, DLStrLoc))
        return true;
      break;
    case lltok::kw_source_filename:
      if (parseSourceFileName())
        return true;
      break;
    default:
      Done = true;
    }
  }
  // Run the override callback to potentially change the data layout string, and
  // parse the data layout string.
  if (auto LayoutOverride =
          DataLayoutCallback(M->getTargetTriple().str(), TentativeDLStr)) {
    TentativeDLStr = *LayoutOverride;
    DLStrLoc = {};
  }
  Expected<DataLayout> MaybeDL = DataLayout::parse(TentativeDLStr);
  if (!MaybeDL)
    return error(DLStrLoc, toString(MaybeDL.takeError()));
  M->setDataLayout(MaybeDL.get());
  return false;
}

bool LLParser::parseTopLevelEntities() {
  // If there is no Module, then parse just the summary index entries.
  if (!M) {
    while (true) {
      switch (Lex.getKind()) {
      case lltok::Eof:
        return false;
      case lltok::SummaryID:
        if (parseSummaryEntry())
          return true;
        break;
      case lltok::kw_source_filename:
        if (parseSourceFileName())
          return true;
        break;
      default:
        // Skip everything else
        Lex.Lex();
      }
    }
  }
  while (true) {
    switch (Lex.getKind()) {
    default:
      return tokError("expected top-level entity");
    case lltok::Eof: return false;
    case lltok::kw_declare:
      if (parseDeclare())
        return true;
      break;
    case lltok::kw_define:
      if (parseDefine())
        return true;
      break;
    case lltok::kw_module:
      if (parseModuleAsm())
        return true;
      break;
    case lltok::LocalVarID:
      if (parseUnnamedType())
        return true;
      break;
    case lltok::LocalVar:
      if (parseNamedType())
        return true;
      break;
    case lltok::GlobalID:
      if (parseUnnamedGlobal())
        return true;
      break;
    case lltok::GlobalVar:
      if (parseNamedGlobal())
        return true;
      break;
    case lltok::ComdatVar:  if (parseComdat()) return true; break;
    case lltok::exclaim:
      if (parseStandaloneMetadata())
        return true;
      break;
    case lltok::SummaryID:
      if (parseSummaryEntry())
        return true;
      break;
    case lltok::MetadataVar:
      if (parseNamedMetadata())
        return true;
      break;
    case lltok::kw_attributes:
      if (parseUnnamedAttrGrp())
        return true;
      break;
    case lltok::kw_uselistorder:
      if (parseUseListOrder())
        return true;
      break;
    case lltok::kw_uselistorder_bb:
      if (parseUseListOrderBB())
        return true;
      break;
    }
  }
}

/// toplevelentity
///   ::= 'module' 'asm' STRINGCONSTANT
bool LLParser::parseModuleAsm() {
  assert(Lex.getKind() == lltok::kw_module);
  Lex.Lex();

  std::string AsmStr;
  if (parseToken(lltok::kw_asm, "expected 'module asm'") ||
      parseStringConstant(AsmStr))
    return true;

  M->appendModuleInlineAsm(AsmStr);
  return false;
}

/// toplevelentity
///   ::= 'target' 'triple' '=' STRINGCONSTANT
///   ::= 'target' 'datalayout' '=' STRINGCONSTANT
bool LLParser::parseTargetDefinition(std::string &TentativeDLStr,
                                     LocTy &DLStrLoc) {
  assert(Lex.getKind() == lltok::kw_target);
  std::string Str;
  switch (Lex.Lex()) {
  default:
    return tokError("unknown target property");
  case lltok::kw_triple:
    Lex.Lex();
    if (parseToken(lltok::equal, "expected '=' after target triple") ||
        parseStringConstant(Str))
      return true;
    M->setTargetTriple(Triple(std::move(Str)));
    return false;
  case lltok::kw_datalayout:
    Lex.Lex();
    if (parseToken(lltok::equal, "expected '=' after target datalayout"))
      return true;
    DLStrLoc = Lex.getLoc();
    if (parseStringConstant(TentativeDLStr))
      return true;
    return false;
  }
}

/// toplevelentity
///   ::= 'source_filename' '=' STRINGCONSTANT
bool LLParser::parseSourceFileName() {
  assert(Lex.getKind() == lltok::kw_source_filename);
  Lex.Lex();
  if (parseToken(lltok::equal, "expected '=' after source_filename") ||
      parseStringConstant(SourceFileName))
    return true;
  if (M)
    M->setSourceFileName(SourceFileName);
  return false;
}

/// parseUnnamedType:
///   ::= LocalVarID '=' 'type' type
bool LLParser::parseUnnamedType() {
  LocTy TypeLoc = Lex.getLoc();
  unsigned TypeID = Lex.getUIntVal();
  Lex.Lex(); // eat LocalVarID;

  if (parseToken(lltok::equal, "expected '=' after name") ||
      parseToken(lltok::kw_type, "expected 'type' after '='"))
    return true;

  Type *Result = nullptr;
  if (parseStructDefinition(TypeLoc, "", NumberedTypes[TypeID], Result))
    return true;

  if (!isa<StructType>(Result)) {
    std::pair<Type*, LocTy> &Entry = NumberedTypes[TypeID];
    if (Entry.first)
      return error(TypeLoc, "non-struct types may not be recursive");
    Entry.first = Result;
    Entry.second = SMLoc();
  }

  return false;
}

/// toplevelentity
///   ::= LocalVar '=' 'type' type
bool LLParser::parseNamedType() {
  std::string Name = Lex.getStrVal();
  LocTy NameLoc = Lex.getLoc();
  Lex.Lex();  // eat LocalVar.

  if (parseToken(lltok::equal, "expected '=' after name") ||
      parseToken(lltok::kw_type, "expected 'type' after name"))
    return true;

  Type *Result = nullptr;
  if (parseStructDefinition(NameLoc, Name, NamedTypes[Name], Result))
    return true;

  if (!isa<StructType>(Result)) {
    std::pair<Type*, LocTy> &Entry = NamedTypes[Name];
    if (Entry.first)
      return error(NameLoc, "non-struct types may not be recursive");
    Entry.first = Result;
    Entry.second = SMLoc();
  }

  return false;
}

/// toplevelentity
///   ::= 'declare' FunctionHeader
bool LLParser::parseDeclare() {
  assert(Lex.getKind() == lltok::kw_declare);
  Lex.Lex();

  std::vector<std::pair<unsigned, MDNode *>> MDs;
  while (Lex.getKind() == lltok::MetadataVar) {
    unsigned MDK;
    MDNode *N;
    if (parseMetadataAttachment(MDK, N))
      return true;
    MDs.push_back({MDK, N});
  }

  Function *F;
  unsigned FunctionNumber = -1;
  SmallVector<unsigned> UnnamedArgNums;
  if (parseFunctionHeader(F, false, FunctionNumber, UnnamedArgNums))
    return true;
  for (auto &MD : MDs)
    F->addMetadata(MD.first, *MD.second);
  return false;
}

/// toplevelentity
///   ::= 'define' FunctionHeader (!dbg !56)* '{' ...
bool LLParser::parseDefine() {
  assert(Lex.getKind() == lltok::kw_define);
  Lex.Lex();

  Function *F;
  unsigned FunctionNumber = -1;
  SmallVector<unsigned> UnnamedArgNums;
  return parseFunctionHeader(F, true, FunctionNumber, UnnamedArgNums) ||
         parseOptionalFunctionMetadata(*F) ||
         parseFunctionBody(*F, FunctionNumber, UnnamedArgNums);
}

/// parseGlobalType
///   ::= 'constant'
///   ::= 'global'
bool LLParser::parseGlobalType(bool &IsConstant) {
  if (Lex.getKind() == lltok::kw_constant)
    IsConstant = true;
  else if (Lex.getKind() == lltok::kw_global)
    IsConstant = false;
  else {
    IsConstant = false;
    return tokError("expected 'global' or 'constant'");
  }
  Lex.Lex();
  return false;
}

bool LLParser::parseOptionalUnnamedAddr(
    GlobalVariable::UnnamedAddr &UnnamedAddr) {
  if (EatIfPresent(lltok::kw_unnamed_addr))
    UnnamedAddr = GlobalValue::UnnamedAddr::Global;
  else if (EatIfPresent(lltok::kw_local_unnamed_addr))
    UnnamedAddr = GlobalValue::UnnamedAddr::Local;
  else
    UnnamedAddr = GlobalValue::UnnamedAddr::None;
  return false;
}

/// parseUnnamedGlobal:
///   OptionalVisibility (ALIAS | IFUNC) ...
///   OptionalLinkage OptionalPreemptionSpecifier OptionalVisibility
///   OptionalDLLStorageClass
///                                                     ...   -> global variable
///   GlobalID '=' OptionalVisibility (ALIAS | IFUNC) ...
///   GlobalID '=' OptionalLinkage OptionalPreemptionSpecifier
///   OptionalVisibility
///                OptionalDLLStorageClass
///                                                     ...   -> global variable
bool LLParser::parseUnnamedGlobal() {
  unsigned VarID;
  std::string Name;
  LocTy NameLoc = Lex.getLoc();

  // Handle the GlobalID form.
  if (Lex.getKind() == lltok::GlobalID) {
    VarID = Lex.getUIntVal();
    if (checkValueID(NameLoc, "global", "@", NumberedVals.getNext(), VarID))
      return true;

    Lex.Lex(); // eat GlobalID;
    if (parseToken(lltok::equal, "expected '=' after name"))
      return true;
  } else {
    VarID = NumberedVals.getNext();
  }

  bool HasLinkage;
  unsigned Linkage, Visibility, DLLStorageClass;
  bool DSOLocal;
  GlobalVariable::ThreadLocalMode TLM;
  GlobalVariable::UnnamedAddr UnnamedAddr;
  if (parseOptionalLinkage(Linkage, HasLinkage, Visibility, DLLStorageClass,
                           DSOLocal) ||
      parseOptionalThreadLocal(TLM) || parseOptionalUnnamedAddr(UnnamedAddr))
    return true;

  switch (Lex.getKind()) {
  default:
    return parseGlobal(Name, VarID, NameLoc, Linkage, HasLinkage, Visibility,
                       DLLStorageClass, DSOLocal, TLM, UnnamedAddr);
  case lltok::kw_alias:
  case lltok::kw_ifunc:
    return parseAliasOrIFunc(Name, VarID, NameLoc, Linkage, Visibility,
                             DLLStorageClass, DSOLocal, TLM, UnnamedAddr);
  }
}

/// parseNamedGlobal:
///   GlobalVar '=' OptionalVisibility (ALIAS | IFUNC) ...
///   GlobalVar '=' OptionalLinkage OptionalPreemptionSpecifier
///                 OptionalVisibility OptionalDLLStorageClass
///                                                     ...   -> global variable
bool LLParser::parseNamedGlobal() {
  assert(Lex.getKind() == lltok::GlobalVar);
  LocTy NameLoc = Lex.getLoc();
  std::string Name = Lex.getStrVal();
  Lex.Lex();

  bool HasLinkage;
  unsigned Linkage, Visibility, DLLStorageClass;
  bool DSOLocal;
  GlobalVariable::ThreadLocalMode TLM;
  GlobalVariable::UnnamedAddr UnnamedAddr;
  if (parseToken(lltok::equal, "expected '=' in global variable") ||
      parseOptionalLinkage(Linkage, HasLinkage, Visibility, DLLStorageClass,
                           DSOLocal) ||
      parseOptionalThreadLocal(TLM) || parseOptionalUnnamedAddr(UnnamedAddr))
    return true;

  switch (Lex.getKind()) {
  default:
    return parseGlobal(Name, -1, NameLoc, Linkage, HasLinkage, Visibility,
                       DLLStorageClass, DSOLocal, TLM, UnnamedAddr);
  case lltok::kw_alias:
  case lltok::kw_ifunc:
    return parseAliasOrIFunc(Name, -1, NameLoc, Linkage, Visibility,
                             DLLStorageClass, DSOLocal, TLM, UnnamedAddr);
  }
}

bool LLParser::parseComdat() {
  assert(Lex.getKind() == lltok::ComdatVar);
  std::string Name = Lex.getStrVal();
  LocTy NameLoc = Lex.getLoc();
  Lex.Lex();

  if (parseToken(lltok::equal, "expected '=' here"))
    return true;

  if (parseToken(lltok::kw_comdat, "expected comdat keyword"))
    return tokError("expected comdat type");

  Comdat::SelectionKind SK;
  switch (Lex.getKind()) {
  default:
    return tokError("unknown selection kind");
  case lltok::kw_any:
    SK = Comdat::Any;
    break;
  case lltok::kw_exactmatch:
    SK = Comdat::ExactMatch;
    break;
  case lltok::kw_largest:
    SK = Comdat::Largest;
    break;
  case lltok::kw_nodeduplicate:
    SK = Comdat::NoDeduplicate;
    break;
  case lltok::kw_samesize:
    SK = Comdat::SameSize;
    break;
  }
  Lex.Lex();

  // See if the comdat was forward referenced, if so, use the comdat.
  Module::ComdatSymTabType &ComdatSymTab = M->getComdatSymbolTable();
  Module::ComdatSymTabType::iterator I = ComdatSymTab.find(Name);
  if (I != ComdatSymTab.end() && !ForwardRefComdats.erase(Name))
    return error(NameLoc, "redefinition of comdat '$" + Name + "'");

  Comdat *C;
  if (I != ComdatSymTab.end())
    C = &I->second;
  else
    C = M->getOrInsertComdat(Name);
  C->setSelectionKind(SK);

  return false;
}

// MDString:
//   ::= '!' STRINGCONSTANT
bool LLParser::parseMDString(MDString *&Result) {
  std::string Str;
  if (parseStringConstant(Str))
    return true;
  Result = MDString::get(Context, Str);
  return false;
}

// MDNode:
//   ::= '!' MDNodeNumber
bool LLParser::parseMDNodeID(MDNode *&Result) {
  // !{ ..., !42, ... }
  LocTy IDLoc = Lex.getLoc();
  unsigned MID = 0;
  if (parseUInt32(MID))
    return true;

  // If not a forward reference, just return it now.
  auto [It, Inserted] = NumberedMetadata.try_emplace(MID);
  if (!Inserted) {
    Result = It->second;
    return false;
  }

  // Otherwise, create MDNode forward reference.
  auto &FwdRef = ForwardRefMDNodes[MID];
  FwdRef = std::make_pair(MDTuple::getTemporary(Context, {}), IDLoc);

  Result = FwdRef.first.get();
  It->second.reset(Result);
  return false;
}

/// parseNamedMetadata:
///   !foo = !{ !1, !2 }
bool LLParser::parseNamedMetadata() {
  assert(Lex.getKind() == lltok::MetadataVar);
  std::string Name = Lex.getStrVal();
  Lex.Lex();

  if (parseToken(lltok::equal, "expected '=' here") ||
      parseToken(lltok::exclaim, "Expected '!' here") ||
      parseToken(lltok::lbrace, "Expected '{' here"))
    return true;

  NamedMDNode *NMD = M->getOrInsertNamedMetadata(Name);
  if (Lex.getKind() != lltok::rbrace)
    do {
      MDNode *N = nullptr;
      // parse DIExpressions inline as a special case. They are still MDNodes,
      // so they can still appear in named metadata. Remove this logic if they
      // become plain Metadata.
      if (Lex.getKind() == lltok::MetadataVar &&
          Lex.getStrVal() == "DIExpression") {
        if (parseDIExpression(N, /*IsDistinct=*/false))
          return true;
        // DIArgLists should only appear inline in a function, as they may
        // contain LocalAsMetadata arguments which require a function context.
      } else if (Lex.getKind() == lltok::MetadataVar &&
                 Lex.getStrVal() == "DIArgList") {
        return tokError("found DIArgList outside of function");
      } else if (parseToken(lltok::exclaim, "Expected '!' here") ||
                 parseMDNodeID(N)) {
        return true;
      }
      NMD->addOperand(N);
    } while (EatIfPresent(lltok::comma));

  return parseToken(lltok::rbrace, "expected end of metadata node");
}

/// parseStandaloneMetadata:
///   !42 = !{...}
bool LLParser::parseStandaloneMetadata() {
  assert(Lex.getKind() == lltok::exclaim);
  Lex.Lex();
  unsigned MetadataID = 0;

  MDNode *Init;
  if (parseUInt32(MetadataID) || parseToken(lltok::equal, "expected '=' here"))
    return true;

  // 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.
  auto FI = ForwardRefMDNodes.find(MetadataID);
  if (FI != ForwardRefMDNodes.end()) {
    auto *ToReplace = FI->second.first.get();
    // DIAssignID has its own special forward-reference "replacement" for
    // attachments (the temporary attachments are never actually attached).
    if (isa<DIAssignID>(Init)) {
      for (auto *Inst : TempDIAssignIDAttachments[ToReplace]) {
        assert(!Inst->getMetadata(LLVMContext::MD_DIAssignID) &&
               "Inst unexpectedly already has DIAssignID attachment");
        Inst->setMetadata(LLVMContext::MD_DIAssignID, Init);
      }
    }

    ToReplace->replaceAllUsesWith(Init);
    ForwardRefMDNodes.erase(FI);

    assert(NumberedMetadata[MetadataID] == Init && "Tracking VH didn't work");
  } else {
    auto [It, Inserted] = NumberedMetadata.try_emplace(MetadataID);
    if (!Inserted)
      return tokError("Metadata id is already used");
    It->second.reset(Init);
  }

  return false;
}

// Skips a single module summary entry.
bool LLParser::skipModuleSummaryEntry() {
  // Each module summary entry consists of a tag for the entry
  // type, followed by a colon, then the fields which may be surrounded by
  // nested sets of parentheses. The "tag:" looks like a Label. Once parsing
  // support is in place we will look for the tokens corresponding to the
  // expected tags.
  if (Lex.getKind() != lltok::kw_gv && Lex.getKind() != lltok::kw_module &&
      Lex.getKind() != lltok::kw_typeid && Lex.getKind() != lltok::kw_flags &&
      Lex.getKind() != lltok::kw_blockcount)
    return tokError(
        "Expected 'gv', 'module', 'typeid', 'flags' or 'blockcount' at the "
        "start of summary entry");
  if (Lex.getKind() == lltok::kw_flags)
    return parseSummaryIndexFlags();
  if (Lex.getKind() == lltok::kw_blockcount)
    return parseBlockCount();
  Lex.Lex();
  if (parseToken(lltok::colon, "expected ':' at start of summary entry") ||
      parseToken(lltok::lparen, "expected '(' at start of summary entry"))
    return true;
  // Now walk through the parenthesized entry, until the number of open
  // parentheses goes back down to 0 (the first '(' was parsed above).
  unsigned NumOpenParen = 1;
  do {
    switch (Lex.getKind()) {
    case lltok::lparen:
      NumOpenParen++;
      break;
    case lltok::rparen:
      NumOpenParen--;
      break;
    case lltok::Eof:
      return tokError("found end of file while parsing summary entry");
    default:
      // Skip everything in between parentheses.
      break;
    }
    Lex.Lex();
  } while (NumOpenParen > 0);
  return false;
}

/// SummaryEntry
///   ::= SummaryID '=' GVEntry | ModuleEntry | TypeIdEntry
bool LLParser::parseSummaryEntry() {
  assert(Lex.getKind() == lltok::SummaryID);
  unsigned SummaryID = Lex.getUIntVal();

  // For summary entries, colons should be treated as distinct tokens,
  // not an indication of the end of a label token.
  Lex.setIgnoreColonInIdentifiers(true);

  Lex.Lex();
  if (parseToken(lltok::equal, "expected '=' here"))
    return true;

  // If we don't have an index object, skip the summary entry.
  if (!Index)
    return skipModuleSummaryEntry();

  bool result = false;
  switch (Lex.getKind()) {
  case lltok::kw_gv:
    result = parseGVEntry(SummaryID);
    break;
  case lltok::kw_module:
    result = parseModuleEntry(SummaryID);
    break;
  case lltok::kw_typeid:
    result = parseTypeIdEntry(SummaryID);
    break;
  case lltok::kw_typeidCompatibleVTable:
    result = parseTypeIdCompatibleVtableEntry(SummaryID);
    break;
  case lltok::kw_flags:
    result = parseSummaryIndexFlags();
    break;
  case lltok::kw_blockcount:
    result = parseBlockCount();
    break;
  default:
    result = error(Lex.getLoc(), "unexpected summary kind");
    break;
  }
  Lex.setIgnoreColonInIdentifiers(false);
  return result;
}

static bool isValidVisibilityForLinkage(unsigned V, unsigned L) {
  return !GlobalValue::isLocalLinkage((GlobalValue::LinkageTypes)L) ||
         (GlobalValue::VisibilityTypes)V == GlobalValue::DefaultVisibility;
}
static bool isValidDLLStorageClassForLinkage(unsigned S, unsigned L) {
  return !GlobalValue::isLocalLinkage((GlobalValue::LinkageTypes)L) ||
         (GlobalValue::DLLStorageClassTypes)S == GlobalValue::DefaultStorageClass;
}

// If there was an explicit dso_local, update GV. In the absence of an explicit
// dso_local we keep the default value.
static void maybeSetDSOLocal(bool DSOLocal, GlobalValue &GV) {
  if (DSOLocal)
    GV.setDSOLocal(true);
}

/// parseAliasOrIFunc:
///   ::= GlobalVar '=' OptionalLinkage OptionalPreemptionSpecifier
///                     OptionalVisibility OptionalDLLStorageClass
///                     OptionalThreadLocal OptionalUnnamedAddr
///                     'alias|ifunc' AliaseeOrResolver SymbolAttrs*
///
/// AliaseeOrResolver
///   ::= TypeAndValue
///
/// SymbolAttrs
///   ::= ',' 'partition' StringConstant
///
/// Everything through OptionalUnnamedAddr has already been parsed.
///
bool LLParser::parseAliasOrIFunc(const std::string &Name, unsigned NameID,
                                 LocTy NameLoc, unsigned L, unsigned Visibility,
                                 unsigned DLLStorageClass, bool DSOLocal,
                                 GlobalVariable::ThreadLocalMode TLM,
                                 GlobalVariable::UnnamedAddr UnnamedAddr) {
  bool IsAlias;
  if (Lex.getKind() == lltok::kw_alias)
    IsAlias = true;
  else if (Lex.getKind() == lltok::kw_ifunc)
    IsAlias = false;
  else
    llvm_unreachable("Not an alias or ifunc!");
  Lex.Lex();

  GlobalValue::LinkageTypes Linkage = (GlobalValue::LinkageTypes) L;

  if(IsAlias && !GlobalAlias::isValidLinkage(Linkage))
    return error(NameLoc, "invalid linkage type for alias");

  if (!isValidVisibilityForLinkage(Visibility, L))
    return error(NameLoc,
                 "symbol with local linkage must have default visibility");

  if (!isValidDLLStorageClassForLinkage(DLLStorageClass, L))
    return error(NameLoc,
                 "symbol with local linkage cannot have a DLL storage class");

  Type *Ty;
  LocTy ExplicitTypeLoc = Lex.getLoc();
  if (parseType(Ty) ||
      parseToken(lltok::comma, "expected comma after alias or ifunc's type"))
    return true;

  Constant *Aliasee;
  LocTy AliaseeLoc = Lex.getLoc();
  if (Lex.getKind() != lltok::kw_bitcast &&
      Lex.getKind() != lltok::kw_getelementptr &&
      Lex.getKind() != lltok::kw_addrspacecast &&
      Lex.getKind() != lltok::kw_inttoptr) {
    if (parseGlobalTypeAndValue(Aliasee))
      return true;
  } else {
    // The bitcast dest type is not present, it is implied by the dest type.
    ValID ID;
    if (parseValID(ID, /*PFS=*/nullptr))
      return true;
    if (ID.Kind != ValID::t_Constant)
      return error(AliaseeLoc, "invalid aliasee");
    Aliasee = ID.ConstantVal;
  }

  Type *AliaseeType = Aliasee->getType();
  auto *PTy = dyn_cast<PointerType>(AliaseeType);
  if (!PTy)
    return error(AliaseeLoc, "An alias or ifunc must have pointer type");
  unsigned AddrSpace = PTy->getAddressSpace();

  GlobalValue *GVal = nullptr;

  // See if the alias was forward referenced, if so, prepare to replace the
  // forward reference.
  if (!Name.empty()) {
    auto I = ForwardRefVals.find(Name);
    if (I != ForwardRefVals.end()) {
      GVal = I->second.first;
      ForwardRefVals.erase(Name);
    } else if (M->getNamedValue(Name)) {
      return error(NameLoc, "redefinition of global '@" + Name + "'");
    }
  } else {
    auto I = ForwardRefValIDs.find(NameID);
    if (I != ForwardRefValIDs.end()) {
      GVal = I->second.first;
      ForwardRefValIDs.erase(I);
    }
  }

  // Okay, create the alias/ifunc but do not insert it into the module yet.
  std::unique_ptr<GlobalAlias> GA;
  std::unique_ptr<GlobalIFunc> GI;
  GlobalValue *GV;
  if (IsAlias) {
    GA.reset(GlobalAlias::create(Ty, AddrSpace, Linkage, Name, Aliasee,
                                 /*Parent=*/nullptr));
    GV = GA.get();
  } else {
    GI.reset(GlobalIFunc::create(Ty, AddrSpace, Linkage, Name, Aliasee,
                                 /*Parent=*/nullptr));
    GV = GI.get();
  }
  GV->setThreadLocalMode(TLM);
  GV->setVisibility((GlobalValue::VisibilityTypes)Visibility);
  GV->setDLLStorageClass((GlobalValue::DLLStorageClassTypes)DLLStorageClass);
  GV->setUnnamedAddr(UnnamedAddr);
  maybeSetDSOLocal(DSOLocal, *GV);

  // At this point we've parsed everything except for the IndirectSymbolAttrs.
  // Now parse them if there are any.
  while (Lex.getKind() == lltok::comma) {
    Lex.Lex();

    if (Lex.getKind() == lltok::kw_partition) {
      Lex.Lex();
      GV->setPartition(Lex.getStrVal());
      if (parseToken(lltok::StringConstant, "expected partition string"))
        return true;
    } else {
      return tokError("unknown alias or ifunc property!");
    }
  }

  if (Name.empty())
    NumberedVals.add(NameID, GV);

  if (GVal) {
    // Verify that types agree.
    if (GVal->getType() != GV->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.
    GVal->replaceAllUsesWith(GV);
    GVal->eraseFromParent();
  }

  // Insert into the module, we know its name won't collide now.
  if (IsAlias)
    M->insertAlias(GA.release());
  else
    M->insertIFunc(GI.release());
  assert(GV->getName() == Name && "Should not be a name conflict!");

  return false;
}

static bool isSanitizer(lltok::Kind Kind) {
  switch (Kind) {
  case lltok::kw_no_sanitize_address:
  case lltok::kw_no_sanitize_hwaddress:
  case lltok::kw_sanitize_memtag:
  case lltok::kw_sanitize_address_dyninit:
    return true;
  default:
    return false;
  }
}

bool LLParser::parseSanitizer(GlobalVariable *GV) {
  using SanitizerMetadata = GlobalValue::SanitizerMetadata;
  SanitizerMetadata Meta;
  if (GV->hasSanitizerMetadata())
    Meta = GV->getSanitizerMetadata();

  switch (Lex.getKind()) {
  case lltok::kw_no_sanitize_address:
    Meta.NoAddress = true;
    break;
  case lltok::kw_no_sanitize_hwaddress:
    Meta.NoHWAddress = true;
    break;
  case lltok::kw_sanitize_memtag:
    Meta.Memtag = true;
    break;
  case lltok::kw_sanitize_address_dyninit:
    Meta.IsDynInit = true;
    break;
  default:
    return tokError("non-sanitizer token passed to LLParser::parseSanitizer()");
  }
  GV->setSanitizerMetadata(Meta);
  Lex.Lex();
  return false;
}

/// parseGlobal
///   ::= GlobalVar '=' OptionalLinkage OptionalPreemptionSpecifier
///       OptionalVisibility OptionalDLLStorageClass
///       OptionalThreadLocal OptionalUnnamedAddr OptionalAddrSpace
///       OptionalExternallyInitialized GlobalType Type Const OptionalAttrs
///   ::= OptionalLinkage OptionalPreemptionSpecifier OptionalVisibility
///       OptionalDLLStorageClass OptionalThreadLocal OptionalUnnamedAddr
///       OptionalAddrSpace OptionalExternallyInitialized GlobalType Type
///       Const OptionalAttrs
///
/// Everything up to and including OptionalUnnamedAddr has been parsed
/// already.
///
bool LLParser::parseGlobal(const std::string &Name, unsigned NameID,
                           LocTy NameLoc, unsigned Linkage, bool HasLinkage,
                           unsigned Visibility, unsigned DLLStorageClass,
                           bool DSOLocal, GlobalVariable::ThreadLocalMode TLM,
                           GlobalVariable::UnnamedAddr UnnamedAddr) {
  if (!isValidVisibilityForLinkage(Visibility, Linkage))
    return error(NameLoc,
                 "symbol with local linkage must have default visibility");

  if (!isValidDLLStorageClassForLinkage(DLLStorageClass, Linkage))
    return error(NameLoc,
                 "symbol with local linkage cannot have a DLL storage class");

  unsigned AddrSpace;
  bool IsConstant, IsExternallyInitialized;
  LocTy IsExternallyInitializedLoc;
  LocTy TyLoc;

  Type *Ty = nullptr;
  if (parseOptionalAddrSpace(AddrSpace) ||
      parseOptionalToken(lltok::kw_externally_initialized,
                         IsExternallyInitialized,
                         &IsExternallyInitializedLoc) ||
      parseGlobalType(IsConstant) || parseType(Ty, TyLoc))
    return true;

  // If the linkage is specified and is external, then no initializer is
  // present.
  Constant *Init = nullptr;
  if (!HasLinkage ||
      !GlobalValue::isValidDeclarationLinkage(
          (GlobalValue::LinkageTypes)Linkage)) {
    if (parseGlobalValue(Ty, Init))
      return true;
  }

  if (Ty->isFunctionTy() || !PointerType::isValidElementType(Ty))
    return error(TyLoc, "invalid type for global variable");

  GlobalValue *GVal = nullptr;

  // See if the global was forward referenced, if so, use the global.
  if (!Name.empty()) {
    auto I = ForwardRefVals.find(Name);
    if (I != ForwardRefVals.end()) {
      GVal = I->second.first;
      ForwardRefVals.erase(I);
    } else if (M->getNamedValue(Name)) {
      return error(NameLoc, "redefinition of global '@" + Name + "'");
    }
  } else {
    // Handle @"", where a name is syntactically specified, but semantically
    // missing.
    if (NameID == (unsigned)-1)
      NameID = NumberedVals.getNext();

    auto I = ForwardRefValIDs.find(NameID);
    if (I != ForwardRefValIDs.end()) {
      GVal = I->second.first;
      ForwardRefValIDs.erase(I);
    }
  }

  GlobalVariable *GV = new GlobalVariable(
      *M, Ty, false, GlobalValue::ExternalLinkage, nullptr, Name, nullptr,
      GlobalVariable::NotThreadLocal, AddrSpace);

  if (Name.empty())
    NumberedVals.add(NameID, GV);

  // Set the parsed properties on the global.
  if (Init)
    GV->setInitializer(Init);
  GV->setConstant(IsConstant);
  GV->setLinkage((GlobalValue::LinkageTypes)Linkage);
  maybeSetDSOLocal(DSOLocal, *GV);
  GV->setVisibility((GlobalValue::VisibilityTypes)Visibility);
  GV->setDLLStorageClass((GlobalValue::DLLStorageClassTypes)DLLStorageClass);
  GV->setExternallyInitialized(IsExternallyInitialized);
  GV->setThreadLocalMode(TLM);
  GV->setUnnamedAddr(UnnamedAddr);

  if (GVal) {
    if (GVal->getAddressSpace() != AddrSpace)
      return error(
          TyLoc,
          "forward reference and definition of global have different types");

    GVal->replaceAllUsesWith(GV);
    GVal->eraseFromParent();
  }

  // parse attributes on the global.
  while (Lex.getKind() == lltok::comma) {
    Lex.Lex();

    if (Lex.getKind() == lltok::kw_section) {
      Lex.Lex();
      GV->setSection(Lex.getStrVal());
      if (parseToken(lltok::StringConstant, "expected global section string"))
        return true;
    } else if (Lex.getKind() == lltok::kw_partition) {
      Lex.Lex();
      GV->setPartition(Lex.getStrVal());
      if (parseToken(lltok::StringConstant, "expected partition string"))
        return true;
    } else if (Lex.getKind() == lltok::kw_align) {
      MaybeAlign Alignment;
      if (parseOptionalAlignment(Alignment))
        return true;
      if (Alignment)
        GV->setAlignment(*Alignment);
    } else if (Lex.getKind() == lltok::kw_code_model) {
      CodeModel::Model CodeModel;
      if (parseOptionalCodeModel(CodeModel))
        return true;
      GV->setCodeModel(CodeModel);
    } else if (Lex.getKind() == lltok::MetadataVar) {
      if (parseGlobalObjectMetadataAttachment(*GV))
        return true;
    } else if (isSanitizer(Lex.getKind())) {
      if (parseSanitizer(GV))
        return true;
    } else {
      Comdat *C;
      if (parseOptionalComdat(Name, C))
        return true;
      if (C)
        GV->setComdat(C);
      else
        return tokError("unknown global variable property!");
    }
  }

  AttrBuilder Attrs(M->getContext());
  LocTy BuiltinLoc;
  std::vector<unsigned> FwdRefAttrGrps;
  if (parseFnAttributeValuePairs(Attrs, FwdRefAttrGrps, false, BuiltinLoc))
    return true;
  if (Attrs.hasAttributes() || !FwdRefAttrGrps.empty()) {
    GV->setAttributes(AttributeSet::get(Context, Attrs));
    ForwardRefAttrGroups[GV] = FwdRefAttrGrps;
  }

  return false;
}

/// parseUnnamedAttrGrp
///   ::= 'attributes' AttrGrpID '=' '{' AttrValPair+ '}'
bool LLParser::parseUnnamedAttrGrp() {
  assert(Lex.getKind() == lltok::kw_attributes);
  LocTy AttrGrpLoc = Lex.getLoc();
  Lex.Lex();

  if (Lex.getKind() != lltok::AttrGrpID)
    return tokError("expected attribute group id");

  unsigned VarID = Lex.getUIntVal();
  std::vector<unsigned> unused;
  LocTy BuiltinLoc;
  Lex.Lex();

  if (parseToken(lltok::equal, "expected '=' here") ||
      parseToken(lltok::lbrace, "expected '{' here"))
    return true;

  auto R = NumberedAttrBuilders.find(VarID);
  if (R == NumberedAttrBuilders.end())
    R = NumberedAttrBuilders.emplace(VarID, AttrBuilder(M->getContext())).first;

  if (parseFnAttributeValuePairs(R->second, unused, true, BuiltinLoc) ||
      parseToken(lltok::rbrace, "expected end of attribute group"))
    return true;

  if (!R->second.hasAttributes())
    return error(AttrGrpLoc, "attribute group has no attributes");

  return false;
}

static Attribute::AttrKind tokenToAttribute(lltok::Kind Kind) {
  switch (Kind) {
#define GET_ATTR_NAMES
#define ATTRIBUTE_ENUM(ENUM_NAME, DISPLAY_NAME) \
  case lltok::kw_##DISPLAY_NAME: \
    return Attribute::ENUM_NAME;
#include "llvm/IR/Attributes.inc"
  default:
    return Attribute::None;
  }
}

bool LLParser::parseEnumAttribute(Attribute::AttrKind Attr, AttrBuilder &B,
                                  bool InAttrGroup) {
  if (Attribute::isTypeAttrKind(Attr))
    return parseRequiredTypeAttr(B, Lex.getKind(), Attr);

  switch (Attr) {
  case Attribute::Alignment: {
    MaybeAlign Alignment;
    if (InAttrGroup) {
      uint32_t Value = 0;
      Lex.Lex();
      if (parseToken(lltok::equal, "expected '=' here") || parseUInt32(Value))
        return true;
      Alignment = Align(Value);
    } else {
      if (parseOptionalAlignment(Alignment, true))
        return true;
    }
    B.addAlignmentAttr(Alignment);
    return false;
  }
  case Attribute::StackAlignment: {
    unsigned Alignment;
    if (InAttrGroup) {
      Lex.Lex();
      if (parseToken(lltok::equal, "expected '=' here") ||
          parseUInt32(Alignment))
        return true;
    } else {
      if (parseOptionalStackAlignment(Alignment))
        return true;
    }
    B.addStackAlignmentAttr(Alignment);
    return false;
  }
  case Attribute::AllocSize: {
    unsigned ElemSizeArg;
    std::optional<unsigned> NumElemsArg;
    if (parseAllocSizeArguments(ElemSizeArg, NumElemsArg))
      return true;
    B.addAllocSizeAttr(ElemSizeArg, NumElemsArg);
    return false;
  }
  case Attribute::VScaleRange: {
    unsigned MinValue, MaxValue;
    if (parseVScaleRangeArguments(MinValue, MaxValue))
      return true;
    B.addVScaleRangeAttr(MinValue,
                         MaxValue > 0 ? MaxValue : std::optional<unsigned>());
    return false;
  }
  case Attribute::Dereferenceable: {
    uint64_t Bytes;
    if (parseOptionalDerefAttrBytes(lltok::kw_dereferenceable, Bytes))
      return true;
    B.addDereferenceableAttr(Bytes);
    return false;
  }
  case Attribute::DereferenceableOrNull: {
    uint64_t Bytes;
    if (parseOptionalDerefAttrBytes(lltok::kw_dereferenceable_or_null, Bytes))
      return true;
    B.addDereferenceableOrNullAttr(Bytes);
    return false;
  }
  case Attribute::UWTable: {
    UWTableKind Kind;
    if (parseOptionalUWTableKind(Kind))
      return true;
    B.addUWTableAttr(Kind);
    return false;
  }
  case Attribute::AllocKind: {
    AllocFnKind Kind = AllocFnKind::Unknown;
    if (parseAllocKind(Kind))
      return true;
    B.addAllocKindAttr(Kind);
    return false;
  }
  case Attribute::Memory: {
    std::optional<MemoryEffects> ME = parseMemoryAttr();
    if (!ME)
      return true;
    B.addMemoryAttr(*ME);
    return false;
  }
  case Attribute::NoFPClass: {
    if (FPClassTest NoFPClass =
            static_cast<FPClassTest>(parseNoFPClassAttr())) {
      B.addNoFPClassAttr(NoFPClass);
      return false;
    }

    return true;
  }
  case Attribute::Range:
    return parseRangeAttr(B);
  case Attribute::Initializes:
    return parseInitializesAttr(B);
  case Attribute::Captures:
    return parseCapturesAttr(B);
  default:
    B.addAttribute(Attr);
    Lex.Lex();
    return false;
  }
}

static bool upgradeMemoryAttr(MemoryEffects &ME, lltok::Kind Kind) {
  switch (Kind) {
  case lltok::kw_readnone:
    ME &= MemoryEffects::none();
    return true;
  case lltok::kw_readonly:
    ME &= MemoryEffects::readOnly();
    return true;
  case lltok::kw_writeonly:
    ME &= MemoryEffects::writeOnly();
    return true;
  case lltok::kw_argmemonly:
    ME &= MemoryEffects::argMemOnly();
    return true;
  case lltok::kw_inaccessiblememonly:
    ME &= MemoryEffects::inaccessibleMemOnly();
    return true;
  case lltok::kw_inaccessiblemem_or_argmemonly:
    ME &= MemoryEffects::inaccessibleOrArgMemOnly();
    return true;
  default:
    return false;
  }
}

/// parseFnAttributeValuePairs
///   ::= <attr> | <attr> '=' <value>
bool LLParser::parseFnAttributeValuePairs(AttrBuilder &B,
                                          std::vector<unsigned> &FwdRefAttrGrps,
                                          bool InAttrGrp, LocTy &BuiltinLoc) {
  bool HaveError = false;

  B.clear();

  MemoryEffects ME = MemoryEffects::unknown();
  while (true) {
    lltok::Kind Token = Lex.getKind();
    if (Token == lltok::rbrace)
      break; // Finished.

    if (Token == lltok::StringConstant) {
      if (parseStringAttribute(B))
        return true;
      continue;
    }

    if (Token == lltok::AttrGrpID) {
      // Allow a function to reference an attribute group:
      //
      //   define void @foo() #1 { ... }
      if (InAttrGrp) {
        HaveError |= error(
            Lex.getLoc(),
            "cannot have an attribute group reference in an attribute group");
      } else {
        // Save the reference to the attribute group. We'll fill it in later.
        FwdRefAttrGrps.push_back(Lex.getUIntVal());
      }
      Lex.Lex();
      continue;
    }

    SMLoc Loc = Lex.getLoc();
    if (Token == lltok::kw_builtin)
      BuiltinLoc = Loc;

    if (upgradeMemoryAttr(ME, Token)) {
      Lex.Lex();
      continue;
    }

    Attribute::AttrKind Attr = tokenToAttribute(Token);
    if (Attr == Attribute::None) {
      if (!InAttrGrp)
        break;
      return error(Lex.getLoc(), "unterminated attribute group");
    }

    if (parseEnumAttribute(Attr, B, InAttrGrp))
      return true;

    // As a hack, we allow function alignment to be initially parsed as an
    // attribute on a function declaration/definition or added to an attribute
    // group and later moved to the alignment field.
    if (!Attribute::canUseAsFnAttr(Attr) && Attr != Attribute::Alignment)
      HaveError |= error(Loc, "this attribute does not apply to functions");
  }

  if (ME != MemoryEffects::unknown())
    B.addMemoryAttr(ME);
  return HaveError;
}

//===----------------------------------------------------------------------===//
// GlobalValue Reference/Resolution Routines.
//===----------------------------------------------------------------------===//

static inline GlobalValue *createGlobalFwdRef(Module *M, PointerType *PTy) {
  // The used global type does not matter. We will later RAUW it with a
  // global/function of the correct type.
  return new GlobalVariable(*M, Type::getInt8Ty(M->getContext()), false,
                            GlobalValue::ExternalWeakLinkage, nullptr, "",
                            nullptr, GlobalVariable::NotThreadLocal,
                            PTy->getAddressSpace());
}

Value *LLParser::checkValidVariableType(LocTy Loc, const Twine &Name, Type *Ty,
                                        Value *Val) {
  Type *ValTy = Val->getType();
  if (ValTy == Ty)
    return Val;
  if (Ty->isLabelTy())
    error(Loc, "'" + Name + "' is not a basic block");
  else
    error(Loc, "'" + Name + "' defined with type '" +
                   getTypeString(Val->getType()) + "' but expected '" +
                   getTypeString(Ty) + "'");
  return nullptr;
}

/// 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.
GlobalValue *LLParser::getGlobalVal(const std::string &Name, Type *Ty,
                                    LocTy Loc) {
  PointerType *PTy = dyn_cast<PointerType>(Ty);
  if (!PTy) {
    error(Loc, "global variable reference must have pointer type");
    return nullptr;
  }

  // Look this name up in the normal function symbol table.
  GlobalValue *Val =
    cast_or_null<GlobalValue>(M->getValueSymbolTable().lookup(Name));

  // If this is a forward reference for the value, see if we already created a
  // forward ref record.
  if (!Val) {
    auto I = ForwardRefVals.find(Name);
    if (I != ForwardRefVals.end())
      Val = I->second.first;
  }

  // If we have the value in the symbol table or fwd-ref table, return it.
  if (Val)
    return cast_or_null<GlobalValue>(
        checkValidVariableType(Loc, "@" + Name, Ty, Val));

  // Otherwise, create a new forward reference for this value and remember it.
  GlobalValue *FwdVal = createGlobalFwdRef(M, PTy);
  ForwardRefVals[Name] = std::make_pair(FwdVal, Loc);
  return FwdVal;
}

GlobalValue *LLParser::getGlobalVal(unsigned ID, Type *Ty, LocTy Loc) {
  PointerType *PTy = dyn_cast<PointerType>(Ty);
  if (!PTy) {
    error(Loc, "global variable reference must have pointer type");
    return nullptr;
  }

  GlobalValue *Val = NumberedVals.get(ID);

  // If this is a forward reference for the value, see if we already created a
  // forward ref record.
  if (!Val) {
    auto I = ForwardRefValIDs.find(ID);
    if (I != ForwardRefValIDs.end())
      Val = I->second.first;
  }

  // If we have the value in the symbol table or fwd-ref table, return it.
  if (Val)
    return cast_or_null<GlobalValue>(
        checkValidVariableType(Loc, "@" + Twine(ID), Ty, Val));

  // Otherwise, create a new forward reference for this value and remember it.
  GlobalValue *FwdVal = createGlobalFwdRef(M, PTy);
  ForwardRefValIDs[ID] = std::make_pair(FwdVal, Loc);
  return FwdVal;
}

//===----------------------------------------------------------------------===//
// Comdat Reference/Resolution Routines.
//===----------------------------------------------------------------------===//

Comdat *LLParser::getComdat(const std::string &Name, LocTy Loc) {
  // Look this name up in the comdat symbol table.
  Module::ComdatSymTabType &ComdatSymTab = M->getComdatSymbolTable();
  Module::ComdatSymTabType::iterator I = ComdatSymTab.find(Name);
  if (I != ComdatSymTab.end())
    return &I->second;

  // Otherwise, create a new forward reference for this value and remember it.
  Comdat *C = M->getOrInsertComdat(Name);
  ForwardRefComdats[Name] = Loc;
  return C;
}

//===----------------------------------------------------------------------===//
// Helper Routines.
//===----------------------------------------------------------------------===//

/// parseToken - If the current token has the specified kind, eat it and return
/// success.  Otherwise, emit the specified error and return failure.
bool LLParser::parseToken(lltok::Kind T, const char *ErrMsg) {
  if (Lex.getKind() != T)
    return tokError(ErrMsg);
  Lex.Lex();
  return false;
}

/// parseStringConstant
///   ::= StringConstant
bool LLParser::parseStringConstant(std::string &Result) {
  if (Lex.getKind() != lltok::StringConstant)
    return tokError("expected string constant");
  Result = Lex.getStrVal();
  Lex.Lex();
  return false;
}

/// parseUInt32
///   ::= uint32
bool LLParser::parseUInt32(uint32_t &Val) {
  if (Lex.getKind() != lltok::APSInt || Lex.getAPSIntVal().isSigned())
    return tokError("expected integer");
  uint64_t Val64 = Lex.getAPSIntVal().getLimitedValue(0xFFFFFFFFULL+1);
  if (Val64 != unsigned(Val64))
    return tokError("expected 32-bit integer (too large)");
  Val = Val64;
  Lex.Lex();
  return false;
}

/// parseUInt64
///   ::= uint64
bool LLParser::parseUInt64(uint64_t &Val) {
  if (Lex.getKind() != lltok::APSInt || Lex.getAPSIntVal().isSigned())
    return tokError("expected integer");
  Val = Lex.getAPSIntVal().getLimitedValue();
  Lex.Lex();
  return false;
}

/// parseTLSModel
///   := 'localdynamic'
///   := 'initialexec'
///   := 'localexec'
bool LLParser::parseTLSModel(GlobalVariable::ThreadLocalMode &TLM) {
  switch (Lex.getKind()) {
    default:
      return tokError("expected localdynamic, initialexec or localexec");
    case lltok::kw_localdynamic:
      TLM = GlobalVariable::LocalDynamicTLSModel;
      break;
    case lltok::kw_initialexec:
      TLM = GlobalVariable::InitialExecTLSModel;
      break;
    case lltok::kw_localexec:
      TLM = GlobalVariable::LocalExecTLSModel;
      break;
  }

  Lex.Lex();
  return false;
}

/// parseOptionalThreadLocal
///   := /*empty*/
///   := 'thread_local'
///   := 'thread_local' '(' tlsmodel ')'
bool LLParser::parseOptionalThreadLocal(GlobalVariable::ThreadLocalMode &TLM) {
  TLM = GlobalVariable::NotThreadLocal;
  if (!EatIfPresent(lltok::kw_thread_local))
    return false;

  TLM = GlobalVariable::GeneralDynamicTLSModel;
  if (Lex.getKind() == lltok::lparen) {
    Lex.Lex();
    return parseTLSModel(TLM) ||
           parseToken(lltok::rparen, "expected ')' after thread local model");
  }
  return false;
}

/// parseOptionalAddrSpace
///   := /*empty*/
///   := 'addrspace' '(' uint32 ')'
bool LLParser::parseOptionalAddrSpace(unsigned &AddrSpace, unsigned DefaultAS) {
  AddrSpace = DefaultAS;
  if (!EatIfPresent(lltok::kw_addrspace))
    return false;

  auto ParseAddrspaceValue = [&](unsigned &AddrSpace) -> bool {
    if (Lex.getKind() == lltok::StringConstant) {
      auto AddrSpaceStr = Lex.getStrVal();
      if (AddrSpaceStr == "A") {
        AddrSpace = M->getDataLayout().getAllocaAddrSpace();
      } else if (AddrSpaceStr == "G") {
        AddrSpace = M->getDataLayout().getDefaultGlobalsAddressSpace();
      } else if (AddrSpaceStr == "P") {
        AddrSpace = M->getDataLayout().getProgramAddressSpace();
      } else {
        return tokError("invalid symbolic addrspace '" + AddrSpaceStr + "'");
      }
      Lex.Lex();
      return false;
    }
    if (Lex.getKind() != lltok::APSInt)
      return tokError("expected integer or string constant");
    SMLoc Loc = Lex.getLoc();
    if (parseUInt32(AddrSpace))
      return true;
    if (!isUInt<24>(AddrSpace))
      return error(Loc, "invalid address space, must be a 24-bit integer");
    return false;
  };

  return parseToken(lltok::lparen, "expected '(' in address space") ||
         ParseAddrspaceValue(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;
}

/// Parse a potentially empty list of parameter or return attributes.
bool LLParser::parseOptionalParamOrReturnAttrs(AttrBuilder &B, bool IsParam) {
  bool HaveError = false;

  B.clear();

  while (true) {
    lltok::Kind Token = Lex.getKind();
    if (Token == lltok::StringConstant) {
      if (parseStringAttribute(B))
        return true;
      continue;
    }

    if (Token == lltok::kw_nocapture) {
      Lex.Lex();
      B.addCapturesAttr(CaptureInfo::none());
      continue;
    }

    SMLoc Loc = Lex.getLoc();
    Attribute::AttrKind Attr = tokenToAttribute(Token);
    if (Attr == Attribute::None)
      return HaveError;

    if (parseEnumAttribute(Attr, B, /* InAttrGroup */ false))
      return true;

    if (IsParam && !Attribute::canUseAsParamAttr(Attr))
      HaveError |= error(Loc, "this attribute does not apply to parameters");
    if (!IsParam && !Attribute::canUseAsRetAttr(Attr))
      HaveError |= error(Loc, "this attribute does not apply to return values");
  }
}

static unsigned parseOptionalLinkageAux(lltok::Kind Kind, bool &HasLinkage) {
  HasLinkage = true;
  switch (Kind) {
  default:
    HasLinkage = false;
    return GlobalValue::ExternalLinkage;
  case lltok::kw_private:
    return GlobalValue::PrivateLinkage;
  case lltok::kw_internal:
    return GlobalValue::InternalLinkage;
  case lltok::kw_weak:
    return GlobalValue::WeakAnyLinkage;
  case lltok::kw_weak_odr:
    return GlobalValue::WeakODRLinkage;
  case lltok::kw_linkonce:
    return GlobalValue::LinkOnceAnyLinkage;
  case lltok::kw_linkonce_odr:
    return GlobalValue::LinkOnceODRLinkage;
  case lltok::kw_available_externally:
    return GlobalValue::AvailableExternallyLinkage;
  case lltok::kw_appending:
    return GlobalValue::AppendingLinkage;
  case lltok::kw_common:
    return GlobalValue::CommonLinkage;
  case lltok::kw_extern_weak:
    return GlobalValue::ExternalWeakLinkage;
  case lltok::kw_external:
    return GlobalValue::ExternalLinkage;
  }
}

/// parseOptionalLinkage
///   ::= /*empty*/
///   ::= 'private'
///   ::= 'internal'
///   ::= 'weak'
///   ::= 'weak_odr'
///   ::= 'linkonce'
///   ::= 'linkonce_odr'
///   ::= 'available_externally'
///   ::= 'appending'
///   ::= 'common'
///   ::= 'extern_weak'
///   ::= 'external'
bool LLParser::parseOptionalLinkage(unsigned &Res, bool &HasLinkage,
                                    unsigned &Visibility,
                                    unsigned &DLLStorageClass, bool &DSOLocal) {
  Res = parseOptionalLinkageAux(Lex.getKind(), HasLinkage);
  if (HasLinkage)
    Lex.Lex();
  parseOptionalDSOLocal(DSOLocal);
  parseOptionalVisibility(Visibility);
  parseOptionalDLLStorageClass(DLLStorageClass);

  if (DSOLocal && DLLStorageClass == GlobalValue::DLLImportStorageClass) {
    return error(Lex.getLoc(), "dso_location and DLL-StorageClass mismatch");
  }

  return false;
}

void LLParser::parseOptionalDSOLocal(bool &DSOLocal) {
  switch (Lex.getKind()) {
  default:
    DSOLocal = false;
    break;
  case lltok::kw_dso_local:
    DSOLocal = true;
    Lex.Lex();
    break;
  case lltok::kw_dso_preemptable:
    DSOLocal = false;
    Lex.Lex();
    break;
  }
}

/// parseOptionalVisibility
///   ::= /*empty*/
///   ::= 'default'
///   ::= 'hidden'
///   ::= 'protected'
///
void LLParser::parseOptionalVisibility(unsigned &Res) {
  switch (Lex.getKind()) {
  default:
    Res = GlobalValue::DefaultVisibility;
    return;
  case lltok::kw_default:
    Res = GlobalValue::DefaultVisibility;
    break;
  case lltok::kw_hidden:
    Res = GlobalValue::HiddenVisibility;
    break;
  case lltok::kw_protected:
    Res = GlobalValue::ProtectedVisibility;
    break;
  }
  Lex.Lex();
}

bool LLParser::parseOptionalImportType(lltok::Kind Kind,
                                       GlobalValueSummary::ImportKind &Res) {
  switch (Kind) {
  default:
    return tokError("unknown import kind. Expect definition or declaration.");
  case lltok::kw_definition:
    Res = GlobalValueSummary::Definition;
    return false;
  case lltok::kw_declaration:
    Res = GlobalValueSummary::Declaration;
    return false;
  }
}

/// parseOptionalDLLStorageClass
///   ::= /*empty*/
///   ::= 'dllimport'
///   ::= 'dllexport'
///
void LLParser::parseOptionalDLLStorageClass(unsigned &Res) {
  switch (Lex.getKind()) {
  default:
    Res = GlobalValue::DefaultStorageClass;
    return;
  case lltok::kw_dllimport:
    Res = GlobalValue::DLLImportStorageClass;
    break;
  case lltok::kw_dllexport:
    Res = GlobalValue::DLLExportStorageClass;
    break;
  }
  Lex.Lex();
}

/// parseOptionalCallingConv
///   ::= /*empty*/
///   ::= 'ccc'
///   ::= 'fastcc'
///   ::= 'intel_ocl_bicc'
///   ::= 'coldcc'
///   ::= 'cfguard_checkcc'
///   ::= 'x86_stdcallcc'
///   ::= 'x86_fastcallcc'
///   ::= 'x86_thiscallcc'
///   ::= 'x86_vectorcallcc'
///   ::= 'arm_apcscc'
///   ::= 'arm_aapcscc'
///   ::= 'arm_aapcs_vfpcc'
///   ::= 'aarch64_vector_pcs'
///   ::= 'aarch64_sve_vector_pcs'
///   ::= 'aarch64_sme_preservemost_from_x0'
///   ::= 'aarch64_sme_preservemost_from_x1'
///   ::= 'aarch64_sme_preservemost_from_x2'
///   ::= 'msp430_intrcc'
///   ::= 'avr_intrcc'
///   ::= 'avr_signalcc'
///   ::= 'ptx_kernel'
///   ::= 'ptx_device'
///   ::= 'spir_func'
///   ::= 'spir_kernel'
///   ::= 'x86_64_sysvcc'
///   ::= 'win64cc'
///   ::= 'anyregcc'
///   ::= 'preserve_mostcc'
///   ::= 'preserve_allcc'
///   ::= 'preserve_nonecc'
///   ::= 'ghccc'
///   ::= 'swiftcc'
///   ::= 'swifttailcc'
///   ::= 'x86_intrcc'
///   ::= 'hhvmcc'
///   ::= 'hhvm_ccc'
///   ::= 'cxx_fast_tlscc'
///   ::= 'amdgpu_vs'
///   ::= 'amdgpu_ls'
///   ::= 'amdgpu_hs'
///   ::= 'amdgpu_es'
///   ::= 'amdgpu_gs'
///   ::= 'amdgpu_ps'
///   ::= 'amdgpu_cs'
///   ::= 'amdgpu_cs_chain'
///   ::= 'amdgpu_cs_chain_preserve'
///   ::= 'amdgpu_kernel'
///   ::= 'tailcc'
///   ::= 'm68k_rtdcc'
///   ::= 'graalcc'
///   ::= 'riscv_vector_cc'
///   ::= 'riscv_vls_cc'
///   ::= 'cc' UINT
///
bool LLParser::parseOptionalCallingConv(unsigned &CC) {
  switch (Lex.getKind()) {
  default:                       CC = CallingConv::C; return false;
  case lltok::kw_ccc:            CC = CallingConv::C; break;
  case lltok::kw_fastcc:         CC = CallingConv::Fast; break;
  case lltok::kw_coldcc:         CC = CallingConv::Cold; break;
  case lltok::kw_cfguard_checkcc: CC = CallingConv::CFGuard_Check; break;
  case lltok::kw_x86_stdcallcc:  CC = CallingConv::X86_StdCall; break;
  case lltok::kw_x86_fastcallcc: CC = CallingConv::X86_FastCall; break;
  case lltok::kw_x86_regcallcc:  CC = CallingConv::X86_RegCall; break;
  case lltok::kw_x86_thiscallcc: CC = CallingConv::X86_ThisCall; break;
  case lltok::kw_x86_vectorcallcc:CC = CallingConv::X86_VectorCall; break;
  case lltok::kw_arm_apcscc:     CC = CallingConv::ARM_APCS; break;
  case lltok::kw_arm_aapcscc:    CC = CallingConv::ARM_AAPCS; break;
  case lltok::kw_arm_aapcs_vfpcc:CC = CallingConv::ARM_AAPCS_VFP; break;
  case lltok::kw_aarch64_vector_pcs:CC = CallingConv::AArch64_VectorCall; break;
  case lltok::kw_aarch64_sve_vector_pcs:
    CC = CallingConv::AArch64_SVE_VectorCall;
    break;
  case lltok::kw_aarch64_sme_preservemost_from_x0:
    CC = CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0;
    break;
  case lltok::kw_aarch64_sme_preservemost_from_x1:
    CC = CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X1;
    break;
  case lltok::kw_aarch64_sme_preservemost_from_x2:
    CC = CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2;
    break;
  case lltok::kw_msp430_intrcc:  CC = CallingConv::MSP430_INTR; break;
  case lltok::kw_avr_intrcc:     CC = CallingConv::AVR_INTR; break;
  case lltok::kw_avr_signalcc:   CC = CallingConv::AVR_SIGNAL; break;
  case lltok::kw_ptx_kernel:     CC = CallingConv::PTX_Kernel; break;
  case lltok::kw_ptx_device:     CC = CallingConv::PTX_Device; break;
  case lltok::kw_spir_kernel:    CC = CallingConv::SPIR_KERNEL; break;
  case lltok::kw_spir_func:      CC = CallingConv::SPIR_FUNC; break;
  case lltok::kw_intel_ocl_bicc: CC = CallingConv::Intel_OCL_BI; break;
  case lltok::kw_x86_64_sysvcc:  CC = CallingConv::X86_64_SysV; break;
  case lltok::kw_win64cc:        CC = CallingConv::Win64; break;
  case lltok::kw_anyregcc:       CC = CallingConv::AnyReg; break;
  case lltok::kw_preserve_mostcc:CC = CallingConv::PreserveMost; break;
  case lltok::kw_preserve_allcc: CC = CallingConv::PreserveAll; break;
  case lltok::kw_preserve_nonecc:CC = CallingConv::PreserveNone; break;
  case lltok::kw_ghccc:          CC = CallingConv::GHC; break;
  case lltok::kw_swiftcc:        CC = CallingConv::Swift; break;
  case lltok::kw_swifttailcc:    CC = CallingConv::SwiftTail; break;
  case lltok::kw_x86_intrcc:     CC = CallingConv::X86_INTR; break;
  case lltok::kw_hhvmcc:
    CC = CallingConv::DUMMY_HHVM;
    break;
  case lltok::kw_hhvm_ccc:
    CC = CallingConv::DUMMY_HHVM_C;
    break;
  case lltok::kw_cxx_fast_tlscc: CC = CallingConv::CXX_FAST_TLS; break;
  case lltok::kw_amdgpu_vs:      CC = CallingConv::AMDGPU_VS; break;
  case lltok::kw_amdgpu_gfx:     CC = CallingConv::AMDGPU_Gfx; break;
  case lltok::kw_amdgpu_ls:      CC = CallingConv::AMDGPU_LS; break;
  case lltok::kw_amdgpu_hs:      CC = CallingConv::AMDGPU_HS; break;
  case lltok::kw_amdgpu_es:      CC = CallingConv::AMDGPU_ES; break;
  case lltok::kw_amdgpu_gs:      CC = CallingConv::AMDGPU_GS; break;
  case lltok::kw_amdgpu_ps:      CC = CallingConv::AMDGPU_PS; break;
  case lltok::kw_amdgpu_cs:      CC = CallingConv::AMDGPU_CS; break;
  case lltok::kw_amdgpu_cs_chain:
    CC = CallingConv::AMDGPU_CS_Chain;
    break;
  case lltok::kw_amdgpu_cs_chain_preserve:
    CC = CallingConv::AMDGPU_CS_ChainPreserve;
    break;
  case lltok::kw_amdgpu_kernel:  CC = CallingConv::AMDGPU_KERNEL; break;
  case lltok::kw_amdgpu_gfx_whole_wave:
    CC = CallingConv::AMDGPU_Gfx_WholeWave;
    break;
  case lltok::kw_tailcc:         CC = CallingConv::Tail; break;
  case lltok::kw_m68k_rtdcc:     CC = CallingConv::M68k_RTD; break;
  case lltok::kw_graalcc:        CC = CallingConv::GRAAL; break;
  case lltok::kw_riscv_vector_cc:
    CC = CallingConv::RISCV_VectorCall;
    break;
  case lltok::kw_riscv_vls_cc:
    // Default ABI_VLEN
    CC = CallingConv::RISCV_VLSCall_128;
    Lex.Lex();
    if (!EatIfPresent(lltok::lparen))
      break;
    uint32_t ABIVlen;
    if (parseUInt32(ABIVlen) || !EatIfPresent(lltok::rparen))
      return true;
    switch (ABIVlen) {
    default:
      return tokError("unknown RISC-V ABI VLEN");
#define CC_VLS_CASE(ABIVlen)                                                   \
  case ABIVlen:                                                                \
    CC = CallingConv::RISCV_VLSCall_##ABIVlen;                                 \
    break;
      CC_VLS_CASE(32)
      CC_VLS_CASE(64)
      CC_VLS_CASE(128)
      CC_VLS_CASE(256)
      CC_VLS_CASE(512)
      CC_VLS_CASE(1024)
      CC_VLS_CASE(2048)
      CC_VLS_CASE(4096)
      CC_VLS_CASE(8192)
      CC_VLS_CASE(16384)
      CC_VLS_CASE(32768)
      CC_VLS_CASE(65536)
#undef CC_VLS_CASE
    }
    return false;
  case lltok::kw_cc: {
      Lex.Lex();
      return parseUInt32(CC);
    }
  }

  Lex.Lex();
  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) {
  do {
    if (Lex.getKind() != lltok::MetadataVar)
      return tokError("expected metadata after comma");

    unsigned MDK;
    MDNode *N;
    if (parseMetadataAttachment(MDK, N))
      return true;

    if (MDK == LLVMContext::MD_DIAssignID)
      TempDIAssignIDAttachments[N].push_back(&Inst);
    else
      Inst.setMetadata(MDK, N);

    if (MDK == LLVMContext::MD_tbaa)
      InstsWithTBAATag.push_back(&Inst);

    // If this is the end of the list, we're done.
  } while (EatIfPresent(lltok::comma));
  return false;
}

/// parseGlobalObjectMetadataAttachment
///   ::= !dbg !57
bool LLParser::parseGlobalObjectMetadataAttachment(GlobalObject &GO) {
  unsigned MDK;
  MDNode *N;
  if (parseMetadataAttachment(MDK, N))
    return true;

  GO.addMetadata(MDK, *N);
  return false;
}

/// parseOptionalFunctionMetadata
///   ::= (!dbg !57)*
bool LLParser::parseOptionalFunctionMetadata(Function &F) {
  while (Lex.getKind() == lltok::MetadataVar)
    if (parseGlobalObjectMetadataAttachment(F))
      return true;
  return false;
}

/// parseOptionalAlignment
///   ::= /* empty */
///   ::= 'align' 4
bool LLParser::parseOptionalAlignment(MaybeAlign &Alignment, bool AllowParens) {
  Alignment = std::nullopt;
  if (!EatIfPresent(lltok::kw_align))
    return false;
  LocTy AlignLoc = Lex.getLoc();
  uint64_t Value = 0;

  LocTy ParenLoc = Lex.getLoc();
  bool HaveParens = false;
  if (AllowParens) {
    if (EatIfPresent(lltok::lparen))
      HaveParens = true;
  }

  if (parseUInt64(Value))
    return true;

  if (HaveParens && !EatIfPresent(lltok::rparen))
    return error(ParenLoc, "expected ')'");

  if (!isPowerOf2_64(Value))
    return error(AlignLoc, "alignment is not a power of two");
  if (Value > Value::MaximumAlignment)
    return error(AlignLoc, "huge alignments are not supported yet");
  Alignment = Align(Value);
  return false;
}

/// parseOptionalCodeModel
///   ::= /* empty */
///   ::= 'code_model' "large"
bool LLParser::parseOptionalCodeModel(CodeModel::Model &model) {
  Lex.Lex();
  auto StrVal = Lex.getStrVal();
  auto ErrMsg = "expected global code model string";
  if (StrVal == "tiny")
    model = CodeModel::Tiny;
  else if (StrVal == "small")
    model = CodeModel::Small;
  else if (StrVal == "kernel")
    model = CodeModel::Kernel;
  else if (StrVal == "medium")
    model = CodeModel::Medium;
  else if (StrVal == "large")
    model = CodeModel::Large;
  else
    return tokError(ErrMsg);
  if (parseToken(lltok::StringConstant, ErrMsg))
    return true;
  return false;
}

/// parseOptionalDerefAttrBytes
///   ::= /* empty */
///   ::= 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(AttrKind))
    return false;
  LocTy ParenLoc = Lex.getLoc();
  if (!EatIfPresent(lltok::lparen))
    return error(ParenLoc, "expected '('");
  LocTy DerefLoc = Lex.getLoc();
  if (parseUInt64(Bytes))
    return true;
  ParenLoc = Lex.getLoc();
  if (!EatIfPresent(lltok::rparen))
    return error(ParenLoc, "expected ')'");
  if (!Bytes)
    return error(DerefLoc, "dereferenceable bytes must be non-zero");
  return false;
}

bool LLParser::parseOptionalUWTableKind(UWTableKind &Kind) {
  Lex.Lex();
  Kind = UWTableKind::Default;
  if (!EatIfPresent(lltok::lparen))
    return false;
  LocTy KindLoc = Lex.getLoc();
  if (Lex.getKind() == lltok::kw_sync)
    Kind = UWTableKind::Sync;
  else if (Lex.getKind() == lltok::kw_async)
    Kind = UWTableKind::Async;
  else
    return error(KindLoc, "expected unwind table kind");
  Lex.Lex();
  return parseToken(lltok::rparen, "expected ')'");
}

bool LLParser::parseAllocKind(AllocFnKind &Kind) {
  Lex.Lex();
  LocTy ParenLoc = Lex.getLoc();
  if (!EatIfPresent(lltok::lparen))
    return error(ParenLoc, "expected '('");
  LocTy KindLoc = Lex.getLoc();
  std::string Arg;
  if (parseStringConstant(Arg))
    return error(KindLoc, "expected allockind value");
  for (StringRef A : llvm::split(Arg, ",")) {
    if (A == "alloc") {
      Kind |= AllocFnKind::Alloc;
    } else if (A == "realloc") {
      Kind |= AllocFnKind::Realloc;
    } else if (A == "free") {
      Kind |= AllocFnKind::Free;
    } else if (A == "uninitialized") {
      Kind |= AllocFnKind::Uninitialized;
    } else if (A == "zeroed") {
      Kind |= AllocFnKind::Zeroed;
    } else if (A == "aligned") {
      Kind |= AllocFnKind::Aligned;
    } else {
      return error(KindLoc, Twine("unknown allockind ") + A);
    }
  }
  ParenLoc = Lex.getLoc();
  if (!EatIfPresent(lltok::rparen))
    return error(ParenLoc, "expected ')'");
  if (Kind == AllocFnKind::Unknown)
    return error(KindLoc, "expected allockind value");
  return false;
}

static std::optional<MemoryEffects::Location> keywordToLoc(lltok::Kind Tok) {
  switch (Tok) {
  case lltok::kw_argmem:
    return IRMemLocation::ArgMem;
  case lltok::kw_inaccessiblemem:
    return IRMemLocation::InaccessibleMem;
  case lltok::kw_errnomem:
    return IRMemLocation::ErrnoMem;
  default:
    return std::nullopt;
  }
}

static std::optional<ModRefInfo> keywordToModRef(lltok::Kind Tok) {
  switch (Tok) {
  case lltok::kw_none:
    return ModRefInfo::NoModRef;
  case lltok::kw_read:
    return ModRefInfo::Ref;
  case lltok::kw_write:
    return ModRefInfo::Mod;
  case lltok::kw_readwrite:
    return ModRefInfo::ModRef;
  default:
    return std::nullopt;
  }
}

std::optional<MemoryEffects> LLParser::parseMemoryAttr() {
  MemoryEffects ME = MemoryEffects::none();

  // We use syntax like memory(argmem: read), so the colon should not be
  // interpreted as a label terminator.
  Lex.setIgnoreColonInIdentifiers(true);
  auto _ = make_scope_exit([&] { Lex.setIgnoreColonInIdentifiers(false); });

  Lex.Lex();
  if (!EatIfPresent(lltok::lparen)) {
    tokError("expected '('");
    return std::nullopt;
  }

  bool SeenLoc = false;
  do {
    std::optional<IRMemLocation> Loc = keywordToLoc(Lex.getKind());
    if (Loc) {
      Lex.Lex();
      if (!EatIfPresent(lltok::colon)) {
        tokError("expected ':' after location");
        return std::nullopt;
      }
    }

    std::optional<ModRefInfo> MR = keywordToModRef(Lex.getKind());
    if (!MR) {
      if (!Loc)
        tokError("expected memory location (argmem, inaccessiblemem, errnomem) "
                 "or access kind (none, read, write, readwrite)");
      else
        tokError("expected access kind (none, read, write, readwrite)");
      return std::nullopt;
    }

    Lex.Lex();
    if (Loc) {
      SeenLoc = true;
      ME = ME.getWithModRef(*Loc, *MR);
    } else {
      if (SeenLoc) {
        tokError("default access kind must be specified first");
        return std::nullopt;
      }
      ME = MemoryEffects(*MR);
    }

    if (EatIfPresent(lltok::rparen))
      return ME;
  } while (EatIfPresent(lltok::comma));

  tokError("unterminated memory attribute");
  return std::nullopt;
}

static unsigned keywordToFPClassTest(lltok::Kind Tok) {
  switch (Tok) {
  case lltok::kw_all:
    return fcAllFlags;
  case lltok::kw_nan:
    return fcNan;
  case lltok::kw_snan:
    return fcSNan;
  case lltok::kw_qnan:
    return fcQNan;
  case lltok::kw_inf:
    return fcInf;
  case lltok::kw_ninf:
    return fcNegInf;
  case lltok::kw_pinf:
    return fcPosInf;
  case lltok::kw_norm:
    return fcNormal;
  case lltok::kw_nnorm:
    return fcNegNormal;
  case lltok::kw_pnorm:
    return fcPosNormal;
  case lltok::kw_sub:
    return fcSubnormal;
  case lltok::kw_nsub:
    return fcNegSubnormal;
  case lltok::kw_psub:
    return fcPosSubnormal;
  case lltok::kw_zero:
    return fcZero;
  case lltok::kw_nzero:
    return fcNegZero;
  case lltok::kw_pzero:
    return fcPosZero;
  default:
    return 0;
  }
}

unsigned LLParser::parseNoFPClassAttr() {
  unsigned Mask = fcNone;

  Lex.Lex();
  if (!EatIfPresent(lltok::lparen)) {
    tokError("expected '('");
    return 0;
  }

  do {
    uint64_t Value = 0;
    unsigned TestMask = keywordToFPClassTest(Lex.getKind());
    if (TestMask != 0) {
      Mask |= TestMask;
      // TODO: Disallow overlapping masks to avoid copy paste errors
    } else if (Mask == 0 && Lex.getKind() == lltok::APSInt &&
               !parseUInt64(Value)) {
      if (Value == 0 || (Value & ~static_cast<unsigned>(fcAllFlags)) != 0) {
        error(Lex.getLoc(), "invalid mask value for 'nofpclass'");
        return 0;
      }

      if (!EatIfPresent(lltok::rparen)) {
        error(Lex.getLoc(), "expected ')'");
        return 0;
      }

      return Value;
    } else {
      error(Lex.getLoc(), "expected nofpclass test mask");
      return 0;
    }

    Lex.Lex();
    if (EatIfPresent(lltok::rparen))
      return Mask;
  } while (1);

  llvm_unreachable("unterminated nofpclass attribute");
}

/// parseOptionalCommaAlign
///   ::=
///   ::= ',' align 4
///
/// This returns with AteExtraComma set to true if it ate an excess comma at the
/// end.
bool LLParser::parseOptionalCommaAlign(MaybeAlign &Alignment,
                                       bool &AteExtraComma) {
  AteExtraComma = false;
  while (EatIfPresent(lltok::comma)) {
    // Metadata at the end is an early exit.
    if (Lex.getKind() == lltok::MetadataVar) {
      AteExtraComma = true;
      return false;
    }

    if (Lex.getKind() != lltok::kw_align)
      return error(Lex.getLoc(), "expected metadata or 'align'");

    if (parseOptionalAlignment(Alignment))
      return true;
  }

  return false;
}

/// parseOptionalCommaAddrSpace
///   ::=
///   ::= ',' addrspace(1)
///
/// This returns with AteExtraComma set to true if it ate an excess comma at the
/// end.
bool LLParser::parseOptionalCommaAddrSpace(unsigned &AddrSpace, LocTy &Loc,
                                           bool &AteExtraComma) {
  AteExtraComma = false;
  while (EatIfPresent(lltok::comma)) {
    // Metadata at the end is an early exit.
    if (Lex.getKind() == lltok::MetadataVar) {
      AteExtraComma = true;
      return false;
    }

    Loc = Lex.getLoc();
    if (Lex.getKind() != lltok::kw_addrspace)
      return error(Lex.getLoc(), "expected metadata or 'addrspace'");

    if (parseOptionalAddrSpace(AddrSpace))
      return true;
  }

  return false;
}

bool LLParser::parseAllocSizeArguments(unsigned &BaseSizeArg,
                                       std::optional<unsigned> &HowManyArg) {
  Lex.Lex();

  auto StartParen = Lex.getLoc();
  if (!EatIfPresent(lltok::lparen))
    return error(StartParen, "expected '('");

  if (parseUInt32(BaseSizeArg))
    return true;

  if (EatIfPresent(lltok::comma)) {
    auto HowManyAt = Lex.getLoc();
    unsigned HowMany;
    if (parseUInt32(HowMany))
      return true;
    if (HowMany == BaseSizeArg)
      return error(HowManyAt,
                   "'allocsize' indices can't refer to the same parameter");
    HowManyArg = HowMany;
  } else
    HowManyArg = std::nullopt;

  auto EndParen = Lex.getLoc();
  if (!EatIfPresent(lltok::rparen))
    return error(EndParen, "expected ')'");
  return false;
}

bool LLParser::parseVScaleRangeArguments(unsigned &MinValue,
                                         unsigned &MaxValue) {
  Lex.Lex();

  auto StartParen = Lex.getLoc();
  if (!EatIfPresent(lltok::lparen))
    return error(StartParen, "expected '('");

  if (parseUInt32(MinValue))
    return true;

  if (EatIfPresent(lltok::comma)) {
    if (parseUInt32(MaxValue))
      return true;
  } else
    MaxValue = MinValue;

  auto EndParen = Lex.getLoc();
  if (!EatIfPresent(lltok::rparen))
    return error(EndParen, "expected ')'");
  return false;
}

/// parseScopeAndOrdering
///   if isAtomic: ::= SyncScope? AtomicOrdering
///   else: ::=
///
/// This sets Scope and Ordering to the parsed values.
bool LLParser::parseScopeAndOrdering(bool IsAtomic, SyncScope::ID &SSID,
                                     AtomicOrdering &Ordering) {
  if (!IsAtomic)
    return false;

  return parseScope(SSID) || parseOrdering(Ordering);
}

/// parseScope
///   ::= syncscope("singlethread" | "<target scope>")?
///
/// This sets synchronization scope ID to the ID of the parsed value.
bool LLParser::parseScope(SyncScope::ID &SSID) {
  SSID = SyncScope::System;
  if (EatIfPresent(lltok::kw_syncscope)) {
    auto StartParenAt = Lex.getLoc();
    if (!EatIfPresent(lltok::lparen))
      return error(StartParenAt, "Expected '(' in syncscope");

    std::string SSN;
    auto SSNAt = Lex.getLoc();
    if (parseStringConstant(SSN))
      return error(SSNAt, "Expected synchronization scope name");

    auto EndParenAt = Lex.getLoc();
    if (!EatIfPresent(lltok::rparen))
      return error(EndParenAt, "Expected ')' in syncscope");

    SSID = Context.getOrInsertSyncScopeID(SSN);
  }

  return false;
}

/// parseOrdering
///   ::= AtomicOrdering
///
/// This sets Ordering to the parsed value.
bool LLParser::parseOrdering(AtomicOrdering &Ordering) {
  switch (Lex.getKind()) {
  default:
    return tokError("Expected ordering on atomic instruction");
  case lltok::kw_unordered: Ordering = AtomicOrdering::Unordered; break;
  case lltok::kw_monotonic: Ordering = AtomicOrdering::Monotonic; break;
  // Not specified yet:
  // case lltok::kw_consume: Ordering = AtomicOrdering::Consume; break;
  case lltok::kw_acquire: Ordering = AtomicOrdering::Acquire; break;
  case lltok::kw_release: Ordering = AtomicOrdering::Release; break;
  case lltok::kw_acq_rel: Ordering = AtomicOrdering::AcquireRelease; break;
  case lltok::kw_seq_cst:
    Ordering = AtomicOrdering::SequentiallyConsistent;
    break;
  }
  Lex.Lex();
  return false;
}

/// parseOptionalStackAlignment
///   ::= /* empty */
///   ::= 'alignstack' '(' 4 ')'
bool LLParser::parseOptionalStackAlignment(unsigned &Alignment) {
  Alignment = 0;
  if (!EatIfPresent(lltok::kw_alignstack))
    return false;
  LocTy ParenLoc = Lex.getLoc();
  if (!EatIfPresent(lltok::lparen))
    return error(ParenLoc, "expected '('");
  LocTy AlignLoc = Lex.getLoc();
  if (parseUInt32(Alignment))
    return true;
  ParenLoc = Lex.getLoc();
  if (!EatIfPresent(lltok::rparen))
    return error(ParenLoc, "expected ')'");
  if (!isPowerOf2_32(Alignment))
    return error(AlignLoc, "stack alignment is not a power of two");
  return false;
}

/// parseIndexList - This parses the index list for an insert/extractvalue
/// instruction.  This sets AteExtraComma in the case where we eat an extra
/// comma at the end of the line and find that it is followed by metadata.
/// Clients that don't allow metadata can call the version of this function that
/// only takes one argument.
///
/// parseIndexList
///    ::=  (',' uint32)+
///
bool LLParser::parseIndexList(SmallVectorImpl<unsigned> &Indices,
                              bool &AteExtraComma) {
  AteExtraComma = false;

  if (Lex.getKind() != lltok::comma)
    return tokError("expected ',' as start of index list");

  while (EatIfPresent(lltok::comma)) {
    if (Lex.getKind() == lltok::MetadataVar) {
      if (Indices.empty())
        return tokError("expected index");
      AteExtraComma = true;
      return false;
    }
    unsigned Idx = 0;
    if (parseUInt32(Idx))
      return true;
    Indices.push_back(Idx);
  }

  return false;
}

//===----------------------------------------------------------------------===//
// Type Parsing.
//===----------------------------------------------------------------------===//

/// parseType - parse a type.
bool LLParser::parseType(Type *&Result, const Twine &Msg, bool AllowVoid) {
  SMLoc TypeLoc = Lex.getLoc();
  switch (Lex.getKind()) {
  default:
    return tokError(Msg);
  case lltok::Type:
    // Type ::= 'float' | 'void' (etc)
    Result = Lex.getTyVal();
    Lex.Lex();

    // Handle "ptr" opaque pointer type.
    //
    // Type ::= ptr ('addrspace' '(' uint32 ')')?
    if (Result->isPointerTy()) {
      unsigned AddrSpace;
      if (parseOptionalAddrSpace(AddrSpace))
        return true;
      Result = PointerType::get(getContext(), AddrSpace);

      // Give a nice error for 'ptr*'.
      if (Lex.getKind() == lltok::star)
        return tokError("ptr* is invalid - use ptr instead");

      // Fall through to parsing the type suffixes only if this 'ptr' is a
      // function return. Otherwise, return success, implicitly rejecting other
      // suffixes.
      if (Lex.getKind() != lltok::lparen)
        return false;
    }
    break;
  case lltok::kw_target: {
    // Type ::= TargetExtType
    if (parseTargetExtType(Result))
      return true;
    break;
  }
  case lltok::lbrace:
    // Type ::= StructType
    if (parseAnonStructType(Result, false))
      return true;
    break;
  case lltok::lsquare:
    // Type ::= '[' ... ']'
    Lex.Lex(); // eat the lsquare.
    if (parseArrayVectorType(Result, false))
      return true;
    break;
  case lltok::less: // Either vector or packed struct.
    // Type ::= '<' ... '>'
    Lex.Lex();
    if (Lex.getKind() == lltok::lbrace) {
      if (parseAnonStructType(Result, true) ||
          parseToken(lltok::greater, "expected '>' at end of packed struct"))
        return true;
    } else if (parseArrayVectorType(Result, true))
      return true;
    break;
  case lltok::LocalVar: {
    // Type ::= %foo
    std::pair<Type*, LocTy> &Entry = NamedTypes[Lex.getStrVal()];

    // If the type hasn't been defined yet, create a forward definition and
    // remember where that forward def'n was seen (in case it never is defined).
    if (!Entry.first) {
      Entry.first = StructType::create(Context, Lex.getStrVal());
      Entry.second = Lex.getLoc();
    }
    Result = Entry.first;
    Lex.Lex();
    break;
  }

  case lltok::LocalVarID: {
    // Type ::= %4
    std::pair<Type*, LocTy> &Entry = NumberedTypes[Lex.getUIntVal()];

    // If the type hasn't been defined yet, create a forward definition and
    // remember where that forward def'n was seen (in case it never is defined).
    if (!Entry.first) {
      Entry.first = StructType::create(Context);
      Entry.second = Lex.getLoc();
    }
    Result = Entry.first;
    Lex.Lex();
    break;
  }
  }

  // parse the type suffixes.
  while (true) {
    switch (Lex.getKind()) {
    // End of type.
    default:
      if (!AllowVoid && Result->isVoidTy())
        return error(TypeLoc, "void type only allowed for function results");
      return false;

    // Type ::= Type '*'
    case lltok::star:
      if (Result->isLabelTy())
        return tokError("basic block pointers are invalid");
      if (Result->isVoidTy())
        return tokError("pointers to void are invalid - use i8* instead");
      if (!PointerType::isValidElementType(Result))
        return tokError("pointer to this type is invalid");
      Result = PointerType::getUnqual(Context);
      Lex.Lex();
      break;

    // Type ::= Type 'addrspace' '(' uint32 ')' '*'
    case lltok::kw_addrspace: {
      if (Result->isLabelTy())
        return tokError("basic block pointers are invalid");
      if (Result->isVoidTy())
        return tokError("pointers to void are invalid; use i8* instead");
      if (!PointerType::isValidElementType(Result))
        return tokError("pointer to this type is invalid");
      unsigned AddrSpace;
      if (parseOptionalAddrSpace(AddrSpace) ||
          parseToken(lltok::star, "expected '*' in address space"))
        return true;

      Result = PointerType::get(Context, AddrSpace);
      break;
    }

    /// Types '(' ArgTypeListI ')' OptFuncAttrs
    case lltok::lparen:
      if (parseFunctionType(Result))
        return true;
      break;
    }
  }
}

/// parseParameterList
///    ::= '(' ')'
///    ::= '(' Arg (',' Arg)* ')'
///  Arg
///    ::= Type OptionalAttributes Value OptionalAttributes
bool LLParser::parseParameterList(SmallVectorImpl<ParamInfo> &ArgList,
                                  PerFunctionState &PFS, bool IsMustTailCall,
                                  bool InVarArgsFunc) {
  if (parseToken(lltok::lparen, "expected '(' in call"))
    return true;

  while (Lex.getKind() != lltok::rparen) {
    // If this isn't the first argument, we need a comma.
    if (!ArgList.empty() &&
        parseToken(lltok::comma, "expected ',' in argument list"))
      return true;

    // parse an ellipsis if this is a musttail call in a variadic function.
    if (Lex.getKind() == lltok::dotdotdot) {
      const char *Msg = "unexpected ellipsis in argument list for ";
      if (!IsMustTailCall)
        return tokError(Twine(Msg) + "non-musttail call");
      if (!InVarArgsFunc)
        return tokError(Twine(Msg) + "musttail call in non-varargs function");
      Lex.Lex();  // Lex the '...', it is purely for readability.
      return parseToken(lltok::rparen, "expected ')' at end of argument list");
    }

    // parse the argument.
    LocTy ArgLoc;
    Type *ArgTy = nullptr;
    Value *V;
    if (parseType(ArgTy, ArgLoc))
      return true;
    if (!FunctionType::isValidArgumentType(ArgTy))
      return error(ArgLoc, "invalid type for function argument");

    AttrBuilder ArgAttrs(M->getContext());

    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(), ArgAttrs)));
  }

  if (IsMustTailCall && InVarArgsFunc)
    return tokError("expected '...' at end of argument list for musttail call "
                    "in varargs function");

  Lex.Lex();  // Lex the ')'.
  return false;
}

/// parseRequiredTypeAttr
///   ::= attrname(<ty>)
bool LLParser::parseRequiredTypeAttr(AttrBuilder &B, lltok::Kind AttrToken,
                                     Attribute::AttrKind AttrKind) {
  Type *Ty = nullptr;
  if (!EatIfPresent(AttrToken))
    return true;
  if (!EatIfPresent(lltok::lparen))
    return error(Lex.getLoc(), "expected '('");
  if (parseType(Ty))
    return true;
  if (!EatIfPresent(lltok::rparen))
    return error(Lex.getLoc(), "expected ')'");

  B.addTypeAttr(AttrKind, Ty);
  return false;
}

/// parseRangeAttr
///   ::= range(<ty> <n>,<n>)
bool LLParser::parseRangeAttr(AttrBuilder &B) {
  Lex.Lex();

  APInt Lower;
  APInt Upper;
  Type *Ty = nullptr;
  LocTy TyLoc;

  auto ParseAPSInt = [&](unsigned BitWidth, APInt &Val) {
    if (Lex.getKind() != lltok::APSInt)
      return tokError("expected integer");
    if (Lex.getAPSIntVal().getBitWidth() > BitWidth)
      return tokError(
          "integer is too large for the bit width of specified type");
    Val = Lex.getAPSIntVal().extend(BitWidth);
    Lex.Lex();
    return false;
  };

  if (parseToken(lltok::lparen, "expected '('") || parseType(Ty, TyLoc))
    return true;
  if (!Ty->isIntegerTy())
    return error(TyLoc, "the range must have integer type!");

  unsigned BitWidth = Ty->getPrimitiveSizeInBits();

  if (ParseAPSInt(BitWidth, Lower) ||
      parseToken(lltok::comma, "expected ','") || ParseAPSInt(BitWidth, Upper))
    return true;
  if (Lower == Upper && !Lower.isZero())
    return tokError("the range represent the empty set but limits aren't 0!");

  if (parseToken(lltok::rparen, "expected ')'"))
    return true;

  B.addRangeAttr(ConstantRange(Lower, Upper));
  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;
}

bool LLParser::parseCapturesAttr(AttrBuilder &B) {
  CaptureComponents Other = CaptureComponents::None;
  std::optional<CaptureComponents> Ret;

  // We use syntax like captures(ret: address, provenance), so the colon
  // should not be interpreted as a label terminator.
  Lex.setIgnoreColonInIdentifiers(true);
  auto _ = make_scope_exit([&] { Lex.setIgnoreColonInIdentifiers(false); });

  Lex.Lex();
  if (parseToken(lltok::lparen, "expected '('"))
    return true;

  CaptureComponents *Current = &Other;
  bool SeenComponent = false;
  while (true) {
    if (EatIfPresent(lltok::kw_ret)) {
      if (parseToken(lltok::colon, "expected ':'"))
        return true;
      if (Ret)
        return tokError("duplicate 'ret' location");
      Ret = CaptureComponents::None;
      Current = &*Ret;
      SeenComponent = false;
    }

    if (EatIfPresent(lltok::kw_none)) {
      if (SeenComponent)
        return tokError("cannot use 'none' with other component");
      *Current = CaptureComponents::None;
    } else {
      if (SeenComponent && capturesNothing(*Current))
        return tokError("cannot use 'none' with other component");

      if (EatIfPresent(lltok::kw_address_is_null))
        *Current |= CaptureComponents::AddressIsNull;
      else if (EatIfPresent(lltok::kw_address))
        *Current |= CaptureComponents::Address;
      else if (EatIfPresent(lltok::kw_provenance))
        *Current |= CaptureComponents::Provenance;
      else if (EatIfPresent(lltok::kw_read_provenance))
        *Current |= CaptureComponents::ReadProvenance;
      else
        return tokError("expected one of 'none', 'address', 'address_is_null', "
                        "'provenance' or 'read_provenance'");
    }

    SeenComponent = true;
    if (EatIfPresent(lltok::rparen))
      break;

    if (parseToken(lltok::comma, "expected ',' or ')'"))
      return true;
  }

  B.addCapturesAttr(CaptureInfo(Other, Ret.value_or(Other)));
  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))
        return true;
      if (Ty->isMetadataTy()) {
        if (parseMetadataAsValue(Input, PFS))
          return true;
      } else if (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;
}

bool LLParser::checkValueID(LocTy Loc, StringRef Kind, StringRef Prefix,
                            unsigned NextID, unsigned ID) {
  if (ID < NextID)
    return error(Loc, Kind + " expected to be numbered '" + Prefix +
                          Twine(NextID) + "' or greater");

  return false;
}

/// parseArgumentList - parse the argument list for a function type or function
/// prototype.
///   ::= '(' ArgTypeListI ')'
/// ArgTypeListI
///   ::= /*empty*/
///   ::= '...'
///   ::= ArgTypeList ',' '...'
///   ::= ArgType (',' ArgType)*
///
bool LLParser::parseArgumentList(SmallVectorImpl<ArgInfo> &ArgList,
                                 SmallVectorImpl<unsigned> &UnnamedArgNums,
                                 bool &IsVarArg) {
  unsigned CurValID = 0;
  IsVarArg = false;
  assert(Lex.getKind() == lltok::lparen);
  Lex.Lex(); // eat the (.

  if (Lex.getKind() != lltok::rparen) {
    do {
      // Handle ... at end of arg list.
      if (EatIfPresent(lltok::dotdotdot)) {
        IsVarArg = true;
        break;
      }

      // Otherwise must be an argument type.
      LocTy TypeLoc = Lex.getLoc();
      Type *ArgTy = nullptr;
      AttrBuilder Attrs(M->getContext());
      if (parseType(ArgTy) || parseOptionalParamAttrs(Attrs))
        return true;

      if (ArgTy->isVoidTy())
        return error(TypeLoc, "argument can not have void type");

      std::string Name;
      if (Lex.getKind() == lltok::LocalVar) {
        Name = Lex.getStrVal();
        Lex.Lex();
      } else {
        unsigned ArgID;
        if (Lex.getKind() == lltok::LocalVarID) {
          ArgID = Lex.getUIntVal();
          if (checkValueID(TypeLoc, "argument", "%", CurValID, ArgID))
            return true;
          Lex.Lex();
        } else {
          ArgID = CurValID;
        }
        UnnamedArgNums.push_back(ArgID);
        CurValID = ArgID + 1;
      }

      if (!FunctionType::isValidArgumentType(ArgTy))
        return error(TypeLoc, "invalid type for function argument");

      ArgList.emplace_back(TypeLoc, ArgTy,
                           AttributeSet::get(ArgTy->getContext(), Attrs),
                           std::move(Name));
    } while (EatIfPresent(lltok::comma));
  }

  return parseToken(lltok::rparen, "expected ')' at end of argument list");
}

/// parseFunctionType
///  ::= Type ArgumentList OptionalAttrs
bool LLParser::parseFunctionType(Type *&Result) {
  assert(Lex.getKind() == lltok::lparen);

  if (!FunctionType::isValidReturnType(Result))
    return tokError("invalid function return type");

  SmallVector<ArgInfo, 8> ArgList;
  bool IsVarArg;
  SmallVector<unsigned> UnnamedArgNums;
  if (parseArgumentList(ArgList, UnnamedArgNums, IsVarArg))
    return true;

  // Reject names on the arguments lists.
  for (const ArgInfo &Arg : ArgList) {
    if (!Arg.Name.empty())
      return error(Arg.Loc, "argument name invalid in function type");
    if (Arg.Attrs.hasAttributes())
      return error(Arg.Loc, "argument attributes invalid in function type");
  }

  SmallVector<Type*, 16> ArgListTy;
  for (const ArgInfo &Arg : ArgList)
    ArgListTy.push_back(Arg.Ty);

  Result = FunctionType::get(Result, ArgListTy, IsVarArg);
  return false;
}

/// parseAnonStructType - parse an anonymous struct type, which is inlined into
/// other structs.
bool LLParser::parseAnonStructType(Type *&Result, bool Packed) {
  SmallVector<Type*, 8> Elts;
  if (parseStructBody(Elts))
    return true;

  Result = StructType::get(Context, Elts, Packed);
  return false;
}

/// parseStructDefinition - parse a struct in a 'type' definition.
bool LLParser::parseStructDefinition(SMLoc TypeLoc, StringRef Name,
                                     std::pair<Type *, LocTy> &Entry,
                                     Type *&ResultTy) {
  // If the type was already defined, diagnose the redefinition.
  if (Entry.first && !Entry.second.isValid())
    return error(TypeLoc, "redefinition of type");

  // If we have opaque, just return without filling in the definition for the
  // struct.  This counts as a definition as far as the .ll file goes.
  if (EatIfPresent(lltok::kw_opaque)) {
    // This type is being defined, so clear the location to indicate this.
    Entry.second = SMLoc();

    // If this type number has never been uttered, create it.
    if (!Entry.first)
      Entry.first = StructType::create(Context, Name);
    ResultTy = Entry.first;
    return false;
  }

  // If the type starts with '<', then it is either a packed struct or a vector.
  bool isPacked = EatIfPresent(lltok::less);

  // If we don't have a struct, then we have a random type alias, which we
  // accept for compatibility with old files.  These types are not allowed to be
  // forward referenced and not allowed to be recursive.
  if (Lex.getKind() != lltok::lbrace) {
    if (Entry.first)
      return error(TypeLoc, "forward references to non-struct type");

    ResultTy = nullptr;
    if (isPacked)
      return parseArrayVectorType(ResultTy, true);
    return parseType(ResultTy);
  }

  // This type is being defined, so clear the location to indicate this.
  Entry.second = SMLoc();

  // If this type number has never been uttered, create it.
  if (!Entry.first)
    Entry.first = StructType::create(Context, Name);

  StructType *STy = cast<StructType>(Entry.first);

  SmallVector<Type*, 8> Body;
  if (parseStructBody(Body) ||
      (isPacked && parseToken(lltok::greater, "expected '>' in packed struct")))
    return true;

  if (auto E = STy->setBodyOrError(Body, isPacked))
    return tokError(toString(std::move(E)));

  ResultTy = STy;
  return false;
}

/// parseStructType: Handles packed and unpacked types.  </> parsed elsewhere.
///   StructType
///     ::= '{' '}'
///     ::= '{' Type (',' Type)* '}'
///     ::= '<' '{' '}' '>'
///     ::= '<' '{' Type (',' Type)* '}' '>'
bool LLParser::parseStructBody(SmallVectorImpl<Type *> &Body) {
  assert(Lex.getKind() == lltok::lbrace);
  Lex.Lex(); // Consume the '{'

  // Handle the empty struct.
  if (EatIfPresent(lltok::rbrace))
    return false;

  LocTy EltTyLoc = Lex.getLoc();
  Type *Ty = nullptr;
  if (parseType(Ty))
    return true;
  Body.push_back(Ty);

  if (!StructType::isValidElementType(Ty))
    return error(EltTyLoc, "invalid element type for struct");

  while (EatIfPresent(lltok::comma)) {
    EltTyLoc = Lex.getLoc();
    if (parseType(Ty))
      return true;

    if (!StructType::isValidElementType(Ty))
      return error(EltTyLoc, "invalid element type for struct");

    Body.push_back(Ty);
  }

  return parseToken(lltok::rbrace, "expected '}' at end of struct");
}

/// parseArrayVectorType - parse an array or vector type, assuming the first
/// token has already been consumed.
///   Type
///     ::= '[' APSINTVAL 'x' Types ']'
///     ::= '<' APSINTVAL 'x' Types '>'
///     ::= '<' 'vscale' 'x' APSINTVAL 'x' Types '>'
bool LLParser::parseArrayVectorType(Type *&Result, bool IsVector) {
  bool Scalable = false;

  if (IsVector && Lex.getKind() == lltok::kw_vscale) {
    Lex.Lex(); // consume the 'vscale'
    if (parseToken(lltok::kw_x, "expected 'x' after vscale"))
      return true;

    Scalable = true;
  }

  if (Lex.getKind() != lltok::APSInt || Lex.getAPSIntVal().isSigned() ||
      Lex.getAPSIntVal().getBitWidth() > 64)
    return tokError("expected number in address space");

  LocTy SizeLoc = Lex.getLoc();
  uint64_t Size = Lex.getAPSIntVal().getZExtValue();
  Lex.Lex();

  if (parseToken(lltok::kw_x, "expected 'x' after element count"))
    return true;

  LocTy TypeLoc = Lex.getLoc();
  Type *EltTy = nullptr;
  if (parseType(EltTy))
    return true;

  if (parseToken(IsVector ? lltok::greater : lltok::rsquare,
                 "expected end of sequential type"))
    return true;

  if (IsVector) {
    if (Size == 0)
      return error(SizeLoc, "zero element vector is illegal");
    if ((unsigned)Size != Size)
      return error(SizeLoc, "size too large for vector");
    if (!VectorType::isValidElementType(EltTy))
      return error(TypeLoc, "invalid vector element type");
    Result = VectorType::get(EltTy, unsigned(Size), Scalable);
  } else {
    if (!ArrayType::isValidElementType(EltTy))
      return error(TypeLoc, "invalid array element type");
    Result = ArrayType::get(EltTy, Size);
  }
  return false;
}

/// parseTargetExtType - handle target extension type syntax
///   TargetExtType
///     ::= 'target' '(' STRINGCONSTANT TargetExtTypeParams TargetExtIntParams ')'
///
///   TargetExtTypeParams
///     ::= /*empty*/
///     ::= ',' Type TargetExtTypeParams
///
///   TargetExtIntParams
///     ::= /*empty*/
///     ::= ',' uint32 TargetExtIntParams
bool LLParser::parseTargetExtType(Type *&Result) {
  Lex.Lex(); // Eat the 'target' keyword.

  // Get the mandatory type name.
  std::string TypeName;
  if (parseToken(lltok::lparen, "expected '(' in target extension type") ||
      parseStringConstant(TypeName))
    return true;

  // Parse all of the integer and type parameters at the same time; the use of
  // SeenInt will allow us to catch cases where type parameters follow integer
  // parameters.
  SmallVector<Type *> TypeParams;
  SmallVector<unsigned> IntParams;
  bool SeenInt = false;
  while (Lex.getKind() == lltok::comma) {
    Lex.Lex(); // Eat the comma.

    if (Lex.getKind() == lltok::APSInt) {
      SeenInt = true;
      unsigned IntVal;
      if (parseUInt32(IntVal))
        return true;
      IntParams.push_back(IntVal);
    } else if (SeenInt) {
      // The only other kind of parameter we support is type parameters, which
      // must precede the integer parameters. This is therefore an error.
      return tokError("expected uint32 param");
    } else {
      Type *TypeParam;
      if (parseType(TypeParam, /*AllowVoid=*/true))
        return true;
      TypeParams.push_back(TypeParam);
    }
  }

  if (parseToken(lltok::rparen, "expected ')' in target extension type"))
    return true;

  auto TTy =
      TargetExtType::getOrError(Context, TypeName, TypeParams, IntParams);
  if (auto E = TTy.takeError())
    return tokError(toString(std::move(E)));

  Result = *TTy;
  return false;
}

//===----------------------------------------------------------------------===//
// Function Semantic Analysis.
//===----------------------------------------------------------------------===//

LLParser::PerFunctionState::PerFunctionState(LLParser &p, Function &f,
                                             int functionNumber,
                                             ArrayRef<unsigned> UnnamedArgNums)
  : P(p), F(f), FunctionNumber(functionNumber) {

  // Insert unnamed arguments into the NumberedVals list.
  auto It = UnnamedArgNums.begin();
  for (Argument &A : F.args()) {
    if (!A.hasName()) {
      unsigned ArgNum = *It++;
      NumberedVals.add(ArgNum, &A);
    }
  }
}

LLParser::PerFunctionState::~PerFunctionState() {
  // If there were any forward referenced non-basicblock values, delete them.

  for (const auto &P : ForwardRefVals) {
    if (isa<BasicBlock>(P.second.first))
      continue;
    P.second.first->replaceAllUsesWith(
        PoisonValue::get(P.second.first->getType()));
    P.second.first->deleteValue();
  }

  for (const auto &P : ForwardRefValIDs) {
    if (isa<BasicBlock>(P.second.first))
      continue;
    P.second.first->replaceAllUsesWith(
        PoisonValue::get(P.second.first->getType()));
    P.second.first->deleteValue();
  }
}

bool LLParser::PerFunctionState::finishFunction() {
  if (!ForwardRefVals.empty())
    return P.error(ForwardRefVals.begin()->second.second,
                   "use of undefined value '%" + ForwardRefVals.begin()->first +
                       "'");
  if (!ForwardRefValIDs.empty())
    return P.error(ForwardRefValIDs.begin()->second.second,
                   "use of undefined value '%" +
                       Twine(ForwardRefValIDs.begin()->first) + "'");
  return false;
}

/// 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) {
  // 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) {
    auto I = ForwardRefVals.find(Name);
    if (I != ForwardRefVals.end())
      Val = I->second.first;
  }

  // If we have the value in the symbol table or fwd-ref table, return it.
  if (Val)
    return P.checkValidVariableType(Loc, "%" + Name, Ty, Val);

  // Don't make placeholders with invalid type.
  if (!Ty->isFirstClassType()) {
    P.error(Loc, "invalid use of a non-first-class type");
    return nullptr;
  }

  // Otherwise, create a new forward reference for this value and remember it.
  Value *FwdVal;
  if (Ty->isLabelTy()) {
    FwdVal = BasicBlock::Create(F.getContext(), Name, &F);
  } else {
    FwdVal = new Argument(Ty, Name);
  }
  if (FwdVal->getName() != Name) {
    P.error(Loc, "name is too long which can result in name collisions, "
                 "consider making the name shorter or "
                 "increasing -non-global-value-max-name-size");
    return nullptr;
  }

  ForwardRefVals[Name] = std::make_pair(FwdVal, Loc);
  return FwdVal;
}

Value *LLParser::PerFunctionState::getVal(unsigned ID, Type *Ty, LocTy Loc) {
  // Look this name up in the normal function symbol table.
  Value *Val = NumberedVals.get(ID);

  // If this is a forward reference for the value, see if we already created a
  // forward ref record.
  if (!Val) {
    auto I = ForwardRefValIDs.find(ID);
    if (I != ForwardRefValIDs.end())
      Val = I->second.first;
  }

  // If we have the value in the symbol table or fwd-ref table, return it.
  if (Val)
    return P.checkValidVariableType(Loc, "%" + Twine(ID), Ty, Val);

  if (!Ty->isFirstClassType()) {
    P.error(Loc, "invalid use of a non-first-class type");
    return nullptr;
  }

  // Otherwise, create a new forward reference for this value and remember it.
  Value *FwdVal;
  if (Ty->isLabelTy()) {
    FwdVal = BasicBlock::Create(F.getContext(), "", &F);
  } else {
    FwdVal = new Argument(Ty);
  }

  ForwardRefValIDs[ID] = std::make_pair(FwdVal, Loc);
  return FwdVal;
}

/// setInstName - After an instruction is parsed and inserted into its
/// basic block, this installs its name.
bool LLParser::PerFunctionState::setInstName(int NameID,
                                             const std::string &NameStr,
                                             LocTy NameLoc, Instruction *Inst) {
  // If this instruction has void type, it cannot have a name or ID specified.
  if (Inst->getType()->isVoidTy()) {
    if (NameID != -1 || !NameStr.empty())
      return P.error(NameLoc, "instructions returning void cannot have a name");
    return false;
  }

  // If this was a numbered instruction, verify that the instruction is the
  // expected value and resolve any forward references.
  if (NameStr.empty()) {
    // If neither a name nor an ID was specified, just use the next ID.
    if (NameID == -1)
      NameID = NumberedVals.getNext();

    if (P.checkValueID(NameLoc, "instruction", "%", NumberedVals.getNext(),
                       NameID))
      return true;

    auto FI = ForwardRefValIDs.find(NameID);
    if (FI != ForwardRefValIDs.end()) {
      Value *Sentinel = FI->second.first;
      if (Sentinel->getType() != Inst->getType())
        return P.error(NameLoc, "instruction forward referenced with type '" +
                                    getTypeString(FI->second.first->getType()) +
                                    "'");

      Sentinel->replaceAllUsesWith(Inst);
      Sentinel->deleteValue();
      ForwardRefValIDs.erase(FI);
    }

    NumberedVals.add(NameID, Inst);
    return false;
  }

  // Otherwise, the instruction had a name.  Resolve forward refs and set it.
  auto FI = ForwardRefVals.find(NameStr);
  if (FI != ForwardRefVals.end()) {
    Value *Sentinel = FI->second.first;
    if (Sentinel->getType() != Inst->getType())
      return P.error(NameLoc, "instruction forward referenced with type '" +
                                  getTypeString(FI->second.first->getType()) +
                                  "'");

    Sentinel->replaceAllUsesWith(Inst);
    Sentinel->deleteValue();
    ForwardRefVals.erase(FI);
  }

  // Set the name on the instruction.
  Inst->setName(NameStr);

  if (Inst->getName() != NameStr)
    return P.error(NameLoc, "multiple definition of local value named '" +
                                NameStr + "'");
  return false;
}

/// getBB - Get a basic block with the specified name or ID, creating a
/// forward reference record if needed.
BasicBlock *LLParser::PerFunctionState::getBB(const std::string &Name,
                                              LocTy Loc) {
  return dyn_cast_or_null<BasicBlock>(
      getVal(Name, Type::getLabelTy(F.getContext()), Loc));
}

BasicBlock *LLParser::PerFunctionState::getBB(unsigned ID, LocTy 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
/// unnamed.  If there is an error, this returns null otherwise it returns
/// the block being defined.
BasicBlock *LLParser::PerFunctionState::defineBB(const std::string &Name,
                                                 int NameID, LocTy Loc) {
  BasicBlock *BB;
  if (Name.empty()) {
    if (NameID != -1) {
      if (P.checkValueID(Loc, "label", "", NumberedVals.getNext(), NameID))
        return nullptr;
    } else {
      NameID = NumberedVals.getNext();
    }
    BB = getBB(NameID, Loc);
    if (!BB) {
      P.error(Loc, "unable to create block numbered '" + Twine(NameID) + "'");
      return nullptr;
    }
  } else {
    BB = getBB(Name, Loc);
    if (!BB) {
      P.error(Loc, "unable to create block named '" + Name + "'");
      return nullptr;
    }
  }

  // Move the block to the end of the function.  Forward ref'd blocks are
  // inserted wherever they happen to be referenced.
  F.splice(F.end(), &F, BB->getIterator());

  // Remove the block from forward ref sets.
  if (Name.empty()) {
    ForwardRefValIDs.erase(NameID);
    NumberedVals.add(NameID, BB);
  } else {
    // BB forward references are already in the function symbol table.
    ForwardRefVals.erase(Name);
  }

  return BB;
}

//===----------------------------------------------------------------------===//
// Constants.
//===----------------------------------------------------------------------===//

/// parseValID - parse an abstract value that doesn't necessarily have a
/// type implied.  For example, if we parse "4" we don't know what integer type
/// it has.  The value will later be combined with its type and checked for
/// basic correctness.  PFS is used to convert function-local operands of
/// metadata (since metadata operands are not just parsed here but also
/// converted to values). PFS can be null when we are not parsing metadata
/// values inside a function.
bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS, Type *ExpectedTy) {
  ID.Loc = Lex.getLoc();
  switch (Lex.getKind()) {
  default:
    return tokError("expected value token");
  case lltok::GlobalID:  // @42
    ID.UIntVal = Lex.getUIntVal();
    ID.Kind = ValID::t_GlobalID;
    break;
  case lltok::GlobalVar:  // @foo
    ID.StrVal = Lex.getStrVal();
    ID.Kind = ValID::t_GlobalName;
    break;
  case lltok::LocalVarID:  // %42
    ID.UIntVal = Lex.getUIntVal();
    ID.Kind = ValID::t_LocalID;
    break;
  case lltok::LocalVar:  // %foo
    ID.StrVal = Lex.getStrVal();
    ID.Kind = ValID::t_LocalName;
    break;
  case lltok::APSInt:
    ID.APSIntVal = Lex.getAPSIntVal();
    ID.Kind = ValID::t_APSInt;
    break;
  case lltok::APFloat:
    ID.APFloatVal = Lex.getAPFloatVal();
    ID.Kind = ValID::t_APFloat;
    break;
  case lltok::kw_true:
    ID.ConstantVal = ConstantInt::getTrue(Context);
    ID.Kind = ValID::t_Constant;
    break;
  case lltok::kw_false:
    ID.ConstantVal = ConstantInt::getFalse(Context);
    ID.Kind = ValID::t_Constant;
    break;
  case lltok::kw_null: ID.Kind = ValID::t_Null; break;
  case lltok::kw_undef: ID.Kind = ValID::t_Undef; break;
  case lltok::kw_poison: ID.Kind = ValID::t_Poison; 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 '}'
    Lex.Lex();
    SmallVector<Constant*, 16> Elts;
    if (parseGlobalValueVector(Elts) ||
        parseToken(lltok::rbrace, "expected end of struct constant"))
      return true;

    ID.ConstantStructElts = std::make_unique<Constant *[]>(Elts.size());
    ID.UIntVal = Elts.size();
    memcpy(ID.ConstantStructElts.get(), Elts.data(),
           Elts.size() * sizeof(Elts[0]));
    ID.Kind = ValID::t_ConstantStruct;
    return false;
  }
  case lltok::less: {
    // ValID ::= '<' ConstVector '>'         --> Vector.
    // ValID ::= '<' '{' ConstVector '}' '>' --> Packed Struct.
    Lex.Lex();
    bool isPackedStruct = EatIfPresent(lltok::lbrace);

    SmallVector<Constant*, 16> Elts;
    LocTy FirstEltLoc = Lex.getLoc();
    if (parseGlobalValueVector(Elts) ||
        (isPackedStruct &&
         parseToken(lltok::rbrace, "expected end of packed struct")) ||
        parseToken(lltok::greater, "expected end of constant"))
      return true;

    if (isPackedStruct) {
      ID.ConstantStructElts = std::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 (Elts.empty())
      return error(ID.Loc, "constant vector must not be empty");

    if (!Elts[0]->getType()->isIntegerTy() &&
        !Elts[0]->getType()->isFloatingPointTy() &&
        !Elts[0]->getType()->isPointerTy())
      return error(
          FirstEltLoc,
          "vector elements must have integer, pointer or floating point type");

    // Verify that all the vector elements have the same type.
    for (unsigned i = 1, e = Elts.size(); i != e; ++i)
      if (Elts[i]->getType() != Elts[0]->getType())
        return error(FirstEltLoc, "vector element #" + Twine(i) +
                                      " is not of type '" +
                                      getTypeString(Elts[0]->getType()));

    ID.ConstantVal = ConstantVector::get(Elts);
    ID.Kind = ValID::t_Constant;
    return false;
  }
  case lltok::lsquare: {   // Array Constant
    Lex.Lex();
    SmallVector<Constant*, 16> Elts;
    LocTy FirstEltLoc = Lex.getLoc();
    if (parseGlobalValueVector(Elts) ||
        parseToken(lltok::rsquare, "expected end of array constant"))
      return true;

    // Handle empty element.
    if (Elts.empty()) {
      // Use undef instead of an array because it's inconvenient to determine
      // the element type at this point, there being no elements to examine.
      ID.Kind = ValID::t_EmptyArray;
      return false;
    }

    if (!Elts[0]->getType()->isFirstClassType())
      return error(FirstEltLoc, "invalid array element type: " +
                                    getTypeString(Elts[0]->getType()));

    ArrayType *ATy = ArrayType::get(Elts[0]->getType(), Elts.size());

    // Verify all elements are correct type!
    for (unsigned i = 0, e = Elts.size(); i != e; ++i) {
      if (Elts[i]->getType() != Elts[0]->getType())
        return error(FirstEltLoc, "array element #" + Twine(i) +
                                      " is not of type '" +
                                      getTypeString(Elts[0]->getType()));
    }

    ID.ConstantVal = ConstantArray::get(ATy, Elts);
    ID.Kind = ValID::t_Constant;
    return false;
  }
  case lltok::kw_c:  // c "foo"
    Lex.Lex();
    ID.ConstantVal = ConstantDataArray::getString(Context, Lex.getStrVal(),
                                                  false);
    if (parseToken(lltok::StringConstant, "expected string"))
      return true;
    ID.Kind = ValID::t_Constant;
    return false;

  case lltok::kw_asm: {
    // ValID ::= 'asm' SideEffect? AlignStack? IntelDialect? STRINGCONSTANT ','
    //             STRINGCONSTANT
    bool HasSideEffect, AlignStack, AsmDialect, CanThrow;
    Lex.Lex();
    if (parseOptionalToken(lltok::kw_sideeffect, HasSideEffect) ||
        parseOptionalToken(lltok::kw_alignstack, AlignStack) ||
        parseOptionalToken(lltok::kw_inteldialect, AsmDialect) ||
        parseOptionalToken(lltok::kw_unwind, CanThrow) ||
        parseStringConstant(ID.StrVal) ||
        parseToken(lltok::comma, "expected comma in inline asm expression") ||
        parseToken(lltok::StringConstant, "expected constraint string"))
      return true;
    ID.StrVal2 = Lex.getStrVal();
    ID.UIntVal = unsigned(HasSideEffect) | (unsigned(AlignStack) << 1) |
                 (unsigned(AsmDialect) << 2) | (unsigned(CanThrow) << 3);
    ID.Kind = ValID::t_InlineAsm;
    return false;
  }

  case lltok::kw_blockaddress: {
    // ValID ::= 'blockaddress' '(' @foo ',' %bar ')'
    Lex.Lex();

    ValID Fn, Label;

    if (parseToken(lltok::lparen, "expected '(' in block address expression") ||
        parseValID(Fn, PFS) ||
        parseToken(lltok::comma,
                   "expected comma in block address expression") ||
        parseValID(Label, PFS) ||
        parseToken(lltok::rparen, "expected ')' in block address expression"))
      return true;

    if (Fn.Kind != ValID::t_GlobalID && Fn.Kind != ValID::t_GlobalName)
      return error(Fn.Loc, "expected function name in blockaddress");
    if (Label.Kind != ValID::t_LocalID && Label.Kind != ValID::t_LocalName)
      return error(Label.Loc, "expected basic block name in blockaddress");

    // Try to find the function (but skip it if it's forward-referenced).
    GlobalValue *GV = nullptr;
    if (Fn.Kind == ValID::t_GlobalID) {
      GV = NumberedVals.get(Fn.UIntVal);
    } else if (!ForwardRefVals.count(Fn.StrVal)) {
      GV = M->getNamedValue(Fn.StrVal);
    }
    Function *F = nullptr;
    if (GV) {
      // Confirm that it's actually a function with a definition.
      if (!isa<Function>(GV))
        return error(Fn.Loc, "expected function name in blockaddress");
      F = cast<Function>(GV);
      if (F->isDeclaration())
        return error(Fn.Loc, "cannot take blockaddress inside a declaration");
    }

    if (!F) {
      // Make a global variable as a placeholder for this reference.
      GlobalValue *&FwdRef =
          ForwardRefBlockAddresses[std::move(Fn)][std::move(Label)];
      if (!FwdRef) {
        unsigned FwdDeclAS;
        if (ExpectedTy) {
          // If we know the type that the blockaddress is being assigned to,
          // we can use the address space of that type.
          if (!ExpectedTy->isPointerTy())
            return error(ID.Loc,
                         "type of blockaddress must be a pointer and not '" +
                             getTypeString(ExpectedTy) + "'");
          FwdDeclAS = ExpectedTy->getPointerAddressSpace();
        } else if (PFS) {
          // Otherwise, we default the address space of the current function.
          FwdDeclAS = PFS->getFunction().getAddressSpace();
        } else {
          llvm_unreachable("Unknown address space for blockaddress");
        }
        FwdRef = new GlobalVariable(
            *M, Type::getInt8Ty(Context), false, GlobalValue::InternalLinkage,
            nullptr, "", nullptr, GlobalValue::NotThreadLocal, FwdDeclAS);
      }

      ID.ConstantVal = FwdRef;
      ID.Kind = ValID::t_Constant;
      return false;
    }

    // We found the function; now find the basic block.  Don't use PFS, since we
    // might be inside a constant expression.
    BasicBlock *BB;
    if (BlockAddressPFS && F == &BlockAddressPFS->getFunction()) {
      if (Label.Kind == ValID::t_LocalID)
        BB = BlockAddressPFS->getBB(Label.UIntVal, Label.Loc);
      else
        BB = BlockAddressPFS->getBB(Label.StrVal, Label.Loc);
      if (!BB)
        return error(Label.Loc, "referenced value is not a basic block");
    } else {
      if (Label.Kind == ValID::t_LocalID)
        return error(Label.Loc, "cannot take address of numeric label after "
                                "the function is defined");
      BB = dyn_cast_or_null<BasicBlock>(
          F->getValueSymbolTable()->lookup(Label.StrVal));
      if (!BB)
        return error(Label.Loc, "referenced value is not a basic block");
    }

    ID.ConstantVal = BlockAddress::get(F, BB);
    ID.Kind = ValID::t_Constant;
    return false;
  }

  case lltok::kw_dso_local_equivalent: {
    // ValID ::= 'dso_local_equivalent' @foo
    Lex.Lex();

    ValID Fn;

    if (parseValID(Fn, PFS))
      return true;

    if (Fn.Kind != ValID::t_GlobalID && Fn.Kind != ValID::t_GlobalName)
      return error(Fn.Loc,
                   "expected global value name in dso_local_equivalent");

    // Try to find the function (but skip it if it's forward-referenced).
    GlobalValue *GV = nullptr;
    if (Fn.Kind == ValID::t_GlobalID) {
      GV = NumberedVals.get(Fn.UIntVal);
    } else if (!ForwardRefVals.count(Fn.StrVal)) {
      GV = M->getNamedValue(Fn.StrVal);
    }

    if (!GV) {
      // Make a placeholder global variable as a placeholder for this reference.
      auto &FwdRefMap = (Fn.Kind == ValID::t_GlobalID)
                            ? ForwardRefDSOLocalEquivalentIDs
                            : ForwardRefDSOLocalEquivalentNames;
      GlobalValue *&FwdRef = FwdRefMap[Fn];
      if (!FwdRef) {
        FwdRef = new GlobalVariable(*M, Type::getInt8Ty(Context), false,
                                    GlobalValue::InternalLinkage, nullptr, "",
                                    nullptr, GlobalValue::NotThreadLocal);
      }

      ID.ConstantVal = FwdRef;
      ID.Kind = ValID::t_Constant;
      return false;
    }

    if (!GV->getValueType()->isFunctionTy())
      return error(Fn.Loc, "expected a function, alias to function, or ifunc "
                           "in dso_local_equivalent");

    ID.ConstantVal = DSOLocalEquivalent::get(GV);
    ID.Kind = ValID::t_Constant;
    return false;
  }

  case lltok::kw_no_cfi: {
    // ValID ::= 'no_cfi' @foo
    Lex.Lex();

    if (parseValID(ID, PFS))
      return true;

    if (ID.Kind != ValID::t_GlobalID && ID.Kind != ValID::t_GlobalName)
      return error(ID.Loc, "expected global value name in no_cfi");

    ID.NoCFI = true;
    return false;
  }
  case lltok::kw_ptrauth: {
    // ValID ::= 'ptrauth' '(' ptr @foo ',' i32 <key>
    //                         (',' i64 <disc> (',' ptr addrdisc)? )? ')'
    Lex.Lex();

    Constant *Ptr, *Key;
    Constant *Disc = nullptr, *AddrDisc = nullptr;

    if (parseToken(lltok::lparen,
                   "expected '(' in constant ptrauth expression") ||
        parseGlobalTypeAndValue(Ptr) ||
        parseToken(lltok::comma,
                   "expected comma in constant ptrauth expression") ||
        parseGlobalTypeAndValue(Key))
      return true;
    // If present, parse the optional disc/addrdisc.
    if (EatIfPresent(lltok::comma))
      if (parseGlobalTypeAndValue(Disc) ||
          (EatIfPresent(lltok::comma) && parseGlobalTypeAndValue(AddrDisc)))
        return true;
    if (parseToken(lltok::rparen,
                   "expected ')' in constant ptrauth expression"))
      return true;

    if (!Ptr->getType()->isPointerTy())
      return error(ID.Loc, "constant ptrauth base pointer must be a pointer");

    auto *KeyC = dyn_cast<ConstantInt>(Key);
    if (!KeyC || KeyC->getBitWidth() != 32)
      return error(ID.Loc, "constant ptrauth key must be i32 constant");

    ConstantInt *DiscC = nullptr;
    if (Disc) {
      DiscC = dyn_cast<ConstantInt>(Disc);
      if (!DiscC || DiscC->getBitWidth() != 64)
        return error(
            ID.Loc,
            "constant ptrauth integer discriminator must be i64 constant");
    } else {
      DiscC = ConstantInt::get(Type::getInt64Ty(Context), 0);
    }

    if (AddrDisc) {
      if (!AddrDisc->getType()->isPointerTy())
        return error(
            ID.Loc, "constant ptrauth address discriminator must be a pointer");
    } else {
      AddrDisc = ConstantPointerNull::get(PointerType::get(Context, 0));
    }

    ID.ConstantVal = ConstantPtrAuth::get(Ptr, KeyC, DiscC, AddrDisc);
    ID.Kind = ValID::t_Constant;
    return false;
  }

  case lltok::kw_trunc:
  case lltok::kw_bitcast:
  case lltok::kw_addrspacecast:
  case lltok::kw_inttoptr:
  case lltok::kw_ptrtoaddr:
  case lltok::kw_ptrtoint: {
    unsigned Opc = Lex.getUIntVal();
    Type *DestTy = nullptr;
    Constant *SrcVal;
    Lex.Lex();
    if (parseToken(lltok::lparen, "expected '(' after constantexpr cast") ||
        parseGlobalTypeAndValue(SrcVal) ||
        parseToken(lltok::kw_to, "expected 'to' in constantexpr cast") ||
        parseType(DestTy) ||
        parseToken(lltok::rparen, "expected ')' at end of constantexpr cast"))
      return true;
    if (!CastInst::castIsValid((Instruction::CastOps)Opc, SrcVal, DestTy))
      return error(ID.Loc, "invalid cast opcode for cast from '" +
                               getTypeString(SrcVal->getType()) + "' to '" +
                               getTypeString(DestTy) + "'");
    ID.ConstantVal = ConstantExpr::getCast((Instruction::CastOps)Opc,
                                                 SrcVal, DestTy);
    ID.Kind = ValID::t_Constant;
    return false;
  }
  case lltok::kw_extractvalue:
    return error(ID.Loc, "extractvalue constexprs are no longer supported");
  case lltok::kw_insertvalue:
    return error(ID.Loc, "insertvalue constexprs are no longer supported");
  case lltok::kw_udiv:
    return error(ID.Loc, "udiv constexprs are no longer supported");
  case lltok::kw_sdiv:
    return error(ID.Loc, "sdiv constexprs are no longer supported");
  case lltok::kw_urem:
    return error(ID.Loc, "urem constexprs are no longer supported");
  case lltok::kw_srem:
    return error(ID.Loc, "srem constexprs are no longer supported");
  case lltok::kw_fadd:
    return error(ID.Loc, "fadd constexprs are no longer supported");
  case lltok::kw_fsub:
    return error(ID.Loc, "fsub constexprs are no longer supported");
  case lltok::kw_fmul:
    return error(ID.Loc, "fmul constexprs are no longer supported");
  case lltok::kw_fdiv:
    return error(ID.Loc, "fdiv constexprs are no longer supported");
  case lltok::kw_frem:
    return error(ID.Loc, "frem constexprs are no longer supported");
  case lltok::kw_and:
    return error(ID.Loc, "and constexprs are no longer supported");
  case lltok::kw_or:
    return error(ID.Loc, "or constexprs are no longer supported");
  case lltok::kw_lshr:
    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_mul:
    return error(ID.Loc, "mul constexprs are no longer supported");
  case lltok::kw_fneg:
    return error(ID.Loc, "fneg constexprs are no longer supported");
  case lltok::kw_select:
    return error(ID.Loc, "select constexprs are no longer supported");
  case lltok::kw_zext:
    return error(ID.Loc, "zext constexprs are no longer supported");
  case lltok::kw_sext:
    return error(ID.Loc, "sext constexprs are no longer supported");
  case lltok::kw_fptrunc:
    return error(ID.Loc, "fptrunc constexprs are no longer supported");
  case lltok::kw_fpext:
    return error(ID.Loc, "fpext constexprs are no longer supported");
  case lltok::kw_uitofp:
    return error(ID.Loc, "uitofp constexprs are no longer supported");
  case lltok::kw_sitofp:
    return error(ID.Loc, "sitofp constexprs are no longer supported");
  case lltok::kw_fptoui:
    return error(ID.Loc, "fptoui constexprs are no longer supported");
  case lltok::kw_fptosi:
    return error(ID.Loc, "fptosi constexprs are no longer supported");
  case lltok::kw_icmp:
    return error(ID.Loc, "icmp constexprs are no longer supported");
  case lltok::kw_fcmp:
    return error(ID.Loc, "fcmp constexprs are no longer supported");

  // Binary Operators.
  case lltok::kw_add:
  case lltok::kw_sub:
  case lltok::kw_xor: {
    bool NUW = false;
    bool NSW = false;
    unsigned Opc = Lex.getUIntVal();
    Constant *Val0, *Val1;
    Lex.Lex();
    if (Opc == Instruction::Add || Opc == Instruction::Sub ||
        Opc == Instruction::Mul) {
      if (EatIfPresent(lltok::kw_nuw))
        NUW = true;
      if (EatIfPresent(lltok::kw_nsw)) {
        NSW = true;
        if (EatIfPresent(lltok::kw_nuw))
          NUW = true;
      }
    }
    if (parseToken(lltok::lparen, "expected '(' in binary constantexpr") ||
        parseGlobalTypeAndValue(Val0) ||
        parseToken(lltok::comma, "expected comma in binary constantexpr") ||
        parseGlobalTypeAndValue(Val1) ||
        parseToken(lltok::rparen, "expected ')' in binary constantexpr"))
      return true;
    if (Val0->getType() != Val1->getType())
      return error(ID.Loc, "operands of constexpr must have same type");
    // Check that the type is valid for the operator.
    if (!Val0->getType()->isIntOrIntVectorTy())
      return error(ID.Loc,
                   "constexpr requires integer or integer vector operands");
    unsigned Flags = 0;
    if (NUW)   Flags |= OverflowingBinaryOperator::NoUnsignedWrap;
    if (NSW)   Flags |= OverflowingBinaryOperator::NoSignedWrap;
    ID.ConstantVal = ConstantExpr::get(Opc, Val0, Val1, Flags);
    ID.Kind = ValID::t_Constant;
    return false;
  }

  case lltok::kw_splat: {
    Lex.Lex();
    if (parseToken(lltok::lparen, "expected '(' after vector splat"))
      return true;
    Constant *C;
    if (parseGlobalTypeAndValue(C))
      return true;
    if (parseToken(lltok::rparen, "expected ')' at end of vector splat"))
      return true;

    ID.ConstantVal = C;
    ID.Kind = ValID::t_ConstantSplat;
    return false;
  }

  case lltok::kw_getelementptr:
  case lltok::kw_shufflevector:
  case lltok::kw_insertelement:
  case lltok::kw_extractelement: {
    unsigned Opc = Lex.getUIntVal();
    SmallVector<Constant*, 16> Elts;
    GEPNoWrapFlags NW;
    bool HasInRange = false;
    APSInt InRangeStart;
    APSInt InRangeEnd;
    Type *Ty;
    Lex.Lex();

    if (Opc == Instruction::GetElementPtr) {
      while (true) {
        if (EatIfPresent(lltok::kw_inbounds))
          NW |= GEPNoWrapFlags::inBounds();
        else if (EatIfPresent(lltok::kw_nusw))
          NW |= GEPNoWrapFlags::noUnsignedSignedWrap();
        else if (EatIfPresent(lltok::kw_nuw))
          NW |= GEPNoWrapFlags::noUnsignedWrap();
        else
          break;
      }

      if (EatIfPresent(lltok::kw_inrange)) {
        if (parseToken(lltok::lparen, "expected '('"))
          return true;
        if (Lex.getKind() != lltok::APSInt)
          return tokError("expected integer");
        InRangeStart = Lex.getAPSIntVal();
        Lex.Lex();
        if (parseToken(lltok::comma, "expected ','"))
          return true;
        if (Lex.getKind() != lltok::APSInt)
          return tokError("expected integer");
        InRangeEnd = Lex.getAPSIntVal();
        Lex.Lex();
        if (parseToken(lltok::rparen, "expected ')'"))
          return true;
        HasInRange = true;
      }
    }

    if (parseToken(lltok::lparen, "expected '(' in constantexpr"))
      return true;

    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()->isPtrOrPtrVectorTy())
        return error(ID.Loc, "base of getelementptr must be a pointer");

      Type *BaseType = Elts[0]->getType();
      std::optional<ConstantRange> InRange;
      if (HasInRange) {
        unsigned IndexWidth =
            M->getDataLayout().getIndexTypeSizeInBits(BaseType);
        InRangeStart = InRangeStart.extOrTrunc(IndexWidth);
        InRangeEnd = InRangeEnd.extOrTrunc(IndexWidth);
        if (InRangeStart.sge(InRangeEnd))
          return error(ID.Loc, "expected end to be larger than start");
        InRange = ConstantRange::getNonEmpty(InRangeStart, InRangeEnd);
      }

      unsigned GEPWidth =
          BaseType->isVectorTy()
              ? cast<FixedVectorType>(BaseType)->getNumElements()
              : 0;

      ArrayRef<Constant *> Indices(Elts.begin() + 1, Elts.end());
      for (Constant *Val : Indices) {
        Type *ValTy = Val->getType();
        if (!ValTy->isIntOrIntVectorTy())
          return error(ID.Loc, "getelementptr index must be an integer");
        if (auto *ValVTy = dyn_cast<VectorType>(ValTy)) {
          unsigned ValNumEl = cast<FixedVectorType>(ValVTy)->getNumElements();
          if (GEPWidth && (ValNumEl != GEPWidth))
            return error(
                ID.Loc,
                "getelementptr vector index has a wrong number of elements");
          // GEPWidth may have been unknown because the base is a scalar,
          // but it is known now.
          GEPWidth = ValNumEl;
        }
      }

      SmallPtrSet<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, NW, InRange);
    } else if (Opc == Instruction::ShuffleVector) {
      if (Elts.size() != 3)
        return error(ID.Loc, "expected three operands to shufflevector");
      if (!ShuffleVectorInst::isValidOperands(Elts[0], Elts[1], Elts[2]))
        return error(ID.Loc, "invalid operands to shufflevector");
      SmallVector<int, 16> Mask;
      ShuffleVectorInst::getShuffleMask(cast<Constant>(Elts[2]), Mask);
      ID.ConstantVal = ConstantExpr::getShuffleVector(Elts[0], Elts[1], Mask);
    } else if (Opc == Instruction::ExtractElement) {
      if (Elts.size() != 2)
        return error(ID.Loc, "expected two operands to extractelement");
      if (!ExtractElementInst::isValidOperands(Elts[0], Elts[1]))
        return error(ID.Loc, "invalid extractelement operands");
      ID.ConstantVal = ConstantExpr::getExtractElement(Elts[0], Elts[1]);
    } else {
      assert(Opc == Instruction::InsertElement && "Unknown opcode");
      if (Elts.size() != 3)
        return error(ID.Loc, "expected three operands to insertelement");
      if (!InsertElementInst::isValidOperands(Elts[0], Elts[1], Elts[2]))
        return error(ID.Loc, "invalid insertelement operands");
      ID.ConstantVal =
                 ConstantExpr::getInsertElement(Elts[0], Elts[1],Elts[2]);
    }

    ID.Kind = ValID::t_Constant;
    return false;
  }
  }

  Lex.Lex();
  return false;
}

/// parseGlobalValue - parse a global value with the specified type.
bool LLParser::parseGlobalValue(Type *Ty, Constant *&C) {
  C = nullptr;
  ValID ID;
  Value *V = nullptr;
  bool Parsed = parseValID(ID, /*PFS=*/nullptr, Ty) ||
                convertValIDToValue(Ty, ID, V, nullptr);
  if (V && !(C = dyn_cast<Constant>(V)))
    return error(ID.Loc, "global values must be constants");
  return Parsed;
}

bool LLParser::parseGlobalTypeAndValue(Constant *&V) {
  Type *Ty = nullptr;
  return parseType(Ty) || parseGlobalValue(Ty, V);
}

bool LLParser::parseOptionalComdat(StringRef GlobalName, Comdat *&C) {
  C = nullptr;

  LocTy KwLoc = Lex.getLoc();
  if (!EatIfPresent(lltok::kw_comdat))
    return false;

  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(std::string(GlobalName), KwLoc);
  }

  return false;
}

/// parseGlobalValueVector
///   ::= /*empty*/
///   ::= TypeAndValue (',' TypeAndValue)*
bool LLParser::parseGlobalValueVector(SmallVectorImpl<Constant *> &Elts) {
  // Empty list.
  if (Lex.getKind() == lltok::rbrace ||
      Lex.getKind() == lltok::rsquare ||
      Lex.getKind() == lltok::greater ||
      Lex.getKind() == lltok::rparen)
    return false;

  do {
    // Let the caller deal with inrange.
    if (Lex.getKind() == lltok::kw_inrange)
      return false;

    Constant *C;
    if (parseGlobalTypeAndValue(C))
      return true;
    Elts.push_back(C);
  } while (EatIfPresent(lltok::comma));

  return false;
}

bool LLParser::parseMDTuple(MDNode *&MD, bool IsDistinct) {
  SmallVector<Metadata *, 16> Elts;
  if (parseMDNodeVector(Elts))
    return true;

  MD = (IsDistinct ? MDTuple::getDistinct : MDTuple::get)(Context, Elts);
  return false;
}

/// MDNode:
///  ::= !{ ... }
///  ::= !7
///  ::= !DILocation(...)
bool LLParser::parseMDNode(MDNode *&N) {
  if (Lex.getKind() == lltok::MetadataVar)
    return parseSpecializedMDNode(N);

  return parseToken(lltok::exclaim, "expected '!' here") || parseMDNodeTail(N);
}

bool LLParser::parseMDNodeTail(MDNode *&N) {
  // !{ ... }
  if (Lex.getKind() == lltok::lbrace)
    return parseMDTuple(N);

  // !42
  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) {}
};

/// Structure to represent an optional metadata field that
/// can be of either type (A or B) and encapsulates the
/// MD<typeofA>Field and MD<typeofB>Field structs, so not
/// to reimplement the specifics for representing each Field.
template <class FieldTypeA, class FieldTypeB> struct MDEitherFieldImpl {
  typedef MDEitherFieldImpl<FieldTypeA, FieldTypeB> ImplTy;
  FieldTypeA A;
  FieldTypeB B;
  bool Seen;

  enum {
    IsInvalid = 0,
    IsTypeA = 1,
    IsTypeB = 2
  } WhatIs;

  void assign(FieldTypeA A) {
    Seen = true;
    this->A = std::move(A);
    WhatIs = IsTypeA;
  }

  void assign(FieldTypeB B) {
    Seen = true;
    this->B = std::move(B);
    WhatIs = IsTypeB;
  }

  explicit MDEitherFieldImpl(FieldTypeA DefaultA, FieldTypeB DefaultB)
      : A(std::move(DefaultA)), B(std::move(DefaultB)), Seen(false),
        WhatIs(IsInvalid) {}
};

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 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) {}
};

struct DwarfVirtualityField : public MDUnsignedField {
  DwarfVirtualityField() : MDUnsignedField(0, dwarf::DW_VIRTUALITY_max) {}
};

struct DwarfLangField : public MDUnsignedField {
  DwarfLangField() : MDUnsignedField(0, dwarf::DW_LANG_hi_user) {}
};

struct DwarfCCField : public MDUnsignedField {
  DwarfCCField() : MDUnsignedField(0, dwarf::DW_CC_hi_user) {}
};

struct DwarfEnumKindField : public MDUnsignedField {
  DwarfEnumKindField()
      : MDUnsignedField(dwarf::DW_APPLE_ENUM_KIND_invalid,
                        dwarf::DW_APPLE_ENUM_KIND_max) {}
};

struct EmissionKindField : public MDUnsignedField {
  EmissionKindField() : MDUnsignedField(0, DICompileUnit::LastEmissionKind) {}
};

struct FixedPointKindField : public MDUnsignedField {
  FixedPointKindField()
      : MDUnsignedField(0, DIFixedPointType::LastFixedPointKind) {}
};

struct NameTableKindField : public MDUnsignedField {
  NameTableKindField()
      : MDUnsignedField(
            0, (unsigned)
                   DICompileUnit::DebugNameTableKind::LastDebugNameTableKind) {}
};

struct DIFlagField : public MDFieldImpl<DINode::DIFlags> {
  DIFlagField() : MDFieldImpl(DINode::FlagZero) {}
};

struct DISPFlagField : public MDFieldImpl<DISubprogram::DISPFlags> {
  DISPFlagField() : MDFieldImpl(DISubprogram::SPFlagZero) {}
};

struct MDAPSIntField : public MDFieldImpl<APSInt> {
  MDAPSIntField() : ImplTy(APSInt()) {}
};

struct MDSignedField : public MDFieldImpl<int64_t> {
  int64_t Min = INT64_MIN;
  int64_t Max = INT64_MAX;

  MDSignedField(int64_t Default = 0)
      : ImplTy(Default) {}
  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 MDStringField : public MDFieldImpl<MDString *> {
  enum class EmptyIs {
    Null,  //< Allow empty input string, map to nullptr
    Empty, //< Allow empty input string, map to an empty MDString
    Error, //< Disallow empty string, map to an error
  } EmptyIs;
  MDStringField(enum EmptyIs EmptyIs = EmptyIs::Null)
      : ImplTy(nullptr), EmptyIs(EmptyIs) {}
};

struct MDFieldList : public MDFieldImpl<SmallVector<Metadata *, 4>> {
  MDFieldList() : ImplTy(SmallVector<Metadata *, 4>()) {}
};

struct ChecksumKindField : public MDFieldImpl<DIFile::ChecksumKind> {
  ChecksumKindField(DIFile::ChecksumKind CSKind) : ImplTy(CSKind) {}
};

struct MDSignedOrMDField : MDEitherFieldImpl<MDSignedField, MDField> {
  MDSignedOrMDField(int64_t Default = 0, bool AllowNull = true)
      : ImplTy(MDSignedField(Default), MDField(AllowNull)) {}

  MDSignedOrMDField(int64_t Default, int64_t Min, int64_t Max,
                    bool AllowNull = true)
      : ImplTy(MDSignedField(Default, Min, Max), MDField(AllowNull)) {}

  bool isMDSignedField() const { return WhatIs == IsTypeA; }
  bool isMDField() const { return WhatIs == IsTypeB; }
  int64_t getMDSignedValue() const {
    assert(isMDSignedField() && "Wrong field type");
    return A.Val;
  }
  Metadata *getMDFieldValue() const {
    assert(isMDField() && "Wrong field type");
    return B.Val;
  }
};

struct MDUnsignedOrMDField : MDEitherFieldImpl<MDUnsignedField, MDField> {
  MDUnsignedOrMDField(uint64_t Default = 0, bool AllowNull = true)
      : ImplTy(MDUnsignedField(Default), MDField(AllowNull)) {}

  MDUnsignedOrMDField(uint64_t Default, uint64_t Max, bool AllowNull = true)
      : ImplTy(MDUnsignedField(Default, Max), MDField(AllowNull)) {}

  bool isMDUnsignedField() const { return WhatIs == IsTypeA; }
  bool isMDField() const { return WhatIs == IsTypeB; }
  uint64_t getMDUnsignedValue() const {
    assert(isMDUnsignedField() && "Wrong field type");
    return A.Val;
  }
  Metadata *getMDFieldValue() const {
    assert(isMDField() && "Wrong field type");
    return B.Val;
  }

  Metadata *getValueAsMetadata(LLVMContext &Context) const {
    if (isMDUnsignedField())
      return ConstantAsMetadata::get(
          ConstantInt::get(Type::getInt64Ty(Context), getMDUnsignedValue()));
    if (isMDField())
      return getMDFieldValue();
    return nullptr;
  }
};

} // end anonymous namespace

namespace llvm {

template <>
bool LLParser::parseMDField(LocTy Loc, StringRef Name, MDAPSIntField &Result) {
  if (Lex.getKind() != lltok::APSInt)
    return tokError("expected integer");

  Result.assign(Lex.getAPSIntVal());
  Lex.Lex();
  return false;
}

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,
                            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));

  if (Lex.getKind() != lltok::DwarfVirtuality)
    return tokError("expected DWARF virtuality code");

  unsigned Virtuality = dwarf::getVirtuality(Lex.getStrVal());
  if (Virtuality == dwarf::DW_VIRTUALITY_invalid)
    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,
                            DwarfEnumKindField &Result) {
  if (Lex.getKind() == lltok::APSInt)
    return parseMDField(Loc, Name, static_cast<MDUnsignedField &>(Result));

  if (Lex.getKind() != lltok::DwarfEnumKind)
    return tokError("expected DWARF enum kind code");

  unsigned EnumKind = dwarf::getEnumKind(Lex.getStrVal());
  if (EnumKind == dwarf::DW_APPLE_ENUM_KIND_invalid)
    return tokError("invalid DWARF enum kind code" + Twine(" '") +
                    Lex.getStrVal() + "'");
  assert(EnumKind <= Result.Max && "Expected valid DWARF enum kind code");
  Result.assign(EnumKind);
  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, DwarfCCField &Result) {
  if (Lex.getKind() == lltok::APSInt)
    return parseMDField(Loc, Name, static_cast<MDUnsignedField &>(Result));

  if (Lex.getKind() != lltok::DwarfCC)
    return tokError("expected DWARF calling convention");

  unsigned CC = dwarf::getCallingConvention(Lex.getStrVal());
  if (!CC)
    return tokError("invalid DWARF calling convention" + Twine(" '") +
                    Lex.getStrVal() + "'");
  assert(CC <= Result.Max && "Expected valid DWARF calling convention");
  Result.assign(CC);
  Lex.Lex();
  return false;
}

template <>
bool LLParser::parseMDField(LocTy Loc, StringRef Name,
                            EmissionKindField &Result) {
  if (Lex.getKind() == lltok::APSInt)
    return parseMDField(Loc, Name, static_cast<MDUnsignedField &>(Result));

  if (Lex.getKind() != lltok::EmissionKind)
    return tokError("expected emission kind");

  auto Kind = DICompileUnit::getEmissionKind(Lex.getStrVal());
  if (!Kind)
    return tokError("invalid emission kind" + Twine(" '") + Lex.getStrVal() +
                    "'");
  assert(*Kind <= Result.Max && "Expected valid emission kind");
  Result.assign(*Kind);
  Lex.Lex();
  return false;
}

template <>
bool LLParser::parseMDField(LocTy Loc, StringRef Name,
                            FixedPointKindField &Result) {
  if (Lex.getKind() == lltok::APSInt)
    return parseMDField(Loc, Name, static_cast<MDUnsignedField &>(Result));

  if (Lex.getKind() != lltok::FixedPointKind)
    return tokError("expected fixed-point kind");

  auto Kind = DIFixedPointType::getFixedPointKind(Lex.getStrVal());
  if (!Kind)
    return tokError("invalid fixed-point kind" + Twine(" '") + Lex.getStrVal() +
                    "'");
  assert(*Kind <= Result.Max && "Expected valid fixed-point kind");
  Result.assign(*Kind);
  Lex.Lex();
  return false;
}

template <>
bool LLParser::parseMDField(LocTy Loc, StringRef Name,
                            NameTableKindField &Result) {
  if (Lex.getKind() == lltok::APSInt)
    return parseMDField(Loc, Name, static_cast<MDUnsignedField &>(Result));

  if (Lex.getKind() != lltok::NameTableKind)
    return tokError("expected nameTable kind");

  auto Kind = DICompileUnit::getNameTableKind(Lex.getStrVal());
  if (!Kind)
    return tokError("invalid nameTable kind" + Twine(" '") + Lex.getStrVal() +
                    "'");
  assert(((unsigned)*Kind) <= Result.Max && "Expected valid nameTable kind");
  Result.assign((unsigned)*Kind);
  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) {

  // parser for a single flag.
  auto parseFlag = [&](DINode::DIFlags &Val) {
    if (Lex.getKind() == lltok::APSInt && !Lex.getAPSIntVal().isSigned()) {
      uint32_t TempVal = static_cast<uint32_t>(Val);
      bool Res = parseUInt32(TempVal);
      Val = static_cast<DINode::DIFlags>(TempVal);
      return Res;
    }

    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 '") + Lex.getStrVal() +
                      "'");
    Lex.Lex();
    return false;
  };

  // parse the flags and combine them together.
  DINode::DIFlags Combined = DINode::FlagZero;
  do {
    DINode::DIFlags Val;
    if (parseFlag(Val))
      return true;
    Combined |= Val;
  } while (EatIfPresent(lltok::bar));

  Result.assign(Combined);
  return false;
}

/// DISPFlagField
///  ::= uint32
///  ::= DISPFlagVector
///  ::= DISPFlagVector '|' DISPFlag* '|' uint32
template <>
bool LLParser::parseMDField(LocTy Loc, StringRef Name, DISPFlagField &Result) {

  // parser for a single flag.
  auto parseFlag = [&](DISubprogram::DISPFlags &Val) {
    if (Lex.getKind() == lltok::APSInt && !Lex.getAPSIntVal().isSigned()) {
      uint32_t TempVal = static_cast<uint32_t>(Val);
      bool Res = parseUInt32(TempVal);
      Val = static_cast<DISubprogram::DISPFlags>(TempVal);
      return Res;
    }

    if (Lex.getKind() != lltok::DISPFlag)
      return tokError("expected debug info flag");

    Val = DISubprogram::getFlag(Lex.getStrVal());
    if (!Val)
      return tokError(Twine("invalid subprogram debug info flag '") +
                      Lex.getStrVal() + "'");
    Lex.Lex();
    return false;
  };

  // parse the flags and combine them together.
  DISubprogram::DISPFlags Combined = DISubprogram::SPFlagZero;
  do {
    DISubprogram::DISPFlags 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,
                            MDSignedOrMDField &Result) {
  // Try to parse a signed int.
  if (Lex.getKind() == lltok::APSInt) {
    MDSignedField Res = Result.A;
    if (!parseMDField(Loc, Name, Res)) {
      Result.assign(Res);
      return false;
    }
    return true;
  }

  // Otherwise, try to parse as an MDField.
  MDField Res = Result.B;
  if (!parseMDField(Loc, Name, Res)) {
    Result.assign(Res);
    return false;
  }

  return true;
}

template <>
bool LLParser::parseMDField(LocTy Loc, StringRef Name,
                            MDUnsignedOrMDField &Result) {
  // Try to parse an unsigned int.
  if (Lex.getKind() == lltok::APSInt) {
    MDUnsignedField Res = Result.A;
    if (!parseMDField(Loc, Name, Res)) {
      Result.assign(Res);
      return false;
    }
    return true;
  }

  // Otherwise, try to parse as an MDField.
  MDField Res = Result.B;
  if (!parseMDField(Loc, Name, Res)) {
    Result.assign(Res);
    return false;
  }

  return true;
}

template <>
bool LLParser::parseMDField(LocTy Loc, StringRef Name, MDStringField &Result) {
  LocTy ValueLoc = Lex.getLoc();
  std::string S;
  if (parseStringConstant(S))
    return true;

  if (S.empty()) {
    switch (Result.EmptyIs) {
    case MDStringField::EmptyIs::Null:
      Result.assign(nullptr);
      return false;
    case MDStringField::EmptyIs::Empty:
      break;
    case MDStringField::EmptyIs::Error:
      return error(ValueLoc, "'" + Name + "' cannot be empty");
    }
  }

  Result.assign(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;
}

template <>
bool LLParser::parseMDField(LocTy Loc, StringRef Name,
                            ChecksumKindField &Result) {
  std::optional<DIFile::ChecksumKind> CSKind =
      DIFile::getChecksumKind(Lex.getStrVal());

  if (Lex.getKind() != lltok::ChecksumKind || !CSKind)
    return tokError("invalid checksum kind" + Twine(" '") + Lex.getStrVal() +
                    "'");

  Result.assign(*CSKind);
  Lex.Lex();
  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,
///   isImplicitCode: true, atomGroup: 1, atomRank: 1)
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, );                                              \
  OPTIONAL(isImplicitCode, MDBoolField, (false));                              \
  OPTIONAL(atomGroup, MDUnsignedField, (0, UINT64_MAX));                       \
  OPTIONAL(atomRank, MDUnsignedField, (0, UINT8_MAX));
  PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS

  Result = GET_OR_DISTINCT(
      DILocation, (Context, line.Val, column.Val, scope.Val, inlinedAt.Val,
                   isImplicitCode.Val, atomGroup.Val, atomRank.Val));
  return false;
}

/// parseDIAssignID:
///   ::= distinct !DIAssignID()
bool LLParser::parseDIAssignID(MDNode *&Result, bool IsDistinct) {
  if (!IsDistinct)
    return tokError("missing 'distinct', required for !DIAssignID()");

  Lex.Lex();

  // Now eat the parens.
  if (parseToken(lltok::lparen, "expected '(' here"))
    return true;
  if (parseToken(lltok::rparen, "expected ')' here"))
    return true;

  Result = DIAssignID::getDistinct(Context);
  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;
}

/// parseDISubrangeType:
///   ::= !DISubrangeType(name: "whatever", file: !0,
///                      line: 7, scope: !1, baseType: !2, size: 32,
///                      align: 32, flags: 0, lowerBound: !3
///                      upperBound: !4, stride: !5, bias: !6)
bool LLParser::parseDISubrangeType(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED)                                    \
  OPTIONAL(name, MDStringField, );                                             \
  OPTIONAL(file, MDField, );                                                   \
  OPTIONAL(line, LineField, );                                                 \
  OPTIONAL(scope, MDField, );                                                  \
  OPTIONAL(baseType, MDField, );                                               \
  OPTIONAL(size, MDUnsignedOrMDField, (0, UINT64_MAX));                        \
  OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX));                           \
  OPTIONAL(flags, DIFlagField, );                                              \
  OPTIONAL(lowerBound, MDSignedOrMDField, );                                   \
  OPTIONAL(upperBound, MDSignedOrMDField, );                                   \
  OPTIONAL(stride, MDSignedOrMDField, );                                       \
  OPTIONAL(bias, MDSignedOrMDField, );
  PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS

  auto convToMetadata = [&](MDSignedOrMDField Bound) -> Metadata * {
    if (Bound.isMDSignedField())
      return ConstantAsMetadata::get(ConstantInt::getSigned(
          Type::getInt64Ty(Context), Bound.getMDSignedValue()));
    if (Bound.isMDField())
      return Bound.getMDFieldValue();
    return nullptr;
  };

  Metadata *LowerBound = convToMetadata(lowerBound);
  Metadata *UpperBound = convToMetadata(upperBound);
  Metadata *Stride = convToMetadata(stride);
  Metadata *Bias = convToMetadata(bias);

  Result = GET_OR_DISTINCT(
      DISubrangeType, (Context, name.Val, file.Val, line.Val, scope.Val,
                       size.getValueAsMetadata(Context), align.Val, flags.Val,
                       baseType.Val, LowerBound, UpperBound, Stride, Bias));

  return false;
}

/// parseDISubrange:
///   ::= !DISubrange(count: 30, lowerBound: 2)
///   ::= !DISubrange(count: !node, lowerBound: 2)
///   ::= !DISubrange(lowerBound: !node1, upperBound: !node2, stride: !node3)
bool LLParser::parseDISubrange(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED)                                    \
  OPTIONAL(count, MDSignedOrMDField, (-1, -1, INT64_MAX, false));              \
  OPTIONAL(lowerBound, MDSignedOrMDField, );                                   \
  OPTIONAL(upperBound, MDSignedOrMDField, );                                   \
  OPTIONAL(stride, MDSignedOrMDField, );
  PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS

  Metadata *Count = nullptr;
  Metadata *LowerBound = nullptr;
  Metadata *UpperBound = nullptr;
  Metadata *Stride = nullptr;

  auto convToMetadata = [&](const MDSignedOrMDField &Bound) -> Metadata * {
    if (Bound.isMDSignedField())
      return ConstantAsMetadata::get(ConstantInt::getSigned(
          Type::getInt64Ty(Context), Bound.getMDSignedValue()));
    if (Bound.isMDField())
      return Bound.getMDFieldValue();
    return nullptr;
  };

  Count = convToMetadata(count);
  LowerBound = convToMetadata(lowerBound);
  UpperBound = convToMetadata(upperBound);
  Stride = convToMetadata(stride);

  Result = GET_OR_DISTINCT(DISubrange,
                           (Context, Count, LowerBound, UpperBound, Stride));

  return false;
}

/// parseDIGenericSubrange:
///   ::= !DIGenericSubrange(lowerBound: !node1, upperBound: !node2, stride:
///   !node3)
bool LLParser::parseDIGenericSubrange(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED)                                    \
  OPTIONAL(count, MDSignedOrMDField, );                                        \
  OPTIONAL(lowerBound, MDSignedOrMDField, );                                   \
  OPTIONAL(upperBound, MDSignedOrMDField, );                                   \
  OPTIONAL(stride, MDSignedOrMDField, );
  PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS

  auto ConvToMetadata = [&](const MDSignedOrMDField &Bound) -> Metadata * {
    if (Bound.isMDSignedField())
      return DIExpression::get(
          Context, {dwarf::DW_OP_consts,
                    static_cast<uint64_t>(Bound.getMDSignedValue())});
    if (Bound.isMDField())
      return Bound.getMDFieldValue();
    return nullptr;
  };

  Metadata *Count = ConvToMetadata(count);
  Metadata *LowerBound = ConvToMetadata(lowerBound);
  Metadata *UpperBound = ConvToMetadata(upperBound);
  Metadata *Stride = ConvToMetadata(stride);

  Result = GET_OR_DISTINCT(DIGenericSubrange,
                           (Context, Count, LowerBound, UpperBound, Stride));

  return false;
}

/// parseDIEnumerator:
///   ::= !DIEnumerator(value: 30, isUnsigned: true, name: "SomeKind")
bool LLParser::parseDIEnumerator(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED)                                    \
  REQUIRED(name, MDStringField, );                                             \
  REQUIRED(value, MDAPSIntField, );                                            \
  OPTIONAL(isUnsigned, MDBoolField, (false));
  PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS

  if (isUnsigned.Val && value.Val.isNegative())
    return tokError("unsigned enumerator with negative value");

  APSInt Value(value.Val);
  // Add a leading zero so that unsigned values with the msb set are not
  // mistaken for negative values when used for signed enumerators.
  if (!isUnsigned.Val && value.Val.isUnsigned() && value.Val.isSignBitSet())
    Value = Value.zext(Value.getBitWidth() + 1);

  Result =
      GET_OR_DISTINCT(DIEnumerator, (Context, Value, isUnsigned.Val, name.Val));

  return false;
}

/// parseDIBasicType:
///   ::= !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32,
///                    encoding: DW_ATE_encoding, flags: 0)
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, MDUnsignedOrMDField, (0, UINT64_MAX));                        \
  OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX));                           \
  OPTIONAL(encoding, DwarfAttEncodingField, );                                 \
  OPTIONAL(num_extra_inhabitants, MDUnsignedField, (0, UINT32_MAX));           \
  OPTIONAL(flags, DIFlagField, );
  PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS

  Result = GET_OR_DISTINCT(DIBasicType, (Context, tag.Val, name.Val,
                                         size.getValueAsMetadata(Context),
                                         align.Val, encoding.Val,
                                         num_extra_inhabitants.Val, flags.Val));
  return false;
}

/// parseDIFixedPointType:
///   ::= !DIFixedPointType(tag: DW_TAG_base_type, name: "xyz", size: 32,
///                         align: 32, encoding: DW_ATE_signed_fixed,
///                         flags: 0, kind: Rational, factor: 3, numerator: 1,
///                         denominator: 8)
bool LLParser::parseDIFixedPointType(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED)                                    \
  OPTIONAL(tag, DwarfTagField, (dwarf::DW_TAG_base_type));                     \
  OPTIONAL(name, MDStringField, );                                             \
  OPTIONAL(size, MDUnsignedOrMDField, (0, UINT64_MAX));                        \
  OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX));                           \
  OPTIONAL(encoding, DwarfAttEncodingField, );                                 \
  OPTIONAL(flags, DIFlagField, );                                              \
  OPTIONAL(kind, FixedPointKindField, );                                       \
  OPTIONAL(factor, MDSignedField, );                                           \
  OPTIONAL(numerator, MDAPSIntField, );                                        \
  OPTIONAL(denominator, MDAPSIntField, );
  PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS

  Result = GET_OR_DISTINCT(DIFixedPointType,
                           (Context, tag.Val, name.Val,
                            size.getValueAsMetadata(Context), align.Val,
                            encoding.Val, flags.Val, kind.Val, factor.Val,
                            numerator.Val, denominator.Val));
  return false;
}

/// parseDIStringType:
///   ::= !DIStringType(name: "character(4)", size: 32, align: 32)
bool LLParser::parseDIStringType(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED)                                    \
  OPTIONAL(tag, DwarfTagField, (dwarf::DW_TAG_string_type));                   \
  OPTIONAL(name, MDStringField, );                                             \
  OPTIONAL(stringLength, MDField, );                                           \
  OPTIONAL(stringLengthExpression, MDField, );                                 \
  OPTIONAL(stringLocationExpression, MDField, );                               \
  OPTIONAL(size, MDUnsignedOrMDField, (0, UINT64_MAX));                        \
  OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX));                           \
  OPTIONAL(encoding, DwarfAttEncodingField, );
  PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS

  Result = GET_OR_DISTINCT(
      DIStringType,
      (Context, tag.Val, name.Val, stringLength.Val, stringLengthExpression.Val,
       stringLocationExpression.Val, size.getValueAsMetadata(Context),
       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,
///                      dwarfAddressSpace: 3, ptrAuthKey: 1,
///                      ptrAuthIsAddressDiscriminated: true,
///                      ptrAuthExtraDiscriminator: 0x1234,
///                      ptrAuthIsaPointer: 1, ptrAuthAuthenticatesNullValues:1
///                      )
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, MDUnsignedOrMDField, (0, UINT64_MAX));                        \
  OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX));                           \
  OPTIONAL(offset, MDUnsignedOrMDField, (0, UINT64_MAX));                      \
  OPTIONAL(flags, DIFlagField, );                                              \
  OPTIONAL(extraData, MDField, );                                              \
  OPTIONAL(dwarfAddressSpace, MDUnsignedField, (UINT32_MAX, UINT32_MAX));      \
  OPTIONAL(annotations, MDField, );                                            \
  OPTIONAL(ptrAuthKey, MDUnsignedField, (0, 7));                               \
  OPTIONAL(ptrAuthIsAddressDiscriminated, MDBoolField, );                      \
  OPTIONAL(ptrAuthExtraDiscriminator, MDUnsignedField, (0, 0xffff));           \
  OPTIONAL(ptrAuthIsaPointer, MDBoolField, );                                  \
  OPTIONAL(ptrAuthAuthenticatesNullValues, MDBoolField, );
  PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS

  std::optional<unsigned> DWARFAddressSpace;
  if (dwarfAddressSpace.Val != UINT32_MAX)
    DWARFAddressSpace = dwarfAddressSpace.Val;
  std::optional<DIDerivedType::PtrAuthData> PtrAuthData;
  if (ptrAuthKey.Val)
    PtrAuthData.emplace(
        (unsigned)ptrAuthKey.Val, ptrAuthIsAddressDiscriminated.Val,
        (unsigned)ptrAuthExtraDiscriminator.Val, ptrAuthIsaPointer.Val,
        ptrAuthAuthenticatesNullValues.Val);

  Result = GET_OR_DISTINCT(
      DIDerivedType, (Context, tag.Val, name.Val, file.Val, line.Val, scope.Val,
                      baseType.Val, size.getValueAsMetadata(Context), align.Val,
                      offset.getValueAsMetadata(Context), DWARFAddressSpace,
                      PtrAuthData, flags.Val, extraData.Val, annotations.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, MDUnsignedOrMDField, (0, UINT64_MAX));                        \
  OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX));                           \
  OPTIONAL(offset, MDUnsignedOrMDField, (0, UINT64_MAX));                      \
  OPTIONAL(flags, DIFlagField, );                                              \
  OPTIONAL(elements, MDField, );                                               \
  OPTIONAL(runtimeLang, DwarfLangField, );                                     \
  OPTIONAL(enumKind, DwarfEnumKindField, );                                    \
  OPTIONAL(vtableHolder, MDField, );                                           \
  OPTIONAL(templateParams, MDField, );                                         \
  OPTIONAL(identifier, MDStringField, );                                       \
  OPTIONAL(discriminator, MDField, );                                          \
  OPTIONAL(dataLocation, MDField, );                                           \
  OPTIONAL(associated, MDField, );                                             \
  OPTIONAL(allocated, MDField, );                                              \
  OPTIONAL(rank, MDSignedOrMDField, );                                         \
  OPTIONAL(annotations, MDField, );                                            \
  OPTIONAL(num_extra_inhabitants, MDUnsignedField, (0, UINT32_MAX));           \
  OPTIONAL(specification, MDField, );                                          \
  OPTIONAL(bitStride, MDField, );
  PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS

  Metadata *Rank = nullptr;
  if (rank.isMDSignedField())
    Rank = ConstantAsMetadata::get(ConstantInt::getSigned(
        Type::getInt64Ty(Context), rank.getMDSignedValue()));
  else if (rank.isMDField())
    Rank = rank.getMDFieldValue();

  std::optional<unsigned> EnumKind;
  if (enumKind.Val != dwarf::DW_APPLE_ENUM_KIND_invalid)
    EnumKind = enumKind.Val;

  // If this has an identifier try to build an ODR type.
  if (identifier.Val)
    if (auto *CT = DICompositeType::buildODRType(
            Context, *identifier.Val, tag.Val, name.Val, file.Val, line.Val,
            scope.Val, baseType.Val, size.getValueAsMetadata(Context),
            align.Val, offset.getValueAsMetadata(Context), specification.Val,
            num_extra_inhabitants.Val, flags.Val, elements.Val, runtimeLang.Val,
            EnumKind, vtableHolder.Val, templateParams.Val, discriminator.Val,
            dataLocation.Val, associated.Val, allocated.Val, Rank,
            annotations.Val, bitStride.Val)) {
      Result = CT;
      return false;
    }

  // Create a new node, and save it in the context if it belongs in the type
  // map.
  Result = GET_OR_DISTINCT(
      DICompositeType,
      (Context, tag.Val, name.Val, file.Val, line.Val, scope.Val, baseType.Val,
       size.getValueAsMetadata(Context), align.Val,
       offset.getValueAsMetadata(Context), flags.Val, elements.Val,
       runtimeLang.Val, EnumKind, vtableHolder.Val, templateParams.Val,
       identifier.Val, discriminator.Val, dataLocation.Val, associated.Val,
       allocated.Val, Rank, annotations.Val, specification.Val,
       num_extra_inhabitants.Val, bitStride.Val));
  return false;
}

bool LLParser::parseDISubroutineType(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED)                                    \
  OPTIONAL(flags, DIFlagField, );                                              \
  OPTIONAL(cc, DwarfCCField, );                                                \
  REQUIRED(types, MDField, );
  PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS

  Result = GET_OR_DISTINCT(DISubroutineType,
                           (Context, flags.Val, cc.Val, types.Val));
  return false;
}

/// parseDIFileType:
///   ::= !DIFileType(filename: "path/to/file", directory: "/path/to/dir",
///                   checksumkind: CSK_MD5,
///                   checksum: "000102030405060708090a0b0c0d0e0f",
///                   source: "source file contents")
bool LLParser::parseDIFile(MDNode *&Result, bool IsDistinct) {
  // The default constructed value for checksumkind is required, but will never
  // be used, as the parser checks if the field was actually Seen before using
  // the Val.
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED)                                    \
  REQUIRED(filename, MDStringField, );                                         \
  REQUIRED(directory, MDStringField, );                                        \
  OPTIONAL(checksumkind, ChecksumKindField, (DIFile::CSK_MD5));                \
  OPTIONAL(checksum, MDStringField, );                                         \
  OPTIONAL(source, MDStringField, (MDStringField::EmptyIs::Empty));
  PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS

  std::optional<DIFile::ChecksumInfo<MDString *>> OptChecksum;
  if (checksumkind.Seen && checksum.Seen)
    OptChecksum.emplace(checksumkind.Val, checksum.Val);
  else if (checksumkind.Seen || checksum.Seen)
    return tokError("'checksumkind' and 'checksum' must be provided together");

  MDString *Source = nullptr;
  if (source.Seen)
    Source = source.Val;
  Result = GET_OR_DISTINCT(
      DIFile, (Context, filename.Val, directory.Val, OptChecksum, Source));
  return false;
}

/// parseDICompileUnit:
///   ::= !DICompileUnit(language: DW_LANG_C99, file: !0, producer: "clang",
///                      isOptimized: true, flags: "-O2", runtimeVersion: 1,
///                      splitDebugFilename: "abc.debug",
///                      emissionKind: FullDebug, enums: !1, retainedTypes: !2,
///                      globals: !4, imports: !5, macros: !6, dwoId: 0x0abcd,
///                      sysroot: "/", sdk: "MacOSX.sdk")
bool LLParser::parseDICompileUnit(MDNode *&Result, bool IsDistinct) {
  if (!IsDistinct)
    return tokError("missing 'distinct', required for !DICompileUnit");

#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, EmissionKindField, );                                 \
  OPTIONAL(enums, MDField, );                                                  \
  OPTIONAL(retainedTypes, MDField, );                                          \
  OPTIONAL(globals, MDField, );                                                \
  OPTIONAL(imports, MDField, );                                                \
  OPTIONAL(macros, MDField, );                                                 \
  OPTIONAL(dwoId, MDUnsignedField, );                                          \
  OPTIONAL(splitDebugInlining, MDBoolField, = true);                           \
  OPTIONAL(debugInfoForProfiling, MDBoolField, = false);                       \
  OPTIONAL(nameTableKind, NameTableKindField, );                               \
  OPTIONAL(rangesBaseAddress, MDBoolField, = false);                           \
  OPTIONAL(sysroot, MDStringField, );                                          \
  OPTIONAL(sdk, MDStringField, );
  PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS

  Result = DICompileUnit::getDistinct(
      Context, language.Val, file.Val, producer.Val, isOptimized.Val, flags.Val,
      runtimeVersion.Val, splitDebugFilename.Val, emissionKind.Val, enums.Val,
      retainedTypes.Val, globals.Val, imports.Val, macros.Val, dwoId.Val,
      splitDebugInlining.Val, debugInfoForProfiling.Val, nameTableKind.Val,
      rangesBaseAddress.Val, sysroot.Val, sdk.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, thisAdjustment: 4, flags: 11,
///                     spFlags: 10, isOptimized: false, templateParams: !4,
///                     declaration: !5, retainedNodes: !6, thrownTypes: !7,
///                     annotations: !8)
bool LLParser::parseDISubprogram(MDNode *&Result, bool IsDistinct) {
  auto Loc = Lex.getLoc();
#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(thisAdjustment, MDSignedField, (0, INT32_MIN, INT32_MAX));          \
  OPTIONAL(flags, DIFlagField, );                                              \
  OPTIONAL(spFlags, DISPFlagField, );                                          \
  OPTIONAL(isOptimized, MDBoolField, );                                        \
  OPTIONAL(unit, MDField, );                                                   \
  OPTIONAL(templateParams, MDField, );                                         \
  OPTIONAL(declaration, MDField, );                                            \
  OPTIONAL(retainedNodes, MDField, );                                          \
  OPTIONAL(thrownTypes, MDField, );                                            \
  OPTIONAL(annotations, MDField, );                                            \
  OPTIONAL(targetFuncName, MDStringField, );                                   \
  OPTIONAL(keyInstructions, MDBoolField, );
  PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS

  // An explicit spFlags field takes precedence over individual fields in
  // older IR versions.
  DISubprogram::DISPFlags SPFlags =
      spFlags.Seen ? spFlags.Val
                   : DISubprogram::toSPFlags(isLocal.Val, isDefinition.Val,
                                             isOptimized.Val, virtuality.Val);
  if ((SPFlags & DISubprogram::SPFlagDefinition) && !IsDistinct)
    return error(
        Loc,
        "missing 'distinct', required for !DISubprogram that is a Definition");
  Result = GET_OR_DISTINCT(
      DISubprogram,
      (Context, scope.Val, name.Val, linkageName.Val, file.Val, line.Val,
       type.Val, scopeLine.Val, containingType.Val, virtualIndex.Val,
       thisAdjustment.Val, flags.Val, SPFlags, unit.Val, templateParams.Val,
       declaration.Val, retainedNodes.Val, thrownTypes.Val, annotations.Val,
       targetFuncName.Val, keyInstructions.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;
}

/// parseDICommonBlock:
///   ::= !DICommonBlock(scope: !0, file: !2, name: "COMMON name", line: 9)
bool LLParser::parseDICommonBlock(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED)                                    \
  REQUIRED(scope, MDField, );                                                  \
  OPTIONAL(declaration, MDField, );                                            \
  OPTIONAL(name, MDStringField, );                                             \
  OPTIONAL(file, MDField, );                                                   \
  OPTIONAL(line, LineField, );
  PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS

  Result = GET_OR_DISTINCT(DICommonBlock,
                           (Context, scope.Val, declaration.Val, name.Val,
                            file.Val, line.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(name, MDStringField, );                                             \
  OPTIONAL(exportSymbols, MDBoolField, );
  PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS

  Result = GET_OR_DISTINCT(DINamespace,
                           (Context, scope.Val, name.Val, exportSymbols.Val));
  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, );                                     \
  OPTIONAL(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));       \
  OPTIONAL(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", apinotes: "module.apinotes",
///   file: !1, line: 4, isDecl: false)
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(apinotes, MDStringField, );                                         \
  OPTIONAL(file, MDField, );                                                   \
  OPTIONAL(line, LineField, );                                                 \
  OPTIONAL(isDecl, MDBoolField, );
  PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS

  Result = GET_OR_DISTINCT(DIModule, (Context, file.Val, scope.Val, name.Val,
                                      configMacros.Val, includePath.Val,
                                      apinotes.Val, line.Val, isDecl.Val));
  return false;
}

/// parseDITemplateTypeParameter:
///   ::= !DITemplateTypeParameter(name: "Ty", type: !1, defaulted: false)
bool LLParser::parseDITemplateTypeParameter(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED)                                    \
  OPTIONAL(name, MDStringField, );                                             \
  REQUIRED(type, MDField, );                                                   \
  OPTIONAL(defaulted, MDBoolField, );
  PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS

  Result = GET_OR_DISTINCT(DITemplateTypeParameter,
                           (Context, name.Val, type.Val, defaulted.Val));
  return false;
}

/// parseDITemplateValueParameter:
///   ::= !DITemplateValueParameter(tag: DW_TAG_template_value_parameter,
///                                 name: "V", type: !1, defaulted: false,
///                                 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, );                                                   \
  OPTIONAL(defaulted, MDBoolField, );                                          \
  REQUIRED(value, MDField, );

  PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS

  Result = GET_OR_DISTINCT(
      DITemplateValueParameter,
      (Context, tag.Val, name.Val, type.Val, defaulted.Val, value.Val));
  return false;
}

/// parseDIGlobalVariable:
///   ::= !DIGlobalVariable(scope: !0, name: "foo", linkageName: "foo",
///                         file: !1, line: 7, type: !2, isLocal: false,
///                         isDefinition: true, templateParams: !3,
///                         declaration: !4, align: 8)
bool LLParser::parseDIGlobalVariable(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED)                                    \
  OPTIONAL(name, MDStringField, (MDStringField::EmptyIs::Error));              \
  OPTIONAL(scope, MDField, );                                                  \
  OPTIONAL(linkageName, MDStringField, );                                      \
  OPTIONAL(file, MDField, );                                                   \
  OPTIONAL(line, LineField, );                                                 \
  OPTIONAL(type, MDField, );                                                   \
  OPTIONAL(isLocal, MDBoolField, );                                            \
  OPTIONAL(isDefinition, MDBoolField, (true));                                 \
  OPTIONAL(templateParams, MDField, );                                         \
  OPTIONAL(declaration, MDField, );                                            \
  OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX));                           \
  OPTIONAL(annotations, 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,
                       declaration.Val, templateParams.Val, align.Val,
                       annotations.Val));
  return false;
}

/// parseDILocalVariable:
///   ::= !DILocalVariable(arg: 7, scope: !0, name: "foo",
///                        file: !1, line: 7, type: !2, arg: 2, flags: 7,
///                        align: 8)
///   ::= !DILocalVariable(scope: !0, name: "foo",
///                        file: !1, line: 7, type: !2, arg: 2, flags: 7,
///                        align: 8)
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, );                                              \
  OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX));                           \
  OPTIONAL(annotations, MDField, );
  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, align.Val,
                            annotations.Val));
  return false;
}

/// parseDILabel:
///   ::= !DILabel(scope: !0, name: "foo", file: !1, line: 7, column: 4)
bool LLParser::parseDILabel(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED)                                    \
  REQUIRED(scope, MDField, (/* AllowNull */ false));                           \
  REQUIRED(name, MDStringField, );                                             \
  REQUIRED(file, MDField, );                                                   \
  REQUIRED(line, LineField, );                                                 \
  OPTIONAL(column, ColumnField, );                                             \
  OPTIONAL(isArtificial, MDBoolField, );                                       \
  OPTIONAL(coroSuspendIdx, MDUnsignedField, );
  PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS

  std::optional<unsigned> CoroSuspendIdx =
      coroSuspendIdx.Seen ? std::optional<unsigned>(coroSuspendIdx.Val)
                          : std::nullopt;

  Result = GET_OR_DISTINCT(DILabel,
                           (Context, scope.Val, name.Val, file.Val, line.Val,
                            column.Val, isArtificial.Val, CoroSuspendIdx));
  return false;
}

/// parseDIExpressionBody:
///   ::= (0, 7, -1)
bool LLParser::parseDIExpressionBody(MDNode *&Result, bool IsDistinct) {
  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::DwarfAttEncoding) {
        if (unsigned Op = dwarf::getAttributeEncoding(Lex.getStrVal())) {
          Lex.Lex();
          Elements.push_back(Op);
          continue;
        }
        return tokError(Twine("invalid DWARF attribute encoding '") +
                        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;
}

/// parseDIExpression:
///   ::= !DIExpression(0, 7, -1)
bool LLParser::parseDIExpression(MDNode *&Result, bool IsDistinct) {
  assert(Lex.getKind() == lltok::MetadataVar && "Expected metadata type name");
  assert(Lex.getStrVal() == "DIExpression" && "Expected '!DIExpression'");
  Lex.Lex();

  return parseDIExpressionBody(Result, IsDistinct);
}

/// ParseDIArgList:
///   ::= !DIArgList(i32 7, i64 %0)
bool LLParser::parseDIArgList(Metadata *&MD, PerFunctionState *PFS) {
  assert(PFS && "Expected valid function state");
  assert(Lex.getKind() == lltok::MetadataVar && "Expected metadata type name");
  Lex.Lex();

  if (parseToken(lltok::lparen, "expected '(' here"))
    return true;

  SmallVector<ValueAsMetadata *, 4> Args;
  if (Lex.getKind() != lltok::rparen)
    do {
      Metadata *MD;
      if (parseValueAsMetadata(MD, "expected value-as-metadata operand", PFS))
        return true;
      Args.push_back(dyn_cast<ValueAsMetadata>(MD));
    } while (EatIfPresent(lltok::comma));

  if (parseToken(lltok::rparen, "expected ')' here"))
    return true;

  MD = DIArgList::get(Context, Args);
  return false;
}

/// parseDIGlobalVariableExpression:
///   ::= !DIGlobalVariableExpression(var: !0, expr: !1)
bool LLParser::parseDIGlobalVariableExpression(MDNode *&Result,
                                               bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED)                                    \
  REQUIRED(var, MDField, );                                                    \
  REQUIRED(expr, MDField, );
  PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS

  Result =
      GET_OR_DISTINCT(DIGlobalVariableExpression, (Context, var.Val, expr.Val));
  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", elements: !2)
bool LLParser::parseDIImportedEntity(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED)                                    \
  REQUIRED(tag, DwarfTagField, );                                              \
  REQUIRED(scope, MDField, );                                                  \
  OPTIONAL(entity, MDField, );                                                 \
  OPTIONAL(file, MDField, );                                                   \
  OPTIONAL(line, LineField, );                                                 \
  OPTIONAL(name, MDStringField, );                                             \
  OPTIONAL(elements, MDField, );
  PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS

  Result = GET_OR_DISTINCT(DIImportedEntity,
                           (Context, tag.Val, scope.Val, entity.Val, file.Val,
                            line.Val, name.Val, elements.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) {
    // DIArgLists are a special case, as they are a list of ValueAsMetadata and
    // so parsing this requires a Function State.
    if (Lex.getStrVal() == "DIArgList") {
      Metadata *AL;
      if (parseDIArgList(AL, PFS))
        return true;
      MD = AL;
      return false;
    }
    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 (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;
}

//===----------------------------------------------------------------------===//
// Function Parsing.
//===----------------------------------------------------------------------===//

bool LLParser::convertValIDToValue(Type *Ty, ValID &ID, Value *&V,
                                   PerFunctionState *PFS) {
  if (Ty->isFunctionTy())
    return error(ID.Loc, "functions are not values, refer to them as pointers");

  switch (ID.Kind) {
  case ValID::t_LocalID:
    if (!PFS)
      return error(ID.Loc, "invalid use of function-local name");
    V = PFS->getVal(ID.UIntVal, Ty, ID.Loc);
    return V == nullptr;
  case ValID::t_LocalName:
    if (!PFS)
      return error(ID.Loc, "invalid use of function-local name");
    V = PFS->getVal(ID.StrVal, Ty, ID.Loc);
    return V == nullptr;
  case ValID::t_InlineAsm: {
    if (!ID.FTy)
      return error(ID.Loc, "invalid type for inline asm constraint string");
    if (Error Err = InlineAsm::verify(ID.FTy, ID.StrVal2))
      return error(ID.Loc, toString(std::move(Err)));
    V = InlineAsm::get(
        ID.FTy, ID.StrVal, ID.StrVal2, ID.UIntVal & 1, (ID.UIntVal >> 1) & 1,
        InlineAsm::AsmDialect((ID.UIntVal >> 2) & 1), (ID.UIntVal >> 3) & 1);
    return false;
  }
  case ValID::t_GlobalName:
    V = getGlobalVal(ID.StrVal, Ty, ID.Loc);
    if (V && ID.NoCFI)
      V = NoCFIValue::get(cast<GlobalValue>(V));
    return V == nullptr;
  case ValID::t_GlobalID:
    V = getGlobalVal(ID.UIntVal, Ty, ID.Loc);
    if (V && ID.NoCFI)
      V = NoCFIValue::get(cast<GlobalValue>(V));
    return V == nullptr;
  case ValID::t_APSInt:
    if (!Ty->isIntegerTy())
      return error(ID.Loc, "integer constant must have integer type");
    ID.APSIntVal = ID.APSIntVal.extOrTrunc(Ty->getPrimitiveSizeInBits());
    V = ConstantInt::get(Context, ID.APSIntVal);
    return false;
  case ValID::t_APFloat:
    if (!Ty->isFloatingPointTy() ||
        !ConstantFP::isValueValidForType(Ty, ID.APFloatVal))
      return error(ID.Loc, "floating point constant invalid for type");

    // The lexer has no type info, so builds all half, bfloat, float, and double
    // FP constants as double.  Fix this here.  Long double does not need this.
    if (&ID.APFloatVal.getSemantics() == &APFloat::IEEEdouble()) {
      // Check for signaling before potentially converting and losing that info.
      bool IsSNAN = ID.APFloatVal.isSignaling();
      bool Ignored;
      if (Ty->isHalfTy())
        ID.APFloatVal.convert(APFloat::IEEEhalf(), APFloat::rmNearestTiesToEven,
                              &Ignored);
      else if (Ty->isBFloatTy())
        ID.APFloatVal.convert(APFloat::BFloat(), APFloat::rmNearestTiesToEven,
                              &Ignored);
      else if (Ty->isFloatTy())
        ID.APFloatVal.convert(APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven,
                              &Ignored);
      if (IsSNAN) {
        // The convert call above may quiet an SNaN, so manufacture another
        // SNaN. The bitcast works because the payload (significand) parameter
        // is truncated to fit.
        APInt Payload = ID.APFloatVal.bitcastToAPInt();
        ID.APFloatVal = APFloat::getSNaN(ID.APFloatVal.getSemantics(),
                                         ID.APFloatVal.isNegative(), &Payload);
      }
    }
    V = ConstantFP::get(Context, ID.APFloatVal);

    if (V->getType() != Ty)
      return error(ID.Loc, "floating point constant does not have type '" +
                               getTypeString(Ty) + "'");

    return false;
  case ValID::t_Null:
    if (!Ty->isPointerTy())
      return error(ID.Loc, "null must be a pointer type");
    V = ConstantPointerNull::get(cast<PointerType>(Ty));
    return false;
  case ValID::t_Undef:
    // FIXME: LabelTy should not be a first-class type.
    if (!Ty->isFirstClassType() || Ty->isLabelTy())
      return error(ID.Loc, "invalid type for undef constant");
    V = UndefValue::get(Ty);
    return false;
  case ValID::t_EmptyArray:
    if (!Ty->isArrayTy() || cast<ArrayType>(Ty)->getNumElements() != 0)
      return error(ID.Loc, "invalid empty array initializer");
    V = PoisonValue::get(Ty);
    return false;
  case ValID::t_Zero:
    // FIXME: LabelTy should not be a first-class type.
    if (!Ty->isFirstClassType() || Ty->isLabelTy())
      return error(ID.Loc, "invalid type for null constant");
    if (auto *TETy = dyn_cast<TargetExtType>(Ty))
      if (!TETy->hasProperty(TargetExtType::HasZeroInit))
        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_Poison:
    // FIXME: LabelTy should not be a first-class type.
    if (!Ty->isFirstClassType() || Ty->isLabelTy())
      return error(ID.Loc, "invalid type for poison constant");
    V = PoisonValue::get(Ty);
    return false;
  case ValID::t_Constant:
    if (ID.ConstantVal->getType() != Ty)
      return error(ID.Loc, "constant expression type mismatch: got type '" +
                               getTypeString(ID.ConstantVal->getType()) +
                               "' but expected '" + getTypeString(Ty) + "'");
    V = ID.ConstantVal;
    return false;
  case ValID::t_ConstantSplat:
    if (!Ty->isVectorTy())
      return error(ID.Loc, "vector constant must have vector type");
    if (ID.ConstantVal->getType() != Ty->getScalarType())
      return error(ID.Loc, "constant expression type mismatch: got type '" +
                               getTypeString(ID.ConstantVal->getType()) +
                               "' but expected '" +
                               getTypeString(Ty->getScalarType()) + "'");
    V = ConstantVector::getSplat(cast<VectorType>(Ty)->getElementCount(),
                                 ID.ConstantVal);
    return false;
  case ValID::t_ConstantStruct:
  case ValID::t_PackedConstantStruct:
    if (StructType *ST = dyn_cast<StructType>(Ty)) {
      if (ST->getNumElements() != ID.UIntVal)
        return error(ID.Loc,
                     "initializer with struct type has wrong # elements");
      if (ST->isPacked() != (ID.Kind == ValID::t_PackedConstantStruct))
        return error(ID.Loc, "packed'ness of initializer and type don't match");

      // Verify that the elements are compatible with the structtype.
      for (unsigned i = 0, e = ID.UIntVal; i != e; ++i)
        if (ID.ConstantStructElts[i]->getType() != ST->getElementType(i))
          return error(
              ID.Loc,
              "element " + Twine(i) +
                  " of struct initializer doesn't match struct element type");

      V = ConstantStruct::get(
          ST, ArrayRef(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_Undef:
  case ValID::t_Poison:
  case ValID::t_Zero:
  case ValID::t_Constant:
  case ValID::t_ConstantSplat:
  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;
  }
  case ValID::t_Null:
    C = Constant::getNullValue(Ty);
    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, Ty) ||
         convertValIDToValue(Ty, ID, V, PFS);
}

bool LLParser::parseTypeAndValue(Value *&V, PerFunctionState *PFS) {
  Type *Ty = nullptr;
  return parseType(Ty) || parseValue(Ty, V, PFS);
}

bool LLParser::parseTypeAndBasicBlock(BasicBlock *&BB, LocTy &Loc,
                                      PerFunctionState &PFS) {
  Value *V;
  Loc = Lex.getLoc();
  if (parseTypeAndValue(V, PFS))
    return true;
  if (!isa<BasicBlock>(V))
    return error(Loc, "expected a basic block");
  BB = cast<BasicBlock>(V);
  return false;
}

bool isOldDbgFormatIntrinsic(StringRef Name) {
  // Exit early for the common (non-debug-intrinsic) case.
  // We can make this the only check when we begin supporting all "llvm.dbg"
  // intrinsics in the new debug info format.
  if (!Name.starts_with("llvm.dbg."))
    return false;
  Intrinsic::ID FnID = Intrinsic::lookupIntrinsicID(Name);
  return FnID == Intrinsic::dbg_declare || FnID == Intrinsic::dbg_value ||
         FnID == Intrinsic::dbg_assign;
}

/// FunctionHeader
///   ::= OptionalLinkage OptionalPreemptionSpecifier OptionalVisibility
///       OptionalCallingConv OptRetAttrs OptUnnamedAddr Type GlobalName
///       '(' ArgList ')' OptAddrSpace OptFuncAttrs OptSection OptionalAlign
///       OptGC OptionalPrefix OptionalPrologue OptPersonalityFn
bool LLParser::parseFunctionHeader(Function *&Fn, bool IsDefine,
                                   unsigned &FunctionNumber,
                                   SmallVectorImpl<unsigned> &UnnamedArgNums) {
  // parse the linkage.
  LocTy LinkageLoc = Lex.getLoc();
  unsigned Linkage;
  unsigned Visibility;
  unsigned DLLStorageClass;
  bool DSOLocal;
  AttrBuilder RetAttrs(M->getContext());
  unsigned CC;
  bool HasLinkage;
  Type *RetType = nullptr;
  LocTy RetTypeLoc = Lex.getLoc();
  if (parseOptionalLinkage(Linkage, HasLinkage, Visibility, DLLStorageClass,
                           DSOLocal) ||
      parseOptionalCallingConv(CC) || parseOptionalReturnAttrs(RetAttrs) ||
      parseType(RetType, RetTypeLoc, true /*void allowed*/))
    return true;

  // Verify that the linkage is ok.
  switch ((GlobalValue::LinkageTypes)Linkage) {
  case GlobalValue::ExternalLinkage:
    break; // always ok.
  case GlobalValue::ExternalWeakLinkage:
    if (IsDefine)
      return error(LinkageLoc, "invalid linkage for function definition");
    break;
  case GlobalValue::PrivateLinkage:
  case GlobalValue::InternalLinkage:
  case GlobalValue::AvailableExternallyLinkage:
  case GlobalValue::LinkOnceAnyLinkage:
  case GlobalValue::LinkOnceODRLinkage:
  case GlobalValue::WeakAnyLinkage:
  case GlobalValue::WeakODRLinkage:
    if (!IsDefine)
      return error(LinkageLoc, "invalid linkage for function declaration");
    break;
  case GlobalValue::AppendingLinkage:
  case GlobalValue::CommonLinkage:
    return error(LinkageLoc, "invalid function linkage type");
  }

  if (!isValidVisibilityForLinkage(Visibility, Linkage))
    return error(LinkageLoc,
                 "symbol with local linkage must have default visibility");

  if (!isValidDLLStorageClassForLinkage(DLLStorageClass, Linkage))
    return error(LinkageLoc,
                 "symbol with local linkage cannot have a DLL storage class");

  if (!FunctionType::isValidReturnType(RetType))
    return error(RetTypeLoc, "invalid function return type");

  LocTy NameLoc = Lex.getLoc();

  std::string FunctionName;
  if (Lex.getKind() == lltok::GlobalVar) {
    FunctionName = Lex.getStrVal();
  } else if (Lex.getKind() == lltok::GlobalID) {     // @42 is ok.
    FunctionNumber = Lex.getUIntVal();
    if (checkValueID(NameLoc, "function", "@", NumberedVals.getNext(),
                     FunctionNumber))
      return true;
  } else {
    return tokError("expected function name");
  }

  Lex.Lex();

  if (Lex.getKind() != lltok::lparen)
    return tokError("expected '(' in function argument list");

  SmallVector<ArgInfo, 8> ArgList;
  bool IsVarArg;
  AttrBuilder FuncAttrs(M->getContext());
  std::vector<unsigned> FwdRefAttrGrps;
  LocTy BuiltinLoc;
  std::string Section;
  std::string Partition;
  MaybeAlign Alignment;
  std::string GC;
  GlobalValue::UnnamedAddr UnnamedAddr = GlobalValue::UnnamedAddr::None;
  unsigned AddrSpace = 0;
  Constant *Prefix = nullptr;
  Constant *Prologue = nullptr;
  Constant *PersonalityFn = nullptr;
  Comdat *C;

  if (parseArgumentList(ArgList, UnnamedArgNums, IsVarArg) ||
      parseOptionalUnnamedAddr(UnnamedAddr) ||
      parseOptionalProgramAddrSpace(AddrSpace) ||
      parseFnAttributeValuePairs(FuncAttrs, FwdRefAttrGrps, false,
                                 BuiltinLoc) ||
      (EatIfPresent(lltok::kw_section) && parseStringConstant(Section)) ||
      (EatIfPresent(lltok::kw_partition) && parseStringConstant(Partition)) ||
      parseOptionalComdat(FunctionName, C) ||
      parseOptionalAlignment(Alignment) ||
      (EatIfPresent(lltok::kw_gc) && parseStringConstant(GC)) ||
      (EatIfPresent(lltok::kw_prefix) && parseGlobalTypeAndValue(Prefix)) ||
      (EatIfPresent(lltok::kw_prologue) && parseGlobalTypeAndValue(Prologue)) ||
      (EatIfPresent(lltok::kw_personality) &&
       parseGlobalTypeAndValue(PersonalityFn)))
    return true;

  if (FuncAttrs.contains(Attribute::Builtin))
    return error(BuiltinLoc, "'builtin' attribute not valid on function");

  // If the alignment was parsed as an attribute, move to the alignment field.
  if (MaybeAlign A = FuncAttrs.getAlignment()) {
    Alignment = A;
    FuncAttrs.removeAttribute(Attribute::Alignment);
  }

  // Okay, if we got here, the function is syntactically valid.  Convert types
  // and do semantic checks.
  std::vector<Type*> ParamTypeList;
  SmallVector<AttributeSet, 8> Attrs;

  for (const ArgInfo &Arg : ArgList) {
    ParamTypeList.push_back(Arg.Ty);
    Attrs.push_back(Arg.Attrs);
  }

  AttributeList PAL =
      AttributeList::get(Context, AttributeSet::get(Context, FuncAttrs),
                         AttributeSet::get(Context, RetAttrs), Attrs);

  if (PAL.hasParamAttr(0, Attribute::StructRet) && !RetType->isVoidTy())
    return error(RetTypeLoc, "functions with 'sret' argument must return void");

  FunctionType *FT = FunctionType::get(RetType, ParamTypeList, IsVarArg);
  PointerType *PFT = PointerType::get(Context, AddrSpace);

  Fn = nullptr;
  GlobalValue *FwdFn = nullptr;
  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.
    auto FRVI = ForwardRefVals.find(FunctionName);
    if (FRVI != ForwardRefVals.end()) {
      FwdFn = FRVI->second.first;
      if (FwdFn->getType() != PFT)
        return error(FRVI->second.second,
                     "invalid forward reference to "
                     "function '" +
                         FunctionName +
                         "' with wrong type: "
                         "expected '" +
                         getTypeString(PFT) + "' but was '" +
                         getTypeString(FwdFn->getType()) + "'");
      ForwardRefVals.erase(FRVI);
    } else if ((Fn = M->getFunction(FunctionName))) {
      // Reject redefinitions.
      return error(NameLoc,
                   "invalid redefinition of function '" + FunctionName + "'");
    } else if (M->getNamedValue(FunctionName)) {
      return error(NameLoc, "redefinition of function '@" + FunctionName + "'");
    }

  } else {
    // Handle @"", where a name is syntactically specified, but semantically
    // missing.
    if (FunctionNumber == (unsigned)-1)
      FunctionNumber = NumberedVals.getNext();

    // If this is a definition of a forward referenced function, make sure the
    // types agree.
    auto I = ForwardRefValIDs.find(FunctionNumber);
    if (I != ForwardRefValIDs.end()) {
      FwdFn = I->second.first;
      if (FwdFn->getType() != PFT)
        return error(NameLoc, "type of definition and forward reference of '@" +
                                  Twine(FunctionNumber) +
                                  "' disagree: "
                                  "expected '" +
                                  getTypeString(PFT) + "' but was '" +
                                  getTypeString(FwdFn->getType()) + "'");
      ForwardRefValIDs.erase(I);
    }
  }

  Fn = Function::Create(FT, GlobalValue::ExternalLinkage, AddrSpace,
                        FunctionName, M);

  assert(Fn->getAddressSpace() == AddrSpace && "Created function in wrong AS");

  if (FunctionName.empty())
    NumberedVals.add(FunctionNumber, Fn);

  Fn->setLinkage((GlobalValue::LinkageTypes)Linkage);
  maybeSetDSOLocal(DSOLocal, *Fn);
  Fn->setVisibility((GlobalValue::VisibilityTypes)Visibility);
  Fn->setDLLStorageClass((GlobalValue::DLLStorageClassTypes)DLLStorageClass);
  Fn->setCallingConv(CC);
  Fn->setAttributes(PAL);
  Fn->setUnnamedAddr(UnnamedAddr);
  if (Alignment)
    Fn->setAlignment(*Alignment);
  Fn->setSection(Section);
  Fn->setPartition(Partition);
  Fn->setComdat(C);
  Fn->setPersonalityFn(PersonalityFn);
  if (!GC.empty()) Fn->setGC(GC);
  Fn->setPrefixData(Prefix);
  Fn->setPrologueData(Prologue);
  ForwardRefAttrGroups[Fn] = FwdRefAttrGrps;

  // Add all of the arguments we parsed to the function.
  Function::arg_iterator ArgIt = Fn->arg_begin();
  for (unsigned i = 0, e = ArgList.size(); i != e; ++i, ++ArgIt) {
    // If the argument has a name, insert it into the argument symbol table.
    if (ArgList[i].Name.empty()) continue;

    // Set the name, if it conflicted, it will be auto-renamed.
    ArgIt->setName(ArgList[i].Name);

    if (ArgIt->getName() != ArgList[i].Name)
      return error(ArgList[i].Loc,
                   "redefinition of argument '%" + ArgList[i].Name + "'");
  }

  if (FwdFn) {
    FwdFn->replaceAllUsesWith(Fn);
    FwdFn->eraseFromParent();
  }

  if (IsDefine)
    return false;

  // Check the declaration has no block address forward references.
  ValID ID;
  if (FunctionName.empty()) {
    ID.Kind = ValID::t_GlobalID;
    ID.UIntVal = FunctionNumber;
  } else {
    ID.Kind = ValID::t_GlobalName;
    ID.StrVal = FunctionName;
  }
  auto Blocks = ForwardRefBlockAddresses.find(ID);
  if (Blocks != ForwardRefBlockAddresses.end())
    return error(Blocks->first.Loc,
                 "cannot take blockaddress inside a declaration");
  return false;
}

bool LLParser::PerFunctionState::resolveForwardRefBlockAddresses() {
  ValID ID;
  if (FunctionNumber == -1) {
    ID.Kind = ValID::t_GlobalName;
    ID.StrVal = std::string(F.getName());
  } else {
    ID.Kind = ValID::t_GlobalID;
    ID.UIntVal = FunctionNumber;
  }

  auto Blocks = P.ForwardRefBlockAddresses.find(ID);
  if (Blocks == P.ForwardRefBlockAddresses.end())
    return false;

  for (const auto &I : Blocks->second) {
    const ValID &BBID = I.first;
    GlobalValue *GV = I.second;

    assert((BBID.Kind == ValID::t_LocalID || BBID.Kind == ValID::t_LocalName) &&
           "Expected local id or name");
    BasicBlock *BB;
    if (BBID.Kind == ValID::t_LocalName)
      BB = getBB(BBID.StrVal, BBID.Loc);
    else
      BB = getBB(BBID.UIntVal, BBID.Loc);
    if (!BB)
      return P.error(BBID.Loc, "referenced value is not a basic block");

    Value *ResolvedVal = BlockAddress::get(&F, BB);
    ResolvedVal = P.checkValidVariableType(BBID.Loc, BBID.StrVal, GV->getType(),
                                           ResolvedVal);
    if (!ResolvedVal)
      return true;
    GV->replaceAllUsesWith(ResolvedVal);
    GV->eraseFromParent();
  }

  P.ForwardRefBlockAddresses.erase(Blocks);
  return false;
}

/// parseFunctionBody
///   ::= '{' BasicBlock+ UseListOrderDirective* '}'
bool LLParser::parseFunctionBody(Function &Fn, unsigned FunctionNumber,
                                 ArrayRef<unsigned> UnnamedArgNums) {
  if (Lex.getKind() != lltok::lbrace)
    return tokError("expected '{' in function body");
  Lex.Lex();  // eat the {.

  PerFunctionState PFS(*this, Fn, FunctionNumber, UnnamedArgNums);

  // Resolve block addresses and allow basic blocks to be forward-declared
  // within this function.
  if (PFS.resolveForwardRefBlockAddresses())
    return true;
  SaveAndRestore ScopeExit(BlockAddressPFS, &PFS);

  // We need at least one basic block.
  if (Lex.getKind() == lltok::rbrace || Lex.getKind() == lltok::kw_uselistorder)
    return tokError("function body requires at least one basic block");

  while (Lex.getKind() != lltok::rbrace &&
         Lex.getKind() != lltok::kw_uselistorder)
    if (parseBasicBlock(PFS))
      return true;

  while (Lex.getKind() != lltok::rbrace)
    if (parseUseListOrder(&PFS))
      return true;

  // Eat the }.
  Lex.Lex();

  // Verify function is ok.
  return PFS.finishFunction();
}

/// parseBasicBlock
///   ::= (LabelStr|LabelID)? Instruction*
bool LLParser::parseBasicBlock(PerFunctionState &PFS) {
  // If this basic block starts out with a name, remember it.
  std::string Name;
  int NameID = -1;
  LocTy NameLoc = Lex.getLoc();
  if (Lex.getKind() == lltok::LabelStr) {
    Name = Lex.getStrVal();
    Lex.Lex();
  } else if (Lex.getKind() == lltok::LabelID) {
    NameID = Lex.getUIntVal();
    Lex.Lex();
  }

  BasicBlock *BB = PFS.defineBB(Name, NameID, NameLoc);
  if (!BB)
    return true;

  std::string NameStr;

  // Parse the instructions and debug values in this block until we get a
  // terminator.
  Instruction *Inst;
  auto DeleteDbgRecord = [](DbgRecord *DR) { DR->deleteRecord(); };
  using DbgRecordPtr = std::unique_ptr<DbgRecord, decltype(DeleteDbgRecord)>;
  SmallVector<DbgRecordPtr> TrailingDbgRecord;
  do {
    // Handle debug records first - there should always be an instruction
    // following the debug records, i.e. they cannot appear after the block
    // terminator.
    while (Lex.getKind() == lltok::hash) {
      if (SeenOldDbgInfoFormat)
        return error(Lex.getLoc(), "debug record should not appear in a module "
                                   "containing debug info intrinsics");
      SeenNewDbgInfoFormat = true;
      Lex.Lex();

      DbgRecord *DR;
      if (parseDebugRecord(DR, PFS))
        return true;
      TrailingDbgRecord.emplace_back(DR, DeleteDbgRecord);
    }

    // This instruction may have three possibilities for a name: a) none
    // specified, b) name specified "%foo =", c) number specified: "%4 =".
    LocTy NameLoc = Lex.getLoc();
    int NameID = -1;
    NameStr = "";

    if (Lex.getKind() == lltok::LocalVarID) {
      NameID = Lex.getUIntVal();
      Lex.Lex();
      if (parseToken(lltok::equal, "expected '=' after instruction id"))
        return true;
    } else if (Lex.getKind() == lltok::LocalVar) {
      NameStr = Lex.getStrVal();
      Lex.Lex();
      if (parseToken(lltok::equal, "expected '=' after instruction name"))
        return true;
    }

    switch (parseInstruction(Inst, BB, PFS)) {
    default:
      llvm_unreachable("Unknown parseInstruction result!");
    case InstError: return true;
    case InstNormal:
      Inst->insertInto(BB, BB->end());

      // With a normal result, we check to see if the instruction is followed by
      // a comma and metadata.
      if (EatIfPresent(lltok::comma))
        if (parseInstructionMetadata(*Inst))
          return true;
      break;
    case InstExtraComma:
      Inst->insertInto(BB, BB->end());

      // If the instruction parser ate an extra comma at the end of it, it
      // *must* be followed by metadata.
      if (parseInstructionMetadata(*Inst))
        return true;
      break;
    }

    // Set the name on the instruction.
    if (PFS.setInstName(NameID, NameStr, NameLoc, Inst))
      return true;

    // Attach any preceding debug values to this instruction.
    for (DbgRecordPtr &DR : TrailingDbgRecord)
      BB->insertDbgRecordBefore(DR.release(), Inst->getIterator());
    TrailingDbgRecord.clear();
  } while (!Inst->isTerminator());

  assert(TrailingDbgRecord.empty() &&
         "All debug values should have been attached to an instruction.");

  return false;
}

/// parseDebugRecord
///   ::= #dbg_label '(' MDNode ')'
///   ::= #dbg_type '(' Metadata ',' MDNode ',' Metadata ','
///                 (MDNode ',' Metadata ',' Metadata ',')? MDNode ')'
bool LLParser::parseDebugRecord(DbgRecord *&DR, PerFunctionState &PFS) {
  using RecordKind = DbgRecord::Kind;
  using LocType = DbgVariableRecord::LocationType;
  LocTy DVRLoc = Lex.getLoc();
  if (Lex.getKind() != lltok::DbgRecordType)
    return error(DVRLoc, "expected debug record type here");
  RecordKind RecordType = StringSwitch<RecordKind>(Lex.getStrVal())
                              .Case("declare", RecordKind::ValueKind)
                              .Case("value", RecordKind::ValueKind)
                              .Case("assign", RecordKind::ValueKind)
                              .Case("label", RecordKind::LabelKind);

  // Parsing labels is trivial; parse here and early exit, otherwise go into the
  // full DbgVariableRecord processing stage.
  if (RecordType == RecordKind::LabelKind) {
    Lex.Lex();
    if (parseToken(lltok::lparen, "Expected '(' here"))
      return true;
    MDNode *Label;
    if (parseMDNode(Label))
      return true;
    if (parseToken(lltok::comma, "Expected ',' here"))
      return true;
    MDNode *DbgLoc;
    if (parseMDNode(DbgLoc))
      return true;
    if (parseToken(lltok::rparen, "Expected ')' here"))
      return true;
    DR = DbgLabelRecord::createUnresolvedDbgLabelRecord(Label, DbgLoc);
    return false;
  }

  LocType ValueType = StringSwitch<LocType>(Lex.getStrVal())
                          .Case("declare", LocType::Declare)
                          .Case("value", LocType::Value)
                          .Case("assign", LocType::Assign);

  Lex.Lex();
  if (parseToken(lltok::lparen, "Expected '(' here"))
    return true;

  // Parse Value field.
  Metadata *ValLocMD;
  if (parseMetadata(ValLocMD, &PFS))
    return true;
  if (parseToken(lltok::comma, "Expected ',' here"))
    return true;

  // Parse Variable field.
  MDNode *Variable;
  if (parseMDNode(Variable))
    return true;
  if (parseToken(lltok::comma, "Expected ',' here"))
    return true;

  // Parse Expression field.
  MDNode *Expression;
  if (parseMDNode(Expression))
    return true;
  if (parseToken(lltok::comma, "Expected ',' here"))
    return true;

  // Parse additional fields for #dbg_assign.
  MDNode *AssignID = nullptr;
  Metadata *AddressLocation = nullptr;
  MDNode *AddressExpression = nullptr;
  if (ValueType == LocType::Assign) {
    // Parse DIAssignID.
    if (parseMDNode(AssignID))
      return true;
    if (parseToken(lltok::comma, "Expected ',' here"))
      return true;

    // Parse address ValueAsMetadata.
    if (parseMetadata(AddressLocation, &PFS))
      return true;
    if (parseToken(lltok::comma, "Expected ',' here"))
      return true;

    // Parse address DIExpression.
    if (parseMDNode(AddressExpression))
      return true;
    if (parseToken(lltok::comma, "Expected ',' here"))
      return true;
  }

  /// Parse DILocation.
  MDNode *DebugLoc;
  if (parseMDNode(DebugLoc))
    return true;

  if (parseToken(lltok::rparen, "Expected ')' here"))
    return true;
  DR = DbgVariableRecord::createUnresolvedDbgVariableRecord(
      ValueType, ValLocMD, Variable, Expression, AssignID, AddressLocation,
      AddressExpression, DebugLoc);
  return false;
}
//===----------------------------------------------------------------------===//
// Instruction Parsing.
//===----------------------------------------------------------------------===//

/// parseInstruction - parse one of the many different instructions.
///
int LLParser::parseInstruction(Instruction *&Inst, BasicBlock *BB,
                               PerFunctionState &PFS) {
  lltok::Kind Token = Lex.getKind();
  if (Token == lltok::Eof)
    return tokError("found end of file when expecting more instructions");
  LocTy Loc = Lex.getLoc();
  unsigned KeywordVal = Lex.getUIntVal();
  Lex.Lex();  // Eat the keyword.

  switch (Token) {
  default:
    return error(Loc, "expected instruction opcode");
  // Terminator Instructions.
  case lltok::kw_unreachable: Inst = new UnreachableInst(Context); return false;
  case lltok::kw_ret:
    return parseRet(Inst, BB, PFS);
  case lltok::kw_br:
    return parseBr(Inst, PFS);
  case lltok::kw_switch:
    return parseSwitch(Inst, PFS);
  case lltok::kw_indirectbr:
    return parseIndirectBr(Inst, PFS);
  case lltok::kw_invoke:
    return parseInvoke(Inst, PFS);
  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);
  case lltok::kw_callbr:
    return parseCallBr(Inst, PFS);
  // Unary Operators.
  case lltok::kw_fneg: {
    FastMathFlags FMF = EatFastMathFlagsIfPresent();
    int Res = parseUnaryOp(Inst, PFS, KeywordVal, /*IsFP*/ true);
    if (Res != 0)
      return Res;
    if (FMF.any())
      Inst->setFastMathFlags(FMF);
    return false;
  }
  // Binary Operators.
  case lltok::kw_add:
  case lltok::kw_sub:
  case lltok::kw_mul:
  case lltok::kw_shl: {
    bool NUW = EatIfPresent(lltok::kw_nuw);
    bool NSW = EatIfPresent(lltok::kw_nsw);
    if (!NUW) NUW = EatIfPresent(lltok::kw_nuw);

    if (parseArithmetic(Inst, PFS, KeywordVal, /*IsFP*/ false))
      return true;

    if (NUW) cast<BinaryOperator>(Inst)->setHasNoUnsignedWrap(true);
    if (NSW) cast<BinaryOperator>(Inst)->setHasNoSignedWrap(true);
    return false;
  }
  case lltok::kw_fadd:
  case lltok::kw_fsub:
  case lltok::kw_fmul:
  case lltok::kw_fdiv:
  case lltok::kw_frem: {
    FastMathFlags FMF = EatFastMathFlagsIfPresent();
    int Res = parseArithmetic(Inst, PFS, KeywordVal, /*IsFP*/ true);
    if (Res != 0)
      return Res;
    if (FMF.any())
      Inst->setFastMathFlags(FMF);
    return 0;
  }

  case lltok::kw_sdiv:
  case lltok::kw_udiv:
  case lltok::kw_lshr:
  case lltok::kw_ashr: {
    bool Exact = EatIfPresent(lltok::kw_exact);

    if (parseArithmetic(Inst, PFS, KeywordVal, /*IsFP*/ false))
      return true;
    if (Exact) cast<BinaryOperator>(Inst)->setIsExact(true);
    return false;
  }

  case lltok::kw_urem:
  case lltok::kw_srem:
    return parseArithmetic(Inst, PFS, KeywordVal,
                           /*IsFP*/ false);
  case lltok::kw_or: {
    bool Disjoint = EatIfPresent(lltok::kw_disjoint);
    if (parseLogical(Inst, PFS, KeywordVal))
      return true;
    if (Disjoint)
      cast<PossiblyDisjointInst>(Inst)->setIsDisjoint(true);
    return false;
  }
  case lltok::kw_and:
  case lltok::kw_xor:
    return parseLogical(Inst, PFS, KeywordVal);
  case lltok::kw_icmp: {
    bool SameSign = EatIfPresent(lltok::kw_samesign);
    if (parseCompare(Inst, PFS, KeywordVal))
      return true;
    if (SameSign)
      cast<ICmpInst>(Inst)->setSameSign();
    return false;
  }
  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_uitofp:
  case lltok::kw_zext: {
    bool NonNeg = EatIfPresent(lltok::kw_nneg);
    bool Res = parseCast(Inst, PFS, KeywordVal);
    if (Res != 0)
      return Res;
    if (NonNeg)
      Inst->setNonNeg();
    return 0;
  }
  case lltok::kw_trunc: {
    bool NUW = EatIfPresent(lltok::kw_nuw);
    bool NSW = EatIfPresent(lltok::kw_nsw);
    if (!NUW)
      NUW = EatIfPresent(lltok::kw_nuw);
    if (parseCast(Inst, PFS, KeywordVal))
      return true;
    if (NUW)
      cast<TruncInst>(Inst)->setHasNoUnsignedWrap(true);
    if (NSW)
      cast<TruncInst>(Inst)->setHasNoSignedWrap(true);
    return false;
  }
  case lltok::kw_sext:
  case lltok::kw_bitcast:
  case lltok::kw_addrspacecast:
  case lltok::kw_sitofp:
  case lltok::kw_fptoui:
  case lltok::kw_fptosi:
  case lltok::kw_inttoptr:
  case lltok::kw_ptrtoaddr:
  case lltok::kw_ptrtoint:
    return parseCast(Inst, PFS, KeywordVal);
  case lltok::kw_fptrunc:
  case lltok::kw_fpext: {
    FastMathFlags FMF = EatFastMathFlagsIfPresent();
    if (parseCast(Inst, PFS, KeywordVal))
      return true;
    if (FMF.any())
      Inst->setFastMathFlags(FMF);
    return false;
  }

  // Other.
  case lltok::kw_select: {
    FastMathFlags FMF = EatFastMathFlagsIfPresent();
    int Res = parseSelect(Inst, PFS);
    if (Res != 0)
      return Res;
    if (FMF.any()) {
      if (!isa<FPMathOperator>(Inst))
        return error(Loc, "fast-math-flags specified for select without "
                          "floating-point scalar or vector return type");
      Inst->setFastMathFlags(FMF);
    }
    return 0;
  }
  case lltok::kw_va_arg:
    return parseVAArg(Inst, PFS);
  case lltok::kw_extractelement:
    return parseExtractElement(Inst, PFS);
  case lltok::kw_insertelement:
    return parseInsertElement(Inst, PFS);
  case lltok::kw_shufflevector:
    return parseShuffleVector(Inst, PFS);
  case lltok::kw_phi: {
    FastMathFlags FMF = EatFastMathFlagsIfPresent();
    int Res = parsePHI(Inst, PFS);
    if (Res != 0)
      return Res;
    if (FMF.any()) {
      if (!isa<FPMathOperator>(Inst))
        return error(Loc, "fast-math-flags specified for phi without "
                          "floating-point scalar or vector return type");
      Inst->setFastMathFlags(FMF);
    }
    return 0;
  }
  case lltok::kw_landingpad:
    return parseLandingPad(Inst, PFS);
  case lltok::kw_freeze:
    return parseFreeze(Inst, PFS);
  // Call.
  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);
  case lltok::kw_store:
    return parseStore(Inst, PFS);
  case lltok::kw_cmpxchg:
    return parseCmpXchg(Inst, PFS);
  case lltok::kw_atomicrmw:
    return parseAtomicRMW(Inst, PFS);
  case lltok::kw_fence:
    return parseFence(Inst, PFS);
  case lltok::kw_getelementptr:
    return parseGetElementPtr(Inst, PFS);
  case lltok::kw_extractvalue:
    return parseExtractValue(Inst, PFS);
  case lltok::kw_insertvalue:
    return parseInsertValue(Inst, PFS);
  }
}

/// parseCmpPredicate - parse an integer or fp predicate, based on Kind.
bool LLParser::parseCmpPredicate(unsigned &P, unsigned Opc) {
  if (Opc == Instruction::FCmp) {
    switch (Lex.getKind()) {
    default:
      return tokError("expected fcmp predicate (e.g. 'oeq')");
    case lltok::kw_oeq: P = CmpInst::FCMP_OEQ; break;
    case lltok::kw_one: P = CmpInst::FCMP_ONE; break;
    case lltok::kw_olt: P = CmpInst::FCMP_OLT; break;
    case lltok::kw_ogt: P = CmpInst::FCMP_OGT; break;
    case lltok::kw_ole: P = CmpInst::FCMP_OLE; break;
    case lltok::kw_oge: P = CmpInst::FCMP_OGE; break;
    case lltok::kw_ord: P = CmpInst::FCMP_ORD; break;
    case lltok::kw_uno: P = CmpInst::FCMP_UNO; break;
    case lltok::kw_ueq: P = CmpInst::FCMP_UEQ; break;
    case lltok::kw_une: P = CmpInst::FCMP_UNE; break;
    case lltok::kw_ult: P = CmpInst::FCMP_ULT; break;
    case lltok::kw_ugt: P = CmpInst::FCMP_UGT; break;
    case lltok::kw_ule: P = CmpInst::FCMP_ULE; break;
    case lltok::kw_uge: P = CmpInst::FCMP_UGE; break;
    case lltok::kw_true: P = CmpInst::FCMP_TRUE; break;
    case lltok::kw_false: P = CmpInst::FCMP_FALSE; break;
    }
  } else {
    switch (Lex.getKind()) {
    default:
      return tokError("expected icmp predicate (e.g. 'eq')");
    case lltok::kw_eq:  P = CmpInst::ICMP_EQ; break;
    case lltok::kw_ne:  P = CmpInst::ICMP_NE; break;
    case lltok::kw_slt: P = CmpInst::ICMP_SLT; break;
    case lltok::kw_sgt: P = CmpInst::ICMP_SGT; break;
    case lltok::kw_sle: P = CmpInst::ICMP_SLE; break;
    case lltok::kw_sge: P = CmpInst::ICMP_SGE; break;
    case lltok::kw_ult: P = CmpInst::ICMP_ULT; break;
    case lltok::kw_ugt: P = CmpInst::ICMP_UGT; break;
    case lltok::kw_ule: P = CmpInst::ICMP_ULE; break;
    case lltok::kw_uge: P = CmpInst::ICMP_UGE; break;
    }
  }
  Lex.Lex();
  return false;
}

//===----------------------------------------------------------------------===//
// Terminator Instructions.
//===----------------------------------------------------------------------===//

/// parseRet - parse a return instruction.
///   ::= 'ret' void (',' !dbg, !1)*
///   ::= 'ret' TypeAndValue (',' !dbg, !1)*
bool LLParser::parseRet(Instruction *&Inst, BasicBlock *BB,
                        PerFunctionState &PFS) {
  SMLoc TypeLoc = Lex.getLoc();
  Type *Ty = nullptr;
  if (parseType(Ty, true /*void allowed*/))
    return true;

  Type *ResType = PFS.getFunction().getReturnType();

  if (Ty->isVoidTy()) {
    if (!ResType->isVoidTy())
      return error(TypeLoc, "value doesn't match function result type '" +
                                getTypeString(ResType) + "'");

    Inst = ReturnInst::Create(Context);
    return false;
  }

  Value *RV;
  if (parseValue(Ty, RV, PFS))
    return true;

  if (ResType != RV->getType())
    return error(TypeLoc, "value doesn't match function result type '" +
                              getTypeString(ResType) + "'");

  Inst = ReturnInst::Create(Context, RV);
  return false;
}

/// parseBr
///   ::= 'br' TypeAndValue
///   ::= 'br' TypeAndValue ',' TypeAndValue ',' TypeAndValue
bool LLParser::parseBr(Instruction *&Inst, PerFunctionState &PFS) {
  LocTy Loc, Loc2;
  Value *Op0;
  BasicBlock *Op1, *Op2;
  if (parseTypeAndValue(Op0, Loc, PFS))
    return true;

  if (BasicBlock *BB = dyn_cast<BasicBlock>(Op0)) {
    Inst = BranchInst::Create(BB);
    return false;
  }

  if (Op0->getType() != Type::getInt1Ty(Context))
    return error(Loc, "branch condition must have 'i1' type");

  if (parseToken(lltok::comma, "expected ',' after branch condition") ||
      parseTypeAndBasicBlock(Op1, Loc, PFS) ||
      parseToken(lltok::comma, "expected ',' after true destination") ||
      parseTypeAndBasicBlock(Op2, Loc2, PFS))
    return true;

  Inst = BranchInst::Create(Op1, Op2, Op0);
  return false;
}

/// parseSwitch
///  Instruction
///    ::= 'switch' TypeAndValue ',' TypeAndValue '[' JumpTable ']'
///  JumpTable
///    ::= (TypeAndValue ',' TypeAndValue)*
bool LLParser::parseSwitch(Instruction *&Inst, PerFunctionState &PFS) {
  LocTy CondLoc, BBLoc;
  Value *Cond;
  BasicBlock *DefaultBB;
  if (parseTypeAndValue(Cond, CondLoc, PFS) ||
      parseToken(lltok::comma, "expected ',' after switch condition") ||
      parseTypeAndBasicBlock(DefaultBB, BBLoc, PFS) ||
      parseToken(lltok::lsquare, "expected '[' with switch table"))
    return true;

  if (!Cond->getType()->isIntegerTy())
    return error(CondLoc, "switch condition must have integer type");

  // parse the jump table pairs.
  SmallPtrSet<Value*, 32> SeenCases;
  SmallVector<std::pair<ConstantInt*, BasicBlock*>, 32> Table;
  while (Lex.getKind() != lltok::rsquare) {
    Value *Constant;
    BasicBlock *DestBB;

    if (parseTypeAndValue(Constant, CondLoc, PFS) ||
        parseToken(lltok::comma, "expected ',' after case value") ||
        parseTypeAndBasicBlock(DestBB, PFS))
      return true;

    if (!SeenCases.insert(Constant).second)
      return error(CondLoc, "duplicate case value in switch");
    if (!isa<ConstantInt>(Constant))
      return error(CondLoc, "case value is not a constant integer");

    Table.push_back(std::make_pair(cast<ConstantInt>(Constant), DestBB));
  }

  Lex.Lex();  // Eat the ']'.

  SwitchInst *SI = SwitchInst::Create(Cond, DefaultBB, Table.size());
  for (const auto &[OnVal, Dest] : Table)
    SI->addCase(OnVal, Dest);
  Inst = SI;
  return false;
}

/// parseIndirectBr
///  Instruction
///    ::= 'indirectbr' TypeAndValue ',' '[' LabelList ']'
bool LLParser::parseIndirectBr(Instruction *&Inst, PerFunctionState &PFS) {
  LocTy AddrLoc;
  Value *Address;
  if (parseTypeAndValue(Address, AddrLoc, PFS) ||
      parseToken(lltok::comma, "expected ',' after indirectbr address") ||
      parseToken(lltok::lsquare, "expected '[' with indirectbr"))
    return true;

  if (!Address->getType()->isPointerTy())
    return error(AddrLoc, "indirectbr address must have pointer type");

  // parse the destination list.
  SmallVector<BasicBlock*, 16> DestList;

  if (Lex.getKind() != lltok::rsquare) {
    BasicBlock *DestBB;
    if (parseTypeAndBasicBlock(DestBB, PFS))
      return true;
    DestList.push_back(DestBB);

    while (EatIfPresent(lltok::comma)) {
      if (parseTypeAndBasicBlock(DestBB, PFS))
        return true;
      DestList.push_back(DestBB);
    }
  }

  if (parseToken(lltok::rsquare, "expected ']' at end of block list"))
    return true;

  IndirectBrInst *IBI = IndirectBrInst::Create(Address, DestList.size());
  for (BasicBlock *Dest : DestList)
    IBI->addDestination(Dest);
  Inst = IBI;
  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.
bool LLParser::resolveFunctionType(Type *RetType, ArrayRef<ParamInfo> ArgList,
                                   FunctionType *&FuncTy) {
  FuncTy = dyn_cast<FunctionType>(RetType);
  if (!FuncTy) {
    // Pull out the types of all of the arguments...
    SmallVector<Type *, 8> ParamTypes;
    ParamTypes.reserve(ArgList.size());
    for (const ParamInfo &Arg : ArgList)
      ParamTypes.push_back(Arg.V->getType());

    if (!FunctionType::isValidReturnType(RetType))
      return true;

    FuncTy = FunctionType::get(RetType, ParamTypes, false);
  }
  return false;
}

/// parseInvoke
///   ::= 'invoke' OptionalCallingConv OptionalAttrs Type Value ParamList
///       OptionalAttrs 'to' TypeAndValue 'unwind' TypeAndValue
bool LLParser::parseInvoke(Instruction *&Inst, PerFunctionState &PFS) {
  LocTy CallLoc = Lex.getLoc();
  AttrBuilder RetAttrs(M->getContext()), FnAttrs(M->getContext());
  std::vector<unsigned> FwdRefAttrGrps;
  LocTy NoBuiltinLoc;
  unsigned CC;
  unsigned InvokeAddrSpace;
  Type *RetType = nullptr;
  LocTy RetTypeLoc;
  ValID CalleeID;
  SmallVector<ParamInfo, 16> ArgList;
  SmallVector<OperandBundleDef, 2> BundleList;

  BasicBlock *NormalBB, *UnwindBB;
  if (parseOptionalCallingConv(CC) || parseOptionalReturnAttrs(RetAttrs) ||
      parseOptionalProgramAddrSpace(InvokeAddrSpace) ||
      parseType(RetType, RetTypeLoc, true /*void allowed*/) ||
      parseValID(CalleeID, &PFS) || 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") ||
      parseTypeAndBasicBlock(UnwindBB, PFS))
    return true;

  // 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.
  FunctionType *Ty;
  if (resolveFunctionType(RetType, ArgList, Ty))
    return error(RetTypeLoc, "Invalid result type for LLVM function");

  CalleeID.FTy = Ty;

  // Look up the callee.
  Value *Callee;
  if (convertValIDToValue(PointerType::get(Context, InvokeAddrSpace), CalleeID,
                          Callee, &PFS))
    return true;

  // Set up the Attribute for the function.
  SmallVector<Value *, 8> Args;
  SmallVector<AttributeSet, 8> ArgAttrs;

  // Loop through FunctionType's arguments and ensure they are specified
  // correctly.  Also, gather any parameter attributes.
  FunctionType::param_iterator I = Ty->param_begin();
  FunctionType::param_iterator E = Ty->param_end();
  for (const ParamInfo &Arg : ArgList) {
    Type *ExpectedTy = nullptr;
    if (I != E) {
      ExpectedTy = *I++;
    } else if (!Ty->isVarArg()) {
      return error(Arg.Loc, "too many arguments specified");
    }

    if (ExpectedTy && ExpectedTy != Arg.V->getType())
      return error(Arg.Loc, "argument is not of expected type '" +
                                getTypeString(ExpectedTy) + "'");
    Args.push_back(Arg.V);
    ArgAttrs.push_back(Arg.Attrs);
  }

  if (I != E)
    return error(CallLoc, "not enough parameters specified for call");

  // Finish off the Attribute and check them
  AttributeList PAL =
      AttributeList::get(Context, AttributeSet::get(Context, FnAttrs),
                         AttributeSet::get(Context, RetAttrs), ArgAttrs);

  InvokeInst *II =
      InvokeInst::Create(Ty, Callee, NormalBB, UnwindBB, Args, BundleList);
  II->setCallingConv(CC);
  II->setAttributes(PAL);
  ForwardRefAttrGroups[II] = FwdRefAttrGrps;
  Inst = II;
  return false;
}

/// parseResume
///   ::= 'resume' TypeAndValue
bool LLParser::parseResume(Instruction *&Inst, PerFunctionState &PFS) {
  Value *Exn; LocTy ExnLoc;
  if (parseTypeAndValue(Exn, ExnLoc, PFS))
    return true;

  ResumeInst *RI = ResumeInst::Create(Exn);
  Inst = RI;
  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;

  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;
}

//===----------------------------------------------------------------------===//
// Unary Operators.
//===----------------------------------------------------------------------===//

/// parseUnaryOp
///  ::= UnaryOp TypeAndValue ',' Value
///
/// If IsFP is false, then any integer operand is allowed, if it is true, any fp
/// operand is allowed.
bool LLParser::parseUnaryOp(Instruction *&Inst, PerFunctionState &PFS,
                            unsigned Opc, bool IsFP) {
  LocTy Loc; Value *LHS;
  if (parseTypeAndValue(LHS, Loc, PFS))
    return true;

  bool Valid = IsFP ? LHS->getType()->isFPOrFPVectorTy()
                    : LHS->getType()->isIntOrIntVectorTy();

  if (!Valid)
    return error(Loc, "invalid operand type for instruction");

  Inst = UnaryOperator::Create((Instruction::UnaryOps)Opc, LHS);
  return false;
}

/// parseCallBr
///   ::= 'callbr' OptionalCallingConv OptionalAttrs Type Value ParamList
///       OptionalAttrs OptionalOperandBundles 'to' TypeAndValue
///       '[' LabelList ']'
bool LLParser::parseCallBr(Instruction *&Inst, PerFunctionState &PFS) {
  LocTy CallLoc = Lex.getLoc();
  AttrBuilder RetAttrs(M->getContext()), FnAttrs(M->getContext());
  std::vector<unsigned> FwdRefAttrGrps;
  LocTy NoBuiltinLoc;
  unsigned CC;
  Type *RetType = nullptr;
  LocTy RetTypeLoc;
  ValID CalleeID;
  SmallVector<ParamInfo, 16> ArgList;
  SmallVector<OperandBundleDef, 2> BundleList;

  BasicBlock *DefaultDest;
  if (parseOptionalCallingConv(CC) || parseOptionalReturnAttrs(RetAttrs) ||
      parseType(RetType, RetTypeLoc, true /*void allowed*/) ||
      parseValID(CalleeID, &PFS) || parseParameterList(ArgList, PFS) ||
      parseFnAttributeValuePairs(FnAttrs, FwdRefAttrGrps, false,
                                 NoBuiltinLoc) ||
      parseOptionalOperandBundles(BundleList, PFS) ||
      parseToken(lltok::kw_to, "expected 'to' in callbr") ||
      parseTypeAndBasicBlock(DefaultDest, PFS) ||
      parseToken(lltok::lsquare, "expected '[' in callbr"))
    return true;

  // parse the destination list.
  SmallVector<BasicBlock *, 16> IndirectDests;

  if (Lex.getKind() != lltok::rsquare) {
    BasicBlock *DestBB;
    if (parseTypeAndBasicBlock(DestBB, PFS))
      return true;
    IndirectDests.push_back(DestBB);

    while (EatIfPresent(lltok::comma)) {
      if (parseTypeAndBasicBlock(DestBB, PFS))
        return true;
      IndirectDests.push_back(DestBB);
    }
  }

  if (parseToken(lltok::rsquare, "expected ']' at end of block list"))
    return true;

  // 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.
  FunctionType *Ty;
  if (resolveFunctionType(RetType, ArgList, Ty))
    return error(RetTypeLoc, "Invalid result type for LLVM function");

  CalleeID.FTy = Ty;

  // Look up the callee.
  Value *Callee;
  if (convertValIDToValue(PointerType::getUnqual(Context), CalleeID, Callee,
                          &PFS))
    return true;

  // Set up the Attribute for the function.
  SmallVector<Value *, 8> Args;
  SmallVector<AttributeSet, 8> ArgAttrs;

  // Loop through FunctionType's arguments and ensure they are specified
  // correctly.  Also, gather any parameter attributes.
  FunctionType::param_iterator I = Ty->param_begin();
  FunctionType::param_iterator E = Ty->param_end();
  for (const ParamInfo &Arg : ArgList) {
    Type *ExpectedTy = nullptr;
    if (I != E) {
      ExpectedTy = *I++;
    } else if (!Ty->isVarArg()) {
      return error(Arg.Loc, "too many arguments specified");
    }

    if (ExpectedTy && ExpectedTy != Arg.V->getType())
      return error(Arg.Loc, "argument is not of expected type '" +
                                getTypeString(ExpectedTy) + "'");
    Args.push_back(Arg.V);
    ArgAttrs.push_back(Arg.Attrs);
  }

  if (I != E)
    return error(CallLoc, "not enough parameters specified for call");

  // Finish off the Attribute and check them
  AttributeList PAL =
      AttributeList::get(Context, AttributeSet::get(Context, FnAttrs),
                         AttributeSet::get(Context, RetAttrs), ArgAttrs);

  CallBrInst *CBI =
      CallBrInst::Create(Ty, Callee, DefaultDest, IndirectDests, Args,
                         BundleList);
  CBI->setCallingConv(CC);
  CBI->setAttributes(PAL);
  ForwardRefAttrGroups[CBI] = FwdRefAttrGrps;
  Inst = CBI;
  return false;
}

//===----------------------------------------------------------------------===//
// Binary Operators.
//===----------------------------------------------------------------------===//

/// parseArithmetic
///  ::= ArithmeticOps TypeAndValue ',' Value
///
/// If IsFP is false, then any integer operand is allowed, if it is true, any fp
/// operand is allowed.
bool LLParser::parseArithmetic(Instruction *&Inst, PerFunctionState &PFS,
                               unsigned Opc, bool IsFP) {
  LocTy Loc; Value *LHS, *RHS;
  if (parseTypeAndValue(LHS, Loc, PFS) ||
      parseToken(lltok::comma, "expected ',' in arithmetic operation") ||
      parseValue(LHS->getType(), RHS, PFS))
    return true;

  bool Valid = IsFP ? LHS->getType()->isFPOrFPVectorTy()
                    : LHS->getType()->isIntOrIntVectorTy();

  if (!Valid)
    return error(Loc, "invalid operand type for instruction");

  Inst = BinaryOperator::Create((Instruction::BinaryOps)Opc, LHS, RHS);
  return false;
}

/// parseLogical
///  ::= ArithmeticOps TypeAndValue ',' Value {
bool LLParser::parseLogical(Instruction *&Inst, PerFunctionState &PFS,
                            unsigned Opc) {
  LocTy Loc; Value *LHS, *RHS;
  if (parseTypeAndValue(LHS, Loc, PFS) ||
      parseToken(lltok::comma, "expected ',' in logical operation") ||
      parseValue(LHS->getType(), RHS, PFS))
    return true;

  if (!LHS->getType()->isIntOrIntVectorTy())
    return error(Loc,
                 "instruction requires integer or integer vector operands");

  Inst = BinaryOperator::Create((Instruction::BinaryOps)Opc, LHS, RHS);
  return false;
}

/// parseCompare
///  ::= 'icmp' IPredicates TypeAndValue ',' Value
///  ::= 'fcmp' FPredicates TypeAndValue ',' Value
bool LLParser::parseCompare(Instruction *&Inst, PerFunctionState &PFS,
                            unsigned Opc) {
  // parse the integer/fp comparison predicate.
  LocTy Loc;
  unsigned Pred;
  Value *LHS, *RHS;
  if (parseCmpPredicate(Pred, Opc) || parseTypeAndValue(LHS, Loc, PFS) ||
      parseToken(lltok::comma, "expected ',' after compare value") ||
      parseValue(LHS->getType(), RHS, PFS))
    return true;

  if (Opc == Instruction::FCmp) {
    if (!LHS->getType()->isFPOrFPVectorTy())
      return error(Loc, "fcmp requires floating point operands");
    Inst = new FCmpInst(CmpInst::Predicate(Pred), LHS, RHS);
  } else {
    assert(Opc == Instruction::ICmp && "Unknown opcode for CmpInst!");
    if (!LHS->getType()->isIntOrIntVectorTy() &&
        !LHS->getType()->isPtrOrPtrVectorTy())
      return error(Loc, "icmp requires integer operands");
    Inst = new ICmpInst(CmpInst::Predicate(Pred), LHS, RHS);
  }
  return false;
}

//===----------------------------------------------------------------------===//
// Other Instructions.
//===----------------------------------------------------------------------===//

/// parseCast
///   ::= CastOpc TypeAndValue 'to' Type
bool LLParser::parseCast(Instruction *&Inst, PerFunctionState &PFS,
                         unsigned Opc) {
  LocTy Loc;
  Value *Op;
  Type *DestTy = nullptr;
  if (parseTypeAndValue(Op, Loc, PFS) ||
      parseToken(lltok::kw_to, "expected 'to' after cast value") ||
      parseType(DestTy))
    return true;

  if (!CastInst::castIsValid((Instruction::CastOps)Opc, Op, DestTy))
    return error(Loc, "invalid cast opcode for cast from '" +
                          getTypeString(Op->getType()) + "' to '" +
                          getTypeString(DestTy) + "'");
  Inst = CastInst::Create((Instruction::CastOps)Opc, Op, DestTy);
  return false;
}

/// parseSelect
///   ::= 'select' TypeAndValue ',' TypeAndValue ',' TypeAndValue
bool LLParser::parseSelect(Instruction *&Inst, PerFunctionState &PFS) {
  LocTy Loc;
  Value *Op0, *Op1, *Op2;
  if (parseTypeAndValue(Op0, Loc, PFS) ||
      parseToken(lltok::comma, "expected ',' after select condition") ||
      parseTypeAndValue(Op1, PFS) ||
      parseToken(lltok::comma, "expected ',' after select value") ||
      parseTypeAndValue(Op2, PFS))
    return true;

  if (const char *Reason = SelectInst::areInvalidOperands(Op0, Op1, Op2))
    return error(Loc, Reason);

  Inst = SelectInst::Create(Op0, Op1, Op2);
  return false;
}

/// parseVAArg
///   ::= 'va_arg' TypeAndValue ',' Type
bool LLParser::parseVAArg(Instruction *&Inst, PerFunctionState &PFS) {
  Value *Op;
  Type *EltTy = nullptr;
  LocTy TypeLoc;
  if (parseTypeAndValue(Op, PFS) ||
      parseToken(lltok::comma, "expected ',' after vaarg operand") ||
      parseType(EltTy, TypeLoc))
    return true;

  if (!EltTy->isFirstClassType())
    return error(TypeLoc, "va_arg requires operand with first class type");

  Inst = new VAArgInst(Op, EltTy);
  return false;
}

/// parseExtractElement
///   ::= 'extractelement' TypeAndValue ',' TypeAndValue
bool LLParser::parseExtractElement(Instruction *&Inst, PerFunctionState &PFS) {
  LocTy Loc;
  Value *Op0, *Op1;
  if (parseTypeAndValue(Op0, Loc, PFS) ||
      parseToken(lltok::comma, "expected ',' after extract value") ||
      parseTypeAndValue(Op1, PFS))
    return true;

  if (!ExtractElementInst::isValidOperands(Op0, Op1))
    return error(Loc, "invalid extractelement operands");

  Inst = ExtractElementInst::Create(Op0, Op1);
  return false;
}

/// parseInsertElement
///   ::= 'insertelement' TypeAndValue ',' TypeAndValue ',' TypeAndValue
bool LLParser::parseInsertElement(Instruction *&Inst, PerFunctionState &PFS) {
  LocTy Loc;
  Value *Op0, *Op1, *Op2;
  if (parseTypeAndValue(Op0, Loc, PFS) ||
      parseToken(lltok::comma, "expected ',' after insertelement value") ||
      parseTypeAndValue(Op1, PFS) ||
      parseToken(lltok::comma, "expected ',' after insertelement value") ||
      parseTypeAndValue(Op2, PFS))
    return true;

  if (!InsertElementInst::isValidOperands(Op0, Op1, Op2))
    return error(Loc, "invalid insertelement operands");

  Inst = InsertElementInst::Create(Op0, Op1, Op2);
  return false;
}

/// parseShuffleVector
///   ::= 'shufflevector' TypeAndValue ',' TypeAndValue ',' TypeAndValue
bool LLParser::parseShuffleVector(Instruction *&Inst, PerFunctionState &PFS) {
  LocTy Loc;
  Value *Op0, *Op1, *Op2;
  if (parseTypeAndValue(Op0, Loc, PFS) ||
      parseToken(lltok::comma, "expected ',' after shuffle mask") ||
      parseTypeAndValue(Op1, PFS) ||
      parseToken(lltok::comma, "expected ',' after shuffle value") ||
      parseTypeAndValue(Op2, PFS))
    return true;

  if (!ShuffleVectorInst::isValidOperands(Op0, Op1, Op2))
    return error(Loc, "invalid shufflevector operands");

  Inst = new ShuffleVectorInst(Op0, Op1, Op2);
  return false;
}

/// parsePHI
///   ::= 'phi' Type '[' Value ',' Value ']' (',' '[' Value ',' Value ']')*
int LLParser::parsePHI(Instruction *&Inst, PerFunctionState &PFS) {
  Type *Ty = nullptr;  LocTy TypeLoc;
  Value *Op0, *Op1;

  if (parseType(Ty, TypeLoc))
    return true;

  if (!Ty->isFirstClassType())
    return error(TypeLoc, "phi node must have first class type");

  bool First = true;
  bool AteExtraComma = false;
  SmallVector<std::pair<Value*, BasicBlock*>, 16> PHIVals;

  while (true) {
    if (First) {
      if (Lex.getKind() != lltok::lsquare)
        break;
      First = false;
    } else if (!EatIfPresent(lltok::comma))
      break;

    if (Lex.getKind() == lltok::MetadataVar) {
      AteExtraComma = true;
      break;
    }

    if (parseToken(lltok::lsquare, "expected '[' in phi value list") ||
        parseValue(Ty, Op0, PFS) ||
        parseToken(lltok::comma, "expected ',' after insertelement value") ||
        parseValue(Type::getLabelTy(Context), Op1, PFS) ||
        parseToken(lltok::rsquare, "expected ']' in phi value list"))
      return true;

    PHIVals.push_back(std::make_pair(Op0, cast<BasicBlock>(Op1)));
  }

  PHINode *PN = PHINode::Create(Ty, PHIVals.size());
  for (const auto &[Val, BB] : PHIVals)
    PN->addIncoming(Val, BB);
  Inst = PN;
  return AteExtraComma ? InstExtraComma : InstNormal;
}

/// parseLandingPad
///   ::= 'landingpad' Type 'personality' TypeAndValue 'cleanup'? Clause+
/// Clause
///   ::= 'catch' TypeAndValue
///   ::= 'filter'
///   ::= 'filter' TypeAndValue ( ',' TypeAndValue )*
bool LLParser::parseLandingPad(Instruction *&Inst, PerFunctionState &PFS) {
  Type *Ty = nullptr; LocTy TyLoc;

  if (parseType(Ty, TyLoc))
    return true;

  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){
    LandingPadInst::ClauseType CT;
    if (EatIfPresent(lltok::kw_catch))
      CT = LandingPadInst::Catch;
    else if (EatIfPresent(lltok::kw_filter))
      CT = LandingPadInst::Filter;
    else
      return tokError("expected 'catch' or 'filter' clause type");

    Value *V;
    LocTy VLoc;
    if (parseTypeAndValue(V, VLoc, PFS))
      return true;

    // A 'catch' type expects a non-array constant. A filter clause expects an
    // array constant.
    if (CT == LandingPadInst::Catch) {
      if (isa<ArrayType>(V->getType()))
        return error(VLoc, "'catch' clause has an invalid type");
    } else {
      if (!isa<ArrayType>(V->getType()))
        return error(VLoc, "'filter' clause has an invalid type");
    }

    Constant *CV = dyn_cast<Constant>(V);
    if (!CV)
      return error(VLoc, "clause argument must be a constant");
    LP->addClause(CV);
  }

  Inst = LP.release();
  return false;
}

/// parseFreeze
///   ::= 'freeze' Type Value
bool LLParser::parseFreeze(Instruction *&Inst, PerFunctionState &PFS) {
  LocTy Loc;
  Value *Op;
  if (parseTypeAndValue(Op, Loc, PFS))
    return true;

  Inst = new FreezeInst(Op);
  return false;
}

/// parseCall
///   ::= '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(M->getContext()), FnAttrs(M->getContext());
  std::vector<unsigned> FwdRefAttrGrps;
  LocTy BuiltinLoc;
  unsigned CallAddrSpace;
  unsigned CC;
  Type *RetType = nullptr;
  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', 'musttail call', or 'notail call'"))
    return true;

  FastMathFlags FMF = EatFastMathFlagsIfPresent();

  if (parseOptionalCallingConv(CC) || parseOptionalReturnAttrs(RetAttrs) ||
      parseOptionalProgramAddrSpace(CallAddrSpace) ||
      parseType(RetType, RetTypeLoc, true /*void allowed*/) ||
      parseValID(CalleeID, &PFS) ||
      parseParameterList(ArgList, PFS, TCK == CallInst::TCK_MustTail,
                         PFS.getFunction().isVarArg()) ||
      parseFnAttributeValuePairs(FnAttrs, FwdRefAttrGrps, false, BuiltinLoc) ||
      parseOptionalOperandBundles(BundleList, PFS))
    return true;

  // 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.
  FunctionType *Ty;
  if (resolveFunctionType(RetType, ArgList, Ty))
    return error(RetTypeLoc, "Invalid result type for LLVM function");

  CalleeID.FTy = Ty;

  // Look up the callee.
  Value *Callee;
  if (convertValIDToValue(PointerType::get(Context, CallAddrSpace), CalleeID,
                          Callee, &PFS))
    return true;

  // Set up the Attribute for the function.
  SmallVector<AttributeSet, 8> Attrs;

  SmallVector<Value*, 8> Args;

  // Loop through FunctionType's arguments and ensure they are specified
  // correctly.  Also, gather any parameter attributes.
  FunctionType::param_iterator I = Ty->param_begin();
  FunctionType::param_iterator E = Ty->param_end();
  for (const ParamInfo &Arg : ArgList) {
    Type *ExpectedTy = nullptr;
    if (I != E) {
      ExpectedTy = *I++;
    } else if (!Ty->isVarArg()) {
      return error(Arg.Loc, "too many arguments specified");
    }

    if (ExpectedTy && ExpectedTy != Arg.V->getType())
      return error(Arg.Loc, "argument is not of expected type '" +
                                getTypeString(ExpectedTy) + "'");
    Args.push_back(Arg.V);
    Attrs.push_back(Arg.Attrs);
  }

  if (I != E)
    return error(CallLoc, "not enough parameters specified for call");

  // Finish off the Attribute and check them
  AttributeList PAL =
      AttributeList::get(Context, AttributeSet::get(Context, FnAttrs),
                         AttributeSet::get(Context, RetAttrs), Attrs);

  CallInst *CI = CallInst::Create(Ty, Callee, Args, BundleList);
  CI->setTailCallKind(TCK);
  CI->setCallingConv(CC);
  if (FMF.any()) {
    if (!isa<FPMathOperator>(CI)) {
      CI->deleteValue();
      return error(CallLoc, "fast-math-flags specified for call without "
                            "floating-point scalar or vector return type");
    }
    CI->setFastMathFlags(FMF);
  }

  if (CalleeID.Kind == ValID::t_GlobalName &&
      isOldDbgFormatIntrinsic(CalleeID.StrVal)) {
    if (SeenNewDbgInfoFormat) {
      CI->deleteValue();
      return error(CallLoc, "llvm.dbg intrinsic should not appear in a module "
                            "using non-intrinsic debug info");
    }
    SeenOldDbgInfoFormat = true;
  }
  CI->setAttributes(PAL);
  ForwardRefAttrGroups[CI] = FwdRefAttrGrps;
  Inst = CI;
  return false;
}

//===----------------------------------------------------------------------===//
// Memory Instructions.
//===----------------------------------------------------------------------===//

/// parseAlloc
///   ::= 'alloca' 'inalloca'? 'swifterror'? Type (',' TypeAndValue)?
///       (',' 'align' i32)? (',', 'addrspace(n))?
int LLParser::parseAlloc(Instruction *&Inst, PerFunctionState &PFS) {
  Value *Size = nullptr;
  LocTy SizeLoc, TyLoc, ASLoc;
  MaybeAlign Alignment;
  unsigned AddrSpace = 0;
  Type *Ty = nullptr;

  bool IsInAlloca = EatIfPresent(lltok::kw_inalloca);
  bool IsSwiftError = EatIfPresent(lltok::kw_swifterror);

  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)) {
    if (Lex.getKind() == lltok::kw_align) {
      if (parseOptionalAlignment(Alignment))
        return true;
      if (parseOptionalCommaAddrSpace(AddrSpace, ASLoc, AteExtraComma))
        return true;
    } else if (Lex.getKind() == lltok::kw_addrspace) {
      ASLoc = Lex.getLoc();
      if (parseOptionalAddrSpace(AddrSpace))
        return true;
    } else if (Lex.getKind() == lltok::MetadataVar) {
      AteExtraComma = true;
    } else {
      if (parseTypeAndValue(Size, SizeLoc, PFS))
        return true;
      if (EatIfPresent(lltok::comma)) {
        if (Lex.getKind() == lltok::kw_align) {
          if (parseOptionalAlignment(Alignment))
            return true;
          if (parseOptionalCommaAddrSpace(AddrSpace, ASLoc, AteExtraComma))
            return true;
        } else if (Lex.getKind() == lltok::kw_addrspace) {
          ASLoc = Lex.getLoc();
          if (parseOptionalAddrSpace(AddrSpace))
            return true;
        } else if (Lex.getKind() == lltok::MetadataVar) {
          AteExtraComma = true;
        }
      }
    }
  }

  if (Size && !Size->getType()->isIntegerTy())
    return error(SizeLoc, "element count must have integer type");

  SmallPtrSet<Type *, 4> Visited;
  if (!Alignment && !Ty->isSized(&Visited))
    return error(TyLoc, "Cannot allocate unsized type");
  if (!Alignment)
    Alignment = M->getDataLayout().getPrefTypeAlign(Ty);
  AllocaInst *AI = new AllocaInst(Ty, AddrSpace, Size, *Alignment);
  AI->setUsedWithInAlloca(IsInAlloca);
  AI->setSwiftError(IsSwiftError);
  Inst = AI;
  return AteExtraComma ? InstExtraComma : InstNormal;
}

/// parseLoad
///   ::= 'load' 'volatile'? TypeAndValue (',' 'align' i32)?
///   ::= 'load' 'atomic' 'volatile'? TypeAndValue
///       'singlethread'? AtomicOrdering (',' 'align' i32)?
int LLParser::parseLoad(Instruction *&Inst, PerFunctionState &PFS) {
  Value *Val; LocTy Loc;
  MaybeAlign Alignment;
  bool AteExtraComma = false;
  bool isAtomic = false;
  AtomicOrdering Ordering = AtomicOrdering::NotAtomic;
  SyncScope::ID SSID = SyncScope::System;

  if (Lex.getKind() == lltok::kw_atomic) {
    isAtomic = true;
    Lex.Lex();
  }

  bool isVolatile = false;
  if (Lex.getKind() == lltok::kw_volatile) {
    isVolatile = true;
    Lex.Lex();
  }

  Type *Ty;
  LocTy ExplicitTypeLoc = Lex.getLoc();
  if (parseType(Ty) ||
      parseToken(lltok::comma, "expected comma after load's type") ||
      parseTypeAndValue(Val, Loc, PFS) ||
      parseScopeAndOrdering(isAtomic, SSID, Ordering) ||
      parseOptionalCommaAlign(Alignment, AteExtraComma))
    return true;

  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 == AtomicOrdering::Release ||
      Ordering == AtomicOrdering::AcquireRelease)
    return error(Loc, "atomic load cannot use Release ordering");

  SmallPtrSet<Type *, 4> Visited;
  if (!Alignment && !Ty->isSized(&Visited))
    return error(ExplicitTypeLoc, "loading unsized types is not allowed");
  if (!Alignment)
    Alignment = M->getDataLayout().getABITypeAlign(Ty);
  Inst = new LoadInst(Ty, Val, "", isVolatile, *Alignment, Ordering, SSID);
  return AteExtraComma ? InstExtraComma : InstNormal;
}

/// parseStore

///   ::= 'store' 'volatile'? TypeAndValue ',' TypeAndValue (',' 'align' i32)?
///   ::= 'store' 'atomic' 'volatile'? TypeAndValue ',' TypeAndValue
///       'singlethread'? AtomicOrdering (',' 'align' i32)?
int LLParser::parseStore(Instruction *&Inst, PerFunctionState &PFS) {
  Value *Val, *Ptr; LocTy Loc, PtrLoc;
  MaybeAlign Alignment;
  bool AteExtraComma = false;
  bool isAtomic = false;
  AtomicOrdering Ordering = AtomicOrdering::NotAtomic;
  SyncScope::ID SSID = SyncScope::System;

  if (Lex.getKind() == lltok::kw_atomic) {
    isAtomic = true;
    Lex.Lex();
  }

  bool isVolatile = false;
  if (Lex.getKind() == lltok::kw_volatile) {
    isVolatile = true;
    Lex.Lex();
  }

  if (parseTypeAndValue(Val, Loc, PFS) ||
      parseToken(lltok::comma, "expected ',' after store operand") ||
      parseTypeAndValue(Ptr, PtrLoc, PFS) ||
      parseScopeAndOrdering(isAtomic, SSID, Ordering) ||
      parseOptionalCommaAlign(Alignment, AteExtraComma))
    return true;

  if (!Ptr->getType()->isPointerTy())
    return error(PtrLoc, "store operand must be a pointer");
  if (!Val->getType()->isFirstClassType())
    return error(Loc, "store operand must be a first class value");
  if (isAtomic && !Alignment)
    return error(Loc, "atomic store must have explicit non-zero alignment");
  if (Ordering == AtomicOrdering::Acquire ||
      Ordering == AtomicOrdering::AcquireRelease)
    return error(Loc, "atomic store cannot use Acquire ordering");
  SmallPtrSet<Type *, 4> Visited;
  if (!Alignment && !Val->getType()->isSized(&Visited))
    return error(Loc, "storing unsized types is not allowed");
  if (!Alignment)
    Alignment = M->getDataLayout().getABITypeAlign(Val->getType());

  Inst = new StoreInst(Val, Ptr, isVolatile, *Alignment, Ordering, SSID);
  return AteExtraComma ? InstExtraComma : InstNormal;
}

/// parseCmpXchg
///   ::= 'cmpxchg' 'weak'? 'volatile'? TypeAndValue ',' TypeAndValue ','
///       TypeAndValue 'singlethread'? AtomicOrdering AtomicOrdering ','
///       'Align'?
int LLParser::parseCmpXchg(Instruction *&Inst, PerFunctionState &PFS) {
  Value *Ptr, *Cmp, *New; LocTy PtrLoc, CmpLoc, NewLoc;
  bool AteExtraComma = false;
  AtomicOrdering SuccessOrdering = AtomicOrdering::NotAtomic;
  AtomicOrdering FailureOrdering = AtomicOrdering::NotAtomic;
  SyncScope::ID SSID = SyncScope::System;
  bool isVolatile = false;
  bool isWeak = false;
  MaybeAlign Alignment;

  if (EatIfPresent(lltok::kw_weak))
    isWeak = true;

  if (EatIfPresent(lltok::kw_volatile))
    isVolatile = true;

  if (parseTypeAndValue(Ptr, PtrLoc, PFS) ||
      parseToken(lltok::comma, "expected ',' after cmpxchg address") ||
      parseTypeAndValue(Cmp, CmpLoc, PFS) ||
      parseToken(lltok::comma, "expected ',' after cmpxchg cmp operand") ||
      parseTypeAndValue(New, NewLoc, PFS) ||
      parseScopeAndOrdering(true /*Always atomic*/, SSID, SuccessOrdering) ||
      parseOrdering(FailureOrdering) ||
      parseOptionalCommaAlign(Alignment, AteExtraComma))
    return true;

  if (!AtomicCmpXchgInst::isValidSuccessOrdering(SuccessOrdering))
    return tokError("invalid cmpxchg success ordering");
  if (!AtomicCmpXchgInst::isValidFailureOrdering(FailureOrdering))
    return tokError("invalid cmpxchg failure ordering");
  if (!Ptr->getType()->isPointerTy())
    return error(PtrLoc, "cmpxchg operand must be a pointer");
  if (Cmp->getType() != New->getType())
    return error(NewLoc, "compare value and new value type do not match");
  if (!New->getType()->isFirstClassType())
    return error(NewLoc, "cmpxchg operand must be a first class value");

  const Align DefaultAlignment(
      PFS.getFunction().getDataLayout().getTypeStoreSize(
          Cmp->getType()));

  AtomicCmpXchgInst *CXI =
      new AtomicCmpXchgInst(Ptr, Cmp, New, Alignment.value_or(DefaultAlignment),
                            SuccessOrdering, FailureOrdering, SSID);
  CXI->setVolatile(isVolatile);
  CXI->setWeak(isWeak);

  Inst = CXI;
  return AteExtraComma ? InstExtraComma : InstNormal;
}

/// parseAtomicRMW
///   ::= 'atomicrmw' 'volatile'? BinOp TypeAndValue ',' TypeAndValue
///       'singlethread'? AtomicOrdering
int LLParser::parseAtomicRMW(Instruction *&Inst, PerFunctionState &PFS) {
  Value *Ptr, *Val; LocTy PtrLoc, ValLoc;
  bool AteExtraComma = false;
  AtomicOrdering Ordering = AtomicOrdering::NotAtomic;
  SyncScope::ID SSID = SyncScope::System;
  bool isVolatile = false;
  bool IsFP = false;
  AtomicRMWInst::BinOp Operation;
  MaybeAlign Alignment;

  if (EatIfPresent(lltok::kw_volatile))
    isVolatile = true;

  switch (Lex.getKind()) {
  default:
    return tokError("expected binary operation in atomicrmw");
  case lltok::kw_xchg: Operation = AtomicRMWInst::Xchg; break;
  case lltok::kw_add: Operation = AtomicRMWInst::Add; break;
  case lltok::kw_sub: Operation = AtomicRMWInst::Sub; break;
  case lltok::kw_and: Operation = AtomicRMWInst::And; break;
  case lltok::kw_nand: Operation = AtomicRMWInst::Nand; break;
  case lltok::kw_or: Operation = AtomicRMWInst::Or; break;
  case lltok::kw_xor: Operation = AtomicRMWInst::Xor; break;
  case lltok::kw_max: Operation = AtomicRMWInst::Max; break;
  case lltok::kw_min: Operation = AtomicRMWInst::Min; break;
  case lltok::kw_umax: Operation = AtomicRMWInst::UMax; break;
  case lltok::kw_umin: Operation = AtomicRMWInst::UMin; break;
  case lltok::kw_uinc_wrap:
    Operation = AtomicRMWInst::UIncWrap;
    break;
  case lltok::kw_udec_wrap:
    Operation = AtomicRMWInst::UDecWrap;
    break;
  case lltok::kw_usub_cond:
    Operation = AtomicRMWInst::USubCond;
    break;
  case lltok::kw_usub_sat:
    Operation = AtomicRMWInst::USubSat;
    break;
  case lltok::kw_fadd:
    Operation = AtomicRMWInst::FAdd;
    IsFP = true;
    break;
  case lltok::kw_fsub:
    Operation = AtomicRMWInst::FSub;
    IsFP = true;
    break;
  case lltok::kw_fmax:
    Operation = AtomicRMWInst::FMax;
    IsFP = true;
    break;
  case lltok::kw_fmin:
    Operation = AtomicRMWInst::FMin;
    IsFP = true;
    break;
  case lltok::kw_fmaximum:
    Operation = AtomicRMWInst::FMaximum;
    IsFP = true;
    break;
  case lltok::kw_fminimum:
    Operation = AtomicRMWInst::FMinimum;
    IsFP = true;
    break;
  }
  Lex.Lex();  // Eat the operation.

  if (parseTypeAndValue(Ptr, PtrLoc, PFS) ||
      parseToken(lltok::comma, "expected ',' after atomicrmw address") ||
      parseTypeAndValue(Val, ValLoc, PFS) ||
      parseScopeAndOrdering(true /*Always atomic*/, SSID, Ordering) ||
      parseOptionalCommaAlign(Alignment, AteExtraComma))
    return true;

  if (Ordering == AtomicOrdering::Unordered)
    return tokError("atomicrmw cannot be unordered");
  if (!Ptr->getType()->isPointerTy())
    return error(PtrLoc, "atomicrmw operand must be a pointer");
  if (Val->getType()->isScalableTy())
    return error(ValLoc, "atomicrmw operand may not be scalable");

  if (Operation == AtomicRMWInst::Xchg) {
    if (!Val->getType()->isIntegerTy() &&
        !Val->getType()->isFloatingPointTy() &&
        !Val->getType()->isPointerTy()) {
      return error(
          ValLoc,
          "atomicrmw " + AtomicRMWInst::getOperationName(Operation) +
              " operand must be an integer, floating point, or pointer type");
    }
  } else if (IsFP) {
    if (!Val->getType()->isFPOrFPVectorTy()) {
      return error(ValLoc, "atomicrmw " +
                               AtomicRMWInst::getOperationName(Operation) +
                               " operand must be a floating point type");
    }
  } else {
    if (!Val->getType()->isIntegerTy()) {
      return error(ValLoc, "atomicrmw " +
                               AtomicRMWInst::getOperationName(Operation) +
                               " operand must be an integer");
    }
  }

  unsigned Size =
      PFS.getFunction().getDataLayout().getTypeStoreSizeInBits(
          Val->getType());
  if (Size < 8 || (Size & (Size - 1)))
    return error(ValLoc, "atomicrmw operand must be power-of-two byte-sized"
                         " integer");
  const Align DefaultAlignment(
      PFS.getFunction().getDataLayout().getTypeStoreSize(
          Val->getType()));
  AtomicRMWInst *RMWI =
      new AtomicRMWInst(Operation, Ptr, Val,
                        Alignment.value_or(DefaultAlignment), Ordering, SSID);
  RMWI->setVolatile(isVolatile);
  Inst = RMWI;
  return AteExtraComma ? InstExtraComma : InstNormal;
}

/// parseFence
///   ::= 'fence' 'singlethread'? AtomicOrdering
int LLParser::parseFence(Instruction *&Inst, PerFunctionState &PFS) {
  AtomicOrdering Ordering = AtomicOrdering::NotAtomic;
  SyncScope::ID SSID = SyncScope::System;
  if (parseScopeAndOrdering(true /*Always atomic*/, SSID, Ordering))
    return true;

  if (Ordering == AtomicOrdering::Unordered)
    return tokError("fence cannot be unordered");
  if (Ordering == AtomicOrdering::Monotonic)
    return tokError("fence cannot be monotonic");

  Inst = new FenceInst(Context, Ordering, SSID);
  return InstNormal;
}

/// parseGetElementPtr
///   ::= 'getelementptr' 'inbounds'? TypeAndValue (',' TypeAndValue)*
int LLParser::parseGetElementPtr(Instruction *&Inst, PerFunctionState &PFS) {
  Value *Ptr = nullptr;
  Value *Val = nullptr;
  LocTy Loc, EltLoc;
  GEPNoWrapFlags NW;

  while (true) {
    if (EatIfPresent(lltok::kw_inbounds))
      NW |= GEPNoWrapFlags::inBounds();
    else if (EatIfPresent(lltok::kw_nusw))
      NW |= GEPNoWrapFlags::noUnsignedSignedWrap();
    else if (EatIfPresent(lltok::kw_nuw))
      NW |= GEPNoWrapFlags::noUnsignedWrap();
    else
      break;
  }

  Type *Ty = nullptr;
  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");

  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.
  ElementCount GEPWidth = BaseType->isVectorTy()
                              ? cast<VectorType>(BaseType)->getElementCount()
                              : ElementCount::getFixed(0);

  while (EatIfPresent(lltok::comma)) {
    if (Lex.getKind() == lltok::MetadataVar) {
      AteExtraComma = true;
      break;
    }
    if (parseTypeAndValue(Val, EltLoc, PFS))
      return true;
    if (!Val->getType()->isIntOrIntVectorTy())
      return error(EltLoc, "getelementptr index must be an integer");

    if (auto *ValVTy = dyn_cast<VectorType>(Val->getType())) {
      ElementCount ValNumEl = ValVTy->getElementCount();
      if (GEPWidth != ElementCount::getFixed(0) && GEPWidth != ValNumEl)
        return error(
            EltLoc,
            "getelementptr vector index has a wrong number of elements");
      GEPWidth = ValNumEl;
    }
    Indices.push_back(Val);
  }

  SmallPtrSet<Type*, 4> Visited;
  if (!Indices.empty() && !Ty->isSized(&Visited))
    return error(Loc, "base element of getelementptr must be sized");

  auto *STy = dyn_cast<StructType>(Ty);
  if (STy && STy->isScalableTy())
    return error(Loc, "getelementptr cannot target structure that contains "
                      "scalable vector type");

  if (!GetElementPtrInst::getIndexedType(Ty, Indices))
    return error(Loc, "invalid getelementptr indices");
  GetElementPtrInst *GEP = GetElementPtrInst::Create(Ty, Ptr, Indices);
  Inst = GEP;
  GEP->setNoWrapFlags(NW);
  return AteExtraComma ? InstExtraComma : InstNormal;
}

/// parseExtractValue
///   ::= 'extractvalue' TypeAndValue (',' uint32)+
int LLParser::parseExtractValue(Instruction *&Inst, PerFunctionState &PFS) {
  Value *Val; LocTy Loc;
  SmallVector<unsigned, 4> Indices;
  bool AteExtraComma;
  if (parseTypeAndValue(Val, Loc, PFS) ||
      parseIndexList(Indices, AteExtraComma))
    return true;

  if (!Val->getType()->isAggregateType())
    return error(Loc, "extractvalue operand must be aggregate type");

  if (!ExtractValueInst::getIndexedType(Val->getType(), Indices))
    return error(Loc, "invalid indices for extractvalue");
  Inst = ExtractValueInst::Create(Val, Indices);
  return AteExtraComma ? InstExtraComma : InstNormal;
}

/// parseInsertValue
///   ::= 'insertvalue' TypeAndValue ',' TypeAndValue (',' uint32)+
int LLParser::parseInsertValue(Instruction *&Inst, PerFunctionState &PFS) {
  Value *Val0, *Val1; LocTy Loc0, Loc1;
  SmallVector<unsigned, 4> Indices;
  bool AteExtraComma;
  if (parseTypeAndValue(Val0, Loc0, PFS) ||
      parseToken(lltok::comma, "expected comma after insertvalue operand") ||
      parseTypeAndValue(Val1, Loc1, PFS) ||
      parseIndexList(Indices, AteExtraComma))
    return true;

  if (!Val0->getType()->isAggregateType())
    return error(Loc0, "insertvalue operand must be aggregate type");

  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;
}

//===----------------------------------------------------------------------===//
// Embedded metadata.
//===----------------------------------------------------------------------===//

/// parseMDNodeVector
///   ::= { Element (',' Element)* }
/// Element
///   ::= 'null' | Metadata
bool LLParser::parseMDNodeVector(SmallVectorImpl<Metadata *> &Elts) {
  if (parseToken(lltok::lbrace, "expected '{' here"))
    return true;

  // Check for an empty list.
  if (EatIfPresent(lltok::rbrace))
    return false;

  do {
    if (EatIfPresent(lltok::kw_null)) {
      Elts.push_back(nullptr);
      continue;
    }

    Metadata *MD;
    if (parseMetadata(MD, nullptr))
      return true;
    Elts.push_back(MD);
  } while (EatIfPresent(lltok::comma));

  return parseToken(lltok::rbrace, "expected end of metadata node");
}

//===----------------------------------------------------------------------===//
// Use-list order directives.
//===----------------------------------------------------------------------===//
bool LLParser::sortUseListOrder(Value *V, ArrayRef<unsigned> Indexes,
                                SMLoc Loc) {
  if (!V->hasUseList())
    return false;
  if (V->use_empty())
    return error(Loc, "value has no uses");

  unsigned NumUses = 0;
  SmallDenseMap<const Use *, unsigned, 16> Order;
  for (const Use &U : V->uses()) {
    if (++NumUses > Indexes.size())
      break;
    Order[&U] = Indexes[NumUses - 1];
  }
  if (NumUses < 2)
    return error(Loc, "value only has one use");
  if (Order.size() != Indexes.size() || NumUses > Indexes.size())
    return error(Loc,
                 "wrong number of indexes, expected " + Twine(V->getNumUses()));

  V->sortUseList([&](const Use &L, const Use &R) {
    return Order.lookup(&L) < Order.lookup(&R);
  });
  return false;
}

/// parseUseListOrderIndexes
///   ::= '{' uint32 (',' uint32)+ '}'
bool LLParser::parseUseListOrderIndexes(SmallVectorImpl<unsigned> &Indexes) {
  SMLoc Loc = Lex.getLoc();
  if (parseToken(lltok::lbrace, "expected '{' here"))
    return true;
  if (Lex.getKind() == lltok::rbrace)
    return tokError("expected non-empty list of uselistorder indexes");

  // Use Offset, Max, and IsOrdered to check consistency of indexes.  The
  // indexes should be distinct numbers in the range [0, size-1], and should
  // not be in order.
  unsigned Offset = 0;
  unsigned Max = 0;
  bool IsOrdered = true;
  assert(Indexes.empty() && "Expected empty order vector");
  do {
    unsigned Index;
    if (parseUInt32(Index))
      return true;

    // Update consistency checks.
    Offset += Index - Indexes.size();
    Max = std::max(Max, Index);
    IsOrdered &= Index == Indexes.size();

    Indexes.push_back(Index);
  } while (EatIfPresent(lltok::comma));

  if (parseToken(lltok::rbrace, "expected '}' here"))
    return true;

  if (Indexes.size() < 2)
    return error(Loc, "expected >= 2 uselistorder indexes");
  if (Offset != 0 || Max >= Indexes.size())
    return error(Loc,
                 "expected distinct uselistorder indexes in range [0, size)");
  if (IsOrdered)
    return error(Loc, "expected uselistorder indexes to change the order");

  return false;
}

/// parseUseListOrder
///   ::= 'uselistorder' Type Value ',' UseListOrderIndexes
bool LLParser::parseUseListOrder(PerFunctionState *PFS) {
  SMLoc Loc = Lex.getLoc();
  if (parseToken(lltok::kw_uselistorder, "expected uselistorder directive"))
    return true;

  Value *V;
  SmallVector<unsigned, 16> Indexes;
  if (parseTypeAndValue(V, PFS) ||
      parseToken(lltok::comma, "expected comma in uselistorder directive") ||
      parseUseListOrderIndexes(Indexes))
    return true;

  return sortUseListOrder(V, Indexes, Loc);
}

/// parseUseListOrderBB
///   ::= 'uselistorder_bb' @foo ',' %bar ',' UseListOrderIndexes
bool LLParser::parseUseListOrderBB() {
  assert(Lex.getKind() == lltok::kw_uselistorder_bb);
  SMLoc Loc = Lex.getLoc();
  Lex.Lex();

  ValID Fn, Label;
  SmallVector<unsigned, 16> Indexes;
  if (parseValID(Fn, /*PFS=*/nullptr) ||
      parseToken(lltok::comma, "expected comma in uselistorder_bb directive") ||
      parseValID(Label, /*PFS=*/nullptr) ||
      parseToken(lltok::comma, "expected comma in uselistorder_bb directive") ||
      parseUseListOrderIndexes(Indexes))
    return true;

  // Check the function.
  GlobalValue *GV;
  if (Fn.Kind == ValID::t_GlobalName)
    GV = M->getNamedValue(Fn.StrVal);
  else if (Fn.Kind == ValID::t_GlobalID)
    GV = NumberedVals.get(Fn.UIntVal);
  else
    return error(Fn.Loc, "expected function name in uselistorder_bb");
  if (!GV)
    return error(Fn.Loc,
                 "invalid function forward reference in uselistorder_bb");
  auto *F = dyn_cast<Function>(GV);
  if (!F)
    return error(Fn.Loc, "expected function name in uselistorder_bb");
  if (F->isDeclaration())
    return error(Fn.Loc, "invalid declaration in uselistorder_bb");

  // Check the basic block.
  if (Label.Kind == ValID::t_LocalID)
    return error(Label.Loc, "invalid numeric label in uselistorder_bb");
  if (Label.Kind != ValID::t_LocalName)
    return error(Label.Loc, "expected basic block name in uselistorder_bb");
  Value *V = F->getValueSymbolTable()->lookup(Label.StrVal);
  if (!V)
    return error(Label.Loc, "invalid basic block in uselistorder_bb");
  if (!isa<BasicBlock>(V))
    return error(Label.Loc, "expected basic block in uselistorder_bb");

  return sortUseListOrder(V, Indexes, Loc);
}

/// ModuleEntry
///   ::= 'module' ':' '(' 'path' ':' STRINGCONSTANT ',' 'hash' ':' Hash ')'
/// Hash ::= '(' UInt32 ',' UInt32 ',' UInt32 ',' UInt32 ',' UInt32 ')'
bool LLParser::parseModuleEntry(unsigned ID) {
  assert(Lex.getKind() == lltok::kw_module);
  Lex.Lex();

  std::string Path;
  if (parseToken(lltok::colon, "expected ':' here") ||
      parseToken(lltok::lparen, "expected '(' here") ||
      parseToken(lltok::kw_path, "expected 'path' here") ||
      parseToken(lltok::colon, "expected ':' here") ||
      parseStringConstant(Path) ||
      parseToken(lltok::comma, "expected ',' here") ||
      parseToken(lltok::kw_hash, "expected 'hash' here") ||
      parseToken(lltok::colon, "expected ':' here") ||
      parseToken(lltok::lparen, "expected '(' here"))
    return true;

  ModuleHash Hash;
  if (parseUInt32(Hash[0]) || parseToken(lltok::comma, "expected ',' here") ||
      parseUInt32(Hash[1]) || parseToken(lltok::comma, "expected ',' here") ||
      parseUInt32(Hash[2]) || parseToken(lltok::comma, "expected ',' here") ||
      parseUInt32(Hash[3]) || parseToken(lltok::comma, "expected ',' here") ||
      parseUInt32(Hash[4]))
    return true;

  if (parseToken(lltok::rparen, "expected ')' here") ||
      parseToken(lltok::rparen, "expected ')' here"))
    return true;

  auto ModuleEntry = Index->addModule(Path, Hash);
  ModuleIdMap[ID] = ModuleEntry->first();

  return false;
}

/// TypeIdEntry
///   ::= 'typeid' ':' '(' 'name' ':' STRINGCONSTANT ',' TypeIdSummary ')'
bool LLParser::parseTypeIdEntry(unsigned ID) {
  assert(Lex.getKind() == lltok::kw_typeid);
  Lex.Lex();

  std::string Name;
  if (parseToken(lltok::colon, "expected ':' here") ||
      parseToken(lltok::lparen, "expected '(' here") ||
      parseToken(lltok::kw_name, "expected 'name' here") ||
      parseToken(lltok::colon, "expected ':' here") ||
      parseStringConstant(Name))
    return true;

  TypeIdSummary &TIS = Index->getOrInsertTypeIdSummary(Name);
  if (parseToken(lltok::comma, "expected ',' here") ||
      parseTypeIdSummary(TIS) || parseToken(lltok::rparen, "expected ')' here"))
    return true;

  // Check if this ID was forward referenced, and if so, update the
  // corresponding GUIDs.
  auto FwdRefTIDs = ForwardRefTypeIds.find(ID);
  if (FwdRefTIDs != ForwardRefTypeIds.end()) {
    for (auto TIDRef : FwdRefTIDs->second) {
      assert(!*TIDRef.first &&
             "Forward referenced type id GUID expected to be 0");
      *TIDRef.first = GlobalValue::getGUIDAssumingExternalLinkage(Name);
    }
    ForwardRefTypeIds.erase(FwdRefTIDs);
  }

  return false;
}

/// TypeIdSummary
///   ::= 'summary' ':' '(' TypeTestResolution [',' OptionalWpdResolutions]? ')'
bool LLParser::parseTypeIdSummary(TypeIdSummary &TIS) {
  if (parseToken(lltok::kw_summary, "expected 'summary' here") ||
      parseToken(lltok::colon, "expected ':' here") ||
      parseToken(lltok::lparen, "expected '(' here") ||
      parseTypeTestResolution(TIS.TTRes))
    return true;

  if (EatIfPresent(lltok::comma)) {
    // Expect optional wpdResolutions field
    if (parseOptionalWpdResolutions(TIS.WPDRes))
      return true;
  }

  if (parseToken(lltok::rparen, "expected ')' here"))
    return true;

  return false;
}

static ValueInfo EmptyVI =
    ValueInfo(false, (GlobalValueSummaryMapTy::value_type *)-8);

/// TypeIdCompatibleVtableEntry
///   ::= 'typeidCompatibleVTable' ':' '(' 'name' ':' STRINGCONSTANT ','
///   TypeIdCompatibleVtableInfo
///   ')'
bool LLParser::parseTypeIdCompatibleVtableEntry(unsigned ID) {
  assert(Lex.getKind() == lltok::kw_typeidCompatibleVTable);
  Lex.Lex();

  std::string Name;
  if (parseToken(lltok::colon, "expected ':' here") ||
      parseToken(lltok::lparen, "expected '(' here") ||
      parseToken(lltok::kw_name, "expected 'name' here") ||
      parseToken(lltok::colon, "expected ':' here") ||
      parseStringConstant(Name))
    return true;

  TypeIdCompatibleVtableInfo &TI =
      Index->getOrInsertTypeIdCompatibleVtableSummary(Name);
  if (parseToken(lltok::comma, "expected ',' here") ||
      parseToken(lltok::kw_summary, "expected 'summary' here") ||
      parseToken(lltok::colon, "expected ':' here") ||
      parseToken(lltok::lparen, "expected '(' here"))
    return true;

  IdToIndexMapType IdToIndexMap;
  // parse each call edge
  do {
    uint64_t Offset;
    if (parseToken(lltok::lparen, "expected '(' here") ||
        parseToken(lltok::kw_offset, "expected 'offset' here") ||
        parseToken(lltok::colon, "expected ':' here") || parseUInt64(Offset) ||
        parseToken(lltok::comma, "expected ',' here"))
      return true;

    LocTy Loc = Lex.getLoc();
    unsigned GVId;
    ValueInfo VI;
    if (parseGVReference(VI, GVId))
      return true;

    // Keep track of the TypeIdCompatibleVtableInfo array index needing a
    // forward reference. We will save the location of the ValueInfo needing an
    // update, but can only do so once the std::vector is finalized.
    if (VI == EmptyVI)
      IdToIndexMap[GVId].push_back(std::make_pair(TI.size(), Loc));
    TI.push_back({Offset, VI});

    if (parseToken(lltok::rparen, "expected ')' in call"))
      return true;
  } while (EatIfPresent(lltok::comma));

  // Now that the TI vector is finalized, it is safe to save the locations
  // of any forward GV references that need updating later.
  for (auto I : IdToIndexMap) {
    auto &Infos = ForwardRefValueInfos[I.first];
    for (auto P : I.second) {
      assert(TI[P.first].VTableVI == EmptyVI &&
             "Forward referenced ValueInfo expected to be empty");
      Infos.emplace_back(&TI[P.first].VTableVI, P.second);
    }
  }

  if (parseToken(lltok::rparen, "expected ')' here") ||
      parseToken(lltok::rparen, "expected ')' here"))
    return true;

  // Check if this ID was forward referenced, and if so, update the
  // corresponding GUIDs.
  auto FwdRefTIDs = ForwardRefTypeIds.find(ID);
  if (FwdRefTIDs != ForwardRefTypeIds.end()) {
    for (auto TIDRef : FwdRefTIDs->second) {
      assert(!*TIDRef.first &&
             "Forward referenced type id GUID expected to be 0");
      *TIDRef.first = GlobalValue::getGUIDAssumingExternalLinkage(Name);
    }
    ForwardRefTypeIds.erase(FwdRefTIDs);
  }

  return false;
}

/// TypeTestResolution
///   ::= 'typeTestRes' ':' '(' 'kind' ':'
///         ( 'unsat' | 'byteArray' | 'inline' | 'single' | 'allOnes' ) ','
///         'sizeM1BitWidth' ':' SizeM1BitWidth [',' 'alignLog2' ':' UInt64]?
///         [',' 'sizeM1' ':' UInt64]? [',' 'bitMask' ':' UInt8]?
///         [',' 'inlinesBits' ':' UInt64]? ')'
bool LLParser::parseTypeTestResolution(TypeTestResolution &TTRes) {
  if (parseToken(lltok::kw_typeTestRes, "expected 'typeTestRes' here") ||
      parseToken(lltok::colon, "expected ':' here") ||
      parseToken(lltok::lparen, "expected '(' here") ||
      parseToken(lltok::kw_kind, "expected 'kind' here") ||
      parseToken(lltok::colon, "expected ':' here"))
    return true;

  switch (Lex.getKind()) {
  case lltok::kw_unknown:
    TTRes.TheKind = TypeTestResolution::Unknown;
    break;
  case lltok::kw_unsat:
    TTRes.TheKind = TypeTestResolution::Unsat;
    break;
  case lltok::kw_byteArray:
    TTRes.TheKind = TypeTestResolution::ByteArray;
    break;
  case lltok::kw_inline:
    TTRes.TheKind = TypeTestResolution::Inline;
    break;
  case lltok::kw_single:
    TTRes.TheKind = TypeTestResolution::Single;
    break;
  case lltok::kw_allOnes:
    TTRes.TheKind = TypeTestResolution::AllOnes;
    break;
  default:
    return error(Lex.getLoc(), "unexpected TypeTestResolution kind");
  }
  Lex.Lex();

  if (parseToken(lltok::comma, "expected ',' here") ||
      parseToken(lltok::kw_sizeM1BitWidth, "expected 'sizeM1BitWidth' here") ||
      parseToken(lltok::colon, "expected ':' here") ||
      parseUInt32(TTRes.SizeM1BitWidth))
    return true;

  // parse optional fields
  while (EatIfPresent(lltok::comma)) {
    switch (Lex.getKind()) {
    case lltok::kw_alignLog2:
      Lex.Lex();
      if (parseToken(lltok::colon, "expected ':'") ||
          parseUInt64(TTRes.AlignLog2))
        return true;
      break;
    case lltok::kw_sizeM1:
      Lex.Lex();
      if (parseToken(lltok::colon, "expected ':'") || parseUInt64(TTRes.SizeM1))
        return true;
      break;
    case lltok::kw_bitMask: {
      unsigned Val;
      Lex.Lex();
      if (parseToken(lltok::colon, "expected ':'") || parseUInt32(Val))
        return true;
      assert(Val <= 0xff);
      TTRes.BitMask = (uint8_t)Val;
      break;
    }
    case lltok::kw_inlineBits:
      Lex.Lex();
      if (parseToken(lltok::colon, "expected ':'") ||
          parseUInt64(TTRes.InlineBits))
        return true;
      break;
    default:
      return error(Lex.getLoc(), "expected optional TypeTestResolution field");
    }
  }

  if (parseToken(lltok::rparen, "expected ')' here"))
    return true;

  return false;
}

/// OptionalWpdResolutions
///   ::= 'wpsResolutions' ':' '(' WpdResolution [',' WpdResolution]* ')'
/// WpdResolution ::= '(' 'offset' ':' UInt64 ',' WpdRes ')'
bool LLParser::parseOptionalWpdResolutions(
    std::map<uint64_t, WholeProgramDevirtResolution> &WPDResMap) {
  if (parseToken(lltok::kw_wpdResolutions, "expected 'wpdResolutions' here") ||
      parseToken(lltok::colon, "expected ':' here") ||
      parseToken(lltok::lparen, "expected '(' here"))
    return true;

  do {
    uint64_t Offset;
    WholeProgramDevirtResolution WPDRes;
    if (parseToken(lltok::lparen, "expected '(' here") ||
        parseToken(lltok::kw_offset, "expected 'offset' here") ||
        parseToken(lltok::colon, "expected ':' here") || parseUInt64(Offset) ||
        parseToken(lltok::comma, "expected ',' here") || parseWpdRes(WPDRes) ||
        parseToken(lltok::rparen, "expected ')' here"))
      return true;
    WPDResMap[Offset] = WPDRes;
  } while (EatIfPresent(lltok::comma));

  if (parseToken(lltok::rparen, "expected ')' here"))
    return true;

  return false;
}

/// WpdRes
///   ::= 'wpdRes' ':' '(' 'kind' ':' 'indir'
///         [',' OptionalResByArg]? ')'
///   ::= 'wpdRes' ':' '(' 'kind' ':' 'singleImpl'
///         ',' 'singleImplName' ':' STRINGCONSTANT ','
///         [',' OptionalResByArg]? ')'
///   ::= 'wpdRes' ':' '(' 'kind' ':' 'branchFunnel'
///         [',' OptionalResByArg]? ')'
bool LLParser::parseWpdRes(WholeProgramDevirtResolution &WPDRes) {
  if (parseToken(lltok::kw_wpdRes, "expected 'wpdRes' here") ||
      parseToken(lltok::colon, "expected ':' here") ||
      parseToken(lltok::lparen, "expected '(' here") ||
      parseToken(lltok::kw_kind, "expected 'kind' here") ||
      parseToken(lltok::colon, "expected ':' here"))
    return true;

  switch (Lex.getKind()) {
  case lltok::kw_indir:
    WPDRes.TheKind = WholeProgramDevirtResolution::Indir;
    break;
  case lltok::kw_singleImpl:
    WPDRes.TheKind = WholeProgramDevirtResolution::SingleImpl;
    break;
  case lltok::kw_branchFunnel:
    WPDRes.TheKind = WholeProgramDevirtResolution::BranchFunnel;
    break;
  default:
    return error(Lex.getLoc(), "unexpected WholeProgramDevirtResolution kind");
  }
  Lex.Lex();

  // parse optional fields
  while (EatIfPresent(lltok::comma)) {
    switch (Lex.getKind()) {
    case lltok::kw_singleImplName:
      Lex.Lex();
      if (parseToken(lltok::colon, "expected ':' here") ||
          parseStringConstant(WPDRes.SingleImplName))
        return true;
      break;
    case lltok::kw_resByArg:
      if (parseOptionalResByArg(WPDRes.ResByArg))
        return true;
      break;
    default:
      return error(Lex.getLoc(),
                   "expected optional WholeProgramDevirtResolution field");
    }
  }

  if (parseToken(lltok::rparen, "expected ')' here"))
    return true;

  return false;
}

/// OptionalResByArg
///   ::= 'wpdRes' ':' '(' ResByArg[, ResByArg]* ')'
/// ResByArg ::= Args ',' 'byArg' ':' '(' 'kind' ':'
///                ( 'indir' | 'uniformRetVal' | 'UniqueRetVal' |
///                  'virtualConstProp' )
///                [',' 'info' ':' UInt64]? [',' 'byte' ':' UInt32]?
///                [',' 'bit' ':' UInt32]? ')'
bool LLParser::parseOptionalResByArg(
    std::map<std::vector<uint64_t>, WholeProgramDevirtResolution::ByArg>
        &ResByArg) {
  if (parseToken(lltok::kw_resByArg, "expected 'resByArg' here") ||
      parseToken(lltok::colon, "expected ':' here") ||
      parseToken(lltok::lparen, "expected '(' here"))
    return true;

  do {
    std::vector<uint64_t> Args;
    if (parseArgs(Args) || parseToken(lltok::comma, "expected ',' here") ||
        parseToken(lltok::kw_byArg, "expected 'byArg here") ||
        parseToken(lltok::colon, "expected ':' here") ||
        parseToken(lltok::lparen, "expected '(' here") ||
        parseToken(lltok::kw_kind, "expected 'kind' here") ||
        parseToken(lltok::colon, "expected ':' here"))
      return true;

    WholeProgramDevirtResolution::ByArg ByArg;
    switch (Lex.getKind()) {
    case lltok::kw_indir:
      ByArg.TheKind = WholeProgramDevirtResolution::ByArg::Indir;
      break;
    case lltok::kw_uniformRetVal:
      ByArg.TheKind = WholeProgramDevirtResolution::ByArg::UniformRetVal;
      break;
    case lltok::kw_uniqueRetVal:
      ByArg.TheKind = WholeProgramDevirtResolution::ByArg::UniqueRetVal;
      break;
    case lltok::kw_virtualConstProp:
      ByArg.TheKind = WholeProgramDevirtResolution::ByArg::VirtualConstProp;
      break;
    default:
      return error(Lex.getLoc(),
                   "unexpected WholeProgramDevirtResolution::ByArg kind");
    }
    Lex.Lex();

    // parse optional fields
    while (EatIfPresent(lltok::comma)) {
      switch (Lex.getKind()) {
      case lltok::kw_info:
        Lex.Lex();
        if (parseToken(lltok::colon, "expected ':' here") ||
            parseUInt64(ByArg.Info))
          return true;
        break;
      case lltok::kw_byte:
        Lex.Lex();
        if (parseToken(lltok::colon, "expected ':' here") ||
            parseUInt32(ByArg.Byte))
          return true;
        break;
      case lltok::kw_bit:
        Lex.Lex();
        if (parseToken(lltok::colon, "expected ':' here") ||
            parseUInt32(ByArg.Bit))
          return true;
        break;
      default:
        return error(Lex.getLoc(),
                     "expected optional whole program devirt field");
      }
    }

    if (parseToken(lltok::rparen, "expected ')' here"))
      return true;

    ResByArg[Args] = ByArg;
  } while (EatIfPresent(lltok::comma));

  if (parseToken(lltok::rparen, "expected ')' here"))
    return true;

  return false;
}

/// OptionalResByArg
///   ::= 'args' ':' '(' UInt64[, UInt64]* ')'
bool LLParser::parseArgs(std::vector<uint64_t> &Args) {
  if (parseToken(lltok::kw_args, "expected 'args' here") ||
      parseToken(lltok::colon, "expected ':' here") ||
      parseToken(lltok::lparen, "expected '(' here"))
    return true;

  do {
    uint64_t Val;
    if (parseUInt64(Val))
      return true;
    Args.push_back(Val);
  } while (EatIfPresent(lltok::comma));

  if (parseToken(lltok::rparen, "expected ')' here"))
    return true;

  return false;
}

static const auto FwdVIRef = (GlobalValueSummaryMapTy::value_type *)-8;

static void resolveFwdRef(ValueInfo *Fwd, ValueInfo &Resolved) {
  bool ReadOnly = Fwd->isReadOnly();
  bool WriteOnly = Fwd->isWriteOnly();
  assert(!(ReadOnly && WriteOnly));
  *Fwd = Resolved;
  if (ReadOnly)
    Fwd->setReadOnly();
  if (WriteOnly)
    Fwd->setWriteOnly();
}

/// Stores the given Name/GUID and associated summary into the Index.
/// Also updates any forward references to the associated entry ID.
bool LLParser::addGlobalValueToIndex(
    std::string Name, GlobalValue::GUID GUID, GlobalValue::LinkageTypes Linkage,
    unsigned ID, std::unique_ptr<GlobalValueSummary> Summary, LocTy Loc) {
  // First create the ValueInfo utilizing the Name or GUID.
  ValueInfo VI;
  if (GUID != 0) {
    assert(Name.empty());
    VI = Index->getOrInsertValueInfo(GUID);
  } else {
    assert(!Name.empty());
    if (M) {
      auto *GV = M->getNamedValue(Name);
      if (!GV)
        return error(Loc, "Reference to undefined global \"" + Name + "\"");

      VI = Index->getOrInsertValueInfo(GV);
    } else {
      assert(
          (!GlobalValue::isLocalLinkage(Linkage) || !SourceFileName.empty()) &&
          "Need a source_filename to compute GUID for local");
      GUID = GlobalValue::getGUIDAssumingExternalLinkage(
          GlobalValue::getGlobalIdentifier(Name, Linkage, SourceFileName));
      VI = Index->getOrInsertValueInfo(GUID, Index->saveString(Name));
    }
  }

  // Resolve forward references from calls/refs
  auto FwdRefVIs = ForwardRefValueInfos.find(ID);
  if (FwdRefVIs != ForwardRefValueInfos.end()) {
    for (auto VIRef : FwdRefVIs->second) {
      assert(VIRef.first->getRef() == FwdVIRef &&
             "Forward referenced ValueInfo expected to be empty");
      resolveFwdRef(VIRef.first, VI);
    }
    ForwardRefValueInfos.erase(FwdRefVIs);
  }

  // Resolve forward references from aliases
  auto FwdRefAliasees = ForwardRefAliasees.find(ID);
  if (FwdRefAliasees != ForwardRefAliasees.end()) {
    for (auto AliaseeRef : FwdRefAliasees->second) {
      assert(!AliaseeRef.first->hasAliasee() &&
             "Forward referencing alias already has aliasee");
      assert(Summary && "Aliasee must be a definition");
      AliaseeRef.first->setAliasee(VI, Summary.get());
    }
    ForwardRefAliasees.erase(FwdRefAliasees);
  }

  // Add the summary if one was provided.
  if (Summary)
    Index->addGlobalValueSummary(VI, std::move(Summary));

  // Save the associated ValueInfo for use in later references by ID.
  if (ID == NumberedValueInfos.size())
    NumberedValueInfos.push_back(VI);
  else {
    // Handle non-continuous numbers (to make test simplification easier).
    if (ID > NumberedValueInfos.size())
      NumberedValueInfos.resize(ID + 1);
    NumberedValueInfos[ID] = VI;
  }

  return false;
}

/// parseSummaryIndexFlags
///   ::= 'flags' ':' UInt64
bool LLParser::parseSummaryIndexFlags() {
  assert(Lex.getKind() == lltok::kw_flags);
  Lex.Lex();

  if (parseToken(lltok::colon, "expected ':' here"))
    return true;
  uint64_t Flags;
  if (parseUInt64(Flags))
    return true;
  if (Index)
    Index->setFlags(Flags);
  return false;
}

/// parseBlockCount
///   ::= 'blockcount' ':' UInt64
bool LLParser::parseBlockCount() {
  assert(Lex.getKind() == lltok::kw_blockcount);
  Lex.Lex();

  if (parseToken(lltok::colon, "expected ':' here"))
    return true;
  uint64_t BlockCount;
  if (parseUInt64(BlockCount))
    return true;
  if (Index)
    Index->setBlockCount(BlockCount);
  return false;
}

/// parseGVEntry
///   ::= 'gv' ':' '(' ('name' ':' STRINGCONSTANT | 'guid' ':' UInt64)
///         [',' 'summaries' ':' Summary[',' Summary]* ]? ')'
/// Summary ::= '(' (FunctionSummary | VariableSummary | AliasSummary) ')'
bool LLParser::parseGVEntry(unsigned ID) {
  assert(Lex.getKind() == lltok::kw_gv);
  Lex.Lex();

  if (parseToken(lltok::colon, "expected ':' here") ||
      parseToken(lltok::lparen, "expected '(' here"))
    return true;

  LocTy Loc = Lex.getLoc();
  std::string Name;
  GlobalValue::GUID GUID = 0;
  switch (Lex.getKind()) {
  case lltok::kw_name:
    Lex.Lex();
    if (parseToken(lltok::colon, "expected ':' here") ||
        parseStringConstant(Name))
      return true;
    // Can't create GUID/ValueInfo until we have the linkage.
    break;
  case lltok::kw_guid:
    Lex.Lex();
    if (parseToken(lltok::colon, "expected ':' here") || parseUInt64(GUID))
      return true;
    break;
  default:
    return error(Lex.getLoc(), "expected name or guid tag");
  }

  if (!EatIfPresent(lltok::comma)) {
    // No summaries. Wrap up.
    if (parseToken(lltok::rparen, "expected ')' here"))
      return true;
    // This was created for a call to an external or indirect target.
    // A GUID with no summary came from a VALUE_GUID record, dummy GUID
    // created for indirect calls with VP. A Name with no GUID came from
    // an external definition. We pass ExternalLinkage since that is only
    // used when the GUID must be computed from Name, and in that case
    // the symbol must have external linkage.
    return addGlobalValueToIndex(Name, GUID, GlobalValue::ExternalLinkage, ID,
                                 nullptr, Loc);
  }

  // Have a list of summaries
  if (parseToken(lltok::kw_summaries, "expected 'summaries' here") ||
      parseToken(lltok::colon, "expected ':' here") ||
      parseToken(lltok::lparen, "expected '(' here"))
    return true;
  do {
    switch (Lex.getKind()) {
    case lltok::kw_function:
      if (parseFunctionSummary(Name, GUID, ID))
        return true;
      break;
    case lltok::kw_variable:
      if (parseVariableSummary(Name, GUID, ID))
        return true;
      break;
    case lltok::kw_alias:
      if (parseAliasSummary(Name, GUID, ID))
        return true;
      break;
    default:
      return error(Lex.getLoc(), "expected summary type");
    }
  } while (EatIfPresent(lltok::comma));

  if (parseToken(lltok::rparen, "expected ')' here") ||
      parseToken(lltok::rparen, "expected ')' here"))
    return true;

  return false;
}

/// FunctionSummary
///   ::= 'function' ':' '(' 'module' ':' ModuleReference ',' GVFlags
///         ',' 'insts' ':' UInt32 [',' OptionalFFlags]? [',' OptionalCalls]?
///         [',' OptionalTypeIdInfo]? [',' OptionalParamAccesses]?
///         [',' OptionalRefs]? ')'
bool LLParser::parseFunctionSummary(std::string Name, GlobalValue::GUID GUID,
                                    unsigned ID) {
  LocTy Loc = Lex.getLoc();
  assert(Lex.getKind() == lltok::kw_function);
  Lex.Lex();

  StringRef ModulePath;
  GlobalValueSummary::GVFlags GVFlags = GlobalValueSummary::GVFlags(
      GlobalValue::ExternalLinkage, GlobalValue::DefaultVisibility,
      /*NotEligibleToImport=*/false,
      /*Live=*/false, /*IsLocal=*/false, /*CanAutoHide=*/false,
      GlobalValueSummary::Definition);
  unsigned InstCount;
  SmallVector<FunctionSummary::EdgeTy, 0> Calls;
  FunctionSummary::TypeIdInfo TypeIdInfo;
  std::vector<FunctionSummary::ParamAccess> ParamAccesses;
  SmallVector<ValueInfo, 0> Refs;
  std::vector<CallsiteInfo> Callsites;
  std::vector<AllocInfo> Allocs;
  // Default is all-zeros (conservative values).
  FunctionSummary::FFlags FFlags = {};
  if (parseToken(lltok::colon, "expected ':' here") ||
      parseToken(lltok::lparen, "expected '(' here") ||
      parseModuleReference(ModulePath) ||
      parseToken(lltok::comma, "expected ',' here") || parseGVFlags(GVFlags) ||
      parseToken(lltok::comma, "expected ',' here") ||
      parseToken(lltok::kw_insts, "expected 'insts' here") ||
      parseToken(lltok::colon, "expected ':' here") || parseUInt32(InstCount))
    return true;

  // parse optional fields
  while (EatIfPresent(lltok::comma)) {
    switch (Lex.getKind()) {
    case lltok::kw_funcFlags:
      if (parseOptionalFFlags(FFlags))
        return true;
      break;
    case lltok::kw_calls:
      if (parseOptionalCalls(Calls))
        return true;
      break;
    case lltok::kw_typeIdInfo:
      if (parseOptionalTypeIdInfo(TypeIdInfo))
        return true;
      break;
    case lltok::kw_refs:
      if (parseOptionalRefs(Refs))
        return true;
      break;
    case lltok::kw_params:
      if (parseOptionalParamAccesses(ParamAccesses))
        return true;
      break;
    case lltok::kw_allocs:
      if (parseOptionalAllocs(Allocs))
        return true;
      break;
    case lltok::kw_callsites:
      if (parseOptionalCallsites(Callsites))
        return true;
      break;
    default:
      return error(Lex.getLoc(), "expected optional function summary field");
    }
  }

  if (parseToken(lltok::rparen, "expected ')' here"))
    return true;

  auto FS = std::make_unique<FunctionSummary>(
      GVFlags, InstCount, FFlags, std::move(Refs), std::move(Calls),
      std::move(TypeIdInfo.TypeTests),
      std::move(TypeIdInfo.TypeTestAssumeVCalls),
      std::move(TypeIdInfo.TypeCheckedLoadVCalls),
      std::move(TypeIdInfo.TypeTestAssumeConstVCalls),
      std::move(TypeIdInfo.TypeCheckedLoadConstVCalls),
      std::move(ParamAccesses), std::move(Callsites), std::move(Allocs));

  FS->setModulePath(ModulePath);

  return addGlobalValueToIndex(Name, GUID,
                               (GlobalValue::LinkageTypes)GVFlags.Linkage, ID,
                               std::move(FS), Loc);
}

/// VariableSummary
///   ::= 'variable' ':' '(' 'module' ':' ModuleReference ',' GVFlags
///         [',' OptionalRefs]? ')'
bool LLParser::parseVariableSummary(std::string Name, GlobalValue::GUID GUID,
                                    unsigned ID) {
  LocTy Loc = Lex.getLoc();
  assert(Lex.getKind() == lltok::kw_variable);
  Lex.Lex();

  StringRef ModulePath;
  GlobalValueSummary::GVFlags GVFlags = GlobalValueSummary::GVFlags(
      GlobalValue::ExternalLinkage, GlobalValue::DefaultVisibility,
      /*NotEligibleToImport=*/false,
      /*Live=*/false, /*IsLocal=*/false, /*CanAutoHide=*/false,
      GlobalValueSummary::Definition);
  GlobalVarSummary::GVarFlags GVarFlags(/*ReadOnly*/ false,
                                        /* WriteOnly */ false,
                                        /* Constant */ false,
                                        GlobalObject::VCallVisibilityPublic);
  SmallVector<ValueInfo, 0> Refs;
  VTableFuncList VTableFuncs;
  if (parseToken(lltok::colon, "expected ':' here") ||
      parseToken(lltok::lparen, "expected '(' here") ||
      parseModuleReference(ModulePath) ||
      parseToken(lltok::comma, "expected ',' here") || parseGVFlags(GVFlags) ||
      parseToken(lltok::comma, "expected ',' here") ||
      parseGVarFlags(GVarFlags))
    return true;

  // parse optional fields
  while (EatIfPresent(lltok::comma)) {
    switch (Lex.getKind()) {
    case lltok::kw_vTableFuncs:
      if (parseOptionalVTableFuncs(VTableFuncs))
        return true;
      break;
    case lltok::kw_refs:
      if (parseOptionalRefs(Refs))
        return true;
      break;
    default:
      return error(Lex.getLoc(), "expected optional variable summary field");
    }
  }

  if (parseToken(lltok::rparen, "expected ')' here"))
    return true;

  auto GS =
      std::make_unique<GlobalVarSummary>(GVFlags, GVarFlags, std::move(Refs));

  GS->setModulePath(ModulePath);
  GS->setVTableFuncs(std::move(VTableFuncs));

  return addGlobalValueToIndex(Name, GUID,
                               (GlobalValue::LinkageTypes)GVFlags.Linkage, ID,
                               std::move(GS), Loc);
}

/// AliasSummary
///   ::= 'alias' ':' '(' 'module' ':' ModuleReference ',' GVFlags ','
///         'aliasee' ':' GVReference ')'
bool LLParser::parseAliasSummary(std::string Name, GlobalValue::GUID GUID,
                                 unsigned ID) {
  assert(Lex.getKind() == lltok::kw_alias);
  LocTy Loc = Lex.getLoc();
  Lex.Lex();

  StringRef ModulePath;
  GlobalValueSummary::GVFlags GVFlags = GlobalValueSummary::GVFlags(
      GlobalValue::ExternalLinkage, GlobalValue::DefaultVisibility,
      /*NotEligibleToImport=*/false,
      /*Live=*/false, /*IsLocal=*/false, /*CanAutoHide=*/false,
      GlobalValueSummary::Definition);
  if (parseToken(lltok::colon, "expected ':' here") ||
      parseToken(lltok::lparen, "expected '(' here") ||
      parseModuleReference(ModulePath) ||
      parseToken(lltok::comma, "expected ',' here") || parseGVFlags(GVFlags) ||
      parseToken(lltok::comma, "expected ',' here") ||
      parseToken(lltok::kw_aliasee, "expected 'aliasee' here") ||
      parseToken(lltok::colon, "expected ':' here"))
    return true;

  ValueInfo AliaseeVI;
  unsigned GVId;
  if (parseGVReference(AliaseeVI, GVId))
    return true;

  if (parseToken(lltok::rparen, "expected ')' here"))
    return true;

  auto AS = std::make_unique<AliasSummary>(GVFlags);

  AS->setModulePath(ModulePath);

  // Record forward reference if the aliasee is not parsed yet.
  if (AliaseeVI.getRef() == FwdVIRef) {
    ForwardRefAliasees[GVId].emplace_back(AS.get(), Loc);
  } else {
    auto Summary = Index->findSummaryInModule(AliaseeVI, ModulePath);
    assert(Summary && "Aliasee must be a definition");
    AS->setAliasee(AliaseeVI, Summary);
  }

  return addGlobalValueToIndex(Name, GUID,
                               (GlobalValue::LinkageTypes)GVFlags.Linkage, ID,
                               std::move(AS), Loc);
}

/// Flag
///   ::= [0|1]
bool LLParser::parseFlag(unsigned &Val) {
  if (Lex.getKind() != lltok::APSInt || Lex.getAPSIntVal().isSigned())
    return tokError("expected integer");
  Val = (unsigned)Lex.getAPSIntVal().getBoolValue();
  Lex.Lex();
  return false;
}

/// OptionalFFlags
///   := 'funcFlags' ':' '(' ['readNone' ':' Flag]?
///        [',' 'readOnly' ':' Flag]? [',' 'noRecurse' ':' Flag]?
///        [',' 'returnDoesNotAlias' ':' Flag]? ')'
///        [',' 'noInline' ':' Flag]? ')'
///        [',' 'alwaysInline' ':' Flag]? ')'
///        [',' 'noUnwind' ':' Flag]? ')'
///        [',' 'mayThrow' ':' Flag]? ')'
///        [',' 'hasUnknownCall' ':' Flag]? ')'
///        [',' 'mustBeUnreachable' ':' Flag]? ')'

bool LLParser::parseOptionalFFlags(FunctionSummary::FFlags &FFlags) {
  assert(Lex.getKind() == lltok::kw_funcFlags);
  Lex.Lex();

  if (parseToken(lltok::colon, "expected ':' in funcFlags") ||
      parseToken(lltok::lparen, "expected '(' in funcFlags"))
    return true;

  do {
    unsigned Val = 0;
    switch (Lex.getKind()) {
    case lltok::kw_readNone:
      Lex.Lex();
      if (parseToken(lltok::colon, "expected ':'") || parseFlag(Val))
        return true;
      FFlags.ReadNone = Val;
      break;
    case lltok::kw_readOnly:
      Lex.Lex();
      if (parseToken(lltok::colon, "expected ':'") || parseFlag(Val))
        return true;
      FFlags.ReadOnly = Val;
      break;
    case lltok::kw_noRecurse:
      Lex.Lex();
      if (parseToken(lltok::colon, "expected ':'") || parseFlag(Val))
        return true;
      FFlags.NoRecurse = Val;
      break;
    case lltok::kw_returnDoesNotAlias:
      Lex.Lex();
      if (parseToken(lltok::colon, "expected ':'") || parseFlag(Val))
        return true;
      FFlags.ReturnDoesNotAlias = Val;
      break;
    case lltok::kw_noInline:
      Lex.Lex();
      if (parseToken(lltok::colon, "expected ':'") || parseFlag(Val))
        return true;
      FFlags.NoInline = Val;
      break;
    case lltok::kw_alwaysInline:
      Lex.Lex();
      if (parseToken(lltok::colon, "expected ':'") || parseFlag(Val))
        return true;
      FFlags.AlwaysInline = Val;
      break;
    case lltok::kw_noUnwind:
      Lex.Lex();
      if (parseToken(lltok::colon, "expected ':'") || parseFlag(Val))
        return true;
      FFlags.NoUnwind = Val;
      break;
    case lltok::kw_mayThrow:
      Lex.Lex();
      if (parseToken(lltok::colon, "expected ':'") || parseFlag(Val))
        return true;
      FFlags.MayThrow = Val;
      break;
    case lltok::kw_hasUnknownCall:
      Lex.Lex();
      if (parseToken(lltok::colon, "expected ':'") || parseFlag(Val))
        return true;
      FFlags.HasUnknownCall = Val;
      break;
    case lltok::kw_mustBeUnreachable:
      Lex.Lex();
      if (parseToken(lltok::colon, "expected ':'") || parseFlag(Val))
        return true;
      FFlags.MustBeUnreachable = Val;
      break;
    default:
      return error(Lex.getLoc(), "expected function flag type");
    }
  } while (EatIfPresent(lltok::comma));

  if (parseToken(lltok::rparen, "expected ')' in funcFlags"))
    return true;

  return false;
}

/// OptionalCalls
///   := 'calls' ':' '(' Call [',' Call]* ')'
/// Call ::= '(' 'callee' ':' GVReference
///            [( ',' 'hotness' ':' Hotness | ',' 'relbf' ':' UInt32 )]?
///            [ ',' 'tail' ]? ')'
bool LLParser::parseOptionalCalls(
    SmallVectorImpl<FunctionSummary::EdgeTy> &Calls) {
  assert(Lex.getKind() == lltok::kw_calls);
  Lex.Lex();

  if (parseToken(lltok::colon, "expected ':' in calls") ||
      parseToken(lltok::lparen, "expected '(' in calls"))
    return true;

  IdToIndexMapType IdToIndexMap;
  // parse each call edge
  do {
    ValueInfo VI;
    if (parseToken(lltok::lparen, "expected '(' in call") ||
        parseToken(lltok::kw_callee, "expected 'callee' in call") ||
        parseToken(lltok::colon, "expected ':'"))
      return true;

    LocTy Loc = Lex.getLoc();
    unsigned GVId;
    if (parseGVReference(VI, GVId))
      return true;

    CalleeInfo::HotnessType Hotness = CalleeInfo::HotnessType::Unknown;
    unsigned RelBF = 0;
    unsigned HasTailCall = false;

    // parse optional fields
    while (EatIfPresent(lltok::comma)) {
      switch (Lex.getKind()) {
      case lltok::kw_hotness:
        Lex.Lex();
        if (parseToken(lltok::colon, "expected ':'") || parseHotness(Hotness))
          return true;
        break;
      case lltok::kw_relbf:
        Lex.Lex();
        if (parseToken(lltok::colon, "expected ':'") || parseUInt32(RelBF))
          return true;
        break;
      case lltok::kw_tail:
        Lex.Lex();
        if (parseToken(lltok::colon, "expected ':'") || parseFlag(HasTailCall))
          return true;
        break;
      default:
        return error(Lex.getLoc(), "expected hotness, relbf, or tail");
      }
    }
    if (Hotness != CalleeInfo::HotnessType::Unknown && RelBF > 0)
      return tokError("Expected only one of hotness or relbf");
    // Keep track of the Call array index needing a forward reference.
    // We will save the location of the ValueInfo needing an update, but
    // can only do so once the std::vector is finalized.
    if (VI.getRef() == FwdVIRef)
      IdToIndexMap[GVId].push_back(std::make_pair(Calls.size(), Loc));
    Calls.push_back(
        FunctionSummary::EdgeTy{VI, CalleeInfo(Hotness, HasTailCall, RelBF)});

    if (parseToken(lltok::rparen, "expected ')' in call"))
      return true;
  } while (EatIfPresent(lltok::comma));

  // Now that the Calls vector is finalized, it is safe to save the locations
  // of any forward GV references that need updating later.
  for (auto I : IdToIndexMap) {
    auto &Infos = ForwardRefValueInfos[I.first];
    for (auto P : I.second) {
      assert(Calls[P.first].first.getRef() == FwdVIRef &&
             "Forward referenced ValueInfo expected to be empty");
      Infos.emplace_back(&Calls[P.first].first, P.second);
    }
  }

  if (parseToken(lltok::rparen, "expected ')' in calls"))
    return true;

  return false;
}

/// Hotness
///   := ('unknown'|'cold'|'none'|'hot'|'critical')
bool LLParser::parseHotness(CalleeInfo::HotnessType &Hotness) {
  switch (Lex.getKind()) {
  case lltok::kw_unknown:
    Hotness = CalleeInfo::HotnessType::Unknown;
    break;
  case lltok::kw_cold:
    Hotness = CalleeInfo::HotnessType::Cold;
    break;
  case lltok::kw_none:
    Hotness = CalleeInfo::HotnessType::None;
    break;
  case lltok::kw_hot:
    Hotness = CalleeInfo::HotnessType::Hot;
    break;
  case lltok::kw_critical:
    Hotness = CalleeInfo::HotnessType::Critical;
    break;
  default:
    return error(Lex.getLoc(), "invalid call edge hotness");
  }
  Lex.Lex();
  return false;
}

/// OptionalVTableFuncs
///   := 'vTableFuncs' ':' '(' VTableFunc [',' VTableFunc]* ')'
/// VTableFunc ::= '(' 'virtFunc' ':' GVReference ',' 'offset' ':' UInt64 ')'
bool LLParser::parseOptionalVTableFuncs(VTableFuncList &VTableFuncs) {
  assert(Lex.getKind() == lltok::kw_vTableFuncs);
  Lex.Lex();

  if (parseToken(lltok::colon, "expected ':' in vTableFuncs") ||
      parseToken(lltok::lparen, "expected '(' in vTableFuncs"))
    return true;

  IdToIndexMapType IdToIndexMap;
  // parse each virtual function pair
  do {
    ValueInfo VI;
    if (parseToken(lltok::lparen, "expected '(' in vTableFunc") ||
        parseToken(lltok::kw_virtFunc, "expected 'callee' in vTableFunc") ||
        parseToken(lltok::colon, "expected ':'"))
      return true;

    LocTy Loc = Lex.getLoc();
    unsigned GVId;
    if (parseGVReference(VI, GVId))
      return true;

    uint64_t Offset;
    if (parseToken(lltok::comma, "expected comma") ||
        parseToken(lltok::kw_offset, "expected offset") ||
        parseToken(lltok::colon, "expected ':'") || parseUInt64(Offset))
      return true;

    // Keep track of the VTableFuncs array index needing a forward reference.
    // We will save the location of the ValueInfo needing an update, but
    // can only do so once the std::vector is finalized.
    if (VI == EmptyVI)
      IdToIndexMap[GVId].push_back(std::make_pair(VTableFuncs.size(), Loc));
    VTableFuncs.push_back({VI, Offset});

    if (parseToken(lltok::rparen, "expected ')' in vTableFunc"))
      return true;
  } while (EatIfPresent(lltok::comma));

  // Now that the VTableFuncs vector is finalized, it is safe to save the
  // locations of any forward GV references that need updating later.
  for (auto I : IdToIndexMap) {
    auto &Infos = ForwardRefValueInfos[I.first];
    for (auto P : I.second) {
      assert(VTableFuncs[P.first].FuncVI == EmptyVI &&
             "Forward referenced ValueInfo expected to be empty");
      Infos.emplace_back(&VTableFuncs[P.first].FuncVI, P.second);
    }
  }

  if (parseToken(lltok::rparen, "expected ')' in vTableFuncs"))
    return true;

  return false;
}

/// ParamNo := 'param' ':' UInt64
bool LLParser::parseParamNo(uint64_t &ParamNo) {
  if (parseToken(lltok::kw_param, "expected 'param' here") ||
      parseToken(lltok::colon, "expected ':' here") || parseUInt64(ParamNo))
    return true;
  return false;
}

/// ParamAccessOffset := 'offset' ':' '[' APSINTVAL ',' APSINTVAL ']'
bool LLParser::parseParamAccessOffset(ConstantRange &Range) {
  APSInt Lower;
  APSInt Upper;
  auto ParseAPSInt = [&](APSInt &Val) {
    if (Lex.getKind() != lltok::APSInt)
      return tokError("expected integer");
    Val = Lex.getAPSIntVal();
    Val = Val.extOrTrunc(FunctionSummary::ParamAccess::RangeWidth);
    Val.setIsSigned(true);
    Lex.Lex();
    return false;
  };
  if (parseToken(lltok::kw_offset, "expected 'offset' here") ||
      parseToken(lltok::colon, "expected ':' here") ||
      parseToken(lltok::lsquare, "expected '[' here") || ParseAPSInt(Lower) ||
      parseToken(lltok::comma, "expected ',' here") || ParseAPSInt(Upper) ||
      parseToken(lltok::rsquare, "expected ']' here"))
    return true;

  ++Upper;
  Range =
      (Lower == Upper && !Lower.isMaxValue())
          ? ConstantRange::getEmpty(FunctionSummary::ParamAccess::RangeWidth)
          : ConstantRange(Lower, Upper);

  return false;
}

/// ParamAccessCall
///   := '(' 'callee' ':' GVReference ',' ParamNo ',' ParamAccessOffset ')'
bool LLParser::parseParamAccessCall(FunctionSummary::ParamAccess::Call &Call,
                                    IdLocListType &IdLocList) {
  if (parseToken(lltok::lparen, "expected '(' here") ||
      parseToken(lltok::kw_callee, "expected 'callee' here") ||
      parseToken(lltok::colon, "expected ':' here"))
    return true;

  unsigned GVId;
  ValueInfo VI;
  LocTy Loc = Lex.getLoc();
  if (parseGVReference(VI, GVId))
    return true;

  Call.Callee = VI;
  IdLocList.emplace_back(GVId, Loc);

  if (parseToken(lltok::comma, "expected ',' here") ||
      parseParamNo(Call.ParamNo) ||
      parseToken(lltok::comma, "expected ',' here") ||
      parseParamAccessOffset(Call.Offsets))
    return true;

  if (parseToken(lltok::rparen, "expected ')' here"))
    return true;

  return false;
}

/// ParamAccess
///   := '(' ParamNo ',' ParamAccessOffset [',' OptionalParamAccessCalls]? ')'
/// OptionalParamAccessCalls := '(' Call [',' Call]* ')'
bool LLParser::parseParamAccess(FunctionSummary::ParamAccess &Param,
                                IdLocListType &IdLocList) {
  if (parseToken(lltok::lparen, "expected '(' here") ||
      parseParamNo(Param.ParamNo) ||
      parseToken(lltok::comma, "expected ',' here") ||
      parseParamAccessOffset(Param.Use))
    return true;

  if (EatIfPresent(lltok::comma)) {
    if (parseToken(lltok::kw_calls, "expected 'calls' here") ||
        parseToken(lltok::colon, "expected ':' here") ||
        parseToken(lltok::lparen, "expected '(' here"))
      return true;
    do {
      FunctionSummary::ParamAccess::Call Call;
      if (parseParamAccessCall(Call, IdLocList))
        return true;
      Param.Calls.push_back(Call);
    } while (EatIfPresent(lltok::comma));

    if (parseToken(lltok::rparen, "expected ')' here"))
      return true;
  }

  if (parseToken(lltok::rparen, "expected ')' here"))
    return true;

  return false;
}

/// OptionalParamAccesses
///   := 'params' ':' '(' ParamAccess [',' ParamAccess]* ')'
bool LLParser::parseOptionalParamAccesses(
    std::vector<FunctionSummary::ParamAccess> &Params) {
  assert(Lex.getKind() == lltok::kw_params);
  Lex.Lex();

  if (parseToken(lltok::colon, "expected ':' here") ||
      parseToken(lltok::lparen, "expected '(' here"))
    return true;

  IdLocListType VContexts;
  size_t CallsNum = 0;
  do {
    FunctionSummary::ParamAccess ParamAccess;
    if (parseParamAccess(ParamAccess, VContexts))
      return true;
    CallsNum += ParamAccess.Calls.size();
    assert(VContexts.size() == CallsNum);
    (void)CallsNum;
    Params.emplace_back(std::move(ParamAccess));
  } while (EatIfPresent(lltok::comma));

  if (parseToken(lltok::rparen, "expected ')' here"))
    return true;

  // Now that the Params is finalized, it is safe to save the locations
  // of any forward GV references that need updating later.
  IdLocListType::const_iterator ItContext = VContexts.begin();
  for (auto &PA : Params) {
    for (auto &C : PA.Calls) {
      if (C.Callee.getRef() == FwdVIRef)
        ForwardRefValueInfos[ItContext->first].emplace_back(&C.Callee,
                                                            ItContext->second);
      ++ItContext;
    }
  }
  assert(ItContext == VContexts.end());

  return false;
}

/// OptionalRefs
///   := 'refs' ':' '(' GVReference [',' GVReference]* ')'
bool LLParser::parseOptionalRefs(SmallVectorImpl<ValueInfo> &Refs) {
  assert(Lex.getKind() == lltok::kw_refs);
  Lex.Lex();

  if (parseToken(lltok::colon, "expected ':' in refs") ||
      parseToken(lltok::lparen, "expected '(' in refs"))
    return true;

  struct ValueContext {
    ValueInfo VI;
    unsigned GVId;
    LocTy Loc;
  };
  std::vector<ValueContext> VContexts;
  // parse each ref edge
  do {
    ValueContext VC;
    VC.Loc = Lex.getLoc();
    if (parseGVReference(VC.VI, VC.GVId))
      return true;
    VContexts.push_back(VC);
  } while (EatIfPresent(lltok::comma));

  // Sort value contexts so that ones with writeonly
  // and readonly ValueInfo  are at the end of VContexts vector.
  // See FunctionSummary::specialRefCounts()
  llvm::sort(VContexts, [](const ValueContext &VC1, const ValueContext &VC2) {
    return VC1.VI.getAccessSpecifier() < VC2.VI.getAccessSpecifier();
  });

  IdToIndexMapType IdToIndexMap;
  for (auto &VC : VContexts) {
    // Keep track of the Refs array index needing a forward reference.
    // We will save the location of the ValueInfo needing an update, but
    // can only do so once the std::vector is finalized.
    if (VC.VI.getRef() == FwdVIRef)
      IdToIndexMap[VC.GVId].push_back(std::make_pair(Refs.size(), VC.Loc));
    Refs.push_back(VC.VI);
  }

  // Now that the Refs vector is finalized, it is safe to save the locations
  // of any forward GV references that need updating later.
  for (auto I : IdToIndexMap) {
    auto &Infos = ForwardRefValueInfos[I.first];
    for (auto P : I.second) {
      assert(Refs[P.first].getRef() == FwdVIRef &&
             "Forward referenced ValueInfo expected to be empty");
      Infos.emplace_back(&Refs[P.first], P.second);
    }
  }

  if (parseToken(lltok::rparen, "expected ')' in refs"))
    return true;

  return false;
}

/// OptionalTypeIdInfo
///   := 'typeidinfo' ':' '(' [',' TypeTests]? [',' TypeTestAssumeVCalls]?
///         [',' TypeCheckedLoadVCalls]?  [',' TypeTestAssumeConstVCalls]?
///         [',' TypeCheckedLoadConstVCalls]? ')'
bool LLParser::parseOptionalTypeIdInfo(
    FunctionSummary::TypeIdInfo &TypeIdInfo) {
  assert(Lex.getKind() == lltok::kw_typeIdInfo);
  Lex.Lex();

  if (parseToken(lltok::colon, "expected ':' here") ||
      parseToken(lltok::lparen, "expected '(' in typeIdInfo"))
    return true;

  do {
    switch (Lex.getKind()) {
    case lltok::kw_typeTests:
      if (parseTypeTests(TypeIdInfo.TypeTests))
        return true;
      break;
    case lltok::kw_typeTestAssumeVCalls:
      if (parseVFuncIdList(lltok::kw_typeTestAssumeVCalls,
                           TypeIdInfo.TypeTestAssumeVCalls))
        return true;
      break;
    case lltok::kw_typeCheckedLoadVCalls:
      if (parseVFuncIdList(lltok::kw_typeCheckedLoadVCalls,
                           TypeIdInfo.TypeCheckedLoadVCalls))
        return true;
      break;
    case lltok::kw_typeTestAssumeConstVCalls:
      if (parseConstVCallList(lltok::kw_typeTestAssumeConstVCalls,
                              TypeIdInfo.TypeTestAssumeConstVCalls))
        return true;
      break;
    case lltok::kw_typeCheckedLoadConstVCalls:
      if (parseConstVCallList(lltok::kw_typeCheckedLoadConstVCalls,
                              TypeIdInfo.TypeCheckedLoadConstVCalls))
        return true;
      break;
    default:
      return error(Lex.getLoc(), "invalid typeIdInfo list type");
    }
  } while (EatIfPresent(lltok::comma));

  if (parseToken(lltok::rparen, "expected ')' in typeIdInfo"))
    return true;

  return false;
}

/// TypeTests
///   ::= 'typeTests' ':' '(' (SummaryID | UInt64)
///         [',' (SummaryID | UInt64)]* ')'
bool LLParser::parseTypeTests(std::vector<GlobalValue::GUID> &TypeTests) {
  assert(Lex.getKind() == lltok::kw_typeTests);
  Lex.Lex();

  if (parseToken(lltok::colon, "expected ':' here") ||
      parseToken(lltok::lparen, "expected '(' in typeIdInfo"))
    return true;

  IdToIndexMapType IdToIndexMap;
  do {
    GlobalValue::GUID GUID = 0;
    if (Lex.getKind() == lltok::SummaryID) {
      unsigned ID = Lex.getUIntVal();
      LocTy Loc = Lex.getLoc();
      // Keep track of the TypeTests array index needing a forward reference.
      // We will save the location of the GUID needing an update, but
      // can only do so once the std::vector is finalized.
      IdToIndexMap[ID].push_back(std::make_pair(TypeTests.size(), Loc));
      Lex.Lex();
    } else if (parseUInt64(GUID))
      return true;
    TypeTests.push_back(GUID);
  } while (EatIfPresent(lltok::comma));

  // Now that the TypeTests vector is finalized, it is safe to save the
  // locations of any forward GV references that need updating later.
  for (auto I : IdToIndexMap) {
    auto &Ids = ForwardRefTypeIds[I.first];
    for (auto P : I.second) {
      assert(TypeTests[P.first] == 0 &&
             "Forward referenced type id GUID expected to be 0");
      Ids.emplace_back(&TypeTests[P.first], P.second);
    }
  }

  if (parseToken(lltok::rparen, "expected ')' in typeIdInfo"))
    return true;

  return false;
}

/// VFuncIdList
///   ::= Kind ':' '(' VFuncId [',' VFuncId]* ')'
bool LLParser::parseVFuncIdList(
    lltok::Kind Kind, std::vector<FunctionSummary::VFuncId> &VFuncIdList) {
  assert(Lex.getKind() == Kind);
  Lex.Lex();

  if (parseToken(lltok::colon, "expected ':' here") ||
      parseToken(lltok::lparen, "expected '(' here"))
    return true;

  IdToIndexMapType IdToIndexMap;
  do {
    FunctionSummary::VFuncId VFuncId;
    if (parseVFuncId(VFuncId, IdToIndexMap, VFuncIdList.size()))
      return true;
    VFuncIdList.push_back(VFuncId);
  } while (EatIfPresent(lltok::comma));

  if (parseToken(lltok::rparen, "expected ')' here"))
    return true;

  // Now that the VFuncIdList vector is finalized, it is safe to save the
  // locations of any forward GV references that need updating later.
  for (auto I : IdToIndexMap) {
    auto &Ids = ForwardRefTypeIds[I.first];
    for (auto P : I.second) {
      assert(VFuncIdList[P.first].GUID == 0 &&
             "Forward referenced type id GUID expected to be 0");
      Ids.emplace_back(&VFuncIdList[P.first].GUID, P.second);
    }
  }

  return false;
}

/// ConstVCallList
///   ::= Kind ':' '(' ConstVCall [',' ConstVCall]* ')'
bool LLParser::parseConstVCallList(
    lltok::Kind Kind,
    std::vector<FunctionSummary::ConstVCall> &ConstVCallList) {
  assert(Lex.getKind() == Kind);
  Lex.Lex();

  if (parseToken(lltok::colon, "expected ':' here") ||
      parseToken(lltok::lparen, "expected '(' here"))
    return true;

  IdToIndexMapType IdToIndexMap;
  do {
    FunctionSummary::ConstVCall ConstVCall;
    if (parseConstVCall(ConstVCall, IdToIndexMap, ConstVCallList.size()))
      return true;
    ConstVCallList.push_back(ConstVCall);
  } while (EatIfPresent(lltok::comma));

  if (parseToken(lltok::rparen, "expected ')' here"))
    return true;

  // Now that the ConstVCallList vector is finalized, it is safe to save the
  // locations of any forward GV references that need updating later.
  for (auto I : IdToIndexMap) {
    auto &Ids = ForwardRefTypeIds[I.first];
    for (auto P : I.second) {
      assert(ConstVCallList[P.first].VFunc.GUID == 0 &&
             "Forward referenced type id GUID expected to be 0");
      Ids.emplace_back(&ConstVCallList[P.first].VFunc.GUID, P.second);
    }
  }

  return false;
}

/// ConstVCall
///   ::= '(' VFuncId ',' Args ')'
bool LLParser::parseConstVCall(FunctionSummary::ConstVCall &ConstVCall,
                               IdToIndexMapType &IdToIndexMap, unsigned Index) {
  if (parseToken(lltok::lparen, "expected '(' here") ||
      parseVFuncId(ConstVCall.VFunc, IdToIndexMap, Index))
    return true;

  if (EatIfPresent(lltok::comma))
    if (parseArgs(ConstVCall.Args))
      return true;

  if (parseToken(lltok::rparen, "expected ')' here"))
    return true;

  return false;
}

/// VFuncId
///   ::= 'vFuncId' ':' '(' (SummaryID | 'guid' ':' UInt64) ','
///         'offset' ':' UInt64 ')'
bool LLParser::parseVFuncId(FunctionSummary::VFuncId &VFuncId,
                            IdToIndexMapType &IdToIndexMap, unsigned Index) {
  assert(Lex.getKind() == lltok::kw_vFuncId);
  Lex.Lex();

  if (parseToken(lltok::colon, "expected ':' here") ||
      parseToken(lltok::lparen, "expected '(' here"))
    return true;

  if (Lex.getKind() == lltok::SummaryID) {
    VFuncId.GUID = 0;
    unsigned ID = Lex.getUIntVal();
    LocTy Loc = Lex.getLoc();
    // Keep track of the array index needing a forward reference.
    // We will save the location of the GUID needing an update, but
    // can only do so once the caller's std::vector is finalized.
    IdToIndexMap[ID].push_back(std::make_pair(Index, Loc));
    Lex.Lex();
  } else if (parseToken(lltok::kw_guid, "expected 'guid' here") ||
             parseToken(lltok::colon, "expected ':' here") ||
             parseUInt64(VFuncId.GUID))
    return true;

  if (parseToken(lltok::comma, "expected ',' here") ||
      parseToken(lltok::kw_offset, "expected 'offset' here") ||
      parseToken(lltok::colon, "expected ':' here") ||
      parseUInt64(VFuncId.Offset) ||
      parseToken(lltok::rparen, "expected ')' here"))
    return true;

  return false;
}

/// GVFlags
///   ::= 'flags' ':' '(' 'linkage' ':' OptionalLinkageAux ','
///         'visibility' ':' Flag 'notEligibleToImport' ':' Flag ','
///         'live' ':' Flag ',' 'dsoLocal' ':' Flag ','
///         'canAutoHide' ':' Flag ',' ')'
bool LLParser::parseGVFlags(GlobalValueSummary::GVFlags &GVFlags) {
  assert(Lex.getKind() == lltok::kw_flags);
  Lex.Lex();

  if (parseToken(lltok::colon, "expected ':' here") ||
      parseToken(lltok::lparen, "expected '(' here"))
    return true;

  do {
    unsigned Flag = 0;
    switch (Lex.getKind()) {
    case lltok::kw_linkage:
      Lex.Lex();
      if (parseToken(lltok::colon, "expected ':'"))
        return true;
      bool HasLinkage;
      GVFlags.Linkage = parseOptionalLinkageAux(Lex.getKind(), HasLinkage);
      assert(HasLinkage && "Linkage not optional in summary entry");
      Lex.Lex();
      break;
    case lltok::kw_visibility:
      Lex.Lex();
      if (parseToken(lltok::colon, "expected ':'"))
        return true;
      parseOptionalVisibility(Flag);
      GVFlags.Visibility = Flag;
      break;
    case lltok::kw_notEligibleToImport:
      Lex.Lex();
      if (parseToken(lltok::colon, "expected ':'") || parseFlag(Flag))
        return true;
      GVFlags.NotEligibleToImport = Flag;
      break;
    case lltok::kw_live:
      Lex.Lex();
      if (parseToken(lltok::colon, "expected ':'") || parseFlag(Flag))
        return true;
      GVFlags.Live = Flag;
      break;
    case lltok::kw_dsoLocal:
      Lex.Lex();
      if (parseToken(lltok::colon, "expected ':'") || parseFlag(Flag))
        return true;
      GVFlags.DSOLocal = Flag;
      break;
    case lltok::kw_canAutoHide:
      Lex.Lex();
      if (parseToken(lltok::colon, "expected ':'") || parseFlag(Flag))
        return true;
      GVFlags.CanAutoHide = Flag;
      break;
    case lltok::kw_importType:
      Lex.Lex();
      if (parseToken(lltok::colon, "expected ':'"))
        return true;
      GlobalValueSummary::ImportKind IK;
      if (parseOptionalImportType(Lex.getKind(), IK))
        return true;
      GVFlags.ImportType = static_cast<unsigned>(IK);
      Lex.Lex();
      break;
    default:
      return error(Lex.getLoc(), "expected gv flag type");
    }
  } while (EatIfPresent(lltok::comma));

  if (parseToken(lltok::rparen, "expected ')' here"))
    return true;

  return false;
}

/// GVarFlags
///   ::= 'varFlags' ':' '(' 'readonly' ':' Flag
///                      ',' 'writeonly' ':' Flag
///                      ',' 'constant' ':' Flag ')'
bool LLParser::parseGVarFlags(GlobalVarSummary::GVarFlags &GVarFlags) {
  assert(Lex.getKind() == lltok::kw_varFlags);
  Lex.Lex();

  if (parseToken(lltok::colon, "expected ':' here") ||
      parseToken(lltok::lparen, "expected '(' here"))
    return true;

  auto ParseRest = [this](unsigned int &Val) {
    Lex.Lex();
    if (parseToken(lltok::colon, "expected ':'"))
      return true;
    return parseFlag(Val);
  };

  do {
    unsigned Flag = 0;
    switch (Lex.getKind()) {
    case lltok::kw_readonly:
      if (ParseRest(Flag))
        return true;
      GVarFlags.MaybeReadOnly = Flag;
      break;
    case lltok::kw_writeonly:
      if (ParseRest(Flag))
        return true;
      GVarFlags.MaybeWriteOnly = Flag;
      break;
    case lltok::kw_constant:
      if (ParseRest(Flag))
        return true;
      GVarFlags.Constant = Flag;
      break;
    case lltok::kw_vcall_visibility:
      if (ParseRest(Flag))
        return true;
      GVarFlags.VCallVisibility = Flag;
      break;
    default:
      return error(Lex.getLoc(), "expected gvar flag type");
    }
  } while (EatIfPresent(lltok::comma));
  return parseToken(lltok::rparen, "expected ')' here");
}

/// ModuleReference
///   ::= 'module' ':' UInt
bool LLParser::parseModuleReference(StringRef &ModulePath) {
  // parse module id.
  if (parseToken(lltok::kw_module, "expected 'module' here") ||
      parseToken(lltok::colon, "expected ':' here") ||
      parseToken(lltok::SummaryID, "expected module ID"))
    return true;

  unsigned ModuleID = Lex.getUIntVal();
  auto I = ModuleIdMap.find(ModuleID);
  // We should have already parsed all module IDs
  assert(I != ModuleIdMap.end());
  ModulePath = I->second;
  return false;
}

/// GVReference
///   ::= SummaryID
bool LLParser::parseGVReference(ValueInfo &VI, unsigned &GVId) {
  bool WriteOnly = false, ReadOnly = EatIfPresent(lltok::kw_readonly);
  if (!ReadOnly)
    WriteOnly = EatIfPresent(lltok::kw_writeonly);
  if (parseToken(lltok::SummaryID, "expected GV ID"))
    return true;

  GVId = Lex.getUIntVal();
  // Check if we already have a VI for this GV
  if (GVId < NumberedValueInfos.size() && NumberedValueInfos[GVId]) {
    assert(NumberedValueInfos[GVId].getRef() != FwdVIRef);
    VI = NumberedValueInfos[GVId];
  } else
    // We will create a forward reference to the stored location.
    VI = ValueInfo(false, FwdVIRef);

  if (ReadOnly)
    VI.setReadOnly();
  if (WriteOnly)
    VI.setWriteOnly();
  return false;
}

/// OptionalAllocs
///   := 'allocs' ':' '(' Alloc [',' Alloc]* ')'
/// Alloc ::= '(' 'versions' ':' '(' Version [',' Version]* ')'
///              ',' MemProfs ')'
/// Version ::= UInt32
bool LLParser::parseOptionalAllocs(std::vector<AllocInfo> &Allocs) {
  assert(Lex.getKind() == lltok::kw_allocs);
  Lex.Lex();

  if (parseToken(lltok::colon, "expected ':' in allocs") ||
      parseToken(lltok::lparen, "expected '(' in allocs"))
    return true;

  // parse each alloc
  do {
    if (parseToken(lltok::lparen, "expected '(' in alloc") ||
        parseToken(lltok::kw_versions, "expected 'versions' in alloc") ||
        parseToken(lltok::colon, "expected ':'") ||
        parseToken(lltok::lparen, "expected '(' in versions"))
      return true;

    SmallVector<uint8_t> Versions;
    do {
      uint8_t V = 0;
      if (parseAllocType(V))
        return true;
      Versions.push_back(V);
    } while (EatIfPresent(lltok::comma));

    if (parseToken(lltok::rparen, "expected ')' in versions") ||
        parseToken(lltok::comma, "expected ',' in alloc"))
      return true;

    std::vector<MIBInfo> MIBs;
    if (parseMemProfs(MIBs))
      return true;

    Allocs.push_back({Versions, MIBs});

    if (parseToken(lltok::rparen, "expected ')' in alloc"))
      return true;
  } while (EatIfPresent(lltok::comma));

  if (parseToken(lltok::rparen, "expected ')' in allocs"))
    return true;

  return false;
}

/// MemProfs
///   := 'memProf' ':' '(' MemProf [',' MemProf]* ')'
/// MemProf ::= '(' 'type' ':' AllocType
///              ',' 'stackIds' ':' '(' StackId [',' StackId]* ')' ')'
/// StackId ::= UInt64
bool LLParser::parseMemProfs(std::vector<MIBInfo> &MIBs) {
  assert(Lex.getKind() == lltok::kw_memProf);
  Lex.Lex();

  if (parseToken(lltok::colon, "expected ':' in memprof") ||
      parseToken(lltok::lparen, "expected '(' in memprof"))
    return true;

  // parse each MIB
  do {
    if (parseToken(lltok::lparen, "expected '(' in memprof") ||
        parseToken(lltok::kw_type, "expected 'type' in memprof") ||
        parseToken(lltok::colon, "expected ':'"))
      return true;

    uint8_t AllocType;
    if (parseAllocType(AllocType))
      return true;

    if (parseToken(lltok::comma, "expected ',' in memprof") ||
        parseToken(lltok::kw_stackIds, "expected 'stackIds' in memprof") ||
        parseToken(lltok::colon, "expected ':'") ||
        parseToken(lltok::lparen, "expected '(' in stackIds"))
      return true;

    SmallVector<unsigned> StackIdIndices;
    // Combined index alloc records may not have a stack id list.
    if (Lex.getKind() != lltok::rparen) {
      do {
        uint64_t StackId = 0;
        if (parseUInt64(StackId))
          return true;
        StackIdIndices.push_back(Index->addOrGetStackIdIndex(StackId));
      } while (EatIfPresent(lltok::comma));
    }

    if (parseToken(lltok::rparen, "expected ')' in stackIds"))
      return true;

    MIBs.push_back({(AllocationType)AllocType, StackIdIndices});

    if (parseToken(lltok::rparen, "expected ')' in memprof"))
      return true;
  } while (EatIfPresent(lltok::comma));

  if (parseToken(lltok::rparen, "expected ')' in memprof"))
    return true;

  return false;
}

/// AllocType
///   := ('none'|'notcold'|'cold'|'hot')
bool LLParser::parseAllocType(uint8_t &AllocType) {
  switch (Lex.getKind()) {
  case lltok::kw_none:
    AllocType = (uint8_t)AllocationType::None;
    break;
  case lltok::kw_notcold:
    AllocType = (uint8_t)AllocationType::NotCold;
    break;
  case lltok::kw_cold:
    AllocType = (uint8_t)AllocationType::Cold;
    break;
  case lltok::kw_hot:
    AllocType = (uint8_t)AllocationType::Hot;
    break;
  default:
    return error(Lex.getLoc(), "invalid alloc type");
  }
  Lex.Lex();
  return false;
}

/// OptionalCallsites
///   := 'callsites' ':' '(' Callsite [',' Callsite]* ')'
/// Callsite ::= '(' 'callee' ':' GVReference
///              ',' 'clones' ':' '(' Version [',' Version]* ')'
///              ',' 'stackIds' ':' '(' StackId [',' StackId]* ')' ')'
/// Version ::= UInt32
/// StackId ::= UInt64
bool LLParser::parseOptionalCallsites(std::vector<CallsiteInfo> &Callsites) {
  assert(Lex.getKind() == lltok::kw_callsites);
  Lex.Lex();

  if (parseToken(lltok::colon, "expected ':' in callsites") ||
      parseToken(lltok::lparen, "expected '(' in callsites"))
    return true;

  IdToIndexMapType IdToIndexMap;
  // parse each callsite
  do {
    if (parseToken(lltok::lparen, "expected '(' in callsite") ||
        parseToken(lltok::kw_callee, "expected 'callee' in callsite") ||
        parseToken(lltok::colon, "expected ':'"))
      return true;

    ValueInfo VI;
    unsigned GVId = 0;
    LocTy Loc = Lex.getLoc();
    if (!EatIfPresent(lltok::kw_null)) {
      if (parseGVReference(VI, GVId))
        return true;
    }

    if (parseToken(lltok::comma, "expected ',' in callsite") ||
        parseToken(lltok::kw_clones, "expected 'clones' in callsite") ||
        parseToken(lltok::colon, "expected ':'") ||
        parseToken(lltok::lparen, "expected '(' in clones"))
      return true;

    SmallVector<unsigned> Clones;
    do {
      unsigned V = 0;
      if (parseUInt32(V))
        return true;
      Clones.push_back(V);
    } while (EatIfPresent(lltok::comma));

    if (parseToken(lltok::rparen, "expected ')' in clones") ||
        parseToken(lltok::comma, "expected ',' in callsite") ||
        parseToken(lltok::kw_stackIds, "expected 'stackIds' in callsite") ||
        parseToken(lltok::colon, "expected ':'") ||
        parseToken(lltok::lparen, "expected '(' in stackIds"))
      return true;

    SmallVector<unsigned> StackIdIndices;
    // Synthesized callsite records will not have a stack id list.
    if (Lex.getKind() != lltok::rparen) {
      do {
        uint64_t StackId = 0;
        if (parseUInt64(StackId))
          return true;
        StackIdIndices.push_back(Index->addOrGetStackIdIndex(StackId));
      } while (EatIfPresent(lltok::comma));
    }

    if (parseToken(lltok::rparen, "expected ')' in stackIds"))
      return true;

    // Keep track of the Callsites array index needing a forward reference.
    // We will save the location of the ValueInfo needing an update, but
    // can only do so once the SmallVector is finalized.
    if (VI.getRef() == FwdVIRef)
      IdToIndexMap[GVId].push_back(std::make_pair(Callsites.size(), Loc));
    Callsites.push_back({VI, Clones, StackIdIndices});

    if (parseToken(lltok::rparen, "expected ')' in callsite"))
      return true;
  } while (EatIfPresent(lltok::comma));

  // Now that the Callsites vector is finalized, it is safe to save the
  // locations of any forward GV references that need updating later.
  for (auto I : IdToIndexMap) {
    auto &Infos = ForwardRefValueInfos[I.first];
    for (auto P : I.second) {
      assert(Callsites[P.first].Callee.getRef() == FwdVIRef &&
             "Forward referenced ValueInfo expected to be empty");
      Infos.emplace_back(&Callsites[P.first].Callee, P.second);
    }
  }

  if (parseToken(lltok::rparen, "expected ')' in callsites"))
    return true;

  return false;
}
