Implement the StartChained and EndChained Win64 EH methods on MCStreamer.
authorCharles Davis <cdavis@mines.edu>
Thu, 19 May 2011 04:04:13 +0000 (04:04 +0000)
committerCharles Davis <cdavis@mines.edu>
Thu, 19 May 2011 04:04:13 +0000 (04:04 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@131629 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/MC/MCStreamer.h
include/llvm/MC/MCWin64EH.h
lib/MC/MCStreamer.cpp

index 8fb46317db3aa6352daffac285e94c535a4e67d3..83bcb15ae9ae2b2ad8d0d84fcdb14cb7b0fe3362 100644 (file)
@@ -59,7 +59,8 @@ namespace llvm {
     void EnsureValidFrame();
 
     std::vector<MCWin64EHUnwindInfo> W64UnwindInfos;
-    MCWin64EHUnwindInfo *getCurrentW64UnwindInfo();
+    MCWin64EHUnwindInfo *CurrentW64UnwindInfo;
+    void setCurrentW64UnwindInfo(MCWin64EHUnwindInfo *Frame);
     void EnsureValidW64UnwindInfo();
 
     const MCSymbol* LastNonPrivate;
index b7513c8867a10c0f0cd68df3e2d66fc0d47eab6a..c772cdef2a5a488ad1683826be8e9a2047e7b6e4 100644 (file)
@@ -64,7 +64,7 @@ namespace llvm {
   struct MCWin64EHUnwindInfo {
     MCWin64EHUnwindInfo() : Begin(0), End(0), ExceptionHandler(0), Lsda(0),
                             Function(0), UnwindOnly(false), LsdaSize(0),
-                            PrologSize(0), LastFrameInst(-1), Chained(false),
+                            PrologSize(0), LastFrameInst(-1), ChainedParent(0),
                             Instructions() {}
     MCSymbol *Begin;
     MCSymbol *End;
@@ -75,7 +75,7 @@ namespace llvm {
     unsigned LsdaSize;
     unsigned PrologSize;
     int LastFrameInst;
-    bool Chained;
+    MCWin64EHUnwindInfo *ChainedParent;
     std::vector<MCWin64EHInstruction> Instructions;
   };
 
index ed73c1b3a34296f400b981ae9b2f026a18b721e8..4163198e3945d87443d48ea3a535d26868950a12 100644 (file)
@@ -310,20 +310,19 @@ void MCStreamer::EmitCFISameValue(int64_t Register) {
   CurFrame->Instructions.push_back(Instruction);
 }
 
-MCWin64EHUnwindInfo *MCStreamer::getCurrentW64UnwindInfo() {
-  if (W64UnwindInfos.empty())
-    return NULL;
-  return &W64UnwindInfos.back();
+void MCStreamer::setCurrentW64UnwindInfo(MCWin64EHUnwindInfo *Frame) {
+  W64UnwindInfos.push_back(*Frame);
+  CurrentW64UnwindInfo = &W64UnwindInfos.back();
 }
 
 void MCStreamer::EnsureValidW64UnwindInfo() {
-  MCWin64EHUnwindInfo *CurFrame = getCurrentW64UnwindInfo();
+  MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
   if (!CurFrame || CurFrame->End)
     report_fatal_error("No open Win64 EH frame function!");
 }
 
 void MCStreamer::EmitWin64EHStartProc(MCSymbol *Symbol, MCSymbol *EHandler) {
-  MCWin64EHUnwindInfo *CurFrame = getCurrentW64UnwindInfo();
+  MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
   if (CurFrame && !CurFrame->End)
     report_fatal_error("Starting a function before ending the previous one!");
   MCWin64EHUnwindInfo Frame;
@@ -331,13 +330,13 @@ void MCStreamer::EmitWin64EHStartProc(MCSymbol *Symbol, MCSymbol *EHandler) {
   Frame.Function = Symbol;
   Frame.ExceptionHandler = EHandler;
   EmitLabel(Frame.Begin);
-  W64UnwindInfos.push_back(Frame);
+  setCurrentW64UnwindInfo(&Frame);
 }
 
 void MCStreamer::EmitWin64EHEndProc() {
   EnsureValidW64UnwindInfo();
-  MCWin64EHUnwindInfo *CurFrame = getCurrentW64UnwindInfo();
-  if (CurFrame->Chained)
+  MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
+  if (CurFrame->ChainedParent)
     report_fatal_error("Not all chained regions terminated!");
   CurFrame->End = getContext().CreateTempSymbol();
   EmitLabel(CurFrame->End);
@@ -345,14 +344,25 @@ void MCStreamer::EmitWin64EHEndProc() {
 
 void MCStreamer::EmitWin64EHStartChained()
 {
-  errs() << "Not implemented yet\n";
-  abort();
+  EnsureValidW64UnwindInfo();
+  MCWin64EHUnwindInfo Frame;
+  MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
+  Frame.Begin = getContext().CreateTempSymbol();
+  Frame.Function = CurFrame->Function;
+  Frame.ChainedParent = CurFrame;
+  EmitLabel(Frame.Begin);
+  setCurrentW64UnwindInfo(&Frame);
 }
 
 void MCStreamer::EmitWin64EHEndChained()
 {
-  errs() << "Not implemented yet\n";
-  abort();
+  EnsureValidW64UnwindInfo();
+  MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
+  if (!CurFrame->ChainedParent)
+    report_fatal_error("End of a chained region outside a chained region!");
+  CurFrame->End = getContext().CreateTempSymbol();
+  EmitLabel(CurFrame->End);
+  CurrentW64UnwindInfo = CurFrame->ChainedParent;
 }
 
 void MCStreamer::EmitWin64EHUnwindOnly()