//===-- 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 "LLParser.h"
#include "LLToken.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/None.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.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/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/Intrinsics.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Value.h"
#include "llvm/IR/ValueSymbolTable.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/SaveAndRestore.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cassert>
#include <cstring>
#include <iterator>
#include <vector>

using namespace llvm;

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())
      return true;

    if (auto LayoutOverride = DataLayoutCallback(M->getTargetTriple()))
      M->setDataLayout(*LayoutOverride);
  }

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

void LLParser::restoreParsingState(const SlotMapping *Slots) {
  if (!Slots)
    return;
  NumberedVals = Slots->GlobalValues;
  NumberedMetadata = Slots->MetadataNodes;
  for (const auto &I : Slots->NamedTypes)
    NamedTypes.insert(
        std::make_pair(I.getKey(), std::make_pair(I.second, LocTy())));
  for (const auto &I : Slots->Types)
    NumberedTypes.insert(
        std::make_pair(I.first, std::make_pair(I.second, LocTy())));
}

/// validateEndOfModule - Do final validity and sanity checks at the end of the
/// module.
bool LLParser::validateEndOfModule(bool UpgradeDebugInfo) {
  if (!M)
    return false;
  // 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;

    for (const auto &Attr : Attrs)
      B.merge(NumberedAttrBuilders[Attr]);

    if (Function *Fn = dyn_cast<Function>(V)) {
      AttributeList AS = Fn->getAttributes();
      AttrBuilder FnAttrs(AS.getFnAttributes());
      AS = AS.removeAttributes(Context, AttributeList::FunctionIndex);

      FnAttrs.merge(B);

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

      AS = AS.addAttributes(Context, AttributeList::FunctionIndex,
                            AttributeSet::get(Context, FnAttrs));
      Fn->setAttributes(AS);
    } else if (CallInst *CI = dyn_cast<CallInst>(V)) {
      AttributeList AS = CI->getAttributes();
      AttrBuilder FnAttrs(AS.getFnAttributes());
      AS = AS.removeAttributes(Context, AttributeList::FunctionIndex);
      FnAttrs.merge(B);
      AS = AS.addAttributes(Context, AttributeList::FunctionIndex,
                            AttributeSet::get(Context, FnAttrs));
      CI->setAttributes(AS);
    } else if (InvokeInst *II = dyn_cast<InvokeInst>(V)) {
      AttributeList AS = II->getAttributes();
      AttrBuilder FnAttrs(AS.getFnAttributes());
      AS = AS.removeAttributes(Context, AttributeList::FunctionIndex);
      FnAttrs.merge(B);
      AS = AS.addAttributes(Context, AttributeList::FunctionIndex,
                            AttributeSet::get(Context, FnAttrs));
      II->setAttributes(AS);
    } else if (CallBrInst *CBI = dyn_cast<CallBrInst>(V)) {
      AttributeList AS = CBI->getAttributes();
      AttrBuilder FnAttrs(AS.getFnAttributes());
      AS = AS.removeAttributes(Context, AttributeList::FunctionIndex);
      FnAttrs.merge(B);
      AS = AS.addAttributes(Context, AttributeList::FunctionIndex,
                            AttributeSet::get(Context, FnAttrs));
      CBI->setAttributes(AS);
    } else if (auto *GV = dyn_cast<GlobalVariable>(V)) {
      AttrBuilder Attrs(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");

  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 + "'");

  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 (!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);
    assert(MD && "UpgradeInstWithTBAATag should have a TBAA tag");
    auto *UpgradedMD = UpgradeTBAANode(*MD);
    if (MD != UpgradedMD)
      Inst->setMetadata(LLVMContext::MD_tbaa, UpgradedMD);
  }

  // Look for intrinsic functions and CallInst that need to be upgraded
  for (Module::iterator FI = M->begin(), FE = M->end(); FI != FE; )
    UpgradeCallsToIntrinsic(&*FI++); // must be post-increment, as we remove

  // Some types could be renamed during loading if several modules are
  // loaded in the same LLVMContext (LTO scenario). In this case we should
  // remangle intrinsics names as well.
  for (Module::iterator FI = M->begin(), FE = M->end(); FI != FE; ) {
    Function *F = &*FI++;
    if (auto Remangled = Intrinsic::remangleIntrinsicFunction(F)) {
      F->replaceAllUsesWith(Remangled.getValue());
      F->eraseFromParent();
    }
  }

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

  UpgradeModuleFlags(*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 sanity 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() {
  while (true) {
    switch (Lex.getKind()) {
    case lltok::kw_target:
      if (parseTargetDefinition())
        return true;
      break;
    case lltok::kw_source_filename:
      if (parseSourceFileName())
        return true;
      break;
    default:
      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::kw_deplibs:
      if (parseDepLibs())
        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() {
  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(Str);
    return false;
  case lltok::kw_datalayout:
    Lex.Lex();
    if (parseToken(lltok::equal, "expected '=' after target datalayout") ||
        parseStringConstant(Str))
      return true;
    M->setDataLayout(Str);
    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;
}

/// toplevelentity
///   ::= 'deplibs' '=' '[' ']'
///   ::= 'deplibs' '=' '[' STRINGCONSTANT (',' STRINGCONSTANT)* ']'
/// FIXME: Remove in 4.0. Currently parse, but ignore.
bool LLParser::parseDepLibs() {
  assert(Lex.getKind() == lltok::kw_deplibs);
  Lex.Lex();
  if (parseToken(lltok::equal, "expected '=' after deplibs") ||
      parseToken(lltok::lsquare, "expected '=' after deplibs"))
    return true;

  if (EatIfPresent(lltok::rsquare))
    return false;

  do {
    std::string Str;
    if (parseStringConstant(Str))
      return true;
  } while (EatIfPresent(lltok::comma));

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

/// 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;
  if (parseFunctionHeader(F, false))
    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;
  return parseFunctionHeader(F, true) || parseOptionalFunctionMetadata(*F) ||
         parseFunctionBody(*F);
}

/// 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 = NumberedVals.size();
  std::string Name;
  LocTy NameLoc = Lex.getLoc();

  // Handle the GlobalID form.
  if (Lex.getKind() == lltok::GlobalID) {
    if (Lex.getUIntVal() != VarID)
      return error(Lex.getLoc(),
                   "variable expected to be numbered '%" + Twine(VarID) + "'");
    Lex.Lex(); // eat GlobalID;

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

  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;

  if (Lex.getKind() != lltok::kw_alias && Lex.getKind() != lltok::kw_ifunc)
    return parseGlobal(Name, NameLoc, Linkage, HasLinkage, Visibility,
                       DLLStorageClass, DSOLocal, TLM, UnnamedAddr);

  return parseIndirectSymbol(Name, 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;

  if (Lex.getKind() != lltok::kw_alias && Lex.getKind() != lltok::kw_ifunc)
    return parseGlobal(Name, NameLoc, Linkage, HasLinkage, Visibility,
                       DLLStorageClass, DSOLocal, TLM, UnnamedAddr);

  return parseIndirectSymbol(Name, 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_noduplicates:
    SK = Comdat::NoDuplicates;
    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.
  if (NumberedMetadata.count(MID)) {
    Result = NumberedMetadata[MID];
    return false;
  }

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

  Result = FwdRef.first.get();
  NumberedMetadata[MID].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;
      } 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()) {
    FI->second.first->replaceAllUsesWith(Init);
    ForwardRefMDNodes.erase(FI);

    assert(NumberedMetadata[MetadataID] == Init && "Tracking VH didn't work");
  } else {
    if (NumberedMetadata.count(MetadataID))
      return tokError("Metadata id is already used");
    NumberedMetadata[MetadataID].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;
}

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

/// parseIndirectSymbol:
///   ::= GlobalVar '=' OptionalLinkage OptionalPreemptionSpecifier
///                     OptionalVisibility OptionalDLLStorageClass
///                     OptionalThreadLocal OptionalUnnamedAddr
///                     'alias|ifunc' IndirectSymbol IndirectSymbolAttr*
///
/// IndirectSymbol
///   ::= TypeAndValue
///
/// IndirectSymbolAttr
///   ::= ',' 'partition' StringConstant
///
/// Everything through OptionalUnnamedAddr has already been parsed.
///
bool LLParser::parseIndirectSymbol(const std::string &Name, 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");

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

  if (IsAlias && Ty != PTy->getElementType())
    return error(ExplicitTypeLoc,
                 "explicit pointee type doesn't match operand's pointee type");

  if (!IsAlias && !PTy->getElementType()->isFunctionTy())
    return error(ExplicitTypeLoc,
                 "explicit pointee type should be a function type");

  GlobalValue *GVal = nullptr;

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

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

  // 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();
      GA->setPartition(Lex.getStrVal());
      if (parseToken(lltok::StringConstant, "expected partition string"))
        return true;
    } else {
      return tokError("unknown alias or ifunc property!");
    }
  }

  if (Name.empty())
    NumberedVals.push_back(GA.get());

  if (GVal) {
    // Verify that types agree.
    if (GVal->getType() != GA->getType())
      return error(
          ExplicitTypeLoc,
          "forward reference and definition of alias have different types");

    // If they agree, just RAUW the old value with the alias and remove the
    // forward ref info.
    GVal->replaceAllUsesWith(GA.get());
    GVal->eraseFromParent();
  }

  // Insert into the module, we know its name won't collide now.
  if (IsAlias)
    M->getAliasList().push_back(cast<GlobalAlias>(GA.get()));
  else
    M->getIFuncList().push_back(cast<GlobalIFunc>(GA.get()));
  assert(GA->getName() == Name && "Should not be a name conflict!");

  // The module owns this now
  GA.release();

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

  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()) {
    GVal = M->getNamedValue(Name);
    if (GVal) {
      if (!ForwardRefVals.erase(Name))
        return error(NameLoc, "redefinition of global '@" + Name + "'");
    }
  } else {
    auto I = ForwardRefValIDs.find(NumberedVals.size());
    if (I != ForwardRefValIDs.end()) {
      GVal = I->second.first;
      ForwardRefValIDs.erase(I);
    }
  }

  GlobalVariable *GV;
  if (!GVal) {
    GV = new GlobalVariable(*M, Ty, false, GlobalValue::ExternalLinkage, nullptr,
                            Name, nullptr, GlobalVariable::NotThreadLocal,
                            AddrSpace);
  } else {
    if (GVal->getValueType() != Ty)
      return error(
          TyLoc,
          "forward reference and definition of global have different types");

    GV = cast<GlobalVariable>(GVal);

    // Move the forward-reference to the correct spot in the module.
    M->getGlobalList().splice(M->global_end(), M->getGlobalList(), GV);
  }

  if (Name.empty())
    NumberedVals.push_back(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);

  // 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;
      GV->setAlignment(Alignment);
    } else if (Lex.getKind() == lltok::MetadataVar) {
      if (parseGlobalObjectMetadataAttachment(*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;
  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") ||
      parseFnAttributeValuePairs(NumberedAttrBuilders[VarID], unused, true,
                                 BuiltinLoc) ||
      parseToken(lltok::rbrace, "expected end of attribute group"))
    return true;

  if (!NumberedAttrBuilders[VarID].hasAttributes())
    return error(AttrGrpLoc, "attribute group has no attributes");

  return false;
}

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

  B.clear();

  while (true) {
    lltok::Kind Token = Lex.getKind();
    if (Token == lltok::kw_builtin)
      BuiltinLoc = Lex.getLoc();
    switch (Token) {
    default:
      if (!inAttrGrp) return HaveError;
      return error(Lex.getLoc(), "unterminated attribute group");
    case lltok::rbrace:
      // Finished.
      return false;

    case 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");

      unsigned AttrGrpNum = Lex.getUIntVal();
      if (inAttrGrp) break;

      // Save the reference to the attribute group. We'll fill it in later.
      FwdRefAttrGrps.push_back(AttrGrpNum);
      break;
    }
    // Target-dependent attributes:
    case lltok::StringConstant: {
      if (parseStringAttribute(B))
        return true;
      continue;
    }

    // Target-independent attributes:
    case lltok::kw_align: {
      // 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.
      MaybeAlign Alignment;
      if (inAttrGrp) {
        Lex.Lex();
        uint32_t Value = 0;
        if (parseToken(lltok::equal, "expected '=' here") || parseUInt32(Value))
          return true;
        Alignment = Align(Value);
      } else {
        if (parseOptionalAlignment(Alignment))
          return true;
      }
      B.addAlignmentAttr(Alignment);
      continue;
    }
    case lltok::kw_alignstack: {
      unsigned Alignment;
      if (inAttrGrp) {
        Lex.Lex();
        if (parseToken(lltok::equal, "expected '=' here") ||
            parseUInt32(Alignment))
          return true;
      } else {
        if (parseOptionalStackAlignment(Alignment))
          return true;
      }
      B.addStackAlignmentAttr(Alignment);
      continue;
    }
    case lltok::kw_allocsize: {
      unsigned ElemSizeArg;
      Optional<unsigned> NumElemsArg;
      // inAttrGrp doesn't matter; we only support allocsize(a[, b])
      if (parseAllocSizeArguments(ElemSizeArg, NumElemsArg))
        return true;
      B.addAllocSizeAttr(ElemSizeArg, NumElemsArg);
      continue;
    }
    case lltok::kw_alwaysinline: B.addAttribute(Attribute::AlwaysInline); break;
    case lltok::kw_argmemonly: B.addAttribute(Attribute::ArgMemOnly); break;
    case lltok::kw_builtin: B.addAttribute(Attribute::Builtin); break;
    case lltok::kw_cold: B.addAttribute(Attribute::Cold); break;
    case lltok::kw_hot: B.addAttribute(Attribute::Hot); break;
    case lltok::kw_convergent: B.addAttribute(Attribute::Convergent); break;
    case lltok::kw_inaccessiblememonly:
      B.addAttribute(Attribute::InaccessibleMemOnly); break;
    case lltok::kw_inaccessiblemem_or_argmemonly:
      B.addAttribute(Attribute::InaccessibleMemOrArgMemOnly); break;
    case lltok::kw_inlinehint: B.addAttribute(Attribute::InlineHint); break;
    case lltok::kw_jumptable: B.addAttribute(Attribute::JumpTable); break;
    case lltok::kw_minsize: B.addAttribute(Attribute::MinSize); break;
    case lltok::kw_mustprogress:
      B.addAttribute(Attribute::MustProgress);
      break;
    case lltok::kw_naked: B.addAttribute(Attribute::Naked); break;
    case lltok::kw_nobuiltin: B.addAttribute(Attribute::NoBuiltin); break;
    case lltok::kw_nocallback:
      B.addAttribute(Attribute::NoCallback);
      break;
    case lltok::kw_noduplicate: B.addAttribute(Attribute::NoDuplicate); break;
    case lltok::kw_nofree: B.addAttribute(Attribute::NoFree); break;
    case lltok::kw_noimplicitfloat:
      B.addAttribute(Attribute::NoImplicitFloat); break;
    case lltok::kw_noinline: B.addAttribute(Attribute::NoInline); break;
    case lltok::kw_nonlazybind: B.addAttribute(Attribute::NonLazyBind); break;
    case lltok::kw_nomerge: B.addAttribute(Attribute::NoMerge); break;
    case lltok::kw_noredzone: B.addAttribute(Attribute::NoRedZone); break;
    case lltok::kw_noreturn: B.addAttribute(Attribute::NoReturn); break;
    case lltok::kw_nosync: B.addAttribute(Attribute::NoSync); break;
    case lltok::kw_nocf_check: B.addAttribute(Attribute::NoCfCheck); break;
    case lltok::kw_noprofile: B.addAttribute(Attribute::NoProfile); break;
    case lltok::kw_norecurse: B.addAttribute(Attribute::NoRecurse); break;
    case lltok::kw_nounwind: B.addAttribute(Attribute::NoUnwind); break;
    case lltok::kw_null_pointer_is_valid:
      B.addAttribute(Attribute::NullPointerIsValid); break;
    case lltok::kw_optforfuzzing:
      B.addAttribute(Attribute::OptForFuzzing); break;
    case lltok::kw_optnone: B.addAttribute(Attribute::OptimizeNone); break;
    case lltok::kw_optsize: B.addAttribute(Attribute::OptimizeForSize); break;
    case lltok::kw_readnone: B.addAttribute(Attribute::ReadNone); break;
    case lltok::kw_readonly: B.addAttribute(Attribute::ReadOnly); break;
    case lltok::kw_returns_twice:
      B.addAttribute(Attribute::ReturnsTwice); break;
    case lltok::kw_speculatable: B.addAttribute(Attribute::Speculatable); break;
    case lltok::kw_ssp: B.addAttribute(Attribute::StackProtect); break;
    case lltok::kw_sspreq: B.addAttribute(Attribute::StackProtectReq); break;
    case lltok::kw_sspstrong:
      B.addAttribute(Attribute::StackProtectStrong); break;
    case lltok::kw_safestack: B.addAttribute(Attribute::SafeStack); break;
    case lltok::kw_shadowcallstack:
      B.addAttribute(Attribute::ShadowCallStack); break;
    case lltok::kw_sanitize_address:
      B.addAttribute(Attribute::SanitizeAddress); break;
    case lltok::kw_sanitize_hwaddress:
      B.addAttribute(Attribute::SanitizeHWAddress); break;
    case lltok::kw_sanitize_memtag:
      B.addAttribute(Attribute::SanitizeMemTag); break;
    case lltok::kw_sanitize_thread:
      B.addAttribute(Attribute::SanitizeThread); break;
    case lltok::kw_sanitize_memory:
      B.addAttribute(Attribute::SanitizeMemory); break;
    case lltok::kw_speculative_load_hardening:
      B.addAttribute(Attribute::SpeculativeLoadHardening);
      break;
    case lltok::kw_strictfp: B.addAttribute(Attribute::StrictFP); break;
    case lltok::kw_uwtable: B.addAttribute(Attribute::UWTable); break;
    case lltok::kw_willreturn: B.addAttribute(Attribute::WillReturn); break;
    case lltok::kw_writeonly: B.addAttribute(Attribute::WriteOnly); break;
    case lltok::kw_preallocated: {
      Type *Ty;
      if (parsePreallocated(Ty))
        return true;
      B.addPreallocatedAttr(Ty);
      break;
    }

    // error handling.
    case lltok::kw_inreg:
    case lltok::kw_signext:
    case lltok::kw_zeroext:
      HaveError |=
          error(Lex.getLoc(), "invalid use of attribute on a function");
      break;
    case lltok::kw_byval:
    case lltok::kw_dereferenceable:
    case lltok::kw_dereferenceable_or_null:
    case lltok::kw_inalloca:
    case lltok::kw_nest:
    case lltok::kw_noalias:
    case lltok::kw_noundef:
    case lltok::kw_nocapture:
    case lltok::kw_nonnull:
    case lltok::kw_returned:
    case lltok::kw_sret:
    case lltok::kw_swifterror:
    case lltok::kw_swiftself:
    case lltok::kw_immarg:
    case lltok::kw_byref:
      HaveError |=
          error(Lex.getLoc(),
                "invalid use of parameter-only attribute on a function");
      break;
    }

    // parsePreallocated() consumes token
    if (Token != lltok::kw_preallocated)
      Lex.Lex();
  }
}

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

static inline GlobalValue *createGlobalFwdRef(Module *M, PointerType *PTy,
                                              const std::string &Name) {
  if (auto *FT = dyn_cast<FunctionType>(PTy->getElementType()))
    return Function::Create(FT, GlobalValue::ExternalWeakLinkage,
                            PTy->getAddressSpace(), Name, M);
  else
    return new GlobalVariable(*M, PTy->getElementType(), false,
                              GlobalValue::ExternalWeakLinkage, nullptr, Name,
                              nullptr, GlobalVariable::NotThreadLocal,
                              PTy->getAddressSpace());
}

Value *LLParser::checkValidVariableType(LocTy Loc, const Twine &Name, Type *Ty,
                                        Value *Val, bool IsCall) {
  if (Val->getType() == Ty)
    return Val;
  // For calls we also accept variables in the program address space.
  Type *SuggestedTy = Ty;
  if (IsCall && isa<PointerType>(Ty)) {
    Type *TyInProgAS = cast<PointerType>(Ty)->getElementType()->getPointerTo(
        M->getDataLayout().getProgramAddressSpace());
    SuggestedTy = TyInProgAS;
    if (Val->getType() == TyInProgAS)
      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(SuggestedTy) + "'");
  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, bool IsCall) {
  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, IsCall));

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

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

  GlobalValue *Val = ID < NumberedVals.size() ? NumberedVals[ID] : nullptr;

  // If this is a forward reference for the value, see if we already created a
  // forward ref record.
  if (!Val) {
    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, IsCall));

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

