summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2011-02-16 01:08:29 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2011-02-16 01:08:29 +0000
commit7768a9dce14431018133cd586f5c8ce3e057f069 (patch)
tree96d6d88654a2520802874c021b320394bfe2e1ff /include
parente32effb02f28025bcbb1eb6b673f46f8d072627b (diff)
downloadllvm-7768a9dce14431018133cd586f5c8ce3e057f069.tar.gz
llvm-7768a9dce14431018133cd586f5c8ce3e057f069.tar.bz2
llvm-7768a9dce14431018133cd586f5c8ce3e057f069.tar.xz
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.h2
-rw-r--r--include/llvm/MC/MCStreamer.h69
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;