Adding dllimport, dllexport and external weak linkage types.
DLL* linkages got full (I hope) codegeneration support in C & both x86
assembler backends.
External weak linkage added for future use, we don't provide any
codegeneration, etc. support for it.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@30374 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AsmParser/Lexer.l b/lib/AsmParser/Lexer.l
index fd75245..7c27f13 100644
--- a/lib/AsmParser/Lexer.l
+++ b/lib/AsmParser/Lexer.l
@@ -191,6 +191,9 @@
 linkonce        { return LINKONCE; }
 weak            { return WEAK; }
 appending       { return APPENDING; }
+dllimport       { return DLLIMPORT; }
+dllexport       { return DLLEXPORT; }
+extern_weak     { return EXTERN_WEAK; }
 uninitialized   { return EXTERNAL; }    /* Deprecated, turn into external */
 external        { return EXTERNAL; }
 implementation  { return IMPLEMENTATION; }
diff --git a/lib/AsmParser/Lexer.l.cvs b/lib/AsmParser/Lexer.l.cvs
index fd75245..7c27f13 100644
--- a/lib/AsmParser/Lexer.l.cvs
+++ b/lib/AsmParser/Lexer.l.cvs
@@ -191,6 +191,9 @@
 linkonce        { return LINKONCE; }
 weak            { return WEAK; }
 appending       { return APPENDING; }
+dllimport       { return DLLIMPORT; }
+dllexport       { return DLLEXPORT; }
+extern_weak     { return EXTERN_WEAK; }
 uninitialized   { return EXTERNAL; }    /* Deprecated, turn into external */
 external        { return EXTERNAL; }
 implementation  { return IMPLEMENTATION; }
diff --git a/lib/AsmParser/llvmAsmParser.y b/lib/AsmParser/llvmAsmParser.y
index 7d6a9f7..af3a39d 100644
--- a/lib/AsmParser/llvmAsmParser.y
+++ b/lib/AsmParser/llvmAsmParser.y
@@ -150,9 +150,10 @@
 static struct PerFunctionInfo {
   Function *CurrentFunction;     // Pointer to current function being created
 
-  std::map<const Type*, ValueList> Values;   // Keep track of #'d definitions
+  std::map<const Type*, ValueList> Values; // Keep track of #'d definitions
   std::map<const Type*, ValueList> LateResolveValues;
-  bool isDeclare;                // Is this function a forward declararation?
+  bool isDeclare;                    // Is this function a forward declararation?
+  GlobalValue::LinkageTypes Linkage; // Linkage for forward declaration.
 
   /// BBForwardRefs - When we see forward references to basic blocks, keep
   /// track of them here.
@@ -163,6 +164,7 @@
   inline PerFunctionInfo() {
     CurrentFunction = 0;
     isDeclare = false;
+    Linkage = GlobalValue::ExternalLinkage;    
   }
 
   inline void FunctionStart(Function *M) {
@@ -184,6 +186,7 @@
     Values.clear();         // Clear out function local definitions
     CurrentFunction = 0;
     isDeclare = false;
+    Linkage = GlobalValue::ExternalLinkage;
   }
 } CurFun;  // Info for the current function...
 
@@ -998,7 +1001,8 @@
 
 %token IMPLEMENTATION ZEROINITIALIZER TRUETOK FALSETOK BEGINTOK ENDTOK
 %token DECLARE GLOBAL CONSTANT SECTION VOLATILE
-%token TO DOTDOTDOT NULL_TOK UNDEF CONST INTERNAL LINKONCE WEAK  APPENDING
+%token TO DOTDOTDOT NULL_TOK UNDEF CONST INTERNAL LINKONCE WEAK APPENDING
+%token DLLIMPORT DLLEXPORT EXTERN_WEAK
 %token OPAQUE NOT EXTERNAL TARGET TRIPLE ENDIAN POINTERSIZE LITTLE BIG ALIGN
 %token DEPLIBS CALL TAIL ASM_TOK MODULE SIDEEFFECT
 %token CC_TOK CCC_TOK CSRETCC_TOK FASTCC_TOK COLDCC_TOK
@@ -1070,11 +1074,14 @@
     CHECK_FOR_ERROR
   };
 
-OptLinkage : INTERNAL  { $$ = GlobalValue::InternalLinkage; } |
-             LINKONCE  { $$ = GlobalValue::LinkOnceLinkage; } |
-             WEAK      { $$ = GlobalValue::WeakLinkage; } |
-             APPENDING { $$ = GlobalValue::AppendingLinkage; } |
-             /*empty*/ { $$ = GlobalValue::ExternalLinkage; };
+OptLinkage : INTERNAL    { $$ = GlobalValue::InternalLinkage; } |
+             LINKONCE    { $$ = GlobalValue::LinkOnceLinkage; } |
+             WEAK        { $$ = GlobalValue::WeakLinkage; } |
+             APPENDING   { $$ = GlobalValue::AppendingLinkage; } |
+             DLLIMPORT   { $$ = GlobalValue::DLLImportLinkage; } |
+             DLLEXPORT   { $$ = GlobalValue::DLLExportLinkage; } |
+             EXTERN_WEAK { $$ = GlobalValue::ExternalWeakLinkage; } |
+             /*empty*/   { $$ = GlobalValue::ExternalLinkage; };
 
 OptCallingConv : /*empty*/      { $$ = CallingConv::C; } |
                  CCC_TOK        { $$ = CallingConv::C; } |
@@ -1728,8 +1735,24 @@
     CHECK_FOR_ERROR
   }
   | ConstPool OptAssign EXTERNAL GlobalType Types {
-    CurGV = ParseGlobalVariable($2, GlobalValue::ExternalLinkage,
-                                             $4, *$5, 0);
+    CurGV = ParseGlobalVariable($2,
+                                GlobalValue::ExternalLinkage, $4, *$5, 0);
+    delete $5;
+                                                   } GlobalVarAttributes {
+    CurGV = 0;
+    CHECK_FOR_ERROR
+  }
+  | ConstPool OptAssign DLLIMPORT GlobalType Types {
+    CurGV = ParseGlobalVariable($2,
+                                GlobalValue::DLLImportLinkage, $4, *$5, 0);
+    delete $5;
+                                                   } GlobalVarAttributes {
+    CurGV = 0;
+    CHECK_FOR_ERROR
+  }
+  | ConstPool OptAssign EXTERN_WEAK GlobalType Types {
+    CurGV = ParseGlobalVariable($2,
+                                GlobalValue::ExternalWeakLinkage, $4, *$5, 0);
     delete $5;
                                                    } GlobalVarAttributes {
     CurGV = 0;
@@ -1895,9 +1918,17 @@
            AI != AE; ++AI)
         AI->setName("");
 