/// parseStringAttribute
///   := StringConstant
///   := StringConstant '=' StringConstant
bool LLParser::parseStringAttribute(AttrBuilder &B) {
  std::string Attr = Lex.getStrVal();
  Lex.Lex();
  std::string Val;
  if (EatIfPresent(lltok::equal) && parseStringConstant(Val))
    return true;
  B.addAttribute(Attr, Val);
  return false;
}

/// parseOptionalParamAttrs - parse a potentially empty list of parameter
/// attributes.
bool LLParser::parseOptionalParamAttrs(AttrBuilder &B) {
  bool HaveError = false;

  B.clear();

  while (true) {
    lltok::Kind Token = Lex.getKind();
    switch (Token) {
    default:  // End of attributes.
      return HaveError;
    case lltok::StringConstant: {
      if (parseStringAttribute(B))
        return true;
      continue;
    }
    case lltok::kw_align: {
      MaybeAlign Alignment;
      if (parseOptionalAlignment(Alignment, true))
        return true;
      B.addAlignmentAttr(Alignment);
      continue;
    }
    case lltok::kw_byval: {
      Type *Ty;
      if (parseRequiredTypeAttr(Ty, lltok::kw_byval))
        return true;
      B.addByValAttr(Ty);
      continue;
    }
    case lltok::kw_sret: {
      Type *Ty;
      if (parseRequiredTypeAttr(Ty, lltok::kw_sret))
        return true;
      B.addStructRetAttr(Ty);
      continue;
    }
    case lltok::kw_preallocated: {
      Type *Ty;
      if (parsePreallocated(Ty))
        return true;
      B.addPreallocatedAttr(Ty);
      continue;
    }
    case lltok::kw_dereferenceable: {
      uint64_t Bytes;
      if (parseOptionalDerefAttrBytes(lltok::kw_dereferenceable, Bytes))
        return true;
      B.addDereferenceableAttr(Bytes);
      continue;
    }
    case lltok::kw_dereferenceable_or_null: {
      uint64_t Bytes;
      if (parseOptionalDerefAttrBytes(lltok::kw_dereferenceable_or_null, Bytes))
        return true;
      B.addDereferenceableOrNullAttr(Bytes);
      continue;
    }
    case lltok::kw_byref: {
      Type *Ty;
      if (parseByRef(Ty))
        return true;
      B.addByRefAttr(Ty);
      continue;
    }
    case lltok::kw_inalloca:        B.addAttribute(Attribute::InAlloca); break;
    case lltok::kw_inreg:           B.addAttribute(Attribute::InReg); break;
    case lltok::kw_nest:            B.addAttribute(Attribute::Nest); break;
    case lltok::kw_noundef:
      B.addAttribute(Attribute::NoUndef);
      break;
    case lltok::kw_noalias:         B.addAttribute(Attribute::NoAlias); break;
    case lltok::kw_nocapture:       B.addAttribute(Attribute::NoCapture); break;
    case lltok::kw_nofree:          B.addAttribute(Attribute::NoFree); break;
    case lltok::kw_nonnull:         B.addAttribute(Attribute::NonNull); break;
    case lltok::kw_readnone:        B.addAttribute(Attribute::ReadNone); break;
    case lltok::kw_readonly:        B.addAttribute(Attribute::ReadOnly); break;
    case lltok::kw_returned:        B.addAttribute(Attribute::Returned); break;
    case lltok::kw_signext:         B.addAttribute(Attribute::SExt); break;
    case lltok::kw_swifterror:      B.addAttribute(Attribute::SwiftError); break;
    case lltok::kw_swiftself:       B.addAttribute(Attribute::SwiftSelf); break;
    case lltok::kw_writeonly:       B.addAttribute(Attribute::WriteOnly); break;
    case lltok::kw_zeroext:         B.addAttribute(Attribute::ZExt); break;
    case lltok::kw_immarg:          B.addAttribute(Attribute::ImmArg); break;

    case lltok::kw_alignstack:
    case lltok::kw_alwaysinline:
    case lltok::kw_argmemonly:
    case lltok::kw_builtin:
    case lltok::kw_inlinehint:
    case lltok::kw_jumptable:
    case lltok::kw_minsize:
    case lltok::kw_mustprogress:
    case lltok::kw_naked:
    case lltok::kw_nobuiltin:
    case lltok::kw_noduplicate:
    case lltok::kw_noimplicitfloat:
    case lltok::kw_noinline:
    case lltok::kw_nonlazybind:
    case lltok::kw_nomerge:
    case lltok::kw_noprofile:
    case lltok::kw_noredzone:
    case lltok::kw_noreturn:
    case lltok::kw_nocf_check:
    case lltok::kw_nounwind:
    case lltok::kw_optforfuzzing:
    case lltok::kw_optnone:
    case lltok::kw_optsize:
    case lltok::kw_returns_twice:
    case lltok::kw_sanitize_address:
    case lltok::kw_sanitize_hwaddress:
    case lltok::kw_sanitize_memtag:
    case lltok::kw_sanitize_memory:
    case lltok::kw_sanitize_thread:
    case lltok::kw_speculative_load_hardening:
    case lltok::kw_ssp:
    case lltok::kw_sspreq:
    case lltok::kw_sspstrong:
    case lltok::kw_safestack:
    case lltok::kw_shadowcallstack:
    case lltok::kw_strictfp:
    case lltok::kw_uwtable:
      HaveError |=
          error(Lex.getLoc(), "invalid use of function-only attribute");
      break;
    }

    Lex.Lex();
  }
}

