[llvm] r199204 - Decouple dllexport/dllimport from linkage

Nico Rieck nico.rieck at gmail.com
Tue Jan 14 03:55:03 PST 2014


Author: nrieck
Date: Tue Jan 14 05:55:03 2014
New Revision: 199204

URL: http://llvm.org/viewvc/llvm-project?rev=199204&view=rev
Log:
Decouple dllexport/dllimport from linkage

Representing dllexport/dllimport as distinct linkage types prevents using
these attributes on templates and inline functions.

Instead of introducing further mixed linkage types to include linkonce and
weak ODR, the old import/export linkage types are replaced with a new
separate visibility-like specifier:

  define available_externally dllimport void @f() {}
  @Var = dllexport global i32 1, align 4

Linkage for dllexported globals and functions is now equal to their linkage
without dllexport. Imported globals and functions must be either
declarations with external linkage, or definitions with
AvailableExternallyLinkage.

Added:
    llvm/trunk/test/CodeGen/X86/dllexport-x86_64.ll
    llvm/trunk/test/CodeGen/X86/dllimport-x86_64.ll
    llvm/trunk/test/CodeGen/X86/dllimport.ll
Removed:
    llvm/trunk/test/CodeGen/X86/dll-linkage.ll
Modified:
    llvm/trunk/docs/BitCodeFormat.rst
    llvm/trunk/docs/LangRef.rst
    llvm/trunk/include/llvm-c/Core.h
    llvm/trunk/include/llvm/IR/GlobalValue.h
    llvm/trunk/lib/AsmParser/LLParser.cpp
    llvm/trunk/lib/AsmParser/LLParser.h
    llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
    llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp
    llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
    llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp
    llvm/trunk/lib/IR/AsmWriter.cpp
    llvm/trunk/lib/IR/Core.cpp
    llvm/trunk/lib/IR/Verifier.cpp
    llvm/trunk/lib/Linker/LinkModules.cpp
    llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp
    llvm/trunk/lib/Target/X86/X86AsmPrinter.cpp
    llvm/trunk/lib/Target/X86/X86FastISel.cpp
    llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
    llvm/trunk/lib/Target/X86/X86Subtarget.cpp
    llvm/trunk/lib/Target/XCore/XCoreAsmPrinter.cpp
    llvm/trunk/lib/Transforms/IPO/Internalize.cpp
    llvm/trunk/test/Bitcode/linkage-types-3.2.ll
    llvm/trunk/test/CodeGen/X86/dllexport.ll

Modified: llvm/trunk/docs/BitCodeFormat.rst
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/BitCodeFormat.rst?rev=199204&r1=199203&r2=199204&view=diff
==============================================================================
--- llvm/trunk/docs/BitCodeFormat.rst (original)
+++ llvm/trunk/docs/BitCodeFormat.rst Tue Jan 14 05:55:03 2014
@@ -658,7 +658,7 @@ for each library name referenced.
 MODULE_CODE_GLOBALVAR Record
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-``[GLOBALVAR, pointer type, isconst, initid, linkage, alignment, section, visibility, threadlocal, unnamed_addr]``
+``[GLOBALVAR, pointer type, isconst, initid, linkage, alignment, section, visibility, threadlocal, unnamed_addr, dllstorageclass]``
 
 The ``GLOBALVAR`` record (code 7) marks the declaration or definition of a
 global variable. The operand fields are:
@@ -713,12 +713,20 @@ global variable. The operand fields are:
 * *unnamed_addr*: If present and non-zero, indicates that the variable has
   ``unnamed_addr``
 
+.. _dllstorageclass:
+
+* *dllstorageclass*: If present, an encoding of the DLL storage class of this variable:
+
+  * ``default``: code 0
+  * ``dllimport``: code 1
+  * ``dllexport``: code 2
+
 .. _FUNCTION:
 
 MODULE_CODE_FUNCTION Record
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-``[FUNCTION, type, callingconv, isproto, linkage, paramattr, alignment, section, visibility, gc, prefix]``
+``[FUNCTION, type, callingconv, isproto, linkage, paramattr, alignment, section, visibility, gc, prefix, dllstorageclass]``
 
 The ``FUNCTION`` record (code 8) marks the declaration or definition of a
 function. The operand fields are:
@@ -762,10 +770,12 @@ function. The operand fields are:
 * *prefix*: If non-zero, the value index of the prefix data for this function,
   plus 1.
 
+* *dllstorageclass*: An encoding of the `dllstorageclass`_ of this function
+
 MODULE_CODE_ALIAS Record
 ^^^^^^^^^^^^^^^^^^^^^^^^
 
