change the LabelSDNode to be EHLabelSDNode and make it hold
[oota-llvm.git] / lib / CodeGen / AsmPrinter / DwarfException.cpp
index 4f445343555eb9541a44f912627a4a7b0c89c045..b5f7270ba5e7b5b7f866a5ffd13476851b89e0cc 100644 (file)
@@ -50,25 +50,6 @@ DwarfException::~DwarfException() {
   delete ExceptionTimer;
 }
 
-/// CreateLabelDiff - Emit a label and subtract it from the expression we
-/// already have.  This is equivalent to emitting "foo - .", but we have to emit
-/// the label for "." directly.
-const MCExpr *DwarfException::CreateLabelDiff(const MCExpr *ExprRef,
-                                              const char *LabelName,
-                                              unsigned Index) {
-  SmallString<64> Name;
-  raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix()
-                            << LabelName << Asm->getFunctionNumber()
-                            << "_" << Index;
-  MCSymbol *DotSym = Asm->OutContext.GetOrCreateSymbol(Name.str());
-  Asm->OutStreamer.EmitLabel(DotSym);
-
-  return MCBinaryExpr::CreateSub(ExprRef,
-                                 MCSymbolRefExpr::Create(DotSym,
-                                                         Asm->OutContext),
-                                 Asm->OutContext);
-}
-
 /// EmitCIE - Emit a Common Information Entry (CIE). This holds information that
 /// is shared among many Frame Description Entries.  There is at least one CIE
 /// in every non-empty .debug_frame section.
