Add Available Externally linkage type to isWeakForLinker()
[oota-llvm.git] / include / llvm / IR / GlobalValue.h
index 4f20a31a294b577da063e78f7e0745d12424016f..3461b9ee8b82d1851ddef99bf45280722a6c5d07 100644 (file)
 
 #include "llvm/IR/Constant.h"
 #include "llvm/IR/DerivedTypes.h"
+#include <system_error>
 
 namespace llvm {
 
+class Comdat;
 class PointerType;
 class Module;
 
+namespace Intrinsic {
+  enum ID : unsigned;
+}
+
 class GlobalValue : public Constant {
-  GlobalValue(const GlobalValue &) LLVM_DELETED_FUNCTION;
+  GlobalValue(const GlobalValue &) = delete;
 public:
   /// @brief An enumeration for the kinds of linkage for global values.
   enum LinkageTypes {
@@ -40,10 +46,6 @@ public:
     AppendingLinkage,   ///< Special purpose, only applies to global arrays
     InternalLinkage,    ///< Rename collisions when linking (static functions).
     PrivateLinkage,     ///< Like Internal, but omit from symbol table.
-    LinkerPrivateLinkage, ///< Like Private, but linker removes.
-    LinkerPrivateWeakLinkage, ///< Like LinkerPrivate, but weak.
-    DLLImportLinkage,   ///< Function to be imported from DLL
-    DLLExportLinkage,   ///< Function to be accessible from DLL.
     ExternalWeakLinkage,///< ExternalWeak linkage description.
     CommonLinkage       ///< Tentative definitions.
   };
@@ -55,59 +57,136 @@ public:
     ProtectedVisibility     ///< The GV is protected
   };
 
+  /// @brief Storage classes of global values for PE targets.
+  enum DLLStorageClassTypes {
+    DefaultStorageClass   = 0,
+    DLLImportStorageClass = 1, ///< Function to be imported from DLL
+    DLLExportStorageClass = 2  ///< Function to be accessible from DLL.
+  };
+
 protected:
-  GlobalValue(Type *ty, ValueTy vty, Use *Ops, unsigned NumOps,
-              LinkageTypes linkage, const Twine &Name)
-    : Constant(ty, vty, Ops, NumOps), Linkage(linkage),
-      Visibility(DefaultVisibility), Alignment(0), UnnamedAddr(0), Parent(0) {
+  GlobalValue(Type *Ty, ValueTy VTy, Use *Ops, unsigned NumOps,
+              LinkageTypes Linkage, const Twine &Name, unsigned AddressSpace)
+      : Constant(PointerType::get(Ty, AddressSpace), VTy, Ops, NumOps),
+        ValueType(Ty), Linkage(Linkage), Visibility(DefaultVisibility),
+        UnnamedAddr(0), DllStorageClass(DefaultStorageClass),
+        ThreadLocal(NotThreadLocal), IntID((Intrinsic::ID)0U), Parent(nullptr) {
     setName(Name);
   }
 
+  Type *ValueType;
   // Note: VC++ treats enums as signed, so an extra bit is required to prevent
   // Linkage and Visibility from turning into negative values.
   LinkageTypes Linkage : 5;   // The linkage of this global
   unsigned Visibility : 2;    // The visibility style of this global
-  unsigned Alignment : 16;    // Alignment of this symbol, must be power of two
   unsigned UnnamedAddr : 1;   // This value's address is not significant
+  unsigned DllStorageClass : 2; // DLL storage class
+
+  unsigned ThreadLocal : 3; // Is this symbol "Thread Local", if so, what is
+                            // the desired model?
+  static const unsigned GlobalValueSubClassDataBits = 19;
+
+private:
+  // Give subclasses access to what otherwise would be wasted padding.
+  // (19 + 3 + 2 + 1 + 2 + 5) == 32.
+  unsigned SubClassData : GlobalValueSubClassDataBits;
+
+  friend class Constant;
+  void destroyConstantImpl();
+  Value *handleOperandChangeImpl(Value *From, Value *To, Use *U);
+
+protected:
+  /// \brief The intrinsic ID for this subclass (which must be a Function).
+  ///
+  /// This member is defined by this class, but not used for anything.
+  /// Subclasses can use it to store their intrinsic ID, if they have one.
+  ///
+  /// This is stored here to save space in Function on 64-bit hosts.
+  Intrinsic::ID IntID;
+
+  unsigned getGlobalValueSubClassData() const {
+    return SubClassData;
+  }
+  void setGlobalValueSubClassData(unsigned V) {
+    assert(V < (1 << GlobalValueSubClassDataBits) && "It will not fit");
+    SubClassData = V;
+  }
+
   Module *Parent;             // The containing module.
-  std::string Section;        // Section to emit this into, empty mean default
 public:
-  ~GlobalValue() {
+  enum ThreadLocalMode {
+    NotThreadLocal = 0,
+    GeneralDynamicTLSModel,
+    LocalDynamicTLSModel,
+    InitialExecTLSModel,
+    LocalExecTLSModel
+  };
+
+  ~GlobalValue() override {
     removeDeadConstantUsers();   // remove any dead constants using this.
   }
 
-  unsigned getAlignment() const {
-    return (1u << Alignment) >> 1;
-  }
-  void setAlignment(unsigned Align);
+  unsigned getAlignment() const;
 
   bool hasUnnamedAddr() const { return UnnamedAddr; }
   void setUnnamedAddr(bool Val) { UnnamedAddr = Val; }
 
+  bool hasComdat() const { return getComdat() != nullptr; }
+  Comdat *getComdat();
+  const Comdat *getComdat() const {
+    return const_cast<GlobalValue *>(this)->getComdat();
+  }
+
   VisibilityTypes getVisibility() const { return VisibilityTypes(Visibility); }
   bool hasDefaultVisibility() const { return Visibility == DefaultVisibility; }
   bool hasHiddenVisibility() const { return Visibility == HiddenVisibility; }
   bool hasProtectedVisibility() const {
     return Visibility == ProtectedVisibility;
   }
-  void setVisibility(VisibilityTypes V) { Visibility = V; }
-  
-  bool hasSection() const { return !Section.empty(); }
-  const std::string &getSection() const { return Section; }
-  void setSection(StringRef S) { Section = S; }
-  
-  /// If the usage is empty (except transitively dead constants), then this
-  /// global value can be safely deleted since the destructor will
-  /// delete the dead constants as well.
-  /// @brief Determine if the usage of this global value is empty except
-  /// for transitively dead constants.
-  bool use_empty_except_constants();
+  void setVisibility(VisibilityTypes V) {
+    assert((!hasLocalLinkage() || V == DefaultVisibility) &&
+           "local linkage requires default visibility");
+    Visibility = V;
+  }
 
-  /// getType - Global values are always pointers.
-  inline PointerType *getType() const {
-    return cast<PointerType>(User::getType());
+  /// If the value is "Thread Local", its value isn't shared by the threads.
+  bool isThreadLocal() const { return getThreadLocalMode() != NotThreadLocal; }
+  void setThreadLocal(bool Val) {
+    setThreadLocalMode(Val ? GeneralDynamicTLSModel : NotThreadLocal);
+  }
+  void setThreadLocalMode(ThreadLocalMode Val) {
+    assert(Val == NotThreadLocal || getValueID() != Value::FunctionVal);
+    ThreadLocal = Val;
+  }
+  ThreadLocalMode getThreadLocalMode() const {
+    return static_cast<ThreadLocalMode>(ThreadLocal);
   }
 
+  DLLStorageClassTypes getDLLStorageClass() const {
+    return DLLStorageClassTypes(DllStorageClass);
+  }
+  bool hasDLLImportStorageClass() const {
+    return DllStorageClass == DLLImportStorageClass;
+  }
+  bool hasDLLExportStorageClass() const {
+    return DllStorageClass == DLLExportStorageClass;
+  }
+  void setDLLStorageClass(DLLStorageClassTypes C) { DllStorageClass = C; }
+
+  bool hasSection() const { return !StringRef(getSection()).empty(); }
+  // It is unfortunate that we have to use "char *" in here since this is
+  // always non NULL, but:
+  // * The C API expects a null terminated string, so we cannot use StringRef.
+  // * The C API expects us to own it, so we cannot use a std:string.
+  // * For GlobalAliases we can fail to find the section and we have to
+  //   return "", so we cannot use a "const std::string &".
+  const char *getSection() const;
+
+  /// Global values are always pointers.
+  PointerType *getType() const { return cast<PointerType>(User::getType()); }
+
+  Type *getValueType() const { return ValueType; }
+
   static LinkageTypes getLinkOnceLinkage(bool ODR) {
     return ODR ? LinkOnceODRLinkage : LinkOnceAnyLinkage;
   }
@@ -121,11 +200,20 @@ public:
   static bool isAvailableExternallyLinkage(LinkageTypes Linkage) {
     return Linkage == AvailableExternallyLinkage;
   }
+  static bool isLinkOnceODRLinkage(LinkageTypes Linkage) {
+    return Linkage == LinkOnceODRLinkage;
+  }
   static bool isLinkOnceLinkage(LinkageTypes Linkage) {
     return Linkage == LinkOnceAnyLinkage || Linkage == LinkOnceODRLinkage;
   }
+  static bool isWeakAnyLinkage(LinkageTypes Linkage) {
+    return Linkage == WeakAnyLinkage;
+  }
+  static bool isWeakODRLinkage(LinkageTypes Linkage) {
+    return Linkage == WeakODRLinkage;
+  }
   static bool isWeakLinkage(LinkageTypes Linkage) {
-    return Linkage == WeakAnyLinkage || Linkage == WeakODRLinkage;
+    return isWeakAnyLinkage(Linkage) || isWeakODRLinkage(Linkage);
   }
   static bool isAppendingLinkage(LinkageTypes Linkage) {
     return Linkage == AppendingLinkage;
@@ -136,21 +224,8 @@ public:
   static bool isPrivateLinkage(LinkageTypes Linkage) {
     return Linkage == PrivateLinkage;
   }
-  static bool isLinkerPrivateLinkage(LinkageTypes Linkage) {
-    return Linkage == LinkerPrivateLinkage;
-  }
-  static bool isLinkerPrivateWeakLinkage(LinkageTypes Linkage) {
-    return Linkage == LinkerPrivateWeakLinkage;
-  }
   static bool isLocalLinkage(LinkageTypes Linkage) {
-    return isInternalLinkage(Linkage) || isPrivateLinkage(Linkage) ||
-      isLinkerPrivateLinkage(Linkage) || isLinkerPrivateWeakLinkage(Linkage);
-  }
-  static bool isDLLImportLinkage(LinkageTypes Linkage) {
-    return Linkage == DLLImportLinkage;
-  }
-  static bool isDLLExportLinkage(LinkageTypes Linkage) {
-    return Linkage == DLLExportLinkage;
+    return isInternalLinkage(Linkage) || isPrivateLinkage(Linkage);
   }
   static bool isExternalWeakLinkage(LinkageTypes Linkage) {
     return Linkage == ExternalWeakLinkage;
@@ -159,36 +234,30 @@ public:
     return Linkage == CommonLinkage;
   }
 
-  /// isDiscardableIfUnused - Whether the definition of this global may be
-  /// discarded if it is not used in its compilation unit.
+  /// Whether the definition of this global may be discarded if it is not used
+  /// in its compilation unit.
   static bool isDiscardableIfUnused(LinkageTypes Linkage) {
-    return isLinkOnceLinkage(Linkage) || isLocalLinkage(Linkage);
+    return isLinkOnceLinkage(Linkage) || isLocalLinkage(Linkage) ||
+           isAvailableExternallyLinkage(Linkage);
   }
 
-  /// mayBeOverridden - Whether the definition of this global may be replaced
-  /// by something non-equivalent at link time.  For example, if a function has
-  /// weak linkage then the code defining it may be replaced by different code.
+  /// Whether the definition of this global may be replaced by something
+  /// non-equivalent at link time. For example, if a function has weak linkage
+  /// then the code defining it may be replaced by different code.
   static bool mayBeOverridden(LinkageTypes Linkage) {
-    return Linkage == WeakAnyLinkage ||
-           Linkage == LinkOnceAnyLinkage ||
-           Linkage == CommonLinkage ||
-           Linkage == ExternalWeakLinkage ||
-           Linkage == LinkerPrivateWeakLinkage;
+    return Linkage == WeakAnyLinkage || Linkage == LinkOnceAnyLinkage ||
+           Linkage == CommonLinkage || Linkage == ExternalWeakLinkage;
   }
 
-  /// isWeakForLinker - Whether the definition of this global may be replaced at
-  /// link time.  NB: Using this method outside of the code generators is almost
-  /// always a mistake: when working at the IR level use mayBeOverridden instead
-  /// as it knows about ODR semantics.
+  /// Whether the definition of this global may be replaced at link time.  NB:
+  /// Using this method outside of the code generators is almost always a
+  /// mistake: when working at the IR level use mayBeOverridden instead as it
+  /// knows about ODR semantics.
   static bool isWeakForLinker(LinkageTypes Linkage)  {
-    return Linkage == AvailableExternallyLinkage ||
-           Linkage == WeakAnyLinkage ||
-           Linkage == WeakODRLinkage ||
-           Linkage == LinkOnceAnyLinkage ||
-           Linkage == LinkOnceODRLinkage ||
-           Linkage == CommonLinkage ||
-           Linkage == ExternalWeakLinkage ||
-           Linkage == LinkerPrivateWeakLinkage;
+    return Linkage == WeakAnyLinkage || Linkage == WeakODRLinkage ||
+           Linkage == LinkOnceAnyLinkage || Linkage == LinkOnceODRLinkage ||
+           Linkage == CommonLinkage || Linkage == ExternalWeakLinkage ||
+           Linkage == AvailableExternallyLinkage;
   }
 
   bool hasExternalLinkage() const { return isExternalLinkage(Linkage); }
@@ -198,23 +267,28 @@ public:
   bool hasLinkOnceLinkage() const {
     return isLinkOnceLinkage(Linkage);
   }
+  bool hasLinkOnceODRLinkage() const { return isLinkOnceODRLinkage(Linkage); }
   bool hasWeakLinkage() const {
     return isWeakLinkage(Linkage);
   }
+  bool hasWeakAnyLinkage() const {
+    return isWeakAnyLinkage(Linkage);
+  }
+  bool hasWeakODRLinkage() const {
+    return isWeakODRLinkage(Linkage);
+  }
   bool hasAppendingLinkage() const { return isAppendingLinkage(Linkage); }
   bool hasInternalLinkage() const { return isInternalLinkage(Linkage); }
   bool hasPrivateLinkage() const { return isPrivateLinkage(Linkage); }
-  bool hasLinkerPrivateLinkage() const { return isLinkerPrivateLinkage(Linkage); }
-  bool hasLinkerPrivateWeakLinkage() const {
-    return isLinkerPrivateWeakLinkage(Linkage);
-  }
   bool hasLocalLinkage() const { return isLocalLinkage(Linkage); }
-  bool hasDLLImportLinkage() const { return isDLLImportLinkage(Linkage); }
-  bool hasDLLExportLinkage() const { return isDLLExportLinkage(Linkage); }
   bool hasExternalWeakLinkage() const { return isExternalWeakLinkage(Linkage); }
   bool hasCommonLinkage() const { return isCommonLinkage(Linkage); }
 
-  void setLinkage(LinkageTypes LT) { Linkage = LT; }
+  void setLinkage(LinkageTypes LT) {
+    if (isLocalLinkage(LT))
+      Visibility = DefaultVisibility;
+    Linkage = LT;
+  }
   LinkageTypes getLinkage() const { return Linkage; }
 
   bool isDiscardableIfUnused() const {
@@ -225,13 +299,13 @@ public:
 
   bool isWeakForLinker() const { return isWeakForLinker(Linkage); }
 
-  /// copyAttributesFrom - copy all additional attributes (those not needed to
-  /// create a GlobalValue) from the GlobalValue Src to this one.
+  /// Copy all additional attributes (those not needed to create a GlobalValue)
+  /// from the GlobalValue Src to this one.
   virtual void copyAttributesFrom(const GlobalValue *Src);
 
-  /// getRealLinkageName - If special LLVM prefix that is used to inform the asm
-  /// printer to not emit usual symbol prefix before the symbol name is used
-  /// then return linkage name after skipping this special LLVM prefix.
+  /// If special LLVM prefix that is used to inform the asm printer to not emit
+  /// usual symbol prefix before the symbol name is used then return linkage
+  /// name after skipping this special LLVM prefix.
   static StringRef getRealLinkageName(StringRef Name) {
     if (!Name.empty() && Name[0] == '\1')
       return Name.substr(1);
@@ -244,50 +318,58 @@ public:
 /// BitcodeReader to load the Module.
 /// @{
 
-  /// isMaterializable - If this function's Module is being lazily streamed in
-  /// functions from disk or some other source, this method can be used to check
-  /// to see if the function has been read in yet or not.
+  /// If this function's Module is being lazily streamed in functions from disk
+  /// or some other source, this method can be used to check to see if the
+  /// function has been read in yet or not.
   bool isMaterializable() const;
 
-  /// isDematerializable - Returns true if this function was loaded from a
-  /// GVMaterializer that's still attached to its Module and that knows how to
-  /// dematerialize the function.
+  /// Returns true if this function was loaded from a GVMaterializer that's
+  /// still attached to its Module and that knows how to dematerialize the
+  /// function.
   bool isDematerializable() const;
 
-  /// Materialize - make sure this GlobalValue is fully read.  If the module is
-  /// corrupt, this returns true and fills in the optional string with
-  /// information about the problem.  If successful, this returns false.
-  bool Materialize(std::string *ErrInfo = 0);
+  /// Make sure this GlobalValue is fully read. If the module is corrupt, this
+  /// returns true and fills in the optional string with information about the
+  /// problem.  If successful, this returns false.
+  std::error_code materialize();
 
-  /// Dematerialize - If this GlobalValue is read in, and if the GVMaterializer
-  /// supports it, release the memory for the function, and set it up to be
-  /// materialized lazily.  If !isDematerializable(), this method is a noop.
-  void Dematerialize();
+  /// If this GlobalValue is read in, and if the GVMaterializer supports it,
+  /// release the memory for the function, and set it up to be materialized
+  /// lazily. If !isDematerializable(), this method is a noop.
+  void dematerialize();
 
 /// @}
 
-  /// Override from Constant class.
-  virtual void destroyConstant();
-
-  /// isDeclaration - Return true if the primary definition of this global 
-  /// value is outside of the current translation unit.
+  /// Return true if the primary definition of this global value is outside of
+  /// the current translation unit.
   bool isDeclaration() const;
 
-  /// removeFromParent - This method unlinks 'this' from the containing module,
-  /// but does not delete it.
+  bool isDeclarationForLinker() const {
+    if (hasAvailableExternallyLinkage())
+      return true;
+
+    return isDeclaration();
+  }
+
+  /// Returns true if this global's definition will be the one chosen by the
+  /// linker.
+  bool isStrongDefinitionForLinker() const {
+    return !(isDeclarationForLinker() || isWeakForLinker());
+  }
+
+  /// This method unlinks 'this' from the containing module, but does not delete
+  /// it.
   virtual void removeFromParent() = 0;
 
-  /// eraseFromParent - This method unlinks 'this' from the containing module
-  /// and deletes it.
+  /// This method unlinks 'this' from the containing module and deletes it.
   virtual void eraseFromParent() = 0;
 
-  /// getParent - Get the module that this global value is contained inside
-  /// of...
-  inline Module *getParent() { return Parent; }
-  inline const Module *getParent() const { return Parent; }
+  /// Get the module that this global value is contained inside of...
+  Module *getParent() { return Parent; }
+  const Module *getParent() const { return Parent; }
 
   // Methods for support type inquiry through isa, cast, and dyn_cast:
-  static inline bool classof(const Value *V) {
+  static bool classof(const Value *V) {
     return V->getValueID() == Value::FunctionVal ||
            V->getValueID() == Value::GlobalVariableVal ||
            V->getValueID() == Value::GlobalAliasVal;