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 FooTargetAsmStreamer 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: