diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.h')
-rw-r--r-- | contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.h | 818 |
1 files changed, 420 insertions, 398 deletions
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.h b/contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.h index c161224..9533a8d 100644 --- a/contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.h +++ b/contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.h @@ -16,6 +16,7 @@ #include "CGVTables.h" #include "CodeGenTypes.h" +#include "SanitizerBlacklist.h" #include "clang/AST/Attr.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" @@ -30,129 +31,124 @@ #include "llvm/ADT/StringMap.h" #include "llvm/IR/CallingConv.h" #include "llvm/IR/Module.h" -#include "llvm/Support/ValueHandle.h" -#include "llvm/Transforms/Utils/SpecialCaseList.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 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 DiagnosticsEngine; - class AnnotateAttr; - class CXXDestructorDecl; - class MangleBuffer; - class Module; +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 DiagnosticsEngine; +class AnnotateAttr; +class CXXDestructorDecl; +class Module; namespace CodeGen { - class CallArgList; - class CodeGenFunction; - class CodeGenTBAA; - class CGCXXABI; - class CGDebugInfo; - class CGObjCRuntime; - class CGOpenCLRuntime; - class CGCUDARuntime; - class BlockFieldFlags; - class FunctionArgList; - - struct OrderGlobalInits { - unsigned int priority; - unsigned int lex_order; - OrderGlobalInits(unsigned int p, unsigned int l) +class CallArgList; +class CodeGenFunction; +class CodeGenTBAA; +class CGCXXABI; +class CGDebugInfo; +class CGObjCRuntime; +class CGOpenCLRuntime; +class CGOpenMPRuntime; +class CGCUDARuntime; +class BlockFieldFlags; +class FunctionArgList; + +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 { - if (priority < RHS.priority) - return true; - - return priority == RHS.priority && lex_order < RHS.lex_order; - } + + 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 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; }; - 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 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) - }; - - llvm::CallingConv::ID RuntimeCC; - llvm::CallingConv::ID getRuntimeCC() const { - return RuntimeCC; - } + /// 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 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) + }; + + llvm::CallingConv::ID RuntimeCC; + llvm::CallingConv::ID getRuntimeCC() const { return RuntimeCC; } +}; + struct RREntrypoints { RREntrypoints() { memset(this, 0, sizeof(*this)); } /// void objc_autoreleasePoolPop(void*); @@ -221,13 +217,57 @@ struct ARCEntrypoints { llvm::Constant *clang_arc_use; }; -/// CodeGenModule - This class organizes the cross-function state that is used -/// while generating LLVM code. +/// 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); +}; + +/// This class organizes the cross-function state that is used while generating +/// LLVM code. class CodeGenModule : public CodeGenTypeCache { CodeGenModule(const CodeGenModule &) LLVM_DELETED_FUNCTION; void operator=(const CodeGenModule &) LLVM_DELETED_FUNCTION; - typedef std::vector<std::pair<llvm::Constant*, int> > CtorList; + 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<Structor> CtorList; ASTContext &Context; const LangOptions &LangOpts; @@ -236,7 +276,7 @@ class CodeGenModule : public CodeGenTypeCache { DiagnosticsEngine &Diags; const llvm::DataLayout &TheDataLayout; const TargetInfo &Target; - CGCXXABI &ABI; + std::unique_ptr<CGCXXABI> ABI; llvm::LLVMContext &VMContext; CodeGenTBAA *TBAA; @@ -248,32 +288,42 @@ class CodeGenModule : public CodeGenTypeCache { // if TheTargetCodeGenInfo is NULL CodeGenTypes Types; - /// VTables - Holds information about C++ vtables. + /// Holds information about C++ vtables. CodeGenVTables VTables; CGObjCRuntime* ObjCRuntime; CGOpenCLRuntime* OpenCLRuntime; + CGOpenMPRuntime* OpenMPRuntime; CGCUDARuntime* CUDARuntime; CGDebugInfo* DebugInfo; ARCEntrypoints *ARCData; llvm::MDNode *NoObjCARCExceptionsMetadata; RREntrypoints *RRData; + std::unique_ptr<llvm::IndexedInstrProfReader> PGOReader; + InstrProfStats PGOStats; - // WeakRefReferences - 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. + // 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<llvm::GlobalValue*, 10> WeakRefReferences; - /// DeferredDecls - 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. - llvm::StringMap<GlobalDecl> DeferredDecls; - - /// DeferredDeclsToEmit - This is a list of deferred decls which we have seen - /// that *are* actually referenced. These get code generated when the module - /// is done. - std::vector<GlobalDecl> DeferredDeclsToEmit; + /// 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<StringRef, GlobalDecl> 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::AssertingVH<llvm::GlobalValue> GV; + GlobalDecl GD; + }; + std::vector<DeferredGlobal> DeferredDeclsToEmit; + void addDeferredDeclToEmit(llvm::GlobalValue *GV, GlobalDecl GD) { + DeferredDeclsToEmit.push_back(DeferredGlobal(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. @@ -282,27 +332,27 @@ class CodeGenModule : public CodeGenTypeCache { typedef llvm::StringMap<llvm::TrackingVH<llvm::Constant> > ReplacementsTy; ReplacementsTy Replacements; - /// DeferredVTables - A queue of (optional) vtables to consider emitting. + /// A queue of (optional) vtables to consider emitting. std::vector<const CXXRecordDecl*> DeferredVTables; - /// LLVMUsed - 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. + /// 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<llvm::WeakVH> LLVMUsed; + std::vector<llvm::WeakVH> LLVMCompilerUsed; - /// GlobalCtors - Store the list of global constructors and their respective - /// priorities to be emitted when the translation unit is complete. + /// Store the list of global constructors and their respective priorities to + /// be emitted when the translation unit is complete. CtorList GlobalCtors; - /// GlobalDtors - Store the list of global destructors and their respective - /// priorities to be emitted when the translation unit is complete. + /// Store the list of global destructors and their respective priorities to be + /// emitted when the translation unit is complete. CtorList GlobalDtors; - /// MangledDeclNames - A map of canonical GlobalDecls to their mangled names. - llvm::DenseMap<GlobalDecl, StringRef> MangledDeclNames; - llvm::BumpPtrAllocator MangledNamesAllocator; - + /// An ordered map of canonical GlobalDecls to their mangled names. + llvm::MapVector<GlobalDecl, StringRef> MangledDeclNames; + llvm::StringMap<GlobalDecl, llvm::BumpPtrAllocator> Manglings; + /// Global annotations. std::vector<llvm::Constant*> Annotations; @@ -310,7 +360,8 @@ class CodeGenModule : public CodeGenTypeCache { llvm::StringMap<llvm::Constant*> AnnotationStrings; llvm::StringMap<llvm::Constant*> CFConstantStringMap; - llvm::StringMap<llvm::GlobalVariable*> ConstantStringMap; + + llvm::DenseMap<llvm::Constant *, llvm::GlobalVariable *> ConstantStringMap; llvm::DenseMap<const Decl*, llvm::Constant *> StaticLocalDeclMap; llvm::DenseMap<const Decl*, llvm::GlobalVariable*> StaticLocalDeclGuardMap; llvm::DenseMap<const Expr*, llvm::Constant *> MaterializedGlobalTemporaryMap; @@ -335,8 +386,7 @@ class CodeGenModule : public CodeGenTypeCache { /// before any thread_local variable in this TU is odr-used. std::vector<llvm::Constant*> CXXThreadLocalInits; - /// CXXGlobalInits - Global variables with initializers that need to run - /// before main. + /// Global variables with initializers that need to run before main. std::vector<llvm::Constant*> CXXGlobalInits; /// When a C++ decl with an initializer is deferred, null is @@ -354,12 +404,11 @@ class CodeGenModule : public CodeGenTypeCache { } }; - /// - Global variables with initializers whose order of initialization - /// is set by init_priority attribute. + /// Global variables with initializers whose order of initialization is set by + /// init_priority attribute. SmallVector<GlobalInitData, 8> PrioritizedCXXGlobalInits; - /// CXXGlobalDtors - Global destructor functions and arguments that need to - /// run on termination. + /// Global destructor functions and arguments that need to run on termination. std::vector<std::pair<llvm::WeakVH,llvm::Constant*> > CXXGlobalDtors; /// \brief The complete set of modules that has been imported. @@ -371,12 +420,12 @@ class CodeGenModule : public CodeGenTypeCache { /// @name Cache for Objective-C runtime types /// @{ - /// CFConstantStringClassRef - Cached reference to the class for constant - /// strings. This value has type int * but is actually an Obj-C class pointer. + /// Cached reference to the class for constant strings. This value has type + /// int * but is actually an Obj-C class pointer. llvm::WeakVH CFConstantStringClassRef; - /// ConstantStringClassRef - Cached reference to the class for constant - /// strings. This value has type int * but is actually an Obj-C class pointer. + /// 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. @@ -392,6 +441,7 @@ class CodeGenModule : public CodeGenTypeCache { void createObjCRuntime(); void createOpenCLRuntime(); + void createOpenMPRuntime(); void createCUDARuntime(); bool isTriviallyRecursive(const FunctionDecl *F); @@ -421,9 +471,7 @@ class CodeGenModule : public CodeGenTypeCache { GlobalDecl initializedGlobalDecl; - llvm::OwningPtr<llvm::SpecialCaseList> SanitizerBlacklist; - - const SanitizerOptions &SanOpts; + SanitizerBlacklist SanitizerBL; /// @} public: @@ -433,42 +481,51 @@ public: ~CodeGenModule(); - /// Release - Finalize LLVM code generation. + void clear(); + + /// Finalize LLVM code generation. void Release(); - /// getObjCRuntime() - Return a reference to the configured - /// Objective-C runtime. + /// Return a reference to the configured Objective-C runtime. CGObjCRuntime &getObjCRuntime() { if (!ObjCRuntime) createObjCRuntime(); return *ObjCRuntime; } - /// hasObjCRuntime() - Return true iff an Objective-C runtime has - /// been configured. + /// Return true iff an Objective-C runtime has been configured. bool hasObjCRuntime() { return !!ObjCRuntime; } - /// getOpenCLRuntime() - Return a reference to the configured OpenCL runtime. + /// Return a reference to the configured OpenCL runtime. CGOpenCLRuntime &getOpenCLRuntime() { - assert(OpenCLRuntime != 0); + assert(OpenCLRuntime != nullptr); return *OpenCLRuntime; } - /// getCUDARuntime() - Return a reference to the configured CUDA runtime. + /// 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 != 0); + assert(CUDARuntime != nullptr); return *CUDARuntime; } ARCEntrypoints &getARCEntrypoints() const { - assert(getLangOpts().ObjCAutoRefCount && ARCData != 0); + assert(getLangOpts().ObjCAutoRefCount && ARCData != nullptr); return *ARCData; } RREntrypoints &getRREntrypoints() const { - assert(RRData != 0); + assert(RRData != nullptr); return *RRData; } + InstrProfStats &getPGOStats() { return PGOStats; } + llvm::IndexedInstrProfReader *getPGOReader() const { return PGOReader.get(); } + llvm::Constant *getStaticLocalDeclAddress(const VarDecl *D) { return StaticLocalDeclMap[D]; } @@ -485,6 +542,9 @@ public: StaticLocalDeclGuardMap[D] = C; } + bool lookupRepresentativeDecl(StringRef MangledName, + GlobalDecl &Result) const; + llvm::Constant *getAtomicSetterHelperFnMap(QualType Ty) { return AtomicSetterHelperFnMap[Ty]; } @@ -501,10 +561,10 @@ public: AtomicGetterHelperFnMap[Ty] = Fn; } - llvm::Constant *getTypeDescriptor(QualType Ty) { + llvm::Constant *getTypeDescriptorFromMap(QualType Ty) { return TypeDescriptorMap[Ty]; } - void setTypeDescriptor(QualType Ty, llvm::Constant *C) { + void setTypeDescriptorInMap(QualType Ty, llvm::Constant *C) { TypeDescriptorMap[Ty] = C; } @@ -525,10 +585,10 @@ public: DiagnosticsEngine &getDiags() const { return Diags; } const llvm::DataLayout &getDataLayout() const { return TheDataLayout; } const TargetInfo &getTarget() const { return Target; } - CGCXXABI &getCXXABI() { return ABI; } + CGCXXABI &getCXXABI() const { return *ABI; } llvm::LLVMContext &getLLVMContext() { return VMContext; } - - bool shouldUseTBAA() const { return TBAA != 0; } + + bool shouldUseTBAA() const { return TBAA != nullptr; } const TargetCodeGenInfo &getTargetCodeGenInfo(); @@ -566,32 +626,16 @@ public: llvm::MDNode *TBAAInfo, bool ConvertTypeToTag = true); - /// getSize - Emit the given number of characters as a value of type size_t. + /// Emit the given number of characters as a value of type size_t. llvm::ConstantInt *getSize(CharUnits numChars); - /// setGlobalVisibility - Set the visibility for the given LLVM - /// GlobalValue. + /// Set the visibility for the given LLVM GlobalValue. void setGlobalVisibility(llvm::GlobalValue *GV, const NamedDecl *D) const; - /// setTLSMode - Set the TLS mode for the given LLVM GlobalVariable - /// for the thread-local variable declaration D. + /// Set the TLS mode for the given LLVM GlobalVariable for the thread-local + /// variable declaration D. void setTLSMode(llvm::GlobalVariable *GV, const VarDecl &D) const; - /// TypeVisibilityKind - The kind of global variable that is passed to - /// setTypeVisibility - enum TypeVisibilityKind { - TVK_ForVTT, - TVK_ForVTable, - TVK_ForConstructionVTable, - TVK_ForRTTI, - TVK_ForRTTIName - }; - - /// setTypeVisibility - Set the visibility for the given global - /// value which holds information about a type. - void setTypeVisibility(llvm::GlobalValue *GV, const CXXRecordDecl *D, - TypeVisibilityKind TVK) const; - static llvm::GlobalValue::VisibilityTypes GetLLVMVisibility(Visibility V) { switch (V) { case DefaultVisibility: return llvm::GlobalValue::DefaultVisibility; @@ -614,50 +658,47 @@ public: return GetAddrOfGlobalVar(cast<VarDecl>(GD.getDecl())); } - /// CreateOrReplaceCXXRuntimeVariable - 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. + /// 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); - /// GetGlobalVarAddressSpace - 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. + /// 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); - /// GetAddrOfGlobalVar - 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. + /// 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 = 0); - + llvm::Type *Ty = nullptr); - /// GetAddrOfFunction - 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 = 0, - bool ForVTable = false); + /// 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 = 0, + bool ForVTable = false, + bool DontDefer = false); - /// GetAddrOfRTTIDescriptor - Get the address of the RTTI descriptor - /// for the given type. + /// Get the address of the RTTI descriptor for the given type. llvm::Constant *GetAddrOfRTTIDescriptor(QualType Ty, bool ForEH = false); - /// GetAddrOfUuidDescriptor - Get the address of a uuid descriptor . + /// Get the address of a uuid descriptor . llvm::Constant *GetAddrOfUuidDescriptor(const CXXUuidofExpr* E); - /// GetAddrOfThunk - Get the address of the thunk for the given global decl. + /// Get the address of the thunk for the given global decl. llvm::Constant *GetAddrOfThunk(GlobalDecl GD, const ThunkInfo &Thunk); - /// GetWeakRefReference - Get a reference to the target of VD. + /// Get a reference to the target of VD. llvm::Constant *GetWeakRefReference(const ValueDecl *VD); - /// GetNonVirtualBaseClassOffset - Returns the offset from a derived class to - /// a class. Returns null if the offset is 0. + /// 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, @@ -693,67 +734,49 @@ public: llvm::FoldingSet<ByrefHelpers> ByrefHelpersCache; - /// getUniqueBlockCount - Fetches the global unique block count. + /// Fetches the global unique block count. int getUniqueBlockCount() { return ++Block.GlobalUniqueCount; } - /// getBlockDescriptorType - Fetches the type of a generic block - /// descriptor. + /// Fetches the type of a generic block descriptor. llvm::Type *getBlockDescriptorType(); - /// getGenericBlockLiteralType - The type of a generic block literal. + /// The type of a generic block literal. llvm::Type *getGenericBlockLiteralType(); - /// GetAddrOfGlobalBlock - Gets the address of a block which - /// requires no captures. + /// Gets the address of a block which requires no captures. llvm::Constant *GetAddrOfGlobalBlock(const BlockExpr *BE, const char *); - /// GetAddrOfConstantCFString - Return a pointer to a constant CFString object - /// for the given string. + /// Return a pointer to a constant CFString object for the given string. llvm::Constant *GetAddrOfConstantCFString(const StringLiteral *Literal); - - /// GetAddrOfConstantString - Return a pointer to a constant NSString object - /// for the given string. Or a user defined String object as defined via + + /// 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. llvm::Constant *GetAddrOfConstantString(const StringLiteral *Literal); - /// GetConstantArrayFromStringLiteral - Return a constant array for the given - /// string. + /// Return a constant array for the given string. llvm::Constant *GetConstantArrayFromStringLiteral(const StringLiteral *E); - /// GetAddrOfConstantStringFromLiteral - Return a pointer to a constant array - /// for the given string literal. - llvm::Constant *GetAddrOfConstantStringFromLiteral(const StringLiteral *S); + /// Return a pointer to a constant array for the given string literal. + llvm::GlobalVariable * + GetAddrOfConstantStringFromLiteral(const StringLiteral *S); - /// GetAddrOfConstantStringFromObjCEncode - Return a pointer to a constant - /// array for the given ObjCEncodeExpr node. - llvm::Constant *GetAddrOfConstantStringFromObjCEncode(const ObjCEncodeExpr *); + /// Return a pointer to a constant array for the given ObjCEncodeExpr node. + llvm::GlobalVariable * + GetAddrOfConstantStringFromObjCEncode(const ObjCEncodeExpr *); - /// GetAddrOfConstantString - Returns a pointer to a character array - /// containing the literal. This contents are exactly that of the given - /// string, i.e. it will not be null terminated automatically; see - /// GetAddrOfConstantCString. Note that whether the result is actually a - /// pointer to an LLVM constant depends on Feature.WriteableStrings. - /// - /// The result has pointer to array type. - /// - /// \param GlobalName If provided, the name to use for the global - /// (if one is created). - llvm::Constant *GetAddrOfConstantString(StringRef Str, - const char *GlobalName=0, - unsigned Alignment=0); - - /// GetAddrOfConstantCString - Returns a pointer to a character array - /// containing the literal and a terminating '\0' character. The result has - /// pointer to array type. + /// 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). - llvm::Constant *GetAddrOfConstantCString(const std::string &str, - const char *GlobalName=0, - unsigned Alignment=0); + llvm::GlobalVariable * + GetAddrOfConstantCString(const std::string &Str, + const char *GlobalName = nullptr, + unsigned Alignment = 0); - /// GetAddrOfConstantCompoundLiteral - Returns a pointer to a constant global - /// variable for the given file-scope compound literal expression. + /// Returns a pointer to a constant global variable for the given file-scope + /// compound literal expression. llvm::Constant *GetAddrOfConstantCompoundLiteral(const CompoundLiteralExpr*E); /// \brief Returns a pointer to a global variable representing a temporary @@ -765,31 +788,31 @@ public: /// Objective-C fast enumeration loop (for..in). QualType getObjCFastEnumerationStateType(); - /// GetAddrOfCXXConstructor - Return the address of the constructor of the - /// given type. - llvm::GlobalValue *GetAddrOfCXXConstructor(const CXXConstructorDecl *ctor, - CXXCtorType ctorType, - const CGFunctionInfo *fnInfo = 0); - - /// GetAddrOfCXXDestructor - Return the address of the constructor of the - /// given type. - llvm::GlobalValue *GetAddrOfCXXDestructor(const CXXDestructorDecl *dtor, - CXXDtorType dtorType, - const CGFunctionInfo *fnInfo = 0, - llvm::FunctionType *fnType = 0); - - /// getBuiltinLibFunction - Given a builtin id for a function like - /// "__builtin_fabsf", return a Function* for "fabsf". + /// Return the address of the constructor of the given type. + llvm::GlobalValue * + GetAddrOfCXXConstructor(const CXXConstructorDecl *ctor, CXXCtorType ctorType, + const CGFunctionInfo *fnInfo = nullptr, + bool DontDefer = false); + + /// Return the address of the constructor of the given type. + llvm::GlobalValue * + GetAddrOfCXXDestructor(const CXXDestructorDecl *dtor, + CXXDtorType dtorType, + const CGFunctionInfo *fnInfo = nullptr, + llvm::FunctionType *fnType = nullptr, + bool DontDefer = 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<llvm::Type*> Tys = None); - /// EmitTopLevelDecl - Emit code for a single top level declaration. + /// Emit code for a single top level declaration. void EmitTopLevelDecl(Decl *D); - /// HandleCXXStaticMemberVarInstantiation - Tell the consumer that this - // variable has been instantiated. + /// Tell the consumer that this variable has been instantiated. void HandleCXXStaticMemberVarInstantiation(VarDecl *VD); /// \brief If the declaration has internal linkage but is inside an @@ -798,25 +821,23 @@ public: template<typename SomeDecl> void MaybeHandleStaticInExternC(const SomeDecl *D, llvm::GlobalValue *GV); - /// AddUsedGlobal - Add a global which should be forced to be - /// present in the object file; these are emitted to the llvm.used - /// metadata global. - void AddUsedGlobal(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); - /// AddCXXDtorEntry - Add a destructor and object to add to the C++ global - /// destructor function. + /// Add a destructor and object to add to the C++ global destructor function. void AddCXXDtorEntry(llvm::Constant *DtorFn, llvm::Constant *Object) { CXXGlobalDtors.push_back(std::make_pair(DtorFn, Object)); } - /// CreateRuntimeFunction - Create a new runtime function with the specified - /// type and name. + /// Create a new runtime function with the specified type and name. llvm::Constant *CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeSet ExtraAttrs = llvm::AttributeSet()); - /// CreateRuntimeVariable - Create a new runtime global variable with the - /// specified type and name. + /// Create a new runtime global variable with the specified type and name. llvm::Constant *CreateRuntimeVariable(llvm::Type *Ty, StringRef Name); @@ -833,85 +854,80 @@ public: llvm::Constant *getLLVMLifetimeStartFn(); llvm::Constant *getLLVMLifetimeEndFn(); - // UpdateCompleteType - Make sure that this type is translated. + // Make sure that this type is translated. void UpdateCompletedType(const TagDecl *TD); llvm::Constant *getMemberPointerConstant(const UnaryOperator *e); - /// EmitConstantInit - 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 = 0); + /// 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); - /// EmitConstantExpr - Try to emit the given expression as a - /// constant; returns 0 if the expression cannot be emitted as a - /// constant. + /// 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 = 0); + CodeGenFunction *CGF = nullptr); - /// EmitConstantValue - Emit the given constant value as a constant, in the - /// type's scalar representation. + /// Emit the given constant value as a constant, in the type's scalar + /// representation. llvm::Constant *EmitConstantValue(const APValue &Value, QualType DestType, - CodeGenFunction *CGF = 0); + CodeGenFunction *CGF = nullptr); - /// EmitConstantValueForMemory - Emit the given constant value as a constant, - /// in the type's memory representation. + /// Emit the given constant value as a constant, in the type's memory + /// representation. llvm::Constant *EmitConstantValueForMemory(const APValue &Value, QualType DestType, - CodeGenFunction *CGF = 0); + CodeGenFunction *CGF = nullptr); - /// EmitNullConstant - 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. + /// 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); - /// EmitNullConstantForBase - 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. + /// 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); - /// Error - Emit a general error that something can't be done. + /// Emit a general error that something can't be done. void Error(SourceLocation loc, StringRef error); - /// ErrorUnsupported - Print out an error that codegen doesn't support the - /// specified stmt yet. + /// Print out an error that codegen doesn't support the specified stmt yet. void ErrorUnsupported(const Stmt *S, const char *Type); - /// ErrorUnsupported - Print out an error that codegen doesn't support the - /// specified decl yet. + /// Print out an error that codegen doesn't support the specified decl yet. void ErrorUnsupported(const Decl *D, const char *Type); - /// SetInternalFunctionAttributes - 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. + /// 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); - /// SetLLVMFunctionAttributes - Set the LLVM function attributes - /// (sext, zext, etc). + /// Set the LLVM function attributes (sext, zext, etc). void SetLLVMFunctionAttributes(const Decl *D, const CGFunctionInfo &Info, llvm::Function *F); - /// SetLLVMFunctionAttributesForDefinition - Set the LLVM function attributes - /// which only apply to a function definintion. + /// Set the LLVM function attributes which only apply to a function + /// definintion. void SetLLVMFunctionAttributesForDefinition(const Decl *D, llvm::Function *F); - /// ReturnTypeUsesSRet - Return true iff the given type uses 'sret' when used - /// as a return type. + /// Return true iff the given type uses 'sret' when used as a return type. bool ReturnTypeUsesSRet(const CGFunctionInfo &FI); - /// ReturnTypeUsesFPRet - Return true iff the given type uses 'fpret' when - /// used as a return type. + /// 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); - /// ReturnTypeUsesFP2Ret - Return true iff the given type uses 'fp2ret' when - /// used as a return type. + /// Return true iff the given type uses 'fp2ret' when used as a return type. bool ReturnTypeUsesFP2Ret(QualType ResultType); - /// ConstructAttributeList - Get the LLVM attributes and calling convention to - /// use for a particular function type. + /// Get the LLVM attributes and calling convention to use for a particular + /// function type. /// /// \param Info - The function type information. /// \param TargetDecl - The decl these attributes are being constructed @@ -926,15 +942,13 @@ public: bool AttrOnCallSite); StringRef getMangledName(GlobalDecl GD); - void getBlockMangledName(GlobalDecl GD, MangleBuffer &Buffer, - const BlockDecl *BD); + StringRef getBlockMangledName(GlobalDecl GD, const BlockDecl *BD); void EmitTentativeDefinition(const VarDecl *D); void EmitVTable(CXXRecordDecl *Class, bool DefinitionRequired); - /// EmitFundamentalRTTIDescriptors - Emit the RTTI descriptors for the - /// builtin types. + /// Emit the RTTI descriptors for the builtin types. void EmitFundamentalRTTIDescriptors(); /// \brief Appends Opts to the "Linker Options" metadata value. @@ -948,23 +962,26 @@ public: llvm::GlobalVariable::LinkageTypes getFunctionLinkage(GlobalDecl GD); - void setFunctionLinkage(GlobalDecl GD, llvm::GlobalValue *V) { - V->setLinkage(getFunctionLinkage(GD)); + void setFunctionLinkage(GlobalDecl GD, llvm::Function *F) { + F->setLinkage(getFunctionLinkage(GD)); } - /// getVTableLinkage - Return the appropriate linkage for the vtable, VTT, - /// and type information of the given class. + /// Return the appropriate linkage for the vtable, VTT, and type information + /// of the given class. llvm::GlobalVariable::LinkageTypes getVTableLinkage(const CXXRecordDecl *RD); - /// GetTargetTypeStoreSize - Return the store size, in character units, of - /// the given LLVM type. + /// Return the store size, in character units, of the given LLVM type. CharUnits GetTargetTypeStoreSize(llvm::Type *Ty) const; - /// GetLLVMLinkageVarDefinition - Returns LLVM linkage for a global - /// variable. - llvm::GlobalValue::LinkageTypes - GetLLVMLinkageVarDefinition(const VarDecl *D, bool isConstant); - + /// 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(); @@ -977,8 +994,8 @@ public: /// Emit the annotation line number. llvm::Constant *EmitAnnotationLineNo(SourceLocation L); - /// EmitAnnotateAttr - Generate the llvm::ConstantStruct which contains the - /// annotation information for a given GlobalValue. The annotation struct is + /// 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 @@ -992,54 +1009,59 @@ public: /// annotations are emitted during finalization of the LLVM code. void AddGlobalAnnotations(const ValueDecl *D, llvm::GlobalValue *GV); - const llvm::SpecialCaseList &getSanitizerBlacklist() const { - return *SanitizerBlacklist; + const SanitizerBlacklist &getSanitizerBlacklist() const { + return SanitizerBL; } - const SanitizerOptions &getSanOpts() const { return SanOpts; } + void reportGlobalToASan(llvm::GlobalVariable *GV, const VarDecl &D, + bool IsDynInit = false); + void reportGlobalToASan(llvm::GlobalVariable *GV, SourceLocation Loc, + StringRef Name, bool IsDynInit = false, + bool IsBlacklisted = false); + + /// Disable sanitizer instrumentation for this global. + void disableSanitizerForGlobal(llvm::GlobalVariable *GV); void addDeferredVTable(const CXXRecordDecl *RD) { DeferredVTables.push_back(RD); } - /// EmitGlobal - Emit code for a singal global function or var decl. Forward - /// declarations are emitted lazily. + /// Emit code for a singal global function or var decl. Forward declarations + /// are emitted lazily. void EmitGlobal(GlobalDecl D); private: llvm::GlobalValue *GetGlobalValue(StringRef Ref); - llvm::Constant *GetOrCreateLLVMFunction(StringRef MangledName, - llvm::Type *Ty, - GlobalDecl D, - bool ForVTable, - llvm::AttributeSet ExtraAttrs = - llvm::AttributeSet()); + llvm::Constant * + GetOrCreateLLVMFunction(StringRef MangledName, llvm::Type *Ty, GlobalDecl D, + bool ForVTable, bool DontDefer = false, + llvm::AttributeSet ExtraAttrs = llvm::AttributeSet()); + llvm::Constant *GetOrCreateLLVMGlobal(StringRef MangledName, llvm::PointerType *PTy, - const VarDecl *D, - bool UnnamedAddr = false); + const VarDecl *D); - /// SetCommonAttributes - Set attributes which are common to any - /// form of a global definition (alias, Objective-C method, - /// function, global variable). + /// 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); - /// SetFunctionDefinitionAttributes - Set attributes for a global definition. - void SetFunctionDefinitionAttributes(const FunctionDecl *D, - llvm::GlobalValue *GV); + void setNonAliasAttributes(const Decl *D, llvm::GlobalObject *GO); + + /// Set attributes for a global definition. + void setFunctionDefinitionAttributes(const FunctionDecl *D, + llvm::Function *F); - /// SetFunctionAttributes - Set function attributes for a function - /// declaration. + /// Set function attributes for a function declaration. void SetFunctionAttributes(GlobalDecl GD, llvm::Function *F, bool IsIncompleteFunction); - void EmitGlobalDefinition(GlobalDecl D); + void EmitGlobalDefinition(GlobalDecl D, llvm::GlobalValue *GV = nullptr); - void EmitGlobalFunctionDefinition(GlobalDecl GD); + void EmitGlobalFunctionDefinition(GlobalDecl GD, llvm::GlobalValue *GV); void EmitGlobalVarDefinition(const VarDecl *D); void EmitAliasDefinition(GlobalDecl GD); void EmitObjCPropertyImplementations(const ObjCImplementationDecl *D); @@ -1055,44 +1077,44 @@ private: void EmitLinkageSpec(const LinkageSpecDecl *D); void CompleteDIClassType(const CXXMethodDecl* D); - /// EmitCXXConstructor - Emit a single constructor with the given type from - /// a C++ constructor Decl. + /// Emit a single constructor with the given type from a C++ constructor Decl. void EmitCXXConstructor(const CXXConstructorDecl *D, CXXCtorType Type); - /// EmitCXXDestructor - Emit a single destructor with the given type from - /// a C++ destructor Decl. + /// Emit a single destructor with the given type from a C++ destructor Decl. void EmitCXXDestructor(const CXXDestructorDecl *D, CXXDtorType Type); /// \brief Emit the function that initializes C++ thread_local variables. void EmitCXXThreadLocalInitFunc(); - /// EmitCXXGlobalInitFunc - Emit the function that initializes C++ globals. + /// Emit the function that initializes C++ globals. void EmitCXXGlobalInitFunc(); - /// EmitCXXGlobalDtorFunc - Emit the function that destroys C++ globals. + /// Emit the function that destroys C++ globals. void EmitCXXGlobalDtorFunc(); - /// EmitCXXGlobalVarDeclInitFunc - Emit the function that initializes the - /// specified global (if PerformInit is true) and registers its destructor. + /// 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); - void AddGlobalDtor(llvm::Function *Dtor, int Priority=65535); + void AddGlobalCtor(llvm::Function *Ctor, int Priority = 65535, + llvm::Constant *AssociatedData = 0); + void AddGlobalDtor(llvm::Function *Dtor, int Priority = 65535); - /// EmitCtorList - 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. + /// 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); - /// EmitFundamentalRTTIDescriptor - Emit the RTTI descriptors for the - /// given type. + /// Emit the RTTI descriptors for the given type. void EmitFundamentalRTTIDescriptor(QualType Type); - /// EmitDeferred - Emit any needed decls for which code generation - /// was deferred. + /// Emit any needed decls for which code generation was deferred. void EmitDeferred(); /// Call replaceAllUsesWith on all pairs in Replacements. @@ -1100,13 +1122,11 @@ private: void checkAliases(); - /// EmitDeferredVTables - Emit any vtables which we deferred and - /// still have a use for. + /// Emit any vtables which we deferred and still have a use for. void EmitDeferredVTables(); - /// EmitLLVMUsed - Emit the llvm.used metadata used to force - /// references to global which may otherwise be optimized out. - void EmitLLVMUsed(); + /// Emit the llvm.used and llvm.compiler.used metadata. + void emitLLVMUsed(); /// \brief Emit the link options introduced by imported modules. void EmitModuleLinkOptions(); @@ -1120,20 +1140,22 @@ private: /// \brief Emit the Clang version as llvm.ident metadata. void EmitVersionIdentMetadata(); - /// EmitCoverageFile - 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. + /// 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, QualType IIDType); - /// MayDeferGeneration - Determine if the given decl can be emitted - /// lazily; this is only relevant for definitions. The given decl - /// must be either a function or var decl. + /// Determine if the given decl can be emitted lazily; this is only relevant + /// for definitions. The given decl must be either a function or var decl. bool MayDeferGeneration(const ValueDecl *D); - /// SimplifyPersonality - Check whether we can use a "simpler", more - /// core exceptions personality function. + /// Check whether we can use a "simpler", more core exceptions personality + /// function. void SimplifyPersonality(); }; } // end namespace CodeGen |