/// parseOptionalReturnAttrs - parse a potentially empty list of return
/// attributes.
bool LLParser::parseOptionalReturnAttrs(AttrBuilder &B) {
  bool HaveError = false;

  B.clear();

  while (true) {
    lltok::Kind Token = Lex.getKind();
    switch (Token) {
    default:  // End of attributes.
      return HaveError;
    case lltok::StringConstant: {
      if (parseStringAttribute(B))
        return true;
      continue;
    }
    case lltok::kw_dereferenceable: {
      uint64_t Bytes;
      if (parseOptionalDerefAttrBytes(lltok::kw_dereferenceable, Bytes))
        return true;
      B.addDereferenceableAttr(Bytes);
      continue;
    }
    case lltok::kw_dereferenceable_or_null: {
      uint64_t Bytes;
      if (parseOptionalDerefAttrBytes(lltok::kw_dereferenceable_or_null, Bytes))
        return true;
      B.addDereferenceableOrNullAttr(Bytes);
      continue;
    }
    case lltok::kw_align: {
      MaybeAlign Alignment;
      if (parseOptionalAlignment(Alignment))
        return true;
      B.addAlignmentAttr(Alignment);
      continue;
    }
    case lltok::kw_inreg:           B.addAttribute(Attribute::InReg); break;
    case lltok::kw_noalias:         B.addAttribute(Attribute::NoAlias); break;
    case lltok::kw_noundef:
      B.addAttribute(Attribute::NoUndef);
      break;
    case lltok::kw_nonnull:         B.addAttribute(Attribute::NonNull); break;
    case lltok::kw_signext:         B.addAttribute(Attribute::SExt); break;
    case lltok::kw_zeroext:         B.addAttribute(Attribute::ZExt); break;

    // error handling.
    case lltok::kw_byval:
    case lltok::kw_inalloca:
    case lltok::kw_nest:
    case lltok::kw_nocapture:
    case lltok::kw_returned:
    case lltok::kw_sret:
    case lltok::kw_swifterror:
    case lltok::kw_swiftself:
    case lltok::kw_immarg:
    case lltok::kw_byref:
      HaveError |=
          error(Lex.getLoc(), "invalid use of parameter-only attribute");
      break;

    case lltok::kw_alignstack:
    case lltok::kw_alwaysinline:
    case lltok::kw_argmemonly:
    case lltok::kw_builtin:
    case lltok::kw_cold:
    case lltok::kw_inlinehint:
    case lltok::kw_jumptable:
    case lltok::kw_minsize:
    case lltok::kw_mustprogress:
    case lltok::kw_naked:
    case lltok::kw_nobuiltin:
    case lltok::kw_noduplicate:
    case lltok::kw_noimplicitfloat:
    case lltok::kw_noinline:
    case lltok::kw_nonlazybind:
    case lltok::kw_nomerge:
    case lltok::kw_noprofile:
    case lltok::kw_noredzone:
    case lltok::kw_noreturn:
    case lltok::kw_nocf_check:
    case lltok::kw_nounwind:
    case lltok::kw_optforfuzzing:
    case lltok::kw_optnone:
    case lltok::kw_optsize:
    case lltok::kw_returns_twice:
    case lltok::kw_sanitize_address:
    case lltok::kw_sanitize_hwaddress:
    case lltok::kw_sanitize_memtag:
    case lltok::kw_sanitize_memory:
    case lltok::kw_sanitize_thread:
    case lltok::kw_speculative_load_hardening:
    case lltok::kw_ssp:
    case lltok::kw_sspreq:
    case lltok::kw_sspstrong:
    case lltok::kw_safestack:
    case lltok::kw_shadowcallstack:
    case lltok::kw_strictfp:
    case lltok::kw_uwtable:
      HaveError |=
          error(Lex.getLoc(), "invalid use of function-only attribute");
      break;
    case lltok::kw_readnone:
    case lltok::kw_readonly:
      HaveError |=
          error(Lex.getLoc(), "invalid use of attribute on return type");
      break;
    case lltok::kw_preallocated:
      HaveError |=
          error(Lex.getLoc(),
                "invalid use of parameter-only/call site-only attribute");
      break;
    }

    Lex.Lex();
  }
}

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

