move reasoning about darwin $non_lazy_ptr stubs from asmprinter into
[oota-llvm.git] / lib / Target / X86 / AsmPrinter / X86ATTAsmPrinter.cpp
index 1b76606178f3f138e3a575010bf10646aae008b3..44d1e25461d93c1eefce1d3014f1f45c5f5470d2 100644 (file)
@@ -52,7 +52,7 @@ void X86ATTAsmPrinter::PrintPICBaseSymbol() const {
   if (Subtarget->isTargetDarwin())
     O << "\"L" << getFunctionNumber() << "$pb\"";
   else if (Subtarget->isTargetELF())
-    O << ".Lllvm$" << getFunctionNumber() << "." "$piclabel";
+    O << ".Lllvm$" << getFunctionNumber() << ".$piclabel";
   else
     assert(0 && "Don't know how to print PIC label!\n");
 }
@@ -154,21 +154,13 @@ void X86ATTAsmPrinter::decorateName(std::string &Name,
   }
 }
 
-
-
 void X86ATTAsmPrinter::emitFunctionHeader(const MachineFunction &MF) {
+  unsigned FnAlign = MF.getAlignment();
   const Function *F = MF.getFunction();
 
   decorateName(CurrentFnName, F);
 
   SwitchToSection(TAI->SectionForGlobal(F));
-
-  // FIXME: A function's alignment should be part of MachineFunction.  There
-  // shouldn't be a policy decision here.
-  unsigned FnAlign = 4;
-  if (F->hasFnAttr(Attribute::OptimizeForSize))
-    FnAlign = 1;
-  
   switch (F->getLinkage()) {
   default: assert(0 && "Unknown linkage type!");
   case Function::InternalLinkage:  // Symbols default to internal.
@@ -290,18 +282,6 @@ bool X86ATTAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
   return false;
 }
 
-static inline bool shouldPrintGOT(TargetMachine &TM, const X86Subtarget* ST) {
-  return ST->isPICStyleGOT() && TM.getRelocationModel() == Reloc::PIC_;
-}
-
-static inline bool shouldPrintPLT(TargetMachine &TM, const X86Subtarget* ST) {
-  return ST->isTargetELF() && TM.getRelocationModel() == Reloc::PIC_;
-}
-
-static inline bool shouldPrintStub(TargetMachine &TM, const X86Subtarget* ST) {
-  return ST->isPICStyleStub() && TM.getRelocationModel() != Reloc::Static;
-}
-
 /// print_pcrel_imm - This is used to print an immediate value that ends up
 /// being encoded as a pc-relative value.  These print slightly differently, for
 /// example, a $ is not emitted.
@@ -329,54 +309,25 @@ void X86ATTAsmPrinter::print_pcrel_imm(const MachineInstr *MI, unsigned OpNo) {
       needCloseParen = true;
     }
     
-    if (shouldPrintStub(TM, Subtarget)) {
-      // DARWIN/X86-32 in != static mode.
-      
-      // Link-once, declaration, or Weakly-linked global variables need
-      // non-lazily-resolved stubs
-      if (GV->isDeclaration() || GV->isWeakForLinker()) {
-        // Dynamically-resolved functions need a stub for the function.
-        if (isa<Function>(GV)) {
-          // Function stubs are no longer needed for Mac OS X 10.5 and up.
-          if (Subtarget->isTargetDarwin() && Subtarget->getDarwinVers() >= 9) {
-            O << Name;
-          } else {
-            FnStubs.insert(Name);
-            printSuffixedName(Name, "$stub");
-          }
-        } else if (GV->hasHiddenVisibility()) {
-          if (!GV->isDeclaration() && !GV->hasCommonLinkage())
-            // Definition is not definitely in the current translation unit.
-            O << Name;
-          else {
-            HiddenGVStubs.insert(Name);
-            printSuffixedName(Name, "$non_lazy_ptr");
-          }
-        } else {
-          GVStubs.insert(Name);
-          printSuffixedName(Name, "$non_lazy_ptr");
-        }
-      } else {
-        if (GV->hasDLLImportLinkage())
-          O << "__imp_";
-        O << Name;
-      }
+    // Handle dllimport linkage.
+    if (MO.getTargetFlags() == X86II::MO_DLLIMPORT)
+      O << "__imp_";
+    
+    if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB) {
+      FnStubs.insert(Name);
+      printSuffixedName(Name, "$stub");
     } else {
-      if (GV->hasDLLImportLinkage())
-        O << "__imp_";
       O << Name;
-      
-      if (shouldPrintPLT(TM, Subtarget)) {
-        // Assemble call via PLT for externally visible symbols
-        if (!GV->hasHiddenVisibility() && !GV->hasProtectedVisibility() &&
-            !GV->hasLocalLinkage())
-          O << "@PLT";
-      }
-      if (Subtarget->isTargetCygMing() && GV->isDeclaration())
-        // Save function name for later type emission
-        FnStubs.insert(Name);
     }
     
+    // Assemble call via PLT for externally visible symbols.
+    if (MO.getTargetFlags() == X86II::MO_PLT)
+      O << "@PLT";
+    
+    if (Subtarget->isTargetCygMing() && GV->isDeclaration())
+      // Save function name for later type emission
+      CygMingStubs.insert(Name);
+    
     printOffset(MO.getOffset());
     
     if (needCloseParen)
@@ -388,16 +339,7 @@ void X86ATTAsmPrinter::print_pcrel_imm(const MachineInstr *MI, unsigned OpNo) {
     bool needCloseParen = false;
     std::string Name(TAI->getGlobalPrefix());
     Name += MO.getSymbolName();
-    // Print function stub suffix unless it's Mac OS X 10.5 and up.
-    if (shouldPrintStub(TM, Subtarget) && 
-        // DARWIN/X86-32 in != static mode.
-        !(Subtarget->isTargetDarwin() && Subtarget->getDarwinVers() >= 9)) {
-      
-      FnStubs.insert(Name);
-      printSuffixedName(Name, "$stub");
-      return;
-    }
-    
+     
     if (Name[0] == '$') {
       // The name begins with a dollar-sign. In order to avoid having it look
       // like an integer immediate to the assembler, enclose it in parens.
@@ -405,7 +347,12 @@ void X86ATTAsmPrinter::print_pcrel_imm(const MachineInstr *MI, unsigned OpNo) {
       needCloseParen = true;
     }
     
-    O << Name;
+    if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB) {
+      FnStubs.insert(Name);
+      printSuffixedName(Name, "$stub");
+    } else {
+      O << Name;
+    }
     
     if (MO.getTargetFlags() == X86II::MO_GOT_ABSOLUTE_ADDRESS) {
       O << " + [.-";
@@ -413,7 +360,7 @@ void X86ATTAsmPrinter::print_pcrel_imm(const MachineInstr *MI, unsigned OpNo) {
       O << ']';
     }
     
-    if (shouldPrintPLT(TM, Subtarget))
+    if (MO.getTargetFlags() == X86II::MO_PLT)
       O << "@PLT";
     
     if (needCloseParen)
@@ -425,9 +372,10 @@ void X86ATTAsmPrinter::print_pcrel_imm(const MachineInstr *MI, unsigned OpNo) {
 }
 
 void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
-                                    const char *Modifier, bool NotRIPRel) {
+                                    const char *Modifier) {
   const MachineOperand &MO = MI->getOperand(OpNo);
   switch (MO.getType()) {
+  default: assert(0 && "unknown operand type!");
   case MachineOperand::MO_Register: {
     assert(TargetRegisterInfo::isPhysicalRegister(MO.getReg()) &&
            "Virtual registers should not make it this far!");
@@ -444,8 +392,7 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
   }
 
   case MachineOperand::MO_Immediate:
-    if (!Modifier || (strcmp(Modifier, "debug") &&
-                      strcmp(Modifier, "mem")))
+    if (!Modifier || (strcmp(Modifier, "debug") && strcmp(Modifier, "mem")))
       O << '$';
     O << MO.getImm();
     return;
@@ -454,31 +401,7 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
     if (!isMemOp) O << '$';
     O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() << '_'
       << MO.getIndex();
-
-    switch (MO.getTargetFlags()) {
-    default:
-      assert(0 && "Unknown target flag on jump table operand");
-    case X86II::MO_NO_FLAG:
-      // FIXME: REMOVE EVENTUALLY.
-      if (TM.getRelocationModel() == Reloc::PIC_) {
-        assert(!Subtarget->isPICStyleStub() &&
-               !Subtarget->isPICStyleGOT() &&
-               "Should have operand flag!");
-      }
-        
-      break;
-    case X86II::MO_PIC_BASE_OFFSET:
-      O << '-';
-      PrintPICBaseSymbol();
-      break;
-    case X86II::MO_GOTOFF:
-      O << "@GOTOFF";
-      break;
-    }
-
-    if (isMemOp && Subtarget->isPICStyleRIPRel() && !NotRIPRel)
-      O << "(%rip)";
-    return;
+    break;
   }
   case MachineOperand::MO_ConstantPoolIndex: {
     bool isMemOp  = Modifier && !strcmp(Modifier, "mem");
@@ -487,50 +410,15 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
       << MO.getIndex();
 
     printOffset(MO.getOffset());
-
-    switch (MO.getTargetFlags()) {
-    default:
-      assert(0 && "Unknown target flag on constant pool operand");
-    case X86II::MO_NO_FLAG:
-      // FIXME: REMOVE EVENTUALLY.
-      if (TM.getRelocationModel() == Reloc::PIC_) {
-        assert(!Subtarget->isPICStyleStub() &&
-               !Subtarget->isPICStyleGOT() &&
-               "Should have operand flag!");
-      }
-      
-      break;
-    case X86II::MO_PIC_BASE_OFFSET:
-      O << '-';
-      PrintPICBaseSymbol();
-      break;
-    case X86II::MO_GOTOFF:
-      O << "@GOTOFF";
-      break;
-    }
-
-    if (isMemOp && Subtarget->isPICStyleRIPRel() && !NotRIPRel)
-      O << "(%rip)";
-    return;
+    break;
   }
   case MachineOperand::MO_GlobalAddress: {
     bool isMemOp = Modifier && !strcmp(Modifier, "mem");
-    bool needCloseParen = false;
-
     const GlobalValue *GV = MO.getGlobal();
-    const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV);
-    if (!GVar) {
-      // If GV is an alias then use the aliasee for determining
-      // thread-localness.
-      if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(GV))
-        GVar =dyn_cast_or_null<GlobalVariable>(GA->resolveAliasedGlobal(false));
-    }
-
-    bool isThreadLocal = GVar && GVar->isThreadLocal();
-
     std::string Name = Mang->getValueName(GV);
     decorateName(Name, GV);
 
+    bool needCloseParen = false;
     if (!isMemOp)
       O << '$';
     else if (Name[0] == '$') {
@@ -540,138 +428,69 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
       needCloseParen = true;
     }
 
-    if (shouldPrintStub(TM, Subtarget)) {
-      // DARWIN/X86-32 in != static mode.
-
-      // Link-once, declaration, or Weakly-linked global variables need
-      // non-lazily-resolved stubs
-      if (GV->isDeclaration() || GV->isWeakForLinker()) {
-        // Dynamically-resolved functions need a stub for the function.
-        if (GV->hasHiddenVisibility()) {
-          if (!GV->isDeclaration() && !GV->hasCommonLinkage())
-            // Definition is not definitely in the current translation unit.
-            O << Name;
-          else {
-            HiddenGVStubs.insert(Name);
-            printSuffixedName(Name, "$non_lazy_ptr");
-          }
-        } else {
-          GVStubs.insert(Name);
-          printSuffixedName(Name, "$non_lazy_ptr");
-        }
-      } else {
-        if (GV->hasDLLImportLinkage())
-          O << "__imp_";
-        O << Name;
-      }
-
-      if (TM.getRelocationModel() == Reloc::PIC_) {
-        O << '-';
-        PrintPICBaseSymbol();
-      }        
+    // Handle dllimport linkage.
+    if (MO.getTargetFlags() == X86II::MO_DLLIMPORT) {
+      O << "__imp_" << Name;
+    } else if (MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY ||
+               MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE) {
+      GVStubs.insert(Name);
+      printSuffixedName(Name, "$non_lazy_ptr");
+    } else if (MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY ||
+               MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE){
+      HiddenGVStubs.insert(Name);
+      printSuffixedName(Name, "$non_lazy_ptr");
     } else {
-      if (GV->hasDLLImportLinkage())
-        O << "__imp_";
       O << Name;
     }
 
-    printOffset(MO.getOffset());
-
     if (needCloseParen)
       O << ')';
     
-    bool isRIPRelative = false;
-
-    switch (MO.getTargetFlags()) {
-    default:
-      assert(0 && "Unknown target flag on GV operand");
-    case X86II::MO_NO_FLAG:
-      // FIXME: RIP THIS CHECKING CODE OUT EVENTUALLY.
-      if (isThreadLocal)
-        assert(0 && "Not lowered right");
-      break;
-    case X86II::MO_TLSGD:
-      O << "@TLSGD";
-      break;
-    case X86II::MO_GOTTPOFF:
-      O << "@GOTTPOFF";
-      assert(!NotRIPRel);
-      isRIPRelative = true;
-      break;
-    case X86II::MO_INDNTPOFF:
-      O << "@INDNTPOFF";
-      break;
-    case X86II::MO_TPOFF:
-      O << "@TPOFF";
-      break;
-    case X86II::MO_NTPOFF:
-      O << "@NTPOFF";
-      break;
-    }
-    
-    if (isThreadLocal) {
-      // DEAD
-    } else if (isMemOp) {
-      if (shouldPrintGOT(TM, Subtarget)) {
-        if (Subtarget->GVRequiresExtraLoad(GV, TM, false))
-          O << "@GOT";
-        else
-          O << "@GOTOFF";
-      } else if (Subtarget->isPICStyleRIPRel() &&
-                 !NotRIPRel) {
-        if (TM.getRelocationModel() != Reloc::Static) {
-          if (Subtarget->GVRequiresExtraLoad(GV, TM, false))
-            O << "@GOTPCREL";
-        }
-        
-        isRIPRelative = true;
-      }
-    }
-
-    // Use rip when possible to reduce code size, except when
-    // index or base register are also part of the address. e.g.
-    // foo(%rip)(%rcx,%rax,4) is not legal.
-    if (isRIPRelative)
-      O << "(%rip)";
-    
-    return;
+    printOffset(MO.getOffset());
+    break;
   }
-  case MachineOperand::MO_ExternalSymbol: {
-    bool isMemOp  = Modifier && !strcmp(Modifier, "mem");
-    bool needCloseParen = false;
-    std::string Name(TAI->getGlobalPrefix());
-    Name += MO.getSymbolName();
-
-    // Print function stub suffix unless it's Mac OS X 10.5 and up.
-    if (!isMemOp)
-      O << '$';
-    else if (Name[0] == '$') {
-      // The name begins with a dollar-sign. In order to avoid having it look
-      // like an integer immediate to the assembler, enclose it in parens.
-      O << '(';
-      needCloseParen = true;
-    }
-
-    O << Name;
-
-    if (MO.getTargetFlags() == X86II::MO_GOT_ABSOLUTE_ADDRESS) {
-      O << " + [.-";
-      PrintPICBaseSymbol();
-      O << ']';
-    } else {
-      assert(MO.getTargetFlags() == X86II::MO_NO_FLAG &&
-             "Unknown operand flag for external symbol");
-    }
-
-    if (needCloseParen)
-      O << ')';
-
-    if (Subtarget->isPICStyleRIPRel())
-      O << "(%rip)";
-    return;
+  case MachineOperand::MO_ExternalSymbol:
+    /// NOTE: MO_ExternalSymbol in a non-pcrel_imm context is *only* generated
+    /// by _GLOBAL_OFFSET_TABLE_ on X86-32.  All others are call operands, which
+    /// are pcrel_imm's.
+    assert(!Subtarget->is64Bit());
+    // These are never used as memory operands.
+    assert(Modifier == 0 || strcmp(Modifier, "mem"));
+    O << '$';
+    O << TAI->getGlobalPrefix();
+    O << MO.getSymbolName();
+    break;
   }
+  
+  switch (MO.getTargetFlags()) {
   default:
-    O << "<unknown operand type>"; return;
+    assert(0 && "Unknown target flag on GV operand");
+  case X86II::MO_NO_FLAG:    // No flag.
+    break;
+  case X86II::MO_DARWIN_NONLAZY:
+  case X86II::MO_DARWIN_HIDDEN_NONLAZY:
+  case X86II::MO_DLLIMPORT:
+    // These affect the name of the symbol, not any suffix.
+    break;
+  case X86II::MO_GOT_ABSOLUTE_ADDRESS:
+    O << " + [.-";
+    PrintPICBaseSymbol();
+    O << ']';
+    break;      
+  case X86II::MO_PIC_BASE_OFFSET:
+  case X86II::MO_DARWIN_NONLAZY_PIC_BASE:
+  case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE:
+    O << '-';
+    PrintPICBaseSymbol();
+    break;
+  case X86II::MO_TLSGD:     O << "@TLSGD";     break;
+  case X86II::MO_GOTTPOFF:  O << "@GOTTPOFF";  break;
+  case X86II::MO_INDNTPOFF: O << "@INDNTPOFF"; break;
+  case X86II::MO_TPOFF:     O << "@TPOFF";     break;
+  case X86II::MO_NTPOFF:    O << "@NTPOFF";    break;
+  case X86II::MO_GOTPCREL:  O << "@GOTPCREL";  break;
+  case X86II::MO_GOT:       O << "@GOT";       break;
+  case X86II::MO_GOTOFF:    O << "@GOTOFF";    break;
   }
 }
 
@@ -691,44 +510,42 @@ void X86ATTAsmPrinter::printSSECC(const MachineInstr *MI, unsigned Op) {
 }
 
 void X86ATTAsmPrinter::printLeaMemReference(const MachineInstr *MI, unsigned Op,
-                                            const char *Modifier,
-                                            bool NotRIPRel) {
-  MachineOperand BaseReg  = MI->getOperand(Op);
-  MachineOperand IndexReg = MI->getOperand(Op+2);
+                                            const char *Modifier) {
+  const MachineOperand &BaseReg  = MI->getOperand(Op);
+  const MachineOperand &IndexReg = MI->getOperand(Op+2);
   const MachineOperand &DispSpec = MI->getOperand(Op+3);
 
-  NotRIPRel |= IndexReg.getReg() || BaseReg.getReg();
-  if (DispSpec.isGlobal() ||
-      DispSpec.isCPI() ||
-      DispSpec.isJTI() ||
-      DispSpec.isSymbol()) {
-    printOperand(MI, Op+3, "mem", NotRIPRel);
-  } else {
+  // If we really don't want to print out (rip), don't.
+  bool HasBaseReg = BaseReg.getReg() != 0;
+  if (HasBaseReg && Modifier && !strcmp(Modifier, "no-rip") &&
+      BaseReg.getReg() == X86::RIP)
+    HasBaseReg = false;
+  
+  // HasParenPart - True if we will print out the () part of the mem ref.
+  bool HasParenPart = IndexReg.getReg() || HasBaseReg;
+  
+  if (DispSpec.isImm()) {
     int DispVal = DispSpec.getImm();
-    if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg()))
+    if (DispVal || !HasParenPart)
       O << DispVal;
+  } else {
+    assert(DispSpec.isGlobal() || DispSpec.isCPI() ||
+           DispSpec.isJTI() || DispSpec.isSymbol());
+    printOperand(MI, Op+3, "mem");
   }
 
-  if (IndexReg.getReg() || BaseReg.getReg()) {
-    unsigned ScaleVal = MI->getOperand(Op+1).getImm();
-    unsigned BaseRegOperand = 0, IndexRegOperand = 2;
-
-    // There are cases where we can end up with ESP/RSP in the indexreg slot.
-    // If this happens, swap the base/index register to support assemblers that
-    // don't work when the index is *SP.
-    if (IndexReg.getReg() == X86::ESP || IndexReg.getReg() == X86::RSP) {
-      assert(ScaleVal == 1 && "Scale not supported for stack pointer!");
-      std::swap(BaseReg, IndexReg);
-      std::swap(BaseRegOperand, IndexRegOperand);
-    }
+  if (HasParenPart) {
+    assert(IndexReg.getReg() != X86::ESP &&
+           "X86 doesn't allow scaling by ESP");
 
     O << '(';
-    if (BaseReg.getReg())
-      printOperand(MI, Op+BaseRegOperand, Modifier);
+    if (HasBaseReg)
+      printOperand(MI, Op, Modifier);
 
     if (IndexReg.getReg()) {
       O << ',';
-      printOperand(MI, Op+IndexRegOperand, Modifier);
+      printOperand(MI, Op+2, Modifier);
+      unsigned ScaleVal = MI->getOperand(Op+1).getImm();
       if (ScaleVal != 1)
         O << ',' << ScaleVal;
     }
@@ -737,14 +554,14 @@ void X86ATTAsmPrinter::printLeaMemReference(const MachineInstr *MI, unsigned Op,
 }
 
 void X86ATTAsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op,
-                                         const char *Modifier, bool NotRIPRel){
+                                         const char *Modifier{
   assert(isMem(MI, Op) && "Invalid memory reference!");
-  MachineOperand Segment = MI->getOperand(Op+4);
+  const MachineOperand &Segment = MI->getOperand(Op+4);
   if (Segment.getReg()) {
-      printOperand(MI, Op+4, Modifier);
-      O << ':';
-    }
-  printLeaMemReference(MI, Op, Modifier, NotRIPRel);
+    printOperand(MI, Op+4, Modifier);
+    O << ':';
+  }
+  printLeaMemReference(MI, Op, Modifier);
 }
 
 void X86ATTAsmPrinter::printPICJumpTableSetLabel(unsigned uid,
@@ -837,7 +654,7 @@ bool X86ATTAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
     switch (ExtraCode[0]) {
     default: return true;  // Unknown modifier.
     case 'c': // Don't print "$" before a global var name or constant.
-      printOperand(MI, OpNo, "mem", /*NotRIPRel=*/true);
+      printOperand(MI, OpNo, "mem");
       return false;
     case 'b': // Print QImode register
     case 'h': // Print QImode high register
@@ -849,9 +666,20 @@ bool X86ATTAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
       printOperand(MI, OpNo);
       return false;
 
-    case 'P': // Don't print @PLT, but do print as memory.
-      printOperand(MI, OpNo, "mem", /*NotRIPRel=*/true);
+    case 'P': // This is the operand of a call, treat specially.
+      print_pcrel_imm(MI, OpNo);
       return false;
+
+    case 'n': { // Negate the immediate or print a '-' before the operand.
+      // Note: this is a temporary solution. It should be handled target
+      // independently as part of the 'MC' work.
+      const MachineOperand &MO = MI->getOperand(OpNo);
+      if (MO.isImm()) {
+        O << -MO.getImm();
+        return false;
+      }
+      O << '-';
+    }
     }
   }
 
@@ -876,7 +704,7 @@ bool X86ATTAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
       // These only apply to registers, ignore on mem.
       break;
     case 'P': // Don't print @PLT, but do print as memory.
-      printMemReference(MI, OpNo, "mem", /*NotRIPRel=*/true);
+      printMemReference(MI, OpNo, "no-rip");
       return false;
     }
   }
@@ -1174,7 +1002,7 @@ bool X86ATTAsmPrinter::doFinalization(Module &M) {
     O << "\t.subsections_via_symbols\n";
   } else if (Subtarget->isTargetCygMing()) {
     // Emit type information for external functions
-    for (StringSet<>::iterator i = FnStubs.begin(), e = FnStubs.end();
+    for (StringSet<>::iterator i = CygMingStubs.begin(), e = CygMingStubs.end();
          i != e; ++i) {
       O << "\t.def\t " << i->getKeyData()
         << ";\t.scl\t" << COFF::C_EXT