-``[ALIAS, alias type, aliasee val#, linkage, visibility]``
+``[ALIAS, alias type, aliasee val#, linkage, visibility, dllstorageclass]``
 
 The ``ALIAS`` record (code 9) marks the definition of an alias. The operand
 fields are
@@ -778,6 +788,8 @@ fields are
 
 * *visibility*: If present, an encoding of the `visibility`_ of the alias
 
+* *dllstorageclass*: If present, an encoding of the `dllstorageclass`_ of the alias
+
 MODULE_CODE_PURGEVALS Record
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 

Modified: llvm/trunk/docs/LangRef.rst
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.rst?rev=199204&r1=199203&r2=199204&view=diff
==============================================================================
--- llvm/trunk/docs/LangRef.rst (original)
+++ llvm/trunk/docs/LangRef.rst Tue Jan 14 05:55:03 2014
@@ -274,27 +274,8 @@ linkage:
     visible, meaning that it participates in linkage and can be used to
     resolve external symbol references.
 
-The next two types of linkage are targeted for Microsoft Windows
-platform only. They are designed to support importing (exporting)
-symbols from (to) DLLs (Dynamic Link Libraries).
-
-``dllimport``
-    "``dllimport``" linkage causes the compiler to reference a function
-    or variable via a global pointer to a pointer that is set up by the
-    DLL exporting the symbol. On Microsoft Windows targets, the pointer
-    name is formed by combining ``__imp_`` and the function or variable
-    name.
-``dllexport``
-    "``dllexport``" linkage causes the compiler to provide a global
-    pointer to a pointer in a DLL, so that it can be referenced with the
-    ``dllimport`` attribute. On Microsoft Windows targets, the pointer
-    name is formed by combining ``__imp_`` and the function or variable
-    name. Since this linkage exists for defining a dll interface, the
-    compiler, assembler and linker know it is externally referenced and
-    must refrain from deleting the symbol.
-
 It is illegal for a function *declaration* to have any linkage type
-other than ``external``, ``dllimport`` or ``extern_weak``.
+other than ``external`` or ``extern_weak``.
 
 .. _callingconv:
 
@@ -416,6 +397,25 @@ styles:
 
 .. _namedtypes:
 
+DLL Storage Classes
+-------------------
+
+All Global Variables, Functions and Aliases can have one of the following
+DLL storage class:
+
+``dllimport``
+    "``dllimport``" causes the compiler to reference a function or variable via
+    a global pointer to a pointer that is set up by the DLL exporting the
+    symbol. On Microsoft Windows targets, the pointer name is formed by
+    combining ``__imp_`` and the function or variable name.
+``dllexport``
+    "``dllexport``" causes the compiler to provide a global pointer to a pointer
+    in a DLL, so that it can be referenced with the ``dllimport`` attribute. On
+    Microsoft Windows targets, the pointer name is formed by combining
+    ``__imp_`` and the function or variable name. Since this storage class
+    exists for defining a dll interface, the compiler, assembler and linker know
+    it is externally referenced and must refrain from deleting the symbol.
+
 Named Types
 -----------
 
@@ -529,6 +529,15 @@ assume that the globals are densely pack
 iterate over them as an array, alignment padding would break this
 iteration.
 
+Globals can also have a :ref:`DLL storage class <dllstorageclass>`.
+
+Syntax::
+
+    [@<GlobalVarName> =] [Linkage] [Visibility] [DLLStorageClass] [ThreadLocal]
+                         [AddrSpace] [unnamed_addr] [ExternallyInitialized]
+                         <global | constant> <Type>
+                         [, section "name"] [, align <Alignment>]
+
 For example, the following defines a global in a numbered address space
 with an initializer, section, and alignment:
 
@@ -556,7 +565,8 @@ Functions
 
 LLVM function definitions consist of the "``define``" keyword, an
 optional :ref:`linkage type <linkage>`, an optional :ref:`visibility
-style <visibility>`, an optional :ref:`calling convention <callingconv>`,
+style <visibility>`, an optional :ref:`DLL storage class <dllstorageclass>`,
+an optional :ref:`calling convention <callingconv>`,
 an optional ``unnamed_addr`` attribute, a return type, an optional
 :ref:`parameter attribute <paramattrs>` for the return type, a function
 name, a (possibly empty) argument list (each with optional :ref:`parameter
@@ -567,7 +577,8 @@ curly brace, a list of basic blocks, and
 
 LLVM function declarations consist of the "``declare``" keyword, an
 optional :ref:`linkage type <linkage>`, an optional :ref:`visibility
-style <visibility>`, an optional :ref:`calling convention <callingconv>`,
+style <visibility>`, an optional :ref:`DLL storage class <dllstorageclass>`,
+an optional :ref:`calling convention <callingconv>`,
 an optional ``unnamed_addr`` attribute, a return type, an optional
 :ref:`parameter attribute <paramattrs>` for the return type, a function
 name, a possibly empty list of arguments, an optional alignment, an optional
@@ -603,7 +614,7 @@ be significant and two identical functio
 
 Syntax::
 
-    define [linkage] [visibility]
+    define [linkage] [visibility] [DLLStorageClass]
            [cconv] [ret attrs]
            <ResultType> @<FunctionName> ([argument list])
            [fn Attrs] [section "name"] [align N]
@@ -616,12 +627,13 @@ Aliases
 
 Aliases act as "second name" for the aliasee value (which can be either
 function, global variable, another alias or bitcast of global value).
-Aliases may have an optional :ref:`linkage type <linkage>`, and an optional
-:ref:`visibility style <visibility>`.
+Aliases may have an optional :ref:`linkage type <linkage>`, an optional
+:ref:`visibility style <visibility>`, and an optional :ref:`DLL storage class
+<dllstorageclass>`.
 
 Syntax::
 
-    @<Name> = alias [Linkage] [Visibility] <AliaseeTy> @<Aliasee>
+    @<Name> = [Visibility] [DLLStorageClass] alias [Linkage] <AliaseeTy> @<Aliasee>
 
 The linkage must be one of ``private``, ``linker_private``,
 ``linker_private_weak``, ``internal``, ``linkonce``, ``weak``,

Modified: llvm/trunk/include/llvm-c/Core.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm-c/Core.h?rev=199204&r1=199203&r2=199204&view=diff
==============================================================================
--- llvm/trunk/include/llvm-c/Core.h (original)
+++ llvm/trunk/include/llvm-c/Core.h Tue Jan 14 05:55:03 2014
@@ -284,8 +284,8 @@ typedef enum {
   LLVMInternalLinkage,    /**< Rename collisions when linking (static
                                functions) */
   LLVMPrivateLinkage,     /**< Like Internal, but omit from symbol table */
-  LLVMDLLImportLinkage,   /**< Function to be imported from DLL */
-  LLVMDLLExportLinkage,   /**< Function to be accessible from DLL */
+  LLVMDLLImportLinkage,   /**< Obsolete */
+  LLVMDLLExportLinkage,   /**< Obsolete */
   LLVMExternalWeakLinkage,/**< ExternalWeak linkage description */
   LLVMGhostLinkage,       /**< Obsolete */
   LLVMCommonLinkage,      /**< Tentative definitions */

Modified: llvm/trunk/include/llvm/IR/GlobalValue.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/GlobalValue.h?rev=199204&r1=199203&r2=199204&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/GlobalValue.h (original)
+++ llvm/trunk/include/llvm/IR/GlobalValue.h Tue Jan 14 05:55:03 2014
@@ -42,8 +42,6 @@ public:
     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,11 +53,19 @@ 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) {
+      Visibility(DefaultVisibility), Alignment(0), UnnamedAddr(0),
+      DllStorageClass(DefaultStorageClass), Parent(0) {
     setName(Name);
   }
 
@@ -69,6 +75,7 @@ protected:
   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
   Module *Parent;             // The containing module.
   std::string Section;        // Section to emit this into, empty mean default
 public:
@@ -91,7 +98,18 @@ public:
     return Visibility == ProtectedVisibility;
   }
   void setVisibility(VisibilityTypes V) { Visibility = V; }
-  
+
+  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 !Section.empty(); }
   const std::string &getSection() const { return Section; }
   void setSection(StringRef S) { Section = S; }
@@ -146,12 +164,6 @@ public:
     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;
-  }
   static bool isExternalWeakLinkage(LinkageTypes Linkage) {
     return Linkage == ExternalWeakLinkage;
   }
@@ -209,8 +221,6 @@ public:
     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); }
 

Modified: llvm/trunk/lib/AsmParser/LLParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.cpp?rev=199204&r1=199203&r2=199204&view=diff
==============================================================================
--- llvm/trunk/lib/AsmParser/LLParser.cpp (original)
+++ llvm/trunk/lib/AsmParser/LLParser.cpp Tue Jan 14 05:55:03 2014
@@ -242,8 +242,8 @@ bool LLParser::ParseTopLevelEntities() {
 
     // The Global variable production with no name can have many different
     // optional leading prefixes, the production is:
-    // GlobalVar ::= OptionalLinkage OptionalVisibility OptionalThreadLocal
-    //               OptionalAddrSpace OptionalUnNammedAddr
+    // GlobalVar ::= OptionalLinkage OptionalVisibility OptionalDLLStorageClass
+    //               OptionalThreadLocal OptionalAddrSpace OptionalUnNammedAddr
     //               ('constant'|'global') ...
     case lltok::kw_private:             // OptionalLinkage
     case lltok::kw_linker_private:      // OptionalLinkage
@@ -254,24 +254,24 @@ bool LLParser::ParseTopLevelEntities() {
     case lltok::kw_linkonce:            // OptionalLinkage
     case lltok::kw_linkonce_odr:        // OptionalLinkage
     case lltok::kw_appending:           // OptionalLinkage
-    case lltok::kw_dllexport:           // OptionalLinkage
     case lltok::kw_common:              // OptionalLinkage
-    case lltok::kw_dllimport:           // OptionalLinkage
     case lltok::kw_extern_weak:         // OptionalLinkage
     case lltok::kw_external: {          // OptionalLinkage
-      unsigned Linkage, Visibility;
+      unsigned Linkage, Visibility, DLLStorageClass;
       if (ParseOptionalLinkage(Linkage) ||
           ParseOptionalVisibility(Visibility) ||
-          ParseGlobal("", SMLoc(), Linkage, true, Visibility))
+          ParseOptionalDLLStorageClass(DLLStorageClass) ||
+          ParseGlobal("", SMLoc(), Linkage, true, Visibility, DLLStorageClass))
         return true;
       break;
     }
     case lltok::kw_default:       // OptionalVisibility
     case lltok::kw_hidden:        // OptionalVisibility
     case lltok::kw_protected: {   // OptionalVisibility
-      unsigned Visibility;
+      unsigned Visibility, DLLStorageClass;
       if (ParseOptionalVisibility(Visibility) ||
-          ParseGlobal("", SMLoc(), 0, false, Visibility))
+          ParseOptionalDLLStorageClass(DLLStorageClass) ||
+          ParseGlobal("", SMLoc(), 0, false, Visibility, DLLStorageClass))
         return true;
       break;
     }
@@ -280,7 +280,7 @@ bool LLParser::ParseTopLevelEntities() {
     case lltok::kw_addrspace:     // OptionalAddrSpace
     case lltok::kw_constant:      // GlobalType
     case lltok::kw_global:        // GlobalType
-      if (ParseGlobal("", SMLoc(), 0, false, 0)) return true;
+      if (ParseGlobal("", SMLoc(), 0, false, 0, 0)) return true;
       break;
 
     case lltok::kw_attributes: if (ParseUnnamedAttrGrp()) return true; break;
@@ -446,9 +446,11 @@ bool LLParser::ParseGlobalType(bool &IsC
 
 /// ParseUnnamedGlobal:
 ///   OptionalVisibility ALIAS ...
-///   OptionalLinkage OptionalVisibility ...   -> global variable
+///   OptionalLinkage OptionalVisibility OptionalDLLStorageClass
+///                                                     ...   -> global variable
 ///   GlobalID '=' OptionalVisibility ALIAS ...
-///   GlobalID '=' OptionalLinkage OptionalVisibility ...   -> global variable
+///   GlobalID '=' OptionalLinkage OptionalVisibility OptionalDLLStorageClass
+///                                                     ...   -> global variable
 bool LLParser::ParseUnnamedGlobal() {
   unsigned VarID = NumberedVals.size();
   std::string Name;
@@ -466,19 +468,22 @@ bool LLParser::ParseUnnamedGlobal() {
   }
 
   bool HasLinkage;
-  unsigned Linkage, Visibility;
+  unsigned Linkage, Visibility, DLLStorageClass;
   if (ParseOptionalLinkage(Linkage, HasLinkage) ||
-      ParseOptionalVisibility(Visibility))
+      ParseOptionalVisibility(Visibility) ||
+      ParseOptionalDLLStorageClass(DLLStorageClass))
     return true;
 
   if (HasLinkage || Lex.getKind() != lltok::kw_alias)
-    return ParseGlobal(Name, NameLoc, Linkage, HasLinkage, Visibility);
-  return ParseAlias(Name, NameLoc, Visibility);
+    return ParseGlobal(Name, NameLoc, Linkage, HasLinkage, Visibility,
+                       DLLStorageClass);
+  return ParseAlias(Name, NameLoc, Visibility, DLLStorageClass);
 }
 
 /// ParseNamedGlobal:
 ///   GlobalVar '=' OptionalVisibility ALIAS ...
-///   GlobalVar '=' OptionalLinkage OptionalVisibility ...   -> global variable
+///   GlobalVar '=' OptionalLinkage OptionalVisibility OptionalDLLStorageClass
+///                                                     ...   -> global variable
 bool LLParser::ParseNamedGlobal() {
   assert(Lex.getKind() == lltok::GlobalVar);
   LocTy NameLoc = Lex.getLoc();
@@ -486,15 +491,17 @@ bool LLParser::ParseNamedGlobal() {
   Lex.Lex();
 
   bool HasLinkage;
-  unsigned Linkage, Visibility;
+  unsigned Linkage, Visibility, DLLStorageClass;
   if (ParseToken(lltok::equal, "expected '=' in global variable") ||
       ParseOptionalLinkage(Linkage, HasLinkage) ||
-      ParseOptionalVisibility(Visibility))
+      ParseOptionalVisibility(Visibility) ||
+      ParseOptionalDLLStorageClass(DLLStorageClass))
     return true;
 
   if (HasLinkage || Lex.getKind() != lltok::kw_alias)
-    return ParseGlobal(Name, NameLoc, Linkage, HasLinkage, Visibility);
-  return ParseAlias(Name, NameLoc, Visibility);
+    return ParseGlobal(Name, NameLoc, Linkage, HasLinkage, Visibility,
+                       DLLStorageClass);
+  return ParseAlias(Name, NameLoc, Visibility, DLLStorageClass);
 }
 
 // MDString:
@@ -615,16 +622,17 @@ bool LLParser::ParseStandaloneMetadata()
 }
 
 /// ParseAlias:
-///   ::= GlobalVar '=' OptionalVisibility 'alias' OptionalLinkage Aliasee
+///   ::= GlobalVar '=' OptionalVisibility OptionalDLLStorageClass 'alias'
+///                     OptionalLinkage Aliasee
 /// Aliasee
 ///   ::= TypeAndValue
 ///   ::= 'bitcast' '(' TypeAndValue 'to' Type ')'
 ///   ::= 'getelementptr' 'inbounds'? '(' ... ')'
 ///
-/// Everything through visibility has already been parsed.
+/// Everything through DLL storage class has already been parsed.
 ///
 bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc,
-                          unsigned Visibility) {
+                          unsigned Visibility, unsigned DLLStorageClass) {
   assert(Lex.getKind() == lltok::kw_alias);
   Lex.Lex();
   LocTy LinkageLoc = Lex.getLoc();
@@ -659,6 +667,7 @@ bool LLParser::ParseAlias(const std::str
                                     (GlobalValue::LinkageTypes)Linkage, Name,
                                     Aliasee);
   GA->setVisibility((GlobalValue::VisibilityTypes)Visibility);
+  GA->setDLLStorageClass((GlobalValue::DLLStorageClassTypes)DLLStorageClass);
 
   // See if this value already exists in the symbol table.  If so, it is either
   // a redefinition or a definition of a forward reference.
@@ -691,18 +700,18 @@ bool LLParser::ParseAlias(const std::str
 }
 
 /// ParseGlobal
-///   ::= GlobalVar '=' OptionalLinkage OptionalVisibility OptionalThreadLocal
-///       OptionalAddrSpace OptionalUnNammedAddr
+///   ::= GlobalVar '=' OptionalLinkage OptionalVisibility OptionalDLLStorageClass
+///       OptionalThreadLocal OptionalAddrSpace OptionalUnNammedAddr
 ///       OptionalExternallyInitialized GlobalType Type Const
-///   ::= OptionalLinkage OptionalVisibility OptionalThreadLocal
-///       OptionalAddrSpace OptionalUnNammedAddr
+///   ::= OptionalLinkage OptionalVisibility OptionalDLLStorageClass
+///       OptionalThreadLocal OptionalAddrSpace OptionalUnNammedAddr
 ///       OptionalExternallyInitialized GlobalType Type Const
 ///
 /// Everything through visibility has been parsed already.
 ///
 bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc,
                            unsigned Linkage, bool HasLinkage,
-                           unsigned Visibility) {
+                           unsigned Visibility, unsigned DLLStorageClass) {
   unsigned AddrSpace;
   bool IsConstant, UnnamedAddr, IsExternallyInitialized;
   GlobalVariable::ThreadLocalMode TLM;
@@ -725,8 +734,7 @@ bool LLParser::ParseGlobal(const std::st
   // If the linkage is specified and is external, then no initializer is
   // present.
   Constant *Init = 0;
-  if (!HasLinkage || (Linkage != GlobalValue::DLLImportLinkage &&
-                      Linkage != GlobalValue::ExternalWeakLinkage &&
+  if (!HasLinkage || (Linkage != GlobalValue::ExternalWeakLinkage &&
                       Linkage != GlobalValue::ExternalLinkage)) {
     if (ParseGlobalValue(Ty, Init))
       return true;
@@ -775,6 +783,7 @@ bool LLParser::ParseGlobal(const std::st
   GV->setConstant(IsConstant);
   GV->setLinkage((GlobalValue::LinkageTypes)Linkage);
   GV->setVisibility((GlobalValue::VisibilityTypes)Visibility);
+  GV->setDLLStorageClass((GlobalValue::DLLStorageClassTypes)DLLStorageClass);
   GV->setExternallyInitialized(IsExternallyInitialized);
   GV->setThreadLocalMode(TLM);
   GV->setUnnamedAddr(UnnamedAddr);
@@ -1277,9 +1286,7 @@ bool LLParser::ParseOptionalReturnAttrs(
 ///   ::= 'linkonce_odr'
 ///   ::= 'available_externally'
 ///   ::= 'appending'
-///   ::= 'dllexport'
 ///   ::= 'common'
-///   ::= 'dllimport'
 ///   ::= 'extern_weak'
 ///   ::= 'external'
 bool LLParser::ParseOptionalLinkage(unsigned &Res, bool &HasLinkage) {
@@ -1300,9 +1307,7 @@ bool LLParser::ParseOptionalLinkage(unsi
     Res = GlobalValue::AvailableExternallyLinkage;
     break;
   case lltok::kw_appending:      Res = GlobalValue::AppendingLinkage;     break;
-  case lltok::kw_dllexport:      Res = GlobalValue::DLLExportLinkage;     break;
   case lltok::kw_common:         Res = GlobalValue::CommonLinkage;        break;
-  case lltok::kw_dllimport:      Res = GlobalValue::DLLImportLinkage;     break;
   case lltok::kw_extern_weak:    Res = GlobalValue::ExternalWeakLinkage;  break;
   case lltok::kw_external:       Res = GlobalValue::ExternalLinkage;      break;
   }
@@ -1328,6 +1333,21 @@ bool LLParser::ParseOptionalVisibility(u
   return false;
 }
 
+/// ParseOptionalDLLStorageClass
+///   ::= /*empty*/
+///   ::= 'dllimport'
+///   ::= 'dllexport'
+///
+bool LLParser::ParseOptionalDLLStorageClass(unsigned &Res) {
+  switch (Lex.getKind()) {
+  default:                  Res = GlobalValue::DefaultStorageClass; return false;
+  case lltok::kw_dllimport: Res = GlobalValue::DLLImportStorageClass; break;
+  case lltok::kw_dllexport: Res = GlobalValue::DLLExportStorageClass; break;
+  }
+  Lex.Lex();
+  return false;
+}
+
 /// ParseOptionalCallingConv
 ///   ::= /*empty*/
 ///   ::= 'ccc'
@@ -2934,12 +2954,14 @@ bool LLParser::ParseFunctionHeader(Funct
   unsigned Linkage;
 
   unsigned Visibility;
+  unsigned DLLStorageClass;
   AttrBuilder RetAttrs;
   CallingConv::ID CC;
   Type *RetType = 0;
   LocTy RetTypeLoc = Lex.getLoc();
   if (ParseOptionalLinkage(Linkage) ||
       ParseOptionalVisibility(Visibility) ||
+      ParseOptionalDLLStorageClass(DLLStorageClass) ||
       ParseOptionalCallingConv(CC) ||
       ParseOptionalReturnAttrs(RetAttrs) ||
       ParseType(RetType, RetTypeLoc, true /*void allowed*/))
@@ -2949,7 +2971,6 @@ bool LLParser::ParseFunctionHeader(Funct
   switch ((GlobalValue::LinkageTypes)Linkage) {
   case GlobalValue::ExternalLinkage:
     break; // always ok.
-  case GlobalValue::DLLImportLinkage:
   case GlobalValue::ExternalWeakLinkage:
     if (isDefine)
       return Error(LinkageLoc, "invalid linkage for function definition");
@@ -2963,7 +2984,6 @@ bool LLParser::ParseFunctionHeader(Funct
   case GlobalValue::LinkOnceODRLinkage:
   case GlobalValue::WeakAnyLinkage:
   case GlobalValue::WeakODRLinkage:
-  case GlobalValue::DLLExportLinkage:
     if (!isDefine)
       return Error(LinkageLoc, "invalid linkage for function declaration");
     break;
@@ -3110,6 +3130,7 @@ bool LLParser::ParseFunctionHeader(Funct
 
   Fn->setLinkage((GlobalValue::LinkageTypes)Linkage);
   Fn->setVisibility((GlobalValue::VisibilityTypes)Visibility);
+  Fn->setDLLStorageClass((GlobalValue::DLLStorageClassTypes)DLLStorageClass);
   Fn->setCallingConv(CC);
   Fn->setAttributes(PAL);
   Fn->setUnnamedAddr(UnnamedAddr);

Modified: llvm/trunk/lib/AsmParser/LLParser.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.h?rev=199204&r1=199203&r2=199204&view=diff
==============================================================================
--- llvm/trunk/lib/AsmParser/LLParser.h (original)
+++ llvm/trunk/lib/AsmParser/LLParser.h Tue Jan 14 05:55:03 2014
@@ -204,6 +204,7 @@ namespace llvm {
       bool HasLinkage; return ParseOptionalLinkage(Linkage, HasLinkage);
     }
     bool ParseOptionalVisibility(unsigned &Visibility);
+    bool ParseOptionalDLLStorageClass(unsigned &DLLStorageClass);
     bool ParseOptionalCallingConv(CallingConv::ID &CC);
     bool ParseOptionalAlignment(unsigned &Alignment);
     bool ParseScopeAndOrdering(bool isAtomic, SynchronizationScope &Scope,
@@ -234,8 +235,10 @@ namespace llvm {
     bool ParseUnnamedGlobal();
     bool ParseNamedGlobal();
     bool ParseGlobal(const std::string &Name, LocTy Loc, unsigned Linkage,
-                     bool HasLinkage, unsigned Visibility);
-    bool ParseAlias(const std::string &Name, LocTy Loc, unsigned Visibility);
+                     bool HasLinkage, unsigned Visibility,
+                     unsigned DLLStorageClass);
+    bool ParseAlias(const std::string &Name, LocTy Loc, unsigned Visibility,
+                    unsigned DLLStorageClass);
     bool ParseStandaloneMetadata();
     bool ParseNamedMetadata();
     bool ParseMDString(MDString *&Result);

Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=199204&r1=199203&r2=199204&view=diff
==============================================================================
--- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original)
+++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Tue Jan 14 05:55:03 2014
@@ -80,8 +80,8 @@ static GlobalValue::LinkageTypes GetDeco
   case 2:  return GlobalValue::AppendingLinkage;
   case 3:  return GlobalValue::InternalLinkage;
   case 4:  return GlobalValue::LinkOnceAnyLinkage;
-  case 5:  return GlobalValue::DLLImportLinkage;
-  case 6:  return GlobalValue::DLLExportLinkage;
+  case 5:  return GlobalValue::ExternalLinkage; // Obsolete DLLImportLinkage
+  case 6:  return GlobalValue::ExternalLinkage; // Obsolete DLLExportLinkage
   case 7:  return GlobalValue::ExternalWeakLinkage;
   case 8:  return GlobalValue::CommonLinkage;
   case 9:  return GlobalValue::PrivateLinkage;
@@ -102,6 +102,16 @@ static GlobalValue::VisibilityTypes GetD
   }
 }
 
+static GlobalValue::DLLStorageClassTypes
+GetDecodedDLLStorageClass(unsigned Val) {
+  switch (Val) {
+  default: // Map unknown values to default.
+  case 0: return GlobalValue::DefaultStorageClass;
+  case 1: return GlobalValue::DLLImportStorageClass;
+  case 2: return GlobalValue::DLLExportStorageClass;
+  }
+}
+
 static GlobalVariable::ThreadLocalMode GetDecodedThreadLocalMode(unsigned Val) {
   switch (Val) {
     case 0: return GlobalVariable::NotThreadLocal;
@@ -193,6 +203,13 @@ static SynchronizationScope GetDecodedSy
   }
 }
 
+static void UpgradeDLLImportExportLinkage(llvm::GlobalValue *GV, unsigned Val) {
+  switch (Val) {
+  case 5: GV->setDLLStorageClass(GlobalValue::DLLImportStorageClass); break;
+  case 6: GV->setDLLStorageClass(GlobalValue::DLLExportStorageClass); break;
+  }
+}
+
 namespace llvm {
 namespace {
   /// @brief A class for maintaining the slot number definition
@@ -1797,7 +1814,7 @@ error_code BitcodeReader::ParseModule(bo
     }
     // GLOBALVAR: [pointer type, isconst, initid,
     //             linkage, alignment, section, visibility, threadlocal,
-    //             unnamed_addr]
+    //             unnamed_addr, dllstorageclass]
     case bitc::MODULE_CODE_GLOBALVAR: {
       if (Record.size() < 6)
         return Error(InvalidRecord);
@@ -1843,6 +1860,11 @@ error_code BitcodeReader::ParseModule(bo
       NewGV->setVisibility(Visibility);
       NewGV->setUnnamedAddr(UnnamedAddr);
 
+      if (Record.size() > 10)
+        NewGV->setDLLStorageClass(GetDecodedDLLStorageClass(Record[10]));
+      else
+        UpgradeDLLImportExportLinkage(NewGV, Record[3]);
+
       ValueList.push_back(NewGV);
 
       // Remember which value to use for the global initializer.
@@ -1851,7 +1873,8 @@ error_code BitcodeReader::ParseModule(bo
       break;
     }
     // FUNCTION:  [type, callingconv, isproto, linkage, paramattr,
-    //             alignment, section, visibility, gc, unnamed_addr]
+    //             alignment, section, visibility, gc, unnamed_addr,
+    //             dllstorageclass]
     case bitc::MODULE_CODE_FUNCTION: {
       if (Record.size() < 8)
         return Error(InvalidRecord);
@@ -1891,6 +1914,12 @@ error_code BitcodeReader::ParseModule(bo
       Func->setUnnamedAddr(UnnamedAddr);
       if (Record.size() > 10 && Record[10] != 0)
         FunctionPrefixes.push_back(std::make_pair(Func, Record[10]-1));
+
+      if (Record.size() > 11)
+        Func->setDLLStorageClass(GetDecodedDLLStorageClass(Record[11]));
+      else
+        UpgradeDLLImportExportLinkage(Func, Record[3]);
+
       ValueList.push_back(Func);
 
       // If this is a function with a body, remember the prototype we are
@@ -1902,7 +1931,7 @@ error_code BitcodeReader::ParseModule(bo
       break;
     }
     // ALIAS: [alias type, aliasee val#, linkage]
-    // ALIAS: [alias type, aliasee val#, linkage, visibility]
+    // ALIAS: [alias type, aliasee val#, linkage, visibility, dllstorageclass]
     case bitc::MODULE_CODE_ALIAS: {
       if (Record.size() < 3)
         return Error(InvalidRecord);
@@ -1917,6 +1946,10 @@ error_code BitcodeReader::ParseModule(bo
       // Old bitcode files didn't have visibility field.
       if (Record.size() > 3)
         NewGA->setVisibility(GetDecodedVisibility(Record[3]));
+      if (Record.size() > 4)
+        NewGA->setDLLStorageClass(GetDecodedDLLStorageClass(Record[4]));
+      else
+        UpgradeDLLImportExportLinkage(NewGA, Record[2]);
       ValueList.push_back(NewGA);
       AliasInits.push_back(std::make_pair(NewGA, Record[1]));
       break;

Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp?rev=199204&r1=199203&r2=199204&view=diff
==============================================================================
--- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp (original)
+++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Tue Jan 14 05:55:03 2014
@@ -481,8 +481,6 @@ static unsigned getEncodedLinkage(const
   case GlobalValue::AppendingLinkage:                return 2;
   case GlobalValue::InternalLinkage:                 return 3;
   case GlobalValue::LinkOnceAnyLinkage:              return 4;
-  case GlobalValue::DLLImportLinkage:                return 5;
-  case GlobalValue::DLLExportLinkage:                return 6;
   case GlobalValue::ExternalWeakLinkage:             return 7;
   case GlobalValue::CommonLinkage:                   return 8;
   case GlobalValue::PrivateLinkage:                  return 9;
@@ -504,6 +502,15 @@ static unsigned getEncodedVisibility(con
   llvm_unreachable("Invalid visibility");
 }
 
+static unsigned getEncodedDLLStorageClass(const GlobalValue *GV) {
+  switch (GV->getDLLStorageClass()) {
+  case GlobalValue::DefaultStorageClass:   return 0;
+  case GlobalValue::DLLImportStorageClass: return 1;
+  case GlobalValue::DLLExportStorageClass: return 2;
+  }
+  llvm_unreachable("Invalid DLL storage class");
+}
+
 static unsigned getEncodedThreadLocalMode(const GlobalVariable *GV) {
   switch (GV->getThreadLocalMode()) {
     case GlobalVariable::NotThreadLocal:         return 0;
@@ -607,7 +614,7 @@ static void WriteModuleInfo(const Module
 
     // GLOBALVAR: [type, isconst, initid,
     //             linkage, alignment, section, visibility, threadlocal,
-    //             unnamed_addr, externally_initialized]
+    //             unnamed_addr, externally_initialized, dllstorageclass]
     Vals.push_back(VE.getTypeID(GV->getType()));
     Vals.push_back(GV->isConstant());
     Vals.push_back(GV->isDeclaration() ? 0 :
@@ -617,11 +624,13 @@ static void WriteModuleInfo(const Module
     Vals.push_back(GV->hasSection() ? SectionMap[GV->getSection()] : 0);
     if (GV->isThreadLocal() ||
         GV->getVisibility() != GlobalValue::DefaultVisibility ||
-        GV->hasUnnamedAddr() || GV->isExternallyInitialized()) {
+        GV->hasUnnamedAddr() || GV->isExternallyInitialized() ||
+        GV->getDLLStorageClass() != GlobalValue::DefaultStorageClass) {
       Vals.push_back(getEncodedVisibility(GV));
       Vals.push_back(getEncodedThreadLocalMode(GV));
       Vals.push_back(GV->hasUnnamedAddr());
       Vals.push_back(GV->isExternallyInitialized());
+      Vals.push_back(getEncodedDLLStorageClass(GV));
     } else {
       AbbrevToUse = SimpleGVarAbbrev;
     }
@@ -646,6 +655,7 @@ static void WriteModuleInfo(const Module
     Vals.push_back(F->hasUnnamedAddr());
     Vals.push_back(F->hasPrefixData() ? (VE.getValueID(F->getPrefixData()) + 1)
                                       : 0);
+    Vals.push_back(getEncodedDLLStorageClass(F));
 
     unsigned AbbrevToUse = 0;
     Stream.EmitRecord(bitc::MODULE_CODE_FUNCTION, Vals, AbbrevToUse);
@@ -660,6 +670,7 @@ static void WriteModuleInfo(const Module
     Vals.push_back(VE.getValueID(AI->getAliasee()));
     Vals.push_back(getEncodedLinkage(AI));
     Vals.push_back(getEncodedVisibility(AI));
+    Vals.push_back(getEncodedDLLStorageClass(AI));
     unsigned AbbrevToUse = 0;
     Stream.EmitRecord(bitc::MODULE_CODE_ALIAS, Vals, AbbrevToUse);
     Vals.clear();

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp?rev=199204&r1=199203&r2=199204&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Tue Jan 14 05:55:03 2014
@@ -257,7 +257,6 @@ void AsmPrinter::EmitLinkage(const Globa
       OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Weak);
     }
     return;
-  case GlobalValue::DLLExportLinkage:
   case GlobalValue::AppendingLinkage:
     // FIXME: appending linkage variables should go into a section of
     // their name or something.  For now, just emit them as external.
@@ -272,7 +271,6 @@ void AsmPrinter::EmitLinkage(const Globa
     return;
   case GlobalValue::AvailableExternallyLinkage:
     llvm_unreachable("Should never emit this");
-  case GlobalValue::DLLImportLinkage:
   case GlobalValue::ExternalWeakLinkage:
     llvm_unreachable("Don't know how to emit these");
   }

Modified: llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp?rev=199204&r1=199203&r2=199204&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp Tue Jan 14 05:55:03 2014
@@ -1211,9 +1211,7 @@ void ExecutionEngine::emitGlobals() {
         }
 
         // If the existing global is strong, never replace it.
-        if (GVEntry->hasExternalLinkage() ||
-            GVEntry->hasDLLImportLinkage() ||
-            GVEntry->hasDLLExportLinkage())
+        if (GVEntry->hasExternalLinkage())
           continue;
 
         // Otherwise, we know it's linkonce/weak, replace it if this is a strong

Modified: llvm/trunk/lib/IR/AsmWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/AsmWriter.cpp?rev=199204&r1=199203&r2=199204&view=diff
==============================================================================
--- llvm/trunk/lib/IR/AsmWriter.cpp (original)
+++ llvm/trunk/lib/IR/AsmWriter.cpp Tue Jan 14 05:55:03 2014
@@ -1367,8 +1367,6 @@ static void PrintLinkage(GlobalValue::Li
   case GlobalValue::WeakODRLinkage:       Out << "weak_odr ";       break;
   case GlobalValue::CommonLinkage:        Out << "common ";         break;
   case GlobalValue::AppendingLinkage:     Out << "appending ";      break;
-  case GlobalValue::DLLImportLinkage:     Out << "dllimport ";      break;
-  case GlobalValue::DLLExportLinkage:     Out << "dllexport ";      break;
   case GlobalValue::ExternalWeakLinkage:  Out << "extern_weak ";    break;
   case GlobalValue::AvailableExternallyLinkage:
     Out << "available_externally ";
@@ -1386,6 +1384,15 @@ static void PrintVisibility(GlobalValue:
   }
 }
 
+static void PrintDLLStorageClass(GlobalValue::DLLStorageClassTypes SCT,
+                                 formatted_raw_ostream &Out) {
+  switch (SCT) {
+  case GlobalValue::DefaultStorageClass: break;
+  case GlobalValue::DLLImportStorageClass: Out << "dllimport "; break;
+  case GlobalValue::DLLExportStorageClass: Out << "dllexport "; break;
+  }
+}
+
 static void PrintThreadLocalModel(GlobalVariable::ThreadLocalMode TLM,
                                   formatted_raw_ostream &Out) {
   switch (TLM) {
@@ -1418,6 +1425,7 @@ void AssemblyWriter::printGlobal(const G
 
   PrintLinkage(GV->getLinkage(), Out);
   PrintVisibility(GV->getVisibility(), Out);
+  PrintDLLStorageClass(GV->getDLLStorageClass(), Out);
   PrintThreadLocalModel(GV->getThreadLocalMode(), Out);
 
   if (unsigned AddressSpace = GV->getType()->getAddressSpace())
@@ -1455,6 +1463,7 @@ void AssemblyWriter::printAlias(const Gl
     Out << " = ";
   }
   PrintVisibility(GA->getVisibility(), Out);
+  PrintDLLStorageClass(GA->getDLLStorageClass(), Out);
 
   Out << "alias ";
 
@@ -1552,6 +1561,7 @@ void AssemblyWriter::printFunction(const
 
   PrintLinkage(F->getLinkage(), Out);
   PrintVisibility(F->getVisibility(), Out);
+  PrintDLLStorageClass(F->getDLLStorageClass(), Out);
 
   // Print the calling convention.
   if (F->getCallingConv() != CallingConv::C) {

Modified: llvm/trunk/lib/IR/Core.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Core.cpp?rev=199204&r1=199203&r2=199204&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Core.cpp (original)
+++ llvm/trunk/lib/IR/Core.cpp Tue Jan 14 05:55:03 2014
@@ -1164,10 +1164,6 @@ LLVMLinkage LLVMGetLinkage(LLVMValueRef
     return LLVMLinkerPrivateLinkage;
   case GlobalValue::LinkerPrivateWeakLinkage:
     return LLVMLinkerPrivateWeakLinkage;
-  case GlobalValue::DLLImportLinkage:
-    return LLVMDLLImportLinkage;
-  case GlobalValue::DLLExportLinkage:
-    return LLVMDLLExportLinkage;
   case GlobalValue::ExternalWeakLinkage:
     return LLVMExternalWeakLinkage;
   case GlobalValue::CommonLinkage:
@@ -1219,10 +1215,12 @@ void LLVMSetLinkage(LLVMValueRef Global,
     GV->setLinkage(GlobalValue::LinkerPrivateWeakLinkage);
     break;
   case LLVMDLLImportLinkage:
-    GV->setLinkage(GlobalValue::DLLImportLinkage);
+    DEBUG(errs()
+          << "LLVMSetLinkage(): LLVMDLLImportLinkage is no longer supported.");
     break;
   case LLVMDLLExportLinkage:
-    GV->setLinkage(GlobalValue::DLLExportLinkage);
+    DEBUG(errs()
+          << "LLVMSetLinkage(): LLVMDLLExportLinkage is no longer supported.");
     break;
   case LLVMExternalWeakLinkage:
     GV->setLinkage(GlobalValue::ExternalWeakLinkage);

Modified: llvm/trunk/lib/IR/Verifier.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Verifier.cpp?rev=199204&r1=199203&r2=199204&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Verifier.cpp (original)
+++ llvm/trunk/lib/IR/Verifier.cpp Tue Jan 14 05:55:03 2014
@@ -421,16 +421,12 @@ void Verifier::visitGlobalValue(GlobalVa
   Assert1(!GV.isDeclaration() ||
           GV.isMaterializable() ||
           GV.hasExternalLinkage() ||
-          GV.hasDLLImportLinkage() ||
           GV.hasExternalWeakLinkage() ||
           (isa<GlobalAlias>(GV) &&
            (GV.hasLocalLinkage() || GV.hasWeakLinkage())),
-  "Global is external, but doesn't have external or dllimport or weak linkage!",
+          "Global is external, but doesn't have external or weak linkage!",
           &GV);
 
-  Assert1(!GV.hasDLLImportLinkage() || GV.isDeclaration(),
-          "Global is marked as dllimport, but not external", &GV);
-
   Assert1(!GV.hasAppendingLinkage() || isa<GlobalVariable>(GV),
           "Only global variables can have appending linkage!", &GV);
 
@@ -456,8 +452,7 @@ void Verifier::visitGlobalVariable(Globa
               &GV);
     }
   } else {
-    Assert1(GV.hasExternalLinkage() || GV.hasDLLImportLinkage() ||
-            GV.hasExternalWeakLinkage(),
+    Assert1(GV.hasExternalLinkage() || GV.hasExternalWeakLinkage(),
             "invalid linkage type for global declaration", &GV);
   }
 
@@ -502,6 +497,11 @@ void Verifier::visitGlobalVariable(Globa
     }
   }
 
+  Assert1(!GV.hasDLLImportStorageClass() ||
+          (GV.isDeclaration() && GV.hasExternalLinkage()) ||
+          GV.hasAvailableExternallyLinkage(),
+          "Global is marked as dllimport, but not external", &GV);
+
   if (!GV.hasInitializer()) {
     visitGlobalValue(GV);
     return;
@@ -1078,8 +1078,7 @@ void Verifier::visitFunction(Function &F
   if (F.isMaterializable()) {
     // Function has a body somewhere we can't see.
   } else if (F.isDeclaration()) {
-    Assert1(F.hasExternalLinkage() || F.hasDLLImportLinkage() ||
-            F.hasExternalWeakLinkage(),
+    Assert1(F.hasExternalLinkage() || F.hasExternalWeakLinkage(),
             "invalid linkage type for function declaration", &F);
   } else {
     // Verify that this function (which has a body) is not named "llvm.*".  It
@@ -1105,6 +1104,11 @@ void Verifier::visitFunction(Function &F
     if (F.hasAddressTaken(&U))
       Assert1(0, "Invalid user of intrinsic instruction!", U);
   }
+
+  Assert1(!F.hasDLLImportStorageClass() ||
+          (F.isDeclaration() && F.hasExternalLinkage()) ||
+          F.hasAvailableExternallyLinkage(),
+          "Function is marked as dllimport, but not external.", &F);
 }
 
 // verifyBasicBlock - Verify that a basic block is well formed...

Modified: llvm/trunk/lib/Linker/LinkModules.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Linker/LinkModules.cpp?rev=199204&r1=199203&r2=199204&view=diff
==============================================================================
--- llvm/trunk/lib/Linker/LinkModules.cpp (original)
+++ llvm/trunk/lib/Linker/LinkModules.cpp Tue Jan 14 05:55:03 2014
@@ -543,8 +543,8 @@ bool ModuleLinker::getLinkageResult(Glob
   if (SrcIsDeclaration) {
     // If Src is external or if both Src & Dest are external..  Just link the
     // external globals, we aren't adding anything.
-    if (Src->hasDLLImportLinkage()) {
-      // If one of GVs has DLLImport linkage, result should be dllimport'ed.
+    if (Src->hasDLLImportStorageClass()) {
+      // If one of GVs is marked as DLLImport, result should be dllimport'ed.
       if (DestIsDeclaration) {
         LinkFromSrc = true;
         LT = Src->getLinkage();
@@ -557,7 +557,7 @@ bool ModuleLinker::getLinkageResult(Glob
       LinkFromSrc = false;
       LT = Dest->getLinkage();
     }
-  } else if (DestIsDeclaration && !Dest->hasDLLImportLinkage()) {
+  } else if (DestIsDeclaration && !Dest->hasDLLImportStorageClass()) {
     // If Dest is external but Src is not:
     LinkFromSrc = true;
     LT = Src->getLinkage();
@@ -584,10 +584,8 @@ bool ModuleLinker::getLinkageResult(Glob
       LT = GlobalValue::ExternalLinkage;
     }
   } else {
-    assert((Dest->hasExternalLinkage()  || Dest->hasDLLImportLinkage() ||
-            Dest->hasDLLExportLinkage() || Dest->hasExternalWeakLinkage()) &&
-           (Src->hasExternalLinkage()   || Src->hasDLLImportLinkage() ||
-            Src->hasDLLExportLinkage()  || Src->hasExternalWeakLinkage()) &&
+    assert((Dest->hasExternalLinkage()  || Dest->hasExternalWeakLinkage()) &&
+           (Src->hasExternalLinkage()   || Src->hasExternalWeakLinkage()) &&
            "Unexpected linkage type!");
     return emitError("Linking globals named '" + Src->getName() +
                  "': symbol multiply defined!");

Modified: llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp?rev=199204&r1=199203&r2=199204&view=diff
==============================================================================
--- llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp (original)
+++ llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp Tue Jan 14 05:55:03 2014
@@ -131,6 +131,7 @@ namespace {
   private:
     void printLinkageType(GlobalValue::LinkageTypes LT);
     void printVisibilityType(GlobalValue::VisibilityTypes VisTypes);
+    void printDLLStorageClassType(GlobalValue::DLLStorageClassTypes DSCType);
     void printThreadLocalMode(GlobalVariable::ThreadLocalMode TLM);
     void printCallingConv(CallingConv::ID cc);
     void printEscapedString(const std::string& str);
@@ -300,10 +301,6 @@ void CppWriter::printLinkageType(GlobalV
     Out << "GlobalValue::AppendingLinkage"; break;
   case GlobalValue::ExternalLinkage:
     Out << "GlobalValue::ExternalLinkage"; break;
-  case GlobalValue::DLLImportLinkage:
-    Out << "GlobalValue::DLLImportLinkage"; break;
-  case GlobalValue::DLLExportLinkage:
-    Out << "GlobalValue::DLLExportLinkage"; break;
   case GlobalValue::ExternalWeakLinkage:
     Out << "GlobalValue::ExternalWeakLinkage"; break;
   case GlobalValue::CommonLinkage:
@@ -325,6 +322,21 @@ void CppWriter::printVisibilityType(Glob
   }
 }
 
+void CppWriter::printDLLStorageClassType(
+                                    GlobalValue::DLLStorageClassTypes DSCType) {
+  switch (DSCType) {
+  case GlobalValue::DefaultStorageClass:
+    Out << "GlobalValue::DefaultStorageClass";
+    break;
+  case GlobalValue::DLLImportStorageClass:
+    Out << "GlobalValue::DLLImportStorageClass";
+    break;
+  case GlobalValue::DLLExportStorageClass:
+    Out << "GlobalValue::DLLExportStorageClass";
+    break;
+  }
+}
+
 void CppWriter::printThreadLocalMode(GlobalVariable::ThreadLocalMode TLM) {
   switch (TLM) {
     case GlobalVariable::NotThreadLocal:
@@ -1028,6 +1040,13 @@ void CppWriter::printVariableHead(const
     Out << ");";
     nl(Out);
   }
+  if (GV->getDLLStorageClass() != GlobalValue::DefaultStorageClass) {
+    printCppName(GV);
+    Out << "->setDLLStorageClass(";
+    printDLLStorageClassType(GV->getDLLStorageClass());
+    Out << ");";
+    nl(Out);
+  }
   if (GV->isThreadLocal()) {
     printCppName(GV);
     Out << "->setThreadLocalMode(";
@@ -1746,6 +1765,13 @@ void CppWriter::printFunctionHead(const
     Out << ");";
     nl(Out);
   }
+  if (F->getDLLStorageClass() != GlobalValue::DefaultStorageClass) {
+    printCppName(F);
+    Out << "->setDLLStorageClass(";
+    printDLLStorageClassType(F->getDLLStorageClass());
+    Out << ");";
+    nl(Out);
+  }
   if (F->hasGC()) {
     printCppName(F);
     Out << "->setGC(\"" << F->getGC() << "\");";

Modified: llvm/trunk/lib/Target/X86/X86AsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86AsmPrinter.cpp?rev=199204&r1=199203&r2=199204&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86AsmPrinter.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86AsmPrinter.cpp Tue Jan 14 05:55:03 2014
@@ -649,20 +649,20 @@ void X86AsmPrinter::EmitEndOfAsmFile(Mod
     // Necessary for dllexport support
     std::vector<const MCSymbol*> DLLExportedFns, DLLExportedGlobals;
 
-    const TargetLoweringObjectFileCOFF &TLOFCOFF =
-      static_cast<const TargetLoweringObjectFileCOFF&>(getObjFileLowering());
-
     for (Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I)
-      if (I->hasDLLExportLinkage())
+      if (I->hasDLLExportStorageClass())
         DLLExportedFns.push_back(getSymbol(I));
 
     for (Module::const_global_iterator I = M.global_begin(),
            E = M.global_end(); I != E; ++I)
-      if (I->hasDLLExportLinkage())
+      if (I->hasDLLExportStorageClass())
         DLLExportedGlobals.push_back(getSymbol(I));
 
     // Output linker support code for dllexported globals on windows.
     if (!DLLExportedGlobals.empty() || !DLLExportedFns.empty()) {
+      const TargetLoweringObjectFileCOFF &TLOFCOFF =
+        static_cast<const TargetLoweringObjectFileCOFF&>(getObjFileLowering());
+
       OutStreamer.SwitchSection(TLOFCOFF.getDrectveSection());
       SmallString<128> name;
       for (unsigned i = 0, e = DLLExportedGlobals.size(); i != e; ++i) {

Modified: llvm/trunk/lib/Target/X86/X86FastISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FastISel.cpp?rev=199204&r1=199203&r2=199204&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86FastISel.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86FastISel.cpp Tue Jan 14 05:55:03 2014
@@ -697,7 +697,7 @@ bool X86FastISel::X86SelectCallAddress(c
       return false;
 
     // Can't handle DLLImport.
-    if (GV->hasDLLImportLinkage())
+    if (GV->hasDLLImportStorageClass())
       return false;
 
     // Can't handle TLS.

Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=199204&r1=199203&r2=199204&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Tue Jan 14 05:55:03 2014
@@ -2796,7 +2796,7 @@ X86TargetLowering::LowerCall(TargetLower
     // We should use extra load for direct calls to dllimported functions in
     // non-JIT mode.
     const GlobalValue *GV = G->getGlobal();
-    if (!GV->hasDLLImportLinkage()) {
+    if (!GV->hasDLLImportStorageClass()) {
       unsigned char OpFlags = 0;
       bool ExtraLoad = false;
       unsigned WrapperKind = ISD::DELETED_NODE;

Modified: llvm/trunk/lib/Target/X86/X86Subtarget.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Subtarget.cpp?rev=199204&r1=199203&r2=199204&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86Subtarget.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86Subtarget.cpp Tue Jan 14 05:55:03 2014
@@ -55,7 +55,7 @@ unsigned char X86Subtarget::
 ClassifyGlobalReference(const GlobalValue *GV, const TargetMachine &TM) const {
   // DLLImport only exists on windows, it is implemented as a load from a
   // DLLIMPORT stub.
-  if (GV->hasDLLImportLinkage())
+  if (GV->hasDLLImportStorageClass())
     return X86II::MO_DLLIMPORT;
 
   // Determine whether this is a reference to a definition or a declaration.

Modified: llvm/trunk/lib/Target/XCore/XCoreAsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/XCore/XCoreAsmPrinter.cpp?rev=199204&r1=199203&r2=199204&view=diff
==============================================================================
--- llvm/trunk/lib/Target/XCore/XCoreAsmPrinter.cpp (original)
+++ llvm/trunk/lib/Target/XCore/XCoreAsmPrinter.cpp Tue Jan 14 05:55:03 2014
@@ -135,10 +135,6 @@ void XCoreAsmPrinter::EmitGlobalVariable
   case GlobalValue::InternalLinkage:
   case GlobalValue::PrivateLinkage:
     break;
-  case GlobalValue::DLLImportLinkage:
-    llvm_unreachable("DLLImport linkage is not supported by this target!");
-  case GlobalValue::DLLExportLinkage:
-    llvm_unreachable("DLLExport linkage is not supported by this target!");
   default:
     llvm_unreachable("Unknown linkage type!");
   }

Modified: llvm/trunk/lib/Transforms/IPO/Internalize.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/Internalize.cpp?rev=199204&r1=199203&r2=199204&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/Internalize.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/Internalize.cpp Tue Jan 14 05:55:03 2014
@@ -116,7 +116,7 @@ static bool shouldInternalize(const Glob
     return false;
 
   // Assume that dllexported symbols are referenced elsewhere
-  if (GV.hasDLLExportLinkage())
+  if (GV.hasDLLExportStorageClass())
     return false;
 
   // Already has internal linkage

Modified: llvm/trunk/test/Bitcode/linkage-types-3.2.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Bitcode/linkage-types-3.2.ll?rev=199204&r1=199203&r2=199204&view=diff
==============================================================================
--- llvm/trunk/test/Bitcode/linkage-types-3.2.ll (original)
+++ llvm/trunk/test/Bitcode/linkage-types-3.2.ll Tue Jan 14 05:55:03 2014
@@ -50,7 +50,7 @@
 ; CHECK: @dllexport.var = dllexport global i32 0
 
 @dllimport.var = dllimport global i32
-; CHECK: @dllimport.var = dllimport global i32
+; CHECK: @dllimport.var = external dllimport global i32
 
 define private void @private()
 ; CHECK: define private void @private

Removed: llvm/trunk/test/CodeGen/X86/dll-linkage.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/dll-linkage.ll?rev=199203&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/dll-linkage.ll (original)
+++ llvm/trunk/test/CodeGen/X86/dll-linkage.ll (removed)
@@ -1,14 +0,0 @@
-; RUN: llc < %s -mtriple=i386-pc-mingw32 | FileCheck %s
-
-; RUN: llc < %s -mtriple=i386-pc-mingw32 -O0 | FileCheck %s -check-prefix=FAST
-; PR6275
-
-declare dllimport void @foo()
-
-define void @bar() nounwind {
-; CHECK: calll	*__imp__foo
-; FAST:  movl   __imp__foo, [[R:%[a-z]{3}]]
-; FAST:  calll  *[[R]]
-  call void @foo()
-  ret void
-}

Added: llvm/trunk/test/CodeGen/X86/dllexport-x86_64.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/dllexport-x86_64.ll?rev=199204&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/dllexport-x86_64.ll (added)
+++ llvm/trunk/test/CodeGen/X86/dllexport-x86_64.ll Tue Jan 14 05:55:03 2014
@@ -0,0 +1,79 @@
+; RUN: llc -mtriple x86_64-pc-win32 < %s | FileCheck -check-prefix=CHECK -check-prefix=WIN32 %s
+; RUN: llc -mtriple x86_64-pc-mingw32 < %s | FileCheck -check-prefix=CHECK -check-prefix=MINGW %s
+
+; CHECK: .text
+
+define void @notExported() {
+	ret void
+}
+
+; CHECK: .globl f1
+define dllexport void @f1() {
+	ret void
+}
+
+; CHECK: .globl f2
+define dllexport void @f2() unnamed_addr {
+	ret void
+}
+
+; CHECK: .section .text,"xr",discard,lnk1
+; CHECK: .globl lnk1
+define linkonce_odr dllexport void @lnk1() {
+	ret void
+}
+
+; CHECK: .section .text,"xr",discard,lnk2
+; CHECK: .globl lnk2
+define linkonce_odr dllexport void @lnk2() alwaysinline {
+	ret void
+}
+
+; CHECK: .section .text,"xr",discard,weak1
+; CHECK: .globl weak1
+define weak_odr dllexport void @weak1() {
+	ret void
+}
+
+
+; CHECK: .data
+; CHECK: .globl Var1
+ at Var1 = dllexport global i32 1, align 4
+
+; CHECK: .rdata,"r"
+; CHECK: .globl Var2
+ at Var2 = dllexport unnamed_addr constant i32 1
+
+; CHECK: .comm Var3
+ at Var3 = common dllexport global i32 0, align 4
+
+; CHECK: .section .data,"w",discard,WeakVar1
+; CHECK: .globl WeakVar1
+ at WeakVar1 = weak_odr dllexport global i32 1, align 4
+
+; CHECK: .section .rdata,"r",discard,WeakVar2
+; CHECK: .globl WeakVar2
+ at WeakVar2 = weak_odr dllexport unnamed_addr constant i32 1
+
+
+; CHECK: .section .drectve
+; WIN32: /EXPORT:Var1,DATA
+; WIN32: /EXPORT:Var2,DATA
+; WIN32: /EXPORT:Var3,DATA
+; WIN32: /EXPORT:WeakVar1,DATA
+; WIN32: /EXPORT:WeakVar2,DATA
+; WIN32: /EXPORT:f1
+; WIN32: /EXPORT:f2
+; WIN32: /EXPORT:lnk1
+; WIN32: /EXPORT:lnk2
+; WIN32: /EXPORT:weak1
+; MINGW: -export:Var1,data
+; MINGW: -export:Var2,data
+; MINGW: -export:Var3,data
+; MINGW: -export:WeakVar1,data
+; MINGW: -export:WeakVar2,data
+; MINGW: -export:f1
+; MINGW: -export:f2
+; MINGW: -export:lnk1
+; MINGW: -export:lnk2
+; MINGW: -export:weak1

Modified: llvm/trunk/test/CodeGen/X86/dllexport.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/dllexport.ll?rev=199204&r1=199203&r2=199204&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/dllexport.ll (original)
+++ llvm/trunk/test/CodeGen/X86/dllexport.ll Tue Jan 14 05:55:03 2014
@@ -1,12 +1,100 @@
-; RUN: llc < %s | FileCheck %s
-; PR2936
+; RUN: llc -mtriple i386-pc-win32 < %s | FileCheck -check-prefix=CHECK -check-prefix=WIN32 %s
+; RUN: llc -mtriple i386-pc-mingw32 < %s | FileCheck -check-prefix=CHECK -check-prefix=MINGW %s
 
-target triple = "i386-pc-mingw32"
+; CHECK: .text
 
-define dllexport x86_fastcallcc i32 @foo() nounwind  {
-entry:
+define void @notExported() {
+	ret void
+}
+
+; CHECK: .globl _f1
+define dllexport void @f1() {
+	ret void
+}
+
+; CHECK: .globl _f2
+define dllexport void @f2() unnamed_addr {
+	ret void
+}
+
+; CHECK: .globl _stdfun at 0
+define dllexport x86_stdcallcc void @stdfun() nounwind {
+	ret void
+}
+
+; CHECK: .globl @fastfun at 0
+define dllexport x86_fastcallcc i32 @fastfun() nounwind {
 	ret i32 0
 }
 
+; CHECK: .globl _thisfun
+define dllexport x86_thiscallcc void @thisfun() nounwind {
+	ret void
+}
+
+; CHECK: .section .text,"xr",discard,_lnk1
+; CHECK: .globl _lnk1
+define linkonce_odr dllexport void @lnk1() {
+	ret void
+}
+
+; CHECK: .section .text,"xr",discard,_lnk2
+; CHECK: .globl _lnk2
+define linkonce_odr dllexport void @lnk2() alwaysinline {
+	ret void
+}
+
+; CHECK: .section .text,"xr",discard,_weak1
+; CHECK: .globl _weak1
+define weak_odr dllexport void @weak1() {
+	ret void
+}
+
+
+; CHECK: .data
+; CHECK: .globl _Var1
+ at Var1 = dllexport global i32 1, align 4
+
+; CHECK: .rdata,"r"
+; CHECK: .globl _Var2
+ at Var2 = dllexport unnamed_addr constant i32 1
+
+; CHECK: .comm _Var3
+ at Var3 = common dllexport global i32 0, align 4
+
+; CHECK: .section .data,"w",discard,_WeakVar1
+; CHECK: .globl _WeakVar1
+ at WeakVar1 = weak_odr dllexport global i32 1, align 4
+
+; CHECK: .section .rdata,"r",discard,_WeakVar2
+; CHECK: .globl _WeakVar2
+ at WeakVar2 = weak_odr dllexport unnamed_addr constant i32 1
+
+
 ; CHECK: .section .drectve
-; CHECK: -export:@foo at 0
+; WIN32: /EXPORT:_Var1,DATA
+; WIN32: /EXPORT:_Var2,DATA
+; WIN32: /EXPORT:_Var3,DATA
+; WIN32: /EXPORT:_WeakVar1,DATA
+; WIN32: /EXPORT:_WeakVar2,DATA
+; WIN32: /EXPORT:_f1
+; WIN32: /EXPORT:_f2
+; WIN32: /EXPORT:_stdfun at 0
+; WIN32: /EXPORT:@fastfun at 0
+; WIN32: /EXPORT:_thisfun
+; WIN32: /EXPORT:_lnk1
+; WIN32: /EXPORT:_lnk2
+; WIN32: /EXPORT:_weak1
+; MINGW: -export:_Var1,data
+; MINGW: -export:_Var2,data
+; MINGW: -export:_Var3,data
+; MINGW: -export:_WeakVar1,data
+; MINGW: -export:_WeakVar2,data
+; MINGW: -export:_f1
+; MINGW: -export:_f2
+; MINGW: -export:_stdfun at 0
+; MINGW: -export:@fastfun at 0
+; MINGW: -export:_thisfun
+; MINGW: -export:_lnk1
+; MINGW: -export:_lnk2
+; MINGW: -export:_weak1

Added: llvm/trunk/test/CodeGen/X86/dllimport-x86_64.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/dllimport-x86_64.ll?rev=199204&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/dllimport-x86_64.ll (added)
+++ llvm/trunk/test/CodeGen/X86/dllimport-x86_64.ll Tue Jan 14 05:55:03 2014
@@ -0,0 +1,48 @@
+; RUN: llc -mtriple x86_64-pc-win32 < %s | FileCheck %s
+; RUN: llc -mtriple x86_64-pc-mingw32 < %s | FileCheck %s
+;
+; RUN: llc -mtriple x86_64-pc-mingw32 -O0 < %s | FileCheck %s -check-prefix=FAST
+; PR6275
+;
+; RUN: opt -mtriple x86_64-pc-win32 -std-compile-opts -S < %s | FileCheck %s -check-prefix=OPT
+
+ at Var1 = external dllimport global i32
+ at Var2 = available_externally dllimport unnamed_addr constant i32 1
+
+declare dllimport void @fun()
+
+define available_externally dllimport void @inline1() {
+	ret void
+}
+
+define available_externally dllimport void @inline2() {
+	ret void
+}
+
+declare void @dummy(...)
+
+define void @use() nounwind {
+; CHECK:     callq *__imp_fun(%rip)
+; FAST:      movq  __imp_fun(%rip), [[R:%[a-z]{3}]]
+; FAST-NEXT: callq *[[R]]
+  call void @fun()
+
+; CHECK: callq *__imp_inline1(%rip)
+; CHECK: callq *__imp_inline2(%rip)
+  call void @inline1()
+  call void @inline2()
+
+; available_externally uses go away
+; OPT-NOT: call void @inline1()
+; OPT-NOT: call void @inline2()
+; OPT-NOT: load i32* @Var2
+; OPT: call void (...)* @dummy(i32 %1, i32 1)
+
+; CHECK-DAG: movq __imp_Var1(%rip), [[R1:%[a-z]{3}]]
+; CHECK-DAG: movq __imp_Var2(%rip), [[R2:%[a-z]{3}]]
+  %1 = load i32* @Var1
+  %2 = load i32* @Var2
+  call void(...)* @dummy(i32 %1, i32 %2)
+
+  ret void
+}

Added: llvm/trunk/test/CodeGen/X86/dllimport.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/dllimport.ll?rev=199204&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/dllimport.ll (added)
+++ llvm/trunk/test/CodeGen/X86/dllimport.ll Tue Jan 14 05:55:03 2014
@@ -0,0 +1,59 @@
+; RUN: llc -mtriple i386-pc-win32 < %s | FileCheck %s
+; RUN: llc -mtriple i386-pc-mingw32 < %s | FileCheck %s
+;
+; RUN: llc -mtriple i386-pc-mingw32 -O0 < %s | FileCheck %s -check-prefix=FAST
+; PR6275
+;
+; RUN: opt -mtriple i386-pc-win32 -std-compile-opts -S < %s | FileCheck %s -check-prefix=OPT
+
+ at Var1 = external dllimport global i32
+ at Var2 = available_externally dllimport unnamed_addr constant i32 1
+
+declare dllimport void @fun()
+
+define available_externally dllimport void @inline1() {
+	ret void
+}
+
+define available_externally dllimport void @inline2() alwaysinline {
+	ret void
+}
+
+declare dllimport x86_stdcallcc void @stdfun() nounwind
+declare dllimport x86_fastcallcc void @fastfun() nounwind
+declare dllimport x86_thiscallcc void @thisfun() nounwind
+
+declare void @dummy(...)
+
+define void @use() nounwind {
+; CHECK:     calll *__imp__fun
+; FAST:      movl  __imp__fun, [[R:%[a-z]{3}]]
+; FAST-NEXT: calll *[[R]]
+  call void @fun()
+
+; CHECK: calll *__imp__inline1
+; CHECK: calll *__imp__inline2
+  call void @inline1()
+  call void @inline2()
+
+; CHECK: calll *__imp__stdfun at 0
+; CHECK: calll *__imp_ at fastfun@0
+; CHECK: calll *__imp__thisfun
+  call void @stdfun()
+  call void @fastfun()
+  call void @thisfun()
+
+; available_externally uses go away
+; OPT-NOT: call void @inline1()
+; OPT-NOT: call void @inline2()
+; OPT-NOT: load i32* @Var2
+; OPT: call void (...)* @dummy(i32 %1, i32 1)
+
+; CHECK-DAG: movl __imp__Var1, [[R1:%[a-z]{3}]]
+; CHECK-DAG: movl __imp__Var2, [[R2:%[a-z]{3}]]
+  %1 = load i32* @Var1
+  %2 = load i32* @Var2
+  call void(...)* @dummy(i32 %1, i32 %2)
+
+  ret void
+}





More information about the llvm-commits mailing list