Implement the StartChained and EndChained Win64 EH methods on MCStreamer.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@131629 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Charles Davis
2011-05-19 04:04:13 +00:00
parent d76773a221
commit 91d9a1c0f7
3 changed files with 27 additions and 16 deletions

View File

@@ -59,7 +59,8 @@ namespace llvm {
void EnsureValidFrame(); void EnsureValidFrame();
std::vector<MCWin64EHUnwindInfo> W64UnwindInfos; std::vector<MCWin64EHUnwindInfo> W64UnwindInfos;
MCWin64EHUnwindInfo *getCurrentW64UnwindInfo(); MCWin64EHUnwindInfo *CurrentW64UnwindInfo;
void setCurrentW64UnwindInfo(MCWin64EHUnwindInfo *Frame);
void EnsureValidW64UnwindInfo(); void EnsureValidW64UnwindInfo();
const MCSymbol* LastNonPrivate; const MCSymbol* LastNonPrivate;

View File

@@ -64,7 +64,7 @@ namespace llvm {
struct MCWin64EHUnwindInfo { struct MCWin64EHUnwindInfo {
MCWin64EHUnwindInfo() : Begin(0), End(0), ExceptionHandler(0), Lsda(0), MCWin64EHUnwindInfo() : Begin(0), End(0), ExceptionHandler(0), Lsda(0),
Function(0), UnwindOnly(false), LsdaSize(0), Function(0), UnwindOnly(false), LsdaSize(0),
PrologSize(0), LastFrameInst(-1), Chained(false), PrologSize(0), LastFrameInst(-1), ChainedParent(0),
Instructions() {} Instructions() {}
MCSymbol *Begin; MCSymbol *Begin;
MCSymbol *End; MCSymbol *End;
@@ -75,7 +75,7 @@ namespace llvm {
unsigned LsdaSize; unsigned LsdaSize;
unsigned PrologSize; unsigned PrologSize;
int LastFrameInst; int LastFrameInst;
bool Chained; MCWin64EHUnwindInfo *ChainedParent;
std::vector<MCWin64EHInstruction> Instructions; std::vector<MCWin64EHInstruction> Instructions;
}; };

View File

@@ -310,20 +310,19 @@ void MCStreamer::EmitCFISameValue(int64_t Register) {
CurFrame->Instructions.push_back(Instruction); CurFrame->Instructions.push_back(Instruction);
} }
MCWin64EHUnwindInfo *MCStreamer::getCurrentW64UnwindInfo() { void MCStreamer::setCurrentW64UnwindInfo(MCWin64EHUnwindInfo *Frame) {
if (W64UnwindInfos.empty()) W64UnwindInfos.push_back(*Frame);
return NULL; CurrentW64UnwindInfo = &W64UnwindInfos.back();
return &W64UnwindInfos.back();
} }
void MCStreamer::EnsureValidW64UnwindInfo() { void MCStreamer::EnsureValidW64UnwindInfo() {
MCWin64EHUnwindInfo *CurFrame = getCurrentW64UnwindInfo(); MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
if (!CurFrame || CurFrame->End) if (!CurFrame || CurFrame->End)
report_fatal_error("No open Win64 EH frame function!"); report_fatal_error("No open Win64 EH frame function!");
} }
void MCStreamer::EmitWin64EHStartProc(MCSymbol *Symbol, MCSymbol *EHandler) { void MCStreamer::EmitWin64EHStartProc(MCSymbol *Symbol, MCSymbol *EHandler) {
MCWin64EHUnwindInfo *CurFrame = getCurrentW64UnwindInfo(); MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
if (CurFrame && !CurFrame->End) if (CurFrame && !CurFrame->End)
report_fatal_error("Starting a function before ending the previous one!"); report_fatal_error("Starting a function before ending the previous one!");
MCWin64EHUnwindInfo Frame; MCWin64EHUnwindInfo Frame;
@@ -331,13 +330,13 @@ void MCStreamer::EmitWin64EHStartProc(MCSymbol *Symbol, MCSymbol *EHandler) {
Frame.Function = Symbol; Frame.Function = Symbol;
Frame.ExceptionHandler = EHandler; Frame.ExceptionHandler = EHandler;
EmitLabel(Frame.Begin); EmitLabel(Frame.Begin);
W64UnwindInfos.push_back(Frame); setCurrentW64UnwindInfo(&Frame);
} }
void MCStreamer::EmitWin64EHEndProc() { void MCStreamer::EmitWin64EHEndProc() {
EnsureValidW64UnwindInfo(); EnsureValidW64UnwindInfo();
MCWin64EHUnwindInfo *CurFrame = getCurrentW64UnwindInfo(); MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
if (CurFrame->Chained) if (CurFrame->ChainedParent)
report_fatal_error("Not all chained regions terminated!"); report_fatal_error("Not all chained regions terminated!");
CurFrame->End = getContext().CreateTempSymbol(); CurFrame->End = getContext().CreateTempSymbol();
EmitLabel(CurFrame->End); EmitLabel(CurFrame->End);
@@ -345,14 +344,25 @@ void MCStreamer::EmitWin64EHEndProc() {
void MCStreamer::EmitWin64EHStartChained() void MCStreamer::EmitWin64EHStartChained()
{ {
errs() << "Not implemented yet\n"; EnsureValidW64UnwindInfo();
abort(); MCWin64EHUnwindInfo Frame;
MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
Frame.Begin = getContext().CreateTempSymbol();
Frame.Function = CurFrame->Function;
Frame.ChainedParent = CurFrame;
EmitLabel(Frame.Begin);
setCurrentW64UnwindInfo(&Frame);
} }
void MCStreamer::EmitWin64EHEndChained() void MCStreamer::EmitWin64EHEndChained()
{ {
errs() << "Not implemented yet\n"; EnsureValidW64UnwindInfo();
abort(); 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() void MCStreamer::EmitWin64EHUnwindOnly()