summaryrefslogtreecommitdiff
path: root/clang-r353983/include/clang/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'clang-r353983/include/clang/CodeGen')
-rw-r--r--clang-r353983/include/clang/CodeGen/BackendUtil.h55
-rw-r--r--clang-r353983/include/clang/CodeGen/CGFunctionInfo.h728
-rw-r--r--clang-r353983/include/clang/CodeGen/CodeGenABITypes.h89
-rw-r--r--clang-r353983/include/clang/CodeGen/CodeGenAction.h121
-rw-r--r--clang-r353983/include/clang/CodeGen/ConstantInitBuilder.h560
-rw-r--r--clang-r353983/include/clang/CodeGen/ConstantInitFuture.h108
-rw-r--r--clang-r353983/include/clang/CodeGen/ModuleBuilder.h105
-rw-r--r--clang-r353983/include/clang/CodeGen/ObjectFilePCHContainerOperations.h42
-rw-r--r--clang-r353983/include/clang/CodeGen/SwiftCallingConv.h184
9 files changed, 1992 insertions, 0 deletions
diff --git a/clang-r353983/include/clang/CodeGen/BackendUtil.h b/clang-r353983/include/clang/CodeGen/BackendUtil.h
new file mode 100644
index 00000000..01b1f5bb
--- /dev/null
+++ b/clang-r353983/include/clang/CodeGen/BackendUtil.h
@@ -0,0 +1,55 @@
+//===--- BackendUtil.h - LLVM Backend Utilities -----------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_CODEGEN_BACKENDUTIL_H
+#define LLVM_CLANG_CODEGEN_BACKENDUTIL_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/IR/ModuleSummaryIndex.h"
+#include <memory>
+
+namespace llvm {
+ class BitcodeModule;
+ template <typename T> class Expected;
+ class Module;
+ class MemoryBufferRef;
+}
+
+namespace clang {
+ class DiagnosticsEngine;
+ class HeaderSearchOptions;
+ class CodeGenOptions;
+ class TargetOptions;
+ class LangOptions;
+
+ enum BackendAction {
+ Backend_EmitAssembly, ///< Emit native assembly files
+ Backend_EmitBC, ///< Emit LLVM bitcode files
+ Backend_EmitLL, ///< Emit human-readable LLVM assembly
+ Backend_EmitNothing, ///< Don't emit anything (benchmarking mode)
+ Backend_EmitMCNull, ///< Run CodeGen, but don't emit anything
+ Backend_EmitObj ///< Emit native object files
+ };
+
+ void EmitBackendOutput(DiagnosticsEngine &Diags, const HeaderSearchOptions &,
+ const CodeGenOptions &CGOpts,
+ const TargetOptions &TOpts, const LangOptions &LOpts,
+ const llvm::DataLayout &TDesc, llvm::Module *M,
+ BackendAction Action,
+ std::unique_ptr<raw_pwrite_stream> OS);
+
+ void EmbedBitcode(llvm::Module *M, const CodeGenOptions &CGOpts,
+ llvm::MemoryBufferRef Buf);
+
+ llvm::Expected<llvm::BitcodeModule>
+ FindThinLTOModule(llvm::MemoryBufferRef MBRef);
+ llvm::BitcodeModule *
+ FindThinLTOModule(llvm::MutableArrayRef<llvm::BitcodeModule> BMs);
+}
+
+#endif
diff --git a/clang-r353983/include/clang/CodeGen/CGFunctionInfo.h b/clang-r353983/include/clang/CodeGen/CGFunctionInfo.h
new file mode 100644
index 00000000..52157f0c
--- /dev/null
+++ b/clang-r353983/include/clang/CodeGen/CGFunctionInfo.h
@@ -0,0 +1,728 @@
+//==-- 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 SuppressSRet : 1; // isIndirect()
+
+ 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;
+ }
+
+ ABIArgInfo(Kind K)
+ : TheKind(K), PaddingInReg(false), InReg(false), SuppressSRet(false) {
+ }
+
+public:
+ ABIArgInfo()
+ : TypeData(nullptr), PaddingType(nullptr), DirectOffset(0),
+ TheKind(Direct), PaddingInReg(false), InReg(false),
+ SuppressSRet(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;
+ }
+
+ bool getSuppressSRet() const {
+ assert(isIndirect() && "Invalid kind!");
+ return SuppressSRet;
+ }
+
+ void setSuppressSRet(bool Suppress) {
+ assert(isIndirect() && "Invalid kind!");
+ SuppressSRet = Suppress;
+ }
+
+ 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
diff --git a/clang-r353983/include/clang/CodeGen/CodeGenABITypes.h b/clang-r353983/include/clang/CodeGen/CodeGenABITypes.h
new file mode 100644
index 00000000..febb25aa
--- /dev/null
+++ b/clang-r353983/include/clang/CodeGen/CodeGenABITypes.h
@@ -0,0 +1,89 @@
+//==---- CodeGenABITypes.h - Convert Clang types to LLVM types for ABI -----==//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// CodeGenABITypes is a simple interface for getting LLVM types for
+// the parameters and the return value of a function given the Clang
+// types.
+//
+// The class is implemented as a public wrapper around the private
+// CodeGenTypes class in lib/CodeGen.
+//
+// It allows other clients, like LLDB, to determine the LLVM types that are
+// actually used in function calls, which makes it possible to then determine
+// the actual ABI locations (e.g. registers, stack locations, etc.) that
+// these parameters are stored in.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_CODEGEN_CODEGENABITYPES_H
+#define LLVM_CLANG_CODEGEN_CODEGENABITYPES_H
+
+#include "clang/AST/CanonicalType.h"
+#include "clang/AST/Type.h"
+#include "clang/CodeGen/CGFunctionInfo.h"
+
+namespace llvm {
+ class DataLayout;
+ class Module;
+ class FunctionType;
+ class Type;
+}
+
+namespace clang {
+class ASTContext;
+class CXXRecordDecl;
+class CXXMethodDecl;
+class CodeGenOptions;
+class CoverageSourceInfo;
+class DiagnosticsEngine;
+class HeaderSearchOptions;
+class ObjCMethodDecl;
+class PreprocessorOptions;
+
+namespace CodeGen {
+class CGFunctionInfo;
+class CodeGenModule;
+
+const CGFunctionInfo &arrangeObjCMessageSendSignature(CodeGenModule &CGM,
+ const ObjCMethodDecl *MD,
+ QualType receiverType);
+
+const CGFunctionInfo &arrangeFreeFunctionType(CodeGenModule &CGM,
+ CanQual<FunctionProtoType> Ty);
+
+const CGFunctionInfo &arrangeFreeFunctionType(CodeGenModule &CGM,
+ CanQual<FunctionNoProtoType> Ty);
+
+const CGFunctionInfo &arrangeCXXMethodType(CodeGenModule &CGM,
+ const CXXRecordDecl *RD,
+ const FunctionProtoType *FTP,
+ const CXXMethodDecl *MD);
+
+const CGFunctionInfo &arrangeFreeFunctionCall(CodeGenModule &CGM,
+ CanQualType returnType,
+ ArrayRef<CanQualType> argTypes,
+ FunctionType::ExtInfo info,
+ RequiredArgs args);
+
+/// Returns null if the function type is incomplete and can't be lowered.
+llvm::FunctionType *convertFreeFunctionType(CodeGenModule &CGM,
+ const FunctionDecl *FD);
+
+llvm::Type *convertTypeForMemory(CodeGenModule &CGM, QualType T);
+
+/// Given a non-bitfield struct field, return its index within the elements of
+/// the struct's converted type. The returned index refers to a field number in
+/// the complete object type which is returned by convertTypeForMemory. FD must
+/// be a field in RD directly (i.e. not an inherited field).
+unsigned getLLVMFieldNumber(CodeGenModule &CGM,
+ const RecordDecl *RD, const FieldDecl *FD);
+
+} // end namespace CodeGen
+} // end namespace clang
+
+#endif
diff --git a/clang-r353983/include/clang/CodeGen/CodeGenAction.h b/clang-r353983/include/clang/CodeGen/CodeGenAction.h
new file mode 100644
index 00000000..1db904ea
--- /dev/null
+++ b/clang-r353983/include/clang/CodeGen/CodeGenAction.h
@@ -0,0 +1,121 @@
+//===--- CodeGenAction.h - LLVM Code Generation Frontend Action -*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_CODEGEN_CODEGENACTION_H
+#define LLVM_CLANG_CODEGEN_CODEGENACTION_H
+
+#include "clang/Frontend/FrontendAction.h"
+#include <memory>
+
+namespace llvm {
+ class LLVMContext;
+ class Module;
+}
+
+namespace clang {
+class BackendConsumer;
+
+class CodeGenAction : public ASTFrontendAction {
+private:
+ // Let BackendConsumer access LinkModule.
+ friend class BackendConsumer;
+
+ /// Info about module to link into a module we're generating.
+ struct LinkModule {
+ /// The module to link in.
+ std::unique_ptr<llvm::Module> Module;
+
+ /// If true, we set attributes on Module's functions according to our
+ /// CodeGenOptions and LangOptions, as though we were generating the
+ /// function ourselves.
+ bool PropagateAttrs;
+
+ /// If true, we use LLVM module internalizer.
+ bool Internalize;
+
+ /// Bitwise combination of llvm::LinkerFlags used when we link the module.
+ unsigned LinkFlags;
+ };
+
+ unsigned Act;
+ std::unique_ptr<llvm::Module> TheModule;
+
+ /// Bitcode modules to link in to our module.
+ SmallVector<LinkModule, 4> LinkModules;
+ llvm::LLVMContext *VMContext;
+ bool OwnsVMContext;
+
+ std::unique_ptr<llvm::Module> loadModule(llvm::MemoryBufferRef MBRef);
+
+protected:
+ /// Create a new code generation action. If the optional \p _VMContext
+ /// parameter is supplied, the action uses it without taking ownership,
+ /// otherwise it creates a fresh LLVM context and takes ownership.
+ CodeGenAction(unsigned _Act, llvm::LLVMContext *_VMContext = nullptr);
+
+ bool hasIRSupport() const override;
+
+ std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override;
+
+ void ExecuteAction() override;
+
+ void EndSourceFileAction() override;
+
+public:
+ ~CodeGenAction() override;
+
+ /// Take the generated LLVM module, for use after the action has been run.
+ /// The result may be null on failure.
+ std::unique_ptr<llvm::Module> takeModule();
+
+ /// Take the LLVM context used by this action.
+ llvm::LLVMContext *takeLLVMContext();
+
+ BackendConsumer *BEConsumer;
+};
+
+class EmitAssemblyAction : public CodeGenAction {
+ virtual void anchor();
+public:
+ EmitAssemblyAction(llvm::LLVMContext *_VMContext = nullptr);
+};
+
+class EmitBCAction : public CodeGenAction {
+ virtual void anchor();
+public:
+ EmitBCAction(llvm::LLVMContext *_VMContext = nullptr);
+};
+
+class EmitLLVMAction : public CodeGenAction {
+ virtual void anchor();
+public:
+ EmitLLVMAction(llvm::LLVMContext *_VMContext = nullptr);
+};
+
+class EmitLLVMOnlyAction : public CodeGenAction {
+ virtual void anchor();
+public:
+ EmitLLVMOnlyAction(llvm::LLVMContext *_VMContext = nullptr);
+};
+
+class EmitCodeGenOnlyAction : public CodeGenAction {
+ virtual void anchor();
+public:
+ EmitCodeGenOnlyAction(llvm::LLVMContext *_VMContext = nullptr);
+};
+
+class EmitObjAction : public CodeGenAction {
+ virtual void anchor();
+public:
+ EmitObjAction(llvm::LLVMContext *_VMContext = nullptr);
+};
+
+}
+
+#endif
diff --git a/clang-r353983/include/clang/CodeGen/ConstantInitBuilder.h b/clang-r353983/include/clang/CodeGen/ConstantInitBuilder.h
new file mode 100644
index 00000000..fd07e91b
--- /dev/null
+++ b/clang-r353983/include/clang/CodeGen/ConstantInitBuilder.h
@@ -0,0 +1,560 @@
+//===- ConstantInitBuilder.h - Builder for LLVM IR constants ----*- C++ -*-===//
+//
+// 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 class provides a convenient interface for building complex
+// global initializers of the sort that are frequently required for
+// language ABIs.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_CODEGEN_CONSTANTINITBUILDER_H
+#define LLVM_CLANG_CODEGEN_CONSTANTINITBUILDER_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/GlobalValue.h"
+#include "clang/AST/CharUnits.h"
+#include "clang/CodeGen/ConstantInitFuture.h"
+
+#include <vector>
+
+namespace clang {
+namespace CodeGen {
+
+class CodeGenModule;
+
+/// A convenience builder class for complex constant initializers,
+/// especially for anonymous global structures used by various language
+/// runtimes.
+///
+/// The basic usage pattern is expected to be something like:
+/// ConstantInitBuilder builder(CGM);
+/// auto toplevel = builder.beginStruct();
+/// toplevel.addInt(CGM.SizeTy, widgets.size());
+/// auto widgetArray = builder.beginArray();
+/// for (auto &widget : widgets) {
+/// auto widgetDesc = widgetArray.beginStruct();
+/// widgetDesc.addInt(CGM.SizeTy, widget.getPower());
+/// widgetDesc.add(CGM.GetAddrOfConstantString(widget.getName()));
+/// widgetDesc.add(CGM.GetAddrOfGlobal(widget.getInitializerDecl()));
+/// widgetDesc.finishAndAddTo(widgetArray);
+/// }
+/// widgetArray.finishAndAddTo(toplevel);
+/// auto global = toplevel.finishAndCreateGlobal("WIDGET_LIST", Align,
+/// /*constant*/ true);
+class ConstantInitBuilderBase {
+ struct SelfReference {
+ llvm::GlobalVariable *Dummy;
+ llvm::SmallVector<llvm::Constant*, 4> Indices;
+
+ SelfReference(llvm::GlobalVariable *dummy) : Dummy(dummy) {}
+ };
+ CodeGenModule &CGM;
+ llvm::SmallVector<llvm::Constant*, 16> Buffer;
+ std::vector<SelfReference> SelfReferences;
+ bool Frozen = false;
+
+ friend class ConstantInitFuture;
+ friend class ConstantAggregateBuilderBase;
+ template <class, class>
+ friend class ConstantAggregateBuilderTemplateBase;
+
+protected:
+ explicit ConstantInitBuilderBase(CodeGenModule &CGM) : CGM(CGM) {}
+
+ ~ConstantInitBuilderBase() {
+ assert(Buffer.empty() && "didn't claim all values out of buffer");
+ assert(SelfReferences.empty() && "didn't apply all self-references");
+ }
+
+private:
+ llvm::GlobalVariable *createGlobal(llvm::Constant *initializer,
+ const llvm::Twine &name,
+ CharUnits alignment,
+ bool constant = false,
+ llvm::GlobalValue::LinkageTypes linkage
+ = llvm::GlobalValue::InternalLinkage,
+ unsigned addressSpace = 0);
+
+ ConstantInitFuture createFuture(llvm::Constant *initializer);
+
+ void setGlobalInitializer(llvm::GlobalVariable *GV,
+ llvm::Constant *initializer);
+
+ void resolveSelfReferences(llvm::GlobalVariable *GV);
+
+ void abandon(size_t newEnd);
+};
+
+/// A concrete base class for struct and array aggregate
+/// initializer builders.
+class ConstantAggregateBuilderBase {
+protected:
+ ConstantInitBuilderBase &Builder;
+ ConstantAggregateBuilderBase *Parent;
+ size_t Begin;
+ mutable size_t CachedOffsetEnd = 0;
+ bool Finished = false;
+ bool Frozen = false;
+ bool Packed = false;
+ mutable CharUnits CachedOffsetFromGlobal;
+
+ llvm::SmallVectorImpl<llvm::Constant*> &getBuffer() {
+ return Builder.Buffer;
+ }
+
+ const llvm::SmallVectorImpl<llvm::Constant*> &getBuffer() const {
+ return Builder.Buffer;
+ }
+
+ ConstantAggregateBuilderBase(ConstantInitBuilderBase &builder,
+ ConstantAggregateBuilderBase *parent)
+ : Builder(builder), Parent(parent), Begin(builder.Buffer.size()) {
+ if (parent) {
+ assert(!parent->Frozen && "parent already has child builder active");
+ parent->Frozen = true;
+ } else {
+ assert(!builder.Frozen && "builder already has child builder active");
+ builder.Frozen = true;
+ }
+ }
+
+ ~ConstantAggregateBuilderBase() {
+ assert(Finished && "didn't finish aggregate builder");
+ }
+
+ void markFinished() {
+ assert(!Frozen && "child builder still active");
+ assert(!Finished && "builder already finished");
+ Finished = true;
+ if (Parent) {
+ assert(Parent->Frozen &&
+ "parent not frozen while child builder active");
+ Parent->Frozen = false;
+ } else {
+ assert(Builder.Frozen &&
+ "builder not frozen while child builder active");
+ Builder.Frozen = false;
+ }
+ }
+
+public:
+ // Not copyable.
+ ConstantAggregateBuilderBase(const ConstantAggregateBuilderBase &) = delete;
+ ConstantAggregateBuilderBase &operator=(const ConstantAggregateBuilderBase &)
+ = delete;
+
+ // Movable, mostly to allow returning. But we have to write this out
+ // properly to satisfy the assert in the destructor.
+ ConstantAggregateBuilderBase(ConstantAggregateBuilderBase &&other)
+ : Builder(other.Builder), Parent(other.Parent), Begin(other.Begin),
+ CachedOffsetEnd(other.CachedOffsetEnd),
+ Finished(other.Finished), Frozen(other.Frozen), Packed(other.Packed),
+ CachedOffsetFromGlobal(other.CachedOffsetFromGlobal) {
+ other.Finished = true;
+ }
+ ConstantAggregateBuilderBase &operator=(ConstantAggregateBuilderBase &&other)
+ = delete;
+
+ /// Return the number of elements that have been added to
+ /// this struct or array.
+ size_t size() const {
+ assert(!this->Finished && "cannot query after finishing builder");
+ assert(!this->Frozen && "cannot query while sub-builder is active");
+ assert(this->Begin <= this->getBuffer().size());
+ return this->getBuffer().size() - this->Begin;
+ }
+
+ /// Return true if no elements have yet been added to this struct or array.
+ bool empty() const {
+ return size() == 0;
+ }
+
+ /// Abandon this builder completely.
+ void abandon() {
+ markFinished();
+ Builder.abandon(Begin);
+ }
+
+ /// Add a new value to this initializer.
+ void add(llvm::Constant *value) {
+ assert(value && "adding null value to constant initializer");
+ assert(!Finished && "cannot add more values after finishing builder");
+ assert(!Frozen && "cannot add values while subbuilder is active");
+ Builder.Buffer.push_back(value);
+ }
+
+ /// Add an integer value of type size_t.
+ void addSize(CharUnits size);
+
+ /// Add an integer value of a specific type.
+ void addInt(llvm::IntegerType *intTy, uint64_t value,
+ bool isSigned = false) {
+ add(llvm::ConstantInt::get(intTy, value, isSigned));
+ }
+
+ /// Add a null pointer of a specific type.
+ void addNullPointer(llvm::PointerType *ptrTy) {
+ add(llvm::ConstantPointerNull::get(ptrTy));
+ }
+
+ /// Add a bitcast of a value to a specific type.
+ void addBitCast(llvm::Constant *value, llvm::Type *type) {
+ add(llvm::ConstantExpr::getBitCast(value, type));
+ }
+
+ /// Add a bunch of new values to this initializer.
+ void addAll(llvm::ArrayRef<llvm::Constant *> values) {
+ assert(!Finished && "cannot add more values after finishing builder");
+ assert(!Frozen && "cannot add values while subbuilder is active");
+ Builder.Buffer.append(values.begin(), values.end());
+ }
+
+ /// Add a relative offset to the given target address, i.e. the
+ /// static difference between the target address and the address
+ /// of the relative offset. The target must be known to be defined
+ /// in the current linkage unit. The offset will have the given
+ /// integer type, which must be no wider than intptr_t. Some
+ /// targets may not fully support this operation.
+ void addRelativeOffset(llvm::IntegerType *type, llvm::Constant *target) {
+ add(getRelativeOffset(type, target));
+ }
+
+ /// Add a relative offset to the target address, plus a small
+ /// constant offset. This is primarily useful when the relative
+ /// offset is known to be a multiple of (say) four and therefore
+ /// the tag can be used to express an extra two bits of information.
+ void addTaggedRelativeOffset(llvm::IntegerType *type,
+ llvm::Constant *address,
+ unsigned tag) {
+ llvm::Constant *offset = getRelativeOffset(type, address);
+ if (tag) {
+ offset = llvm::ConstantExpr::getAdd(offset,
+ llvm::ConstantInt::get(type, tag));
+ }
+ add(offset);
+ }
+
+ /// Return the offset from the start of the initializer to the
+ /// next position, assuming no padding is required prior to it.
+ ///
+ /// This operation will not succeed if any unsized placeholders are
+ /// currently in place in the initializer.
+ CharUnits getNextOffsetFromGlobal() const {
+ assert(!Finished && "cannot add more values after finishing builder");
+ assert(!Frozen && "cannot add values while subbuilder is active");
+ return getOffsetFromGlobalTo(Builder.Buffer.size());
+ }
+
+ /// An opaque class to hold the abstract position of a placeholder.
+ class PlaceholderPosition {
+ size_t Index;
+ friend class ConstantAggregateBuilderBase;
+ PlaceholderPosition(size_t index) : Index(index) {}
+ };
+
+ /// Add a placeholder value to the structure. The returned position
+ /// can be used to set the value later; it will not be invalidated by
+ /// any intermediate operations except (1) filling the same position or
+ /// (2) finishing the entire builder.
+ ///
+ /// This is useful for emitting certain kinds of structure which
+ /// contain some sort of summary field, generally a count, before any
+ /// of the data. By emitting a placeholder first, the structure can
+ /// be emitted eagerly.
+ PlaceholderPosition addPlaceholder() {
+ assert(!Finished && "cannot add more values after finishing builder");
+ assert(!Frozen && "cannot add values while subbuilder is active");
+ Builder.Buffer.push_back(nullptr);
+ return Builder.Buffer.size() - 1;
+ }
+
+ /// Add a placeholder, giving the expected type that will be filled in.
+ PlaceholderPosition addPlaceholderWithSize(llvm::Type *expectedType);
+
+ /// Fill a previously-added placeholder.
+ void fillPlaceholderWithInt(PlaceholderPosition position,
+ llvm::IntegerType *type, uint64_t value,
+ bool isSigned = false) {
+ fillPlaceholder(position, llvm::ConstantInt::get(type, value, isSigned));
+ }
+
+ /// Fill a previously-added placeholder.
+ void fillPlaceholder(PlaceholderPosition position, llvm::Constant *value) {
+ assert(!Finished && "cannot change values after finishing builder");
+ assert(!Frozen && "cannot add values while subbuilder is active");
+ llvm::Constant *&slot = Builder.Buffer[position.Index];
+ assert(slot == nullptr && "placeholder already filled");
+ slot = value;
+ }
+
+ /// Produce an address which will eventually point to the next
+ /// position to be filled. This is computed with an indexed
+ /// getelementptr rather than by computing offsets.
+ ///
+ /// The returned pointer will have type T*, where T is the given
+ /// position.
+ llvm::Constant *getAddrOfCurrentPosition(llvm::Type *type);
+
+ llvm::ArrayRef<llvm::Constant*> getGEPIndicesToCurrentPosition(
+ llvm::SmallVectorImpl<llvm::Constant*> &indices) {
+ getGEPIndicesTo(indices, Builder.Buffer.size());
+ return indices;
+ }
+
+protected:
+ llvm::Constant *finishArray(llvm::Type *eltTy);
+ llvm::Constant *finishStruct(llvm::StructType *structTy);
+
+private:
+ void getGEPIndicesTo(llvm::SmallVectorImpl<llvm::Constant*> &indices,
+ size_t position) const;
+
+ llvm::Constant *getRelativeOffset(llvm::IntegerType *offsetType,
+ llvm::Constant *target);
+
+ CharUnits getOffsetFromGlobalTo(size_t index) const;
+};
+
+template <class Impl, class Traits>
+class ConstantAggregateBuilderTemplateBase
+ : public Traits::AggregateBuilderBase {
+ using super = typename Traits::AggregateBuilderBase;
+public:
+ using InitBuilder = typename Traits::InitBuilder;
+ using ArrayBuilder = typename Traits::ArrayBuilder;
+ using StructBuilder = typename Traits::StructBuilder;
+ using AggregateBuilderBase = typename Traits::AggregateBuilderBase;
+
+protected:
+ ConstantAggregateBuilderTemplateBase(InitBuilder &builder,
+ AggregateBuilderBase *parent)
+ : super(builder, parent) {}
+
+ Impl &asImpl() { return *static_cast<Impl*>(this); }
+
+public:
+ ArrayBuilder beginArray(llvm::Type *eltTy = nullptr) {
+ return ArrayBuilder(static_cast<InitBuilder&>(this->Builder), this, eltTy);
+ }
+
+ StructBuilder beginStruct(llvm::StructType *ty = nullptr) {
+ return StructBuilder(static_cast<InitBuilder&>(this->Builder), this, ty);
+ }
+
+ /// Given that this builder was created by beginning an array or struct
+ /// component on the given parent builder, finish the array/struct
+ /// component and add it to the parent.
+ ///
+ /// It is an intentional choice that the parent is passed in explicitly
+ /// despite it being redundant with information already kept in the
+ /// builder. This aids in readability by making it easier to find the
+ /// places that add components to a builder, as well as "bookending"
+ /// the sub-builder more explicitly.
+ void finishAndAddTo(AggregateBuilderBase &parent) {
+ assert(this->Parent == &parent && "adding to non-parent builder");
+ parent.add(asImpl().finishImpl());
+ }
+
+ /// Given that this builder was created by beginning an array or struct
+ /// directly on a ConstantInitBuilder, finish the array/struct and
+ /// create a global variable with it as the initializer.
+ template <class... As>
+ llvm::GlobalVariable *finishAndCreateGlobal(As &&...args) {
+ assert(!this->Parent && "finishing non-root builder");
+ return this->Builder.createGlobal(asImpl().finishImpl(),
+ std::forward<As>(args)...);
+ }
+
+ /// Given that this builder was created by beginning an array or struct
+ /// directly on a ConstantInitBuilder, finish the array/struct and
+ /// set it as the initializer of the given global variable.
+ void finishAndSetAsInitializer(llvm::GlobalVariable *global) {
+ assert(!this->Parent && "finishing non-root builder");
+ return this->Builder.setGlobalInitializer(global, asImpl().finishImpl());
+ }
+
+ /// Given that this builder was created by beginning an array or struct
+ /// directly on a ConstantInitBuilder, finish the array/struct and
+ /// return a future which can be used to install the initializer in
+ /// a global later.
+ ///
+ /// This is useful for allowing a finished initializer to passed to
+ /// an API which will build the global. However, the "future" preserves
+ /// a dependency on the original builder; it is an error to pass it aside.
+ ConstantInitFuture finishAndCreateFuture() {
+ assert(!this->Parent && "finishing non-root builder");
+ return this->Builder.createFuture(asImpl().finishImpl());
+ }
+};
+
+template <class Traits>
+class ConstantArrayBuilderTemplateBase
+ : public ConstantAggregateBuilderTemplateBase<typename Traits::ArrayBuilder,
+ Traits> {
+ using super =
+ ConstantAggregateBuilderTemplateBase<typename Traits::ArrayBuilder, Traits>;
+
+public:
+ using InitBuilder = typename Traits::InitBuilder;
+ using AggregateBuilderBase = typename Traits::AggregateBuilderBase;
+
+private:
+ llvm::Type *EltTy;
+
+ template <class, class>
+ friend class ConstantAggregateBuilderTemplateBase;
+
+protected:
+ ConstantArrayBuilderTemplateBase(InitBuilder &builder,
+ AggregateBuilderBase *parent,
+ llvm::Type *eltTy)
+ : super(builder, parent), EltTy(eltTy) {}
+
+private:
+ /// Form an array constant from the values that have been added to this
+ /// builder.
+ llvm::Constant *finishImpl() {
+ return AggregateBuilderBase::finishArray(EltTy);
+ }
+};
+
+/// A template class designed to allow other frontends to
+/// easily customize the builder classes used by ConstantInitBuilder,
+/// and thus to extend the API to work with the abstractions they
+/// prefer. This would probably not be necessary if C++ just
+/// supported extension methods.
+template <class Traits>
+class ConstantStructBuilderTemplateBase
+ : public ConstantAggregateBuilderTemplateBase<typename Traits::StructBuilder,
+ Traits> {
+ using super =
+ ConstantAggregateBuilderTemplateBase<typename Traits::StructBuilder,Traits>;
+
+public:
+ using InitBuilder = typename Traits::InitBuilder;
+ using AggregateBuilderBase = typename Traits::AggregateBuilderBase;
+
+private:
+ llvm::StructType *StructTy;
+
+ template <class, class>
+ friend class ConstantAggregateBuilderTemplateBase;
+
+protected:
+ ConstantStructBuilderTemplateBase(InitBuilder &builder,
+ AggregateBuilderBase *parent,
+ llvm::StructType *structTy)
+ : super(builder, parent), StructTy(structTy) {
+ if (structTy) this->Packed = structTy->isPacked();
+ }
+
+public:
+ void setPacked(bool packed) {
+ this->Packed = packed;
+ }
+
+ /// Use the given type for the struct if its element count is correct.
+ /// Don't add more elements after calling this.
+ void suggestType(llvm::StructType *structTy) {
+ if (this->size() == structTy->getNumElements()) {
+ StructTy = structTy;
+ }
+ }
+
+private:
+ /// Form an array constant from the values that have been added to this
+ /// builder.
+ llvm::Constant *finishImpl() {
+ return AggregateBuilderBase::finishStruct(StructTy);
+ }
+};
+
+/// A template class designed to allow other frontends to
+/// easily customize the builder classes used by ConstantInitBuilder,
+/// and thus to extend the API to work with the abstractions they
+/// prefer. This would probably not be necessary if C++ just
+/// supported extension methods.
+template <class Traits>
+class ConstantInitBuilderTemplateBase : public ConstantInitBuilderBase {
+protected:
+ ConstantInitBuilderTemplateBase(CodeGenModule &CGM)
+ : ConstantInitBuilderBase(CGM) {}
+
+public:
+ using InitBuilder = typename Traits::InitBuilder;
+ using ArrayBuilder = typename Traits::ArrayBuilder;
+ using StructBuilder = typename Traits::StructBuilder;
+
+ ArrayBuilder beginArray(llvm::Type *eltTy = nullptr) {
+ return ArrayBuilder(static_cast<InitBuilder&>(*this), nullptr, eltTy);
+ }
+
+ StructBuilder beginStruct(llvm::StructType *structTy = nullptr) {
+ return StructBuilder(static_cast<InitBuilder&>(*this), nullptr, structTy);
+ }
+};
+
+class ConstantInitBuilder;
+class ConstantStructBuilder;
+class ConstantArrayBuilder;
+
+struct ConstantInitBuilderTraits {
+ using InitBuilder = ConstantInitBuilder;
+ using AggregateBuilderBase = ConstantAggregateBuilderBase;
+ using ArrayBuilder = ConstantArrayBuilder;
+ using StructBuilder = ConstantStructBuilder;
+};
+
+/// The standard implementation of ConstantInitBuilder used in Clang.
+class ConstantInitBuilder
+ : public ConstantInitBuilderTemplateBase<ConstantInitBuilderTraits> {
+public:
+ explicit ConstantInitBuilder(CodeGenModule &CGM) :
+ ConstantInitBuilderTemplateBase(CGM) {}
+};
+
+/// A helper class of ConstantInitBuilder, used for building constant
+/// array initializers.
+class ConstantArrayBuilder
+ : public ConstantArrayBuilderTemplateBase<ConstantInitBuilderTraits> {
+ template <class Traits>
+ friend class ConstantInitBuilderTemplateBase;
+
+ // The use of explicit qualification is a GCC workaround.
+ template <class Impl, class Traits>
+ friend class CodeGen::ConstantAggregateBuilderTemplateBase;
+
+ ConstantArrayBuilder(ConstantInitBuilder &builder,
+ ConstantAggregateBuilderBase *parent,
+ llvm::Type *eltTy)
+ : ConstantArrayBuilderTemplateBase(builder, parent, eltTy) {}
+};
+
+/// A helper class of ConstantInitBuilder, used for building constant
+/// struct initializers.
+class ConstantStructBuilder
+ : public ConstantStructBuilderTemplateBase<ConstantInitBuilderTraits> {
+ template <class Traits>
+ friend class ConstantInitBuilderTemplateBase;
+
+ // The use of explicit qualification is a GCC workaround.
+ template <class Impl, class Traits>
+ friend class CodeGen::ConstantAggregateBuilderTemplateBase;
+
+ ConstantStructBuilder(ConstantInitBuilder &builder,
+ ConstantAggregateBuilderBase *parent,
+ llvm::StructType *structTy)
+ : ConstantStructBuilderTemplateBase(builder, parent, structTy) {}
+};
+
+} // end namespace CodeGen
+} // end namespace clang
+
+#endif
diff --git a/clang-r353983/include/clang/CodeGen/ConstantInitFuture.h b/clang-r353983/include/clang/CodeGen/ConstantInitFuture.h
new file mode 100644
index 00000000..b08f5287
--- /dev/null
+++ b/clang-r353983/include/clang/CodeGen/ConstantInitFuture.h
@@ -0,0 +1,108 @@
+//===- ConstantInitFuture.h - "Future" constant initializers ----*- C++ -*-===//
+//
+// 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 class defines the ConstantInitFuture class. This is split out
+// from ConstantInitBuilder.h in order to allow APIs to work with it
+// without having to include that entire header. This is particularly
+// important because it is often useful to be able to default-construct
+// a future in, say, a default argument.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_CODEGEN_CONSTANTINITFUTURE_H
+#define LLVM_CLANG_CODEGEN_CONSTANTINITFUTURE_H
+
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/IR/Constant.h"
+
+// Forward-declare ConstantInitBuilderBase and give it a
+// PointerLikeTypeTraits specialization so that we can safely use it
+// in a PointerUnion below.
+namespace clang {
+namespace CodeGen {
+class ConstantInitBuilderBase;
+}
+}
+namespace llvm {
+template <>
+struct PointerLikeTypeTraits< ::clang::CodeGen::ConstantInitBuilderBase*> {
+ using T = ::clang::CodeGen::ConstantInitBuilderBase*;
+
+ static inline void *getAsVoidPointer(T p) { return p; }
+ static inline T getFromVoidPointer(void *p) {return static_cast<T>(p);}
+ enum { NumLowBitsAvailable = 2 };
+};
+}
+
+namespace clang {
+namespace CodeGen {
+
+/// A "future" for a completed constant initializer, which can be passed
+/// around independently of any sub-builders (but not the original parent).
+class ConstantInitFuture {
+ using PairTy = llvm::PointerUnion<ConstantInitBuilderBase*, llvm::Constant*>;
+
+ PairTy Data;
+
+ friend class ConstantInitBuilderBase;
+ explicit ConstantInitFuture(ConstantInitBuilderBase *builder);
+
+public:
+ ConstantInitFuture() {}
+
+ /// A future can be explicitly created from a fixed initializer.
+ explicit ConstantInitFuture(llvm::Constant *initializer) : Data(initializer) {
+ assert(initializer && "creating null future");
+ }
+
+ /// Is this future non-null?
+ explicit operator bool() const { return bool(Data); }
+
+ /// Return the type of the initializer.
+ llvm::Type *getType() const;
+
+ /// Abandon this initializer.
+ void abandon();
+
+ /// Install the initializer into a global variable. This cannot
+ /// be called multiple times.
+ void installInGlobal(llvm::GlobalVariable *global);
+
+ void *getOpaqueValue() const { return Data.getOpaqueValue(); }
+ static ConstantInitFuture getFromOpaqueValue(void *value) {
+ ConstantInitFuture result;
+ result.Data = PairTy::getFromOpaqueValue(value);
+ return result;
+ }
+ enum {
+ NumLowBitsAvailable =
+ llvm::PointerLikeTypeTraits<PairTy>::NumLowBitsAvailable
+ };
+};
+
+} // end namespace CodeGen
+} // end namespace clang
+
+namespace llvm {
+
+template <>
+struct PointerLikeTypeTraits< ::clang::CodeGen::ConstantInitFuture> {
+ using T = ::clang::CodeGen::ConstantInitFuture;
+
+ static inline void *getAsVoidPointer(T future) {
+ return future.getOpaqueValue();
+ }
+ static inline T getFromVoidPointer(void *p) {
+ return T::getFromOpaqueValue(p);
+ }
+ enum { NumLowBitsAvailable = T::NumLowBitsAvailable };
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/clang-r353983/include/clang/CodeGen/ModuleBuilder.h b/clang-r353983/include/clang/CodeGen/ModuleBuilder.h
new file mode 100644
index 00000000..f9d056ed
--- /dev/null
+++ b/clang-r353983/include/clang/CodeGen/ModuleBuilder.h
@@ -0,0 +1,105 @@
+//===--- CodeGen/ModuleBuilder.h - Build LLVM from ASTs ---------*- C++ -*-===//
+//
+// 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 ModuleBuilder interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_CODEGEN_MODULEBUILDER_H
+#define LLVM_CLANG_CODEGEN_MODULEBUILDER_H
+
+#include "clang/AST/ASTConsumer.h"
+
+namespace llvm {
+ class Constant;
+ class LLVMContext;
+ class Module;
+ class StringRef;
+}
+
+namespace clang {
+ class CodeGenOptions;
+ class CoverageSourceInfo;
+ class Decl;
+ class DiagnosticsEngine;
+ class GlobalDecl;
+ class HeaderSearchOptions;
+ class LangOptions;
+ class PreprocessorOptions;
+
+namespace CodeGen {
+ class CodeGenModule;
+ class CGDebugInfo;
+}
+
+/// The primary public interface to the Clang code generator.
+///
+/// This is not really an abstract interface.
+class CodeGenerator : public ASTConsumer {
+ virtual void anchor();
+
+public:
+ /// Return an opaque reference to the CodeGenModule object, which can
+ /// be used in various secondary APIs. It is valid as long as the
+ /// CodeGenerator exists.
+ CodeGen::CodeGenModule &CGM();
+
+ /// Return the module that this code generator is building into.
+ ///
+ /// This may return null after HandleTranslationUnit is called;
+ /// this signifies that there was an error generating code. A
+ /// diagnostic will have been generated in this case, and the module
+ /// will be deleted.
+ ///
+ /// It will also return null if the module is released.
+ llvm::Module *GetModule();
+
+ /// Release ownership of the module to the caller.
+ ///
+ /// It is illegal to call methods other than GetModule on the
+ /// CodeGenerator after releasing its module.
+ llvm::Module *ReleaseModule();
+
+ /// Return debug info code generator.
+ CodeGen::CGDebugInfo *getCGDebugInfo();
+
+ /// Given a mangled name, return a declaration which mangles that way
+ /// which has been added to this code generator via a Handle method.
+ ///
+ /// This may return null if there was no matching declaration.
+ const Decl *GetDeclForMangledName(llvm::StringRef MangledName);
+
+ /// Return the LLVM address of the given global entity.
+ ///
+ /// \param isForDefinition If true, the caller intends to define the
+ /// entity; the object returned will be an llvm::GlobalValue of
+ /// some sort. If false, the caller just intends to use the entity;
+ /// the object returned may be any sort of constant value, and the
+ /// code generator will schedule the entity for emission if a
+ /// definition has been registered with this code generator.
+ llvm::Constant *GetAddrOfGlobal(GlobalDecl decl, bool isForDefinition);
+
+ /// Create a new \c llvm::Module after calling HandleTranslationUnit. This
+ /// enable codegen in interactive processing environments.
+ llvm::Module* StartModule(llvm::StringRef ModuleName, llvm::LLVMContext &C);
+};
+
+/// CreateLLVMCodeGen - Create a CodeGenerator instance.
+/// It is the responsibility of the caller to call delete on
+/// the allocated CodeGenerator instance.
+CodeGenerator *CreateLLVMCodeGen(DiagnosticsEngine &Diags,
+ llvm::StringRef ModuleName,
+ const HeaderSearchOptions &HeaderSearchOpts,
+ const PreprocessorOptions &PreprocessorOpts,
+ const CodeGenOptions &CGO,
+ llvm::LLVMContext& C,
+ CoverageSourceInfo *CoverageInfo = nullptr);
+
+} // end namespace clang
+
+#endif
diff --git a/clang-r353983/include/clang/CodeGen/ObjectFilePCHContainerOperations.h b/clang-r353983/include/clang/CodeGen/ObjectFilePCHContainerOperations.h
new file mode 100644
index 00000000..8821cd70
--- /dev/null
+++ b/clang-r353983/include/clang/CodeGen/ObjectFilePCHContainerOperations.h
@@ -0,0 +1,42 @@
+//===-- CodeGen/ObjectFilePCHContainerOperations.h - ------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_CODEGEN_OBJECT_FILE_PCH_CONTAINER_OPERATIONS_H
+#define LLVM_CLANG_CODEGEN_OBJECT_FILE_PCH_CONTAINER_OPERATIONS_H
+
+#include "clang/Frontend/PCHContainerOperations.h"
+
+namespace clang {
+
+/// A PCHContainerWriter implementation that uses LLVM to
+/// wraps Clang modules inside a COFF, ELF, or Mach-O container.
+class ObjectFilePCHContainerWriter : public PCHContainerWriter {
+ StringRef getFormat() const override { return "obj"; }
+
+ /// Return an ASTConsumer that can be chained with a
+ /// PCHGenerator that produces a wrapper file format
+ /// that also contains full debug info for the module.
+ std::unique_ptr<ASTConsumer>
+ CreatePCHContainerGenerator(CompilerInstance &CI,
+ const std::string &MainFileName,
+ const std::string &OutputFileName,
+ std::unique_ptr<llvm::raw_pwrite_stream> OS,
+ std::shared_ptr<PCHBuffer> Buffer) const override;
+};
+
+/// A PCHContainerReader implementation that uses LLVM to
+/// wraps Clang modules inside a COFF, ELF, or Mach-O container.
+class ObjectFilePCHContainerReader : public PCHContainerReader {
+ StringRef getFormat() const override { return "obj"; }
+
+ /// Returns the serialized AST inside the PCH container Buffer.
+ StringRef ExtractPCH(llvm::MemoryBufferRef Buffer) const override;
+};
+}
+
+#endif
diff --git a/clang-r353983/include/clang/CodeGen/SwiftCallingConv.h b/clang-r353983/include/clang/CodeGen/SwiftCallingConv.h
new file mode 100644
index 00000000..2c5e9a6d
--- /dev/null
+++ b/clang-r353983/include/clang/CodeGen/SwiftCallingConv.h
@@ -0,0 +1,184 @@
+//==-- SwiftCallingConv.h - Swift ABI lowering ------------------*- C++ -*-===//
+//
+// 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 constants and types related to Swift ABI lowering.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_CODEGEN_SWIFTCALLINGCONV_H
+#define LLVM_CLANG_CODEGEN_SWIFTCALLINGCONV_H
+
+#include "clang/AST/CanonicalType.h"
+#include "clang/AST/CharUnits.h"
+#include "clang/AST/Type.h"
+#include "llvm/Support/TrailingObjects.h"
+#include <cassert>
+
+namespace llvm {
+ class IntegerType;
+ class Type;
+ class StructType;
+ class VectorType;
+}
+
+namespace clang {
+class Decl;
+class FieldDecl;
+class ASTRecordLayout;
+
+namespace CodeGen {
+class ABIArgInfo;
+class CodeGenModule;
+class CGFunctionInfo;
+
+namespace swiftcall {
+
+class SwiftAggLowering {
+ CodeGenModule &CGM;
+
+ struct StorageEntry {
+ CharUnits Begin;
+ CharUnits End;
+ llvm::Type *Type;
+
+ CharUnits getWidth() const {
+ return End - Begin;
+ }
+ };
+ SmallVector<StorageEntry, 4> Entries;
+ bool Finished = false;
+
+public:
+ SwiftAggLowering(CodeGenModule &CGM) : CGM(CGM) {}
+
+ void addOpaqueData(CharUnits begin, CharUnits end) {
+ addEntry(nullptr, begin, end);
+ }
+
+ void addTypedData(QualType type, CharUnits begin);
+ void addTypedData(const RecordDecl *record, CharUnits begin);
+ void addTypedData(const RecordDecl *record, CharUnits begin,
+ const ASTRecordLayout &layout);
+ void addTypedData(llvm::Type *type, CharUnits begin);
+ void addTypedData(llvm::Type *type, CharUnits begin, CharUnits end);
+
+ void finish();
+
+ /// Does this lowering require passing any data?
+ bool empty() const {
+ assert(Finished && "didn't finish lowering before calling empty()");
+ return Entries.empty();
+ }
+
+ /// According to the target Swift ABI, should a value with this lowering
+ /// be passed indirectly?
+ ///
+ /// Note that this decision is based purely on the data layout of the
+ /// value and does not consider whether the type is address-only,
+ /// must be passed indirectly to match a function abstraction pattern, or
+ /// anything else that is expected to be handled by high-level lowering.
+ ///
+ /// \param asReturnValue - if true, answer whether it should be passed
+ /// indirectly as a return value; if false, answer whether it should be
+ /// passed indirectly as an argument
+ bool shouldPassIndirectly(bool asReturnValue) const;
+
+ using EnumerationCallback =
+ llvm::function_ref<void(CharUnits offset, CharUnits end, llvm::Type *type)>;
+
+ /// Enumerate the expanded components of this type.
+ ///
+ /// The component types will always be legal vector, floating-point,
+ /// integer, or pointer types.
+ void enumerateComponents(EnumerationCallback callback) const;
+
+ /// Return the types for a coerce-and-expand operation.
+ ///
+ /// The first type matches the memory layout of the data that's been
+ /// added to this structure, including explicit [N x i8] arrays for any
+ /// internal padding.
+ ///
+ /// The second type removes any internal padding members and, if only
+ /// one element remains, is simply that element type.
+ std::pair<llvm::StructType*, llvm::Type*> getCoerceAndExpandTypes() const;
+
+private:
+ void addBitFieldData(const FieldDecl *field, CharUnits begin,
+ uint64_t bitOffset);
+ void addLegalTypedData(llvm::Type *type, CharUnits begin, CharUnits end);
+ void addEntry(llvm::Type *type, CharUnits begin, CharUnits end);
+ void splitVectorEntry(unsigned index);
+ static bool shouldMergeEntries(const StorageEntry &first,
+ const StorageEntry &second,
+ CharUnits chunkSize);
+};
+
+/// Should an aggregate which expands to the given type sequence
+/// be passed/returned indirectly under swiftcall?
+bool shouldPassIndirectly(CodeGenModule &CGM,
+ ArrayRef<llvm::Type*> types,
+ bool asReturnValue);
+
+/// Return the maximum voluntary integer size for the current target.
+CharUnits getMaximumVoluntaryIntegerSize(CodeGenModule &CGM);
+
+/// Return the Swift CC's notion of the natural alignment of a type.
+CharUnits getNaturalAlignment(CodeGenModule &CGM, llvm::Type *type);
+
+/// Is the given integer type "legal" for Swift's perspective on the
+/// current platform?
+bool isLegalIntegerType(CodeGenModule &CGM, llvm::IntegerType *type);
+
+/// Is the given vector type "legal" for Swift's perspective on the
+/// current platform?
+bool isLegalVectorType(CodeGenModule &CGM, CharUnits vectorSize,
+ llvm::VectorType *vectorTy);
+bool isLegalVectorType(CodeGenModule &CGM, CharUnits vectorSize,
+ llvm::Type *eltTy, unsigned numElts);
+
+/// Minimally split a legal vector type.
+std::pair<llvm::Type*, unsigned>
+splitLegalVectorType(CodeGenModule &CGM, CharUnits vectorSize,
+ llvm::VectorType *vectorTy);
+
+/// Turn a vector type in a sequence of legal component vector types.
+///
+/// The caller may assume that the sum of the data sizes of the resulting
+/// types will equal the data size of the vector type.
+void legalizeVectorType(CodeGenModule &CGM, CharUnits vectorSize,
+ llvm::VectorType *vectorTy,
+ llvm::SmallVectorImpl<llvm::Type*> &types);
+
+/// Is the given record type required to be passed and returned indirectly
+/// because of language restrictions?
+///
+/// This considers *only* mandatory indirectness due to language restrictions,
+/// such as C++'s non-trivially-copyable types and Objective-C's __weak
+/// references. A record for which this returns true may still be passed
+/// indirectly for other reasons, such as being too large to fit in a
+/// reasonable number of registers.
+bool mustPassRecordIndirectly(CodeGenModule &CGM, const RecordDecl *record);
+
+/// Classify the rules for how to return a particular type.
+ABIArgInfo classifyReturnType(CodeGenModule &CGM, CanQualType type);
+
+/// Classify the rules for how to pass a particular type.
+ABIArgInfo classifyArgumentType(CodeGenModule &CGM, CanQualType type);
+
+/// Compute the ABI information of a swiftcall function. This is a
+/// private interface for Clang.
+void computeABIInfo(CodeGenModule &CGM, CGFunctionInfo &FI);
+
+/// Is swifterror lowered to a register by the target ABI?
+bool isSwiftErrorLoweredInRegister(CodeGenModule &CGM);
+
+} // end namespace swiftcall
+} // end namespace CodeGen
+} // end namespace clang
+
+#endif