/// 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'
///   ::= 'msp430_intrcc'
///   ::= 'avr_intrcc'
///   ::= 'avr_signalcc'
///   ::= 'ptx_kernel'
///   ::= 'ptx_device'
///   ::= 'spir_func'
///   ::= 'spir_kernel'
///   ::= 'x86_64_sysvcc'
///   ::= 'win64cc'
///   ::= 'webkit_jscc'
///   ::= 'anyregcc'
///   ::= 'preserve_mostcc'
///   ::= 'preserve_allcc'
///   ::= 'ghccc'
///   ::= 'swiftcc'
///   ::= 'x86_intrcc'
///   ::= 'hhvmcc'
///   ::= 'hhvm_ccc'
///   ::= 'cxx_fast_tlscc'
///   ::= 'amdgpu_vs'
///   ::= 'amdgpu_ls'
///   ::= 'amdgpu_hs'
///   ::= 'amdgpu_es'
///   ::= 'amdgpu_gs'
///   ::= 'amdgpu_ps'
///   ::= 'amdgpu_cs'
///   ::= 'amdgpu_kernel'
///   ::= 'tailcc'
///   ::= '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_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_webkit_jscc:    CC = CallingConv::WebKit_JS; 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_ghccc:          CC = CallingConv::GHC; break;
  case lltok::kw_swiftcc:        CC = CallingConv::Swift; break;
  case lltok::kw_x86_intrcc:     CC = CallingConv::X86_INTR; break;
  case lltok::kw_hhvmcc:         CC = CallingConv::HHVM; break;
  case lltok::kw_hhvm_ccc:       CC = CallingConv::HHVM_C; break;
  case lltok::kw_cxx_fast_tlscc: CC = CallingConv::CXX_FAST_TLS; break;
  case lltok::kw_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_kernel:  CC = CallingConv::AMDGPU_KERNEL; break;
  case lltok::kw_tailcc:         CC = CallingConv::Tail; break;
  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;

    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 = None;
  if (!EatIfPresent(lltok::kw_align))
    return false;
  LocTy AlignLoc = Lex.getLoc();
  uint32_t Value = 0;

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

  if (parseUInt32(Value))
    return true;

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

  if (!isPowerOf2_32(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;
}

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

/// 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,
                                       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 = None;

  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();
    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(Result);
      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(Result, 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;
    AttrBuilder ArgAttrs;
    Value *V;
    if (parseType(ArgTy, ArgLoc))
      return true;

    if (ArgTy->isMetadataTy()) {
      if (parseMetadataAsValue(V, PFS))
        return true;
    } else {
      // Otherwise, handle normal operands.
      if (parseOptionalParamAttrs(ArgAttrs) || parseValue(ArgTy, V, PFS))
        return true;
    }
    ArgList.push_back(ParamInfo(
        ArgLoc, V, AttributeSet::get(V->getContext(), 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(Type *&Result, lltok::Kind AttrName) {
  Result = nullptr;
  if (!EatIfPresent(AttrName))
    return true;
  if (!EatIfPresent(lltok::lparen))
    return error(Lex.getLoc(), "expected '('");
  if (parseType(Result))
    return true;
  if (!EatIfPresent(lltok::rparen))
    return error(Lex.getLoc(), "expected ')'");
  return false;
}

/// parsePreallocated
///   ::= preallocated(<ty>)
bool LLParser::parsePreallocated(Type *&Result) {
  return parseRequiredTypeAttr(Result, lltok::kw_preallocated);
}

/// parseByRef
///   ::= byref(<type>)
bool LLParser::parseByRef(Type *&Result) {
  return parseRequiredTypeAttr(Result, lltok::kw_byref);
}

/// parseOptionalOperandBundles
///    ::= /*empty*/
///    ::= '[' OperandBundle [, OperandBundle ]* ']'
///
/// OperandBundle
///    ::= bundle-tag '(' ')'
///    ::= bundle-tag '(' Type Value [, Type Value ]* ')'
///
/// bundle-tag ::= String Constant
bool LLParser::parseOptionalOperandBundles(
    SmallVectorImpl<OperandBundleDef> &BundleList, PerFunctionState &PFS) {
  LocTy BeginLoc = Lex.getLoc();
  if (!EatIfPresent(lltok::lsquare))
    return false;

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

    std::string Tag;
    if (parseStringConstant(Tag))
      return true;

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

    std::vector<Value *> Inputs;
    while (Lex.getKind() != lltok::rparen) {
      // If this isn't the first input, we need a comma.
      if (!Inputs.empty() &&
          parseToken(lltok::comma, "expected ',' in input list"))
        return true;

      Type *Ty = nullptr;
      Value *Input = nullptr;
      if (parseType(Ty) || parseValue(Ty, Input, PFS))
        return true;
      Inputs.push_back(Input);
    }

    BundleList.emplace_back(std::move(Tag), std::move(Inputs));

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

  if (BundleList.empty())
    return error(BeginLoc, "operand bundle set must not be empty");

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

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

  if (Lex.getKind() == lltok::rparen) {
    // empty
  } else if (Lex.getKind() == lltok::dotdotdot) {
    IsVarArg = true;
    Lex.Lex();
  } else {
    LocTy TypeLoc = Lex.getLoc();
    Type *ArgTy = nullptr;
    AttrBuilder Attrs;
    std::string Name;

    if (parseType(ArgTy) || parseOptionalParamAttrs(Attrs))
      return true;

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

    if (Lex.getKind() == lltok::LocalVar) {
      Name = Lex.getStrVal();
      Lex.Lex();
    } else if (Lex.getKind() == lltok::LocalVarID) {
      if (Lex.getUIntVal() != CurValID)
        return error(TypeLoc, "argument expected to be numbered '%" +
                                  Twine(CurValID) + "'");
      ++CurValID;
      Lex.Lex();
    }

    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)) {
      // Handle ... at end of arg list.
      if (EatIfPresent(lltok::dotdotdot)) {
        IsVarArg = true;
        break;
      }

      // Otherwise must be an argument type.
      TypeLoc = Lex.getLoc();
      if (parseType(ArgTy) || parseOptionalParamAttrs(Attrs))
        return true;

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

      if (Lex.getKind() == lltok::LocalVar) {
        Name = Lex.getStrVal();
        Lex.Lex();
      } else {
        if (Lex.getKind() == lltok::LocalVarID) {
          if (Lex.getUIntVal() != CurValID)
            return error(TypeLoc, "argument expected to be numbered '%" +
                                      Twine(CurValID) + "'");
          Lex.Lex();
        }
        ++CurValID;
        Name = "";
      }

      if (!ArgTy->isFirstClassType())
        return error(TypeLoc, "invalid type for function argument");

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

  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;
  if (parseArgumentList(ArgList, IsVarArg))
    return true;

  // Reject names on the arguments lists.
  for (unsigned i = 0, e = ArgList.size(); i != e; ++i) {
    if (!ArgList[i].Name.empty())
      return error(ArgList[i].Loc, "argument name invalid in function type");
    if (ArgList[i].Attrs.hasAttributes())
      return error(ArgList[i].Loc,
                   "argument attributes invalid in function type");
  }

  SmallVector<Type*, 16> ArgListTy;
  for (unsigned i = 0, e = ArgList.size(); i != e; ++i)
    ArgListTy.push_back(ArgList[i].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;

  STy->setBody(Body, isPacked);
  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;
}

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

LLParser::PerFunctionState::PerFunctionState(LLParser &p, Function &f,
                                             int functionNumber)
  : P(p), F(f), FunctionNumber(functionNumber) {

  // Insert unnamed arguments into the NumberedVals list.
  for (Argument &A : F.args())
    if (!A.hasName())
      NumberedVals.push_back(&A);
}

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

  for (const auto &P : ForwardRefVals) {
    if (isa<BasicBlock>(P.second.first))
      continue;
    P.second.first->replaceAllUsesWith(
        UndefValue::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(
        UndefValue::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, bool IsCall) {
  // 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, IsCall);

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

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

Value *LLParser::PerFunctionState::getVal(unsigned ID, Type *Ty, LocTy Loc,
                                          bool IsCall) {
  // Look this name up in the normal function symbol table.
  Value *Val = ID < NumberedVals.size() ? NumberedVals[ID] : nullptr;

  // If this is a forward reference for the value, see if we already created a
  // forward ref record.
  if (!Val) {
    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, IsCall);

  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.size();

    if (unsigned(NameID) != NumberedVals.size())
      return P.error(NameLoc, "instruction expected to be numbered '%" +
                                  Twine(NumberedVals.size()) + "'");

    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.push_back(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, /*IsCall=*/false));
}

BasicBlock *LLParser::PerFunctionState::getBB(unsigned ID, LocTy Loc) {
  return dyn_cast_or_null<BasicBlock>(
      getVal(ID, Type::getLabelTy(F.getContext()), Loc, /*IsCall=*/false));
}

/// 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 && unsigned(NameID) != NumberedVals.size()) {
      P.error(Loc, "label expected to be numbered '" +
                       Twine(NumberedVals.size()) + "'");
      return nullptr;
    }
    BB = getBB(NumberedVals.size(), Loc);
    if (!BB) {
      P.error(Loc, "unable to create block numbered '" +
                       Twine(NumberedVals.size()) + "'");
      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.getBasicBlockList().splice(F.end(), F.getBasicBlockList(), BB);

  // Remove the block from forward ref sets.
  if (Name.empty()) {
    ForwardRefValIDs.erase(NumberedVals.size());
    NumberedVals.push_back(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
/// sanity.  PFS is used to convert function-local operands of metadata (since
/// metadata operands are not just parsed here but also converted to values).
/// PFS can be null when we are not parsing metadata values inside a function.
bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS) {
  ID.Loc = Lex.getLoc();
  switch (Lex.getKind()) {
  default:
    return tokError("expected value token");
  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;
    Lex.Lex();
    if (parseOptionalToken(lltok::kw_sideeffect, HasSideEffect) ||
        parseOptionalToken(lltok::kw_alignstack, AlignStack) ||
        parseOptionalToken(lltok::kw_inteldialect, AsmDialect) ||
        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);
    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) ||
        parseToken(lltok::comma,
                   "expected comma in block address expression") ||
        parseValID(Label) ||
        parseToken(lltok::rparen, "expected ')' in block address expression"))
      return true;

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

    // Try to find the function (but skip it if it's forward-referenced).
    GlobalValue *GV = nullptr;
    if (Fn.Kind == ValID::t_GlobalID) {
      if (Fn.UIntVal < NumberedVals.size())
        GV = NumberedVals[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.insert(std::make_pair(
                                              std::move(Fn),
                                              std::map<ValID, GlobalValue *>()))
              .first->second.insert(std::make_pair(std::move(Label), nullptr))
              .first->second;
      if (!FwdRef)
        FwdRef = new GlobalVariable(*M, Type::getInt8Ty(Context), false,
                                    GlobalValue::InternalLinkage, nullptr, "");
      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))
      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) {
      if (Fn.UIntVal < NumberedVals.size())
        GV = NumberedVals[Fn.UIntVal];
    } else if (!ForwardRefVals.count(Fn.StrVal)) {
      GV = M->getNamedValue(Fn.StrVal);
    }

    assert(GV && "Could not find a corresponding global variable");

    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_trunc:
  case lltok::kw_zext:
  case lltok::kw_sext:
  case lltok::kw_fptrunc:
  case lltok::kw_fpext:
  case lltok::kw_bitcast:
  case lltok::kw_addrspacecast:
  case lltok::kw_uitofp:
  case lltok::kw_sitofp:
  case lltok::kw_fptoui:
  case lltok::kw_fptosi:
  case lltok::kw_inttoptr:
  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: {
    Lex.Lex();
    Constant *Val;
    SmallVector<unsigned, 4> Indices;
    if (parseToken(lltok::lparen,
                   "expected '(' in extractvalue constantexpr") ||
        parseGlobalTypeAndValue(Val) || parseIndexList(Indices) ||
        parseToken(lltok::rparen, "expected ')' in extractvalue constantexpr"))
      return true;

    if (!Val->getType()->isAggregateType())
      return error(ID.Loc, "extractvalue operand must be aggregate type");
    if (!ExtractValueInst::getIndexedType(Val->getType(), Indices))
      return error(ID.Loc, "invalid indices for extractvalue");
    ID.ConstantVal = ConstantExpr::getExtractValue(Val, Indices);
    ID.Kind = ValID::t_Constant;
    return false;
  }
  case lltok::kw_insertvalue: {
    Lex.Lex();
    Constant *Val0, *Val1;
    SmallVector<unsigned, 4> Indices;
    if (parseToken(lltok::lparen, "expected '(' in insertvalue constantexpr") ||
        parseGlobalTypeAndValue(Val0) ||
        parseToken(lltok::comma,
                   "expected comma in insertvalue constantexpr") ||
        parseGlobalTypeAndValue(Val1) || parseIndexList(Indices) ||
        parseToken(lltok::rparen, "expected ')' in insertvalue constantexpr"))
      return true;
    if (!Val0->getType()->isAggregateType())
      return error(ID.Loc, "insertvalue operand must be aggregate type");
    Type *IndexedType =
        ExtractValueInst::getIndexedType(Val0->getType(), Indices);
    if (!IndexedType)
      return error(ID.Loc, "invalid indices for insertvalue");
    if (IndexedType != Val1->getType())
      return error(ID.Loc, "insertvalue operand and field disagree in type: '" +
                               getTypeString(Val1->getType()) +
                               "' instead of '" + getTypeString(IndexedType) +
                               "'");
    ID.ConstantVal = ConstantExpr::getInsertValue(Val0, Val1, Indices);
    ID.Kind = ValID::t_Constant;
    return false;
  }
  case lltok::kw_icmp:
  case lltok::kw_fcmp: {
    unsigned PredVal, Opc = Lex.getUIntVal();
    Constant *Val0, *Val1;
    Lex.Lex();
    if (parseCmpPredicate(PredVal, Opc) ||
        parseToken(lltok::lparen, "expected '(' in compare constantexpr") ||
        parseGlobalTypeAndValue(Val0) ||
        parseToken(lltok::comma, "expected comma in compare constantexpr") ||
        parseGlobalTypeAndValue(Val1) ||
        parseToken(lltok::rparen, "expected ')' in compare constantexpr"))
      return true;

    if (Val0->getType() != Val1->getType())
      return error(ID.Loc, "compare operands must have the same type");

    CmpInst::Predicate Pred = (CmpInst::Predicate)PredVal;

    if (Opc == Instruction::FCmp) {
      if (!Val0->getType()->isFPOrFPVectorTy())
        return error(ID.Loc, "fcmp requires floating point operands");
      ID.ConstantVal = ConstantExpr::getFCmp(Pred, Val0, Val1);
    } else {
      assert(Opc == Instruction::ICmp && "Unexpected opcode for CmpInst!");
      if (!Val0->getType()->isIntOrIntVectorTy() &&
          !Val0->getType()->isPtrOrPtrVectorTy())
        return error(ID.Loc, "icmp requires pointer or integer operands");
      ID.ConstantVal = ConstantExpr::getICmp(Pred, Val0, Val1);
    }
    ID.Kind = ValID::t_Constant;
    return false;
  }

  // Unary Operators.
  case lltok::kw_fneg: {
    unsigned Opc = Lex.getUIntVal();
    Constant *Val;
    Lex.Lex();
    if (parseToken(lltok::lparen, "expected '(' in unary constantexpr") ||
        parseGlobalTypeAndValue(Val) ||
        parseToken(lltok::rparen, "expected ')' in unary constantexpr"))
      return true;

    // Check that the type is valid for the operator.
    switch (Opc) {
    case Instruction::FNeg:
      if (!Val->getType()->isFPOrFPVectorTy())
        return error(ID.Loc, "constexpr requires fp operands");
      break;
    default: llvm_unreachable("Unknown unary operator!");
    }
    unsigned Flags = 0;
    Constant *C = ConstantExpr::get(Opc, Val, Flags);
    ID.ConstantVal = C;
    ID.Kind = ValID::t_Constant;
    return false;
  }
  // Binary Operators.
  case lltok::kw_add:
  case lltok::kw_fadd:
  case lltok::kw_sub:
  case lltok::kw_fsub:
  case lltok::kw_mul:
  case lltok::kw_fmul:
  case lltok::kw_udiv:
  case lltok::kw_sdiv:
  case lltok::kw_fdiv:
  case lltok::kw_urem:
  case lltok::kw_srem:
  case lltok::kw_frem:
  case lltok::kw_shl:
  case lltok::kw_lshr:
  case lltok::kw_ashr: {
    bool NUW = false;
    bool NSW = false;
    bool Exact = false;
    unsigned Opc = Lex.getUIntVal();
    Constant *Val0, *Val1;
    Lex.Lex();
    if (Opc == Instruction::Add || Opc == Instruction::Sub ||
        Opc == Instruction::Mul || Opc == Instruction::Shl) {
      if (EatIfPresent(lltok::kw_nuw))
        NUW = true;
      if (EatIfPresent(lltok::kw_nsw)) {
        NSW = true;
        if (EatIfPresent(lltok::kw_nuw))
          NUW = true;
      }
    } else if (Opc == Instruction::SDiv || Opc == Instruction::UDiv ||
               Opc == Instruction::LShr || Opc == Instruction::AShr) {
      if (EatIfPresent(lltok::kw_exact))
        Exact = 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.
    switch (Opc) {
    case Instruction::Add:
    case Instruction::Sub:
    case Instruction::Mul:
    case Instruction::UDiv:
    case Instruction::SDiv:
    case Instruction::URem:
    case Instruction::SRem:
    case Instruction::Shl:
    case Instruction::AShr:
    case Instruction::LShr:
      if (!Val0->getType()->isIntOrIntVectorTy())
        return error(ID.Loc, "constexpr requires integer operands");
      break;
    case Instruction::FAdd:
    case Instruction::FSub:
    case Instruction::FMul:
    case Instruction::FDiv:
    case Instruction::FRem:
      if (!Val0->getType()->isFPOrFPVectorTy())
        return error(ID.Loc, "constexpr requires fp operands");
      break;
    default: llvm_unreachable("Unknown binary operator!");
    }
    unsigned Flags = 0;
    if (NUW)   Flags |= OverflowingBinaryOperator::NoUnsignedWrap;
    if (NSW)   Flags |= OverflowingBinaryOperator::NoSignedWrap;
    if (Exact) Flags |= PossiblyExactOperator::IsExact;
    Constant *C = ConstantExpr::get(Opc, Val0, Val1, Flags);
    ID.ConstantVal = C;
    ID.Kind = ValID::t_Constant;
    return false;
  }

  // Logical Operations
  case lltok::kw_and:
  case lltok::kw_or:
  case lltok::kw_xor: {
    unsigned Opc = Lex.getUIntVal();
    Constant *Val0, *Val1;
    Lex.Lex();
    if (parseToken(lltok::lparen, "expected '(' in logical constantexpr") ||
        parseGlobalTypeAndValue(Val0) ||
        parseToken(lltok::comma, "expected comma in logical constantexpr") ||
        parseGlobalTypeAndValue(Val1) ||
        parseToken(lltok::rparen, "expected ')' in logical constantexpr"))
      return true;
    if (Val0->getType() != Val1->getType())
      return error(ID.Loc, "operands of constexpr must have same type");
    if (!Val0->getType()->isIntOrIntVectorTy())
      return error(ID.Loc,
                   "constexpr requires integer or integer vector operands");
    ID.ConstantVal = ConstantExpr::get(Opc, Val0, Val1);
    ID.Kind = ValID::t_Constant;
    return false;
  }

  case lltok::kw_getelementptr:
  case lltok::kw_shufflevector:
  case lltok::kw_insertelement:
  case lltok::kw_extractelement:
  case lltok::kw_select: {
    unsigned Opc = Lex.getUIntVal();
    SmallVector<Constant*, 16> Elts;
    bool InBounds = false;
    Type *Ty;
    Lex.Lex();

    if (Opc == Instruction::GetElementPtr)
      InBounds = EatIfPresent(lltok::kw_inbounds);

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

    LocTy ExplicitTypeLoc = Lex.getLoc();
    if (Opc == Instruction::GetElementPtr) {
      if (parseType(Ty) ||
          parseToken(lltok::comma, "expected comma after getelementptr's type"))
        return true;
    }

    Optional<unsigned> InRangeOp;
    if (parseGlobalValueVector(
            Elts, Opc == Instruction::GetElementPtr ? &InRangeOp : nullptr) ||
        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();
      auto *BasePointerType = cast<PointerType>(BaseType->getScalarType());
      if (Ty != BasePointerType->getElementType())
        return error(
            ExplicitTypeLoc,
            "explicit pointee type doesn't match operand's pointee type");

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

      if (InRangeOp) {
        if (*InRangeOp == 0)
          return error(ID.Loc,
                       "inrange keyword may not appear on pointer operand");
        --*InRangeOp;
      }

      ID.ConstantVal = ConstantExpr::getGetElementPtr(Ty, Elts[0], Indices,
                                                      InBounds, InRangeOp);
    } else if (Opc == Instruction::Select) {
      if (Elts.size() != 3)
        return error(ID.Loc, "expected three operands to select");
      if (const char *Reason = SelectInst::areInvalidOperands(Elts[0], Elts[1],
                                                              Elts[2]))
        return error(ID.Loc, Reason);
      ID.ConstantVal = ConstantExpr::getSelect(Elts[0], Elts[1], Elts[2]);
    } 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) ||
                convertValIDToValue(Ty, ID, V, nullptr, /*IsCall=*/false);
  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*/
///   ::= [inrange] TypeAndValue (',' [inrange] TypeAndValue)*
bool LLParser::parseGlobalValueVector(SmallVectorImpl<Constant *> &Elts,
                                      Optional<unsigned> *InRangeOp) {
  // Empty list.
  if (Lex.getKind() == lltok::rbrace ||
      Lex.getKind() == lltok::rsquare ||
      Lex.getKind() == lltok::greater ||
      Lex.getKind() == lltok::rparen)
    return false;

  do {
    if (InRangeOp && !*InRangeOp && EatIfPresent(lltok::kw_inrange))
      *InRangeOp = Elts.size();

    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 EmissionKindField : public MDUnsignedField {
  EmissionKindField() : MDUnsignedField(0, DICompileUnit::LastEmissionKind) {}
};

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_t Max;

  MDSignedField(int64_t Default = 0)
      : ImplTy(Default), Min(INT64_MIN), Max(INT64_MAX) {}
  MDSignedField(int64_t Default, int64_t Min, int64_t Max)
      : ImplTy(Default), Min(Min), Max(Max) {}
};

struct MDBoolField : public MDFieldImpl<bool> {
  MDBoolField(bool Default = false) : ImplTy(Default) {}
};

struct MDField : public MDFieldImpl<Metadata *> {
  bool AllowNull;

  MDField(bool AllowNull = true) : ImplTy(nullptr), AllowNull(AllowNull) {}
};

struct MDConstant : public MDFieldImpl<ConstantAsMetadata *> {
  MDConstant() : ImplTy(nullptr) {}
};

struct MDStringField : public MDFieldImpl<MDString *> {
  bool AllowEmpty;
  MDStringField(bool AllowEmpty = true)
      : ImplTy(nullptr), AllowEmpty(AllowEmpty) {}
};

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

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 MDSignedOrUnsignedField
    : MDEitherFieldImpl<MDSignedField, MDUnsignedField> {
  MDSignedOrUnsignedField() : ImplTy(MDSignedField(0), MDUnsignedField(0)) {}

  bool isMDSignedField() const { return WhatIs == IsTypeA; }
  bool isMDUnsignedField() const { return WhatIs == IsTypeB; }
  int64_t getMDSignedValue() const {
    assert(isMDSignedField() && "Wrong field type");
    return A.Val;
  }
  uint64_t getMDUnsignedValue() const {
    assert(isMDUnsignedField() && "Wrong field type");
    return B.Val;
  }
};

} // 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, 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,
                            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 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, MDStringField &Result) {
  LocTy ValueLoc = Lex.getLoc();
  std::string S;
  if (parseStringConstant(S))
    return true;

  if (!Result.AllowEmpty && S.empty())
    return error(ValueLoc, "'" + Name + "' cannot be empty");

  Result.assign(S.empty() ? nullptr : MDString::get(Context, S));
  return false;
}

template <>
bool LLParser::parseMDField(LocTy Loc, StringRef Name, MDFieldList &Result) {
  SmallVector<Metadata *, 4> MDs;
  if (parseMDNodeVector(MDs))
    return true;

  Result.assign(std::move(MDs));
  return false;
}

template <>
bool LLParser::parseMDField(LocTy Loc, StringRef Name,
                            ChecksumKindField &Result) {
  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)
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));
  PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS

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

/// parseGenericDINode:
///   ::= !GenericDINode(tag: 15, header: "...", operands: {...})
bool LLParser::parseGenericDINode(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED)                                    \
  REQUIRED(tag, DwarfTagField, );                                              \
  OPTIONAL(header, MDStringField, );                                           \
  OPTIONAL(operands, MDFieldList, );
  PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS

  Result = GET_OR_DISTINCT(GenericDINode,
                           (Context, tag.Val, header.Val, operands.Val));
  return false;
}

/// parseDISubrange:
///   ::= !DISubrange(count: 30, lowerBound: 2)
///   ::= !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;
  if (count.isMDSignedField())
    Count = ConstantAsMetadata::get(ConstantInt::getSigned(
        Type::getInt64Ty(Context), count.getMDSignedValue()));
  else if (count.isMDField())
    Count = count.getMDFieldValue();

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

  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 = [&](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, MDUnsignedField, (0, UINT64_MAX));                            \
  OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX));                           \
  OPTIONAL(encoding, DwarfAttEncodingField, );                                 \
  OPTIONAL(flags, DIFlagField, );
  PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS

  Result = GET_OR_DISTINCT(DIBasicType, (Context, tag.Val, name.Val, size.Val,
                                         align.Val, encoding.Val, flags.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(size, MDUnsignedField, (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, size.Val, align.Val,
                            encoding.Val));
  return false;
}

/// parseDIDerivedType:
///   ::= !DIDerivedType(tag: DW_TAG_pointer_type, name: "int", file: !0,
///                      line: 7, scope: !1, baseType: !2, size: 32,
///                      align: 32, offset: 0, flags: 0, extraData: !3,
///                      dwarfAddressSpace: 3)
bool LLParser::parseDIDerivedType(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED)                                    \
  REQUIRED(tag, DwarfTagField, );                                              \
  OPTIONAL(name, MDStringField, );                                             \
  OPTIONAL(file, MDField, );                                                   \
  OPTIONAL(line, LineField, );                                                 \
  OPTIONAL(scope, MDField, );                                                  \
  REQUIRED(baseType, MDField, );                                               \
  OPTIONAL(size, MDUnsignedField, (0, UINT64_MAX));                            \
  OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX));                           \
  OPTIONAL(offset, MDUnsignedField, (0, UINT64_MAX));                          \
  OPTIONAL(flags, DIFlagField, );                                              \
  OPTIONAL(extraData, MDField, );                                              \
  OPTIONAL(dwarfAddressSpace, MDUnsignedField, (UINT32_MAX, UINT32_MAX));
  PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS

  Optional<unsigned> DWARFAddressSpace;
  if (dwarfAddressSpace.Val != UINT32_MAX)
    DWARFAddressSpace = dwarfAddressSpace.Val;

  Result = GET_OR_DISTINCT(DIDerivedType,
                           (Context, tag.Val, name.Val, file.Val, line.Val,
                            scope.Val, baseType.Val, size.Val, align.Val,
                            offset.Val, DWARFAddressSpace, flags.Val,
                            extraData.Val));
  return false;
}

bool LLParser::parseDICompositeType(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED)                                    \
  REQUIRED(tag, DwarfTagField, );                                              \
  OPTIONAL(name, MDStringField, );                                             \
  OPTIONAL(file, MDField, );                                                   \
  OPTIONAL(line, LineField, );                                                 \
  OPTIONAL(scope, MDField, );                                                  \
  OPTIONAL(baseType, MDField, );                                               \
  OPTIONAL(size, MDUnsignedField, (0, UINT64_MAX));                            \
  OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX));                           \
  OPTIONAL(offset, MDUnsignedField, (0, UINT64_MAX));                          \
  OPTIONAL(flags, DIFlagField, );                                              \
  OPTIONAL(elements, MDField, );                                               \
  OPTIONAL(runtimeLang, DwarfLangField, );                                     \
  OPTIONAL(vtableHolder, MDField, );                                           \
  OPTIONAL(templateParams, MDField, );                                         \
  OPTIONAL(identifier, MDStringField, );                                       \
  OPTIONAL(discriminator, MDField, );                                          \
  OPTIONAL(dataLocation, MDField, );                                           \
  OPTIONAL(associated, MDField, );                                             \
  OPTIONAL(allocated, MDField, );                                              \
  OPTIONAL(rank, MDSignedOrMDField, );
  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();

  // 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.Val, align.Val, offset.Val, flags.Val,
            elements.Val, runtimeLang.Val, vtableHolder.Val, templateParams.Val,
            discriminator.Val, dataLocation.Val, associated.Val, allocated.Val,
            Rank)) {
      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.Val, align.Val, offset.Val, flags.Val, elements.Val,
       runtimeLang.Val, vtableHolder.Val, templateParams.Val, identifier.Val,
       discriminator.Val, dataLocation.Val, associated.Val, allocated.Val,
       Rank));
  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, );
  PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS

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

  Optional<MDString *> OptSource;
  if (source.Seen)
    OptSource = source.Val;
  Result = GET_OR_DISTINCT(DIFile, (Context, filename.Val, directory.Val,
                                    OptChecksum, OptSource));
  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 Lex.Error("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)
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, );
  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 Lex.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));
  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)                                    \
  REQUIRED(name, MDStringField, (/* AllowEmpty */ false));                     \
  OPTIONAL(scope, MDField, );                                                  \
  OPTIONAL(linkageName, MDStringField, );                                      \
  OPTIONAL(file, MDField, );                                                   \
  OPTIONAL(line, LineField, );                                                 \
  OPTIONAL(type, MDField, );                                                   \
  OPTIONAL(isLocal, MDBoolField, );                                            \
  OPTIONAL(isDefinition, MDBoolField, (true));                                 \
  OPTIONAL(templateParams, MDField, );                                         \
  OPTIONAL(declaration, MDField, );                                            \
  OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX));
  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));
  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));
  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));
  return false;
}