+    if (CurFun.isDeclare) {
+      Fn->setLinkage(CurFun.Linkage);      
+    }    
   } else  {  // Not already defined?
     Fn = new Function(FT, GlobalValue::ExternalLinkage, FunctionName,
                       CurModule.CurrentModule);
+
+    if (CurFun.isDeclare) {
+      Fn->setLinkage(CurFun.Linkage);      
+    }    
+
     InsertValue(Fn, CurModule.Values);
   }
 
@@ -1948,11 +1979,15 @@
   CHECK_FOR_ERROR
 };
 
-FunctionProto : DECLARE { CurFun.isDeclare = true; } FunctionHeaderH {
-  $$ = CurFun.CurrentFunction;
-  CurFun.FunctionDone();
-  CHECK_FOR_ERROR
-};
+FnDeclareLinkage: /*default*/ |
+                  DLLIMPORT   { CurFun.Linkage = GlobalValue::DLLImportLinkage } |
+                  EXTERN_WEAK { CurFun.Linkage = GlobalValue::DLLImportLinkage };
+  
+FunctionProto : DECLARE { CurFun.isDeclare = true; } FnDeclareLinkage FunctionHeaderH {
+    $$ = CurFun.CurrentFunction;
+    CurFun.FunctionDone();
+    CHECK_FOR_ERROR
+  };
 
 //===----------------------------------------------------------------------===//
 //                        Rules to match Basic Blocks
diff --git a/lib/AsmParser/llvmAsmParser.y.cvs b/lib/AsmParser/llvmAsmParser.y.cvs
index 7d6a9f7..af3a39d 100644
--- a/lib/AsmParser/llvmAsmParser.y.cvs
+++ b/lib/AsmParser/llvmAsmParser.y.cvs
@@ -150,9 +150,10 @@
 static struct PerFunctionInfo {
   Function *CurrentFunction;     // Pointer to current function being created
 
-  std::map<const Type*, ValueList> Values;   // Keep track of #'d definitions
+  std::map<const Type*, ValueList> Values; // Keep track of #'d definitions
   std::map<const Type*, ValueList> LateResolveValues;
-  bool isDeclare;                // Is this function a forward declararation?
+  bool isDeclare;                    // Is this function a forward declararation?
+  GlobalValue::LinkageTypes Linkage; // Linkage for forward declaration.
 
   /// BBForwardRefs - When we see forward references to basic blocks, keep
   /// track of them here.
@@ -163,6 +164,7 @@
   inline PerFunctionInfo() {
     CurrentFunction = 0;
     isDeclare = false;
+    Linkage = GlobalValue::ExternalLinkage;    
   }
 
   inline void FunctionStart(Function *M) {
@@ -184,6 +186,7 @@
     Values.clear();         // Clear out function local definitions
     CurrentFunction = 0;
     isDeclare = false;
+    Linkage = GlobalValue::ExternalLinkage;
   }
 } CurFun;  // Info for the current function...
 
@@ -998,7 +1001,8 @@
 
 %token IMPLEMENTATION ZEROINITIALIZER TRUETOK FALSETOK BEGINTOK ENDTOK
 %token DECLARE GLOBAL CONSTANT SECTION VOLATILE
-%token TO DOTDOTDOT NULL_TOK UNDEF CONST INTERNAL LINKONCE WEAK  APPENDING
+%token TO DOTDOTDOT NULL_TOK UNDEF CONST INTERNAL LINKONCE WEAK APPENDING
+%token DLLIMPORT DLLEXPORT EXTERN_WEAK
 %token OPAQUE NOT EXTERNAL TARGET TRIPLE ENDIAN POINTERSIZE LITTLE BIG ALIGN
 %token DEPLIBS CALL TAIL ASM_TOK MODULE SIDEEFFECT
 %token CC_TOK CCC_TOK CSRETCC_TOK FASTCC_TOK COLDCC_TOK
@@ -1070,11 +1074,14 @@
     CHECK_FOR_ERROR
   };
 
-OptLinkage : INTERNAL  { $$ = GlobalValue::InternalLinkage; } |
-             LINKONCE  { $$ = GlobalValue::LinkOnceLinkage; } |
-             WEAK      { $$ = GlobalValue::WeakLinkage; } |
-             APPENDING { $$ = GlobalValue::AppendingLinkage; } |
-             /*empty*/ { $$ = GlobalValue::ExternalLinkage; };
+OptLinkage : INTERNAL    { $$ = GlobalValue::InternalLinkage; } |
+             LINKONCE    { $$ = GlobalValue::LinkOnceLinkage; } |
+             WEAK        { $$ = GlobalValue::WeakLinkage; } |
+             APPENDING   { $$ = GlobalValue::AppendingLinkage; } |
+             DLLIMPORT   { $$ = GlobalValue::DLLImportLinkage; } |
+             DLLEXPORT   { $$ = GlobalValue::DLLExportLinkage; } |
+             EXTERN_WEAK { $$ = GlobalValue::ExternalWeakLinkage; } |
+             /*empty*/   { $$ = GlobalValue::ExternalLinkage; };
 
 OptCallingConv : /*empty*/      { $$ = CallingConv::C; } |
                  CCC_TOK        { $$ = CallingConv::C; } |
@@ -1728,8 +1735,24 @@
     CHECK_FOR_ERROR
   }
   | ConstPool OptAssign EXTERNAL GlobalType Types {
-    CurGV = ParseGlobalVariable($2, GlobalValue::ExternalLinkage,
-                                             $4, *$5, 0);
+    CurGV = ParseGlobalVariable($2,
+                                GlobalValue::ExternalLinkage, $4, *$5, 0);
+    delete $5;
+                                                   } GlobalVarAttributes {
+    CurGV = 0;
+    CHECK_FOR_ERROR
+  }
+  | ConstPool OptAssign DLLIMPORT GlobalType Types {
+    CurGV = ParseGlobalVariable($2,
+                                GlobalValue::DLLImportLinkage, $4, *$5, 0);
+    delete $5;
+                                                   } GlobalVarAttributes {
+    CurGV = 0;
+    CHECK_FOR_ERROR
+  }
+  | ConstPool OptAssign EXTERN_WEAK GlobalType Types {
+    CurGV = ParseGlobalVariable($2,
+                                GlobalValue::ExternalWeakLinkage, $4, *$5, 0);
     delete $5;
                                                    } GlobalVarAttributes {
     CurGV = 0;
@@ -1895,9 +1918,17 @@
            AI != AE; ++AI)
         AI->setName("");
 
