10b57cec5SDimitry Andric //===-- AsmPrinterDwarf.cpp - AsmPrinter Dwarf Support --------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file implements the Dwarf emissions parts of AsmPrinter. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #include "llvm/ADT/Twine.h" 140b57cec5SDimitry Andric #include "llvm/BinaryFormat/Dwarf.h" 150b57cec5SDimitry Andric #include "llvm/CodeGen/AsmPrinter.h" 160b57cec5SDimitry Andric #include "llvm/CodeGen/DIE.h" 170b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h" 180b57cec5SDimitry Andric #include "llvm/IR/DataLayout.h" 190b57cec5SDimitry Andric #include "llvm/MC/MCAsmInfo.h" 200b57cec5SDimitry Andric #include "llvm/MC/MCDwarf.h" 210b57cec5SDimitry Andric #include "llvm/MC/MCSection.h" 220b57cec5SDimitry Andric #include "llvm/MC/MCStreamer.h" 230b57cec5SDimitry Andric #include "llvm/MC/MCSymbol.h" 240b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 250b57cec5SDimitry Andric #include "llvm/Target/TargetLoweringObjectFile.h" 26e8d8bef9SDimitry Andric #include <cstdint> 270b57cec5SDimitry Andric using namespace llvm; 280b57cec5SDimitry Andric 290b57cec5SDimitry Andric #define DEBUG_TYPE "asm-printer" 300b57cec5SDimitry Andric 310b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 320b57cec5SDimitry Andric // Dwarf Emission Helper Routines 330b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 340b57cec5SDimitry Andric 350b57cec5SDimitry Andric /// EmitSLEB128 - emit the specified signed leb128 value. 365ffd83dbSDimitry Andric void AsmPrinter::emitSLEB128(int64_t Value, const char *Desc) const { 370b57cec5SDimitry Andric if (isVerbose() && Desc) 380b57cec5SDimitry Andric OutStreamer->AddComment(Desc); 390b57cec5SDimitry Andric 405ffd83dbSDimitry Andric OutStreamer->emitSLEB128IntValue(Value); 410b57cec5SDimitry Andric } 420b57cec5SDimitry Andric 435ffd83dbSDimitry Andric void AsmPrinter::emitULEB128(uint64_t Value, const char *Desc, 445ffd83dbSDimitry Andric unsigned PadTo) const { 450b57cec5SDimitry Andric if (isVerbose() && Desc) 460b57cec5SDimitry Andric OutStreamer->AddComment(Desc); 470b57cec5SDimitry Andric 485ffd83dbSDimitry Andric OutStreamer->emitULEB128IntValue(Value, PadTo); 490b57cec5SDimitry Andric } 500b57cec5SDimitry Andric 510b57cec5SDimitry Andric /// Emit something like ".uleb128 Hi-Lo". 525ffd83dbSDimitry Andric void AsmPrinter::emitLabelDifferenceAsULEB128(const MCSymbol *Hi, 530b57cec5SDimitry Andric const MCSymbol *Lo) const { 540b57cec5SDimitry Andric OutStreamer->emitAbsoluteSymbolDiffAsULEB128(Hi, Lo); 550b57cec5SDimitry Andric } 560b57cec5SDimitry Andric 570b57cec5SDimitry Andric static const char *DecodeDWARFEncoding(unsigned Encoding) { 580b57cec5SDimitry Andric switch (Encoding) { 590b57cec5SDimitry Andric case dwarf::DW_EH_PE_absptr: 600b57cec5SDimitry Andric return "absptr"; 610b57cec5SDimitry Andric case dwarf::DW_EH_PE_omit: 620b57cec5SDimitry Andric return "omit"; 630b57cec5SDimitry Andric case dwarf::DW_EH_PE_pcrel: 640b57cec5SDimitry Andric return "pcrel"; 650b57cec5SDimitry Andric case dwarf::DW_EH_PE_uleb128: 660b57cec5SDimitry Andric return "uleb128"; 670b57cec5SDimitry Andric case dwarf::DW_EH_PE_sleb128: 680b57cec5SDimitry Andric return "sleb128"; 690b57cec5SDimitry Andric case dwarf::DW_EH_PE_udata4: 700b57cec5SDimitry Andric return "udata4"; 710b57cec5SDimitry Andric case dwarf::DW_EH_PE_udata8: 720b57cec5SDimitry Andric return "udata8"; 730b57cec5SDimitry Andric case dwarf::DW_EH_PE_sdata4: 740b57cec5SDimitry Andric return "sdata4"; 750b57cec5SDimitry Andric case dwarf::DW_EH_PE_sdata8: 760b57cec5SDimitry Andric return "sdata8"; 770b57cec5SDimitry Andric case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata4: 780b57cec5SDimitry Andric return "pcrel udata4"; 790b57cec5SDimitry Andric case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4: 800b57cec5SDimitry Andric return "pcrel sdata4"; 810b57cec5SDimitry Andric case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8: 820b57cec5SDimitry Andric return "pcrel udata8"; 830b57cec5SDimitry Andric case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8: 840b57cec5SDimitry Andric return "pcrel sdata8"; 850b57cec5SDimitry Andric case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata4 860b57cec5SDimitry Andric : 870b57cec5SDimitry Andric return "indirect pcrel udata4"; 880b57cec5SDimitry Andric case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4 890b57cec5SDimitry Andric : 900b57cec5SDimitry Andric return "indirect pcrel sdata4"; 910b57cec5SDimitry Andric case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8 920b57cec5SDimitry Andric : 930b57cec5SDimitry Andric return "indirect pcrel udata8"; 940b57cec5SDimitry Andric case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8 950b57cec5SDimitry Andric : 960b57cec5SDimitry Andric return "indirect pcrel sdata8"; 97e8d8bef9SDimitry Andric case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_datarel | 98e8d8bef9SDimitry Andric dwarf::DW_EH_PE_sdata4: 99e8d8bef9SDimitry Andric return "indirect datarel sdata4"; 100e8d8bef9SDimitry Andric case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_datarel | 101e8d8bef9SDimitry Andric dwarf::DW_EH_PE_sdata8: 102e8d8bef9SDimitry Andric return "indirect datarel sdata8"; 1030b57cec5SDimitry Andric } 1040b57cec5SDimitry Andric 1050b57cec5SDimitry Andric return "<unknown encoding>"; 1060b57cec5SDimitry Andric } 1070b57cec5SDimitry Andric 1080b57cec5SDimitry Andric /// EmitEncodingByte - Emit a .byte 42 directive that corresponds to an 1090b57cec5SDimitry Andric /// encoding. If verbose assembly output is enabled, we output comments 1100b57cec5SDimitry Andric /// describing the encoding. Desc is an optional string saying what the 1110b57cec5SDimitry Andric /// encoding is specifying (e.g. "LSDA"). 1125ffd83dbSDimitry Andric void AsmPrinter::emitEncodingByte(unsigned Val, const char *Desc) const { 1130b57cec5SDimitry Andric if (isVerbose()) { 1140b57cec5SDimitry Andric if (Desc) 1150b57cec5SDimitry Andric OutStreamer->AddComment(Twine(Desc) + " Encoding = " + 1160b57cec5SDimitry Andric Twine(DecodeDWARFEncoding(Val))); 1170b57cec5SDimitry Andric else 1180b57cec5SDimitry Andric OutStreamer->AddComment(Twine("Encoding = ") + DecodeDWARFEncoding(Val)); 1190b57cec5SDimitry Andric } 1200b57cec5SDimitry Andric 1215ffd83dbSDimitry Andric OutStreamer->emitIntValue(Val, 1); 1220b57cec5SDimitry Andric } 1230b57cec5SDimitry Andric 1240b57cec5SDimitry Andric /// GetSizeOfEncodedValue - Return the size of the encoding in bytes. 1250b57cec5SDimitry Andric unsigned AsmPrinter::GetSizeOfEncodedValue(unsigned Encoding) const { 1260b57cec5SDimitry Andric if (Encoding == dwarf::DW_EH_PE_omit) 1270b57cec5SDimitry Andric return 0; 1280b57cec5SDimitry Andric 1290b57cec5SDimitry Andric switch (Encoding & 0x07) { 1300b57cec5SDimitry Andric default: 1310b57cec5SDimitry Andric llvm_unreachable("Invalid encoded value."); 1320b57cec5SDimitry Andric case dwarf::DW_EH_PE_absptr: 1330b57cec5SDimitry Andric return MF->getDataLayout().getPointerSize(); 1340b57cec5SDimitry Andric case dwarf::DW_EH_PE_udata2: 1350b57cec5SDimitry Andric return 2; 1360b57cec5SDimitry Andric case dwarf::DW_EH_PE_udata4: 1370b57cec5SDimitry Andric return 4; 1380b57cec5SDimitry Andric case dwarf::DW_EH_PE_udata8: 1390b57cec5SDimitry Andric return 8; 1400b57cec5SDimitry Andric } 1410b57cec5SDimitry Andric } 1420b57cec5SDimitry Andric 143e8d8bef9SDimitry Andric void AsmPrinter::emitTTypeReference(const GlobalValue *GV, unsigned Encoding) { 1440b57cec5SDimitry Andric if (GV) { 1450b57cec5SDimitry Andric const TargetLoweringObjectFile &TLOF = getObjFileLowering(); 1460b57cec5SDimitry Andric 1470b57cec5SDimitry Andric const MCExpr *Exp = 1480b57cec5SDimitry Andric TLOF.getTTypeGlobalReference(GV, Encoding, TM, MMI, *OutStreamer); 1495ffd83dbSDimitry Andric OutStreamer->emitValue(Exp, GetSizeOfEncodedValue(Encoding)); 1500b57cec5SDimitry Andric } else 1515ffd83dbSDimitry Andric OutStreamer->emitIntValue(0, GetSizeOfEncodedValue(Encoding)); 1520b57cec5SDimitry Andric } 1530b57cec5SDimitry Andric 1540b57cec5SDimitry Andric void AsmPrinter::emitDwarfSymbolReference(const MCSymbol *Label, 1550b57cec5SDimitry Andric bool ForceOffset) const { 1560b57cec5SDimitry Andric if (!ForceOffset) { 1570b57cec5SDimitry Andric // On COFF targets, we have to emit the special .secrel32 directive. 1580b57cec5SDimitry Andric if (MAI->needsDwarfSectionOffsetDirective()) { 159e8d8bef9SDimitry Andric assert(!isDwarf64() && 160e8d8bef9SDimitry Andric "emitting DWARF64 is not implemented for COFF targets"); 16181ad6265SDimitry Andric OutStreamer->emitCOFFSecRel32(Label, /*Offset=*/0); 1620b57cec5SDimitry Andric return; 1630b57cec5SDimitry Andric } 1640b57cec5SDimitry Andric 1650b57cec5SDimitry Andric // If the format uses relocations with dwarf, refer to the symbol directly. 1660b57cec5SDimitry Andric if (MAI->doesDwarfUseRelocationsAcrossSections()) { 167e8d8bef9SDimitry Andric OutStreamer->emitSymbolValue(Label, getDwarfOffsetByteSize()); 1680b57cec5SDimitry Andric return; 1690b57cec5SDimitry Andric } 1700b57cec5SDimitry Andric } 1710b57cec5SDimitry Andric 1720b57cec5SDimitry Andric // Otherwise, emit it as a label difference from the start of the section. 173e8d8bef9SDimitry Andric emitLabelDifference(Label, Label->getSection().getBeginSymbol(), 174e8d8bef9SDimitry Andric getDwarfOffsetByteSize()); 1750b57cec5SDimitry Andric } 1760b57cec5SDimitry Andric 1770b57cec5SDimitry Andric void AsmPrinter::emitDwarfStringOffset(DwarfStringPoolEntry S) const { 1780b57cec5SDimitry Andric if (MAI->doesDwarfUseRelocationsAcrossSections()) { 1790b57cec5SDimitry Andric assert(S.Symbol && "No symbol available"); 1800b57cec5SDimitry Andric emitDwarfSymbolReference(S.Symbol); 1810b57cec5SDimitry Andric return; 1820b57cec5SDimitry Andric } 1830b57cec5SDimitry Andric 1840b57cec5SDimitry Andric // Just emit the offset directly; no need for symbol math. 185e8d8bef9SDimitry Andric OutStreamer->emitIntValue(S.Offset, getDwarfOffsetByteSize()); 1860b57cec5SDimitry Andric } 1870b57cec5SDimitry Andric 1885ffd83dbSDimitry Andric void AsmPrinter::emitDwarfOffset(const MCSymbol *Label, uint64_t Offset) const { 189e8d8bef9SDimitry Andric emitLabelPlusOffset(Label, Offset, getDwarfOffsetByteSize()); 190e8d8bef9SDimitry Andric } 191e8d8bef9SDimitry Andric 192e8d8bef9SDimitry Andric void AsmPrinter::emitDwarfLengthOrOffset(uint64_t Value) const { 193e8d8bef9SDimitry Andric assert(isDwarf64() || Value <= UINT32_MAX); 194e8d8bef9SDimitry Andric OutStreamer->emitIntValue(Value, getDwarfOffsetByteSize()); 195e8d8bef9SDimitry Andric } 196e8d8bef9SDimitry Andric 197e8d8bef9SDimitry Andric void AsmPrinter::emitDwarfUnitLength(uint64_t Length, 198e8d8bef9SDimitry Andric const Twine &Comment) const { 199fe6060f1SDimitry Andric OutStreamer->emitDwarfUnitLength(Length, Comment); 200e8d8bef9SDimitry Andric } 201e8d8bef9SDimitry Andric 202fe6060f1SDimitry Andric MCSymbol *AsmPrinter::emitDwarfUnitLength(const Twine &Prefix, 203e8d8bef9SDimitry Andric const Twine &Comment) const { 204fe6060f1SDimitry Andric return OutStreamer->emitDwarfUnitLength(Prefix, Comment); 2050b57cec5SDimitry Andric } 2060b57cec5SDimitry Andric 2075ffd83dbSDimitry Andric void AsmPrinter::emitCallSiteOffset(const MCSymbol *Hi, const MCSymbol *Lo, 2080b57cec5SDimitry Andric unsigned Encoding) const { 2090b57cec5SDimitry Andric // The least significant 3 bits specify the width of the encoding 2100b57cec5SDimitry Andric if ((Encoding & 0x7) == dwarf::DW_EH_PE_uleb128) 2115ffd83dbSDimitry Andric emitLabelDifferenceAsULEB128(Hi, Lo); 2120b57cec5SDimitry Andric else 2135ffd83dbSDimitry Andric emitLabelDifference(Hi, Lo, GetSizeOfEncodedValue(Encoding)); 2140b57cec5SDimitry Andric } 2150b57cec5SDimitry Andric 2165ffd83dbSDimitry Andric void AsmPrinter::emitCallSiteValue(uint64_t Value, unsigned Encoding) const { 2170b57cec5SDimitry Andric // The least significant 3 bits specify the width of the encoding 2180b57cec5SDimitry Andric if ((Encoding & 0x7) == dwarf::DW_EH_PE_uleb128) 2195ffd83dbSDimitry Andric emitULEB128(Value); 2200b57cec5SDimitry Andric else 2215ffd83dbSDimitry Andric OutStreamer->emitIntValue(Value, GetSizeOfEncodedValue(Encoding)); 2220b57cec5SDimitry Andric } 2230b57cec5SDimitry Andric 2240b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 2250b57cec5SDimitry Andric // Dwarf Lowering Routines 2260b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 2270b57cec5SDimitry Andric 2280b57cec5SDimitry Andric void AsmPrinter::emitCFIInstruction(const MCCFIInstruction &Inst) const { 2290b57cec5SDimitry Andric switch (Inst.getOperation()) { 2300b57cec5SDimitry Andric default: 2310b57cec5SDimitry Andric llvm_unreachable("Unexpected instruction"); 2320b57cec5SDimitry Andric case MCCFIInstruction::OpDefCfaOffset: 2335ffd83dbSDimitry Andric OutStreamer->emitCFIDefCfaOffset(Inst.getOffset()); 2340b57cec5SDimitry Andric break; 2350b57cec5SDimitry Andric case MCCFIInstruction::OpAdjustCfaOffset: 2365ffd83dbSDimitry Andric OutStreamer->emitCFIAdjustCfaOffset(Inst.getOffset()); 2370b57cec5SDimitry Andric break; 2380b57cec5SDimitry Andric case MCCFIInstruction::OpDefCfa: 2395ffd83dbSDimitry Andric OutStreamer->emitCFIDefCfa(Inst.getRegister(), Inst.getOffset()); 2400b57cec5SDimitry Andric break; 2410b57cec5SDimitry Andric case MCCFIInstruction::OpDefCfaRegister: 2425ffd83dbSDimitry Andric OutStreamer->emitCFIDefCfaRegister(Inst.getRegister()); 2430b57cec5SDimitry Andric break; 244fe6060f1SDimitry Andric case MCCFIInstruction::OpLLVMDefAspaceCfa: 245fe6060f1SDimitry Andric OutStreamer->emitCFILLVMDefAspaceCfa(Inst.getRegister(), Inst.getOffset(), 246fe6060f1SDimitry Andric Inst.getAddressSpace()); 247fe6060f1SDimitry Andric break; 2480b57cec5SDimitry Andric case MCCFIInstruction::OpOffset: 2495ffd83dbSDimitry Andric OutStreamer->emitCFIOffset(Inst.getRegister(), Inst.getOffset()); 2500b57cec5SDimitry Andric break; 2510b57cec5SDimitry Andric case MCCFIInstruction::OpRegister: 2525ffd83dbSDimitry Andric OutStreamer->emitCFIRegister(Inst.getRegister(), Inst.getRegister2()); 2530b57cec5SDimitry Andric break; 2540b57cec5SDimitry Andric case MCCFIInstruction::OpWindowSave: 2555ffd83dbSDimitry Andric OutStreamer->emitCFIWindowSave(); 2560b57cec5SDimitry Andric break; 2570b57cec5SDimitry Andric case MCCFIInstruction::OpNegateRAState: 2585ffd83dbSDimitry Andric OutStreamer->emitCFINegateRAState(); 2590b57cec5SDimitry Andric break; 2600b57cec5SDimitry Andric case MCCFIInstruction::OpSameValue: 2615ffd83dbSDimitry Andric OutStreamer->emitCFISameValue(Inst.getRegister()); 2620b57cec5SDimitry Andric break; 2630b57cec5SDimitry Andric case MCCFIInstruction::OpGnuArgsSize: 2645ffd83dbSDimitry Andric OutStreamer->emitCFIGnuArgsSize(Inst.getOffset()); 2650b57cec5SDimitry Andric break; 2660b57cec5SDimitry Andric case MCCFIInstruction::OpEscape: 26775b4d546SDimitry Andric OutStreamer->AddComment(Inst.getComment()); 2685ffd83dbSDimitry Andric OutStreamer->emitCFIEscape(Inst.getValues()); 2690b57cec5SDimitry Andric break; 2700b57cec5SDimitry Andric case MCCFIInstruction::OpRestore: 2715ffd83dbSDimitry Andric OutStreamer->emitCFIRestore(Inst.getRegister()); 2725ffd83dbSDimitry Andric break; 2735ffd83dbSDimitry Andric case MCCFIInstruction::OpUndefined: 2745ffd83dbSDimitry Andric OutStreamer->emitCFIUndefined(Inst.getRegister()); 2750b57cec5SDimitry Andric break; 27681ad6265SDimitry Andric case MCCFIInstruction::OpRememberState: 27781ad6265SDimitry Andric OutStreamer->emitCFIRememberState(); 27881ad6265SDimitry Andric break; 27981ad6265SDimitry Andric case MCCFIInstruction::OpRestoreState: 28081ad6265SDimitry Andric OutStreamer->emitCFIRestoreState(); 28181ad6265SDimitry Andric break; 2820b57cec5SDimitry Andric } 2830b57cec5SDimitry Andric } 2840b57cec5SDimitry Andric 2850b57cec5SDimitry Andric void AsmPrinter::emitDwarfDIE(const DIE &Die) const { 2860b57cec5SDimitry Andric // Emit the code (index) for the abbreviation. 2870b57cec5SDimitry Andric if (isVerbose()) 2880b57cec5SDimitry Andric OutStreamer->AddComment("Abbrev [" + Twine(Die.getAbbrevNumber()) + "] 0x" + 2890b57cec5SDimitry Andric Twine::utohexstr(Die.getOffset()) + ":0x" + 2900b57cec5SDimitry Andric Twine::utohexstr(Die.getSize()) + " " + 2910b57cec5SDimitry Andric dwarf::TagString(Die.getTag())); 2925ffd83dbSDimitry Andric emitULEB128(Die.getAbbrevNumber()); 2930b57cec5SDimitry Andric 2940b57cec5SDimitry Andric // Emit the DIE attribute values. 2950b57cec5SDimitry Andric for (const auto &V : Die.values()) { 2960b57cec5SDimitry Andric dwarf::Attribute Attr = V.getAttribute(); 2970b57cec5SDimitry Andric assert(V.getForm() && "Too many attributes for DIE (check abbreviation)"); 2980b57cec5SDimitry Andric 2990b57cec5SDimitry Andric if (isVerbose()) { 3000b57cec5SDimitry Andric OutStreamer->AddComment(dwarf::AttributeString(Attr)); 3010b57cec5SDimitry Andric if (Attr == dwarf::DW_AT_accessibility) 3020b57cec5SDimitry Andric OutStreamer->AddComment( 3030b57cec5SDimitry Andric dwarf::AccessibilityString(V.getDIEInteger().getValue())); 3040b57cec5SDimitry Andric } 3050b57cec5SDimitry Andric 3060b57cec5SDimitry Andric // Emit an attribute using the defined form. 3075ffd83dbSDimitry Andric V.emitValue(this); 3080b57cec5SDimitry Andric } 3090b57cec5SDimitry Andric 3100b57cec5SDimitry Andric // Emit the DIE children if any. 3110b57cec5SDimitry Andric if (Die.hasChildren()) { 312*fcaf7f86SDimitry Andric for (const auto &Child : Die.children()) 3130b57cec5SDimitry Andric emitDwarfDIE(Child); 3140b57cec5SDimitry Andric 3150b57cec5SDimitry Andric OutStreamer->AddComment("End Of Children Mark"); 3160b57cec5SDimitry Andric emitInt8(0); 3170b57cec5SDimitry Andric } 3180b57cec5SDimitry Andric } 3190b57cec5SDimitry Andric 3200b57cec5SDimitry Andric void AsmPrinter::emitDwarfAbbrev(const DIEAbbrev &Abbrev) const { 3210b57cec5SDimitry Andric // Emit the abbreviations code (base 1 index.) 3225ffd83dbSDimitry Andric emitULEB128(Abbrev.getNumber(), "Abbreviation Code"); 3230b57cec5SDimitry Andric 3240b57cec5SDimitry Andric // Emit the abbreviations data. 3250b57cec5SDimitry Andric Abbrev.Emit(this); 3260b57cec5SDimitry Andric } 327