const char *ZeroDirective;
/// This directive allows emission of an ascii string with the standard C
- /// escape characters embedded into it. Defaults to "\t.ascii\t"
+ /// escape characters embedded into it. If a target doesn't support this, it
+ /// can be set to null. Defaults to "\t.ascii\t"
const char *AsciiDirective;
/// If not null, this allows for special handling of zero terminated strings
virtual void prettyPrintAsm(MCInstPrinter &InstPrinter, raw_ostream &OS,
const MCInst &Inst, const MCSubtargetInfo &STI);
+ virtual void emitDwarfFileDirective(StringRef Directive);
+
+ /// Update streamer for a new active section.
+ ///
+ /// This is called by PopSection and SwitchSection, if the current
+ /// section changes.
+ virtual void changeSection(const MCSection *CurSection, MCSection *Section,
+ const MCExpr *SubSection, raw_ostream &OS);
+
+ virtual void emitValue(const MCExpr *Value);
+
virtual void finish();
};
void MCAsmStreamer::ChangeSection(MCSection *Section,
const MCExpr *Subsection) {
assert(Section && "Cannot switch to a null section!");
- Section->PrintSwitchToSection(
- *MAI, getContext().getObjectFileInfo()->getTargetTriple(), OS,
- Subsection);
+ if (MCTargetStreamer *TS = getTargetStreamer()) {
+ TS->changeSection(getCurrentSectionOnly(), Section, Subsection, OS);
+ } else {
+ Section->PrintSwitchToSection(
+ *MAI, getContext().getObjectFileInfo()->getTargetTriple(), OS,
+ Subsection);
+ }
}
void MCAsmStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) {
"Cannot emit contents before setting section!");
if (Data.empty()) return;
- if (Data.size() == 1) {
- OS << MAI->getData8bitsDirective();
- OS << (unsigned)(unsigned char)Data[0];
- EmitEOL();
+ // If only single byte is provided or no ascii or asciz directives is
+ // supported, emit as vector of 8bits data.
+ if (Data.size() == 1 ||
+ !(MAI->getAscizDirective() || MAI->getAsciiDirective())) {
+ const char *Directive = MAI->getData8bitsDirective();
+ for (const unsigned char C : Data.bytes()) {
+ OS << Directive << (unsigned)C;
+ EmitEOL();
+ }
return;
}
assert(Directive && "Invalid size for machine code value!");
OS << Directive;
- Value->print(OS, MAI);
- EmitEOL();
+ if (MCTargetStreamer *TS = getTargetStreamer()) {
+ TS->emitValue(Value);
+ } else {
+ Value->print(OS, MAI);
+ EmitEOL();
+ }
}
void MCAsmStreamer::EmitULEB128Value(const MCExpr *Value) {
}
}
- OS << "\t.file\t" << FileNo << ' ';
+ SmallString<128> Str;
+ raw_svector_ostream OS1(Str);
+ OS1 << "\t.file\t" << FileNo << ' ';
if (!Directory.empty()) {
- PrintQuotedString(Directory, OS);
- OS << ' ';
+ PrintQuotedString(Directory, OS1);
+ OS1 << ' ';
+ }
+ PrintQuotedString(Filename, OS1);
+ if (MCTargetStreamer *TS = getTargetStreamer()) {
+ TS->emitDwarfFileDirective(OS1.str());
+ } else {
+ EmitRawText(OS1.str());
}
- PrintQuotedString(Filename, OS);
- EmitEOL();
return FileNo;
}
void MCTargetStreamer::finish() {}
+void MCTargetStreamer::changeSection(const MCSection *CurSection,
+ MCSection *Section,
+ const MCExpr *Subsection,
+ raw_ostream &OS) {
+ Section->PrintSwitchToSection(
+ *Streamer.getContext().getAsmInfo(),
+ Streamer.getContext().getObjectFileInfo()->getTargetTriple(), OS,
+ Subsection);
+}
+
+void MCTargetStreamer::emitDwarfFileDirective(StringRef Directive) {
+ Streamer.EmitRawText(Directive);
+}
+
+void MCTargetStreamer::emitValue(const MCExpr *Value) {
+ SmallString<128> Str;
+ raw_svector_ostream OS(Str);
+
+ Value->print(OS, Streamer.getContext().getAsmInfo());
+ Streamer.EmitRawText(OS.str());
+}
+
void MCTargetStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) {}
MCStreamer::MCStreamer(MCContext &Ctx)