+    if (CurFun.isDeclare) {
+      Fn->setLinkage(CurFun.Linkage);      
+    }    
   } else  {  // Not already defined?
     Fn = new Function(FT, GlobalValue::ExternalLinkage, FunctionName,
                       CurModule.CurrentModule);
+
+    if (CurFun.isDeclare) {
+      Fn->setLinkage(CurFun.Linkage);      
+    }    
+
     InsertValue(Fn, CurModule.Values);
   }
 
@@ -1948,11 +1979,15 @@
   CHECK_FOR_ERROR
 };
 
-FunctionProto : DECLARE { CurFun.isDeclare = true; } FunctionHeaderH {
-  $$ = CurFun.CurrentFunction;
-  CurFun.FunctionDone();
-  CHECK_FOR_ERROR
-};
+FnDeclareLinkage: /*default*/ |
+                  DLLIMPORT   { CurFun.Linkage = GlobalValue::DLLImportLinkage } |
+                  EXTERN_WEAK { CurFun.Linkage = GlobalValue::DLLImportLinkage };
+  
+FunctionProto : DECLARE { CurFun.isDeclare = true; } FnDeclareLinkage FunctionHeaderH {
+    $$ = CurFun.CurrentFunction;
+    CurFun.FunctionDone();
+    CHECK_FOR_ERROR
+  };
 
 //===----------------------------------------------------------------------===//
 //                        Rules to match Basic Blocks
diff --git a/lib/Bytecode/Reader/Reader.cpp b/lib/Bytecode/Reader/Reader.cpp
index 60c8e4f..ac6418d 100644
--- a/lib/Bytecode/Reader/Reader.cpp
+++ b/lib/Bytecode/Reader/Reader.cpp
@@ -1791,6 +1791,9 @@
   case 2: Linkage = GlobalValue::AppendingLinkage; break;
   case 3: Linkage = GlobalValue::InternalLinkage; break;
   case 4: Linkage = GlobalValue::LinkOnceLinkage; break;
+  case 5: Linkage = GlobalValue::DLLImportLinkage; break;
+  case 6: Linkage = GlobalValue::DLLExportLinkage; break;
+  case 7: Linkage = GlobalValue::ExternalWeakLinkage; break;
   default:
     error("Invalid linkage type for Function.");
     Linkage = GlobalValue::InternalLinkage;
@@ -2047,6 +2050,9 @@
     case 2: Linkage = GlobalValue::AppendingLinkage; break;
     case 3: Linkage = GlobalValue::InternalLinkage;  break;
     case 4: Linkage = GlobalValue::LinkOnceLinkage;  break;
+    case 5: Linkage = GlobalValue::DLLImportLinkage;  break;
+    case 6: Linkage = GlobalValue::DLLExportLinkage;  break;
+    case 7: Linkage = GlobalValue::ExternalWeakLinkage;  break;
     default:
       error("Unknown linkage type: " + utostr(LinkageID));
       Linkage = GlobalValue::InternalLinkage;
@@ -2129,6 +2135,14 @@
       
       if (ExtWord & (1 << 10))  // Has a section ID.
         SectionID[Func] = read_vbr_uint();
+
+      // Parse external declaration linkage
+      switch ((ExtWord >> 11) & 3) {
+       case 0: break;
+       case 1: Func->setLinkage(Function::DLLImportLinkage); break;
+       case 2: Func->setLinkage(Function::ExternalWeakLinkage); break;        
+       default: assert(0 && "Unsupported external linkage");        
+      }      
     }
     
     Func->setCallingConv(CC-1);
diff --git a/lib/Bytecode/Writer/Writer.cpp b/lib/Bytecode/Writer/Writer.cpp
index 2fb05f1..48cccda 100644
--- a/lib/Bytecode/Writer/Writer.cpp
+++ b/lib/Bytecode/Writer/Writer.cpp
@@ -938,11 +938,14 @@
 static unsigned getEncodedLinkage(const GlobalValue *GV) {
   switch (GV->getLinkage()) {
   default: assert(0 && "Invalid linkage!");
-  case GlobalValue::ExternalLinkage:  return 0;
-  case GlobalValue::WeakLinkage:      return 1;
-  case GlobalValue::AppendingLinkage: return 2;
-  case GlobalValue::InternalLinkage:  return 3;
-  case GlobalValue::LinkOnceLinkage:  return 4;
+  case GlobalValue::ExternalLinkage:     return 0;
+  case GlobalValue::WeakLinkage:         return 1;
+  case GlobalValue::AppendingLinkage:    return 2;
+  case GlobalValue::InternalLinkage:     return 3;
+  case GlobalValue::LinkOnceLinkage:     return 4;
+  case GlobalValue::DLLImportLinkage:    return 5;
+  case GlobalValue::DLLExportLinkage:    return 6;
+  case GlobalValue::ExternalWeakLinkage: return 7;
   }
 }
 
@@ -973,7 +976,7 @@
       unsigned oSlot = ((unsigned)Slot << 5) | (getEncodedLinkage(I) << 2) |
                         (I->hasInitializer() << 1) | (unsigned)I->isConstant();
       output_vbr(oSlot);
