From: Nico Rieck Date: Tue, 14 Jan 2014 12:38:32 +0000 (+0000) Subject: Revert "Decouple dllexport/dllimport from linkage" X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=55463f4ec19618207dcf07016ad6aa1def429dc4;p=oota-llvm.git Revert "Decouple dllexport/dllimport from linkage" Revert this for now until I fix an issue in Clang with it. This reverts commit r199204. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@199207 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/docs/BitCodeFormat.rst b/docs/BitCodeFormat.rst index 9363a62d080..89531dcfea6 100644 --- a/docs/BitCodeFormat.rst +++ b/docs/BitCodeFormat.rst @@ -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, dllstorageclass]`` +``[GLOBALVAR, pointer type, isconst, initid, linkage, alignment, section, visibility, threadlocal, unnamed_addr]`` The ``GLOBALVAR`` record (code 7) marks the declaration or definition of a global variable. The operand fields are: @@ -713,20 +713,12 @@ 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, dllstorageclass]`` +``[FUNCTION, type, callingconv, isproto, linkage, paramattr, alignment, section, visibility, gc, prefix]`` The ``FUNCTION`` record (code 8) marks the declaration or definition of a function. The operand fields are: @@ -770,12 +762,10 @@ 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, dllstorageclass]`` +``[ALIAS, alias type, aliasee val#, linkage, visibility]`` The ``ALIAS`` record (code 9) marks the definition of an alias. The operand fields are @@ -788,8 +778,6 @@ 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 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/docs/LangRef.rst b/docs/LangRef.rst index 3540bdec8ac..ffe3f09d83b 100644 --- a/docs/LangRef.rst +++ b/docs/LangRef.rst @@ -274,8 +274,27 @@ 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`` or ``extern_weak``. +other than ``external``, ``dllimport`` or ``extern_weak``. .. _callingconv: @@ -397,25 +416,6 @@ 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,15 +529,6 @@ assume that the globals are densely packed in their section and try to iterate over them as an array, alignment padding would break this iteration. -Globals can also have a :ref:`DLL storage class `. - -Syntax:: - - [@ =] [Linkage] [Visibility] [DLLStorageClass] [ThreadLocal] - [AddrSpace] [unnamed_addr] [ExternallyInitialized] - - [, section "name"] [, align ] - For example, the following defines a global in a numbered address space with an initializer, section, and alignment: @@ -565,8 +556,7 @@ Functions LLVM function definitions consist of the "``define``" keyword, an optional :ref:`linkage type `, an optional :ref:`visibility -style `, an optional :ref:`DLL storage class `, -an optional :ref:`calling convention `, +style `, an optional :ref:`calling convention `, an optional ``unnamed_addr`` attribute, a return type, an optional :ref:`parameter attribute ` for the return type, a function name, a (possibly empty) argument list (each with optional :ref:`parameter @@ -577,8 +567,7 @@ curly brace, a list of basic blocks, and a closing curly brace. LLVM function declarations consist of the "``declare``" keyword, an optional :ref:`linkage type `, an optional :ref:`visibility -style `, an optional :ref:`DLL storage class `, -an optional :ref:`calling convention `, +style `, an optional :ref:`calling convention `, an optional ``unnamed_addr`` attribute, a return type, an optional :ref:`parameter attribute ` for the return type, a function name, a possibly empty list of arguments, an optional alignment, an optional @@ -614,7 +603,7 @@ be significant and two identical functions can be merged. Syntax:: - define [linkage] [visibility] [DLLStorageClass] + define [linkage] [visibility] [cconv] [ret attrs] @ ([argument list]) [fn Attrs] [section "name"] [align N] @@ -627,13 +616,12 @@ 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 `, an optional -:ref:`visibility style `, and an optional :ref:`DLL storage class -`. +Aliases may have an optional :ref:`linkage type `, and an optional +:ref:`visibility style `. Syntax:: - @ = [Visibility] [DLLStorageClass] alias [Linkage] @ + @ = alias [Linkage] [Visibility] @ The linkage must be one of ``private``, ``linker_private``, ``linker_private_weak``, ``internal``, ``linkonce``, ``weak``, diff --git a/include/llvm-c/Core.h b/include/llvm-c/Core.h index a84a0313211..269869ef0da 100644 --- a/include/llvm-c/Core.h +++ b/include/llvm-c/Core.h @@ -284,8 +284,8 @@ typedef enum { LLVMInternalLinkage, /**< Rename collisions when linking (static functions) */ LLVMPrivateLinkage, /**< Like Internal, but omit from symbol table */ - LLVMDLLImportLinkage, /**< Obsolete */ - LLVMDLLExportLinkage, /**< Obsolete */ + LLVMDLLImportLinkage, /**< Function to be imported from DLL */ + LLVMDLLExportLinkage, /**< Function to be accessible from DLL */ LLVMExternalWeakLinkage,/**< ExternalWeak linkage description */ LLVMGhostLinkage, /**< Obsolete */ LLVMCommonLinkage, /**< Tentative definitions */ diff --git a/include/llvm/IR/GlobalValue.h b/include/llvm/IR/GlobalValue.h index 5fdf6611e9a..4f20a31a294 100644 --- a/include/llvm/IR/GlobalValue.h +++ b/include/llvm/IR/GlobalValue.h @@ -42,6 +42,8 @@ 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. }; @@ -53,19 +55,11 @@ 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), - DllStorageClass(DefaultStorageClass), Parent(0) { + Visibility(DefaultVisibility), Alignment(0), UnnamedAddr(0), Parent(0) { setName(Name); } @@ -75,7 +69,6 @@ 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: @@ -98,18 +91,7 @@ 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; } @@ -164,6 +146,12 @@ 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; } @@ -221,6 +209,8 @@ 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); } diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index d4d6f7cee14..a5b2aa586e4 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -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 OptionalDLLStorageClass - // OptionalThreadLocal OptionalAddrSpace OptionalUnNammedAddr + // GlobalVar ::= OptionalLinkage OptionalVisibility 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, DLLStorageClass; + unsigned Linkage, Visibility; if (ParseOptionalLinkage(Linkage) || ParseOptionalVisibility(Visibility) || - ParseOptionalDLLStorageClass(DLLStorageClass) || - ParseGlobal("", SMLoc(), Linkage, true, Visibility, DLLStorageClass)) + ParseGlobal("", SMLoc(), Linkage, true, Visibility)) return true; break; } case lltok::kw_default: // OptionalVisibility case lltok::kw_hidden: // OptionalVisibility case lltok::kw_protected: { // OptionalVisibility - unsigned Visibility, DLLStorageClass; + unsigned Visibility; if (ParseOptionalVisibility(Visibility) || - ParseOptionalDLLStorageClass(DLLStorageClass) || - ParseGlobal("", SMLoc(), 0, false, Visibility, DLLStorageClass)) + ParseGlobal("", SMLoc(), 0, false, Visibility)) 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, 0)) return true; + if (ParseGlobal("", SMLoc(), 0, false, 0)) return true; break; case lltok::kw_attributes: if (ParseUnnamedAttrGrp()) return true; break; @@ -446,11 +446,9 @@ bool LLParser::ParseGlobalType(bool &IsConstant) { /// ParseUnnamedGlobal: /// OptionalVisibility ALIAS ... -/// OptionalLinkage OptionalVisibility OptionalDLLStorageClass -/// ... -> global variable +/// OptionalLinkage OptionalVisibility ... -> global variable /// GlobalID '=' OptionalVisibility ALIAS ... -/// GlobalID '=' OptionalLinkage OptionalVisibility OptionalDLLStorageClass -/// ... -> global variable +/// GlobalID '=' OptionalLinkage OptionalVisibility ... -> global variable bool LLParser::ParseUnnamedGlobal() { unsigned VarID = NumberedVals.size(); std::string Name; @@ -468,22 +466,19 @@ bool LLParser::ParseUnnamedGlobal() { } bool HasLinkage; - unsigned Linkage, Visibility, DLLStorageClass; + unsigned Linkage, Visibility; if (ParseOptionalLinkage(Linkage, HasLinkage) || - ParseOptionalVisibility(Visibility) || - ParseOptionalDLLStorageClass(DLLStorageClass)) + ParseOptionalVisibility(Visibility)) return true; if (HasLinkage || Lex.getKind() != lltok::kw_alias) - return ParseGlobal(Name, NameLoc, Linkage, HasLinkage, Visibility, - DLLStorageClass); - return ParseAlias(Name, NameLoc, Visibility, DLLStorageClass); + return ParseGlobal(Name, NameLoc, Linkage, HasLinkage, Visibility); + return ParseAlias(Name, NameLoc, Visibility); } /// ParseNamedGlobal: /// GlobalVar '=' OptionalVisibility ALIAS ... -/// GlobalVar '=' OptionalLinkage OptionalVisibility OptionalDLLStorageClass -/// ... -> global variable +/// GlobalVar '=' OptionalLinkage OptionalVisibility ... -> global variable bool LLParser::ParseNamedGlobal() { assert(Lex.getKind() == lltok::GlobalVar); LocTy NameLoc = Lex.getLoc(); @@ -491,17 +486,15 @@ bool LLParser::ParseNamedGlobal() { Lex.Lex(); bool HasLinkage; - unsigned Linkage, Visibility, DLLStorageClass; + unsigned Linkage, Visibility; if (ParseToken(lltok::equal, "expected '=' in global variable") || ParseOptionalLinkage(Linkage, HasLinkage) || - ParseOptionalVisibility(Visibility) || - ParseOptionalDLLStorageClass(DLLStorageClass)) + ParseOptionalVisibility(Visibility)) return true; if (HasLinkage || Lex.getKind() != lltok::kw_alias) - return ParseGlobal(Name, NameLoc, Linkage, HasLinkage, Visibility, - DLLStorageClass); - return ParseAlias(Name, NameLoc, Visibility, DLLStorageClass); + return ParseGlobal(Name, NameLoc, Linkage, HasLinkage, Visibility); + return ParseAlias(Name, NameLoc, Visibility); } // MDString: @@ -622,17 +615,16 @@ bool LLParser::ParseStandaloneMetadata() { } /// ParseAlias: -/// ::= GlobalVar '=' OptionalVisibility OptionalDLLStorageClass 'alias' -/// OptionalLinkage Aliasee +/// ::= GlobalVar '=' OptionalVisibility 'alias' OptionalLinkage Aliasee /// Aliasee /// ::= TypeAndValue /// ::= 'bitcast' '(' TypeAndValue 'to' Type ')' /// ::= 'getelementptr' 'inbounds'? '(' ... ')' /// -/// Everything through DLL storage class has already been parsed. +/// Everything through visibility has already been parsed. /// bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc, - unsigned Visibility, unsigned DLLStorageClass) { + unsigned Visibility) { assert(Lex.getKind() == lltok::kw_alias); Lex.Lex(); LocTy LinkageLoc = Lex.getLoc(); @@ -667,7 +659,6 @@ bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc, (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. @@ -700,18 +691,18 @@ bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc, } /// ParseGlobal -/// ::= GlobalVar '=' OptionalLinkage OptionalVisibility OptionalDLLStorageClass -/// OptionalThreadLocal OptionalAddrSpace OptionalUnNammedAddr +/// ::= GlobalVar '=' OptionalLinkage OptionalVisibility OptionalThreadLocal +/// OptionalAddrSpace OptionalUnNammedAddr /// OptionalExternallyInitialized GlobalType Type Const -/// ::= OptionalLinkage OptionalVisibility OptionalDLLStorageClass -/// OptionalThreadLocal OptionalAddrSpace OptionalUnNammedAddr +/// ::= OptionalLinkage OptionalVisibility 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 DLLStorageClass) { + unsigned Visibility) { unsigned AddrSpace; bool IsConstant, UnnamedAddr, IsExternallyInitialized; GlobalVariable::ThreadLocalMode TLM; @@ -734,7 +725,8 @@ bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc, // If the linkage is specified and is external, then no initializer is // present. Constant *Init = 0; - if (!HasLinkage || (Linkage != GlobalValue::ExternalWeakLinkage && + if (!HasLinkage || (Linkage != GlobalValue::DLLImportLinkage && + Linkage != GlobalValue::ExternalWeakLinkage && Linkage != GlobalValue::ExternalLinkage)) { if (ParseGlobalValue(Ty, Init)) return true; @@ -783,7 +775,6 @@ bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc, 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); @@ -1286,7 +1277,9 @@ bool LLParser::ParseOptionalReturnAttrs(AttrBuilder &B) { /// ::= 'linkonce_odr' /// ::= 'available_externally' /// ::= 'appending' +/// ::= 'dllexport' /// ::= 'common' +/// ::= 'dllimport' /// ::= 'extern_weak' /// ::= 'external' bool LLParser::ParseOptionalLinkage(unsigned &Res, bool &HasLinkage) { @@ -1307,7 +1300,9 @@ bool LLParser::ParseOptionalLinkage(unsigned &Res, bool &HasLinkage) { 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; } @@ -1333,21 +1328,6 @@ bool LLParser::ParseOptionalVisibility(unsigned &Res) { 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' @@ -2954,14 +2934,12 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { 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*/)) @@ -2971,6 +2949,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { 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"); @@ -2984,6 +2963,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { case GlobalValue::LinkOnceODRLinkage: case GlobalValue::WeakAnyLinkage: case GlobalValue::WeakODRLinkage: + case GlobalValue::DLLExportLinkage: if (!isDefine) return Error(LinkageLoc, "invalid linkage for function declaration"); break; @@ -3130,7 +3110,6 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { Fn->setLinkage((GlobalValue::LinkageTypes)Linkage); Fn->setVisibility((GlobalValue::VisibilityTypes)Visibility); - Fn->setDLLStorageClass((GlobalValue::DLLStorageClassTypes)DLLStorageClass); Fn->setCallingConv(CC); Fn->setAttributes(PAL); Fn->setUnnamedAddr(UnnamedAddr); diff --git a/lib/AsmParser/LLParser.h b/lib/AsmParser/LLParser.h index c62979e6f29..ded776c3989 100644 --- a/lib/AsmParser/LLParser.h +++ b/lib/AsmParser/LLParser.h @@ -204,7 +204,6 @@ 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, @@ -235,10 +234,8 @@ namespace llvm { bool ParseUnnamedGlobal(); bool ParseNamedGlobal(); bool ParseGlobal(const std::string &Name, LocTy Loc, unsigned Linkage, - bool HasLinkage, unsigned Visibility, - unsigned DLLStorageClass); - bool ParseAlias(const std::string &Name, LocTy Loc, unsigned Visibility, - unsigned DLLStorageClass); + bool HasLinkage, unsigned Visibility); + bool ParseAlias(const std::string &Name, LocTy Loc, unsigned Visibility); bool ParseStandaloneMetadata(); bool ParseNamedMetadata(); bool ParseMDString(MDString *&Result); diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 81ed803ba04..39a0dfa5006 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -80,8 +80,8 @@ static GlobalValue::LinkageTypes GetDecodedLinkage(unsigned Val) { case 2: return GlobalValue::AppendingLinkage; case 3: return GlobalValue::InternalLinkage; case 4: return GlobalValue::LinkOnceAnyLinkage; - case 5: return GlobalValue::ExternalLinkage; // Obsolete DLLImportLinkage - case 6: return GlobalValue::ExternalLinkage; // Obsolete DLLExportLinkage + case 5: return GlobalValue::DLLImportLinkage; + case 6: return GlobalValue::DLLExportLinkage; case 7: return GlobalValue::ExternalWeakLinkage; case 8: return GlobalValue::CommonLinkage; case 9: return GlobalValue::PrivateLinkage; @@ -102,16 +102,6 @@ static GlobalValue::VisibilityTypes GetDecodedVisibility(unsigned Val) { } } -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; @@ -203,13 +193,6 @@ static SynchronizationScope GetDecodedSynchScope(unsigned Val) { } } -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 @@ -1814,7 +1797,7 @@ error_code BitcodeReader::ParseModule(bool Resume) { } // GLOBALVAR: [pointer type, isconst, initid, // linkage, alignment, section, visibility, threadlocal, - // unnamed_addr, dllstorageclass] + // unnamed_addr] case bitc::MODULE_CODE_GLOBALVAR: { if (Record.size() < 6) return Error(InvalidRecord); @@ -1860,11 +1843,6 @@ error_code BitcodeReader::ParseModule(bool Resume) { 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. @@ -1873,8 +1851,7 @@ error_code BitcodeReader::ParseModule(bool Resume) { break; } // FUNCTION: [type, callingconv, isproto, linkage, paramattr, - // alignment, section, visibility, gc, unnamed_addr, - // dllstorageclass] + // alignment, section, visibility, gc, unnamed_addr] case bitc::MODULE_CODE_FUNCTION: { if (Record.size() < 8) return Error(InvalidRecord); @@ -1914,12 +1891,6 @@ error_code BitcodeReader::ParseModule(bool Resume) { 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 @@ -1931,7 +1902,7 @@ error_code BitcodeReader::ParseModule(bool Resume) { break; } // ALIAS: [alias type, aliasee val#, linkage] - // ALIAS: [alias type, aliasee val#, linkage, visibility, dllstorageclass] + // ALIAS: [alias type, aliasee val#, linkage, visibility] case bitc::MODULE_CODE_ALIAS: { if (Record.size() < 3) return Error(InvalidRecord); @@ -1946,10 +1917,6 @@ error_code BitcodeReader::ParseModule(bool Resume) { // 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; diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp index 1d763d66ddc..be19b781d4a 100644 --- a/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -481,6 +481,8 @@ static unsigned getEncodedLinkage(const GlobalValue *GV) { 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; @@ -502,15 +504,6 @@ static unsigned getEncodedVisibility(const GlobalValue *GV) { 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; @@ -614,7 +607,7 @@ static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE, // GLOBALVAR: [type, isconst, initid, // linkage, alignment, section, visibility, threadlocal, - // unnamed_addr, externally_initialized, dllstorageclass] + // unnamed_addr, externally_initialized] Vals.push_back(VE.getTypeID(GV->getType())); Vals.push_back(GV->isConstant()); Vals.push_back(GV->isDeclaration() ? 0 : @@ -624,13 +617,11 @@ static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE, Vals.push_back(GV->hasSection() ? SectionMap[GV->getSection()] : 0); if (GV->isThreadLocal() || GV->getVisibility() != GlobalValue::DefaultVisibility || - GV->hasUnnamedAddr() || GV->isExternallyInitialized() || - GV->getDLLStorageClass() != GlobalValue::DefaultStorageClass) { + GV->hasUnnamedAddr() || GV->isExternallyInitialized()) { 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; } @@ -655,7 +646,6 @@ static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE, 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); @@ -670,7 +660,6 @@ static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE, 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(); diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index cf950f8cc75..5a8e8cc2f02 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -257,6 +257,7 @@ void AsmPrinter::EmitLinkage(const GlobalValue *GV, MCSymbol *GVSym) const { 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. @@ -271,6 +272,7 @@ void AsmPrinter::EmitLinkage(const GlobalValue *GV, MCSymbol *GVSym) const { 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"); } diff --git a/lib/ExecutionEngine/ExecutionEngine.cpp b/lib/ExecutionEngine/ExecutionEngine.cpp index 88ec5b3e6a9..abc8877ec59 100644 --- a/lib/ExecutionEngine/ExecutionEngine.cpp +++ b/lib/ExecutionEngine/ExecutionEngine.cpp @@ -1211,7 +1211,9 @@ void ExecutionEngine::emitGlobals() { } // If the existing global is strong, never replace it. - if (GVEntry->hasExternalLinkage()) + if (GVEntry->hasExternalLinkage() || + GVEntry->hasDLLImportLinkage() || + GVEntry->hasDLLExportLinkage()) continue; // Otherwise, we know it's linkonce/weak, replace it if this is a strong diff --git a/lib/IR/AsmWriter.cpp b/lib/IR/AsmWriter.cpp index eba05c5f28e..91684c9c70e 100644 --- a/lib/IR/AsmWriter.cpp +++ b/lib/IR/AsmWriter.cpp @@ -1367,6 +1367,8 @@ static void PrintLinkage(GlobalValue::LinkageTypes LT, 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 "; @@ -1384,15 +1386,6 @@ static void PrintVisibility(GlobalValue::VisibilityTypes Vis, } } -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) { @@ -1425,7 +1418,6 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) { PrintLinkage(GV->getLinkage(), Out); PrintVisibility(GV->getVisibility(), Out); - PrintDLLStorageClass(GV->getDLLStorageClass(), Out); PrintThreadLocalModel(GV->getThreadLocalMode(), Out); if (unsigned AddressSpace = GV->getType()->getAddressSpace()) @@ -1463,7 +1455,6 @@ void AssemblyWriter::printAlias(const GlobalAlias *GA) { Out << " = "; } PrintVisibility(GA->getVisibility(), Out); - PrintDLLStorageClass(GA->getDLLStorageClass(), Out); Out << "alias "; @@ -1561,7 +1552,6 @@ void AssemblyWriter::printFunction(const Function *F) { PrintLinkage(F->getLinkage(), Out); PrintVisibility(F->getVisibility(), Out); - PrintDLLStorageClass(F->getDLLStorageClass(), Out); // Print the calling convention. if (F->getCallingConv() != CallingConv::C) { diff --git a/lib/IR/Core.cpp b/lib/IR/Core.cpp index 6e920a2daa4..ff4976bcbf9 100644 --- a/lib/IR/Core.cpp +++ b/lib/IR/Core.cpp @@ -1164,6 +1164,10 @@ LLVMLinkage LLVMGetLinkage(LLVMValueRef Global) { 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: @@ -1215,12 +1219,10 @@ void LLVMSetLinkage(LLVMValueRef Global, LLVMLinkage Linkage) { GV->setLinkage(GlobalValue::LinkerPrivateWeakLinkage); break; case LLVMDLLImportLinkage: - DEBUG(errs() - << "LLVMSetLinkage(): LLVMDLLImportLinkage is no longer supported."); + GV->setLinkage(GlobalValue::DLLImportLinkage); break; case LLVMDLLExportLinkage: - DEBUG(errs() - << "LLVMSetLinkage(): LLVMDLLExportLinkage is no longer supported."); + GV->setLinkage(GlobalValue::DLLExportLinkage); break; case LLVMExternalWeakLinkage: GV->setLinkage(GlobalValue::ExternalWeakLinkage); diff --git a/lib/IR/Verifier.cpp b/lib/IR/Verifier.cpp index d8e5c89598e..9e150e85756 100644 --- a/lib/IR/Verifier.cpp +++ b/lib/IR/Verifier.cpp @@ -421,12 +421,16 @@ void Verifier::visitGlobalValue(GlobalValue &GV) { Assert1(!GV.isDeclaration() || GV.isMaterializable() || GV.hasExternalLinkage() || + GV.hasDLLImportLinkage() || GV.hasExternalWeakLinkage() || (isa(GV) && (GV.hasLocalLinkage() || GV.hasWeakLinkage())), - "Global is external, but doesn't have external or weak linkage!", + "Global is external, but doesn't have external or dllimport or weak linkage!", &GV); + Assert1(!GV.hasDLLImportLinkage() || GV.isDeclaration(), + "Global is marked as dllimport, but not external", &GV); + Assert1(!GV.hasAppendingLinkage() || isa(GV), "Only global variables can have appending linkage!", &GV); @@ -452,7 +456,8 @@ void Verifier::visitGlobalVariable(GlobalVariable &GV) { &GV); } } else { - Assert1(GV.hasExternalLinkage() || GV.hasExternalWeakLinkage(), + Assert1(GV.hasExternalLinkage() || GV.hasDLLImportLinkage() || + GV.hasExternalWeakLinkage(), "invalid linkage type for global declaration", &GV); } @@ -497,11 +502,6 @@ void Verifier::visitGlobalVariable(GlobalVariable &GV) { } } - 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,7 +1078,8 @@ 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.hasExternalWeakLinkage(), + Assert1(F.hasExternalLinkage() || F.hasDLLImportLinkage() || + F.hasExternalWeakLinkage(), "invalid linkage type for function declaration", &F); } else { // Verify that this function (which has a body) is not named "llvm.*". It @@ -1104,11 +1105,6 @@ 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... diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp index 4d039eb2c6d..8f2200e4ea2 100644 --- a/lib/Linker/LinkModules.cpp +++ b/lib/Linker/LinkModules.cpp @@ -543,8 +543,8 @@ bool ModuleLinker::getLinkageResult(GlobalValue *Dest, const GlobalValue *Src, 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->hasDLLImportStorageClass()) { - // If one of GVs is marked as DLLImport, result should be dllimport'ed. + if (Src->hasDLLImportLinkage()) { + // If one of GVs has DLLImport linkage, result should be dllimport'ed. if (DestIsDeclaration) { LinkFromSrc = true; LT = Src->getLinkage(); @@ -557,7 +557,7 @@ bool ModuleLinker::getLinkageResult(GlobalValue *Dest, const GlobalValue *Src, LinkFromSrc = false; LT = Dest->getLinkage(); } - } else if (DestIsDeclaration && !Dest->hasDLLImportStorageClass()) { + } else if (DestIsDeclaration && !Dest->hasDLLImportLinkage()) { // If Dest is external but Src is not: LinkFromSrc = true; LT = Src->getLinkage(); @@ -584,8 +584,10 @@ bool ModuleLinker::getLinkageResult(GlobalValue *Dest, const GlobalValue *Src, LT = GlobalValue::ExternalLinkage; } } else { - assert((Dest->hasExternalLinkage() || Dest->hasExternalWeakLinkage()) && - (Src->hasExternalLinkage() || Src->hasExternalWeakLinkage()) && + assert((Dest->hasExternalLinkage() || Dest->hasDLLImportLinkage() || + Dest->hasDLLExportLinkage() || Dest->hasExternalWeakLinkage()) && + (Src->hasExternalLinkage() || Src->hasDLLImportLinkage() || + Src->hasDLLExportLinkage() || Src->hasExternalWeakLinkage()) && "Unexpected linkage type!"); return emitError("Linking globals named '" + Src->getName() + "': symbol multiply defined!"); diff --git a/lib/Target/CppBackend/CPPBackend.cpp b/lib/Target/CppBackend/CPPBackend.cpp index b13709914bf..6e2dd0a8e7b 100644 --- a/lib/Target/CppBackend/CPPBackend.cpp +++ b/lib/Target/CppBackend/CPPBackend.cpp @@ -131,7 +131,6 @@ 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); @@ -301,6 +300,10 @@ void CppWriter::printLinkageType(GlobalValue::LinkageTypes LT) { 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: @@ -322,21 +325,6 @@ void CppWriter::printVisibilityType(GlobalValue::VisibilityTypes VisType) { } } -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: @@ -1040,13 +1028,6 @@ void CppWriter::printVariableHead(const GlobalVariable *GV) { 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("; @@ -1765,13 +1746,6 @@ void CppWriter::printFunctionHead(const Function* F) { 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() << "\");"; diff --git a/lib/Target/X86/X86AsmPrinter.cpp b/lib/Target/X86/X86AsmPrinter.cpp index ad7d3e0fdca..a2c3f770d31 100644 --- a/lib/Target/X86/X86AsmPrinter.cpp +++ b/lib/Target/X86/X86AsmPrinter.cpp @@ -649,20 +649,20 @@ void X86AsmPrinter::EmitEndOfAsmFile(Module &M) { // Necessary for dllexport support std::vector DLLExportedFns, DLLExportedGlobals; + const TargetLoweringObjectFileCOFF &TLOFCOFF = + static_cast(getObjFileLowering()); + for (Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I) - if (I->hasDLLExportStorageClass()) + if (I->hasDLLExportLinkage()) DLLExportedFns.push_back(getSymbol(I)); for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) - if (I->hasDLLExportStorageClass()) + if (I->hasDLLExportLinkage()) DLLExportedGlobals.push_back(getSymbol(I)); // Output linker support code for dllexported globals on windows. if (!DLLExportedGlobals.empty() || !DLLExportedFns.empty()) { - const TargetLoweringObjectFileCOFF &TLOFCOFF = - static_cast(getObjFileLowering()); - OutStreamer.SwitchSection(TLOFCOFF.getDrectveSection()); SmallString<128> name; for (unsigned i = 0, e = DLLExportedGlobals.size(); i != e; ++i) { diff --git a/lib/Target/X86/X86FastISel.cpp b/lib/Target/X86/X86FastISel.cpp index 7b2d1d7776f..fd10a4a09ea 100644 --- a/lib/Target/X86/X86FastISel.cpp +++ b/lib/Target/X86/X86FastISel.cpp @@ -697,7 +697,7 @@ bool X86FastISel::X86SelectCallAddress(const Value *V, X86AddressMode &AM) { return false; // Can't handle DLLImport. - if (GV->hasDLLImportStorageClass()) + if (GV->hasDLLImportLinkage()) return false; // Can't handle TLS. diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index ccc96f4a0b8..a41faab73b4 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -2796,7 +2796,7 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, // We should use extra load for direct calls to dllimported functions in // non-JIT mode. const GlobalValue *GV = G->getGlobal(); - if (!GV->hasDLLImportStorageClass()) { + if (!GV->hasDLLImportLinkage()) { unsigned char OpFlags = 0; bool ExtraLoad = false; unsigned WrapperKind = ISD::DELETED_NODE; diff --git a/lib/Target/X86/X86Subtarget.cpp b/lib/Target/X86/X86Subtarget.cpp index 6f724b42d97..b183ed0314f 100644 --- a/lib/Target/X86/X86Subtarget.cpp +++ b/lib/Target/X86/X86Subtarget.cpp @@ -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->hasDLLImportStorageClass()) + if (GV->hasDLLImportLinkage()) return X86II::MO_DLLIMPORT; // Determine whether this is a reference to a definition or a declaration. diff --git a/lib/Target/XCore/XCoreAsmPrinter.cpp b/lib/Target/XCore/XCoreAsmPrinter.cpp index 778bf9ca39d..ee84aa4a882 100644 --- a/lib/Target/XCore/XCoreAsmPrinter.cpp +++ b/lib/Target/XCore/XCoreAsmPrinter.cpp @@ -135,6 +135,10 @@ void XCoreAsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) { 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!"); } diff --git a/lib/Transforms/IPO/Internalize.cpp b/lib/Transforms/IPO/Internalize.cpp index 03077141776..dae69ce0915 100644 --- a/lib/Transforms/IPO/Internalize.cpp +++ b/lib/Transforms/IPO/Internalize.cpp @@ -116,7 +116,7 @@ static bool shouldInternalize(const GlobalValue &GV, return false; // Assume that dllexported symbols are referenced elsewhere - if (GV.hasDLLExportStorageClass()) + if (GV.hasDLLExportLinkage()) return false; // Already has internal linkage diff --git a/test/Bitcode/linkage-types-3.2.ll b/test/Bitcode/linkage-types-3.2.ll index 8bacb124eef..65c31dd1287 100644 --- a/test/Bitcode/linkage-types-3.2.ll +++ b/test/Bitcode/linkage-types-3.2.ll @@ -50,7 +50,7 @@ ; CHECK: @dllexport.var = dllexport global i32 0 @dllimport.var = dllimport global i32 -; CHECK: @dllimport.var = external dllimport global i32 +; CHECK: @dllimport.var = dllimport global i32 define private void @private() ; CHECK: define private void @private diff --git a/test/CodeGen/X86/dll-linkage.ll b/test/CodeGen/X86/dll-linkage.ll new file mode 100644 index 00000000000..a0c2a54a99a --- /dev/null +++ b/test/CodeGen/X86/dll-linkage.ll @@ -0,0 +1,14 @@ +; 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 +} diff --git a/test/CodeGen/X86/dllexport-x86_64.ll b/test/CodeGen/X86/dllexport-x86_64.ll deleted file mode 100644 index 6bf73aa5366..00000000000 --- a/test/CodeGen/X86/dllexport-x86_64.ll +++ /dev/null @@ -1,79 +0,0 @@ -; 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 -@Var1 = dllexport global i32 1, align 4 - -; CHECK: .rdata,"r" -; CHECK: .globl Var2 -@Var2 = dllexport unnamed_addr constant i32 1 - -; CHECK: .comm Var3 -@Var3 = common dllexport global i32 0, align 4 - -; CHECK: .section .data,"w",discard,WeakVar1 -; CHECK: .globl WeakVar1 -@WeakVar1 = weak_odr dllexport global i32 1, align 4 - -; CHECK: .section .rdata,"r",discard,WeakVar2 -; CHECK: .globl WeakVar2 -@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 diff --git a/test/CodeGen/X86/dllexport.ll b/test/CodeGen/X86/dllexport.ll index 1d992125976..bf57e78f35d 100644 --- a/test/CodeGen/X86/dllexport.ll +++ b/test/CodeGen/X86/dllexport.ll @@ -1,100 +1,12 @@ -; 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 +; RUN: llc < %s | FileCheck %s +; PR2936 -; CHECK: .text +target triple = "i386-pc-mingw32" -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@0 -define dllexport x86_stdcallcc void @stdfun() nounwind { - ret void -} - -; CHECK: .globl @fastfun@0 -define dllexport x86_fastcallcc i32 @fastfun() nounwind { +define dllexport x86_fastcallcc i32 @foo() nounwind { +entry: 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 -@Var1 = dllexport global i32 1, align 4 - -; CHECK: .rdata,"r" -; CHECK: .globl _Var2 -@Var2 = dllexport unnamed_addr constant i32 1 - -; CHECK: .comm _Var3 -@Var3 = common dllexport global i32 0, align 4 - -; CHECK: .section .data,"w",discard,_WeakVar1 -; CHECK: .globl _WeakVar1 -@WeakVar1 = weak_odr dllexport global i32 1, align 4 - -; CHECK: .section .rdata,"r",discard,_WeakVar2 -; CHECK: .globl _WeakVar2 -@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:_stdfun@0 -; WIN32: /EXPORT:@fastfun@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@0 -; MINGW: -export:@fastfun@0 -; MINGW: -export:_thisfun -; MINGW: -export:_lnk1 -; MINGW: -export:_lnk2 -; MINGW: -export:_weak1 +; CHECK: -export:@foo@0 diff --git a/test/CodeGen/X86/dllimport-x86_64.ll b/test/CodeGen/X86/dllimport-x86_64.ll deleted file mode 100644 index 666409fd4c0..00000000000 --- a/test/CodeGen/X86/dllimport-x86_64.ll +++ /dev/null @@ -1,48 +0,0 @@ -; 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 - -@Var1 = external dllimport global i32 -@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 -} diff --git a/test/CodeGen/X86/dllimport.ll b/test/CodeGen/X86/dllimport.ll deleted file mode 100644 index 695bfce821b..00000000000 --- a/test/CodeGen/X86/dllimport.ll +++ /dev/null @@ -1,59 +0,0 @@ -; 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 - -@Var1 = external dllimport global i32 -@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@0 -; CHECK: calll *__imp_@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 -}