diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2011-02-16 01:08:29 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2011-02-16 01:08:29 +0000 |
commit | 7768a9dce14431018133cd586f5c8ce3e057f069 (patch) | |
tree | 96d6d88654a2520802874c021b320394bfe2e1ff /include | |
parent | e32effb02f28025bcbb1eb6b673f46f8d072627b (diff) |
Add support for pushsection and popsection. Patch by Joerg Sonnenberger.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@125629 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include')
-rw-r--r-- | include/llvm/MC/MCObjectStreamer.h | 2 | ||||
-rw-r--r-- | include/llvm/MC/MCStreamer.h | 69 |
2 files changed, 59 insertions, 12 deletions
diff --git a/include/llvm/MC/MCObjectStreamer.h b/include/llvm/MC/MCObjectStreamer.h index f6fd9d73c7..833341eb97 100644 --- a/include/llvm/MC/MCObjectStreamer.h +++ b/include/llvm/MC/MCObjectStreamer.h @@ -64,7 +64,7 @@ public: virtual void EmitULEB128Value(const MCExpr *Value, unsigned AddrSpace = 0); virtual void EmitSLEB128Value(const MCExpr *Value, unsigned AddrSpace = 0); virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol); - virtual void SwitchSection(const MCSection *Section); + virtual void ChangeSection(const MCSection *Section); virtual void EmitInstruction(const MCInst &Inst); virtual void EmitInstToFragment(const MCInst &Inst); virtual void EmitValueToOffset(const MCExpr *Offset, unsigned char Value); diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index 1be2dc6bb6..fc2451f9c1 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -14,6 +14,7 @@ #ifndef LLVM_MC_MCSTREAMER_H #define LLVM_MC_MCSTREAMER_H +#include "llvm/ADT/SmallVector.h" #include "llvm/Support/DataTypes.h" #include "llvm/MC/MCDirectives.h" #include "llvm/MC/MCDwarf.h" @@ -56,16 +57,16 @@ namespace llvm { MCDwarfFrameInfo *getCurrentFrameInfo(); void EnsureValidFrame(); - protected: - MCStreamer(MCContext &Ctx); + /// CurSectionStack - This is stack of CurSection values saved by + /// PushSection. + SmallVector<const MCSection *, 4> CurSectionStack; - /// CurSection - This is the current section code is being emitted to, it is - /// kept up to date by SwitchSection. - const MCSection *CurSection; + /// PrevSectionStack - This is stack of PrevSection values saved by + /// PushSection. + SmallVector<const MCSection *, 4> PrevSectionStack; - /// PrevSection - This is the previous section code is being emitted to, it - /// is kept up to date by SwitchSection. - const MCSection *PrevSection; + protected: + MCStreamer(MCContext &Ctx); public: virtual ~MCStreamer(); @@ -115,17 +116,63 @@ namespace llvm { /// getCurrentSection - Return the current section that the streamer is /// emitting code to. - const MCSection *getCurrentSection() const { return CurSection; } + const MCSection *getCurrentSection() const { + if (!CurSectionStack.empty()) + return CurSectionStack.back(); + return NULL; + } /// getPreviousSection - Return the previous section that the streamer is /// emitting code to. - const MCSection *getPreviousSection() const { return PrevSection; } + const MCSection *getPreviousSection() const { + if (!PrevSectionStack.empty()) + return PrevSectionStack.back(); + return NULL; + } + + /// ChangeSection - Update streamer for a new active section. + /// + /// This is called by PopSection and SwitchSection, if the current + /// section changes. + virtual void ChangeSection(const MCSection *) = 0; + + /// pushSection - Save the current and previous section on the + /// section stack. + void PushSection() { + PrevSectionStack.push_back(getPreviousSection()); + CurSectionStack.push_back(getCurrentSection()); + } + + /// popSection - Restore the current and previous section from + /// the section stack. Calls ChangeSection as needed. + /// + /// Returns false if the stack was empty. + bool PopSection() { + if (PrevSectionStack.size() <= 1) + return false; + assert(CurSectionStack.size() > 1); + PrevSectionStack.pop_back(); + const MCSection *oldSection = CurSectionStack.pop_back_val(); + const MCSection *curSection = CurSectionStack.back(); + + if (oldSection != curSection) + ChangeSection(curSection); + return true; + } /// SwitchSection - Set the current section where code is being emitted to /// @p Section. This is required to update CurSection. /// /// This corresponds to assembler directives like .section, .text, etc. - virtual void SwitchSection(const MCSection *Section) = 0; + void SwitchSection(const MCSection *Section) { + assert(Section && "Cannot switch to a null section!"); + const MCSection *curSection = CurSectionStack.back(); + PrevSectionStack.back() = curSection; + if (Section != curSection) { + CurSectionStack.back() = Section; + ChangeSection(Section); + } + } /// InitSections - Create the default sections and set the initial one. virtual void InitSections() = 0; |