-    } else {
+    } else {  
       unsigned oSlot = ((unsigned)Slot << 5) | (3 << 2) |
                         (0 << 1) | (unsigned)I->isConstant();
       output_vbr(oSlot);
@@ -1018,16 +1021,30 @@
     if (I->isExternal())   // If external, we don't have an FunctionInfo block.
       ID |= 1 << 4;
     
-    if (I->getAlignment() || I->hasSection() || (CC & ~15) != 0)
+    if (I->getAlignment() || I->hasSection() || (CC & ~15) != 0 ||
+        (I->isExternal() && I->hasDLLImportLinkage()) ||
+        (I->isExternal() && I->hasExternalWeakLinkage())
+       )
       ID |= 1 << 31;       // Do we need an extension word?
     
     output_vbr(ID);
     
     if (ID & (1 << 31)) {
       // Extension byte: bits 0-4 = alignment, bits 5-9 = top nibble of calling
-      // convention, bit 10 = hasSectionID.
+      // convention, bit 10 = hasSectionID., bits 11-12 = external linkage type
+      unsigned extLinkage = 0;
+
+      if (I->isExternal()) {
+        if (I->hasDLLImportLinkage()) {
+          extLinkage = 1;
+        } else if (I->hasExternalWeakLinkage()) {
+          extLinkage = 2;
+        }
+      }
+
       ID = (Log2_32(I->getAlignment())+1) | ((CC >> 4) << 5) | 
-           (I->hasSection() << 10);
+        (I->hasSection() << 10) |
+        ((extLinkage & 3) << 11);
       output_vbr(ID);
       
       // Give section names unique ID's.
diff --git a/lib/ExecutionEngine/ExecutionEngine.cpp b/lib/ExecutionEngine/ExecutionEngine.cpp
index 9ad6b57..067f24d 100644
--- a/lib/ExecutionEngine/ExecutionEngine.cpp
+++ b/lib/ExecutionEngine/ExecutionEngine.cpp
@@ -657,7 +657,9 @@
         }
         
         // 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/ExecutionEngine/JIT/JITEmitter.cpp b/lib/ExecutionEngine/JIT/JITEmitter.cpp
index 6e60caf..264caae 100644
--- a/lib/ExecutionEngine/JIT/JITEmitter.cpp
+++ b/lib/ExecutionEngine/JIT/JITEmitter.cpp
@@ -542,7 +542,7 @@
   // Call the lazy resolver function unless we already KNOW it is an external
   // function, in which case we just skip the lazy resolution step.
   void *Actual = (void*)(intptr_t)LazyResolverFn;
-  if (F->isExternal() && F->hasExternalLinkage())
+  if (F->isExternal())
     Actual = TheJIT->getPointerToFunction(F);
 
   // Otherwise, codegen a new stub.  For now, the stub will call the lazy
@@ -738,7 +738,7 @@
   void *ResultPtr = TheJIT->getPointerToGlobalIfAvailable(F);
   if (ResultPtr) return ResultPtr;
 
-  if (F->hasExternalLinkage() && F->isExternal()) {
+  if (F->isExternal()) {
     // If this is an external function pointer, we can force the JIT to
     // 'compile' it, which really just adds it to the map.
     if (DoesntNeedStub)
diff --git a/lib/Linker/LinkArchives.cpp b/lib/Linker/LinkArchives.cpp
index e115b93..15d261e 100644
--- a/lib/Linker/LinkArchives.cpp
+++ b/lib/Linker/LinkArchives.cpp
@@ -65,16 +65,22 @@
     if (I->hasName()) {
       if (I->isExternal())
         UndefinedSymbols.insert(I->getName());
-      else if (!I->hasInternalLinkage())
+      else if (!I->hasInternalLinkage()) {
+        assert(!I->hasDLLImportLinkage()
+               && "Found dllimported non-external symbol!");
         DefinedSymbols.insert(I->getName());
+      }      
     }
   for (Module::global_iterator I = M->global_begin(), E = M->global_end();
        I != E; ++I)
     if (I->hasName()) {
       if (I->isExternal())
         UndefinedSymbols.insert(I->getName());
-      else if (!I->hasInternalLinkage())
+      else if (!I->hasInternalLinkage()) {
+        assert(!I->hasDLLImportLinkage()
+               && "Found dllimported non-external symbol!");
         DefinedSymbols.insert(I->getName());
+      }      
     }
 
   // Prune out any defined symbols from the undefined symbols set...
diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp
index 3c87177..90b4502 100644
--- a/lib/Linker/LinkModules.cpp
+++ b/lib/Linker/LinkModules.cpp
@@ -359,9 +359,16 @@
   } else if (Src->isExternal()) {
     // If Src is external or if both Src & Drc are external..  Just link the
     // external globals, we aren't adding anything.
-    LinkFromSrc = false;
-    LT = Dest->getLinkage();
-  } else if (Dest->isExternal()) {
+    if (Src->hasDLLImportLinkage()) {
+      if (Dest->isExternal()) {
+        LinkFromSrc = true;
+        LT = Src->getLinkage();
+      }      
+    } else {
+      LinkFromSrc = false;
+      LT = Dest->getLinkage();
+    }
+  } else if (Dest->isExternal() && !Dest->hasDLLImportLinkage()) {
     // If Dest is external but Src is not:
     LinkFromSrc = true;
     LT = Src->getLinkage();
@@ -372,7 +379,7 @@
     LinkFromSrc = true; // Special cased.
     LT = Src->getLinkage();
   } else if (Src->hasWeakLinkage() || Src->hasLinkOnceLinkage()) {
-    // At this point we know that Dest has LinkOnce, External or Weak linkage.
+    // At this point we know that Dest has LinkOnce, External, Weak, DLL* linkage.
     if (Dest->hasLinkOnceLinkage() && Src->hasWeakLinkage()) {
       LinkFromSrc = true;
       LT = Src->getLinkage();
@@ -381,11 +388,16 @@
       LT = Dest->getLinkage();
     }
   } else if (Dest->hasWeakLinkage() || Dest->hasLinkOnceLinkage()) {
-    // At this point we know that Src has External linkage.
+    // At this point we know that Src has External or DLL* linkage.
     LinkFromSrc = true;
     LT = GlobalValue::ExternalLinkage;
   } else {
-    assert(Dest->hasExternalLinkage() && Src->hasExternalLinkage() &&
+    assert((Dest->hasExternalLinkage() ||
+            Dest->hasDLLImportLinkage() ||
+            Dest->hasDLLExportLinkage()) &&
+           (Src->hasExternalLinkage() ||
+            Src->hasDLLImportLinkage() ||
+            Src->hasDLLExportLinkage()) &&
            "Unexpected linkage type!");
     return Error(Err, "Linking globals named '" + Src->getName() +
                  "': symbol multiply defined!");
@@ -425,7 +437,8 @@
     if (DGV && DGV->hasInternalLinkage())
       DGV = 0;
 
-    assert(SGV->hasInitializer() || SGV->hasExternalLinkage() &&
+    assert(SGV->hasInitializer() ||
+           SGV->hasExternalLinkage() || SGV->hasDLLImportLinkage() &&
            "Global must either be external or have an initializer!");
 
     GlobalValue::LinkageTypes NewLinkage;
@@ -565,7 +578,7 @@
 //
 static bool LinkFunctionProtos(Module *Dest, const Module *Src,
                                std::map<const Value*, Value*> &ValueMap,
-                             std::map<std::string, GlobalValue*> &GlobalsByName,
+                               std::map<std::string, GlobalValue*> &GlobalsByName,
                                std::string *Err) {
   SymbolTable *ST = (SymbolTable*)&Dest->getSymbolTable();
 
@@ -604,12 +617,19 @@
     } else if (SF->isExternal()) {
       // If SF is external or if both SF & DF are external..  Just link the
       // external functions, we aren't adding anything.
-      ValueMap.insert(std::make_pair(SF, DF));
-    } else if (DF->isExternal()) {   // If DF is external but SF is not...
+      if (SF->hasDLLImportLinkage()) {
+        if (DF->isExternal()) {
+          ValueMap.insert(std::make_pair(SF, DF));
+          DF->setLinkage(SF->getLinkage());          
+        }        
+      } else {
+        ValueMap.insert(std::make_pair(SF, DF));
+      }      
+    } else if (DF->isExternal() && !DF->hasDLLImportLinkage()) {
+      // If DF is external but SF is not...
       // Link the external functions, update linkage qualifiers
       ValueMap.insert(std::make_pair(SF, DF));
       DF->setLinkage(SF->getLinkage());
-
     } else if (SF->hasWeakLinkage() || SF->hasLinkOnceLinkage()) {
       // At this point we know that DF has LinkOnce, Weak, or External linkage.
       ValueMap.insert(std::make_pair(SF, DF));
diff --git a/lib/Target/Alpha/AlphaAsmPrinter.cpp b/lib/Target/Alpha/AlphaAsmPrinter.cpp
index 2ce4865..52e2bb6 100644
--- a/lib/Target/Alpha/AlphaAsmPrinter.cpp
+++ b/lib/Target/Alpha/AlphaAsmPrinter.cpp
@@ -258,6 +258,14 @@
         case GlobalValue::GhostLinkage:
           std::cerr << "GhostLinkage cannot appear in AlphaAsmPrinter!\n";
           abort();
+        case GlobalValue::DLLImportLinkage:
+          std::cerr << "DLLImport linkage is not supported by this target!\n";
+          abort();
+        case GlobalValue::DLLExportLinkage:
+          std::cerr << "DLLExport linkage is not supported by this target!\n";
+          abort();
+        default:
+          assert(0 && "Unknown linkage type!");
         }
 
         EmitAlignment(Align);
diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp
index 330a7bc..2aa3627 100644
--- a/lib/Target/CBackend/CBackend.cpp
+++ b/lib/Target/CBackend/CBackend.cpp
@@ -1054,7 +1054,11 @@
         Out << "extern ";
         printType(Out, I->getType()->getElementType(), Mang->getValueName(I));
         Out << ";\n";
-      }
+      } else if (I->hasDLLImportLinkage()) {
+        Out << "__declspec(dllimport) ";
+        printType(Out, I->getType()->getElementType(), Mang->getValueName(I));
+        Out << ";\n";        
+      }      
     }
   }
 
@@ -1118,6 +1122,11 @@
         
         if (I->hasInternalLinkage())
           Out << "static ";
+        else if (I->hasDLLImportLinkage())
+          Out << "__declspec(dllimport) ";
+        else if (I->hasDLLExportLinkage())
+          Out << "__declspec(dllexport) ";
+            
         printType(Out, I->getType()->getElementType(), Mang->getValueName(I));
         if (I->hasLinkOnceLinkage())
           Out << " __attribute__((common))";
@@ -1267,6 +1276,8 @@
   bool isCStructReturn = F->getCallingConv() == CallingConv::CSRet;
   
   if (F->hasInternalLinkage()) Out << "static ";
+  if (F->hasDLLImportLinkage()) Out << "__declspec(dllimport) ";
+  if (F->hasDLLExportLinkage()) Out << "__declspec(dllexport) ";  
 
   // Loop over the arguments, printing them...
   const FunctionType *FT = cast<FunctionType>(F->getFunctionType());
diff --git a/lib/Target/CBackend/Writer.cpp b/lib/Target/CBackend/Writer.cpp
index 330a7bc..2aa3627 100644
--- a/lib/Target/CBackend/Writer.cpp
+++ b/lib/Target/CBackend/Writer.cpp
@@ -1054,7 +1054,11 @@
         Out << "extern ";
         printType(Out, I->getType()->getElementType(), Mang->getValueName(I));
         Out << ";\n";
-      }
+      } else if (I->hasDLLImportLinkage()) {
+        Out << "__declspec(dllimport) ";
+        printType(Out, I->getType()->getElementType(), Mang->getValueName(I));
+        Out << ";\n";        
+      }      
     }
   }
 
