//===-- LLParser.cpp - Parser Class ---------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file defines the parser class for .ll files. // //===----------------------------------------------------------------------===// #include "llvm/AsmParser/LLParser.h" #include "llvm/ADT/APSInt.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/ScopeExit.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/AsmParser/LLToken.h" #include "llvm/AsmParser/SlotMapping.h" #include "llvm/BinaryFormat/Dwarf.h" #include "llvm/IR/Argument.h" #include "llvm/IR/AutoUpgrade.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/CallingConv.h" #include "llvm/IR/Comdat.h" #include "llvm/IR/ConstantRange.h" #include "llvm/IR/ConstantRangeList.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Function.h" #include "llvm/IR/GlobalIFunc.h" #include "llvm/IR/GlobalObject.h" #include "llvm/IR/InlineAsm.h" #include "llvm/IR/InstIterator.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/Intrinsics.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Metadata.h" #include "llvm/IR/Module.h" #include "llvm/IR/Operator.h" #include "llvm/IR/Value.h" #include "llvm/IR/ValueSymbolTable.h" #include "llvm/Support/Casting.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/ModRef.h" #include "llvm/Support/SaveAndRestore.h" #include "llvm/Support/raw_ostream.h" #include <algorithm> #include <cassert> #include <cstring> #include <optional> #include <vector> usingnamespacellvm; static cl::opt<bool> AllowIncompleteIR( "allow-incomplete-ir", cl::init(false), cl::Hidden, cl::desc( "Allow incomplete IR on a best effort basis (references to unknown " "metadata will be dropped)")); extern llvm::cl::opt<bool> UseNewDbgInfoFormat; extern cl::opt<cl::boolOrDefault> PreserveInputDbgFormat; extern bool WriteNewDbgInfoFormatToBitcode; extern cl::opt<bool> WriteNewDbgInfoFormat; static std::string getTypeString(Type *T) { … } /// Run: module ::= toplevelentity* bool LLParser::Run(bool UpgradeDebugInfo, DataLayoutCallbackTy DataLayoutCallback) { … } bool LLParser::parseStandaloneConstantValue(Constant *&C, const SlotMapping *Slots) { … } bool LLParser::parseTypeAtBeginning(Type *&Ty, unsigned &Read, const SlotMapping *Slots) { … } bool LLParser::parseDIExpressionBodyAtBeginning(MDNode *&Result, unsigned &Read, const SlotMapping *Slots) { … } void LLParser::restoreParsingState(const SlotMapping *Slots) { … } static void dropIntrinsicWithUnknownMetadataArgument(IntrinsicInst *II) { … } void LLParser::dropUnknownMetadataReferences() { … } /// validateEndOfModule - Do final validity and basic correctness checks at the /// end of the module. bool LLParser::validateEndOfModule(bool UpgradeDebugInfo) { … } /// Do final validity and basic correctness checks at the end of the index. bool LLParser::validateEndOfIndex() { … } //===----------------------------------------------------------------------===// // Top-Level Entities //===----------------------------------------------------------------------===// bool LLParser::parseTargetDefinitions(DataLayoutCallbackTy DataLayoutCallback) { … } bool LLParser::parseTopLevelEntities() { … } /// toplevelentity /// ::= 'module' 'asm' STRINGCONSTANT bool LLParser::parseModuleAsm() { … } /// toplevelentity /// ::= 'target' 'triple' '=' STRINGCONSTANT /// ::= 'target' 'datalayout' '=' STRINGCONSTANT bool LLParser::parseTargetDefinition(std::string &TentativeDLStr, LocTy &DLStrLoc) { … } /// toplevelentity /// ::= 'source_filename' '=' STRINGCONSTANT bool LLParser::parseSourceFileName() { … } /// parseUnnamedType: /// ::= LocalVarID '=' 'type' type bool LLParser::parseUnnamedType() { … } /// toplevelentity /// ::= LocalVar '=' 'type' type bool LLParser::parseNamedType() { … } /// toplevelentity /// ::= 'declare' FunctionHeader bool LLParser::parseDeclare() { … } /// toplevelentity /// ::= 'define' FunctionHeader (!dbg !56)* '{' ... bool LLParser::parseDefine() { … } /// parseGlobalType /// ::= 'constant' /// ::= 'global' bool LLParser::parseGlobalType(bool &IsConstant) { … } bool LLParser::parseOptionalUnnamedAddr( GlobalVariable::UnnamedAddr &UnnamedAddr) { … } /// parseUnnamedGlobal: /// OptionalVisibility (ALIAS | IFUNC) ... /// OptionalLinkage OptionalPreemptionSpecifier OptionalVisibility /// OptionalDLLStorageClass /// ... -> global variable /// GlobalID '=' OptionalVisibility (ALIAS | IFUNC) ... /// GlobalID '=' OptionalLinkage OptionalPreemptionSpecifier /// OptionalVisibility /// OptionalDLLStorageClass /// ... -> global variable bool LLParser::parseUnnamedGlobal() { … } /// parseNamedGlobal: /// GlobalVar '=' OptionalVisibility (ALIAS | IFUNC) ... /// GlobalVar '=' OptionalLinkage OptionalPreemptionSpecifier /// OptionalVisibility OptionalDLLStorageClass /// ... -> global variable bool LLParser::parseNamedGlobal() { … } bool LLParser::parseComdat() { … } // MDString: // ::= '!' STRINGCONSTANT bool LLParser::parseMDString(MDString *&Result) { … } // MDNode: // ::= '!' MDNodeNumber bool LLParser::parseMDNodeID(MDNode *&Result) { … } /// parseNamedMetadata: /// !foo = !{ !1, !2 } bool LLParser::parseNamedMetadata() { … } /// parseStandaloneMetadata: /// !42 = !{...} bool LLParser::parseStandaloneMetadata() { … } // Skips a single module summary entry. bool LLParser::skipModuleSummaryEntry() { … } /// SummaryEntry /// ::= SummaryID '=' GVEntry | ModuleEntry | TypeIdEntry bool LLParser::parseSummaryEntry() { … } static bool isValidVisibilityForLinkage(unsigned V, unsigned L) { … } static bool isValidDLLStorageClassForLinkage(unsigned S, unsigned L) { … } // 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) { … } /// parseAliasOrIFunc: /// ::= GlobalVar '=' OptionalLinkage OptionalPreemptionSpecifier /// OptionalVisibility OptionalDLLStorageClass /// OptionalThreadLocal OptionalUnnamedAddr /// 'alias|ifunc' AliaseeOrResolver SymbolAttrs* /// /// AliaseeOrResolver /// ::= TypeAndValue /// /// SymbolAttrs /// ::= ',' 'partition' StringConstant /// /// Everything through OptionalUnnamedAddr has already been parsed. /// bool LLParser::parseAliasOrIFunc(const std::string &Name, unsigned NameID, LocTy NameLoc, unsigned L, unsigned Visibility, unsigned DLLStorageClass, bool DSOLocal, GlobalVariable::ThreadLocalMode TLM, GlobalVariable::UnnamedAddr UnnamedAddr) { … } static bool isSanitizer(lltok::Kind Kind) { … } bool LLParser::parseSanitizer(GlobalVariable *GV) { … } /// parseGlobal /// ::= GlobalVar '=' OptionalLinkage OptionalPreemptionSpecifier /// OptionalVisibility OptionalDLLStorageClass /// OptionalThreadLocal OptionalUnnamedAddr OptionalAddrSpace /// OptionalExternallyInitialized GlobalType Type Const OptionalAttrs /// ::= OptionalLinkage OptionalPreemptionSpecifier OptionalVisibility /// OptionalDLLStorageClass OptionalThreadLocal OptionalUnnamedAddr /// OptionalAddrSpace OptionalExternallyInitialized GlobalType Type /// Const OptionalAttrs /// /// Everything up to and including OptionalUnnamedAddr has been parsed /// already. /// bool LLParser::parseGlobal(const std::string &Name, unsigned NameID, LocTy NameLoc, unsigned Linkage, bool HasLinkage, unsigned Visibility, unsigned DLLStorageClass, bool DSOLocal, GlobalVariable::ThreadLocalMode TLM, GlobalVariable::UnnamedAddr UnnamedAddr) { … } /// parseUnnamedAttrGrp /// ::= 'attributes' AttrGrpID '=' '{' AttrValPair+ '}' bool LLParser::parseUnnamedAttrGrp() { … } static Attribute::AttrKind tokenToAttribute(lltok::Kind Kind) { … } bool LLParser::parseEnumAttribute(Attribute::AttrKind Attr, AttrBuilder &B, bool InAttrGroup) { … } static bool upgradeMemoryAttr(MemoryEffects &ME, lltok::Kind Kind) { … } /// parseFnAttributeValuePairs /// ::= <attr> | <attr> '=' <value> bool LLParser::parseFnAttributeValuePairs(AttrBuilder &B, std::vector<unsigned> &FwdRefAttrGrps, bool InAttrGrp, LocTy &BuiltinLoc) { … } //===----------------------------------------------------------------------===// // GlobalValue Reference/Resolution Routines. //===----------------------------------------------------------------------===// static inline GlobalValue *createGlobalFwdRef(Module *M, PointerType *PTy) { … } Value *LLParser::checkValidVariableType(LocTy Loc, const Twine &Name, Type *Ty, Value *Val) { … } /// 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) { … } GlobalValue *LLParser::getGlobalVal(unsigned ID, Type *Ty, LocTy Loc) { … } //===----------------------------------------------------------------------===// // Comdat Reference/Resolution Routines. //===----------------------------------------------------------------------===// Comdat *LLParser::getComdat(const std::string &Name, LocTy Loc) { … } //===----------------------------------------------------------------------===// // 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) { … } /// parseStringConstant /// ::= StringConstant bool LLParser::parseStringConstant(std::string &Result) { … } /// parseUInt32 /// ::= uint32 bool LLParser::parseUInt32(uint32_t &Val) { … } /// parseUInt64 /// ::= uint64 bool LLParser::parseUInt64(uint64_t &Val) { … } /// parseTLSModel /// := 'localdynamic' /// := 'initialexec' /// := 'localexec' bool LLParser::parseTLSModel(GlobalVariable::ThreadLocalMode &TLM) { … } /// parseOptionalThreadLocal /// := /*empty*/ /// := 'thread_local' /// := 'thread_local' '(' tlsmodel ')' bool LLParser::parseOptionalThreadLocal(GlobalVariable::ThreadLocalMode &TLM) { … } /// parseOptionalAddrSpace /// := /*empty*/ /// := 'addrspace' '(' uint32 ')' bool LLParser::parseOptionalAddrSpace(unsigned &AddrSpace, unsigned DefaultAS) { … } /// parseStringAttribute /// := StringConstant /// := StringConstant '=' StringConstant bool LLParser::parseStringAttribute(AttrBuilder &B) { … } /// Parse a potentially empty list of parameter or return attributes. bool LLParser::parseOptionalParamOrReturnAttrs(AttrBuilder &B, bool IsParam) { … } static unsigned parseOptionalLinkageAux(lltok::Kind Kind, bool &HasLinkage) { … } /// 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) { … } void LLParser::parseOptionalDSOLocal(bool &DSOLocal) { … } /// parseOptionalVisibility /// ::= /*empty*/ /// ::= 'default' /// ::= 'hidden' /// ::= 'protected' /// void LLParser::parseOptionalVisibility(unsigned &Res) { … } bool LLParser::parseOptionalImportType(lltok::Kind Kind, GlobalValueSummary::ImportKind &Res) { … } /// parseOptionalDLLStorageClass /// ::= /*empty*/ /// ::= 'dllimport' /// ::= 'dllexport' /// void LLParser::parseOptionalDLLStorageClass(unsigned &Res) { … } /// parseOptionalCallingConv /// ::= /*empty*/ /// ::= 'ccc' /// ::= 'fastcc' /// ::= 'intel_ocl_bicc' /// ::= 'coldcc' /// ::= 'cfguard_checkcc' /// ::= 'x86_stdcallcc' /// ::= 'x86_fastcallcc' /// ::= 'x86_thiscallcc' /// ::= 'x86_vectorcallcc' /// ::= 'arm_apcscc' /// ::= 'arm_aapcscc' /// ::= 'arm_aapcs_vfpcc' /// ::= 'aarch64_vector_pcs' /// ::= 'aarch64_sve_vector_pcs' /// ::= 'aarch64_sme_preservemost_from_x0' /// ::= 'aarch64_sme_preservemost_from_x1' /// ::= 'aarch64_sme_preservemost_from_x2' /// ::= 'msp430_intrcc' /// ::= 'avr_intrcc' /// ::= 'avr_signalcc' /// ::= 'ptx_kernel' /// ::= 'ptx_device' /// ::= 'spir_func' /// ::= 'spir_kernel' /// ::= 'x86_64_sysvcc' /// ::= 'win64cc' /// ::= 'anyregcc' /// ::= 'preserve_mostcc' /// ::= 'preserve_allcc' /// ::= 'preserve_nonecc' /// ::= 'ghccc' /// ::= 'swiftcc' /// ::= 'swifttailcc' /// ::= 'x86_intrcc' /// ::= 'hhvmcc' /// ::= 'hhvm_ccc' /// ::= 'cxx_fast_tlscc' /// ::= 'amdgpu_vs' /// ::= 'amdgpu_ls' /// ::= 'amdgpu_hs' /// ::= 'amdgpu_es' /// ::= 'amdgpu_gs' /// ::= 'amdgpu_ps' /// ::= 'amdgpu_cs' /// ::= 'amdgpu_cs_chain' /// ::= 'amdgpu_cs_chain_preserve' /// ::= 'amdgpu_kernel' /// ::= 'tailcc' /// ::= 'm68k_rtdcc' /// ::= 'graalcc' /// ::= 'riscv_vector_cc' /// ::= 'cc' UINT /// bool LLParser::parseOptionalCallingConv(unsigned &CC) { … } /// parseMetadataAttachment /// ::= !dbg !42 bool LLParser::parseMetadataAttachment(unsigned &Kind, MDNode *&MD) { … } /// parseInstructionMetadata /// ::= !dbg !42 (',' !dbg !57)* bool LLParser::parseInstructionMetadata(Instruction &Inst) { … } /// parseGlobalObjectMetadataAttachment /// ::= !dbg !57 bool LLParser::parseGlobalObjectMetadataAttachment(GlobalObject &GO) { … } /// parseOptionalFunctionMetadata /// ::= (!dbg !57)* bool LLParser::parseOptionalFunctionMetadata(Function &F) { … } /// parseOptionalAlignment /// ::= /* empty */ /// ::= 'align' 4 bool LLParser::parseOptionalAlignment(MaybeAlign &Alignment, bool AllowParens) { … } /// parseOptionalCodeModel /// ::= /* empty */ /// ::= 'code_model' "large" bool LLParser::parseOptionalCodeModel(CodeModel::Model &model) { … } /// parseOptionalDerefAttrBytes /// ::= /* empty */ /// ::= AttrKind '(' 4 ')' /// /// where AttrKind is either 'dereferenceable' or 'dereferenceable_or_null'. bool LLParser::parseOptionalDerefAttrBytes(lltok::Kind AttrKind, uint64_t &Bytes) { … } bool LLParser::parseOptionalUWTableKind(UWTableKind &Kind) { … } bool LLParser::parseAllocKind(AllocFnKind &Kind) { … } static std::optional<MemoryEffects::Location> keywordToLoc(lltok::Kind Tok) { … } static std::optional<ModRefInfo> keywordToModRef(lltok::Kind Tok) { … } std::optional<MemoryEffects> LLParser::parseMemoryAttr() { … } static unsigned keywordToFPClassTest(lltok::Kind Tok) { … } unsigned LLParser::parseNoFPClassAttr() { … } /// 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) { … } /// 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) { … } bool LLParser::parseAllocSizeArguments(unsigned &BaseSizeArg, std::optional<unsigned> &HowManyArg) { … } bool LLParser::parseVScaleRangeArguments(unsigned &MinValue, unsigned &MaxValue) { … } /// 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) { … } /// parseScope /// ::= syncscope("singlethread" | "<target scope>")? /// /// This sets synchronization scope ID to the ID of the parsed value. bool LLParser::parseScope(SyncScope::ID &SSID) { … } /// parseOrdering /// ::= AtomicOrdering /// /// This sets Ordering to the parsed value. bool LLParser::parseOrdering(AtomicOrdering &Ordering) { … } /// parseOptionalStackAlignment /// ::= /* empty */ /// ::= 'alignstack' '(' 4 ')' bool LLParser::parseOptionalStackAlignment(unsigned &Alignment) { … } /// 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) { … } //===----------------------------------------------------------------------===// // Type Parsing. //===----------------------------------------------------------------------===// /// parseType - parse a type. bool LLParser::parseType(Type *&Result, const Twine &Msg, bool AllowVoid) { … } /// parseParameterList /// ::= '(' ')' /// ::= '(' Arg (',' Arg)* ')' /// Arg /// ::= Type OptionalAttributes Value OptionalAttributes bool LLParser::parseParameterList(SmallVectorImpl<ParamInfo> &ArgList, PerFunctionState &PFS, bool IsMustTailCall, bool InVarArgsFunc) { … } /// parseRequiredTypeAttr /// ::= attrname(<ty>) bool LLParser::parseRequiredTypeAttr(AttrBuilder &B, lltok::Kind AttrToken, Attribute::AttrKind AttrKind) { … } /// parseRangeAttr /// ::= range(<ty> <n>,<n>) bool LLParser::parseRangeAttr(AttrBuilder &B) { … } /// parseInitializesAttr /// ::= initializes((Lo1,Hi1),(Lo2,Hi2),...) bool LLParser::parseInitializesAttr(AttrBuilder &B) { … } /// 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) { … } bool LLParser::checkValueID(LocTy Loc, StringRef Kind, StringRef Prefix, unsigned NextID, unsigned ID) { … } /// parseArgumentList - parse the argument list for a function type or function /// prototype. /// ::= '(' ArgTypeListI ')' /// ArgTypeListI /// ::= /*empty*/ /// ::= '...' /// ::= ArgTypeList ',' '...' /// ::= ArgType (',' ArgType)* /// bool LLParser::parseArgumentList(SmallVectorImpl<ArgInfo> &ArgList, SmallVectorImpl<unsigned> &UnnamedArgNums, bool &IsVarArg) { … } /// parseFunctionType /// ::= Type ArgumentList OptionalAttrs bool LLParser::parseFunctionType(Type *&Result) { … } /// parseAnonStructType - parse an anonymous struct type, which is inlined into /// other structs. bool LLParser::parseAnonStructType(Type *&Result, bool Packed) { … } /// parseStructDefinition - parse a struct in a 'type' definition. bool LLParser::parseStructDefinition(SMLoc TypeLoc, StringRef Name, std::pair<Type *, LocTy> &Entry, Type *&ResultTy) { … } /// parseStructType: Handles packed and unpacked types. </> parsed elsewhere. /// StructType /// ::= '{' '}' /// ::= '{' Type (',' Type)* '}' /// ::= '<' '{' '}' '>' /// ::= '<' '{' Type (',' Type)* '}' '>' bool LLParser::parseStructBody(SmallVectorImpl<Type *> &Body) { … } /// 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) { … } /// parseTargetExtType - handle target extension type syntax /// TargetExtType /// ::= 'target' '(' STRINGCONSTANT TargetExtTypeParams TargetExtIntParams ')' /// /// TargetExtTypeParams /// ::= /*empty*/ /// ::= ',' Type TargetExtTypeParams /// /// TargetExtIntParams /// ::= /*empty*/ /// ::= ',' uint32 TargetExtIntParams bool LLParser::parseTargetExtType(Type *&Result) { … } //===----------------------------------------------------------------------===// // Function Semantic Analysis. //===----------------------------------------------------------------------===// LLParser::PerFunctionState::PerFunctionState(LLParser &p, Function &f, int functionNumber, ArrayRef<unsigned> UnnamedArgNums) : … { … } LLParser::PerFunctionState::~PerFunctionState() { … } bool LLParser::PerFunctionState::finishFunction() { … } /// getVal - Get a value with the specified name or ID, creating a /// forward reference record if needed. This can return null if the value /// exists but does not have the right type. Value *LLParser::PerFunctionState::getVal(const std::string &Name, Type *Ty, LocTy Loc) { … } Value *LLParser::PerFunctionState::getVal(unsigned ID, Type *Ty, LocTy Loc) { … } /// 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) { … } /// 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) { … } BasicBlock *LLParser::PerFunctionState::getBB(unsigned ID, LocTy Loc) { … } /// defineBB - Define the specified basic block, which is either named or /// unnamed. If there is an error, this returns null otherwise it returns /// the block being defined. BasicBlock *LLParser::PerFunctionState::defineBB(const std::string &Name, int NameID, LocTy Loc) { … } //===----------------------------------------------------------------------===// // Constants. //===----------------------------------------------------------------------===// /// parseValID - parse an abstract value that doesn't necessarily have a /// type implied. For example, if we parse "4" we don't know what integer type /// it has. The value will later be combined with its type and checked for /// basic correctness. PFS is used to convert function-local operands of /// metadata (since metadata operands are not just parsed here but also /// converted to values). PFS can be null when we are not parsing metadata /// values inside a function. bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS, Type *ExpectedTy) { … } /// parseGlobalValue - parse a global value with the specified type. bool LLParser::parseGlobalValue(Type *Ty, Constant *&C) { … } bool LLParser::parseGlobalTypeAndValue(Constant *&V) { … } bool LLParser::parseOptionalComdat(StringRef GlobalName, Comdat *&C) { … } /// parseGlobalValueVector /// ::= /*empty*/ /// ::= TypeAndValue (',' TypeAndValue)* bool LLParser::parseGlobalValueVector(SmallVectorImpl<Constant *> &Elts) { … } bool LLParser::parseMDTuple(MDNode *&MD, bool IsDistinct) { … } /// MDNode: /// ::= !{ ... } /// ::= !7 /// ::= !DILocation(...) bool LLParser::parseMDNode(MDNode *&N) { … } bool LLParser::parseMDNodeTail(MDNode *&N) { … } namespace { /// Structure to represent an optional metadata field. template <class FieldTy> struct MDFieldImpl { … }; /// 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 { … }; struct MDUnsignedField : public MDFieldImpl<uint64_t> { … }; struct LineField : public MDUnsignedField { … }; struct ColumnField : public MDUnsignedField { … }; struct DwarfTagField : public MDUnsignedField { … }; struct DwarfMacinfoTypeField : public MDUnsignedField { … }; struct DwarfAttEncodingField : public MDUnsignedField { … }; struct DwarfVirtualityField : public MDUnsignedField { … }; struct DwarfLangField : public MDUnsignedField { … }; struct DwarfCCField : public MDUnsignedField { … }; struct EmissionKindField : public MDUnsignedField { … }; struct NameTableKindField : public MDUnsignedField { … }; struct DIFlagField : public MDFieldImpl<DINode::DIFlags> { … }; struct DISPFlagField : public MDFieldImpl<DISubprogram::DISPFlags> { … }; struct MDAPSIntField : public MDFieldImpl<APSInt> { … }; struct MDSignedField : public MDFieldImpl<int64_t> { … }; struct MDBoolField : public MDFieldImpl<bool> { … }; struct MDField : public MDFieldImpl<Metadata *> { … }; struct MDStringField : public MDFieldImpl<MDString *> { … }; struct MDFieldList : public MDFieldImpl<SmallVector<Metadata *, 4>> { … }; struct ChecksumKindField : public MDFieldImpl<DIFile::ChecksumKind> { … }; struct MDSignedOrMDField : MDEitherFieldImpl<MDSignedField, MDField> { … }; } // end anonymous namespace namespace llvm { template <> bool LLParser::parseMDField(LocTy Loc, StringRef Name, MDAPSIntField &Result) { … } template <> bool LLParser::parseMDField(LocTy Loc, StringRef Name, MDUnsignedField &Result) { … } template <> bool LLParser::parseMDField(LocTy Loc, StringRef Name, LineField &Result) { … } template <> bool LLParser::parseMDField(LocTy Loc, StringRef Name, ColumnField &Result) { … } template <> bool LLParser::parseMDField(LocTy Loc, StringRef Name, DwarfTagField &Result) { … } template <> bool LLParser::parseMDField(LocTy Loc, StringRef Name, DwarfMacinfoTypeField &Result) { … } template <> bool LLParser::parseMDField(LocTy Loc, StringRef Name, DwarfVirtualityField &Result) { … } template <> bool LLParser::parseMDField(LocTy Loc, StringRef Name, DwarfLangField &Result) { … } template <> bool LLParser::parseMDField(LocTy Loc, StringRef Name, DwarfCCField &Result) { … } template <> bool LLParser::parseMDField(LocTy Loc, StringRef Name, EmissionKindField &Result) { … } template <> bool LLParser::parseMDField(LocTy Loc, StringRef Name, NameTableKindField &Result) { … } template <> bool LLParser::parseMDField(LocTy Loc, StringRef Name, DwarfAttEncodingField &Result) { … } /// DIFlagField /// ::= uint32 /// ::= DIFlagVector /// ::= DIFlagVector '|' DIFlagFwdDecl '|' uint32 '|' DIFlagPublic template <> bool LLParser::parseMDField(LocTy Loc, StringRef Name, DIFlagField &Result) { … } /// DISPFlagField /// ::= uint32 /// ::= DISPFlagVector /// ::= DISPFlagVector '|' DISPFlag* '|' uint32 template <> bool LLParser::parseMDField(LocTy Loc, StringRef Name, DISPFlagField &Result) { … } template <> bool LLParser::parseMDField(LocTy Loc, StringRef Name, MDSignedField &Result) { … } template <> bool LLParser::parseMDField(LocTy Loc, StringRef Name, MDBoolField &Result) { … } template <> bool LLParser::parseMDField(LocTy Loc, StringRef Name, MDField &Result) { … } template <> bool LLParser::parseMDField(LocTy Loc, StringRef Name, MDSignedOrMDField &Result) { … } template <> bool LLParser::parseMDField(LocTy Loc, StringRef Name, MDStringField &Result) { … } template <> bool LLParser::parseMDField(LocTy Loc, StringRef Name, MDFieldList &Result) { … } template <> bool LLParser::parseMDField(LocTy Loc, StringRef Name, ChecksumKindField &Result) { … } } // end namespace llvm template <class ParserTy> bool LLParser::parseMDFieldsImplBody(ParserTy ParseField) { … } template <class ParserTy> bool LLParser::parseMDFieldsImpl(ParserTy ParseField, LocTy &ClosingLoc) { … } template <class FieldTy> bool LLParser::parseMDField(StringRef Name, FieldTy &Result) { … } bool LLParser::parseSpecializedMDNode(MDNode *&N, bool IsDistinct) { … } #define DECLARE_FIELD … #define NOP_FIELD … #define REQUIRE_FIELD … #define PARSE_MD_FIELD … #define PARSE_MD_FIELDS() … #define GET_OR_DISTINCT(CLASS, ARGS) … /// parseDILocationFields: /// ::= !DILocation(line: 43, column: 8, scope: !5, inlinedAt: !6, /// isImplicitCode: true) bool LLParser::parseDILocation(MDNode *&Result, bool IsDistinct) { … } /// parseDIAssignID: /// ::= distinct !DIAssignID() bool LLParser::parseDIAssignID(MDNode *&Result, bool IsDistinct) { … } /// parseGenericDINode: /// ::= !GenericDINode(tag: 15, header: "...", operands: {...}) bool LLParser::parseGenericDINode(MDNode *&Result, bool IsDistinct) { … } /// 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) { … } /// parseDIGenericSubrange: /// ::= !DIGenericSubrange(lowerBound: !node1, upperBound: !node2, stride: /// !node3) bool LLParser::parseDIGenericSubrange(MDNode *&Result, bool IsDistinct) { … } /// parseDIEnumerator: /// ::= !DIEnumerator(value: 30, isUnsigned: true, name: "SomeKind") bool LLParser::parseDIEnumerator(MDNode *&Result, bool IsDistinct) { … } /// 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) { … } /// parseDIStringType: /// ::= !DIStringType(name: "character(4)", size: 32, align: 32) bool LLParser::parseDIStringType(MDNode *&Result, bool IsDistinct) { … } /// parseDIDerivedType: /// ::= !DIDerivedType(tag: DW_TAG_pointer_type, name: "int", file: !0, /// line: 7, scope: !1, baseType: !2, size: 32, /// align: 32, offset: 0, flags: 0, extraData: !3, /// dwarfAddressSpace: 3, ptrAuthKey: 1, /// ptrAuthIsAddressDiscriminated: true, /// ptrAuthExtraDiscriminator: 0x1234, /// ptrAuthIsaPointer: 1, ptrAuthAuthenticatesNullValues:1 /// ) bool LLParser::parseDIDerivedType(MDNode *&Result, bool IsDistinct) { … } bool LLParser::parseDICompositeType(MDNode *&Result, bool IsDistinct) { … } bool LLParser::parseDISubroutineType(MDNode *&Result, bool IsDistinct) { … } /// 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) { … } /// 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) { … } /// parseDISubprogram: /// ::= !DISubprogram(scope: !0, name: "foo", linkageName: "_Zfoo", /// file: !1, line: 7, type: !2, isLocal: false, /// isDefinition: true, scopeLine: 8, containingType: !3, /// virtuality: DW_VIRTUALTIY_pure_virtual, /// virtualIndex: 10, thisAdjustment: 4, flags: 11, /// spFlags: 10, isOptimized: false, templateParams: !4, /// declaration: !5, retainedNodes: !6, thrownTypes: !7, /// annotations: !8) bool LLParser::parseDISubprogram(MDNode *&Result, bool IsDistinct) { … } /// parseDILexicalBlock: /// ::= !DILexicalBlock(scope: !0, file: !2, line: 7, column: 9) bool LLParser::parseDILexicalBlock(MDNode *&Result, bool IsDistinct) { … } /// parseDILexicalBlockFile: /// ::= !DILexicalBlockFile(scope: !0, file: !2, discriminator: 9) bool LLParser::parseDILexicalBlockFile(MDNode *&Result, bool IsDistinct) { … } /// parseDICommonBlock: /// ::= !DICommonBlock(scope: !0, file: !2, name: "COMMON name", line: 9) bool LLParser::parseDICommonBlock(MDNode *&Result, bool IsDistinct) { … } /// parseDINamespace: /// ::= !DINamespace(scope: !0, file: !2, name: "SomeNamespace", line: 9) bool LLParser::parseDINamespace(MDNode *&Result, bool IsDistinct) { … } /// parseDIMacro: /// ::= !DIMacro(macinfo: type, line: 9, name: "SomeMacro", value: /// "SomeValue") bool LLParser::parseDIMacro(MDNode *&Result, bool IsDistinct) { … } /// parseDIMacroFile: /// ::= !DIMacroFile(line: 9, file: !2, nodes: !3) bool LLParser::parseDIMacroFile(MDNode *&Result, bool IsDistinct) { … } /// 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) { … } /// parseDITemplateTypeParameter: /// ::= !DITemplateTypeParameter(name: "Ty", type: !1, defaulted: false) bool LLParser::parseDITemplateTypeParameter(MDNode *&Result, bool IsDistinct) { … } /// parseDITemplateValueParameter: /// ::= !DITemplateValueParameter(tag: DW_TAG_template_value_parameter, /// name: "V", type: !1, defaulted: false, /// value: i32 7) bool LLParser::parseDITemplateValueParameter(MDNode *&Result, bool IsDistinct) { … } /// 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) { … } /// 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) { … } /// parseDILabel: /// ::= !DILabel(scope: !0, name: "foo", file: !1, line: 7) bool LLParser::parseDILabel(MDNode *&Result, bool IsDistinct) { … } /// parseDIExpressionBody: /// ::= (0, 7, -1) bool LLParser::parseDIExpressionBody(MDNode *&Result, bool IsDistinct) { … } /// parseDIExpression: /// ::= !DIExpression(0, 7, -1) bool LLParser::parseDIExpression(MDNode *&Result, bool IsDistinct) { … } /// ParseDIArgList: /// ::= !DIArgList(i32 7, i64 %0) bool LLParser::parseDIArgList(Metadata *&MD, PerFunctionState *PFS) { … } /// parseDIGlobalVariableExpression: /// ::= !DIGlobalVariableExpression(var: !0, expr: !1) bool LLParser::parseDIGlobalVariableExpression(MDNode *&Result, bool IsDistinct) { … } /// parseDIObjCProperty: /// ::= !DIObjCProperty(name: "foo", file: !1, line: 7, setter: "setFoo", /// getter: "getFoo", attributes: 7, type: !2) bool LLParser::parseDIObjCProperty(MDNode *&Result, bool IsDistinct) { … } /// parseDIImportedEntity: /// ::= !DIImportedEntity(tag: DW_TAG_imported_module, scope: !0, entity: !1, /// line: 7, name: "foo", elements: !2) bool LLParser::parseDIImportedEntity(MDNode *&Result, bool IsDistinct) { … } #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) { … } /// parseValueAsMetadata /// ::= i32 %local /// ::= i32 @global /// ::= i32 7 bool LLParser::parseValueAsMetadata(Metadata *&MD, const Twine &TypeMsg, PerFunctionState *PFS) { … } /// parseMetadata /// ::= i32 %local /// ::= i32 @global /// ::= i32 7 /// ::= !42 /// ::= !{...} /// ::= !"string" /// ::= !DILocation(...) bool LLParser::parseMetadata(Metadata *&MD, PerFunctionState *PFS) { … } //===----------------------------------------------------------------------===// // Function Parsing. //===----------------------------------------------------------------------===// bool LLParser::convertValIDToValue(Type *Ty, ValID &ID, Value *&V, PerFunctionState *PFS) { … } bool LLParser::parseConstantValue(Type *Ty, Constant *&C) { … } bool LLParser::parseValue(Type *Ty, Value *&V, PerFunctionState *PFS) { … } bool LLParser::parseTypeAndValue(Value *&V, PerFunctionState *PFS) { … } bool LLParser::parseTypeAndBasicBlock(BasicBlock *&BB, LocTy &Loc, PerFunctionState &PFS) { … } bool isOldDbgFormatIntrinsic(StringRef Name) { … } /// FunctionHeader /// ::= OptionalLinkage OptionalPreemptionSpecifier OptionalVisibility /// OptionalCallingConv OptRetAttrs OptUnnamedAddr Type GlobalName /// '(' ArgList ')' OptAddrSpace OptFuncAttrs OptSection OptionalAlign /// OptGC OptionalPrefix OptionalPrologue OptPersonalityFn bool LLParser::parseFunctionHeader(Function *&Fn, bool IsDefine, unsigned &FunctionNumber, SmallVectorImpl<unsigned> &UnnamedArgNums) { … } bool LLParser::PerFunctionState::resolveForwardRefBlockAddresses() { … } /// parseFunctionBody /// ::= '{' BasicBlock+ UseListOrderDirective* '}' bool LLParser::parseFunctionBody(Function &Fn, unsigned FunctionNumber, ArrayRef<unsigned> UnnamedArgNums) { … } /// parseBasicBlock /// ::= (LabelStr|LabelID)? Instruction* bool LLParser::parseBasicBlock(PerFunctionState &PFS) { … } /// parseDebugRecord /// ::= #dbg_label '(' MDNode ')' /// ::= #dbg_type '(' Metadata ',' MDNode ',' Metadata ',' /// (MDNode ',' Metadata ',' Metadata ',')? MDNode ')' bool LLParser::parseDebugRecord(DbgRecord *&DR, PerFunctionState &PFS) { … } //===----------------------------------------------------------------------===// // Instruction Parsing. //===----------------------------------------------------------------------===// /// parseInstruction - parse one of the many different instructions. /// int LLParser::parseInstruction(Instruction *&Inst, BasicBlock *BB, PerFunctionState &PFS) { … } /// parseCmpPredicate - parse an integer or fp predicate, based on Kind. bool LLParser::parseCmpPredicate(unsigned &P, unsigned Opc) { … } //===----------------------------------------------------------------------===// // Terminator Instructions. //===----------------------------------------------------------------------===// /// parseRet - parse a return instruction. /// ::= 'ret' void (',' !dbg, !1)* /// ::= 'ret' TypeAndValue (',' !dbg, !1)* bool LLParser::parseRet(Instruction *&Inst, BasicBlock *BB, PerFunctionState &PFS) { … } /// parseBr /// ::= 'br' TypeAndValue /// ::= 'br' TypeAndValue ',' TypeAndValue ',' TypeAndValue bool LLParser::parseBr(Instruction *&Inst, PerFunctionState &PFS) { … } /// parseSwitch /// Instruction /// ::= 'switch' TypeAndValue ',' TypeAndValue '[' JumpTable ']' /// JumpTable /// ::= (TypeAndValue ',' TypeAndValue)* bool LLParser::parseSwitch(Instruction *&Inst, PerFunctionState &PFS) { … } /// parseIndirectBr /// Instruction /// ::= 'indirectbr' TypeAndValue ',' '[' LabelList ']' bool LLParser::parseIndirectBr(Instruction *&Inst, PerFunctionState &PFS) { … } // If RetType is a non-function pointer type, then this is the short syntax // for the call, which means that RetType is just the return type. Infer the // rest of the function argument types from the arguments that are present. bool LLParser::resolveFunctionType(Type *RetType, ArrayRef<ParamInfo> ArgList, FunctionType *&FuncTy) { … } /// parseInvoke /// ::= 'invoke' OptionalCallingConv OptionalAttrs Type Value ParamList /// OptionalAttrs 'to' TypeAndValue 'unwind' TypeAndValue bool LLParser::parseInvoke(Instruction *&Inst, PerFunctionState &PFS) { … } /// parseResume /// ::= 'resume' TypeAndValue bool LLParser::parseResume(Instruction *&Inst, PerFunctionState &PFS) { … } bool LLParser::parseExceptionArgs(SmallVectorImpl<Value *> &Args, PerFunctionState &PFS) { … } /// parseCleanupRet /// ::= 'cleanupret' from Value unwind ('to' 'caller' | TypeAndValue) bool LLParser::parseCleanupRet(Instruction *&Inst, PerFunctionState &PFS) { … } /// parseCatchRet /// ::= 'catchret' from Parent Value 'to' TypeAndValue bool LLParser::parseCatchRet(Instruction *&Inst, PerFunctionState &PFS) { … } /// parseCatchSwitch /// ::= 'catchswitch' within Parent bool LLParser::parseCatchSwitch(Instruction *&Inst, PerFunctionState &PFS) { … } /// parseCatchPad /// ::= 'catchpad' ParamList 'to' TypeAndValue 'unwind' TypeAndValue bool LLParser::parseCatchPad(Instruction *&Inst, PerFunctionState &PFS) { … } /// parseCleanupPad /// ::= 'cleanuppad' within Parent ParamList bool LLParser::parseCleanupPad(Instruction *&Inst, PerFunctionState &PFS) { … } //===----------------------------------------------------------------------===// // 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) { … } /// parseCallBr /// ::= 'callbr' OptionalCallingConv OptionalAttrs Type Value ParamList /// OptionalAttrs OptionalOperandBundles 'to' TypeAndValue /// '[' LabelList ']' bool LLParser::parseCallBr(Instruction *&Inst, PerFunctionState &PFS) { … } //===----------------------------------------------------------------------===// // 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) { … } /// parseLogical /// ::= ArithmeticOps TypeAndValue ',' Value { bool LLParser::parseLogical(Instruction *&Inst, PerFunctionState &PFS, unsigned Opc) { … } /// parseCompare /// ::= 'icmp' IPredicates TypeAndValue ',' Value /// ::= 'fcmp' FPredicates TypeAndValue ',' Value bool LLParser::parseCompare(Instruction *&Inst, PerFunctionState &PFS, unsigned Opc) { … } //===----------------------------------------------------------------------===// // Other Instructions. //===----------------------------------------------------------------------===// /// parseCast /// ::= CastOpc TypeAndValue 'to' Type bool LLParser::parseCast(Instruction *&Inst, PerFunctionState &PFS, unsigned Opc) { … } /// parseSelect /// ::= 'select' TypeAndValue ',' TypeAndValue ',' TypeAndValue bool LLParser::parseSelect(Instruction *&Inst, PerFunctionState &PFS) { … } /// parseVAArg /// ::= 'va_arg' TypeAndValue ',' Type bool LLParser::parseVAArg(Instruction *&Inst, PerFunctionState &PFS) { … } /// parseExtractElement /// ::= 'extractelement' TypeAndValue ',' TypeAndValue bool LLParser::parseExtractElement(Instruction *&Inst, PerFunctionState &PFS) { … } /// parseInsertElement /// ::= 'insertelement' TypeAndValue ',' TypeAndValue ',' TypeAndValue bool LLParser::parseInsertElement(Instruction *&Inst, PerFunctionState &PFS) { … } /// parseShuffleVector /// ::= 'shufflevector' TypeAndValue ',' TypeAndValue ',' TypeAndValue bool LLParser::parseShuffleVector(Instruction *&Inst, PerFunctionState &PFS) { … } /// parsePHI /// ::= 'phi' Type '[' Value ',' Value ']' (',' '[' Value ',' Value ']')* int LLParser::parsePHI(Instruction *&Inst, PerFunctionState &PFS) { … } /// parseLandingPad /// ::= 'landingpad' Type 'personality' TypeAndValue 'cleanup'? Clause+ /// Clause /// ::= 'catch' TypeAndValue /// ::= 'filter' /// ::= 'filter' TypeAndValue ( ',' TypeAndValue )* bool LLParser::parseLandingPad(Instruction *&Inst, PerFunctionState &PFS) { … } /// parseFreeze /// ::= 'freeze' Type Value bool LLParser::parseFreeze(Instruction *&Inst, PerFunctionState &PFS) { … } /// 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) { … } //===----------------------------------------------------------------------===// // Memory Instructions. //===----------------------------------------------------------------------===// /// parseAlloc /// ::= 'alloca' 'inalloca'? 'swifterror'? Type (',' TypeAndValue)? /// (',' 'align' i32)? (',', 'addrspace(n))? int LLParser::parseAlloc(Instruction *&Inst, PerFunctionState &PFS) { … } /// parseLoad /// ::= 'load' 'volatile'? TypeAndValue (',' 'align' i32)? /// ::= 'load' 'atomic' 'volatile'? TypeAndValue /// 'singlethread'? AtomicOrdering (',' 'align' i32)? int LLParser::parseLoad(Instruction *&Inst, PerFunctionState &PFS) { … } /// parseStore /// ::= 'store' 'volatile'? TypeAndValue ',' TypeAndValue (',' 'align' i32)? /// ::= 'store' 'atomic' 'volatile'? TypeAndValue ',' TypeAndValue /// 'singlethread'? AtomicOrdering (',' 'align' i32)? int LLParser::parseStore(Instruction *&Inst, PerFunctionState &PFS) { … } /// parseCmpXchg /// ::= 'cmpxchg' 'weak'? 'volatile'? TypeAndValue ',' TypeAndValue ',' /// TypeAndValue 'singlethread'? AtomicOrdering AtomicOrdering ',' /// 'Align'? int LLParser::parseCmpXchg(Instruction *&Inst, PerFunctionState &PFS) { … } /// parseAtomicRMW /// ::= 'atomicrmw' 'volatile'? BinOp TypeAndValue ',' TypeAndValue /// 'singlethread'? AtomicOrdering int LLParser::parseAtomicRMW(Instruction *&Inst, PerFunctionState &PFS) { … } /// parseFence /// ::= 'fence' 'singlethread'? AtomicOrdering int LLParser::parseFence(Instruction *&Inst, PerFunctionState &PFS) { … } /// parseGetElementPtr /// ::= 'getelementptr' 'inbounds'? TypeAndValue (',' TypeAndValue)* int LLParser::parseGetElementPtr(Instruction *&Inst, PerFunctionState &PFS) { … } /// parseExtractValue /// ::= 'extractvalue' TypeAndValue (',' uint32)+ int LLParser::parseExtractValue(Instruction *&Inst, PerFunctionState &PFS) { … } /// parseInsertValue /// ::= 'insertvalue' TypeAndValue ',' TypeAndValue (',' uint32)+ int LLParser::parseInsertValue(Instruction *&Inst, PerFunctionState &PFS) { … } //===----------------------------------------------------------------------===// // Embedded metadata. //===----------------------------------------------------------------------===// /// parseMDNodeVector /// ::= { Element (',' Element)* } /// Element /// ::= 'null' | Metadata bool LLParser::parseMDNodeVector(SmallVectorImpl<Metadata *> &Elts) { … } //===----------------------------------------------------------------------===// // Use-list order directives. //===----------------------------------------------------------------------===// bool LLParser::sortUseListOrder(Value *V, ArrayRef<unsigned> Indexes, SMLoc Loc) { … } /// parseUseListOrderIndexes /// ::= '{' uint32 (',' uint32)+ '}' bool LLParser::parseUseListOrderIndexes(SmallVectorImpl<unsigned> &Indexes) { … } /// parseUseListOrder /// ::= 'uselistorder' Type Value ',' UseListOrderIndexes bool LLParser::parseUseListOrder(PerFunctionState *PFS) { … } /// parseUseListOrderBB /// ::= 'uselistorder_bb' @foo ',' %bar ',' UseListOrderIndexes bool LLParser::parseUseListOrderBB() { … } /// ModuleEntry /// ::= 'module' ':' '(' 'path' ':' STRINGCONSTANT ',' 'hash' ':' Hash ')' /// Hash ::= '(' UInt32 ',' UInt32 ',' UInt32 ',' UInt32 ',' UInt32 ')' bool LLParser::parseModuleEntry(unsigned ID) { … } /// TypeIdEntry /// ::= 'typeid' ':' '(' 'name' ':' STRINGCONSTANT ',' TypeIdSummary ')' bool LLParser::parseTypeIdEntry(unsigned ID) { … } /// TypeIdSummary /// ::= 'summary' ':' '(' TypeTestResolution [',' OptionalWpdResolutions]? ')' bool LLParser::parseTypeIdSummary(TypeIdSummary &TIS) { … } static ValueInfo EmptyVI = …; /// TypeIdCompatibleVtableEntry /// ::= 'typeidCompatibleVTable' ':' '(' 'name' ':' STRINGCONSTANT ',' /// TypeIdCompatibleVtableInfo /// ')' bool LLParser::parseTypeIdCompatibleVtableEntry(unsigned ID) { … } /// TypeTestResolution /// ::= 'typeTestRes' ':' '(' 'kind' ':' /// ( 'unsat' | 'byteArray' | 'inline' | 'single' | 'allOnes' ) ',' /// 'sizeM1BitWidth' ':' SizeM1BitWidth [',' 'alignLog2' ':' UInt64]? /// [',' 'sizeM1' ':' UInt64]? [',' 'bitMask' ':' UInt8]? /// [',' 'inlinesBits' ':' UInt64]? ')' bool LLParser::parseTypeTestResolution(TypeTestResolution &TTRes) { … } /// OptionalWpdResolutions /// ::= 'wpsResolutions' ':' '(' WpdResolution [',' WpdResolution]* ')' /// WpdResolution ::= '(' 'offset' ':' UInt64 ',' WpdRes ')' bool LLParser::parseOptionalWpdResolutions( std::map<uint64_t, WholeProgramDevirtResolution> &WPDResMap) { … } /// WpdRes /// ::= 'wpdRes' ':' '(' 'kind' ':' 'indir' /// [',' OptionalResByArg]? ')' /// ::= 'wpdRes' ':' '(' 'kind' ':' 'singleImpl' /// ',' 'singleImplName' ':' STRINGCONSTANT ',' /// [',' OptionalResByArg]? ')' /// ::= 'wpdRes' ':' '(' 'kind' ':' 'branchFunnel' /// [',' OptionalResByArg]? ')' bool LLParser::parseWpdRes(WholeProgramDevirtResolution &WPDRes) { … } /// 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) { … } /// OptionalResByArg /// ::= 'args' ':' '(' UInt64[, UInt64]* ')' bool LLParser::parseArgs(std::vector<uint64_t> &Args) { … } static const auto FwdVIRef = …; static void resolveFwdRef(ValueInfo *Fwd, ValueInfo &Resolved) { … } /// Stores the given Name/GUID and associated summary into the Index. /// Also updates any forward references to the associated entry ID. bool LLParser::addGlobalValueToIndex( std::string Name, GlobalValue::GUID GUID, GlobalValue::LinkageTypes Linkage, unsigned ID, std::unique_ptr<GlobalValueSummary> Summary, LocTy Loc) { … } /// parseSummaryIndexFlags /// ::= 'flags' ':' UInt64 bool LLParser::parseSummaryIndexFlags() { … } /// parseBlockCount /// ::= 'blockcount' ':' UInt64 bool LLParser::parseBlockCount() { … } /// parseGVEntry /// ::= 'gv' ':' '(' ('name' ':' STRINGCONSTANT | 'guid' ':' UInt64) /// [',' 'summaries' ':' Summary[',' Summary]* ]? ')' /// Summary ::= '(' (FunctionSummary | VariableSummary | AliasSummary) ')' bool LLParser::parseGVEntry(unsigned ID) { … } /// FunctionSummary /// ::= 'function' ':' '(' 'module' ':' ModuleReference ',' GVFlags /// ',' 'insts' ':' UInt32 [',' OptionalFFlags]? [',' OptionalCalls]? /// [',' OptionalTypeIdInfo]? [',' OptionalParamAccesses]? /// [',' OptionalRefs]? ')' bool LLParser::parseFunctionSummary(std::string Name, GlobalValue::GUID GUID, unsigned ID) { … } /// VariableSummary /// ::= 'variable' ':' '(' 'module' ':' ModuleReference ',' GVFlags /// [',' OptionalRefs]? ')' bool LLParser::parseVariableSummary(std::string Name, GlobalValue::GUID GUID, unsigned ID) { … } /// AliasSummary /// ::= 'alias' ':' '(' 'module' ':' ModuleReference ',' GVFlags ',' /// 'aliasee' ':' GVReference ')' bool LLParser::parseAliasSummary(std::string Name, GlobalValue::GUID GUID, unsigned ID) { … } /// Flag /// ::= [0|1] bool LLParser::parseFlag(unsigned &Val) { … } /// OptionalFFlags /// := 'funcFlags' ':' '(' ['readNone' ':' Flag]? /// [',' 'readOnly' ':' Flag]? [',' 'noRecurse' ':' Flag]? /// [',' 'returnDoesNotAlias' ':' Flag]? ')' /// [',' 'noInline' ':' Flag]? ')' /// [',' 'alwaysInline' ':' Flag]? ')' /// [',' 'noUnwind' ':' Flag]? ')' /// [',' 'mayThrow' ':' Flag]? ')' /// [',' 'hasUnknownCall' ':' Flag]? ')' /// [',' 'mustBeUnreachable' ':' Flag]? ')' bool LLParser::parseOptionalFFlags(FunctionSummary::FFlags &FFlags) { … } /// OptionalCalls /// := 'calls' ':' '(' Call [',' Call]* ')' /// Call ::= '(' 'callee' ':' GVReference /// [( ',' 'hotness' ':' Hotness | ',' 'relbf' ':' UInt32 )]? /// [ ',' 'tail' ]? ')' bool LLParser::parseOptionalCalls( SmallVectorImpl<FunctionSummary::EdgeTy> &Calls) { … } /// Hotness /// := ('unknown'|'cold'|'none'|'hot'|'critical') bool LLParser::parseHotness(CalleeInfo::HotnessType &Hotness) { … } /// OptionalVTableFuncs /// := 'vTableFuncs' ':' '(' VTableFunc [',' VTableFunc]* ')' /// VTableFunc ::= '(' 'virtFunc' ':' GVReference ',' 'offset' ':' UInt64 ')' bool LLParser::parseOptionalVTableFuncs(VTableFuncList &VTableFuncs) { … } /// ParamNo := 'param' ':' UInt64 bool LLParser::parseParamNo(uint64_t &ParamNo) { … } /// ParamAccessOffset := 'offset' ':' '[' APSINTVAL ',' APSINTVAL ']' bool LLParser::parseParamAccessOffset(ConstantRange &Range) { … } /// ParamAccessCall /// := '(' 'callee' ':' GVReference ',' ParamNo ',' ParamAccessOffset ')' bool LLParser::parseParamAccessCall(FunctionSummary::ParamAccess::Call &Call, IdLocListType &IdLocList) { … } /// ParamAccess /// := '(' ParamNo ',' ParamAccessOffset [',' OptionalParamAccessCalls]? ')' /// OptionalParamAccessCalls := '(' Call [',' Call]* ')' bool LLParser::parseParamAccess(FunctionSummary::ParamAccess &Param, IdLocListType &IdLocList) { … } /// OptionalParamAccesses /// := 'params' ':' '(' ParamAccess [',' ParamAccess]* ')' bool LLParser::parseOptionalParamAccesses( std::vector<FunctionSummary::ParamAccess> &Params) { … } /// OptionalRefs /// := 'refs' ':' '(' GVReference [',' GVReference]* ')' bool LLParser::parseOptionalRefs(SmallVectorImpl<ValueInfo> &Refs) { … } /// OptionalTypeIdInfo /// := 'typeidinfo' ':' '(' [',' TypeTests]? [',' TypeTestAssumeVCalls]? /// [',' TypeCheckedLoadVCalls]? [',' TypeTestAssumeConstVCalls]? /// [',' TypeCheckedLoadConstVCalls]? ')' bool LLParser::parseOptionalTypeIdInfo( FunctionSummary::TypeIdInfo &TypeIdInfo) { … } /// TypeTests /// ::= 'typeTests' ':' '(' (SummaryID | UInt64) /// [',' (SummaryID | UInt64)]* ')' bool LLParser::parseTypeTests(std::vector<GlobalValue::GUID> &TypeTests) { … } /// VFuncIdList /// ::= Kind ':' '(' VFuncId [',' VFuncId]* ')' bool LLParser::parseVFuncIdList( lltok::Kind Kind, std::vector<FunctionSummary::VFuncId> &VFuncIdList) { … } /// ConstVCallList /// ::= Kind ':' '(' ConstVCall [',' ConstVCall]* ')' bool LLParser::parseConstVCallList( lltok::Kind Kind, std::vector<FunctionSummary::ConstVCall> &ConstVCallList) { … } /// ConstVCall /// ::= '(' VFuncId ',' Args ')' bool LLParser::parseConstVCall(FunctionSummary::ConstVCall &ConstVCall, IdToIndexMapType &IdToIndexMap, unsigned Index) { … } /// VFuncId /// ::= 'vFuncId' ':' '(' (SummaryID | 'guid' ':' UInt64) ',' /// 'offset' ':' UInt64 ')' bool LLParser::parseVFuncId(FunctionSummary::VFuncId &VFuncId, IdToIndexMapType &IdToIndexMap, unsigned Index) { … } /// GVFlags /// ::= 'flags' ':' '(' 'linkage' ':' OptionalLinkageAux ',' /// 'visibility' ':' Flag 'notEligibleToImport' ':' Flag ',' /// 'live' ':' Flag ',' 'dsoLocal' ':' Flag ',' /// 'canAutoHide' ':' Flag ',' ')' bool LLParser::parseGVFlags(GlobalValueSummary::GVFlags &GVFlags) { … } /// GVarFlags /// ::= 'varFlags' ':' '(' 'readonly' ':' Flag /// ',' 'writeonly' ':' Flag /// ',' 'constant' ':' Flag ')' bool LLParser::parseGVarFlags(GlobalVarSummary::GVarFlags &GVarFlags) { … } /// ModuleReference /// ::= 'module' ':' UInt bool LLParser::parseModuleReference(StringRef &ModulePath) { … } /// GVReference /// ::= SummaryID bool LLParser::parseGVReference(ValueInfo &VI, unsigned &GVId) { … } /// OptionalAllocs /// := 'allocs' ':' '(' Alloc [',' Alloc]* ')' /// Alloc ::= '(' 'versions' ':' '(' Version [',' Version]* ')' /// ',' MemProfs ')' /// Version ::= UInt32 bool LLParser::parseOptionalAllocs(std::vector<AllocInfo> &Allocs) { … } /// MemProfs /// := 'memProf' ':' '(' MemProf [',' MemProf]* ')' /// MemProf ::= '(' 'type' ':' AllocType /// ',' 'stackIds' ':' '(' StackId [',' StackId]* ')' ')' /// StackId ::= UInt64 bool LLParser::parseMemProfs(std::vector<MIBInfo> &MIBs) { … } /// AllocType /// := ('none'|'notcold'|'cold'|'hot') bool LLParser::parseAllocType(uint8_t &AllocType) { … } /// OptionalCallsites /// := 'callsites' ':' '(' Callsite [',' Callsite]* ')' /// Callsite ::= '(' 'callee' ':' GVReference /// ',' 'clones' ':' '(' Version [',' Version]* ')' /// ',' 'stackIds' ':' '(' StackId [',' StackId]* ')' ')' /// Version ::= UInt32 /// StackId ::= UInt64 bool LLParser::parseOptionalCallsites(std::vector<CallsiteInfo> &Callsites) { … }