/// parseDILabel:
///   ::= !DILabel(scope: !0, name: "foo", file: !1, line: 7)
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, );
  PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS

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

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

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

  SmallVector<uint64_t, 8> Elements;
  if (Lex.getKind() != lltok::rparen)
    do {
      if (Lex.getKind() == lltok::DwarfOp) {
        if (unsigned Op = dwarf::getOperationEncoding(Lex.getStrVal())) {
          Lex.Lex();
          Elements.push_back(Op);
          continue;
        }
        return tokError(Twine("invalid DWARF op '") + Lex.getStrVal() + "'");
      }

      if (Lex.getKind() == lltok::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;
}

/// 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")
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, );
  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));
  return false;
}

#undef PARSE_MD_FIELD
#undef NOP_FIELD
#undef REQUIRE_FIELD
#undef DECLARE_FIELD

/// parseMetadataAsValue
///  ::= metadata i32 %local
///  ::= metadata i32 @global
///  ::= metadata i32 7
///  ::= metadata !0
///  ::= metadata !{...}
///  ::= metadata !"string"
bool LLParser::parseMetadataAsValue(Value *&V, PerFunctionState &PFS) {
  // Note: the type 'metadata' has already been parsed.
  Metadata *MD;
  if (parseMetadata(MD, &PFS))
    return true;

  V = MetadataAsValue::get(Context, MD);
  return false;
}