@@ -1118,6 +1122,11 @@
         
         if (I->hasInternalLinkage())
           Out << "static ";
+        else if (I->hasDLLImportLinkage())
+          Out << "__declspec(dllimport) ";
+        else if (I->hasDLLExportLinkage())
+          Out << "__declspec(dllexport) ";
+            
         printType(Out, I->getType()->getElementType(), Mang->getValueName(I));
         if (I->hasLinkOnceLinkage())
           Out << " __attribute__((common))";
@@ -1267,6 +1276,8 @@
   bool isCStructReturn = F->getCallingConv() == CallingConv::CSRet;
   
   if (F->hasInternalLinkage()) Out << "static ";
+  if (F->hasDLLImportLinkage()) Out << "__declspec(dllimport) ";
+  if (F->hasDLLExportLinkage()) Out << "__declspec(dllexport) ";  
 
   // Loop over the arguments, printing them...
   const FunctionType *FT = cast<FunctionType>(F->getFunctionType());
diff --git a/lib/Target/IA64/IA64AsmPrinter.cpp b/lib/Target/IA64/IA64AsmPrinter.cpp
index 4a16777..5fcc86f 100644
--- a/lib/Target/IA64/IA64AsmPrinter.cpp
+++ b/lib/Target/IA64/IA64AsmPrinter.cpp
@@ -306,6 +306,14 @@
           case GlobalValue::GhostLinkage:
             std::cerr << "GhostLinkage cannot appear in IA64AsmPrinter!\n";
             abort();
+          case GlobalValue::DLLImportLinkage:
+            std::cerr << "DLLImport linkage is not supported by this target!\n";
+            abort();
+          case GlobalValue::DLLExportLinkage:
+            std::cerr << "DLLExport linkage is not supported by this target!\n";
+            abort();
+          default:
+            assert(0 && "Unknown linkage type!");            
         }
         
         EmitAlignment(Align);
