Date: Fri, 20 Dec 2019 21:56:45 +0000 (UTC) From: Dimitry Andric <dim@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-vendor@freebsd.org Subject: svn commit: r355963 - in vendor/llvm-project/llvmorg-9.0.1: . clang/include/clang/CodeGen clang/lib/AST clang/lib/CodeGen clang/lib/Driver/ToolChains clang/lib/Sema compiler-rt/lib/profile lld/COFF... Message-ID: <201912202156.xBKLujoQ016624@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: dim Date: Fri Dec 20 21:56:45 2019 New Revision: 355963 URL: https://svnweb.freebsd.org/changeset/base/355963 Log: Tag vendor import of llvm-project llvmorg-9.0.1. Added: vendor/llvm-project/llvmorg-9.0.1/ - copied from r355955, vendor/llvm-project/release-9.x/ vendor/llvm-project/llvmorg-9.0.1/lldb/source/Plugins/ScriptInterpreter/Python/PythonReadline.cpp - copied unchanged from r355961, vendor/llvm-project/release-9.x/lldb/source/Plugins/ScriptInterpreter/Python/PythonReadline.cpp vendor/llvm-project/llvmorg-9.0.1/lldb/source/Plugins/ScriptInterpreter/Python/PythonReadline.h - copied unchanged from r355961, vendor/llvm-project/release-9.x/lldb/source/Plugins/ScriptInterpreter/Python/PythonReadline.h Replaced: vendor/llvm-project/llvmorg-9.0.1/clang/include/clang/CodeGen/CGFunctionInfo.h - copied unchanged from r355961, vendor/llvm-project/release-9.x/clang/include/clang/CodeGen/CGFunctionInfo.h vendor/llvm-project/llvmorg-9.0.1/clang/lib/AST/ExprConstant.cpp - copied unchanged from r355961, vendor/llvm-project/release-9.x/clang/lib/AST/ExprConstant.cpp vendor/llvm-project/llvmorg-9.0.1/clang/lib/CodeGen/CGExpr.cpp - copied unchanged from r355961, vendor/llvm-project/release-9.x/clang/lib/CodeGen/CGExpr.cpp vendor/llvm-project/llvmorg-9.0.1/clang/lib/CodeGen/MicrosoftCXXABI.cpp - copied unchanged from r355961, vendor/llvm-project/release-9.x/clang/lib/CodeGen/MicrosoftCXXABI.cpp vendor/llvm-project/llvmorg-9.0.1/clang/lib/Driver/ToolChains/Linux.cpp - copied unchanged from r355961, vendor/llvm-project/release-9.x/clang/lib/Driver/ToolChains/Linux.cpp vendor/llvm-project/llvmorg-9.0.1/clang/lib/Sema/SemaDecl.cpp - copied unchanged from r355961, vendor/llvm-project/release-9.x/clang/lib/Sema/SemaDecl.cpp vendor/llvm-project/llvmorg-9.0.1/clang/lib/Sema/SemaType.cpp - copied unchanged from r355961, vendor/llvm-project/release-9.x/clang/lib/Sema/SemaType.cpp vendor/llvm-project/llvmorg-9.0.1/compiler-rt/lib/profile/InstrProfilingUtil.c - copied unchanged from r355961, vendor/llvm-project/release-9.x/compiler-rt/lib/profile/InstrProfilingUtil.c vendor/llvm-project/llvmorg-9.0.1/lld/COFF/Driver.cpp - copied unchanged from r355961, vendor/llvm-project/release-9.x/lld/COFF/Driver.cpp vendor/llvm-project/llvmorg-9.0.1/lld/ELF/Symbols.h - copied unchanged from r355961, vendor/llvm-project/release-9.x/lld/ELF/Symbols.h vendor/llvm-project/llvmorg-9.0.1/lld/docs/ReleaseNotes.rst - copied unchanged from r355961, vendor/llvm-project/release-9.x/lld/docs/ReleaseNotes.rst vendor/llvm-project/llvmorg-9.0.1/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp - copied unchanged from r355961, vendor/llvm-project/release-9.x/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp vendor/llvm-project/llvmorg-9.0.1/lldb/source/Symbol/Symtab.cpp - copied unchanged from r355961, vendor/llvm-project/release-9.x/lldb/source/Symbol/Symtab.cpp vendor/llvm-project/llvmorg-9.0.1/llvm/include/llvm/CodeGen/MachineFunction.h - copied unchanged from r355961, vendor/llvm-project/release-9.x/llvm/include/llvm/CodeGen/MachineFunction.h vendor/llvm-project/llvmorg-9.0.1/llvm/include/llvm/CodeGen/MachineInstr.h - copied unchanged from r355961, vendor/llvm-project/release-9.x/llvm/include/llvm/CodeGen/MachineInstr.h vendor/llvm-project/llvmorg-9.0.1/llvm/include/llvm/CodeGen/StackProtector.h - copied unchanged from r355961, vendor/llvm-project/release-9.x/llvm/include/llvm/CodeGen/StackProtector.h vendor/llvm-project/llvmorg-9.0.1/llvm/include/llvm/Demangle/MicrosoftDemangleNodes.h - copied unchanged from r355961, vendor/llvm-project/release-9.x/llvm/include/llvm/Demangle/MicrosoftDemangleNodes.h vendor/llvm-project/llvmorg-9.0.1/llvm/include/llvm/Transforms/Scalar/GVN.h - copied unchanged from r355961, vendor/llvm-project/release-9.x/llvm/include/llvm/Transforms/Scalar/GVN.h vendor/llvm-project/llvmorg-9.0.1/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp - copied unchanged from r355961, vendor/llvm-project/release-9.x/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp vendor/llvm-project/llvmorg-9.0.1/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h - copied unchanged from r355961, vendor/llvm-project/release-9.x/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h vendor/llvm-project/llvmorg-9.0.1/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp - copied unchanged from r355961, vendor/llvm-project/release-9.x/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp vendor/llvm-project/llvmorg-9.0.1/llvm/lib/CodeGen/MachineFunction.cpp - copied unchanged from r355961, vendor/llvm-project/release-9.x/llvm/lib/CodeGen/MachineFunction.cpp vendor/llvm-project/llvmorg-9.0.1/llvm/lib/CodeGen/MachineInstr.cpp - copied unchanged from r355961, vendor/llvm-project/release-9.x/llvm/lib/CodeGen/MachineInstr.cpp vendor/llvm-project/llvmorg-9.0.1/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp - copied unchanged from r355961, vendor/llvm-project/release-9.x/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp vendor/llvm-project/llvmorg-9.0.1/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp - copied unchanged from r355961, vendor/llvm-project/release-9.x/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp vendor/llvm-project/llvmorg-9.0.1/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp - copied unchanged from r355961, vendor/llvm-project/release-9.x/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp vendor/llvm-project/llvmorg-9.0.1/llvm/lib/CodeGen/StackProtector.cpp - copied unchanged from r355961, vendor/llvm-project/release-9.x/llvm/lib/CodeGen/StackProtector.cpp vendor/llvm-project/llvmorg-9.0.1/llvm/lib/Support/ARMTargetParser.cpp - copied unchanged from r355961, vendor/llvm-project/release-9.x/llvm/lib/Support/ARMTargetParser.cpp vendor/llvm-project/llvmorg-9.0.1/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp - copied unchanged from r355961, vendor/llvm-project/release-9.x/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp vendor/llvm-project/llvmorg-9.0.1/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.cpp - copied unchanged from r355961, vendor/llvm-project/release-9.x/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.cpp vendor/llvm-project/llvmorg-9.0.1/llvm/lib/Target/ARM/ARM.td - copied unchanged from r355961, vendor/llvm-project/release-9.x/llvm/lib/Target/ARM/ARM.td vendor/llvm-project/llvmorg-9.0.1/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp - copied unchanged from r355961, vendor/llvm-project/release-9.x/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp vendor/llvm-project/llvmorg-9.0.1/llvm/lib/Target/PowerPC/P9InstrResources.td - copied unchanged from r355961, vendor/llvm-project/release-9.x/llvm/lib/Target/PowerPC/P9InstrResources.td vendor/llvm-project/llvmorg-9.0.1/llvm/lib/Target/PowerPC/PPCInstr64Bit.td - copied unchanged from r355961, vendor/llvm-project/release-9.x/llvm/lib/Target/PowerPC/PPCInstr64Bit.td vendor/llvm-project/llvmorg-9.0.1/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp - copied unchanged from r355961, vendor/llvm-project/release-9.x/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp vendor/llvm-project/llvmorg-9.0.1/llvm/lib/Target/PowerPC/PPCInstrInfo.td - copied unchanged from r355961, vendor/llvm-project/release-9.x/llvm/lib/Target/PowerPC/PPCInstrInfo.td vendor/llvm-project/llvmorg-9.0.1/llvm/lib/Target/PowerPC/PPCTargetTransformInfo.cpp - copied unchanged from r355961, vendor/llvm-project/release-9.x/llvm/lib/Target/PowerPC/PPCTargetTransformInfo.cpp vendor/llvm-project/llvmorg-9.0.1/llvm/lib/Target/RISCV/RISCVRegisterInfo.h - copied unchanged from r355961, vendor/llvm-project/release-9.x/llvm/lib/Target/RISCV/RISCVRegisterInfo.h vendor/llvm-project/llvmorg-9.0.1/llvm/lib/Target/WebAssembly/WebAssemblyInstrFloat.td - copied unchanged from r355961, vendor/llvm-project/release-9.x/llvm/lib/Target/WebAssembly/WebAssemblyInstrFloat.td vendor/llvm-project/llvmorg-9.0.1/llvm/lib/Target/X86/X86FrameLowering.cpp - copied unchanged from r355961, vendor/llvm-project/release-9.x/llvm/lib/Target/X86/X86FrameLowering.cpp vendor/llvm-project/llvmorg-9.0.1/llvm/lib/Target/X86/X86FrameLowering.h - copied unchanged from r355961, vendor/llvm-project/release-9.x/llvm/lib/Target/X86/X86FrameLowering.h vendor/llvm-project/llvmorg-9.0.1/llvm/lib/Target/X86/X86ISelLowering.cpp - copied unchanged from r355961, vendor/llvm-project/release-9.x/llvm/lib/Target/X86/X86ISelLowering.cpp vendor/llvm-project/llvmorg-9.0.1/llvm/lib/Target/X86/X86ISelLowering.h - copied unchanged from r355961, vendor/llvm-project/release-9.x/llvm/lib/Target/X86/X86ISelLowering.h vendor/llvm-project/llvmorg-9.0.1/llvm/lib/Target/X86/X86InstrInfo.cpp - copied unchanged from r355961, vendor/llvm-project/release-9.x/llvm/lib/Target/X86/X86InstrInfo.cpp vendor/llvm-project/llvmorg-9.0.1/llvm/lib/Target/X86/X86MachineFunctionInfo.h - copied unchanged from r355961, vendor/llvm-project/release-9.x/llvm/lib/Target/X86/X86MachineFunctionInfo.h vendor/llvm-project/llvmorg-9.0.1/llvm/lib/Target/X86/X86RegisterInfo.cpp - copied unchanged from r355961, vendor/llvm-project/release-9.x/llvm/lib/Target/X86/X86RegisterInfo.cpp vendor/llvm-project/llvmorg-9.0.1/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp - copied unchanged from r355961, vendor/llvm-project/release-9.x/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp vendor/llvm-project/llvmorg-9.0.1/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp - copied unchanged from r355961, vendor/llvm-project/release-9.x/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp vendor/llvm-project/llvmorg-9.0.1/llvm/lib/Transforms/Scalar/GVN.cpp - copied unchanged from r355961, vendor/llvm-project/release-9.x/llvm/lib/Transforms/Scalar/GVN.cpp vendor/llvm-project/llvmorg-9.0.1/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp - copied unchanged from r355961, vendor/llvm-project/release-9.x/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp vendor/llvm-project/llvmorg-9.0.1/llvm/lib/Transforms/Scalar/SROA.cpp - copied unchanged from r355961, vendor/llvm-project/release-9.x/llvm/lib/Transforms/Scalar/SROA.cpp vendor/llvm-project/llvmorg-9.0.1/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp - copied unchanged from r355961, vendor/llvm-project/release-9.x/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp vendor/llvm-project/llvmorg-9.0.1/llvm/tools/llvm-objcopy/ObjcopyOpts.td - copied unchanged from r355961, vendor/llvm-project/release-9.x/llvm/tools/llvm-objcopy/ObjcopyOpts.td vendor/llvm-project/llvmorg-9.0.1/llvm/tools/llvm-objcopy/StripOpts.td - copied unchanged from r355961, vendor/llvm-project/release-9.x/llvm/tools/llvm-objcopy/StripOpts.td vendor/llvm-project/llvmorg-9.0.1/llvm/tools/opt/opt.cpp - copied unchanged from r355961, vendor/llvm-project/release-9.x/llvm/tools/opt/opt.cpp Copied: vendor/llvm-project/llvmorg-9.0.1/clang/include/clang/CodeGen/CGFunctionInfo.h (from r355961, vendor/llvm-project/release-9.x/clang/include/clang/CodeGen/CGFunctionInfo.h) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ vendor/llvm-project/llvmorg-9.0.1/clang/include/clang/CodeGen/CGFunctionInfo.h Fri Dec 20 21:56:45 2019 (r355963, copy of r355961, vendor/llvm-project/release-9.x/clang/include/clang/CodeGen/CGFunctionInfo.h) @@ -0,0 +1,714 @@ +//==-- CGFunctionInfo.h - Representation of function argument/return types -==// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// Defines CGFunctionInfo and associated types used in representing the +// LLVM source types and ABI-coerced types for function arguments and +// return values. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_CODEGEN_CGFUNCTIONINFO_H +#define LLVM_CLANG_CODEGEN_CGFUNCTIONINFO_H + +#include "clang/AST/Attr.h" +#include "clang/AST/CanonicalType.h" +#include "clang/AST/CharUnits.h" +#include "clang/AST/Decl.h" +#include "clang/AST/Type.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/ADT/FoldingSet.h" +#include "llvm/Support/TrailingObjects.h" +#include <cassert> + +namespace clang { +namespace CodeGen { + +/// ABIArgInfo - Helper class to encapsulate information about how a +/// specific C type should be passed to or returned from a function. +class ABIArgInfo { +public: + enum Kind : uint8_t { + /// Direct - Pass the argument directly using the normal converted LLVM + /// type, or by coercing to another specified type stored in + /// 'CoerceToType'). If an offset is specified (in UIntData), then the + /// argument passed is offset by some number of bytes in the memory + /// representation. A dummy argument is emitted before the real argument + /// if the specified type stored in "PaddingType" is not zero. + Direct, + + /// Extend - Valid only for integer argument types. Same as 'direct' + /// but also emit a zero/sign extension attribute. + Extend, + + /// Indirect - Pass the argument indirectly via a hidden pointer + /// with the specified alignment (0 indicates default alignment). + Indirect, + + /// Ignore - Ignore the argument (treat as void). Useful for void and + /// empty structs. + Ignore, + + /// Expand - Only valid for aggregate argument types. The structure should + /// be expanded into consecutive arguments for its constituent fields. + /// Currently expand is only allowed on structures whose fields + /// are all scalar types or are themselves expandable types. + Expand, + + /// CoerceAndExpand - Only valid for aggregate argument types. The + /// structure should be expanded into consecutive arguments corresponding + /// to the non-array elements of the type stored in CoerceToType. + /// Array elements in the type are assumed to be padding and skipped. + CoerceAndExpand, + + /// InAlloca - Pass the argument directly using the LLVM inalloca attribute. + /// This is similar to indirect with byval, except it only applies to + /// arguments stored in memory and forbids any implicit copies. When + /// applied to a return type, it means the value is returned indirectly via + /// an implicit sret parameter stored in the argument struct. + InAlloca, + KindFirst = Direct, + KindLast = InAlloca + }; + +private: + llvm::Type *TypeData; // canHaveCoerceToType() + union { + llvm::Type *PaddingType; // canHavePaddingType() + llvm::Type *UnpaddedCoerceAndExpandType; // isCoerceAndExpand() + }; + union { + unsigned DirectOffset; // isDirect() || isExtend() + unsigned IndirectAlign; // isIndirect() + unsigned AllocaFieldIndex; // isInAlloca() + }; + Kind TheKind; + bool PaddingInReg : 1; + bool InAllocaSRet : 1; // isInAlloca() + bool IndirectByVal : 1; // isIndirect() + bool IndirectRealign : 1; // isIndirect() + bool SRetAfterThis : 1; // isIndirect() + bool InReg : 1; // isDirect() || isExtend() || isIndirect() + bool CanBeFlattened: 1; // isDirect() + bool SignExt : 1; // isExtend() + + bool canHavePaddingType() const { + return isDirect() || isExtend() || isIndirect() || isExpand(); + } + void setPaddingType(llvm::Type *T) { + assert(canHavePaddingType()); + PaddingType = T; + } + + void setUnpaddedCoerceToType(llvm::Type *T) { + assert(isCoerceAndExpand()); + UnpaddedCoerceAndExpandType = T; + } + +public: + ABIArgInfo(Kind K = Direct) + : TypeData(nullptr), PaddingType(nullptr), DirectOffset(0), + TheKind(K), PaddingInReg(false), InAllocaSRet(false), + IndirectByVal(false), IndirectRealign(false), SRetAfterThis(false), + InReg(false), CanBeFlattened(false), SignExt(false) {} + + static ABIArgInfo getDirect(llvm::Type *T = nullptr, unsigned Offset = 0, + llvm::Type *Padding = nullptr, + bool CanBeFlattened = true) { + auto AI = ABIArgInfo(Direct); + AI.setCoerceToType(T); + AI.setPaddingType(Padding); + AI.setDirectOffset(Offset); + AI.setCanBeFlattened(CanBeFlattened); + return AI; + } + static ABIArgInfo getDirectInReg(llvm::Type *T = nullptr) { + auto AI = getDirect(T); + AI.setInReg(true); + return AI; + } + + static ABIArgInfo getSignExtend(QualType Ty, llvm::Type *T = nullptr) { + assert(Ty->isIntegralOrEnumerationType() && "Unexpected QualType"); + auto AI = ABIArgInfo(Extend); + AI.setCoerceToType(T); + AI.setPaddingType(nullptr); + AI.setDirectOffset(0); + AI.setSignExt(true); + return AI; + } + + static ABIArgInfo getZeroExtend(QualType Ty, llvm::Type *T = nullptr) { + assert(Ty->isIntegralOrEnumerationType() && "Unexpected QualType"); + auto AI = ABIArgInfo(Extend); + AI.setCoerceToType(T); + AI.setPaddingType(nullptr); + AI.setDirectOffset(0); + AI.setSignExt(false); + return AI; + } + + // ABIArgInfo will record the argument as being extended based on the sign + // of its type. + static ABIArgInfo getExtend(QualType Ty, llvm::Type *T = nullptr) { + assert(Ty->isIntegralOrEnumerationType() && "Unexpected QualType"); + if (Ty->hasSignedIntegerRepresentation()) + return getSignExtend(Ty, T); + return getZeroExtend(Ty, T); + } + + static ABIArgInfo getExtendInReg(QualType Ty, llvm::Type *T = nullptr) { + auto AI = getExtend(Ty, T); + AI.setInReg(true); + return AI; + } + static ABIArgInfo getIgnore() { + return ABIArgInfo(Ignore); + } + static ABIArgInfo getIndirect(CharUnits Alignment, bool ByVal = true, + bool Realign = false, + llvm::Type *Padding = nullptr) { + auto AI = ABIArgInfo(Indirect); + AI.setIndirectAlign(Alignment); + AI.setIndirectByVal(ByVal); + AI.setIndirectRealign(Realign); + AI.setSRetAfterThis(false); + AI.setPaddingType(Padding); + return AI; + } + static ABIArgInfo getIndirectInReg(CharUnits Alignment, bool ByVal = true, + bool Realign = false) { + auto AI = getIndirect(Alignment, ByVal, Realign); + AI.setInReg(true); + return AI; + } + static ABIArgInfo getInAlloca(unsigned FieldIndex) { + auto AI = ABIArgInfo(InAlloca); + AI.setInAllocaFieldIndex(FieldIndex); + return AI; + } + static ABIArgInfo getExpand() { + auto AI = ABIArgInfo(Expand); + AI.setPaddingType(nullptr); + return AI; + } + static ABIArgInfo getExpandWithPadding(bool PaddingInReg, + llvm::Type *Padding) { + auto AI = getExpand(); + AI.setPaddingInReg(PaddingInReg); + AI.setPaddingType(Padding); + return AI; + } + + /// \param unpaddedCoerceToType The coerce-to type with padding elements + /// removed, canonicalized to a single element if it would otherwise + /// have exactly one element. + static ABIArgInfo getCoerceAndExpand(llvm::StructType *coerceToType, + llvm::Type *unpaddedCoerceToType) { +#ifndef NDEBUG + // Sanity checks on unpaddedCoerceToType. + + // Assert that we only have a struct type if there are multiple elements. + auto unpaddedStruct = dyn_cast<llvm::StructType>(unpaddedCoerceToType); + assert(!unpaddedStruct || unpaddedStruct->getNumElements() != 1); + + // Assert that all the non-padding elements have a corresponding element + // in the unpadded type. + unsigned unpaddedIndex = 0; + for (auto eltType : coerceToType->elements()) { + if (isPaddingForCoerceAndExpand(eltType)) continue; + if (unpaddedStruct) { + assert(unpaddedStruct->getElementType(unpaddedIndex) == eltType); + } else { + assert(unpaddedIndex == 0 && unpaddedCoerceToType == eltType); + } + unpaddedIndex++; + } + + // Assert that there aren't extra elements in the unpadded type. + if (unpaddedStruct) { + assert(unpaddedStruct->getNumElements() == unpaddedIndex); + } else { + assert(unpaddedIndex == 1); + } +#endif + + auto AI = ABIArgInfo(CoerceAndExpand); + AI.setCoerceToType(coerceToType); + AI.setUnpaddedCoerceToType(unpaddedCoerceToType); + return AI; + } + + static bool isPaddingForCoerceAndExpand(llvm::Type *eltType) { + if (eltType->isArrayTy()) { + assert(eltType->getArrayElementType()->isIntegerTy(8)); + return true; + } else { + return false; + } + } + + Kind getKind() const { return TheKind; } + bool isDirect() const { return TheKind == Direct; } + bool isInAlloca() const { return TheKind == InAlloca; } + bool isExtend() const { return TheKind == Extend; } + bool isIgnore() const { return TheKind == Ignore; } + bool isIndirect() const { return TheKind == Indirect; } + bool isExpand() const { return TheKind == Expand; } + bool isCoerceAndExpand() const { return TheKind == CoerceAndExpand; } + + bool canHaveCoerceToType() const { + return isDirect() || isExtend() || isCoerceAndExpand(); + } + + // Direct/Extend accessors + unsigned getDirectOffset() const { + assert((isDirect() || isExtend()) && "Not a direct or extend kind"); + return DirectOffset; + } + void setDirectOffset(unsigned Offset) { + assert((isDirect() || isExtend()) && "Not a direct or extend kind"); + DirectOffset = Offset; + } + + bool isSignExt() const { + assert(isExtend() && "Invalid kind!"); + return SignExt; + } + void setSignExt(bool SExt) { + assert(isExtend() && "Invalid kind!"); + SignExt = SExt; + } + + llvm::Type *getPaddingType() const { + return (canHavePaddingType() ? PaddingType : nullptr); + } + + bool getPaddingInReg() const { + return PaddingInReg; + } + void setPaddingInReg(bool PIR) { + PaddingInReg = PIR; + } + + llvm::Type *getCoerceToType() const { + assert(canHaveCoerceToType() && "Invalid kind!"); + return TypeData; + } + + void setCoerceToType(llvm::Type *T) { + assert(canHaveCoerceToType() && "Invalid kind!"); + TypeData = T; + } + + llvm::StructType *getCoerceAndExpandType() const { + assert(isCoerceAndExpand()); + return cast<llvm::StructType>(TypeData); + } + + llvm::Type *getUnpaddedCoerceAndExpandType() const { + assert(isCoerceAndExpand()); + return UnpaddedCoerceAndExpandType; + } + + ArrayRef<llvm::Type *>getCoerceAndExpandTypeSequence() const { + assert(isCoerceAndExpand()); + if (auto structTy = + dyn_cast<llvm::StructType>(UnpaddedCoerceAndExpandType)) { + return structTy->elements(); + } else { + return llvm::makeArrayRef(&UnpaddedCoerceAndExpandType, 1); + } + } + + bool getInReg() const { + assert((isDirect() || isExtend() || isIndirect()) && "Invalid kind!"); + return InReg; + } + + void setInReg(bool IR) { + assert((isDirect() || isExtend() || isIndirect()) && "Invalid kind!"); + InReg = IR; + } + + // Indirect accessors + CharUnits getIndirectAlign() const { + assert(isIndirect() && "Invalid kind!"); + return CharUnits::fromQuantity(IndirectAlign); + } + void setIndirectAlign(CharUnits IA) { + assert(isIndirect() && "Invalid kind!"); + IndirectAlign = IA.getQuantity(); + } + + bool getIndirectByVal() const { + assert(isIndirect() && "Invalid kind!"); + return IndirectByVal; + } + void setIndirectByVal(bool IBV) { + assert(isIndirect() && "Invalid kind!"); + IndirectByVal = IBV; + } + + bool getIndirectRealign() const { + assert(isIndirect() && "Invalid kind!"); + return IndirectRealign; + } + void setIndirectRealign(bool IR) { + assert(isIndirect() && "Invalid kind!"); + IndirectRealign = IR; + } + + bool isSRetAfterThis() const { + assert(isIndirect() && "Invalid kind!"); + return SRetAfterThis; + } + void setSRetAfterThis(bool AfterThis) { + assert(isIndirect() && "Invalid kind!"); + SRetAfterThis = AfterThis; + } + + unsigned getInAllocaFieldIndex() const { + assert(isInAlloca() && "Invalid kind!"); + return AllocaFieldIndex; + } + void setInAllocaFieldIndex(unsigned FieldIndex) { + assert(isInAlloca() && "Invalid kind!"); + AllocaFieldIndex = FieldIndex; + } + + /// Return true if this field of an inalloca struct should be returned + /// to implement a struct return calling convention. + bool getInAllocaSRet() const { + assert(isInAlloca() && "Invalid kind!"); + return InAllocaSRet; + } + + void setInAllocaSRet(bool SRet) { + assert(isInAlloca() && "Invalid kind!"); + InAllocaSRet = SRet; + } + + bool getCanBeFlattened() const { + assert(isDirect() && "Invalid kind!"); + return CanBeFlattened; + } + + void setCanBeFlattened(bool Flatten) { + assert(isDirect() && "Invalid kind!"); + CanBeFlattened = Flatten; + } + + void dump() const; +}; + +/// A class for recording the number of arguments that a function +/// signature requires. +class RequiredArgs { + /// The number of required arguments, or ~0 if the signature does + /// not permit optional arguments. + unsigned NumRequired; +public: + enum All_t { All }; + + RequiredArgs(All_t _) : NumRequired(~0U) {} + explicit RequiredArgs(unsigned n) : NumRequired(n) { + assert(n != ~0U); + } + + /// Compute the arguments required by the given formal prototype, + /// given that there may be some additional, non-formal arguments + /// in play. + /// + /// If FD is not null, this will consider pass_object_size params in FD. + static RequiredArgs forPrototypePlus(const FunctionProtoType *prototype, + unsigned additional) { + if (!prototype->isVariadic()) return All; + + if (prototype->hasExtParameterInfos()) + additional += llvm::count_if( + prototype->getExtParameterInfos(), + [](const FunctionProtoType::ExtParameterInfo &ExtInfo) { + return ExtInfo.hasPassObjectSize(); + }); + + return RequiredArgs(prototype->getNumParams() + additional); + } + + static RequiredArgs forPrototypePlus(CanQual<FunctionProtoType> prototype, + unsigned additional) { + return forPrototypePlus(prototype.getTypePtr(), additional); + } + + static RequiredArgs forPrototype(const FunctionProtoType *prototype) { + return forPrototypePlus(prototype, 0); + } + + static RequiredArgs forPrototype(CanQual<FunctionProtoType> prototype) { + return forPrototypePlus(prototype.getTypePtr(), 0); + } + + bool allowsOptionalArgs() const { return NumRequired != ~0U; } + unsigned getNumRequiredArgs() const { + assert(allowsOptionalArgs()); + return NumRequired; + } + + unsigned getOpaqueData() const { return NumRequired; } + static RequiredArgs getFromOpaqueData(unsigned value) { + if (value == ~0U) return All; + return RequiredArgs(value); + } +}; + +// Implementation detail of CGFunctionInfo, factored out so it can be named +// in the TrailingObjects base class of CGFunctionInfo. +struct CGFunctionInfoArgInfo { + CanQualType type; + ABIArgInfo info; +}; + +/// CGFunctionInfo - Class to encapsulate the information about a +/// function definition. +class CGFunctionInfo final + : public llvm::FoldingSetNode, + private llvm::TrailingObjects<CGFunctionInfo, CGFunctionInfoArgInfo, + FunctionProtoType::ExtParameterInfo> { + typedef CGFunctionInfoArgInfo ArgInfo; + typedef FunctionProtoType::ExtParameterInfo ExtParameterInfo; + + /// The LLVM::CallingConv to use for this function (as specified by the + /// user). + unsigned CallingConvention : 8; + + /// The LLVM::CallingConv to actually use for this function, which may + /// depend on the ABI. + unsigned EffectiveCallingConvention : 8; + + /// The clang::CallingConv that this was originally created with. + unsigned ASTCallingConvention : 6; + + /// Whether this is an instance method. + unsigned InstanceMethod : 1; + + /// Whether this is a chain call. + unsigned ChainCall : 1; + + /// Whether this function is noreturn. + unsigned NoReturn : 1; + + /// Whether this function is returns-retained. + unsigned ReturnsRetained : 1; + + /// Whether this function saved caller registers. + unsigned NoCallerSavedRegs : 1; + + /// How many arguments to pass inreg. + unsigned HasRegParm : 1; + unsigned RegParm : 3; + + /// Whether this function has nocf_check attribute. + unsigned NoCfCheck : 1; + + RequiredArgs Required; + + /// The struct representing all arguments passed in memory. Only used when + /// passing non-trivial types with inalloca. Not part of the profile. + llvm::StructType *ArgStruct; + unsigned ArgStructAlign : 31; + unsigned HasExtParameterInfos : 1; + + unsigned NumArgs; + + ArgInfo *getArgsBuffer() { + return getTrailingObjects<ArgInfo>(); + } + const ArgInfo *getArgsBuffer() const { + return getTrailingObjects<ArgInfo>(); + } + + ExtParameterInfo *getExtParameterInfosBuffer() { + return getTrailingObjects<ExtParameterInfo>(); + } + const ExtParameterInfo *getExtParameterInfosBuffer() const{ + return getTrailingObjects<ExtParameterInfo>(); + } + + CGFunctionInfo() : Required(RequiredArgs::All) {} + +public: + static CGFunctionInfo *create(unsigned llvmCC, + bool instanceMethod, + bool chainCall, + const FunctionType::ExtInfo &extInfo, + ArrayRef<ExtParameterInfo> paramInfos, + CanQualType resultType, + ArrayRef<CanQualType> argTypes, + RequiredArgs required); + void operator delete(void *p) { ::operator delete(p); } + + // Friending class TrailingObjects is apparently not good enough for MSVC, + // so these have to be public. + friend class TrailingObjects; + size_t numTrailingObjects(OverloadToken<ArgInfo>) const { + return NumArgs + 1; + } + size_t numTrailingObjects(OverloadToken<ExtParameterInfo>) const { + return (HasExtParameterInfos ? NumArgs : 0); + } + + typedef const ArgInfo *const_arg_iterator; + typedef ArgInfo *arg_iterator; + + typedef llvm::iterator_range<arg_iterator> arg_range; + typedef llvm::iterator_range<const_arg_iterator> const_arg_range; + + arg_range arguments() { return arg_range(arg_begin(), arg_end()); } + const_arg_range arguments() const { + return const_arg_range(arg_begin(), arg_end()); + } + + const_arg_iterator arg_begin() const { return getArgsBuffer() + 1; } + const_arg_iterator arg_end() const { return getArgsBuffer() + 1 + NumArgs; } + arg_iterator arg_begin() { return getArgsBuffer() + 1; } + arg_iterator arg_end() { return getArgsBuffer() + 1 + NumArgs; } + + unsigned arg_size() const { return NumArgs; } + + bool isVariadic() const { return Required.allowsOptionalArgs(); } + RequiredArgs getRequiredArgs() const { return Required; } + unsigned getNumRequiredArgs() const { + return isVariadic() ? getRequiredArgs().getNumRequiredArgs() : arg_size(); + } + + bool isInstanceMethod() const { return InstanceMethod; } + + bool isChainCall() const { return ChainCall; } + + bool isNoReturn() const { return NoReturn; } + + /// In ARC, whether this function retains its return value. This + /// is not always reliable for call sites. + bool isReturnsRetained() const { return ReturnsRetained; } + + /// Whether this function no longer saves caller registers. + bool isNoCallerSavedRegs() const { return NoCallerSavedRegs; } + + /// Whether this function has nocf_check attribute. + bool isNoCfCheck() const { return NoCfCheck; } + + /// getASTCallingConvention() - Return the AST-specified calling + /// convention. + CallingConv getASTCallingConvention() const { + return CallingConv(ASTCallingConvention); + } + + /// getCallingConvention - Return the user specified calling + /// convention, which has been translated into an LLVM CC. + unsigned getCallingConvention() const { return CallingConvention; } + + /// getEffectiveCallingConvention - Return the actual calling convention to + /// use, which may depend on the ABI. + unsigned getEffectiveCallingConvention() const { + return EffectiveCallingConvention; + } + void setEffectiveCallingConvention(unsigned Value) { + EffectiveCallingConvention = Value; + } + + bool getHasRegParm() const { return HasRegParm; } + unsigned getRegParm() const { return RegParm; } + + FunctionType::ExtInfo getExtInfo() const { + return FunctionType::ExtInfo(isNoReturn(), getHasRegParm(), getRegParm(), + getASTCallingConvention(), isReturnsRetained(), + isNoCallerSavedRegs(), isNoCfCheck()); + } + + CanQualType getReturnType() const { return getArgsBuffer()[0].type; } + + ABIArgInfo &getReturnInfo() { return getArgsBuffer()[0].info; } + const ABIArgInfo &getReturnInfo() const { return getArgsBuffer()[0].info; } + + ArrayRef<ExtParameterInfo> getExtParameterInfos() const { + if (!HasExtParameterInfos) return {}; + return llvm::makeArrayRef(getExtParameterInfosBuffer(), NumArgs); + } + ExtParameterInfo getExtParameterInfo(unsigned argIndex) const { + assert(argIndex <= NumArgs); + if (!HasExtParameterInfos) return ExtParameterInfo(); + return getExtParameterInfos()[argIndex]; + } + + /// Return true if this function uses inalloca arguments. + bool usesInAlloca() const { return ArgStruct; } + + /// Get the struct type used to represent all the arguments in memory. + llvm::StructType *getArgStruct() const { return ArgStruct; } + CharUnits getArgStructAlignment() const { + return CharUnits::fromQuantity(ArgStructAlign); + } + void setArgStruct(llvm::StructType *Ty, CharUnits Align) { + ArgStruct = Ty; + ArgStructAlign = Align.getQuantity(); + } + + void Profile(llvm::FoldingSetNodeID &ID) { + ID.AddInteger(getASTCallingConvention()); + ID.AddBoolean(InstanceMethod); + ID.AddBoolean(ChainCall); + ID.AddBoolean(NoReturn); + ID.AddBoolean(ReturnsRetained); + ID.AddBoolean(NoCallerSavedRegs); + ID.AddBoolean(HasRegParm); + ID.AddInteger(RegParm); + ID.AddBoolean(NoCfCheck); + ID.AddInteger(Required.getOpaqueData()); + ID.AddBoolean(HasExtParameterInfos); + if (HasExtParameterInfos) { + for (auto paramInfo : getExtParameterInfos()) + ID.AddInteger(paramInfo.getOpaqueValue()); + } + getReturnType().Profile(ID); + for (const auto &I : arguments()) + I.type.Profile(ID); + } + static void Profile(llvm::FoldingSetNodeID &ID, + bool InstanceMethod, + bool ChainCall, + const FunctionType::ExtInfo &info, + ArrayRef<ExtParameterInfo> paramInfos, + RequiredArgs required, + CanQualType resultType, + ArrayRef<CanQualType> argTypes) { + ID.AddInteger(info.getCC()); + ID.AddBoolean(InstanceMethod); + ID.AddBoolean(ChainCall); + ID.AddBoolean(info.getNoReturn()); + ID.AddBoolean(info.getProducesResult()); + ID.AddBoolean(info.getNoCallerSavedRegs()); + ID.AddBoolean(info.getHasRegParm()); + ID.AddInteger(info.getRegParm()); + ID.AddBoolean(info.getNoCfCheck()); + ID.AddInteger(required.getOpaqueData()); + ID.AddBoolean(!paramInfos.empty()); + if (!paramInfos.empty()) { + for (auto paramInfo : paramInfos) + ID.AddInteger(paramInfo.getOpaqueValue()); + } + resultType.Profile(ID); + for (ArrayRef<CanQualType>::iterator + i = argTypes.begin(), e = argTypes.end(); i != e; ++i) { + i->Profile(ID); + } + } +}; + +} // end namespace CodeGen +} // end namespace clang + +#endif Copied: vendor/llvm-project/llvmorg-9.0.1/clang/lib/AST/ExprConstant.cpp (from r355961, vendor/llvm-project/release-9.x/clang/lib/AST/ExprConstant.cpp) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ vendor/llvm-project/llvmorg-9.0.1/clang/lib/AST/ExprConstant.cpp Fri Dec 20 21:56:45 2019 (r355963, copy of r355961, vendor/llvm-project/release-9.x/clang/lib/AST/ExprConstant.cpp) @@ -0,0 +1,13225 @@ +//===--- ExprConstant.cpp - Expression Constant Evaluator -----------------===// +// +// 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 implements the Expr constant evaluator. +// +// Constant expression evaluation produces four main results: +// +// * A success/failure flag indicating whether constant folding was successful. +// This is the 'bool' return value used by most of the code in this file. A +// 'false' return value indicates that constant folding has failed, and any +// appropriate diagnostic has already been produced. +// +// * An evaluated result, valid only if constant folding has not failed. +// +// * A flag indicating if evaluation encountered (unevaluated) side-effects. +// These arise in cases such as (sideEffect(), 0) and (sideEffect() || 1), +// where it is possible to determine the evaluated result regardless. +// +// * A set of notes indicating why the evaluation was not a constant expression +// (under the C++11 / C++1y rules only, at the moment), or, if folding failed +// too, why the expression could not be folded. +// +// If we are checking for a potential constant expression, failure to constant +// fold a potential constant sub-expression will be indicated by a 'false' +// return value (the expression could not be folded) and no diagnostic (the +// expression is not necessarily non-constant). +// +//===----------------------------------------------------------------------===// + +#include "clang/AST/APValue.h" +#include "clang/AST/ASTContext.h" +#include "clang/AST/ASTDiagnostic.h" +#include "clang/AST/ASTLambda.h" +#include "clang/AST/CharUnits.h" +#include "clang/AST/CurrentSourceLocExprScope.h" +#include "clang/AST/CXXInheritance.h" +#include "clang/AST/Expr.h" +#include "clang/AST/OSLog.h" +#include "clang/AST/RecordLayout.h" +#include "clang/AST/StmtVisitor.h" +#include "clang/AST/TypeLoc.h" +#include "clang/Basic/Builtins.h" +#include "clang/Basic/FixedPoint.h" +#include "clang/Basic/TargetInfo.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/SmallBitVector.h" +#include "llvm/Support/SaveAndRestore.h" +#include "llvm/Support/raw_ostream.h" +#include <cstring> +#include <functional> + +#define DEBUG_TYPE "exprconstant" + +using namespace clang; +using llvm::APInt; +using llvm::APSInt; +using llvm::APFloat; +using llvm::Optional; + +static bool IsGlobalLValue(APValue::LValueBase B); + +namespace { + struct LValue; + struct CallStackFrame; + struct EvalInfo; + + using SourceLocExprScopeGuard = + CurrentSourceLocExprScope::SourceLocExprScopeGuard; + + static QualType getType(APValue::LValueBase B) { + if (!B) return QualType(); + if (const ValueDecl *D = B.dyn_cast<const ValueDecl*>()) { + // FIXME: It's unclear where we're supposed to take the type from, and + // this actually matters for arrays of unknown bound. Eg: + // + // extern int arr[]; void f() { extern int arr[3]; }; + // constexpr int *p = &arr[1]; // valid? + // + // For now, we take the array bound from the most recent declaration. + for (auto *Redecl = cast<ValueDecl>(D->getMostRecentDecl()); Redecl; + Redecl = cast_or_null<ValueDecl>(Redecl->getPreviousDecl())) { + QualType T = Redecl->getType(); + if (!T->isIncompleteArrayType()) + return T; + } + return D->getType(); + } + + if (B.is<TypeInfoLValue>()) + return B.getTypeInfoType(); + + const Expr *Base = B.get<const Expr*>(); + + // For a materialized temporary, the type of the temporary we materialized + // may not be the type of the expression. + if (const MaterializeTemporaryExpr *MTE = + dyn_cast<MaterializeTemporaryExpr>(Base)) { + SmallVector<const Expr *, 2> CommaLHSs; + SmallVector<SubobjectAdjustment, 2> Adjustments; + const Expr *Temp = MTE->GetTemporaryExpr(); + const Expr *Inner = Temp->skipRValueSubobjectAdjustments(CommaLHSs, + Adjustments); + // Keep any cv-qualifiers from the reference if we generated a temporary + // for it directly. Otherwise use the type after adjustment. + if (!Adjustments.empty()) + return Inner->getType(); + } + + return Base->getType(); + } + + /// Get an LValue path entry, which is known to not be an array index, as a + /// field declaration. + static const FieldDecl *getAsField(APValue::LValuePathEntry E) { + return dyn_cast_or_null<FieldDecl>(E.getAsBaseOrMember().getPointer()); + } + /// Get an LValue path entry, which is known to not be an array index, as a + /// base class declaration. + static const CXXRecordDecl *getAsBaseClass(APValue::LValuePathEntry E) { + return dyn_cast_or_null<CXXRecordDecl>(E.getAsBaseOrMember().getPointer()); + } + /// Determine whether this LValue path entry for a base class names a virtual + /// base class. + static bool isVirtualBaseClass(APValue::LValuePathEntry E) { + return E.getAsBaseOrMember().getInt(); + } + + /// Given a CallExpr, try to get the alloc_size attribute. May return null. + static const AllocSizeAttr *getAllocSizeAttr(const CallExpr *CE) { + const FunctionDecl *Callee = CE->getDirectCallee(); + return Callee ? Callee->getAttr<AllocSizeAttr>() : nullptr; + } + + /// Attempts to unwrap a CallExpr (with an alloc_size attribute) from an Expr. + /// This will look through a single cast. + /// + /// Returns null if we couldn't unwrap a function with alloc_size. + static const CallExpr *tryUnwrapAllocSizeCall(const Expr *E) { + if (!E->getType()->isPointerType()) + return nullptr; + + E = E->IgnoreParens(); + // If we're doing a variable assignment from e.g. malloc(N), there will + // probably be a cast of some kind. In exotic cases, we might also see a + // top-level ExprWithCleanups. Ignore them either way. + if (const auto *FE = dyn_cast<FullExpr>(E)) + E = FE->getSubExpr()->IgnoreParens(); + + if (const auto *Cast = dyn_cast<CastExpr>(E)) + E = Cast->getSubExpr()->IgnoreParens(); + + if (const auto *CE = dyn_cast<CallExpr>(E)) + return getAllocSizeAttr(CE) ? CE : nullptr; + return nullptr; + } + + /// Determines whether or not the given Base contains a call to a function + /// with the alloc_size attribute. + static bool isBaseAnAllocSizeCall(APValue::LValueBase Base) { + const auto *E = Base.dyn_cast<const Expr *>(); + return E && E->getType()->isPointerType() && tryUnwrapAllocSizeCall(E); + } + + /// The bound to claim that an array of unknown bound has. + /// The value in MostDerivedArraySize is undefined in this case. So, set it + /// to an arbitrary value that's likely to loudly break things if it's used. + static const uint64_t AssumedSizeForUnsizedArray = + std::numeric_limits<uint64_t>::max() / 2; + + /// Determines if an LValue with the given LValueBase will have an unsized + /// array in its designator. + /// Find the path length and type of the most-derived subobject in the given + /// path, and find the size of the containing array, if any. + static unsigned + findMostDerivedSubobject(ASTContext &Ctx, APValue::LValueBase Base, + ArrayRef<APValue::LValuePathEntry> Path, + uint64_t &ArraySize, QualType &Type, bool &IsArray, + bool &FirstEntryIsUnsizedArray) { + // This only accepts LValueBases from APValues, and APValues don't support + // arrays that lack size info. + assert(!isBaseAnAllocSizeCall(Base) && + "Unsized arrays shouldn't appear here"); + unsigned MostDerivedLength = 0; + Type = getType(Base); + + for (unsigned I = 0, N = Path.size(); I != N; ++I) { + if (Type->isArrayType()) { + const ArrayType *AT = Ctx.getAsArrayType(Type); + Type = AT->getElementType(); + MostDerivedLength = I + 1; + IsArray = true; + + if (auto *CAT = dyn_cast<ConstantArrayType>(AT)) { + ArraySize = CAT->getSize().getZExtValue(); + } else { + assert(I == 0 && "unexpected unsized array designator"); + FirstEntryIsUnsizedArray = true; + ArraySize = AssumedSizeForUnsizedArray; + } + } else if (Type->isAnyComplexType()) { + const ComplexType *CT = Type->castAs<ComplexType>(); + Type = CT->getElementType(); + ArraySize = 2; + MostDerivedLength = I + 1; + IsArray = true; + } else if (const FieldDecl *FD = getAsField(Path[I])) { + Type = FD->getType(); + ArraySize = 0; + MostDerivedLength = I + 1; + IsArray = false; + } else { + // Path[I] describes a base class. + ArraySize = 0; + IsArray = false; + } + } + return MostDerivedLength; + } + + // The order of this enum is important for diagnostics. + enum CheckSubobjectKind { + CSK_Base, CSK_Derived, CSK_Field, CSK_ArrayToPointer, CSK_ArrayIndex, + CSK_Real, CSK_Imag + }; + + /// A path from a glvalue to a subobject of that glvalue. + struct SubobjectDesignator { + /// True if the subobject was named in a manner not supported by C++11. Such + /// lvalues can still be folded, but they are not core constant expressions + /// and we cannot perform lvalue-to-rvalue conversions on them. + unsigned Invalid : 1; + + /// Is this a pointer one past the end of an object? + unsigned IsOnePastTheEnd : 1; + + /// Indicator of whether the first entry is an unsized array. + unsigned FirstEntryIsAnUnsizedArray : 1; + + /// Indicator of whether the most-derived object is an array element. + unsigned MostDerivedIsArrayElement : 1; + + /// The length of the path to the most-derived object of which this is a + /// subobject. + unsigned MostDerivedPathLength : 28; + + /// The size of the array of which the most-derived object is an element. + /// This will always be 0 if the most-derived object is not an array + /// element. 0 is not an indicator of whether or not the most-derived object + /// is an array, however, because 0-length arrays are allowed. + /// + /// If the current array is an unsized array, the value of this is + /// undefined. + uint64_t MostDerivedArraySize; + + /// The type of the most derived object referred to by this address. + QualType MostDerivedType; + + typedef APValue::LValuePathEntry PathEntry; + + /// The entries on the path from the glvalue to the designated subobject. + SmallVector<PathEntry, 8> Entries; + + SubobjectDesignator() : Invalid(true) {} + + explicit SubobjectDesignator(QualType T) + : Invalid(false), IsOnePastTheEnd(false), + FirstEntryIsAnUnsizedArray(false), MostDerivedIsArrayElement(false), + MostDerivedPathLength(0), MostDerivedArraySize(0), + MostDerivedType(T) {} + + SubobjectDesignator(ASTContext &Ctx, const APValue &V) + : Invalid(!V.isLValue() || !V.hasLValuePath()), IsOnePastTheEnd(false), + FirstEntryIsAnUnsizedArray(false), MostDerivedIsArrayElement(false), + MostDerivedPathLength(0), MostDerivedArraySize(0) { + assert(V.isLValue() && "Non-LValue used to make an LValue designator?"); *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201912202156.xBKLujoQ016624>