@@ -84,9 +65,13 @@ void DwarfException::EmitCIE(const Function *PersonalityFn, unsigned Index) {
   // Begin eh frame section.
   Asm->OutStreamer.SwitchSection(TLOF.getEHFrameSection());
 
-  if (MAI->is_EHSymbolPrivate())
-    O << MAI->getPrivateGlobalPrefix();
-  O << "EH_frame" << Index << ":\n";
+  MCSymbol *EHFrameSym;
+  if (TLOF.isFunctionEHFrameSymbolPrivate())
+    EHFrameSym = getDWLabel("EH_frame", Index);
+  else
+    EHFrameSym = Asm->OutContext.GetOrCreateSymbol(Twine("EH_frame") + 
+                                                   Twine(Index));
+  Asm->OutStreamer.EmitLabel(EHFrameSym);
   
   Asm->OutStreamer.EmitLabel(getDWLabel("section_eh_frame", Index));
 
@@ -165,7 +150,7 @@ void DwarfException::EmitCIE(const Function *PersonalityFn, unsigned Index) {
   // Indicate locations of general callee saved registers in frame.
   std::vector<MachineMove> Moves;
   RI->getInitialFrameState(Moves);
-  EmitFrameMoves(NULL, 0, Moves, true);
+  EmitFrameMoves(0, Moves, true);
 
   // On Darwin the linker honors the alignment of eh_frame, which means it must
   // be 8-byte on 64-bit targets to match what gcc does.  Otherwise you get
@@ -189,13 +174,13 @@ void DwarfException::EmitFDE(const FunctionEHFrameInfo &EHFrameInfo) {
 
   // Externally visible entry into the functions eh frame info. If the
   // corresponding function is static, this should not be externally visible.
-  if (!TheFunc->hasLocalLinkage())
-    if (const char *GlobalEHDirective = MAI->getGlobalEHDirective())
-      O << GlobalEHDirective << *EHFrameInfo.FunctionEHSym << '\n';
+  if (!TheFunc->hasLocalLinkage() && TLOF.isFunctionEHSymbolGlobal())
+    Asm->OutStreamer.EmitSymbolAttribute(EHFrameInfo.FunctionEHSym,MCSA_Global);
 
   // If corresponding function is weak definition, this should be too.
   if (TheFunc->isWeakForLinker() && MAI->getWeakDefDirective())
-    O << MAI->getWeakDefDirective() << *EHFrameInfo.FunctionEHSym << '\n';
+    Asm->OutStreamer.EmitSymbolAttribute(EHFrameInfo.FunctionEHSym,
+                                         MCSA_WeakDefinition);
 
   // If corresponding function is hidden, this should be too.
   if (TheFunc->hasHiddenVisibility())
@@ -210,8 +195,9 @@ void DwarfException::EmitFDE(const FunctionEHFrameInfo &EHFrameInfo) {
   if (!EHFrameInfo.hasCalls && !UnwindTablesMandatory &&
       (!TheFunc->isWeakForLinker() ||
        !MAI->getWeakDefDirective() ||
-       MAI->getSupportsWeakOmittedEHFrame())) {
-    O << *EHFrameInfo.FunctionEHSym << " = 0\n";
+       TLOF.getSupportsWeakOmittedEHFrame())) {
+    Asm->OutStreamer.EmitAssignment(EHFrameInfo.FunctionEHSym,
+                                    MCConstantExpr::Create(0, Asm->OutContext));
     // This name has no connection to the function, so it might get
     // dead-stripped when the function is not, erroneously.  Prohibit
     // dead-stripping unconditionally.
@@ -219,7 +205,7 @@ void DwarfException::EmitFDE(const FunctionEHFrameInfo &EHFrameInfo) {
       Asm->OutStreamer.EmitSymbolAttribute(EHFrameInfo.FunctionEHSym,
                                            MCSA_NoDeadStrip);
   } else {
-    O << *EHFrameInfo.FunctionEHSym << ":\n";
+    Asm->OutStreamer.EmitLabel(EHFrameInfo.FunctionEHSym);
 
     // EH frame header.
     Asm->OutStreamer.AddComment("Length of Frame Information Entry");
@@ -235,12 +221,13 @@ void DwarfException::EmitFDE(const FunctionEHFrameInfo &EHFrameInfo) {
                                  EHFrameInfo.PersonalityIndex),
                       true, true);
 
+    MCSymbol *EHFuncBeginSym = getDWLabel("eh_func_begin", EHFrameInfo.Number);
 
     Asm->OutStreamer.AddComment("FDE initial location");
-    EmitReference(getDWLabel("eh_func_begin", EHFrameInfo.Number), FDEEncoding);
+    EmitReference(EHFuncBeginSym, FDEEncoding);
+    
     Asm->OutStreamer.AddComment("FDE address range");
-    EmitDifference(getDWLabel("eh_func_end", EHFrameInfo.Number),
-                   getDWLabel("eh_func_begin", EHFrameInfo.Number),
+    EmitDifference(getDWLabel("eh_func_end", EHFrameInfo.Number),EHFuncBeginSym,
                    SizeOfEncodedValue(FDEEncoding) == 4);
 
     // If there is a personality and landing pads then point to the language
@@ -260,8 +247,7 @@ void DwarfException::EmitFDE(const FunctionEHFrameInfo &EHFrameInfo) {
     }
 
     // Indicate locations of function specific callee saved registers in frame.
-    EmitFrameMoves("eh_func_begin", EHFrameInfo.Number, EHFrameInfo.Moves,
-                   true);
+    EmitFrameMoves(EHFuncBeginSym, EHFrameInfo.Moves, true);
 
     // On Darwin the linker honors the alignment of eh_frame, which means it
     // must be 8-byte on 64-bit targets to match what gcc does.  Otherwise you
@@ -280,7 +266,7 @@ void DwarfException::EmitFDE(const FunctionEHFrameInfo &EHFrameInfo) {
         Asm->OutStreamer.EmitSymbolAttribute(EHFrameInfo.FunctionEHSym,
                                              MCSA_NoDeadStrip);
   }
-  Asm->O << '\n';
+  Asm->OutStreamer.AddBlankLine();
 }
 
 /// SharedTypeIds - How many leading type ids two landing pads have in common.
@@ -468,7 +454,7 @@ ComputeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites,
                      const SmallVectorImpl<const LandingPadInfo *> &LandingPads,
                      const SmallVectorImpl<unsigned> &FirstActions) {
   // The end label of the previous invoke or nounwind try-range.
-  unsigned LastLabel = 0;
+  MCSymbol *LastLabel = 0;
 
   // Whether there is a potentially throwing instruction (currently this means
   // an ordinary call) between the end of the previous try-range and now.
@@ -489,8 +475,15 @@ ComputeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites,
         continue;
       }
 
-      unsigned BeginLabel = MI->getOperand(0).getImm();
-      assert(BeginLabel && "Invalid label!");
+      MCSymbol *BeginLabel;
+      if (MI->getOperand(0).isImm()) {
+        unsigned BeginLabelNo = MI->getOperand(0).getImm();
+        assert(BeginLabelNo && "Invalid label!");
+        BeginLabel = getDWLabel("label", BeginLabelNo);
+      } else {
+        BeginLabel = MI->getOperand(0).getMCSymbol();
+      }
+      
 
       // End of the previous try-range?
       if (BeginLabel == LastLabel)
@@ -594,7 +587,6 @@ void DwarfException::EmitExceptionTable() {
   const std::vector<GlobalVariable *> &TypeInfos = MMI->getTypeInfos();
   const std::vector<unsigned> &FilterIds = MMI->getFilterIds();
   const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads();
-  if (PadInfos.empty()) return;
 
   // Sort the landing pads in order of their type ids.  This is used to fold
   // duplicate actions.
@@ -619,7 +611,7 @@ void DwarfException::EmitExceptionTable() {
   for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) {
     const LandingPadInfo *LandingPad = LandingPads[i];
     for (unsigned j = 0, E = LandingPad->BeginLabels.size(); j != E; ++j) {
-      unsigned BeginLabel = LandingPad->BeginLabels[j];
+      MCSymbol *BeginLabel = LandingPad->BeginLabels[j];
       assert(!PadMap.count(BeginLabel) && "Duplicate landing pad labels!");
       PadRange P = { i, j };
       PadMap[BeginLabel] = P;
@@ -699,15 +691,14 @@ void DwarfException::EmitExceptionTable() {
   Asm->EmitAlignment(2, 0, 0, false);
 
   // Emit the LSDA.
-  O << "GCC_except_table" << SubprogramCount << ":\n";
+  MCSymbol *GCCETSym = 
+    Asm->OutContext.GetOrCreateSymbol(Twine("GCC_except_table")+
+                                      Twine(SubprogramCount));
+  Asm->OutStreamer.EmitLabel(GCCETSym);
   Asm->OutStreamer.EmitLabel(getDWLabel("exception", SubprogramCount));
 
-  if (IsSJLJ) {
-    SmallString<16> LSDAName;
-    raw_svector_ostream(LSDAName) << MAI->getPrivateGlobalPrefix() <<
-      "_LSDA_" << Asm->getFunctionNumber();
-    O << LSDAName.str() << ":\n";
-  }
+  if (IsSJLJ)
+    Asm->OutStreamer.EmitLabel(getDWLabel("_LSDA_", Asm->getFunctionNumber()));
 
   // Emit the LSDA header.
   EmitEncodingByte(dwarf::DW_EH_PE_omit, "@LPStart");
@@ -805,45 +796,33 @@ void DwarfException::EmitExceptionTable() {
     for (SmallVectorImpl<CallSiteEntry>::const_iterator
          I = CallSites.begin(), E = CallSites.end(); I != E; ++I) {
       const CallSiteEntry &S = *I;
-      const char *BeginTag;
-      unsigned BeginNumber;
-
-      if (!S.BeginLabel) {
-        BeginTag = "eh_func_begin";
-        BeginNumber = SubprogramCount;
-      } else {
-        BeginTag = "label";
-        BeginNumber = S.BeginLabel;
-      }
-
+      
+      MCSymbol *EHFuncBeginSym = getDWLabel("eh_func_begin", SubprogramCount);
+      
+      MCSymbol *BeginLabel = S.BeginLabel;
+      if (BeginLabel == 0)
+        BeginLabel = EHFuncBeginSym;
+      MCSymbol *EndLabel = S.EndLabel;
+      if (EndLabel == 0)
+        EndLabel = getDWLabel("eh_func_end", SubprogramCount);
+        
       // Offset of the call site relative to the previous call site, counted in
       // number of 16-byte bundles. The first call site is counted relative to
       // the start of the procedure fragment.
       Asm->OutStreamer.AddComment("Region start");
-      EmitSectionOffset(getDWLabel(BeginTag, BeginNumber),
-                        getDWLabel("eh_func_begin", SubprogramCount),
-                        true, true);
-
+      EmitSectionOffset(EHFuncBeginSym, EndLabel, true);
+      
       Asm->OutStreamer.AddComment("Region length");
-      if (!S.EndLabel)
-        EmitDifference(getDWLabel("eh_func_end", SubprogramCount),
-                       getDWLabel(BeginTag, BeginNumber),
-                       true);
-      else
-        EmitDifference(getDWLabel("label", S.EndLabel), 
-                       getDWLabel(BeginTag, BeginNumber), true);
+      EmitDifference(EndLabel, BeginLabel, true);
 
 
       // Offset of the landing pad, counted in 16-byte bundles relative to the
       // @LPStart address.
       Asm->OutStreamer.AddComment("Landing pad");
-      if (!S.PadLabel) {
+      if (!S.PadLabel)
         Asm->OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/);
-      } else {
-        EmitSectionOffset(getDWLabel("label", S.PadLabel),
-                          getDWLabel("eh_func_begin", SubprogramCount),
-                          true, true);
-      }
+      else
+        EmitSectionOffset(S.PadLabel, EHFuncBeginSym, true, true);
 
       // Offset of the first associated action record, relative to the start of
       // the action table. This value is biased by 1 (1 indicates the start of
@@ -943,16 +922,11 @@ void DwarfException::BeginFunction(const MachineFunction *MF) {
   this->MF = MF;
   shouldEmitTable = shouldEmitMoves = false;
 
-  // Map all labels and get rid of any dead landing pads.
-  MMI->TidyLandingPads();
-
   // If any landing pads survive, we need an EH table.
-  if (!MMI->getLandingPads().empty())
-    shouldEmitTable = true;
+  shouldEmitTable = !MMI->getLandingPads().empty();
 
   // See if we need frame move info.
-  if (!MF->getFunction()->doesNotThrow() || UnwindTablesMandatory)
-    shouldEmitMoves = true;
+  shouldEmitMoves = !MF->getFunction()->doesNotThrow() || UnwindTablesMandatory;
 
   if (shouldEmitMoves || shouldEmitTable)
     // Assumes in correct section after the entry point.
@@ -974,11 +948,21 @@ void DwarfException::EndFunction() {
     ExceptionTimer->startTimer();
 
   Asm->OutStreamer.EmitLabel(getDWLabel("eh_func_end", SubprogramCount));
-  EmitExceptionTable();
 
+  // Record if this personality index uses a landing pad.
+  bool HasLandingPad = !MMI->getLandingPads().empty();
+  UsesLSDA[MMI->getPersonalityIndex()] |= HasLandingPad;
+  
+  // Map all labels and get rid of any dead landing pads.
+  MMI->TidyLandingPads();
+
+  if (HasLandingPad)
+    EmitExceptionTable();
+
+  const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
   MCSymbol *FunctionEHSym =
     Asm->GetSymbolWithGlobalValueBase(MF->getFunction(), ".eh",
-                                      Asm->MAI->is_EHSymbolPrivate());
+                                      TLOF.isFunctionEHFrameSymbolPrivate());
   
   // Save EH frame information
   EHFrames.push_back(FunctionEHFrameInfo(FunctionEHSym, SubprogramCount,
@@ -988,9 +972,6 @@ void DwarfException::EndFunction() {
                                          MMI->getFrameMoves(),
                                          MF->getFunction()));
 
-  // Record if this personality index uses a landing pad.
-  UsesLSDA[MMI->getPersonalityIndex()] |= !MMI->getLandingPads().empty();
-
   if (TimePassesIsEnabled)
     ExceptionTimer->stopTimer();
 }