diff --git a/lib/Target/Sparc/SparcAsmPrinter.cpp b/lib/Target/Sparc/SparcAsmPrinter.cpp
index 1e6efcb..f8efc9e 100644
--- a/lib/Target/Sparc/SparcAsmPrinter.cpp
+++ b/lib/Target/Sparc/SparcAsmPrinter.cpp
@@ -271,6 +271,14 @@
         case GlobalValue::GhostLinkage:
           std::cerr << "Should not have any unmaterialized functions!\n";
           abort();
+        case GlobalValue::DLLImportLinkage:
+          std::cerr << "DLLImport linkage is not supported by this target!\n";
+          abort();
+        case GlobalValue::DLLExportLinkage:
+          std::cerr << "DLLExport linkage is not supported by this target!\n";
+          abort();
+        default:
+          assert(0 && "Unknown linkage type!");          
         }
 
         O << "\t.align " << Align << "\n";
diff --git a/lib/Target/X86/X86ATTAsmPrinter.cpp b/lib/Target/X86/X86ATTAsmPrinter.cpp
index b17cde1..1ce24fd 100755
--- a/lib/Target/X86/X86ATTAsmPrinter.cpp
+++ b/lib/Target/X86/X86ATTAsmPrinter.cpp
@@ -48,10 +48,13 @@
     SwitchToTextSection(TAI->getTextSection(), F);
     EmitAlignment(4, F);     // FIXME: This should be parameterized somewhere.
     break;
+  case Function::DLLExportLinkage:
+    DLLExportedFns.insert(Mang->makeNameProper(F->getName(), ""));
+    //FALLS THROUGH
   case Function::ExternalLinkage:
     SwitchToTextSection(TAI->getTextSection(), F);
     EmitAlignment(4, F);     // FIXME: This should be parameterized somewhere.
-    O << "\t.globl\t" << CurrentFnName << "\n";
+    O << "\t.globl\t" << CurrentFnName << "\n";    
     break;
   case Function::WeakLinkage:
   case Function::LinkOnceLinkage:
@@ -179,8 +182,9 @@
     bool isMemOp  = Modifier && !strcmp(Modifier, "mem");
     if (!isMemOp && !isCallOp) O << '$';
 
-    GlobalValue *GV = MO.getGlobal();
+    GlobalValue *GV = MO.getGlobal();    
     std::string Name = Mang->getValueName(GV);
+    
     bool isExt = (GV->isExternal() || GV->hasWeakLinkage() ||
                   GV->hasLinkOnceLinkage());
     if (X86PICStyle == PICStyle::Stub &&
@@ -196,13 +200,27 @@
           GVStubs.insert(Name);
           O << "L" << Name << "$non_lazy_ptr";
         }
-      } else
+      } else {
+        if (GV->hasDLLImportLinkage()) {
+          // FIXME: This should be fixed with full support of stdcall & fastcall
+          // CC's
+          O << "__imp_";          
+        } 
         O << Name;
+      }
+      
       if (!isCallOp && TM.getRelocationModel() == Reloc::PIC_)
         O << "-\"L" << getFunctionNumber() << "$pb\"";
-    } else
+    } else {
+      if (GV->hasDLLImportLinkage()) {
+        // FIXME: This should be fixed with full support of stdcall & fastcall
+        // CC's
+        O << "__imp_";          
+      }       
       O << Name;
-
+   
+    }
+    
     int Offset = MO.getOffset();
     if (Offset > 0)
       O << "+" << Offset;
diff --git a/lib/Target/X86/X86AsmPrinter.cpp b/lib/Target/X86/X86AsmPrinter.cpp
index b634d13..08dc7b2 100644
--- a/lib/Target/X86/X86AsmPrinter.cpp
+++ b/lib/Target/X86/X86AsmPrinter.cpp
@@ -112,6 +112,9 @@
       case GlobalValue::AppendingLinkage:
         // FIXME: appending linkage variables should go into a section of
         // their name or something.  For now, just emit them as external.
+      case GlobalValue::DLLExportLinkage:
+        DLLExportedGVs.insert(Mang->makeNameProper(I->getName(),""));
+        // FALL THROUGH
       case GlobalValue::ExternalLinkage:
         // If external or appending, declare as a global symbol
         O << "\t.globl " << name << "\n";
@@ -134,6 +137,27 @@
     }
   }
   
+  // Output linker support code for dllexported globals
+  if (DLLExportedGVs.begin() != DLLExportedGVs.end()) {
+    SwitchToDataSection(".section .drectve", 0);    
+  }
+
+  for (std::set<std::string>::iterator i = DLLExportedGVs.begin(),
+         e = DLLExportedGVs.end();
+         i != e; ++i) {
+    O << "\t.ascii \" -export:" << *i << ",data\"\n";
+  }    
+
+  if (DLLExportedFns.begin() != DLLExportedFns.end()) {
+    SwitchToDataSection(".section .drectve", 0);    
+  }
+
+  for (std::set<std::string>::iterator i = DLLExportedFns.begin(),
+         e = DLLExportedFns.end();
+         i != e; ++i) {
+    O << "\t.ascii \" -export:" << *i << "\"\n";
+  }    
+ 
   if (Subtarget->isTargetDarwin()) {
     SwitchToDataSection("", 0);
 
diff --git a/lib/Target/X86/X86AsmPrinter.h b/lib/Target/X86/X86AsmPrinter.h
index 6db9e45..ae03ca5 100755
--- a/lib/Target/X86/X86AsmPrinter.h
+++ b/lib/Target/X86/X86AsmPrinter.h
@@ -63,6 +63,9 @@
   // Necessary for Darwin to print out the apprioriate types of linker stubs
   std::set<std::string> FnStubs, GVStubs, LinkOnceStubs;
 
+  // Necessary for dllexport support
+  std::set<std::string> DLLExportedFns, DLLExportedGVs;
+  
   inline static bool isScale(const MachineOperand &MO) {
     return MO.isImmediate() &&
           (MO.getImmedValue() == 1 || MO.getImmedValue() == 2 ||
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index dfd7aa5..166345c 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -1964,6 +1964,15 @@
           (GV->isExternal() && !GV->hasNotBeenReadFromBytecode()));
 }
 
+/// WinndowsGVRequiresExtraLoad - true if accessing the GV requires an extra
+/// load. For Windows, dllimported variables (not functions!) are indirect,
+/// loading the value at address GV rather then the value of GV itself. This
+/// means that the GlobalAddress must be in the base or index register of the
+/// address, not the GV offset field.
+static bool WindowsGVRequiresExtraLoad(GlobalValue *GV) {
+  return (isa<GlobalVariable>((Value*)GV) && GV->hasDLLImportLinkage());  
+}
+
 /// isUndefOrInRange - Op is either an undef node or a ConstantSDNode.  Return
 /// true if Op is undef or if its value falls within the specified range (L, H].
 static bool isUndefOrInRange(SDOperand Op, unsigned Low, unsigned Hi) {
@@ -3376,7 +3385,14 @@
         DarwinGVRequiresExtraLoad(GV))
       Result = DAG.getLoad(getPointerTy(), DAG.getEntryNode(),
                            Result, DAG.getSrcValue(NULL));
+  } else if (Subtarget->isTargetCygwin() || Subtarget->isTargetWindows()) {
+    // FIXME: What's about PIC?
+    if (WindowsGVRequiresExtraLoad(GV)) {
+      Result = DAG.getLoad(getPointerTy(), DAG.getEntryNode(),
+                           Result, DAG.getSrcValue(NULL));      
+    }    
   }