/// parseValueAsMetadata
///  ::= i32 %local
///  ::= i32 @global
///  ::= i32 7
bool LLParser::parseValueAsMetadata(Metadata *&MD, const Twine &TypeMsg,
                                    PerFunctionState *PFS) {
  Type *Ty;
  LocTy Loc;
  if (parseType(Ty, TypeMsg, Loc))
    return true;
  if (Ty->isMetadataTy())
    return error(Loc, "invalid metadata-value-metadata roundtrip");

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

  MD = ValueAsMetadata::get(V);
  return false;
}

/// parseMetadata
///  ::= i32 %local
///  ::= i32 @global
///  ::= i32 7
///  ::= !42
///  ::= !{...}
///  ::= !"string"
///  ::= !DILocation(...)
bool LLParser::parseMetadata(Metadata *&MD, PerFunctionState *PFS) {
  if (Lex.getKind() == lltok::MetadataVar) {
    MDNode *N;
    if (parseSpecializedMDNode(N))
      return true;
    MD = N;
    return false;
  }

  // ValueAsMetadata:
  // <type> <value>
  if (Lex.getKind() != lltok::exclaim)
    return parseValueAsMetadata(MD, "expected metadata operand", PFS);

  // '!'.
  assert(Lex.getKind() == lltok::exclaim && "Expected '!' here");
  Lex.Lex();

  // MDString:
  //   ::= '!' STRINGCONSTANT
  if (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, bool IsCall) {
  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, IsCall);
    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, IsCall);
    return V == nullptr;
  case ValID::t_InlineAsm: {
    if (!ID.FTy || !InlineAsm::Verify(ID.FTy, ID.StrVal2))
      return error(ID.Loc, "invalid type for inline asm constraint string");
    V = InlineAsm::get(ID.FTy, ID.StrVal, ID.StrVal2, ID.UIntVal & 1,
                       (ID.UIntVal >> 1) & 1,
                       (InlineAsm::AsmDialect(ID.UIntVal >> 2)));
    return false;
  }
  case ValID::t_GlobalName:
    V = getGlobalVal(ID.StrVal, Ty, ID.Loc, IsCall);
    return V == nullptr;
  case ValID::t_GlobalID:
    V = getGlobalVal(ID.UIntVal, Ty, ID.Loc, IsCall);
    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 = UndefValue::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");
    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");
    V = 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, makeArrayRef(ID.ConstantStructElts.get(), ID.UIntVal));
    } else
      return error(ID.Loc, "constant expression type mismatch");
    return false;
  }
  llvm_unreachable("Invalid ValID");
}

