diff --git a/installation/docker/Dockerfile b/installation/docker/Dockerfile index a2a388a..a6d83fb 100644 --- a/installation/docker/Dockerfile +++ b/installation/docker/Dockerfile @@ -1,41 +1,39 @@ FROM opensuse-tumbleweed MAINTAINER Melnychenko Volodymyr ARG CLANG_VERSION=3_8 ARG BOOST_VERSION=_1_61 ARG CLASP_VERSION=a363d9 RUN zypper in -y \ boost$BOOST_VERSION-devel clang$CLANG_VERSION-devel llvm$CLANG_VERSION-gold gcc6-c++ \ tbb-devel cmake git bison re2c scons unzip libgtest0 googletest-devel libxml2-devel wget ## COCO WORKDIR /opt/coco-cpp RUN wget http://www.ssw.uni-linz.ac.at/Coco/CPP/CocoSourcesCPP.zip &&\ unzip ./CocoSourcesCPP.zip &&\ g++-6 *.cpp -o Coco -g -Wall # POTASSCO WORKDIR /opt/potassco/clingo/ RUN git clone https://github.com/potassco/clingo.git ./ &&\ git reset --hard $CLASP_VERSION ADD patches/potassco-patch-$CLASP_VERSION . RUN git apply potassco-patch-$CLASP_VERSION &&\ scons configure --build-dir=debug &&\ sed -i "s/CXXFLAGS = \[\(.*\)\]/CXXFLAGS = \['-fPIC', \1\]/" build/debug.py &&\ sed -i "s/CXX = 'c++'/CXX = 'g++-6'/" build/debug.py &&\ sed -i "s/WITH_LUA = 'auto'/WITH_LUA = None/" build/debug.py &&\ sed -i "s/WITH_PYTHON = 'auto'/WITH_PYTHON = None/" build/debug.py &&\ cat build/debug.py &&\ scons --build-dir=debug # sed -i "s/'-std=c++11'/'-std=c++14'/" build/debug.py # XREATE -WORKDIR /opt/xreate -RUN git clone https://pgess@bitbucket.org/pgess/xreate.git ./ - -WORKDIR /opt/xreate/build -RUN cmake -DBUILD_XREATE_TESTS=1 ../cpp &&\ - make -j4 +WORKDIR /opt/xreate-build +RUN git clone https://pgess@bitbucket.org/pgess/xreate.git ../xreate &&\ + cmake -DBUILD_XREATE_TESTS=1 ../xreate/cpp &&\ + make -j4 diff --git a/vendors/clang-codegen-private-3.8/ABIInfo.h b/vendors/clang-codegen-private-3.8/ABIInfo.h new file mode 100644 index 0000000..a65f270 --- /dev/null +++ b/vendors/clang-codegen-private-3.8/ABIInfo.h @@ -0,0 +1,116 @@ +//===----- ABIInfo.h - ABI information access & encapsulation ---*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LIB_CODEGEN_ABIINFO_H +#define LLVM_CLANG_LIB_CODEGEN_ABIINFO_H + +#include "clang/AST/Type.h" +#include "llvm/IR/CallingConv.h" +#include "llvm/IR/Type.h" + +namespace llvm { + class Value; + class LLVMContext; + class DataLayout; +} + +namespace clang { + class ASTContext; + class TargetInfo; + + namespace CodeGen { + class ABIArgInfo; + class Address; + class CGCXXABI; + class CGFunctionInfo; + class CodeGenFunction; + class CodeGenTypes; + } + + // FIXME: All of this stuff should be part of the target interface + // somehow. It is currently here because it is not clear how to factor + // the targets to support this, since the Targets currently live in a + // layer below types n'stuff. + + + /// ABIInfo - Target specific hooks for defining how a type should be + /// passed or returned from functions. + class ABIInfo { + public: + CodeGen::CodeGenTypes &CGT; + protected: + llvm::CallingConv::ID RuntimeCC; + llvm::CallingConv::ID BuiltinCC; + public: + ABIInfo(CodeGen::CodeGenTypes &cgt) + : CGT(cgt), + RuntimeCC(llvm::CallingConv::C), + BuiltinCC(llvm::CallingConv::C) {} + + virtual ~ABIInfo(); + + CodeGen::CGCXXABI &getCXXABI() const; + ASTContext &getContext() const; + llvm::LLVMContext &getVMContext() const; + const llvm::DataLayout &getDataLayout() const; + const TargetInfo &getTarget() const; + + /// Return the calling convention to use for system runtime + /// functions. + llvm::CallingConv::ID getRuntimeCC() const { + return RuntimeCC; + } + + /// Return the calling convention to use for compiler builtins + llvm::CallingConv::ID getBuiltinCC() const { + return BuiltinCC; + } + + virtual void computeInfo(CodeGen::CGFunctionInfo &FI) const = 0; + + /// EmitVAArg - Emit the target dependent code to load a value of + /// \arg Ty from the va_list pointed to by \arg VAListAddr. + + // FIXME: This is a gaping layering violation if we wanted to drop + // the ABI information any lower than CodeGen. Of course, for + // VAArg handling it has to be at this level; there is no way to + // abstract this out. + virtual CodeGen::Address EmitVAArg(CodeGen::CodeGenFunction &CGF, + CodeGen::Address VAListAddr, + QualType Ty) const = 0; + + /// Emit the target dependent code to load a value of + /// \arg Ty from the \c __builtin_ms_va_list pointed to by \arg VAListAddr. + virtual CodeGen::Address EmitMSVAArg(CodeGen::CodeGenFunction &CGF, + CodeGen::Address VAListAddr, + QualType Ty) const; + + virtual bool isHomogeneousAggregateBaseType(QualType Ty) const; + + virtual bool isHomogeneousAggregateSmallEnough(const Type *Base, + uint64_t Members) const; + + virtual bool shouldSignExtUnsignedType(QualType Ty) const; + + bool isHomogeneousAggregate(QualType Ty, const Type *&Base, + uint64_t &Members) const; + + /// A convenience method to return an indirect ABIArgInfo with an + /// expected alignment equal to the ABI alignment of the given type. + CodeGen::ABIArgInfo + getNaturalAlignIndirect(QualType Ty, bool ByRef = true, + bool Realign = false, + llvm::Type *Padding = nullptr) const; + + CodeGen::ABIArgInfo + getNaturalAlignIndirectInReg(QualType Ty, bool Realign = false) const; + }; +} // end namespace clang + +#endif diff --git a/vendors/clang-codegen-private-3.8/Address.h b/vendors/clang-codegen-private-3.8/Address.h new file mode 100644 index 0000000..3343080 --- /dev/null +++ b/vendors/clang-codegen-private-3.8/Address.h @@ -0,0 +1,118 @@ +//===-- Address.h - An aligned address -------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This class provides a simple wrapper for a pair of a pointer and an +// alignment. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LIB_CODEGEN_ADDRESS_H +#define LLVM_CLANG_LIB_CODEGEN_ADDRESS_H + +#include "llvm/IR/Constants.h" +#include "clang/AST/CharUnits.h" + +namespace clang { +namespace CodeGen { + +/// An aligned address. +class Address { + llvm::Value *Pointer; + CharUnits Alignment; +public: + Address(llvm::Value *pointer, CharUnits alignment) + : Pointer(pointer), Alignment(alignment) { + assert((!alignment.isZero() || pointer == nullptr) && + "creating valid address with invalid alignment"); + } + + static Address invalid() { return Address(nullptr, CharUnits()); } + bool isValid() const { return Pointer != nullptr; } + + llvm::Value *getPointer() const { + assert(isValid()); + return Pointer; + } + + /// Return the type of the pointer value. + llvm::PointerType *getType() const { + return llvm::cast(getPointer()->getType()); + } + + /// Return the type of the values stored in this address. + /// + /// When IR pointer types lose their element type, we should simply + /// store it in Address instead for the convenience of writing code. + llvm::Type *getElementType() const { + return getType()->getElementType(); + } + + /// Return the address space that this address resides in. + unsigned getAddressSpace() const { + return getType()->getAddressSpace(); + } + + /// Return the IR name of the pointer value. + llvm::StringRef getName() const { + return getPointer()->getName(); + } + + /// Return the alignment of this pointer. + CharUnits getAlignment() const { + assert(isValid()); + return Alignment; + } +}; + +/// A specialization of Address that requires the address to be an +/// LLVM Constant. +class ConstantAddress : public Address { +public: + ConstantAddress(llvm::Constant *pointer, CharUnits alignment) + : Address(pointer, alignment) {} + + static ConstantAddress invalid() { + return ConstantAddress(nullptr, CharUnits()); + } + + llvm::Constant *getPointer() const { + return llvm::cast(Address::getPointer()); + } + + ConstantAddress getBitCast(llvm::Type *ty) const { + return ConstantAddress(llvm::ConstantExpr::getBitCast(getPointer(), ty), + getAlignment()); + } + + ConstantAddress getElementBitCast(llvm::Type *ty) const { + return getBitCast(ty->getPointerTo(getAddressSpace())); + } + + static bool isaImpl(Address addr) { + return llvm::isa(addr.getPointer()); + } + static ConstantAddress castImpl(Address addr) { + return ConstantAddress(llvm::cast(addr.getPointer()), + addr.getAlignment()); + } +}; + +} + +// Present a minimal LLVM-like casting interface. +template inline U cast(CodeGen::Address addr) { + return U::castImpl(addr); +} +template inline bool isa(CodeGen::Address addr) { + return U::isaImpl(addr); +} + +} + +#endif diff --git a/vendors/clang-codegen-private-3.8/CGCall.h b/vendors/clang-codegen-private-3.8/CGCall.h new file mode 100644 index 0000000..2ebd09b --- /dev/null +++ b/vendors/clang-codegen-private-3.8/CGCall.h @@ -0,0 +1,178 @@ +//===----- CGCall.h - Encapsulate calling convention details ----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// These classes wrap the information about a call or function +// definition used to handle ABI compliancy. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LIB_CODEGEN_CGCALL_H +#define LLVM_CLANG_LIB_CODEGEN_CGCALL_H + +#include "CGValue.h" +#include "EHScopeStack.h" +#include "clang/AST/CanonicalType.h" +#include "clang/AST/Type.h" +#include "llvm/ADT/FoldingSet.h" +#include "llvm/IR/Value.h" + +// FIXME: Restructure so we don't have to expose so much stuff. +#include "ABIInfo.h" + +namespace llvm { + class AttributeSet; + class Function; + class Type; + class Value; +} + +namespace clang { + class ASTContext; + class Decl; + class FunctionDecl; + class ObjCMethodDecl; + class VarDecl; + +namespace CodeGen { + typedef SmallVector AttributeListType; + + struct CallArg { + RValue RV; + QualType Ty; + bool NeedsCopy; + CallArg(RValue rv, QualType ty, bool needscopy) + : RV(rv), Ty(ty), NeedsCopy(needscopy) + { } + }; + + /// CallArgList - Type for representing both the value and type of + /// arguments in a call. + class CallArgList : + public SmallVector { + public: + CallArgList() : StackBase(nullptr) {} + + struct Writeback { + /// The original argument. Note that the argument l-value + /// is potentially null. + LValue Source; + + /// The temporary alloca. + Address Temporary; + + /// A value to "use" after the writeback, or null. + llvm::Value *ToUse; + }; + + struct CallArgCleanup { + EHScopeStack::stable_iterator Cleanup; + + /// The "is active" insertion point. This instruction is temporary and + /// will be removed after insertion. + llvm::Instruction *IsActiveIP; + }; + + void add(RValue rvalue, QualType type, bool needscopy = false) { + push_back(CallArg(rvalue, type, needscopy)); + } + + void addFrom(const CallArgList &other) { + insert(end(), other.begin(), other.end()); + Writebacks.insert(Writebacks.end(), + other.Writebacks.begin(), other.Writebacks.end()); + } + + void addWriteback(LValue srcLV, Address temporary, + llvm::Value *toUse) { + Writeback writeback = { srcLV, temporary, toUse }; + Writebacks.push_back(writeback); + } + + bool hasWritebacks() const { return !Writebacks.empty(); } + + typedef llvm::iterator_range::const_iterator> + writeback_const_range; + + writeback_const_range writebacks() const { + return writeback_const_range(Writebacks.begin(), Writebacks.end()); + } + + void addArgCleanupDeactivation(EHScopeStack::stable_iterator Cleanup, + llvm::Instruction *IsActiveIP) { + CallArgCleanup ArgCleanup; + ArgCleanup.Cleanup = Cleanup; + ArgCleanup.IsActiveIP = IsActiveIP; + CleanupsToDeactivate.push_back(ArgCleanup); + } + + ArrayRef getCleanupsToDeactivate() const { + return CleanupsToDeactivate; + } + + void allocateArgumentMemory(CodeGenFunction &CGF); + llvm::Instruction *getStackBase() const { return StackBase; } + void freeArgumentMemory(CodeGenFunction &CGF) const; + + /// \brief Returns if we're using an inalloca struct to pass arguments in + /// memory. + bool isUsingInAlloca() const { return StackBase; } + + private: + SmallVector Writebacks; + + /// Deactivate these cleanups immediately before making the call. This + /// is used to cleanup objects that are owned by the callee once the call + /// occurs. + SmallVector CleanupsToDeactivate; + + /// The stacksave call. It dominates all of the argument evaluation. + llvm::CallInst *StackBase; + + /// The iterator pointing to the stack restore cleanup. We manually run and + /// deactivate this cleanup after the call in the unexceptional case because + /// it doesn't run in the normal order. + EHScopeStack::stable_iterator StackCleanup; + }; + + /// FunctionArgList - Type for representing both the decl and type + /// of parameters to a function. The decl must be either a + /// ParmVarDecl or ImplicitParamDecl. + class FunctionArgList : public SmallVector { + }; + + /// ReturnValueSlot - Contains the address where the return value of a + /// function can be stored, and whether the address is volatile or not. + class ReturnValueSlot { + llvm::PointerIntPair Value; + CharUnits Alignment; + + // Return value slot flags + enum Flags { + IS_VOLATILE = 0x1, + IS_UNUSED = 0x2, + }; + + public: + ReturnValueSlot() {} + ReturnValueSlot(Address Addr, bool IsVolatile, bool IsUnused = false) + : Value(Addr.isValid() ? Addr.getPointer() : nullptr, + (IsVolatile ? IS_VOLATILE : 0) | (IsUnused ? IS_UNUSED : 0)), + Alignment(Addr.isValid() ? Addr.getAlignment() : CharUnits::Zero()) {} + + bool isNull() const { return !getValue().isValid(); } + + bool isVolatile() const { return Value.getInt() & IS_VOLATILE; } + Address getValue() const { return Address(Value.getPointer(), Alignment); } + bool isUnused() const { return Value.getInt() & IS_UNUSED; } + }; + +} // end namespace CodeGen +} // end namespace clang + +#endif diff --git a/vendors/clang-codegen-private-3.8/CGVTables.h b/vendors/clang-codegen-private-3.8/CGVTables.h new file mode 100644 index 0000000..c27e54a --- /dev/null +++ b/vendors/clang-codegen-private-3.8/CGVTables.h @@ -0,0 +1,119 @@ +//===--- CGVTables.h - Emit LLVM Code for C++ vtables -----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This contains code dealing with C++ code generation of virtual tables. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LIB_CODEGEN_CGVTABLES_H +#define LLVM_CLANG_LIB_CODEGEN_CGVTABLES_H + +#include "clang/AST/BaseSubobject.h" +#include "clang/AST/CharUnits.h" +#include "clang/AST/GlobalDecl.h" +#include "clang/AST/VTableBuilder.h" +#include "clang/Basic/ABI.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/IR/GlobalVariable.h" + +namespace clang { + class CXXRecordDecl; + +namespace CodeGen { + class CodeGenModule; + +class CodeGenVTables { + CodeGenModule &CGM; + + VTableContextBase *VTContext; + + /// VTableAddressPointsMapTy - Address points for a single vtable. + typedef llvm::DenseMap VTableAddressPointsMapTy; + + typedef std::pair BaseSubobjectPairTy; + typedef llvm::DenseMap SubVTTIndiciesMapTy; + + /// SubVTTIndicies - Contains indices into the various sub-VTTs. + SubVTTIndiciesMapTy SubVTTIndicies; + + typedef llvm::DenseMap + SecondaryVirtualPointerIndicesMapTy; + + /// SecondaryVirtualPointerIndices - Contains the secondary virtual pointer + /// indices. + SecondaryVirtualPointerIndicesMapTy SecondaryVirtualPointerIndices; + + /// emitThunk - Emit a single thunk. + void emitThunk(GlobalDecl GD, const ThunkInfo &Thunk, bool ForVTable); + + /// maybeEmitThunkForVTable - Emit the given thunk for the vtable if needed by + /// the ABI. + void maybeEmitThunkForVTable(GlobalDecl GD, const ThunkInfo &Thunk); + +public: + /// CreateVTableInitializer - Create a vtable initializer for the given record + /// decl. + /// \param Components - The vtable components; this is really an array of + /// VTableComponents. + llvm::Constant *CreateVTableInitializer( + const CXXRecordDecl *RD, const VTableComponent *Components, + unsigned NumComponents, const VTableLayout::VTableThunkTy *VTableThunks, + unsigned NumVTableThunks, llvm::Constant *RTTI); + + CodeGenVTables(CodeGenModule &CGM); + + ItaniumVTableContext &getItaniumVTableContext() { + return *cast(VTContext); + } + + MicrosoftVTableContext &getMicrosoftVTableContext() { + return *cast(VTContext); + } + + /// getSubVTTIndex - Return the index of the sub-VTT for the base class of the + /// given record decl. + uint64_t getSubVTTIndex(const CXXRecordDecl *RD, BaseSubobject Base); + + /// getSecondaryVirtualPointerIndex - Return the index in the VTT where the + /// virtual pointer for the given subobject is located. + uint64_t getSecondaryVirtualPointerIndex(const CXXRecordDecl *RD, + BaseSubobject Base); + + /// GenerateConstructionVTable - Generate a construction vtable for the given + /// base subobject. + llvm::GlobalVariable * + GenerateConstructionVTable(const CXXRecordDecl *RD, const BaseSubobject &Base, + bool BaseIsVirtual, + llvm::GlobalVariable::LinkageTypes Linkage, + VTableAddressPointsMapTy& AddressPoints); + + + /// GetAddrOfVTT - Get the address of the VTT for the given record decl. + llvm::GlobalVariable *GetAddrOfVTT(const CXXRecordDecl *RD); + + /// EmitVTTDefinition - Emit the definition of the given vtable. + void EmitVTTDefinition(llvm::GlobalVariable *VTT, + llvm::GlobalVariable::LinkageTypes Linkage, + const CXXRecordDecl *RD); + + /// EmitThunks - Emit the associated thunks for the given global decl. + void EmitThunks(GlobalDecl GD); + + /// GenerateClassData - Generate all the class data required to be + /// generated upon definition of a KeyFunction. This includes the + /// vtable, the RTTI data structure (if RTTI is enabled) and the VTT + /// (if the class has virtual bases). + void GenerateClassData(const CXXRecordDecl *RD); + + bool isVTableExternal(const CXXRecordDecl *RD); +}; + +} // end namespace CodeGen +} // end namespace clang +#endif diff --git a/vendors/clang-codegen-private-3.8/CGValue.h b/vendors/clang-codegen-private-3.8/CGValue.h new file mode 100644 index 0000000..3ccc4cd --- /dev/null +++ b/vendors/clang-codegen-private-3.8/CGValue.h @@ -0,0 +1,595 @@ +//===-- CGValue.h - LLVM CodeGen wrappers for llvm::Value* ------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// These classes implement wrappers around llvm::Value in order to +// fully represent the range of values for C L- and R- values. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LIB_CODEGEN_CGVALUE_H +#define LLVM_CLANG_LIB_CODEGEN_CGVALUE_H + +#include "clang/AST/ASTContext.h" +#include "clang/AST/Type.h" +#include "llvm/IR/Value.h" +#include "llvm/IR/Type.h" +#include "Address.h" + +namespace llvm { + class Constant; + class MDNode; +} + +namespace clang { +namespace CodeGen { + class AggValueSlot; + struct CGBitFieldInfo; + +/// RValue - This trivial value class is used to represent the result of an +/// expression that is evaluated. It can be one of three things: either a +/// simple LLVM SSA value, a pair of SSA values for complex numbers, or the +/// address of an aggregate value in memory. +class RValue { + enum Flavor { Scalar, Complex, Aggregate }; + + // The shift to make to an aggregate's alignment to make it look + // like a pointer. + enum { AggAlignShift = 4 }; + + // Stores first value and flavor. + llvm::PointerIntPair V1; + // Stores second value and volatility. + llvm::PointerIntPair V2; + +public: + bool isScalar() const { return V1.getInt() == Scalar; } + bool isComplex() const { return V1.getInt() == Complex; } + bool isAggregate() const { return V1.getInt() == Aggregate; } + + bool isVolatileQualified() const { return V2.getInt(); } + + /// getScalarVal() - Return the Value* of this scalar value. + llvm::Value *getScalarVal() const { + assert(isScalar() && "Not a scalar!"); + return V1.getPointer(); + } + + /// getComplexVal - Return the real/imag components of this complex value. + /// + std::pair getComplexVal() const { + return std::make_pair(V1.getPointer(), V2.getPointer()); + } + + /// getAggregateAddr() - Return the Value* of the address of the aggregate. + Address getAggregateAddress() const { + assert(isAggregate() && "Not an aggregate!"); + auto align = reinterpret_cast(V2.getPointer()) >> AggAlignShift; + return Address(V1.getPointer(), CharUnits::fromQuantity(align)); + } + llvm::Value *getAggregatePointer() const { + assert(isAggregate() && "Not an aggregate!"); + return V1.getPointer(); + } + + static RValue getIgnored() { + // FIXME: should we make this a more explicit state? + return get(nullptr); + } + + static RValue get(llvm::Value *V) { + RValue ER; + ER.V1.setPointer(V); + ER.V1.setInt(Scalar); + ER.V2.setInt(false); + return ER; + } + static RValue getComplex(llvm::Value *V1, llvm::Value *V2) { + RValue ER; + ER.V1.setPointer(V1); + ER.V2.setPointer(V2); + ER.V1.setInt(Complex); + ER.V2.setInt(false); + return ER; + } + static RValue getComplex(const std::pair &C) { + return getComplex(C.first, C.second); + } + // FIXME: Aggregate rvalues need to retain information about whether they are + // volatile or not. Remove default to find all places that probably get this + // wrong. + static RValue getAggregate(Address addr, bool isVolatile = false) { + RValue ER; + ER.V1.setPointer(addr.getPointer()); + ER.V1.setInt(Aggregate); + + auto align = static_cast(addr.getAlignment().getQuantity()); + ER.V2.setPointer(reinterpret_cast(align << AggAlignShift)); + ER.V2.setInt(isVolatile); + return ER; + } +}; + +/// Does an ARC strong l-value have precise lifetime? +enum ARCPreciseLifetime_t { + ARCImpreciseLifetime, ARCPreciseLifetime +}; + +/// The source of the alignment of an l-value; an expression of +/// confidence in the alignment actually matching the estimate. +enum class AlignmentSource { + /// The l-value was an access to a declared entity or something + /// equivalently strong, like the address of an array allocated by a + /// language runtime. + Decl, + + /// The l-value was considered opaque, so the alignment was + /// determined from a type, but that type was an explicitly-aligned + /// typedef. + AttributedType, + + /// The l-value was considered opaque, so the alignment was + /// determined from a type. + Type +}; + +/// Given that the base address has the given alignment source, what's +/// our confidence in the alignment of the field? +static inline AlignmentSource getFieldAlignmentSource(AlignmentSource Source) { + // For now, we don't distinguish fields of opaque pointers from + // top-level declarations, but maybe we should. + return AlignmentSource::Decl; +} + +/// LValue - This represents an lvalue references. Because C/C++ allow +/// bitfields, this is not a simple LLVM pointer, it may be a pointer plus a +/// bitrange. +class LValue { + enum { + Simple, // This is a normal l-value, use getAddress(). + VectorElt, // This is a vector element l-value (V[i]), use getVector* + BitField, // This is a bitfield l-value, use getBitfield*. + ExtVectorElt, // This is an extended vector subset, use getExtVectorComp + GlobalReg // This is a register l-value, use getGlobalReg() + } LVType; + + llvm::Value *V; + + union { + // Index into a vector subscript: V[i] + llvm::Value *VectorIdx; + + // ExtVector element subset: V.xyx + llvm::Constant *VectorElts; + + // BitField start bit and size + const CGBitFieldInfo *BitFieldInfo; + }; + + QualType Type; + + // 'const' is unused here + Qualifiers Quals; + + // The alignment to use when accessing this lvalue. (For vector elements, + // this is the alignment of the whole vector.) + int64_t Alignment; + + // objective-c's ivar + bool Ivar:1; + + // objective-c's ivar is an array + bool ObjIsArray:1; + + // LValue is non-gc'able for any reason, including being a parameter or local + // variable. + bool NonGC: 1; + + // Lvalue is a global reference of an objective-c object + bool GlobalObjCRef : 1; + + // Lvalue is a thread local reference + bool ThreadLocalRef : 1; + + // Lvalue has ARC imprecise lifetime. We store this inverted to try + // to make the default bitfield pattern all-zeroes. + bool ImpreciseLifetime : 1; + + unsigned AlignSource : 2; + + // This flag shows if a nontemporal load/stores should be used when accessing + // this lvalue. + bool Nontemporal : 1; + + Expr *BaseIvarExp; + + /// Used by struct-path-aware TBAA. + QualType TBAABaseType; + /// Offset relative to the base type. + uint64_t TBAAOffset; + + /// TBAAInfo - TBAA information to attach to dereferences of this LValue. + llvm::MDNode *TBAAInfo; + +private: + void Initialize(QualType Type, Qualifiers Quals, + CharUnits Alignment, AlignmentSource AlignSource, + llvm::MDNode *TBAAInfo = nullptr) { + assert((!Alignment.isZero() || Type->isIncompleteType()) && + "initializing l-value with zero alignment!"); + this->Type = Type; + this->Quals = Quals; + this->Alignment = Alignment.getQuantity(); + assert(this->Alignment == Alignment.getQuantity() && + "Alignment exceeds allowed max!"); + this->AlignSource = unsigned(AlignSource); + + // Initialize Objective-C flags. + this->Ivar = this->ObjIsArray = this->NonGC = this->GlobalObjCRef = false; + this->ImpreciseLifetime = false; + this->Nontemporal = false; + this->ThreadLocalRef = false; + this->BaseIvarExp = nullptr; + + // Initialize fields for TBAA. + this->TBAABaseType = Type; + this->TBAAOffset = 0; + this->TBAAInfo = TBAAInfo; + } + +public: + bool isSimple() const { return LVType == Simple; } + bool isVectorElt() const { return LVType == VectorElt; } + bool isBitField() const { return LVType == BitField; } + bool isExtVectorElt() const { return LVType == ExtVectorElt; } + bool isGlobalReg() const { return LVType == GlobalReg; } + + bool isVolatileQualified() const { return Quals.hasVolatile(); } + bool isRestrictQualified() const { return Quals.hasRestrict(); } + unsigned getVRQualifiers() const { + return Quals.getCVRQualifiers() & ~Qualifiers::Const; + } + + QualType getType() const { return Type; } + + Qualifiers::ObjCLifetime getObjCLifetime() const { + return Quals.getObjCLifetime(); + } + + bool isObjCIvar() const { return Ivar; } + void setObjCIvar(bool Value) { Ivar = Value; } + + bool isObjCArray() const { return ObjIsArray; } + void setObjCArray(bool Value) { ObjIsArray = Value; } + + bool isNonGC () const { return NonGC; } + void setNonGC(bool Value) { NonGC = Value; } + + bool isGlobalObjCRef() const { return GlobalObjCRef; } + void setGlobalObjCRef(bool Value) { GlobalObjCRef = Value; } + + bool isThreadLocalRef() const { return ThreadLocalRef; } + void setThreadLocalRef(bool Value) { ThreadLocalRef = Value;} + + ARCPreciseLifetime_t isARCPreciseLifetime() const { + return ARCPreciseLifetime_t(!ImpreciseLifetime); + } + void setARCPreciseLifetime(ARCPreciseLifetime_t value) { + ImpreciseLifetime = (value == ARCImpreciseLifetime); + } + bool isNontemporal() const { return Nontemporal; } + void setNontemporal(bool Value) { Nontemporal = Value; } + + bool isObjCWeak() const { + return Quals.getObjCGCAttr() == Qualifiers::Weak; + } + bool isObjCStrong() const { + return Quals.getObjCGCAttr() == Qualifiers::Strong; + } + + bool isVolatile() const { + return Quals.hasVolatile(); + } + + Expr *getBaseIvarExp() const { return BaseIvarExp; } + void setBaseIvarExp(Expr *V) { BaseIvarExp = V; } + + QualType getTBAABaseType() const { return TBAABaseType; } + void setTBAABaseType(QualType T) { TBAABaseType = T; } + + uint64_t getTBAAOffset() const { return TBAAOffset; } + void setTBAAOffset(uint64_t O) { TBAAOffset = O; } + + llvm::MDNode *getTBAAInfo() const { return TBAAInfo; } + void setTBAAInfo(llvm::MDNode *N) { TBAAInfo = N; } + + const Qualifiers &getQuals() const { return Quals; } + Qualifiers &getQuals() { return Quals; } + + unsigned getAddressSpace() const { return Quals.getAddressSpace(); } + + CharUnits getAlignment() const { return CharUnits::fromQuantity(Alignment); } + void setAlignment(CharUnits A) { Alignment = A.getQuantity(); } + + AlignmentSource getAlignmentSource() const { + return AlignmentSource(AlignSource); + } + void setAlignmentSource(AlignmentSource Source) { + AlignSource = unsigned(Source); + } + + // simple lvalue + llvm::Value *getPointer() const { + assert(isSimple()); + return V; + } + Address getAddress() const { return Address(getPointer(), getAlignment()); } + void setAddress(Address address) { + assert(isSimple()); + V = address.getPointer(); + Alignment = address.getAlignment().getQuantity(); + } + + // vector elt lvalue + Address getVectorAddress() const { + return Address(getVectorPointer(), getAlignment()); + } + llvm::Value *getVectorPointer() const { assert(isVectorElt()); return V; } + llvm::Value *getVectorIdx() const { assert(isVectorElt()); return VectorIdx; } + + // extended vector elements. + Address getExtVectorAddress() const { + return Address(getExtVectorPointer(), getAlignment()); + } + llvm::Value *getExtVectorPointer() const { + assert(isExtVectorElt()); + return V; + } + llvm::Constant *getExtVectorElts() const { + assert(isExtVectorElt()); + return VectorElts; + } + + // bitfield lvalue + Address getBitFieldAddress() const { + return Address(getBitFieldPointer(), getAlignment()); + } + llvm::Value *getBitFieldPointer() const { assert(isBitField()); return V; } + const CGBitFieldInfo &getBitFieldInfo() const { + assert(isBitField()); + return *BitFieldInfo; + } + + // global register lvalue + llvm::Value *getGlobalReg() const { assert(isGlobalReg()); return V; } + + static LValue MakeAddr(Address address, QualType type, + ASTContext &Context, + AlignmentSource alignSource, + llvm::MDNode *TBAAInfo = nullptr) { + Qualifiers qs = type.getQualifiers(); + qs.setObjCGCAttr(Context.getObjCGCAttrKind(type)); + + LValue R; + R.LVType = Simple; + assert(address.getPointer()->getType()->isPointerTy()); + R.V = address.getPointer(); + R.Initialize(type, qs, address.getAlignment(), alignSource, TBAAInfo); + return R; + } + + static LValue MakeVectorElt(Address vecAddress, llvm::Value *Idx, + QualType type, AlignmentSource alignSource) { + LValue R; + R.LVType = VectorElt; + R.V = vecAddress.getPointer(); + R.VectorIdx = Idx; + R.Initialize(type, type.getQualifiers(), vecAddress.getAlignment(), + alignSource); + return R; + } + + static LValue MakeExtVectorElt(Address vecAddress, llvm::Constant *Elts, + QualType type, AlignmentSource alignSource) { + LValue R; + R.LVType = ExtVectorElt; + R.V = vecAddress.getPointer(); + R.VectorElts = Elts; + R.Initialize(type, type.getQualifiers(), vecAddress.getAlignment(), + alignSource); + return R; + } + + /// \brief Create a new object to represent a bit-field access. + /// + /// \param Addr - The base address of the bit-field sequence this + /// bit-field refers to. + /// \param Info - The information describing how to perform the bit-field + /// access. + static LValue MakeBitfield(Address Addr, + const CGBitFieldInfo &Info, + QualType type, + AlignmentSource alignSource) { + LValue R; + R.LVType = BitField; + R.V = Addr.getPointer(); + R.BitFieldInfo = &Info; + R.Initialize(type, type.getQualifiers(), Addr.getAlignment(), alignSource); + return R; + } + + static LValue MakeGlobalReg(Address Reg, QualType type) { + LValue R; + R.LVType = GlobalReg; + R.V = Reg.getPointer(); + R.Initialize(type, type.getQualifiers(), Reg.getAlignment(), + AlignmentSource::Decl); + return R; + } + + RValue asAggregateRValue() const { + return RValue::getAggregate(getAddress(), isVolatileQualified()); + } +}; + +/// An aggregate value slot. +class AggValueSlot { + /// The address. + llvm::Value *Addr; + + // Qualifiers + Qualifiers Quals; + + unsigned short Alignment; + + /// DestructedFlag - This is set to true if some external code is + /// responsible for setting up a destructor for the slot. Otherwise + /// the code which constructs it should push the appropriate cleanup. + bool DestructedFlag : 1; + + /// ObjCGCFlag - This is set to true if writing to the memory in the + /// slot might require calling an appropriate Objective-C GC + /// barrier. The exact interaction here is unnecessarily mysterious. + bool ObjCGCFlag : 1; + + /// ZeroedFlag - This is set to true if the memory in the slot is + /// known to be zero before the assignment into it. This means that + /// zero fields don't need to be set. + bool ZeroedFlag : 1; + + /// AliasedFlag - This is set to true if the slot might be aliased + /// and it's not undefined behavior to access it through such an + /// alias. Note that it's always undefined behavior to access a C++ + /// object that's under construction through an alias derived from + /// outside the construction process. + /// + /// This flag controls whether calls that produce the aggregate + /// value may be evaluated directly into the slot, or whether they + /// must be evaluated into an unaliased temporary and then memcpy'ed + /// over. Since it's invalid in general to memcpy a non-POD C++ + /// object, it's important that this flag never be set when + /// evaluating an expression which constructs such an object. + bool AliasedFlag : 1; + +public: + enum IsAliased_t { IsNotAliased, IsAliased }; + enum IsDestructed_t { IsNotDestructed, IsDestructed }; + enum IsZeroed_t { IsNotZeroed, IsZeroed }; + enum NeedsGCBarriers_t { DoesNotNeedGCBarriers, NeedsGCBarriers }; + + /// ignored - Returns an aggregate value slot indicating that the + /// aggregate value is being ignored. + static AggValueSlot ignored() { + return forAddr(Address::invalid(), Qualifiers(), IsNotDestructed, + DoesNotNeedGCBarriers, IsNotAliased); + } + + /// forAddr - Make a slot for an aggregate value. + /// + /// \param quals - The qualifiers that dictate how the slot should + /// be initialied. Only 'volatile' and the Objective-C lifetime + /// qualifiers matter. + /// + /// \param isDestructed - true if something else is responsible + /// for calling destructors on this object + /// \param needsGC - true if the slot is potentially located + /// somewhere that ObjC GC calls should be emitted for + static AggValueSlot forAddr(Address addr, + Qualifiers quals, + IsDestructed_t isDestructed, + NeedsGCBarriers_t needsGC, + IsAliased_t isAliased, + IsZeroed_t isZeroed = IsNotZeroed) { + AggValueSlot AV; + if (addr.isValid()) { + AV.Addr = addr.getPointer(); + AV.Alignment = addr.getAlignment().getQuantity(); + } else { + AV.Addr = nullptr; + AV.Alignment = 0; + } + AV.Quals = quals; + AV.DestructedFlag = isDestructed; + AV.ObjCGCFlag = needsGC; + AV.ZeroedFlag = isZeroed; + AV.AliasedFlag = isAliased; + return AV; + } + + static AggValueSlot forLValue(const LValue &LV, + IsDestructed_t isDestructed, + NeedsGCBarriers_t needsGC, + IsAliased_t isAliased, + IsZeroed_t isZeroed = IsNotZeroed) { + return forAddr(LV.getAddress(), + LV.getQuals(), isDestructed, needsGC, isAliased, isZeroed); + } + + IsDestructed_t isExternallyDestructed() const { + return IsDestructed_t(DestructedFlag); + } + void setExternallyDestructed(bool destructed = true) { + DestructedFlag = destructed; + } + + Qualifiers getQualifiers() const { return Quals; } + + bool isVolatile() const { + return Quals.hasVolatile(); + } + + void setVolatile(bool flag) { + Quals.setVolatile(flag); + } + + Qualifiers::ObjCLifetime getObjCLifetime() const { + return Quals.getObjCLifetime(); + } + + NeedsGCBarriers_t requiresGCollection() const { + return NeedsGCBarriers_t(ObjCGCFlag); + } + + llvm::Value *getPointer() const { + return Addr; + } + + Address getAddress() const { + return Address(Addr, getAlignment()); + } + + bool isIgnored() const { + return Addr == nullptr; + } + + CharUnits getAlignment() const { + return CharUnits::fromQuantity(Alignment); + } + + IsAliased_t isPotentiallyAliased() const { + return IsAliased_t(AliasedFlag); + } + + RValue asRValue() const { + if (isIgnored()) { + return RValue::getIgnored(); + } else { + return RValue::getAggregate(getAddress(), isVolatile()); + } + } + + void setZeroed(bool V = true) { ZeroedFlag = V; } + IsZeroed_t isZeroed() const { + return IsZeroed_t(ZeroedFlag); + } +}; + +} // end namespace CodeGen +} // end namespace clang + +#endif diff --git a/vendors/clang-codegen-private-3.8/CodeGenModule.h b/vendors/clang-codegen-private-3.8/CodeGenModule.h new file mode 100644 index 0000000..fdb4d78 --- /dev/null +++ b/vendors/clang-codegen-private-3.8/CodeGenModule.h @@ -0,0 +1,1245 @@ +//===--- CodeGenModule.h - Per-Module state for LLVM CodeGen ----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This is the internal per-translation-unit state used for llvm translation. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LIB_CODEGEN_CODEGENMODULE_H +#define LLVM_CLANG_LIB_CODEGEN_CODEGENMODULE_H + +#include "CGVTables.h" +#include "CodeGenTypeCache.h" +#include "CodeGenTypes.h" +#include "SanitizerMetadata.h" +#include "clang/AST/Attr.h" +#include "clang/AST/DeclCXX.h" +#include "clang/AST/DeclObjC.h" +#include "clang/AST/GlobalDecl.h" +#include "clang/AST/Mangle.h" +#include "clang/Basic/ABI.h" +#include "clang/Basic/LangOptions.h" +#include "clang/Basic/Module.h" +#include "clang/Basic/SanitizerBlacklist.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SetVector.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/ValueHandle.h" + +namespace llvm { +class Module; +class Constant; +class ConstantInt; +class Function; +class GlobalValue; +class DataLayout; +class FunctionType; +class LLVMContext; +class IndexedInstrProfReader; +} + +namespace clang { +class TargetCodeGenInfo; +class ASTContext; +class AtomicType; +class FunctionDecl; +class IdentifierInfo; +class ObjCMethodDecl; +class ObjCImplementationDecl; +class ObjCCategoryImplDecl; +class ObjCProtocolDecl; +class ObjCEncodeExpr; +class BlockExpr; +class CharUnits; +class Decl; +class Expr; +class Stmt; +class InitListExpr; +class StringLiteral; +class NamedDecl; +class ValueDecl; +class VarDecl; +class LangOptions; +class CodeGenOptions; +class HeaderSearchOptions; +class PreprocessorOptions; +class DiagnosticsEngine; +class AnnotateAttr; +class CXXDestructorDecl; +class Module; +class CoverageSourceInfo; + +namespace CodeGen { + +class CallArgList; +class CodeGenFunction; +class CodeGenTBAA; +class CGCXXABI; +class CGDebugInfo; +class CGObjCRuntime; +class CGOpenCLRuntime; +class CGOpenMPRuntime; +class CGCUDARuntime; +class BlockFieldFlags; +class FunctionArgList; +class CoverageMappingModuleGen; + +struct OrderGlobalInits { + unsigned int priority; + unsigned int lex_order; + OrderGlobalInits(unsigned int p, unsigned int l) + : priority(p), lex_order(l) {} + + bool operator==(const OrderGlobalInits &RHS) const { + return priority == RHS.priority && lex_order == RHS.lex_order; + } + + bool operator<(const OrderGlobalInits &RHS) const { + return std::tie(priority, lex_order) < + std::tie(RHS.priority, RHS.lex_order); + } +}; + +struct ObjCEntrypoints { + ObjCEntrypoints() { memset(this, 0, sizeof(*this)); } + + /// void objc_autoreleasePoolPop(void*); + llvm::Constant *objc_autoreleasePoolPop; + + /// void *objc_autoreleasePoolPush(void); + llvm::Constant *objc_autoreleasePoolPush; + + /// id objc_autorelease(id); + llvm::Constant *objc_autorelease; + + /// id objc_autoreleaseReturnValue(id); + llvm::Constant *objc_autoreleaseReturnValue; + + /// void objc_copyWeak(id *dest, id *src); + llvm::Constant *objc_copyWeak; + + /// void objc_destroyWeak(id*); + llvm::Constant *objc_destroyWeak; + + /// id objc_initWeak(id*, id); + llvm::Constant *objc_initWeak; + + /// id objc_loadWeak(id*); + llvm::Constant *objc_loadWeak; + + /// id objc_loadWeakRetained(id*); + llvm::Constant *objc_loadWeakRetained; + + /// void objc_moveWeak(id *dest, id *src); + llvm::Constant *objc_moveWeak; + + /// id objc_retain(id); + llvm::Constant *objc_retain; + + /// id objc_retainAutorelease(id); + llvm::Constant *objc_retainAutorelease; + + /// id objc_retainAutoreleaseReturnValue(id); + llvm::Constant *objc_retainAutoreleaseReturnValue; + + /// id objc_retainAutoreleasedReturnValue(id); + llvm::Constant *objc_retainAutoreleasedReturnValue; + + /// id objc_retainBlock(id); + llvm::Constant *objc_retainBlock; + + /// void objc_release(id); + llvm::Constant *objc_release; + + /// id objc_storeStrong(id*, id); + llvm::Constant *objc_storeStrong; + + /// id objc_storeWeak(id*, id); + llvm::Constant *objc_storeWeak; + + /// A void(void) inline asm to use to mark that the return value of + /// a call will be immediately retain. + llvm::InlineAsm *retainAutoreleasedReturnValueMarker; + + /// void clang.arc.use(...); + llvm::Constant *clang_arc_use; +}; + +/// This class records statistics on instrumentation based profiling. +class InstrProfStats { + uint32_t VisitedInMainFile; + uint32_t MissingInMainFile; + uint32_t Visited; + uint32_t Missing; + uint32_t Mismatched; + +public: + InstrProfStats() + : VisitedInMainFile(0), MissingInMainFile(0), Visited(0), Missing(0), + Mismatched(0) {} + /// Record that we've visited a function and whether or not that function was + /// in the main source file. + void addVisited(bool MainFile) { + if (MainFile) + ++VisitedInMainFile; + ++Visited; + } + /// Record that a function we've visited has no profile data. + void addMissing(bool MainFile) { + if (MainFile) + ++MissingInMainFile; + ++Missing; + } + /// Record that a function we've visited has mismatched profile data. + void addMismatched(bool MainFile) { ++Mismatched; } + /// Whether or not the stats we've gathered indicate any potential problems. + bool hasDiagnostics() { return Missing || Mismatched; } + /// Report potential problems we've found to \c Diags. + void reportDiagnostics(DiagnosticsEngine &Diags, StringRef MainFile); +}; + +/// A pair of helper functions for a __block variable. +class BlockByrefHelpers : public llvm::FoldingSetNode { + // MSVC requires this type to be complete in order to process this + // header. +public: + llvm::Constant *CopyHelper; + llvm::Constant *DisposeHelper; + + /// The alignment of the field. This is important because + /// different offsets to the field within the byref struct need to + /// have different helper functions. + CharUnits Alignment; + + BlockByrefHelpers(CharUnits alignment) : Alignment(alignment) {} + BlockByrefHelpers(const BlockByrefHelpers &) = default; + virtual ~BlockByrefHelpers(); + + void Profile(llvm::FoldingSetNodeID &id) const { + id.AddInteger(Alignment.getQuantity()); + profileImpl(id); + } + virtual void profileImpl(llvm::FoldingSetNodeID &id) const = 0; + + virtual bool needsCopy() const { return true; } + virtual void emitCopy(CodeGenFunction &CGF, Address dest, Address src) = 0; + + virtual bool needsDispose() const { return true; } + virtual void emitDispose(CodeGenFunction &CGF, Address field) = 0; +}; + +/// This class organizes the cross-function state that is used while generating +/// LLVM code. +class CodeGenModule : public CodeGenTypeCache { + CodeGenModule(const CodeGenModule &) = delete; + void operator=(const CodeGenModule &) = delete; + +public: + struct Structor { + Structor() : Priority(0), Initializer(nullptr), AssociatedData(nullptr) {} + Structor(int Priority, llvm::Constant *Initializer, + llvm::Constant *AssociatedData) + : Priority(Priority), Initializer(Initializer), + AssociatedData(AssociatedData) {} + int Priority; + llvm::Constant *Initializer; + llvm::Constant *AssociatedData; + }; + + typedef std::vector CtorList; + +private: + ASTContext &Context; + const LangOptions &LangOpts; + const HeaderSearchOptions &HeaderSearchOpts; // Only used for debug info. + const PreprocessorOptions &PreprocessorOpts; // Only used for debug info. + const CodeGenOptions &CodeGenOpts; + llvm::Module &TheModule; + DiagnosticsEngine &Diags; + const TargetInfo &Target; + std::unique_ptr ABI; + llvm::LLVMContext &VMContext; + + CodeGenTBAA *TBAA; + + mutable const TargetCodeGenInfo *TheTargetCodeGenInfo; + + // This should not be moved earlier, since its initialization depends on some + // of the previous reference members being already initialized and also checks + // if TheTargetCodeGenInfo is NULL + CodeGenTypes Types; + + /// Holds information about C++ vtables. + CodeGenVTables VTables; + + CGObjCRuntime* ObjCRuntime; + CGOpenCLRuntime* OpenCLRuntime; + CGOpenMPRuntime* OpenMPRuntime; + CGCUDARuntime* CUDARuntime; + CGDebugInfo* DebugInfo; + ObjCEntrypoints *ObjCData; + llvm::MDNode *NoObjCARCExceptionsMetadata; + std::unique_ptr PGOReader; + InstrProfStats PGOStats; + + // A set of references that have only been seen via a weakref so far. This is + // used to remove the weak of the reference if we ever see a direct reference + // or a definition. + llvm::SmallPtrSet WeakRefReferences; + + /// This contains all the decls which have definitions but/ which are deferred + /// for emission and therefore should only be output if they are actually + /// used. If a decl is in this, then it is known to have not been referenced + /// yet. + std::map DeferredDecls; + + /// This is a list of deferred decls which we have seen that *are* actually + /// referenced. These get code generated when the module is done. + struct DeferredGlobal { + DeferredGlobal(llvm::GlobalValue *GV, GlobalDecl GD) : GV(GV), GD(GD) {} + llvm::TrackingVH GV; + GlobalDecl GD; + }; + std::vector DeferredDeclsToEmit; + void addDeferredDeclToEmit(llvm::GlobalValue *GV, GlobalDecl GD) { + DeferredDeclsToEmit.emplace_back(GV, GD); + } + + /// List of alias we have emitted. Used to make sure that what they point to + /// is defined once we get to the end of the of the translation unit. + std::vector Aliases; + + typedef llvm::StringMap > ReplacementsTy; + ReplacementsTy Replacements; + + /// List of global values to be replaced with something else. Used when we + /// want to replace a GlobalValue but can't identify it by its mangled name + /// anymore (because the name is already taken). + llvm::SmallVector, 8> + GlobalValReplacements; + + /// Set of global decls for which we already diagnosed mangled name conflict. + /// Required to not issue a warning (on a mangling conflict) multiple times + /// for the same decl. + llvm::DenseSet DiagnosedConflictingDefinitions; + + /// A queue of (optional) vtables to consider emitting. + std::vector DeferredVTables; + + /// List of global values which are required to be present in the object file; + /// bitcast to i8*. This is used for forcing visibility of symbols which may + /// otherwise be optimized out. + std::vector LLVMUsed; + std::vector LLVMCompilerUsed; + + /// Store the list of global constructors and their respective priorities to + /// be emitted when the translation unit is complete. + CtorList GlobalCtors; + + /// Store the list of global destructors and their respective priorities to be + /// emitted when the translation unit is complete. + CtorList GlobalDtors; + + /// An ordered map of canonical GlobalDecls to their mangled names. + llvm::MapVector MangledDeclNames; + llvm::StringMap Manglings; + + /// Global annotations. + std::vector Annotations; + + /// Map used to get unique annotation strings. + llvm::StringMap AnnotationStrings; + + llvm::StringMap CFConstantStringMap; + + llvm::DenseMap ConstantStringMap; + llvm::DenseMap StaticLocalDeclMap; + llvm::DenseMap StaticLocalDeclGuardMap; + llvm::DenseMap MaterializedGlobalTemporaryMap; + + llvm::DenseMap AtomicSetterHelperFnMap; + llvm::DenseMap AtomicGetterHelperFnMap; + + /// Map used to get unique type descriptor constants for sanitizers. + llvm::DenseMap TypeDescriptorMap; + + /// Map used to track internal linkage functions declared within + /// extern "C" regions. + typedef llvm::MapVector StaticExternCMap; + StaticExternCMap StaticExternCValues; + + /// \brief thread_local variables defined or used in this TU. + std::vector CXXThreadLocals; + + /// \brief thread_local variables with initializers that need to run + /// before any thread_local variable in this TU is odr-used. + std::vector CXXThreadLocalInits; + std::vector CXXThreadLocalInitVars; + + /// Global variables with initializers that need to run before main. + std::vector CXXGlobalInits; + + /// When a C++ decl with an initializer is deferred, null is + /// appended to CXXGlobalInits, and the index of that null is placed + /// here so that the initializer will be performed in the correct + /// order. Once the decl is emitted, the index is replaced with ~0U to ensure + /// that we don't re-emit the initializer. + llvm::DenseMap DelayedCXXInitPosition; + + typedef std::pair GlobalInitData; + + struct GlobalInitPriorityCmp { + bool operator()(const GlobalInitData &LHS, + const GlobalInitData &RHS) const { + return LHS.first.priority < RHS.first.priority; + } + }; + + /// Global variables with initializers whose order of initialization is set by + /// init_priority attribute. + SmallVector PrioritizedCXXGlobalInits; + + /// Global destructor functions and arguments that need to run on termination. + std::vector > CXXGlobalDtors; + + /// \brief The complete set of modules that has been imported. + llvm::SetVector ImportedModules; + + /// \brief A vector of metadata strings. + SmallVector LinkerOptionsMetadata; + + /// @name Cache for Objective-C runtime types + /// @{ + + /// Cached reference to the class for constant strings. This value has type + /// int * but is actually an Obj-C class pointer. + llvm::WeakVH CFConstantStringClassRef; + + /// Cached reference to the class for constant strings. This value has type + /// int * but is actually an Obj-C class pointer. + llvm::WeakVH ConstantStringClassRef; + + /// \brief The LLVM type corresponding to NSConstantString. + llvm::StructType *NSConstantStringType; + + /// \brief The type used to describe the state of a fast enumeration in + /// Objective-C's for..in loop. + QualType ObjCFastEnumerationStateType; + + /// @} + + /// Lazily create the Objective-C runtime + void createObjCRuntime(); + + void createOpenCLRuntime(); + void createOpenMPRuntime(); + void createCUDARuntime(); + + bool isTriviallyRecursive(const FunctionDecl *F); + bool shouldEmitFunction(GlobalDecl GD); + + /// @name Cache for Blocks Runtime Globals + /// @{ + + llvm::Constant *NSConcreteGlobalBlock; + llvm::Constant *NSConcreteStackBlock; + + llvm::Constant *BlockObjectAssign; + llvm::Constant *BlockObjectDispose; + + llvm::Type *BlockDescriptorType; + llvm::Type *GenericBlockLiteralType; + + struct { + int GlobalUniqueCount; + } Block; + + /// void @llvm.lifetime.start(i64 %size, i8* nocapture ) + llvm::Constant *LifetimeStartFn; + + /// void @llvm.lifetime.end(i64 %size, i8* nocapture ) + llvm::Constant *LifetimeEndFn; + + GlobalDecl initializedGlobalDecl; + + std::unique_ptr SanitizerMD; + + /// @} + + llvm::DenseMap DeferredEmptyCoverageMappingDecls; + + std::unique_ptr CoverageMapping; + + /// Mapping from canonical types to their metadata identifiers. We need to + /// maintain this mapping because identifiers may be formed from distinct + /// MDNodes. + llvm::DenseMap MetadataIdMap; + +public: + CodeGenModule(ASTContext &C, const HeaderSearchOptions &headersearchopts, + const PreprocessorOptions &ppopts, + const CodeGenOptions &CodeGenOpts, llvm::Module &M, + DiagnosticsEngine &Diags, + CoverageSourceInfo *CoverageInfo = nullptr); + + ~CodeGenModule(); + + void clear(); + + /// Finalize LLVM code generation. + void Release(); + + /// Return a reference to the configured Objective-C runtime. + CGObjCRuntime &getObjCRuntime() { + if (!ObjCRuntime) createObjCRuntime(); + return *ObjCRuntime; + } + + /// Return true iff an Objective-C runtime has been configured. + bool hasObjCRuntime() { return !!ObjCRuntime; } + + /// Return a reference to the configured OpenCL runtime. + CGOpenCLRuntime &getOpenCLRuntime() { + assert(OpenCLRuntime != nullptr); + return *OpenCLRuntime; + } + + /// Return a reference to the configured OpenMP runtime. + CGOpenMPRuntime &getOpenMPRuntime() { + assert(OpenMPRuntime != nullptr); + return *OpenMPRuntime; + } + + /// Return a reference to the configured CUDA runtime. + CGCUDARuntime &getCUDARuntime() { + assert(CUDARuntime != nullptr); + return *CUDARuntime; + } + + ObjCEntrypoints &getObjCEntrypoints() const { + assert(ObjCData != nullptr); + return *ObjCData; + } + + InstrProfStats &getPGOStats() { return PGOStats; } + llvm::IndexedInstrProfReader *getPGOReader() const { return PGOReader.get(); } + + CoverageMappingModuleGen *getCoverageMapping() const { + return CoverageMapping.get(); + } + + llvm::Constant *getStaticLocalDeclAddress(const VarDecl *D) { + return StaticLocalDeclMap[D]; + } + void setStaticLocalDeclAddress(const VarDecl *D, + llvm::Constant *C) { + StaticLocalDeclMap[D] = C; + } + + llvm::Constant * + getOrCreateStaticVarDecl(const VarDecl &D, + llvm::GlobalValue::LinkageTypes Linkage); + + llvm::GlobalVariable *getStaticLocalDeclGuardAddress(const VarDecl *D) { + return StaticLocalDeclGuardMap[D]; + } + void setStaticLocalDeclGuardAddress(const VarDecl *D, + llvm::GlobalVariable *C) { + StaticLocalDeclGuardMap[D] = C; + } + + bool lookupRepresentativeDecl(StringRef MangledName, + GlobalDecl &Result) const; + + llvm::Constant *getAtomicSetterHelperFnMap(QualType Ty) { + return AtomicSetterHelperFnMap[Ty]; + } + void setAtomicSetterHelperFnMap(QualType Ty, + llvm::Constant *Fn) { + AtomicSetterHelperFnMap[Ty] = Fn; + } + + llvm::Constant *getAtomicGetterHelperFnMap(QualType Ty) { + return AtomicGetterHelperFnMap[Ty]; + } + void setAtomicGetterHelperFnMap(QualType Ty, + llvm::Constant *Fn) { + AtomicGetterHelperFnMap[Ty] = Fn; + } + + llvm::Constant *getTypeDescriptorFromMap(QualType Ty) { + return TypeDescriptorMap[Ty]; + } + void setTypeDescriptorInMap(QualType Ty, llvm::Constant *C) { + TypeDescriptorMap[Ty] = C; + } + + CGDebugInfo *getModuleDebugInfo() { return DebugInfo; } + + llvm::MDNode *getNoObjCARCExceptionsMetadata() { + if (!NoObjCARCExceptionsMetadata) + NoObjCARCExceptionsMetadata = llvm::MDNode::get(getLLVMContext(), None); + return NoObjCARCExceptionsMetadata; + } + + ASTContext &getContext() const { return Context; } + const LangOptions &getLangOpts() const { return LangOpts; } + const HeaderSearchOptions &getHeaderSearchOpts() + const { return HeaderSearchOpts; } + const PreprocessorOptions &getPreprocessorOpts() + const { return PreprocessorOpts; } + const CodeGenOptions &getCodeGenOpts() const { return CodeGenOpts; } + llvm::Module &getModule() const { return TheModule; } + DiagnosticsEngine &getDiags() const { return Diags; } + const llvm::DataLayout &getDataLayout() const { + return TheModule.getDataLayout(); + } + const TargetInfo &getTarget() const { return Target; } + const llvm::Triple &getTriple() const; + bool supportsCOMDAT() const; + void maybeSetTrivialComdat(const Decl &D, llvm::GlobalObject &GO); + + CGCXXABI &getCXXABI() const { return *ABI; } + llvm::LLVMContext &getLLVMContext() { return VMContext; } + + bool shouldUseTBAA() const { return TBAA != nullptr; } + + const TargetCodeGenInfo &getTargetCodeGenInfo(); + + CodeGenTypes &getTypes() { return Types; } + + CodeGenVTables &getVTables() { return VTables; } + + ItaniumVTableContext &getItaniumVTableContext() { + return VTables.getItaniumVTableContext(); + } + + MicrosoftVTableContext &getMicrosoftVTableContext() { + return VTables.getMicrosoftVTableContext(); + } + + CtorList &getGlobalCtors() { return GlobalCtors; } + CtorList &getGlobalDtors() { return GlobalDtors; } + + llvm::MDNode *getTBAAInfo(QualType QTy); + llvm::MDNode *getTBAAInfoForVTablePtr(); + llvm::MDNode *getTBAAStructInfo(QualType QTy); + /// Return the path-aware tag for given base type, access node and offset. + llvm::MDNode *getTBAAStructTagInfo(QualType BaseTy, llvm::MDNode *AccessN, + uint64_t O); + + bool isTypeConstant(QualType QTy, bool ExcludeCtorDtor); + + bool isPaddedAtomicType(QualType type); + bool isPaddedAtomicType(const AtomicType *type); + + /// Decorate the instruction with a TBAA tag. For scalar TBAA, the tag + /// is the same as the type. For struct-path aware TBAA, the tag + /// is different from the type: base type, access type and offset. + /// When ConvertTypeToTag is true, we create a tag based on the scalar type. + void DecorateInstructionWithTBAA(llvm::Instruction *Inst, + llvm::MDNode *TBAAInfo, + bool ConvertTypeToTag = true); + + /// Adds !invariant.barrier !tag to instruction + void DecorateInstructionWithInvariantGroup(llvm::Instruction *I, + const CXXRecordDecl *RD); + + /// Emit the given number of characters as a value of type size_t. + llvm::ConstantInt *getSize(CharUnits numChars); + + /// Set the visibility for the given LLVM GlobalValue. + void setGlobalVisibility(llvm::GlobalValue *GV, const NamedDecl *D) const; + + /// Set the TLS mode for the given LLVM GlobalValue for the thread-local + /// variable declaration D. + void setTLSMode(llvm::GlobalValue *GV, const VarDecl &D) const; + + static llvm::GlobalValue::VisibilityTypes GetLLVMVisibility(Visibility V) { + switch (V) { + case DefaultVisibility: return llvm::GlobalValue::DefaultVisibility; + case HiddenVisibility: return llvm::GlobalValue::HiddenVisibility; + case ProtectedVisibility: return llvm::GlobalValue::ProtectedVisibility; + } + llvm_unreachable("unknown visibility!"); + } + + llvm::Constant *GetAddrOfGlobal(GlobalDecl GD, bool IsForDefinition = false); + + /// Will return a global variable of the given type. If a variable with a + /// different type already exists then a new variable with the right type + /// will be created and all uses of the old variable will be replaced with a + /// bitcast to the new variable. + llvm::GlobalVariable * + CreateOrReplaceCXXRuntimeVariable(StringRef Name, llvm::Type *Ty, + llvm::GlobalValue::LinkageTypes Linkage); + + llvm::Function * + CreateGlobalInitOrDestructFunction(llvm::FunctionType *ty, const Twine &name, + const CGFunctionInfo &FI, + SourceLocation Loc = SourceLocation(), + bool TLS = false); + + /// Return the address space of the underlying global variable for D, as + /// determined by its declaration. Normally this is the same as the address + /// space of D's type, but in CUDA, address spaces are associated with + /// declarations, not types. + unsigned GetGlobalVarAddressSpace(const VarDecl *D, unsigned AddrSpace); + + /// Return the llvm::Constant for the address of the given global variable. + /// If Ty is non-null and if the global doesn't exist, then it will be greated + /// with the specified type instead of whatever the normal requested type + /// would be. + llvm::Constant *GetAddrOfGlobalVar(const VarDecl *D, + llvm::Type *Ty = nullptr); + + /// Return the address of the given function. If Ty is non-null, then this + /// function will use the specified type if it has to create it. + llvm::Constant *GetAddrOfFunction(GlobalDecl GD, llvm::Type *Ty = nullptr, + bool ForVTable = false, + bool DontDefer = false, + bool IsForDefinition = false); + + /// Get the address of the RTTI descriptor for the given type. + llvm::Constant *GetAddrOfRTTIDescriptor(QualType Ty, bool ForEH = false); + + /// Get the address of a uuid descriptor . + ConstantAddress GetAddrOfUuidDescriptor(const CXXUuidofExpr* E); + + /// Get the address of the thunk for the given global decl. + llvm::Constant *GetAddrOfThunk(GlobalDecl GD, const ThunkInfo &Thunk); + + /// Get a reference to the target of VD. + ConstantAddress GetWeakRefReference(const ValueDecl *VD); + + /// Returns the assumed alignment of an opaque pointer to the given class. + CharUnits getClassPointerAlignment(const CXXRecordDecl *CD); + + /// Returns the assumed alignment of a virtual base of a class. + CharUnits getVBaseAlignment(CharUnits DerivedAlign, + const CXXRecordDecl *Derived, + const CXXRecordDecl *VBase); + + /// Given a class pointer with an actual known alignment, and the + /// expected alignment of an object at a dynamic offset w.r.t that + /// pointer, return the alignment to assume at the offset. + CharUnits getDynamicOffsetAlignment(CharUnits ActualAlign, + const CXXRecordDecl *Class, + CharUnits ExpectedTargetAlign); + + CharUnits + computeNonVirtualBaseClassOffset(const CXXRecordDecl *DerivedClass, + CastExpr::path_const_iterator Start, + CastExpr::path_const_iterator End); + + /// Returns the offset from a derived class to a class. Returns null if the + /// offset is 0. + llvm::Constant * + GetNonVirtualBaseClassOffset(const CXXRecordDecl *ClassDecl, + CastExpr::path_const_iterator PathBegin, + CastExpr::path_const_iterator PathEnd); + + llvm::FoldingSet ByrefHelpersCache; + + /// Fetches the global unique block count. + int getUniqueBlockCount() { return ++Block.GlobalUniqueCount; } + + /// Fetches the type of a generic block descriptor. + llvm::Type *getBlockDescriptorType(); + + /// The type of a generic block literal. + llvm::Type *getGenericBlockLiteralType(); + + /// Gets the address of a block which requires no captures. + llvm::Constant *GetAddrOfGlobalBlock(const BlockExpr *BE, const char *); + + /// Return a pointer to a constant CFString object for the given string. + ConstantAddress GetAddrOfConstantCFString(const StringLiteral *Literal); + + /// Return a pointer to a constant NSString object for the given string. Or a + /// user defined String object as defined via + /// -fconstant-string-class=class_name option. + ConstantAddress GetAddrOfConstantString(const StringLiteral *Literal); + + /// Return a constant array for the given string. + llvm::Constant *GetConstantArrayFromStringLiteral(const StringLiteral *E); + + /// Return a pointer to a constant array for the given string literal. + ConstantAddress + GetAddrOfConstantStringFromLiteral(const StringLiteral *S, + StringRef Name = ".str"); + + /// Return a pointer to a constant array for the given ObjCEncodeExpr node. + ConstantAddress + GetAddrOfConstantStringFromObjCEncode(const ObjCEncodeExpr *); + + /// Returns a pointer to a character array containing the literal and a + /// terminating '\0' character. The result has pointer to array type. + /// + /// \param GlobalName If provided, the name to use for the global (if one is + /// created). + ConstantAddress + GetAddrOfConstantCString(const std::string &Str, + const char *GlobalName = nullptr); + + /// Returns a pointer to a constant global variable for the given file-scope + /// compound literal expression. + ConstantAddress GetAddrOfConstantCompoundLiteral(const CompoundLiteralExpr*E); + + /// \brief Returns a pointer to a global variable representing a temporary + /// with static or thread storage duration. + ConstantAddress GetAddrOfGlobalTemporary(const MaterializeTemporaryExpr *E, + const Expr *Inner); + + /// \brief Retrieve the record type that describes the state of an + /// Objective-C fast enumeration loop (for..in). + QualType getObjCFastEnumerationStateType(); + + // Produce code for this constructor/destructor. This method doesn't try + // to apply any ABI rules about which other constructors/destructors + // are needed or if they are alias to each other. + llvm::Function *codegenCXXStructor(const CXXMethodDecl *MD, + StructorType Type); + + /// Return the address of the constructor/destructor of the given type. + llvm::Constant * + getAddrOfCXXStructor(const CXXMethodDecl *MD, StructorType Type, + const CGFunctionInfo *FnInfo = nullptr, + llvm::FunctionType *FnType = nullptr, + bool DontDefer = false, bool IsForDefinition = false); + + /// Given a builtin id for a function like "__builtin_fabsf", return a + /// Function* for "fabsf". + llvm::Value *getBuiltinLibFunction(const FunctionDecl *FD, + unsigned BuiltinID); + + llvm::Function *getIntrinsic(unsigned IID, ArrayRef Tys = None); + + /// Emit code for a single top level declaration. + void EmitTopLevelDecl(Decl *D); + + /// \brief Stored a deferred empty coverage mapping for an unused + /// and thus uninstrumented top level declaration. + void AddDeferredUnusedCoverageMapping(Decl *D); + + /// \brief Remove the deferred empty coverage mapping as this + /// declaration is actually instrumented. + void ClearUnusedCoverageMapping(const Decl *D); + + /// \brief Emit all the deferred coverage mappings + /// for the uninstrumented functions. + void EmitDeferredUnusedCoverageMappings(); + + /// Tell the consumer that this variable has been instantiated. + void HandleCXXStaticMemberVarInstantiation(VarDecl *VD); + + /// \brief If the declaration has internal linkage but is inside an + /// extern "C" linkage specification, prepare to emit an alias for it + /// to the expected name. + template + void MaybeHandleStaticInExternC(const SomeDecl *D, llvm::GlobalValue *GV); + + /// Add a global to a list to be added to the llvm.used metadata. + void addUsedGlobal(llvm::GlobalValue *GV); + + /// Add a global to a list to be added to the llvm.compiler.used metadata. + void addCompilerUsedGlobal(llvm::GlobalValue *GV); + + /// Add a destructor and object to add to the C++ global destructor function. + void AddCXXDtorEntry(llvm::Constant *DtorFn, llvm::Constant *Object) { + CXXGlobalDtors.emplace_back(DtorFn, Object); + } + + /// Create a new runtime function with the specified type and name. + llvm::Constant *CreateRuntimeFunction(llvm::FunctionType *Ty, + StringRef Name, + llvm::AttributeSet ExtraAttrs = + llvm::AttributeSet()); + /// Create a new compiler builtin function with the specified type and name. + llvm::Constant *CreateBuiltinFunction(llvm::FunctionType *Ty, + StringRef Name, + llvm::AttributeSet ExtraAttrs = + llvm::AttributeSet()); + /// Create a new runtime global variable with the specified type and name. + llvm::Constant *CreateRuntimeVariable(llvm::Type *Ty, + StringRef Name); + + ///@name Custom Blocks Runtime Interfaces + ///@{ + + llvm::Constant *getNSConcreteGlobalBlock(); + llvm::Constant *getNSConcreteStackBlock(); + llvm::Constant *getBlockObjectAssign(); + llvm::Constant *getBlockObjectDispose(); + + ///@} + + llvm::Constant *getLLVMLifetimeStartFn(); + llvm::Constant *getLLVMLifetimeEndFn(); + + // Make sure that this type is translated. + void UpdateCompletedType(const TagDecl *TD); + + llvm::Constant *getMemberPointerConstant(const UnaryOperator *e); + + /// Try to emit the initializer for the given declaration as a constant; + /// returns 0 if the expression cannot be emitted as a constant. + llvm::Constant *EmitConstantInit(const VarDecl &D, + CodeGenFunction *CGF = nullptr); + + /// Try to emit the given expression as a constant; returns 0 if the + /// expression cannot be emitted as a constant. + llvm::Constant *EmitConstantExpr(const Expr *E, QualType DestType, + CodeGenFunction *CGF = nullptr); + + /// Emit the given constant value as a constant, in the type's scalar + /// representation. + llvm::Constant *EmitConstantValue(const APValue &Value, QualType DestType, + CodeGenFunction *CGF = nullptr); + + /// Emit the given constant value as a constant, in the type's memory + /// representation. + llvm::Constant *EmitConstantValueForMemory(const APValue &Value, + QualType DestType, + CodeGenFunction *CGF = nullptr); + + /// \brief Emit type info if type of an expression is a variably modified + /// type. Also emit proper debug info for cast types. + void EmitExplicitCastExprType(const ExplicitCastExpr *E, + CodeGenFunction *CGF = nullptr); + + /// Return the result of value-initializing the given type, i.e. a null + /// expression of the given type. This is usually, but not always, an LLVM + /// null constant. + llvm::Constant *EmitNullConstant(QualType T); + + /// Return a null constant appropriate for zero-initializing a base class with + /// the given type. This is usually, but not always, an LLVM null constant. + llvm::Constant *EmitNullConstantForBase(const CXXRecordDecl *Record); + + /// Emit a general error that something can't be done. + void Error(SourceLocation loc, StringRef error); + + /// Print out an error that codegen doesn't support the specified stmt yet. + void ErrorUnsupported(const Stmt *S, const char *Type); + + /// Print out an error that codegen doesn't support the specified decl yet. + void ErrorUnsupported(const Decl *D, const char *Type); + + /// Set the attributes on the LLVM function for the given decl and function + /// info. This applies attributes necessary for handling the ABI as well as + /// user specified attributes like section. + void SetInternalFunctionAttributes(const Decl *D, llvm::Function *F, + const CGFunctionInfo &FI); + + /// Set the LLVM function attributes (sext, zext, etc). + void SetLLVMFunctionAttributes(const Decl *D, + const CGFunctionInfo &Info, + llvm::Function *F); + + /// Set the LLVM function attributes which only apply to a function + /// definition. + void SetLLVMFunctionAttributesForDefinition(const Decl *D, llvm::Function *F); + + /// Return true iff the given type uses 'sret' when used as a return type. + bool ReturnTypeUsesSRet(const CGFunctionInfo &FI); + + /// Return true iff the given type uses an argument slot when 'sret' is used + /// as a return type. + bool ReturnSlotInterferesWithArgs(const CGFunctionInfo &FI); + + /// Return true iff the given type uses 'fpret' when used as a return type. + bool ReturnTypeUsesFPRet(QualType ResultType); + + /// Return true iff the given type uses 'fp2ret' when used as a return type. + bool ReturnTypeUsesFP2Ret(QualType ResultType); + + /// Get the LLVM attributes and calling convention to use for a particular + /// function type. + /// + /// \param Name - The function name. + /// \param Info - The function type information. + /// \param CalleeInfo - The callee information these attributes are being + /// constructed for. If valid, the attributes applied to this decl may + /// contribute to the function attributes and calling convention. + /// \param PAL [out] - On return, the attribute list to use. + /// \param CallingConv [out] - On return, the LLVM calling convention to use. + void ConstructAttributeList(StringRef Name, const CGFunctionInfo &Info, + CGCalleeInfo CalleeInfo, AttributeListType &PAL, + unsigned &CallingConv, bool AttrOnCallSite); + + // Fills in the supplied string map with the set of target features for the + // passed in function. + void getFunctionFeatureMap(llvm::StringMap &FeatureMap, + const FunctionDecl *FD); + + StringRef getMangledName(GlobalDecl GD); + StringRef getBlockMangledName(GlobalDecl GD, const BlockDecl *BD); + + void EmitTentativeDefinition(const VarDecl *D); + + void EmitVTable(CXXRecordDecl *Class); + + /// \brief Appends Opts to the "Linker Options" metadata value. + void AppendLinkerOptions(StringRef Opts); + + /// \brief Appends a detect mismatch command to the linker options. + void AddDetectMismatch(StringRef Name, StringRef Value); + + /// \brief Appends a dependent lib to the "Linker Options" metadata value. + void AddDependentLib(StringRef Lib); + + llvm::GlobalVariable::LinkageTypes getFunctionLinkage(GlobalDecl GD); + + void setFunctionLinkage(GlobalDecl GD, llvm::Function *F) { + F->setLinkage(getFunctionLinkage(GD)); + } + + /// Set the DLL storage class on F. + void setFunctionDLLStorageClass(GlobalDecl GD, llvm::Function *F); + + /// Return the appropriate linkage for the vtable, VTT, and type information + /// of the given class. + llvm::GlobalVariable::LinkageTypes getVTableLinkage(const CXXRecordDecl *RD); + + /// Return the store size, in character units, of the given LLVM type. + CharUnits GetTargetTypeStoreSize(llvm::Type *Ty) const; + + /// Returns LLVM linkage for a declarator. + llvm::GlobalValue::LinkageTypes + getLLVMLinkageForDeclarator(const DeclaratorDecl *D, GVALinkage Linkage, + bool IsConstantVariable); + + /// Returns LLVM linkage for a declarator. + llvm::GlobalValue::LinkageTypes + getLLVMLinkageVarDefinition(const VarDecl *VD, bool IsConstant); + + /// Emit all the global annotations. + void EmitGlobalAnnotations(); + + /// Emit an annotation string. + llvm::Constant *EmitAnnotationString(StringRef Str); + + /// Emit the annotation's translation unit. + llvm::Constant *EmitAnnotationUnit(SourceLocation Loc); + + /// Emit the annotation line number. + llvm::Constant *EmitAnnotationLineNo(SourceLocation L); + + /// Generate the llvm::ConstantStruct which contains the annotation + /// information for a given GlobalValue. The annotation struct is + /// {i8 *, i8 *, i8 *, i32}. The first field is a constant expression, the + /// GlobalValue being annotated. The second field is the constant string + /// created from the AnnotateAttr's annotation. The third field is a constant + /// string containing the name of the translation unit. The fourth field is + /// the line number in the file of the annotated value declaration. + llvm::Constant *EmitAnnotateAttr(llvm::GlobalValue *GV, + const AnnotateAttr *AA, + SourceLocation L); + + /// Add global annotations that are set on D, for the global GV. Those + /// annotations are emitted during finalization of the LLVM code. + void AddGlobalAnnotations(const ValueDecl *D, llvm::GlobalValue *GV); + + bool isInSanitizerBlacklist(llvm::Function *Fn, SourceLocation Loc) const; + + bool isInSanitizerBlacklist(llvm::GlobalVariable *GV, SourceLocation Loc, + QualType Ty, + StringRef Category = StringRef()) const; + + SanitizerMetadata *getSanitizerMetadata() { + return SanitizerMD.get(); + } + + void addDeferredVTable(const CXXRecordDecl *RD) { + DeferredVTables.push_back(RD); + } + + /// Emit code for a singal global function or var decl. Forward declarations + /// are emitted lazily. + void EmitGlobal(GlobalDecl D); + + bool TryEmitDefinitionAsAlias(GlobalDecl Alias, GlobalDecl Target, + bool InEveryTU); + bool TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D); + + /// Set attributes for a global definition. + void setFunctionDefinitionAttributes(const FunctionDecl *D, + llvm::Function *F); + + llvm::GlobalValue *GetGlobalValue(StringRef Ref); + + /// Set attributes which are common to any form of a global definition (alias, + /// Objective-C method, function, global variable). + /// + /// NOTE: This should only be called for definitions. + void SetCommonAttributes(const Decl *D, llvm::GlobalValue *GV); + + /// Set attributes which must be preserved by an alias. This includes common + /// attributes (i.e. it includes a call to SetCommonAttributes). + /// + /// NOTE: This should only be called for definitions. + void setAliasAttributes(const Decl *D, llvm::GlobalValue *GV); + + void addReplacement(StringRef Name, llvm::Constant *C); + + void addGlobalValReplacement(llvm::GlobalValue *GV, llvm::Constant *C); + + /// \brief Emit a code for threadprivate directive. + /// \param D Threadprivate declaration. + void EmitOMPThreadPrivateDecl(const OMPThreadPrivateDecl *D); + + /// Returns whether the given record is blacklisted from control flow + /// integrity checks. + bool IsCFIBlacklistedRecord(const CXXRecordDecl *RD); + + /// Emit bit set entries for the given vtable using the given layout if + /// vptr CFI is enabled. + void EmitVTableBitSetEntries(llvm::GlobalVariable *VTable, + const VTableLayout &VTLayout); + + /// Generate a cross-DSO type identifier for type. + llvm::ConstantInt *CreateCfiIdForTypeMetadata(llvm::Metadata *MD); + + /// Create a metadata identifier for the given type. This may either be an + /// MDString (for external identifiers) or a distinct unnamed MDNode (for + /// internal identifiers). + llvm::Metadata *CreateMetadataIdentifierForType(QualType T); + + /// Create a bitset entry for the given function and add it to BitsetsMD. + void CreateFunctionBitSetEntry(const FunctionDecl *FD, llvm::Function *F); + + /// Create a bitset entry for the given vtable and add it to BitsetsMD. + void CreateVTableBitSetEntry(llvm::NamedMDNode *BitsetsMD, + llvm::GlobalVariable *VTable, CharUnits Offset, + const CXXRecordDecl *RD); + + /// \breif Get the declaration of std::terminate for the platform. + llvm::Constant *getTerminateFn(); + +private: + llvm::Constant * + GetOrCreateLLVMFunction(StringRef MangledName, llvm::Type *Ty, GlobalDecl D, + bool ForVTable, bool DontDefer = false, + bool IsThunk = false, + llvm::AttributeSet ExtraAttrs = llvm::AttributeSet(), + bool IsForDefinition = false); + + llvm::Constant *GetOrCreateLLVMGlobal(StringRef MangledName, + llvm::PointerType *PTy, + const VarDecl *D); + + void setNonAliasAttributes(const Decl *D, llvm::GlobalObject *GO); + + /// Set function attributes for a function declaration. + void SetFunctionAttributes(GlobalDecl GD, llvm::Function *F, + bool IsIncompleteFunction, bool IsThunk); + + void EmitGlobalDefinition(GlobalDecl D, llvm::GlobalValue *GV = nullptr); + + void EmitGlobalFunctionDefinition(GlobalDecl GD, llvm::GlobalValue *GV); + void EmitGlobalVarDefinition(const VarDecl *D); + void EmitAliasDefinition(GlobalDecl GD); + void EmitObjCPropertyImplementations(const ObjCImplementationDecl *D); + void EmitObjCIvarInitializations(ObjCImplementationDecl *D); + + // C++ related functions. + + void EmitNamespace(const NamespaceDecl *D); + void EmitLinkageSpec(const LinkageSpecDecl *D); + void CompleteDIClassType(const CXXMethodDecl* D); + + /// \brief Emit the function that initializes C++ thread_local variables. + void EmitCXXThreadLocalInitFunc(); + + /// Emit the function that initializes C++ globals. + void EmitCXXGlobalInitFunc(); + + /// Emit the function that destroys C++ globals. + void EmitCXXGlobalDtorFunc(); + + /// Emit the function that initializes the specified global (if PerformInit is + /// true) and registers its destructor. + void EmitCXXGlobalVarDeclInitFunc(const VarDecl *D, + llvm::GlobalVariable *Addr, + bool PerformInit); + + void EmitPointerToInitFunc(const VarDecl *VD, llvm::GlobalVariable *Addr, + llvm::Function *InitFunc, InitSegAttr *ISA); + + // FIXME: Hardcoding priority here is gross. + void AddGlobalCtor(llvm::Function *Ctor, int Priority = 65535, + llvm::Constant *AssociatedData = nullptr); + void AddGlobalDtor(llvm::Function *Dtor, int Priority = 65535); + + /// Generates a global array of functions and priorities using the given list + /// and name. This array will have appending linkage and is suitable for use + /// as a LLVM constructor or destructor array. + void EmitCtorList(const CtorList &Fns, const char *GlobalName); + + /// Emit any needed decls for which code generation was deferred. + void EmitDeferred(); + + /// Call replaceAllUsesWith on all pairs in Replacements. + void applyReplacements(); + + /// Call replaceAllUsesWith on all pairs in GlobalValReplacements. + void applyGlobalValReplacements(); + + void checkAliases(); + + /// Emit any vtables which we deferred and still have a use for. + void EmitDeferredVTables(); + + /// Emit the llvm.used and llvm.compiler.used metadata. + void emitLLVMUsed(); + + /// \brief Emit the link options introduced by imported modules. + void EmitModuleLinkOptions(); + + /// \brief Emit aliases for internal-linkage declarations inside "C" language + /// linkage specifications, giving them the "expected" name where possible. + void EmitStaticExternCAliases(); + + void EmitDeclMetadata(); + + /// \brief Emit the Clang version as llvm.ident metadata. + void EmitVersionIdentMetadata(); + + /// Emits target specific Metadata for global declarations. + void EmitTargetMetadata(); + + /// Emit the llvm.gcov metadata used to tell LLVM where to emit the .gcno and + /// .gcda files in a way that persists in .bc files. + void EmitCoverageFile(); + + /// Emits the initializer for a uuidof string. + llvm::Constant *EmitUuidofInitializer(StringRef uuidstr); + + /// Determine whether the definition must be emitted; if this returns \c + /// false, the definition can be emitted lazily if it's used. + bool MustBeEmitted(const ValueDecl *D); + + /// Determine whether the definition can be emitted eagerly, or should be + /// delayed until the end of the translation unit. This is relevant for + /// definitions whose linkage can change, e.g. implicit function instantions + /// which may later be explicitly instantiated. + bool MayBeEmittedEagerly(const ValueDecl *D); + + /// Check whether we can use a "simpler", more core exceptions personality + /// function. + void SimplifyPersonality(); +}; +} // end namespace CodeGen +} // end namespace clang + +#endif // LLVM_CLANG_LIB_CODEGEN_CODEGENMODULE_H diff --git a/vendors/clang-codegen-private-3.8/CodeGenTypeCache.h b/vendors/clang-codegen-private-3.8/CodeGenTypeCache.h new file mode 100644 index 0000000..c32b66d --- /dev/null +++ b/vendors/clang-codegen-private-3.8/CodeGenTypeCache.h @@ -0,0 +1,108 @@ +//===--- CodeGenTypeCache.h - Commonly used LLVM types and info -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This structure provides a set of common types useful during IR emission. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LIB_CODEGEN_CODEGENTYPECACHE_H +#define LLVM_CLANG_LIB_CODEGEN_CODEGENTYPECACHE_H + +#include "clang/AST/CharUnits.h" +#include "llvm/IR/CallingConv.h" + +namespace llvm { + class Type; + class IntegerType; + class PointerType; +} + +namespace clang { +namespace CodeGen { + +/// This structure provides a set of types that are commonly used +/// during IR emission. It's initialized once in CodeGenModule's +/// constructor and then copied around into new CodeGenFunctions. +struct CodeGenTypeCache { + /// void + llvm::Type *VoidTy; + + /// i8, i16, i32, and i64 + llvm::IntegerType *Int8Ty, *Int16Ty, *Int32Ty, *Int64Ty; + /// float, double + llvm::Type *FloatTy, *DoubleTy; + + /// int + llvm::IntegerType *IntTy; + + /// intptr_t, size_t, and ptrdiff_t, which we assume are the same size. + union { + llvm::IntegerType *IntPtrTy; + llvm::IntegerType *SizeTy; + llvm::IntegerType *PtrDiffTy; + }; + + /// void* in address space 0 + union { + llvm::PointerType *VoidPtrTy; + llvm::PointerType *Int8PtrTy; + }; + + /// void** in address space 0 + union { + llvm::PointerType *VoidPtrPtrTy; + llvm::PointerType *Int8PtrPtrTy; + }; + + /// The size and alignment of the builtin C type 'int'. This comes + /// up enough in various ABI lowering tasks to be worth pre-computing. + union { + unsigned char IntSizeInBytes; + unsigned char IntAlignInBytes; + }; + CharUnits getIntSize() const { + return CharUnits::fromQuantity(IntSizeInBytes); + } + CharUnits getIntAlign() const { + return CharUnits::fromQuantity(IntAlignInBytes); + } + + /// The width of a pointer into the generic address space. + unsigned char PointerWidthInBits; + + /// The size and alignment of a pointer into the generic address space. + union { + unsigned char PointerAlignInBytes; + unsigned char PointerSizeInBytes; + unsigned char SizeSizeInBytes; // sizeof(size_t) + unsigned char SizeAlignInBytes; + }; + CharUnits getSizeSize() const { + return CharUnits::fromQuantity(SizeSizeInBytes); + } + CharUnits getSizeAlign() const { + return CharUnits::fromQuantity(SizeAlignInBytes); + } + CharUnits getPointerSize() const { + return CharUnits::fromQuantity(PointerSizeInBytes); + } + CharUnits getPointerAlign() const { + return CharUnits::fromQuantity(PointerAlignInBytes); + } + + llvm::CallingConv::ID RuntimeCC; + llvm::CallingConv::ID getRuntimeCC() const { return RuntimeCC; } + llvm::CallingConv::ID BuiltinCC; + llvm::CallingConv::ID getBuiltinCC() const { return BuiltinCC; } +}; + +} // end namespace CodeGen +} // end namespace clang + +#endif diff --git a/vendors/clang-codegen-private-3.8/CodeGenTypes.h b/vendors/clang-codegen-private-3.8/CodeGenTypes.h new file mode 100644 index 0000000..a96f23c --- /dev/null +++ b/vendors/clang-codegen-private-3.8/CodeGenTypes.h @@ -0,0 +1,335 @@ +//===--- CodeGenTypes.h - Type translation for LLVM CodeGen -----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This is the code that handles AST -> LLVM type lowering. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LIB_CODEGEN_CODEGENTYPES_H +#define LLVM_CLANG_LIB_CODEGEN_CODEGENTYPES_H + +#include "CGCall.h" +#include "clang/AST/GlobalDecl.h" +#include "clang/CodeGen/CGFunctionInfo.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/IR/Module.h" +#include + +namespace llvm { +class FunctionType; +class Module; +class DataLayout; +class Type; +class LLVMContext; +class StructType; +} + +namespace clang { +class ABIInfo; +class ASTContext; +template class CanQual; +class CXXConstructorDecl; +class CXXDestructorDecl; +class CXXMethodDecl; +class CodeGenOptions; +class FieldDecl; +class FunctionProtoType; +class ObjCInterfaceDecl; +class ObjCIvarDecl; +class PointerType; +class QualType; +class RecordDecl; +class TagDecl; +class TargetInfo; +class Type; +typedef CanQual CanQualType; + +namespace CodeGen { +class CGCXXABI; +class CGRecordLayout; +class CodeGenModule; +class RequiredArgs; + +enum class StructorType { + Complete, // constructor or destructor + Base, // constructor or destructor + Deleting // destructor only +}; + +inline CXXCtorType toCXXCtorType(StructorType T) { + switch (T) { + case StructorType::Complete: + return Ctor_Complete; + case StructorType::Base: + return Ctor_Base; + case StructorType::Deleting: + llvm_unreachable("cannot have a deleting ctor"); + } + llvm_unreachable("not a StructorType"); +} + +inline StructorType getFromCtorType(CXXCtorType T) { + switch (T) { + case Ctor_Complete: + return StructorType::Complete; + case Ctor_Base: + return StructorType::Base; + case Ctor_Comdat: + llvm_unreachable("not expecting a COMDAT"); + case Ctor_CopyingClosure: + case Ctor_DefaultClosure: + llvm_unreachable("not expecting a closure"); + } + llvm_unreachable("not a CXXCtorType"); +} + +inline CXXDtorType toCXXDtorType(StructorType T) { + switch (T) { + case StructorType::Complete: + return Dtor_Complete; + case StructorType::Base: + return Dtor_Base; + case StructorType::Deleting: + return Dtor_Deleting; + } + llvm_unreachable("not a StructorType"); +} + +inline StructorType getFromDtorType(CXXDtorType T) { + switch (T) { + case Dtor_Deleting: + return StructorType::Deleting; + case Dtor_Complete: + return StructorType::Complete; + case Dtor_Base: + return StructorType::Base; + case Dtor_Comdat: + llvm_unreachable("not expecting a COMDAT"); + } + llvm_unreachable("not a CXXDtorType"); +} + +/// This class organizes the cross-module state that is used while lowering +/// AST types to LLVM types. +class CodeGenTypes { + CodeGenModule &CGM; + // Some of this stuff should probably be left on the CGM. + ASTContext &Context; + llvm::Module &TheModule; + const TargetInfo &Target; + CGCXXABI &TheCXXABI; + + // This should not be moved earlier, since its initialization depends on some + // of the previous reference members being already initialized + const ABIInfo &TheABIInfo; + + /// The opaque type map for Objective-C interfaces. All direct + /// manipulation is done by the runtime interfaces, which are + /// responsible for coercing to the appropriate type; these opaque + /// types are never refined. + llvm::DenseMap InterfaceTypes; + + /// Maps clang struct type with corresponding record layout info. + llvm::DenseMap CGRecordLayouts; + + /// Contains the LLVM IR type for any converted RecordDecl. + llvm::DenseMap RecordDeclTypes; + + /// Hold memoized CGFunctionInfo results. + llvm::FoldingSet FunctionInfos; + + /// This set keeps track of records that we're currently converting + /// to an IR type. For example, when converting: + /// struct A { struct B { int x; } } when processing 'x', the 'A' and 'B' + /// types will be in this set. + llvm::SmallPtrSet RecordsBeingLaidOut; + + llvm::SmallPtrSet FunctionsBeingProcessed; + + /// True if we didn't layout a function due to a being inside + /// a recursive struct conversion, set this to true. + bool SkippedLayout; + + SmallVector DeferredRecords; + + /// This map keeps cache of llvm::Types and maps clang::Type to + /// corresponding llvm::Type. + llvm::DenseMap TypeCache; + +public: + CodeGenTypes(CodeGenModule &cgm); + ~CodeGenTypes(); + + const llvm::DataLayout &getDataLayout() const { + return TheModule.getDataLayout(); + } + ASTContext &getContext() const { return Context; } + const ABIInfo &getABIInfo() const { return TheABIInfo; } + const TargetInfo &getTarget() const { return Target; } + CGCXXABI &getCXXABI() const { return TheCXXABI; } + llvm::LLVMContext &getLLVMContext() { return TheModule.getContext(); } + + /// ConvertType - Convert type T into a llvm::Type. + llvm::Type *ConvertType(QualType T); + + /// \brief Converts the GlobalDecl into an llvm::Type. This should be used + /// when we know the target of the function we want to convert. This is + /// because some functions (explicitly, those with pass_object_size + /// parameters) may not have the same signature as their type portrays, and + /// can only be called directly. + llvm::Type *ConvertFunctionType(QualType FT, + const FunctionDecl *FD = nullptr); + + /// ConvertTypeForMem - Convert type T into a llvm::Type. This differs from + /// ConvertType in that it is used to convert to the memory representation for + /// a type. For example, the scalar representation for _Bool is i1, but the + /// memory representation is usually i8 or i32, depending on the target. + llvm::Type *ConvertTypeForMem(QualType T); + + /// GetFunctionType - Get the LLVM function type for \arg Info. + llvm::FunctionType *GetFunctionType(const CGFunctionInfo &Info); + + llvm::FunctionType *GetFunctionType(GlobalDecl GD); + + /// isFuncTypeConvertible - Utility to check whether a function type can + /// be converted to an LLVM type (i.e. doesn't depend on an incomplete tag + /// type). + bool isFuncTypeConvertible(const FunctionType *FT); + bool isFuncParamTypeConvertible(QualType Ty); + + /// GetFunctionTypeForVTable - Get the LLVM function type for use in a vtable, + /// given a CXXMethodDecl. If the method to has an incomplete return type, + /// and/or incomplete argument types, this will return the opaque type. + llvm::Type *GetFunctionTypeForVTable(GlobalDecl GD); + + const CGRecordLayout &getCGRecordLayout(const RecordDecl*); + + /// UpdateCompletedType - When we find the full definition for a TagDecl, + /// replace the 'opaque' type we previously made for it if applicable. + void UpdateCompletedType(const TagDecl *TD); + + /// getNullaryFunctionInfo - Get the function info for a void() + /// function with standard CC. + const CGFunctionInfo &arrangeNullaryFunction(); + + // The arrangement methods are split into three families: + // - those meant to drive the signature and prologue/epilogue + // of a function declaration or definition, + // - those meant for the computation of the LLVM type for an abstract + // appearance of a function, and + // - those meant for performing the IR-generation of a call. + // They differ mainly in how they deal with optional (i.e. variadic) + // arguments, as well as unprototyped functions. + // + // Key points: + // - The CGFunctionInfo for emitting a specific call site must include + // entries for the optional arguments. + // - The function type used at the call site must reflect the formal + // signature of the declaration being called, or else the call will + // go awry. + // - For the most part, unprototyped functions are called by casting to + // a formal signature inferred from the specific argument types used + // at the call-site. However, some targets (e.g. x86-64) screw with + // this for compatibility reasons. + + const CGFunctionInfo &arrangeGlobalDeclaration(GlobalDecl GD); + const CGFunctionInfo &arrangeFunctionDeclaration(const FunctionDecl *FD); + const CGFunctionInfo & + arrangeFreeFunctionDeclaration(QualType ResTy, const FunctionArgList &Args, + const FunctionType::ExtInfo &Info, + bool isVariadic); + + const CGFunctionInfo &arrangeObjCMethodDeclaration(const ObjCMethodDecl *MD); + const CGFunctionInfo &arrangeObjCMessageSendSignature(const ObjCMethodDecl *MD, + QualType receiverType); + + const CGFunctionInfo &arrangeCXXMethodDeclaration(const CXXMethodDecl *MD); + const CGFunctionInfo &arrangeCXXStructorDeclaration(const CXXMethodDecl *MD, + StructorType Type); + const CGFunctionInfo &arrangeCXXConstructorCall(const CallArgList &Args, + const CXXConstructorDecl *D, + CXXCtorType CtorKind, + unsigned ExtraArgs); + const CGFunctionInfo &arrangeFreeFunctionCall(const CallArgList &Args, + const FunctionType *Ty, + bool ChainCall); + const CGFunctionInfo &arrangeFreeFunctionCall(QualType ResTy, + const CallArgList &args, + FunctionType::ExtInfo info, + RequiredArgs required); + const CGFunctionInfo &arrangeBlockFunctionCall(const CallArgList &args, + const FunctionType *type); + + const CGFunctionInfo &arrangeCXXMethodCall(const CallArgList &args, + const FunctionProtoType *type, + RequiredArgs required); + const CGFunctionInfo &arrangeMSMemberPointerThunk(const CXXMethodDecl *MD); + const CGFunctionInfo &arrangeMSCtorClosure(const CXXConstructorDecl *CD, + CXXCtorType CT); + const CGFunctionInfo &arrangeFreeFunctionType(CanQual Ty, + const FunctionDecl *FD); + const CGFunctionInfo &arrangeFreeFunctionType(CanQual Ty); + const CGFunctionInfo &arrangeCXXMethodType(const CXXRecordDecl *RD, + const FunctionProtoType *FTP, + const CXXMethodDecl *MD); + + /// "Arrange" the LLVM information for a call or type with the given + /// signature. This is largely an internal method; other clients + /// should use one of the above routines, which ultimately defer to + /// this. + /// + /// \param argTypes - must all actually be canonical as params + const CGFunctionInfo &arrangeLLVMFunctionInfo(CanQualType returnType, + bool instanceMethod, + bool chainCall, + ArrayRef argTypes, + FunctionType::ExtInfo info, + RequiredArgs args); + + /// \brief Compute a new LLVM record layout object for the given record. + CGRecordLayout *ComputeRecordLayout(const RecordDecl *D, + llvm::StructType *Ty); + + /// addRecordTypeName - Compute a name from the given record decl with an + /// optional suffix and name the given LLVM type using it. + void addRecordTypeName(const RecordDecl *RD, llvm::StructType *Ty, + StringRef suffix); + + +public: // These are internal details of CGT that shouldn't be used externally. + /// ConvertRecordDeclType - Lay out a tagged decl type like struct or union. + llvm::StructType *ConvertRecordDeclType(const RecordDecl *TD); + + /// getExpandedTypes - Expand the type \arg Ty into the LLVM + /// argument types it would be passed as. See ABIArgInfo::Expand. + void getExpandedTypes(QualType Ty, + SmallVectorImpl::iterator &TI); + + /// IsZeroInitializable - Return whether a type can be + /// zero-initialized (in the C++ sense) with an LLVM zeroinitializer. + bool isZeroInitializable(QualType T); + + /// IsZeroInitializable - Return whether a record type can be + /// zero-initialized (in the C++ sense) with an LLVM zeroinitializer. + bool isZeroInitializable(const RecordDecl *RD); + + bool isRecordLayoutComplete(const Type *Ty) const; + bool noRecordsBeingLaidOut() const { + return RecordsBeingLaidOut.empty(); + } + bool isRecordBeingLaidOut(const Type *Ty) const { + return RecordsBeingLaidOut.count(Ty); + } + +}; + +} // end namespace CodeGen +} // end namespace clang + +#endif diff --git a/vendors/clang-codegen-private-3.8/EHScopeStack.h b/vendors/clang-codegen-private-3.8/EHScopeStack.h new file mode 100644 index 0000000..85cd154 --- /dev/null +++ b/vendors/clang-codegen-private-3.8/EHScopeStack.h @@ -0,0 +1,420 @@ +//===-- EHScopeStack.h - Stack for cleanup IR generation --------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// These classes should be the minimum interface required for other parts of +// CodeGen to emit cleanups. The implementation is in CGCleanup.cpp and other +// implemenentation details that are not widely needed are in CGCleanup.h. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LIB_CODEGEN_EHSCOPESTACK_H +#define LLVM_CLANG_LIB_CODEGEN_EHSCOPESTACK_H + +#include "clang/Basic/LLVM.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/IR/BasicBlock.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/Value.h" + +namespace clang { +namespace CodeGen { + +class CodeGenFunction; + +/// A branch fixup. These are required when emitting a goto to a +/// label which hasn't been emitted yet. The goto is optimistically +/// emitted as a branch to the basic block for the label, and (if it +/// occurs in a scope with non-trivial cleanups) a fixup is added to +/// the innermost cleanup. When a (normal) cleanup is popped, any +/// unresolved fixups in that scope are threaded through the cleanup. +struct BranchFixup { + /// The block containing the terminator which needs to be modified + /// into a switch if this fixup is resolved into the current scope. + /// If null, LatestBranch points directly to the destination. + llvm::BasicBlock *OptimisticBranchBlock; + + /// The ultimate destination of the branch. + /// + /// This can be set to null to indicate that this fixup was + /// successfully resolved. + llvm::BasicBlock *Destination; + + /// The destination index value. + unsigned DestinationIndex; + + /// The initial branch of the fixup. + llvm::BranchInst *InitialBranch; +}; + +template struct InvariantValue { + typedef T type; + typedef T saved_type; + static bool needsSaving(type value) { return false; } + static saved_type save(CodeGenFunction &CGF, type value) { return value; } + static type restore(CodeGenFunction &CGF, saved_type value) { return value; } +}; + +/// A metaprogramming class for ensuring that a value will dominate an +/// arbitrary position in a function. +template struct DominatingValue : InvariantValue {}; + +template ::value && + !std::is_base_of::value && + !std::is_base_of::value> +struct DominatingPointer; +template struct DominatingPointer : InvariantValue {}; +// template struct DominatingPointer at end of file + +template struct DominatingValue : DominatingPointer {}; + +enum CleanupKind : unsigned { + /// Denotes a cleanup that should run when a scope is exited using exceptional + /// control flow (a throw statement leading to stack unwinding, ). + EHCleanup = 0x1, + + /// Denotes a cleanup that should run when a scope is exited using normal + /// control flow (falling off the end of the scope, return, goto, ...). + NormalCleanup = 0x2, + + NormalAndEHCleanup = EHCleanup | NormalCleanup, + + InactiveCleanup = 0x4, + InactiveEHCleanup = EHCleanup | InactiveCleanup, + InactiveNormalCleanup = NormalCleanup | InactiveCleanup, + InactiveNormalAndEHCleanup = NormalAndEHCleanup | InactiveCleanup +}; + +/// A stack of scopes which respond to exceptions, including cleanups +/// and catch blocks. +class EHScopeStack { +public: + /* Should switch to alignof(uint64_t) instead of 8, when EHCleanupScope can */ + enum { ScopeStackAlignment = 8 }; + + /// A saved depth on the scope stack. This is necessary because + /// pushing scopes onto the stack invalidates iterators. + class stable_iterator { + friend class EHScopeStack; + + /// Offset from StartOfData to EndOfBuffer. + ptrdiff_t Size; + + stable_iterator(ptrdiff_t Size) : Size(Size) {} + + public: + static stable_iterator invalid() { return stable_iterator(-1); } + stable_iterator() : Size(-1) {} + + bool isValid() const { return Size >= 0; } + + /// Returns true if this scope encloses I. + /// Returns false if I is invalid. + /// This scope must be valid. + bool encloses(stable_iterator I) const { return Size <= I.Size; } + + /// Returns true if this scope strictly encloses I: that is, + /// if it encloses I and is not I. + /// Returns false is I is invalid. + /// This scope must be valid. + bool strictlyEncloses(stable_iterator I) const { return Size < I.Size; } + + friend bool operator==(stable_iterator A, stable_iterator B) { + return A.Size == B.Size; + } + friend bool operator!=(stable_iterator A, stable_iterator B) { + return A.Size != B.Size; + } + }; + + /// Information for lazily generating a cleanup. Subclasses must be + /// POD-like: cleanups will not be destructed, and they will be + /// allocated on the cleanup stack and freely copied and moved + /// around. + /// + /// Cleanup implementations should generally be declared in an + /// anonymous namespace. + class Cleanup { + // Anchor the construction vtable. + virtual void anchor(); + + protected: + ~Cleanup() = default; + + public: + Cleanup(const Cleanup &) = default; + Cleanup(Cleanup &&) {} + Cleanup() = default; + + /// Generation flags. + class Flags { + enum { + F_IsForEH = 0x1, + F_IsNormalCleanupKind = 0x2, + F_IsEHCleanupKind = 0x4 + }; + unsigned flags; + + public: + Flags() : flags(0) {} + + /// isForEH - true if the current emission is for an EH cleanup. + bool isForEHCleanup() const { return flags & F_IsForEH; } + bool isForNormalCleanup() const { return !isForEHCleanup(); } + void setIsForEHCleanup() { flags |= F_IsForEH; } + + bool isNormalCleanupKind() const { return flags & F_IsNormalCleanupKind; } + void setIsNormalCleanupKind() { flags |= F_IsNormalCleanupKind; } + + /// isEHCleanupKind - true if the cleanup was pushed as an EH + /// cleanup. + bool isEHCleanupKind() const { return flags & F_IsEHCleanupKind; } + void setIsEHCleanupKind() { flags |= F_IsEHCleanupKind; } + }; + + + /// Emit the cleanup. For normal cleanups, this is run in the + /// same EH context as when the cleanup was pushed, i.e. the + /// immediately-enclosing context of the cleanup scope. For + /// EH cleanups, this is run in a terminate context. + /// + // \param flags cleanup kind. + virtual void Emit(CodeGenFunction &CGF, Flags flags) = 0; + }; + + /// ConditionalCleanup stores the saved form of its parameters, + /// then restores them and performs the cleanup. + template + class ConditionalCleanup final : public Cleanup { + typedef std::tuple::saved_type...> SavedTuple; + SavedTuple Saved; + + template + T restore(CodeGenFunction &CGF, llvm::index_sequence) { + // It's important that the restores are emitted in order. The braced init + // list guarentees that. + return T{DominatingValue::restore(CGF, std::get(Saved))...}; + } + + void Emit(CodeGenFunction &CGF, Flags flags) override { + restore(CGF, llvm::index_sequence_for()).Emit(CGF, flags); + } + + public: + ConditionalCleanup(typename DominatingValue::saved_type... A) + : Saved(A...) {} + + ConditionalCleanup(SavedTuple Tuple) : Saved(std::move(Tuple)) {} + }; + +private: + // The implementation for this class is in CGException.h and + // CGException.cpp; the definition is here because it's used as a + // member of CodeGenFunction. + + /// The start of the scope-stack buffer, i.e. the allocated pointer + /// for the buffer. All of these pointers are either simultaneously + /// null or simultaneously valid. + char *StartOfBuffer; + + /// The end of the buffer. + char *EndOfBuffer; + + /// The first valid entry in the buffer. + char *StartOfData; + + /// The innermost normal cleanup on the stack. + stable_iterator InnermostNormalCleanup; + + /// The innermost EH scope on the stack. + stable_iterator InnermostEHScope; + + /// The current set of branch fixups. A branch fixup is a jump to + /// an as-yet unemitted label, i.e. a label for which we don't yet + /// know the EH stack depth. Whenever we pop a cleanup, we have + /// to thread all the current branch fixups through it. + /// + /// Fixups are recorded as the Use of the respective branch or + /// switch statement. The use points to the final destination. + /// When popping out of a cleanup, these uses are threaded through + /// the cleanup and adjusted to point to the new cleanup. + /// + /// Note that branches are allowed to jump into protected scopes + /// in certain situations; e.g. the following code is legal: + /// struct A { ~A(); }; // trivial ctor, non-trivial dtor + /// goto foo; + /// A a; + /// foo: + /// bar(); + SmallVector BranchFixups; + + char *allocate(size_t Size); + void deallocate(size_t Size); + + void *pushCleanup(CleanupKind K, size_t DataSize); + +public: + EHScopeStack() : StartOfBuffer(nullptr), EndOfBuffer(nullptr), + StartOfData(nullptr), InnermostNormalCleanup(stable_end()), + InnermostEHScope(stable_end()) {} + ~EHScopeStack() { delete[] StartOfBuffer; } + + /// Push a lazily-created cleanup on the stack. + template void pushCleanup(CleanupKind Kind, As... A) { + static_assert(llvm::AlignOf::Alignment <= ScopeStackAlignment, + "Cleanup's alignment is too large."); + void *Buffer = pushCleanup(Kind, sizeof(T)); + Cleanup *Obj = new (Buffer) T(A...); + (void) Obj; + } + + /// Push a lazily-created cleanup on the stack. Tuple version. + template + void pushCleanupTuple(CleanupKind Kind, std::tuple A) { + static_assert(llvm::AlignOf::Alignment <= ScopeStackAlignment, + "Cleanup's alignment is too large."); + void *Buffer = pushCleanup(Kind, sizeof(T)); + Cleanup *Obj = new (Buffer) T(std::move(A)); + (void) Obj; + } + + // Feel free to add more variants of the following: + + /// Push a cleanup with non-constant storage requirements on the + /// stack. The cleanup type must provide an additional static method: + /// static size_t getExtraSize(size_t); + /// The argument to this method will be the value N, which will also + /// be passed as the first argument to the constructor. + /// + /// The data stored in the extra storage must obey the same + /// restrictions as normal cleanup member data. + /// + /// The pointer returned from this method is valid until the cleanup + /// stack is modified. + template + T *pushCleanupWithExtra(CleanupKind Kind, size_t N, As... A) { + static_assert(llvm::AlignOf::Alignment <= ScopeStackAlignment, + "Cleanup's alignment is too large."); + void *Buffer = pushCleanup(Kind, sizeof(T) + T::getExtraSize(N)); + return new (Buffer) T(N, A...); + } + + void pushCopyOfCleanup(CleanupKind Kind, const void *Cleanup, size_t Size) { + void *Buffer = pushCleanup(Kind, Size); + std::memcpy(Buffer, Cleanup, Size); + } + + /// Pops a cleanup scope off the stack. This is private to CGCleanup.cpp. + void popCleanup(); + + /// Push a set of catch handlers on the stack. The catch is + /// uninitialized and will need to have the given number of handlers + /// set on it. + class EHCatchScope *pushCatch(unsigned NumHandlers); + + /// Pops a catch scope off the stack. This is private to CGException.cpp. + void popCatch(); + + /// Push an exceptions filter on the stack. + class EHFilterScope *pushFilter(unsigned NumFilters); + + /// Pops an exceptions filter off the stack. + void popFilter(); + + /// Push a terminate handler on the stack. + void pushTerminate(); + + /// Pops a terminate handler off the stack. + void popTerminate(); + + // Returns true iff the current scope is either empty or contains only + // lifetime markers, i.e. no real cleanup code + bool containsOnlyLifetimeMarkers(stable_iterator Old) const; + + /// Determines whether the exception-scopes stack is empty. + bool empty() const { return StartOfData == EndOfBuffer; } + + bool requiresLandingPad() const { + return InnermostEHScope != stable_end(); + } + + /// Determines whether there are any normal cleanups on the stack. + bool hasNormalCleanups() const { + return InnermostNormalCleanup != stable_end(); + } + + /// Returns the innermost normal cleanup on the stack, or + /// stable_end() if there are no normal cleanups. + stable_iterator getInnermostNormalCleanup() const { + return InnermostNormalCleanup; + } + stable_iterator getInnermostActiveNormalCleanup() const; + + stable_iterator getInnermostEHScope() const { + return InnermostEHScope; + } + + + /// An unstable reference to a scope-stack depth. Invalidated by + /// pushes but not pops. + class iterator; + + /// Returns an iterator pointing to the innermost EH scope. + iterator begin() const; + + /// Returns an iterator pointing to the outermost EH scope. + iterator end() const; + + /// Create a stable reference to the top of the EH stack. The + /// returned reference is valid until that scope is popped off the + /// stack. + stable_iterator stable_begin() const { + return stable_iterator(EndOfBuffer - StartOfData); + } + + /// Create a stable reference to the bottom of the EH stack. + static stable_iterator stable_end() { + return stable_iterator(0); + } + + /// Translates an iterator into a stable_iterator. + stable_iterator stabilize(iterator it) const; + + /// Turn a stable reference to a scope depth into a unstable pointer + /// to the EH stack. + iterator find(stable_iterator save) const; + + /// Add a branch fixup to the current cleanup scope. + BranchFixup &addBranchFixup() { + assert(hasNormalCleanups() && "adding fixup in scope without cleanups"); + BranchFixups.push_back(BranchFixup()); + return BranchFixups.back(); + } + + unsigned getNumBranchFixups() const { return BranchFixups.size(); } + BranchFixup &getBranchFixup(unsigned I) { + assert(I < getNumBranchFixups()); + return BranchFixups[I]; + } + + /// Pops lazily-removed fixups from the end of the list. This + /// should only be called by procedures which have just popped a + /// cleanup or resolved one or more fixups. + void popNullFixups(); + + /// Clears the branch-fixups list. This should only be called by + /// ResolveAllBranchFixups. + void clearFixups() { BranchFixups.clear(); } +}; + +} // namespace CodeGen +} // namespace clang + +#endif diff --git a/vendors/clang-codegen-private-3.8/SanitizerMetadata.h b/vendors/clang-codegen-private-3.8/SanitizerMetadata.h new file mode 100644 index 0000000..166f0e6 --- /dev/null +++ b/vendors/clang-codegen-private-3.8/SanitizerMetadata.h @@ -0,0 +1,53 @@ +//===--- SanitizerMetadata.h - Metadata for sanitizers ----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Class which emits metadata consumed by sanitizer instrumentation passes. +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_CLANG_LIB_CODEGEN_SANITIZERMETADATA_H +#define LLVM_CLANG_LIB_CODEGEN_SANITIZERMETADATA_H + +#include "clang/AST/Type.h" +#include "clang/Basic/LLVM.h" +#include "clang/Basic/SourceLocation.h" + +namespace llvm { +class GlobalVariable; +class Instruction; +class MDNode; +} + +namespace clang { +class VarDecl; + +namespace CodeGen { + +class CodeGenModule; + +class SanitizerMetadata { + SanitizerMetadata(const SanitizerMetadata &) = delete; + void operator=(const SanitizerMetadata &) = delete; + + CodeGenModule &CGM; +public: + SanitizerMetadata(CodeGenModule &CGM); + void reportGlobalToASan(llvm::GlobalVariable *GV, const VarDecl &D, + bool IsDynInit = false); + void reportGlobalToASan(llvm::GlobalVariable *GV, SourceLocation Loc, + StringRef Name, QualType Ty, bool IsDynInit = false, + bool IsBlacklisted = false); + void disableSanitizerForGlobal(llvm::GlobalVariable *GV); + void disableSanitizerForInstruction(llvm::Instruction *I); +private: + llvm::MDNode *getLocationMetadata(SourceLocation Loc); +}; +} // end namespace CodeGen +} // end namespace clang + +#endif diff --git a/vendors/coco/generator/Copyright.frame b/vendors/coco/generator/Copyright.frame new file mode 120000 index 0000000..708b5d5 --- /dev/null +++ b/vendors/coco/generator/Copyright.frame @@ -0,0 +1 @@ +/usr/share/coco-cpp/Copyright.frame \ No newline at end of file diff --git a/vendors/coco/generator/Parser.frame b/vendors/coco/generator/Parser.frame new file mode 100644 index 0000000..4dd62fb --- /dev/null +++ b/vendors/coco/generator/Parser.frame @@ -0,0 +1,338 @@ +/*------------------------------------------------------------------------- +Compiler Generator Coco/R, +Copyright (c) 1990, 2004 Hanspeter Moessenboeck, University of Linz +extended by M. Loeberbauer & A. Woess, Univ. of Linz +ported to C++ by Csaba Balazs, University of Szeged +with improvements by Pat Terry, Rhodes University + +This program is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) any +later version. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As an exception, it is allowed to write an extension of Coco/R that is +used as a plugin in non-free software. + +If not otherwise stated, any source code generated by Coco/R (other than +Coco/R itself) does not fall under the GNU General Public License. +-------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------- +Parser.h Specification +-----------------------------------------------------------------------*/ + +-->begin + +#if !defined(-->prefixCOCO_PARSER_H__) +#define -->prefixCOCO_PARSER_H__ + +-->headerdef + +#include "Scanner.h" + +-->namespace_open + +class Errors { +public: + int count; // number of errors detected + + Errors(); + virtual ~Errors(); + virtual void SynErr(int line, int col, int n); + virtual void Error(int line, int col, const wchar_t *s); + virtual void Warning(int line, int col, const wchar_t *s); + virtual void Warning(const wchar_t *s); + void Exception(const wchar_t *s); + +protected: + wchar_t* convertErrorCode(int n); + +}; // Errors + +class Parser { +private: +-->constantsheader + Token *dummyToken; + int errDist; + int minErrDist; + + void SynErr(int n); + void Get(); + void Expect(int n); + bool StartOf(int s); + void ExpectWeak(int n, int follow); + bool WeakSeparator(int n, int syFol, int repFol); + +public: + Scanner *scanner; + Errors *errors; + + Token *t; // last recognized token + Token *la; // lookahead token + +-->declarations + + Parser(Scanner *scanner); + ~Parser(); + void SemErr(const wchar_t* msg); + +-->productionsheader + void Parse(); + +}; // end Parser + +-->namespace_close + +#endif + +-->implementation + +/*---------------------------------------------------------------------- +Parser.cpp Specification +-----------------------------------------------------------------------*/ + +-->begin + +#include +#include "Parser.h" +#include "Scanner.h" + + +-->namespace_open + +void Parser::SynErr(int n) { + if (errDist >= minErrDist) errors->SynErr(la->line, la->col, n); + errDist = 0; +} + +void Parser::SemErr(const wchar_t* msg) { + if (errDist >= minErrDist) errors->Error(t->line, t->col, msg); + errDist = 0; +} + +void Parser::Get() { + for (;;) { + t = la; + la = scanner->Scan(); + if (la->kind <= maxT) { ++errDist; break; } +-->pragmas + if (dummyToken != t) { + dummyToken->kind = t->kind; + dummyToken->pos = t->pos; + dummyToken->col = t->col; + dummyToken->line = t->line; + dummyToken->next = NULL; + coco_string_delete(dummyToken->val); + dummyToken->val = coco_string_create(t->val); + t = dummyToken; + } + la = t; + } +} + +void Parser::Expect(int n) { + if (la->kind==n) Get(); else { SynErr(n); } +} + +void Parser::ExpectWeak(int n, int follow) { + if (la->kind == n) Get(); + else { + SynErr(n); + while (!StartOf(follow)) Get(); + } +} + +bool Parser::WeakSeparator(int n, int syFol, int repFol) { + if (la->kind == n) {Get(); return true;} + else if (StartOf(repFol)) {return false;} + else { + SynErr(n); + while (!(StartOf(syFol) || StartOf(repFol) || StartOf(0))) { + Get(); + } + return StartOf(syFol); + } +} + +-->productions + + +// If the user declared a method Init and a mehtod Destroy they should +// be called in the contructur and the destructor respctively. +// +// The following templates are used to recognize if the user declared +// the methods Init and Destroy. + +template +struct ParserInitExistsRecognizer { + template + struct ExistsIfInitIsDefinedMarker{}; + + struct InitIsMissingType { + char dummy1; + }; + + struct InitExistsType { + char dummy1; char dummy2; + }; + + // exists always + template + static InitIsMissingType is_here(...); + + // exist only if ExistsIfInitIsDefinedMarker is defined + template + static InitExistsType is_here(ExistsIfInitIsDefinedMarker*); + + enum { InitExists = (sizeof(is_here(NULL)) == sizeof(InitExistsType)) }; +}; + +template +struct ParserDestroyExistsRecognizer { + template + struct ExistsIfDestroyIsDefinedMarker{}; + + struct DestroyIsMissingType { + char dummy1; + }; + + struct DestroyExistsType { + char dummy1; char dummy2; + }; + + // exists always + template + static DestroyIsMissingType is_here(...); + + // exist only if ExistsIfDestroyIsDefinedMarker is defined + template + static DestroyExistsType is_here(ExistsIfDestroyIsDefinedMarker*); + + enum { DestroyExists = (sizeof(is_here(NULL)) == sizeof(DestroyExistsType)) }; +}; + +// The folloing templates are used to call the Init and Destroy methods if they exist. + +// Generic case of the ParserInitCaller, gets used if the Init method is missing +template::InitExists> +struct ParserInitCaller { + static void CallInit(T *t) { + // nothing to do + } +}; + +// True case of the ParserInitCaller, gets used if the Init method exists +template +struct ParserInitCaller { + static void CallInit(T *t) { + t->Init(); + } +}; + +// Generic case of the ParserDestroyCaller, gets used if the Destroy method is missing +template::DestroyExists> +struct ParserDestroyCaller { + static void CallDestroy(T *t) { + // nothing to do + } +}; + +// True case of the ParserDestroyCaller, gets used if the Destroy method exists +template +struct ParserDestroyCaller { + static void CallDestroy(T *t) { + t->Destroy(); + } +}; + +void Parser::Parse() { + t = NULL; + la = dummyToken = new Token(); + la->val = coco_string_create(L"Dummy Token"); + Get(); +-->parseRoot +} + +Parser::Parser(Scanner *scanner) { +-->constants + ParserInitCaller::CallInit(this); + dummyToken = NULL; + t = la = NULL; + minErrDist = 2; + errDist = minErrDist; + this->scanner = scanner; + errors = new Errors(); +} + +bool Parser::StartOf(int s) { + const bool T = true; + const bool x = false; + +-->initialization + + return set[s][la->kind]; +} + +Parser::~Parser() { + ParserDestroyCaller::CallDestroy(this); + delete errors; + delete dummyToken; +} + +Errors::Errors() { + count = 0; +} + +Errors::~Errors() {} + +void Errors::SynErr(int line, int col, int n) { + wchar_t* s = convertErrorCode(n); + wprintf(L"-- line %d col %d: %ls\n", line, col, s); + coco_string_delete(s); + count++; +} + +void Errors::Error(int line, int col, const wchar_t *s) { + wprintf(L"-- line %d col %d: %ls\n", line, col, s); + count++; +} + +void Errors::Warning(int line, int col, const wchar_t *s) { + wprintf(L"-- line %d col %d: %ls\n", line, col, s); +} + +void Errors::Warning(const wchar_t *s) { + wprintf(L"%ls\n", s); +} + +void Errors::Exception(const wchar_t* s) { + wprintf(L"%ls", s); + exit(1); +} + +wchar_t* Errors::convertErrorCode(int n){ + wchar_t* s; + switch (n) { +-->errors + default: + { + wchar_t format[20]; + coco_swprintf(format, 20, L"error %d", n); + s = coco_string_create(format); + } + break; + } + + return s; +} + +-->namespace_close diff --git a/vendors/coco/generator/Scanner.frame b/vendors/coco/generator/Scanner.frame new file mode 120000 index 0000000..d1ee132 --- /dev/null +++ b/vendors/coco/generator/Scanner.frame @@ -0,0 +1 @@ +/usr/share/coco-cpp/Scanner.frame \ No newline at end of file diff --git a/vendors/jeayeson b/vendors/jeayeson new file mode 160000 index 0000000..20389e5 --- /dev/null +++ b/vendors/jeayeson @@ -0,0 +1 @@ +Subproject commit 20389e5ac679f08f0a268ef0886920b1ae3d2d9f