+  
 
   return Result;
 }
diff --git a/lib/Target/X86/X86IntelAsmPrinter.cpp b/lib/Target/X86/X86IntelAsmPrinter.cpp
index 24dbb15..44a218c 100755
--- a/lib/Target/X86/X86IntelAsmPrinter.cpp
+++ b/lib/Target/X86/X86IntelAsmPrinter.cpp
@@ -35,10 +35,23 @@
   EmitConstantPool(MF.getConstantPool());
 
   // Print out labels for the function.
-  SwitchToTextSection("_text", MF.getFunction());
-  EmitAlignment(4);
-  if (MF.getFunction()->getLinkage() == GlobalValue::ExternalLinkage)
+  const Function* F = MF.getFunction();
+  switch (F->getLinkage()) {
+  default: assert(0 && "Unsupported linkage type!");
+  case Function::InternalLinkage:
+    SwitchToTextSection("_text", F);
+    EmitAlignment(4);
+    break;    
+  case Function::DLLExportLinkage:
+    DLLExportedFns.insert(CurrentFnName);
+    //FALLS THROUGH
+  case Function::ExternalLinkage:
     O << "\tpublic " << CurrentFnName << "\n";
+    SwitchToTextSection("_text", F);
+    EmitAlignment(4);
+    break;    
+  }
+  
   O << CurrentFnName << "\tproc near\n";
   
   // Print out code for the function.
@@ -118,8 +131,15 @@
   case MachineOperand::MO_GlobalAddress: {
     bool isCallOp = Modifier && !strcmp(Modifier, "call");
     bool isMemOp  = Modifier && !strcmp(Modifier, "mem");
+    GlobalValue *GV = MO.getGlobal();    
+
     if (!isMemOp && !isCallOp) O << "OFFSET ";
-    O << Mang->getValueName(MO.getGlobal());
+    if (GV->hasDLLImportLinkage()) {
+      // FIXME: This should be fixed with full support of stdcall & fastcall
+      // CC's
+      O << "__imp_";          
+    } 
+    O << Mang->getValueName(GV);
     int Offset = MO.getOffset();
     if (Offset > 0)
       O << " + " << Offset;
@@ -350,6 +370,9 @@
       // FIXME: the default alignment is 16 bytes, but 1, 2, 4, and 256
       // are also available.
       break;
+    case GlobalValue::DLLExportLinkage:
+      DLLExportedGVs.insert(name);
+      // FALL THROUGH
     case GlobalValue::ExternalLinkage:
       O << "\tpublic " << name << "\n";
       // FALL THROUGH
@@ -371,6 +394,34 @@
     if (bCustomSegment)
       O << name << "?\tends\n";
   }
+
+    // Output linker support code for dllexported globals
+  if ((DLLExportedGVs.begin() != DLLExportedGVs.end()) ||
+      (DLLExportedFns.begin() != DLLExportedFns.end())) {
+    SwitchToDataSection("", 0);
+    O << "; WARNING: The following code is valid only with MASM v8.x and (possible) higher\n"
+      << "; This version of MASM is usually shipped with Microsoft Visual Studio 2005\n"
+      << "; or (possible) further versions. Unfortunately, there is no way to support\n"
+      << "; dllexported symbols in the earlier versions of MASM in fully automatic way\n\n";
+    O << "_drectve\t segment info alias('.drectve')\n";
+  }
+
+  for (std::set<std::string>::iterator i = DLLExportedGVs.begin(),
+         e = DLLExportedGVs.end();
+         i != e; ++i) {
+    O << "\t db ' /EXPORT:" << *i << ",data'\n";
+  }    
+
+  for (std::set<std::string>::iterator i = DLLExportedFns.begin(),
+         e = DLLExportedFns.end();
+         i != e; ++i) {
+    O << "\t db ' /EXPORT:" << *i << "'\n";
+  }    
+
+  if ((DLLExportedGVs.begin() != DLLExportedGVs.end()) ||
+      (DLLExportedFns.begin() != DLLExportedFns.end())) {
+    O << "_drectve\t ends\n";    
+  }
   
   // Bypass X86SharedAsmPrinter::doFinalization().
   AsmPrinter::doFinalization(M);
diff --git a/lib/Target/X86/X86Subtarget.h b/lib/Target/X86/X86Subtarget.h
index 224ebcd..6e0d1db 100644
--- a/lib/Target/X86/X86Subtarget.h
+++ b/lib/Target/X86/X86Subtarget.h
@@ -99,6 +99,8 @@
 
   bool isTargetDarwin() const { return TargetType == isDarwin; }
   bool isTargetELF() const { return TargetType == isELF; }
+  bool isTargetWindows() const { return TargetType == isWindows; }
+  bool isTargetCygwin() const { return TargetType == isCygwin; }  
 };
 } // End llvm namespace
 
diff --git a/lib/Transforms/IPO/GlobalOpt.cpp b/lib/Transforms/IPO/GlobalOpt.cpp
index 8324b43..609bd94 100644
--- a/lib/Transforms/IPO/GlobalOpt.cpp
+++ b/lib/Transforms/IPO/GlobalOpt.cpp
@@ -1245,7 +1245,7 @@
 static bool isSimpleEnoughPointerToCommit(Constant *C) {
   if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C)) {
     if (!GV->hasExternalLinkage() && !GV->hasInternalLinkage())
-      return false;  // do not allow weak/linkonce linkage.
+      return false;  // do not allow weak/linkonce/dllimport/dllexport linkage.
     return !GV->isExternal();  // reject external globals.
   }
   if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C))
