Add full dllimport / dllexport support: both sema checks and codegen.
Patch by Ilya Okonsky

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@61437 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index e83d2cd..fc1b108 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -218,17 +218,30 @@
   // approximation of what we really want.
   if (!ForDefinition) {
     // Only a few attributes are set on declarations.
-    if (D->getAttr<DLLImportAttr>())
-      GV->setLinkage(llvm::Function::DLLImportLinkage);
+    if (D->getAttr<DLLImportAttr>()) {
+      // The dllimport attribute is overridden by a subsequent declaration as
+      // dllexport.
+      if (!D->getAttr<DLLExportAttr>())
+        // dllimport attribute can be applied only to function decls, not to
+        // definitions.
+        if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+          if (!FD->getBody())
+            GV->setLinkage(llvm::Function::DLLImportLinkage);
+        } else
+          GV->setLinkage(llvm::Function::DLLImportLinkage);
+    }
   } else {
     if (IsInternal) {
       GV->setLinkage(llvm::Function::InternalLinkage);
     } else {
-      if (D->getAttr<DLLImportAttr>())
-        GV->setLinkage(llvm::Function::DLLImportLinkage);
-      else if (D->getAttr<DLLExportAttr>())
-        GV->setLinkage(llvm::Function::DLLExportLinkage);
-      else if (D->getAttr<WeakAttr>() || IsInline)
+      if (D->getAttr<DLLExportAttr>()) {
+        if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+          // The dllexport attribute is ignored for undefined symbols.
+          if (FD->getBody())
+            GV->setLinkage(llvm::Function::DLLExportLinkage);
+        } else
+          GV->setLinkage(llvm::Function::DLLExportLinkage);
+      } else if (D->getAttr<WeakAttr>() || IsInline)
         GV->setLinkage(llvm::Function::WeakLinkage);
     }
   }