It is common for targets to have specific assembly directives they
need to support. For example, ppc has ".tc" and ARM has its own set of
directives for describing EH tables.
On the parser side we already had a target parser interface, but on
the streamer side they all had to go into the basic MCStreamer. We
also had just one MCAsmStreamer which had to implement them all.
In r192181 I added support for target specific streamers. This is a
very similar design to how we do parsing, with just a small addition
because of the need to handle assembly and object emission.
I have moved directives for PPC, Mips and ARM over to the new
interface. If you think I forgot some, need to add more or maintain an
out of tree target, this is what you need to do for a Foo target:
Implement 3 classes:
* FooTargetStreamer : public MCTargetStreamer
* FooTargetAsmSreamer : public FooTargetStreamer
* FooTargetELFStreamer : public FooTargetStreamer
FooTargetStreamer should have a pure virtual method for each directive. For
example, for a ".bar symbol_name" directive, it should have
virtual emitBar(const MCSymbol &Symbol) = 0;
The FooTargetAsmSreamer and FooTargetELFStreamer classes implement the
method. The assembly streamer just prints ".bar symbol_name". The
object
streamer does whatever is needed to implement .bar in the object file.
In the assembly printer and parser the target streamer can be used by
calling getTargetStreamer and casting it to FooTargetStreamer:
MCTargetStreamer &TS = OutStreamer.getTargetStreamer();
FooTargetStreamer &ATS = static_cast<FooTargetStreamer &>(TS);
The base classes FooTargetAsmSreamer and FooTargetELFStreamer should
*never* be treated differently. Callers should always talk to a
FooTargetStreamer.
Cheers,
Rafael