@@ -1254,7 +1254,7 @@
         isa<GlobalVariable>(CE->getOperand(0))) {
       GlobalVariable *GV = cast<GlobalVariable>(CE->getOperand(0));
       if (!GV->hasExternalLinkage() && !GV->hasInternalLinkage())
-        return false;  // do not allow weak/linkonce linkage.
+        return false;  // do not allow weak/linkonce/dllimport/dllexport linkage.
       return GV->hasInitializer() &&
              ConstantFoldLoadThroughGEPConstantExpr(GV->getInitializer(), CE);
     }
diff --git a/lib/Transforms/IPO/SimplifyLibCalls.cpp b/lib/Transforms/IPO/SimplifyLibCalls.cpp
index 79cdf28..9f9c527 100644
--- a/lib/Transforms/IPO/SimplifyLibCalls.cpp
+++ b/lib/Transforms/IPO/SimplifyLibCalls.cpp
@@ -178,8 +178,10 @@
         // All the "well-known" functions are external and have external linkage
         // because they live in a runtime library somewhere and were (probably)
         // not compiled by LLVM.  So, we only act on external functions that
-        // have external linkage and non-empty uses.
-        if (!FI->isExternal() || !FI->hasExternalLinkage() || FI->use_empty())
+        // have external or dllimport linkage and non-empty uses.
+        if (!FI->isExternal() ||
+            !(FI->hasExternalLinkage() || FI->hasDLLImportLinkage()) ||
+            FI->use_empty())
           continue;
 
         // Get the optimization class that pertains to this function
diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp
index f3bcfb5..b6f5fb3 100644
--- a/lib/VMCore/AsmWriter.cpp
+++ b/lib/VMCore/AsmWriter.cpp
@@ -845,14 +845,21 @@
   if (GV->hasName()) Out << getLLVMName(GV->getName()) << " = ";
 
   if (!GV->hasInitializer())
-    Out << "external ";
+    switch (GV->getLinkage()) {
+     case GlobalValue::DLLImportLinkage:   Out << "dllimport "; break;
+     case GlobalValue::ExternalWeakLinkage: Out << "extern_weak "; break;
+     default: Out << "external "; break;
+    }
   else
     switch (GV->getLinkage()) {
-    case GlobalValue::InternalLinkage:  Out << "internal "; break;
-    case GlobalValue::LinkOnceLinkage:  Out << "linkonce "; break;
-    case GlobalValue::WeakLinkage:      Out << "weak "; break;
-    case GlobalValue::AppendingLinkage: Out << "appending "; break;
-    case GlobalValue::ExternalLinkage: break;
+    case GlobalValue::InternalLinkage:     Out << "internal "; break;
+    case GlobalValue::LinkOnceLinkage:     Out << "linkonce "; break;
+    case GlobalValue::WeakLinkage:         Out << "weak "; 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::ExternalLinkage:     break;
     case GlobalValue::GhostLinkage:
       std::cerr << "GhostLinkage not allowed in AsmWriter!\n";
       abort();
@@ -937,13 +944,20 @@
   if (AnnotationWriter) AnnotationWriter->emitFunctionAnnot(F, Out);
 
   if (F->isExternal())
-    Out << "declare ";
+    switch (F->getLinkage()) {
+    case GlobalValue::DLLImportLinkage:    Out << "declare dllimport "; break;
+    case GlobalValue::ExternalWeakLinkage: Out << "declare extern_weak "; break;
+    default: Out << "declare ";
+    }
   else
     switch (F->getLinkage()) {
-    case GlobalValue::InternalLinkage:  Out << "internal "; break;
-    case GlobalValue::LinkOnceLinkage:  Out << "linkonce "; break;
-    case GlobalValue::WeakLinkage:      Out << "weak "; break;
-    case GlobalValue::AppendingLinkage: Out << "appending "; break;
+    case GlobalValue::InternalLinkage:     Out << "internal "; break;
+    case GlobalValue::LinkOnceLinkage:     Out << "linkonce "; break;
+    case GlobalValue::WeakLinkage:         Out << "weak "; 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::ExternalLinkage: break;
     case GlobalValue::GhostLinkage:
       std::cerr << "GhostLinkage not allowed in AsmWriter!\n";
diff --git a/lib/VMCore/Mangler.cpp b/lib/VMCore/Mangler.cpp
index 8715498..b3211a3 100644
--- a/lib/VMCore/Mangler.cpp
+++ b/lib/VMCore/Mangler.cpp
@@ -162,11 +162,16 @@
     ExistingValue = GV;
   } else {
     // If GV is external but the existing one is static, mangle the existing one
-    if (GV->hasExternalLinkage() && !ExistingValue->hasExternalLinkage()) {
+    if ((GV->hasExternalLinkage() || GV->hasDLLImportLinkage()) &&
+        !(ExistingValue->hasExternalLinkage() || ExistingValue->hasDLLImportLinkage())) {
       MangledGlobals.insert(ExistingValue);
       ExistingValue = GV;
-    } else if (GV->hasExternalLinkage() && ExistingValue->hasExternalLinkage()&&
-               GV->isExternal() && ExistingValue->isExternal()) {
+    } else if ((GV->hasExternalLinkage() ||
+                GV->hasDLLImportLinkage()) &&
+               (ExistingValue->hasExternalLinkage() ||
+                ExistingValue->hasDLLImportLinkage()) &&
+               GV->isExternal() &&
+               ExistingValue->isExternal()) {
       // If the two globals both have external inkage, and are both external,
       // don't mangle either of them, we just have some silly type mismatch.
     } else {
diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp
index 606a43f..cbef68b 100644
--- a/lib/VMCore/Verifier.cpp
+++ b/lib/VMCore/Verifier.cpp
@@ -257,8 +257,16 @@
 
 
 void Verifier::visitGlobalValue(GlobalValue &GV) {
-  Assert1(!GV.isExternal() || GV.hasExternalLinkage(),
-          "Global is external, but doesn't have external linkage!", &GV);
+  Assert1(!GV.isExternal() ||
+          GV.hasExternalLinkage() ||
+          GV.hasDLLImportLinkage() ||
+          GV.hasExternalWeakLinkage(),
+  "Global is external, but doesn't have external or dllimport or weak linkage!",
+          &GV);
+
+  Assert1(!GV.hasDLLImportLinkage() || GV.isExternal(),
+          "Global is marked as dllimport, but not external", &GV);
+  
   Assert1(!GV.hasAppendingLinkage() || isa<GlobalVariable>(GV),
           "Only global variables can have appending linkage!", &GV);