bool LLParser::parseConstantValue(Type *Ty, Constant *&C) {
  C = nullptr;
  ValID ID;
  auto Loc = Lex.getLoc();
  if (parseValID(ID, /*PFS=*/nullptr))
    return true;
  switch (ID.Kind) {
  case ValID::t_APSInt:
  case ValID::t_APFloat:
  case ValID::t_Undef:
  case ValID::t_Constant:
  case ValID::t_ConstantStruct:
  case ValID::t_PackedConstantStruct: {
    Value *V;
    if (convertValIDToValue(Ty, ID, V, /*PFS=*/nullptr, /*IsCall=*/false))
      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) ||
         convertValIDToValue(Ty, ID, V, PFS, /*IsCall=*/false);
}

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

/// 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) {
  // parse the linkage.
  LocTy LinkageLoc = Lex.getLoc();
  unsigned Linkage;
  unsigned Visibility;
  unsigned DLLStorageClass;
  bool DSOLocal;
  AttrBuilder RetAttrs;
  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 (!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.
    unsigned NameID = Lex.getUIntVal();

    if (NameID != NumberedVals.size())
      return tokError("function expected to be numbered '%" +
                      Twine(NumberedVals.size()) + "'");
  } 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;
  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, 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 (FuncAttrs.hasAlignmentAttr()) {
    Alignment = FuncAttrs.getAlignment();
    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 (unsigned i = 0, e = ArgList.size(); i != e; ++i) {
    ParamTypeList.push_back(ArgList[i].Ty);
    Attrs.push_back(ArgList[i].Attrs);
  }

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

  if (PAL.hasAttribute(1, 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(FT, AddrSpace);

  Fn = 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()) {
      Fn = M->getFunction(FunctionName);
      if (!Fn)
        return error(FRVI->second.second, "invalid forward reference to "
                                          "function as global value!");
      if (Fn->getType() != PFT)
        return error(FRVI->second.second,
                     "invalid forward reference to "
                     "function '" +
                         FunctionName +
                         "' with wrong type: "
                         "expected '" +
                         getTypeString(PFT) + "' but was '" +
                         getTypeString(Fn->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 {
    // If this is a definition of a forward referenced function, make sure the
    // types agree.
    auto I = ForwardRefValIDs.find(NumberedVals.size());
    if (I != ForwardRefValIDs.end()) {
      Fn = cast<Function>(I->second.first);
      if (Fn->getType() != PFT)
        return error(NameLoc, "type of definition and forward reference of '@" +
                                  Twine(NumberedVals.size()) +
                                  "' disagree: "
                                  "expected '" +
                                  getTypeString(PFT) + "' but was '" +
                                  getTypeString(Fn->getType()) + "'");
      ForwardRefValIDs.erase(I);
    }
  }

  if (!Fn)
    Fn = Function::Create(FT, GlobalValue::ExternalLinkage, AddrSpace,
                          FunctionName, M);
  else // Move the forward-reference to the correct spot in the module.
    M->getFunctionList().splice(M->end(), M->getFunctionList(), Fn);

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

  if (FunctionName.empty())
    NumberedVals.push_back(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);
  Fn->setAlignment(MaybeAlign(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 (IsDefine)
    return false;

  // Check the declaration has no block address forward references.
  ValID ID;
  if (FunctionName.empty()) {
    ID.Kind = ValID::t_GlobalID;
    ID.UIntVal = NumberedVals.size() - 1;
  } 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");

    GV->replaceAllUsesWith(BlockAddress::get(&F, BB));
    GV->eraseFromParent();
  }

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

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

  int FunctionNumber = -1;
  if (!Fn.hasName()) FunctionNumber = NumberedVals.size()-1;

  PerFunctionState PFS(*this, Fn, FunctionNumber);

  // Resolve block addresses and allow basic blocks to be forward-declared
  // within this function.
  if (PFS.resolveForwardRefBlockAddresses())
    return true;
  SaveAndRestore<PerFunctionState *> 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 in this block until we get a terminator.
  Instruction *Inst;
  do {
    // 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:
      BB->getInstList().push_back(Inst);

      // 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:
      BB->getInstList().push_back(Inst);

      // 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;
  } while (!Inst->isTerminator());

  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_and:
  case lltok::kw_or:
  case lltok::kw_xor:
    return parseLogical(Inst, PFS, KeywordVal);
  case lltok::kw_icmp:
    return parseCompare(Inst, PFS, KeywordVal);
  case lltok::kw_fcmp: {
    FastMathFlags FMF = EatFastMathFlagsIfPresent();
    int Res = parseCompare(Inst, PFS, KeywordVal);
    if (Res != 0)
      return Res;
    if (FMF.any())
      Inst->setFastMathFlags(FMF);
    return 0;
  }

  // Casts.
  case lltok::kw_trunc:
  case lltok::kw_zext:
  case lltok::kw_sext:
  case lltok::kw_fptrunc:
  case lltok::kw_fpext:
  case lltok::kw_bitcast:
  case lltok::kw_addrspacecast:
  case lltok::kw_uitofp:
  case lltok::kw_sitofp:
  case lltok::kw_fptoui:
  case lltok::kw_fptosi:
  case lltok::kw_inttoptr:
  case lltok::kw_ptrtoint:
    return parseCast(Inst, PFS, KeywordVal);
  // 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 (unsigned i = 0, e = Table.size(); i != e; ++i)
    SI->addCase(Table[i].first, Table[i].second);
  Inst = SI;
  return false;
}

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

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

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

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

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

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

  IndirectBrInst *IBI = IndirectBrInst::Create(Address, DestList.size());
  for (unsigned i = 0, e = DestList.size(); i != e; ++i)
    IBI->addDestination(DestList[i]);
  Inst = IBI;
  return false;
}

/// parseInvoke
///   ::= 'invoke' OptionalCallingConv OptionalAttrs Type Value ParamList
///       OptionalAttrs 'to' TypeAndValue 'unwind' TypeAndValue
bool LLParser::parseInvoke(Instruction *&Inst, PerFunctionState &PFS) {
  LocTy CallLoc = Lex.getLoc();
  AttrBuilder RetAttrs, FnAttrs;
  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) || 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 = dyn_cast<FunctionType>(RetType);
  if (!Ty) {
    // Pull out the types of all of the arguments...
    std::vector<Type*> ParamTypes;
    for (unsigned i = 0, e = ArgList.size(); i != e; ++i)
      ParamTypes.push_back(ArgList[i].V->getType());

    if (!FunctionType::isValidReturnType(RetType))
      return error(RetTypeLoc, "Invalid result type for LLVM function");

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

  CalleeID.FTy = Ty;

  // Look up the callee.
  Value *Callee;
  if (convertValIDToValue(PointerType::get(Ty, InvokeAddrSpace), CalleeID,
                          Callee, &PFS, /*IsCall=*/true))
    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 (unsigned i = 0, e = ArgList.size(); i != e; ++i) {
    Type *ExpectedTy = nullptr;
    if (I != E) {
      ExpectedTy = *I++;
    } else if (!Ty->isVarArg()) {
      return error(ArgList[i].Loc, "too many arguments specified");
    }

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

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

  if (FnAttrs.hasAlignmentAttr())
    return error(CallLoc, "invoke instructions may not have an alignment");

  // 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, FnAttrs;
  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) || 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 = dyn_cast<FunctionType>(RetType);
  if (!Ty) {
    // Pull out the types of all of the arguments...
    std::vector<Type *> ParamTypes;
    for (unsigned i = 0, e = ArgList.size(); i != e; ++i)
      ParamTypes.push_back(ArgList[i].V->getType());

    if (!FunctionType::isValidReturnType(RetType))
      return error(RetTypeLoc, "Invalid result type for LLVM function");

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

  CalleeID.FTy = Ty;

  // Look up the callee.
  Value *Callee;
  if (convertValIDToValue(PointerType::getUnqual(Ty), CalleeID, Callee, &PFS,
                          /*IsCall=*/true))
    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 (unsigned i = 0, e = ArgList.size(); i != e; ++i) {
    Type *ExpectedTy = nullptr;
    if (I != E) {
      ExpectedTy = *I++;
    } else if (!Ty->isVarArg()) {
      return error(ArgList[i].Loc, "too many arguments specified");
    }

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

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

  if (FnAttrs.hasAlignmentAttr())
    return error(CallLoc, "callbr instructions may not have an alignment");

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

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

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

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

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

  PHINode *PN = PHINode::Create(Ty, PHIVals.size());
  for (unsigned i = 0, e = PHIVals.size(); i != e; ++i)
    PN->addIncoming(PHIVals[i].first, PHIVals[i].second);
  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()))
        error(VLoc, "'catch' clause has an invalid type");
    } else {
      if (!isa<ArrayType>(V->getType()))
        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, FnAttrs;
  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) ||
      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 = dyn_cast<FunctionType>(RetType);
  if (!Ty) {
    // Pull out the types of all of the arguments...
    std::vector<Type*> ParamTypes;
    for (unsigned i = 0, e = ArgList.size(); i != e; ++i)
      ParamTypes.push_back(ArgList[i].V->getType());

    if (!FunctionType::isValidReturnType(RetType))
      return error(RetTypeLoc, "Invalid result type for LLVM function");

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

  CalleeID.FTy = Ty;

  // Look up the callee.
  Value *Callee;
  if (convertValIDToValue(PointerType::get(Ty, CallAddrSpace), CalleeID, Callee,
                          &PFS, /*IsCall=*/true))
    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 (unsigned i = 0, e = ArgList.size(); i != e; ++i) {
    Type *ExpectedTy = nullptr;
    if (I != E) {
      ExpectedTy = *I++;
    } else if (!Ty->isVarArg()) {
      return error(ArgList[i].Loc, "too many arguments specified");
    }

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

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

  if (FnAttrs.hasAlignmentAttr())
    return error(CallLoc, "call instructions may not have an alignment");

  // 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);
  }
  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");

  if (Ty != cast<PointerType>(Val->getType())->getElementType())
    return error(ExplicitTypeLoc,
                 "explicit pointee type doesn't match operand's pointee type");
  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 (cast<PointerType>(Ptr->getType())->getElementType() != Val->getType())
    return error(Loc, "stored value and pointer type do not match");
  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
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;

  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))
    return true;

  if (SuccessOrdering == AtomicOrdering::Unordered ||
      FailureOrdering == AtomicOrdering::Unordered)
    return tokError("cmpxchg cannot be unordered");
  if (isStrongerThan(FailureOrdering, SuccessOrdering))
    return tokError("cmpxchg failure argument shall be no stronger than the "
                    "success argument");
  if (FailureOrdering == AtomicOrdering::Release ||
      FailureOrdering == AtomicOrdering::AcquireRelease)
    return tokError(
        "cmpxchg failure ordering cannot include release semantics");
  if (!Ptr->getType()->isPointerTy())
    return error(PtrLoc, "cmpxchg operand must be a pointer");
  if (cast<PointerType>(Ptr->getType())->getElementType() != Cmp->getType())
    return error(CmpLoc, "compare value and pointer type do not match");
  if (cast<PointerType>(Ptr->getType())->getElementType() != New->getType())
    return error(NewLoc, "new value and pointer type do not match");
  if (!New->getType()->isFirstClassType())
    return error(NewLoc, "cmpxchg operand must be a first class value");

  Align Alignment(
      PFS.getFunction().getParent()->getDataLayout().getTypeStoreSize(
          Cmp->getType()));

  AtomicCmpXchgInst *CXI = new AtomicCmpXchgInst(
      Ptr, Cmp, New, Alignment, 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;

  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_fadd:
    Operation = AtomicRMWInst::FAdd;
    IsFP = true;
    break;
  case lltok::kw_fsub:
    Operation = AtomicRMWInst::FSub;
    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))
    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 (cast<PointerType>(Ptr->getType())->getElementType() != Val->getType())
    return error(ValLoc, "atomicrmw value and pointer type do not match");

  if (Operation == AtomicRMWInst::Xchg) {
    if (!Val->getType()->isIntegerTy() &&
        !Val->getType()->isFloatingPointTy()) {
      return error(ValLoc,
                   "atomicrmw " + AtomicRMWInst::getOperationName(Operation) +
                       " operand must be an integer or floating point type");
    }
  } else if (IsFP) {
    if (!Val->getType()->isFloatingPointTy()) {
      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 = Val->getType()->getPrimitiveSizeInBits();
  if (Size < 8 || (Size & (Size - 1)))
    return error(ValLoc, "atomicrmw operand must be power-of-two byte-sized"
                         " integer");
  Align Alignment(
      PFS.getFunction().getParent()->getDataLayout().getTypeStoreSize(
          Val->getType()));
  AtomicRMWInst *RMWI =
      new AtomicRMWInst(Operation, Ptr, Val, Alignment, 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;

  bool InBounds = EatIfPresent(lltok::kw_inbounds);

  Type *Ty = nullptr;
  LocTy ExplicitTypeLoc = Lex.getLoc();
  if (parseType(Ty) ||
      parseToken(lltok::comma, "expected comma after getelementptr's type") ||
      parseTypeAndValue(Ptr, Loc, PFS))
    return true;

  Type *BaseType = Ptr->getType();
  PointerType *BasePointerType = dyn_cast<PointerType>(BaseType->getScalarType());
  if (!BasePointerType)
    return error(Loc, "base of getelementptr must be a pointer");

  if (Ty != BasePointerType->getElementType())
    return error(ExplicitTypeLoc,
                 "explicit pointee type doesn't match operand's pointee type");

  SmallVector<Value*, 16> Indices;
  bool AteExtraComma = false;
  // GEP returns a vector of pointers if at least one of parameters is a vector.
  // All vector parameters should have the same vector width.
  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");

  if (!GetElementPtrInst::getIndexedType(Ty, Indices))
    return error(Loc, "invalid getelementptr indices");
  Inst = GetElementPtrInst::Create(Ty, Ptr, Indices);
  if (InBounds)
    cast<GetElementPtrInst>(Inst)->setIsInBounds(true);
  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' | TypeAndValue
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 {
    // Null is a special case since it is typeless.
    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->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 Lex.Error("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) ||
      parseToken(lltok::comma, "expected comma in uselistorder_bb directive") ||
      parseValID(Label) ||
      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 = Fn.UIntVal < NumberedVals.size() ? NumberedVals[Fn.UIntVal] : nullptr;
  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, ID, 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::getGUID(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::getGUID(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.
void LLParser::addGlobalValueToIndex(
    std::string Name, GlobalValue::GUID GUID, GlobalValue::LinkageTypes Linkage,
    unsigned ID, std::unique_ptr<GlobalValueSummary> Summary) {
  // 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);
      assert(GV);
      VI = Index->getOrInsertValueInfo(GV);
    } else {
      assert(
          (!GlobalValue::isLocalLinkage(Linkage) || !SourceFileName.empty()) &&
          "Need a source_filename to compute GUID for local");
      GUID = GlobalValue::getGUID(
          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;
  }
}

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

  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.
    addGlobalValueToIndex(Name, GUID, GlobalValue::ExternalLinkage, ID,
                          nullptr);
    return false;
  }

  // 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) {
  assert(Lex.getKind() == lltok::kw_function);
  Lex.Lex();

  StringRef ModulePath;
  GlobalValueSummary::GVFlags GVFlags = GlobalValueSummary::GVFlags(
      /*Linkage=*/GlobalValue::ExternalLinkage, /*NotEligibleToImport=*/false,
      /*Live=*/false, /*IsLocal=*/false, /*CanAutoHide=*/false);
  unsigned InstCount;
  std::vector<FunctionSummary::EdgeTy> Calls;
  FunctionSummary::TypeIdInfo TypeIdInfo;
  std::vector<FunctionSummary::ParamAccess> ParamAccesses;
  std::vector<ValueInfo> Refs;
  // 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;
    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, /*EntryCount=*/0, 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));

  FS->setModulePath(ModulePath);

  addGlobalValueToIndex(Name, GUID, (GlobalValue::LinkageTypes)GVFlags.Linkage,
                        ID, std::move(FS));

  return false;
}

/// VariableSummary
///   ::= 'variable' ':' '(' 'module' ':' ModuleReference ',' GVFlags
///         [',' OptionalRefs]? ')'
bool LLParser::parseVariableSummary(std::string Name, GlobalValue::GUID GUID,
                                    unsigned ID) {
  assert(Lex.getKind() == lltok::kw_variable);
  Lex.Lex();

  StringRef ModulePath;
  GlobalValueSummary::GVFlags GVFlags = GlobalValueSummary::GVFlags(
      /*Linkage=*/GlobalValue::ExternalLinkage, /*NotEligibleToImport=*/false,
      /*Live=*/false, /*IsLocal=*/false, /*CanAutoHide=*/false);
  GlobalVarSummary::GVarFlags GVarFlags(/*ReadOnly*/ false,
                                        /* WriteOnly */ false,
                                        /* Constant */ false,
                                        GlobalObject::VCallVisibilityPublic);
  std::vector<ValueInfo> 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));

  addGlobalValueToIndex(Name, GUID, (GlobalValue::LinkageTypes)GVFlags.Linkage,
                        ID, std::move(GS));

  return false;
}

/// 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(
      /*Linkage=*/GlobalValue::ExternalLinkage, /*NotEligibleToImport=*/false,
      /*Live=*/false, /*IsLocal=*/false, /*CanAutoHide=*/false);
  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);
  }

  addGlobalValueToIndex(Name, GUID, (GlobalValue::LinkageTypes)GVFlags.Linkage,
                        ID, std::move(AS));

  return false;
}

/// 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]? ')'

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;
    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 )]? ')'
bool LLParser::parseOptionalCalls(std::vector<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;
    if (EatIfPresent(lltok::comma)) {
      // Expect either hotness or relbf
      if (EatIfPresent(lltok::kw_hotness)) {
        if (parseToken(lltok::colon, "expected ':'") || parseHotness(Hotness))
          return true;
      } else {
        if (parseToken(lltok::kw_relbf, "expected relbf") ||
            parseToken(lltok::colon, "expected ':'") || parseUInt32(RelBF))
          return true;
      }
    }
    // 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, 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);
    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(std::vector<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 ','
///         '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_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;
    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()) {
    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;
}
