Reapply 56585:56589 with proper fix for some gcc versions

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@56621 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/X86/X86TargetAsmInfo.cpp b/lib/Target/X86/X86TargetAsmInfo.cpp
index c6a76f2..fcd797e 100644
--- a/lib/Target/X86/X86TargetAsmInfo.cpp
+++ b/lib/Target/X86/X86TargetAsmInfo.cpp
@@ -25,27 +25,26 @@
 using namespace llvm;
 using namespace llvm::dwarf;
 
-static const char *const x86_asm_table[] = {
-                                      "{si}", "S",
-                                      "{di}", "D",
-                                      "{ax}", "a",
-                                      "{cx}", "c",
-                                      "{memory}", "memory",
-                                      "{flags}", "",
-                                      "{dirflag}", "",
-                                      "{fpsr}", "",
-                                      "{cc}", "cc",
-                                      0,0};
+const char *const llvm::x86_asm_table[] = {
+  "{si}", "S",
+  "{di}", "D",
+  "{ax}", "a",
+  "{cx}", "c",
+  "{memory}", "memory",
+  "{flags}", "",
+  "{dirflag}", "",
+  "{fpsr}", "",
+  "{cc}", "cc",
+  0,0};
 
-X86TargetAsmInfo::X86TargetAsmInfo(const X86TargetMachine &TM) {
-  const X86Subtarget *Subtarget = &TM.getSubtarget<X86Subtarget>();
+TEMPLATE_INSTANTIATION(class X86TargetAsmInfo<TargetAsmInfo>);
+TEMPLATE_INSTANTIATION(
+  bool X86TargetAsmInfo<TargetAsmInfo>::ExpandInlineAsm(CallInst*) const);
+TEMPLATE_INSTANTIATION(
+  bool X86TargetAsmInfo<TargetAsmInfo>::LowerToBSwap(CallInst*) const);
 
-  AsmTransCBE = x86_asm_table;
-
-  AssemblerDialect = Subtarget->getAsmFlavor();
-}
-
-bool X86TargetAsmInfo::LowerToBSwap(CallInst *CI) const {
+template <class BaseTAI>
+bool X86TargetAsmInfo<BaseTAI>::LowerToBSwap(CallInst *CI) const {
   // FIXME: this should verify that we are targetting a 486 or better.  If not,
   // we will turn this bswap into something that will be lowered to logical ops
   // instead of emitting the bswap asm.  For now, we don't support 486 or lower
@@ -74,7 +73,8 @@
   return true;
 }
 
-bool X86TargetAsmInfo::ExpandInlineAsm(CallInst *CI) const {
+template <class BaseTAI>
+bool X86TargetAsmInfo<BaseTAI>::ExpandInlineAsm(CallInst *CI) const {
   InlineAsm *IA = cast<InlineAsm>(CI->getCalledValue());
   std::vector<InlineAsm::ConstraintInfo> Constraints = IA->ParseConstraints();
 
@@ -125,7 +125,7 @@
 }
 
 X86DarwinTargetAsmInfo::X86DarwinTargetAsmInfo(const X86TargetMachine &TM):
-  X86TargetAsmInfo(TM), DarwinTargetAsmInfo(TM) {
+  X86TargetAsmInfo<DarwinTargetAsmInfo>(TM) {
   const X86Subtarget* Subtarget = &DTM->getSubtarget<X86Subtarget>();
   bool is64Bit = Subtarget->is64Bit();
 
@@ -225,7 +225,7 @@
 }
 
 X86ELFTargetAsmInfo::X86ELFTargetAsmInfo(const X86TargetMachine &TM):
-  X86TargetAsmInfo(TM), ELFTargetAsmInfo(TM) {
+  X86TargetAsmInfo<ELFTargetAsmInfo>(TM) {
 
   CStringSection = ".rodata.str";
   PrivateGlobalPrefix = ".L";
@@ -302,7 +302,7 @@
 }
 
 X86COFFTargetAsmInfo::X86COFFTargetAsmInfo(const X86TargetMachine &TM):
-  X86TargetAsmInfo(TM) {
+  X86GenericTargetAsmInfo(TM) {
   X86TM = &TM;
 
   GlobalPrefix = "_";
@@ -408,7 +408,7 @@
 }
 
 X86WinTargetAsmInfo::X86WinTargetAsmInfo(const X86TargetMachine &TM):
-  X86TargetAsmInfo(TM) {
+  X86GenericTargetAsmInfo(TM) {
   GlobalPrefix = "_";
   CommentString = ";";
 
diff --git a/lib/Target/X86/X86TargetAsmInfo.h b/lib/Target/X86/X86TargetAsmInfo.h
index d7e11e0..9100fc0 100644
--- a/lib/Target/X86/X86TargetAsmInfo.h
+++ b/lib/Target/X86/X86TargetAsmInfo.h
@@ -14,17 +14,25 @@
 #ifndef X86TARGETASMINFO_H
 #define X86TARGETASMINFO_H
 
+#include "X86TargetMachine.h"
 #include "llvm/Target/TargetAsmInfo.h"
 #include "llvm/Target/ELFTargetAsmInfo.h"
 #include "llvm/Target/DarwinTargetAsmInfo.h"
+#include "llvm/Support/Compiler.h"
 
 namespace llvm {
 
-  // Forward declaration.
-  class X86TargetMachine;
+  extern const char *const x86_asm_table[];
 
-  struct X86TargetAsmInfo : public virtual TargetAsmInfo {
-    explicit X86TargetAsmInfo(const X86TargetMachine &TM);
+  template <class BaseTAI>
+  struct X86TargetAsmInfo : public BaseTAI {
+    explicit X86TargetAsmInfo(const X86TargetMachine &TM):
+      BaseTAI(TM) {
+      const X86Subtarget *Subtarget = &TM.getSubtarget<X86Subtarget>();
+
+      BaseTAI::AsmTransCBE = x86_asm_table;
+      BaseTAI::AssemblerDialect = Subtarget->getAsmFlavor();
+    }
 
     virtual bool ExpandInlineAsm(CallInst *CI) const;
 
@@ -32,21 +40,23 @@
     bool LowerToBSwap(CallInst *CI) const;
   };
 
-  struct X86DarwinTargetAsmInfo : public X86TargetAsmInfo,
-                                  public DarwinTargetAsmInfo {
+  typedef X86TargetAsmInfo<TargetAsmInfo> X86GenericTargetAsmInfo;
+
+  EXTERN_TEMPLATE_INSTANTIATION(class X86TargetAsmInfo<TargetAsmInfo>);
+
+  struct X86DarwinTargetAsmInfo : public X86TargetAsmInfo<DarwinTargetAsmInfo> {
     explicit X86DarwinTargetAsmInfo(const X86TargetMachine &TM);
     virtual unsigned PreferredEHDataFormat(DwarfEncoding::Target Reason,
                                            bool Global) const;
   };
 
-  struct X86ELFTargetAsmInfo : public X86TargetAsmInfo,
-                               public ELFTargetAsmInfo {
+  struct X86ELFTargetAsmInfo : public X86TargetAsmInfo<ELFTargetAsmInfo> {
     explicit X86ELFTargetAsmInfo(const X86TargetMachine &TM);
     virtual unsigned PreferredEHDataFormat(DwarfEncoding::Target Reason,
                                            bool Global) const;
   };
 
-  struct X86COFFTargetAsmInfo : public X86TargetAsmInfo {
+  struct X86COFFTargetAsmInfo : public X86GenericTargetAsmInfo {
     explicit X86COFFTargetAsmInfo(const X86TargetMachine &TM);
     virtual unsigned PreferredEHDataFormat(DwarfEncoding::Target Reason,
                                            bool Global) const;
@@ -57,9 +67,11 @@
     const X86TargetMachine *X86TM;
   };
 
-  struct X86WinTargetAsmInfo : public X86TargetAsmInfo {
+  struct X86WinTargetAsmInfo : public X86GenericTargetAsmInfo {
     explicit X86WinTargetAsmInfo(const X86TargetMachine &TM);
   };
+
 } // namespace llvm
 
 #endif
+
diff --git a/lib/Target/X86/X86TargetMachine.cpp b/lib/Target/X86/X86TargetMachine.cpp
index 5be5c5d..08753e7 100644
--- a/lib/Target/X86/X86TargetMachine.cpp
+++ b/lib/Target/X86/X86TargetMachine.cpp
@@ -54,7 +54,7 @@
      case X86Subtarget::isWindows:
       return new X86WinTargetAsmInfo(*this);
      default:
-      return new X86TargetAsmInfo(*this);
+      return new X86GenericTargetAsmInfo(*this);
     }
 }