]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/llvm/include/llvm/MC/MCDwarf.h
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm-project / llvm / include / llvm / MC / MCDwarf.h
1 //===- MCDwarf.h - Machine Code Dwarf support -------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains the declaration of the MCDwarfFile to support the dwarf
10 // .file directive and the .loc directive.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_MC_MCDWARF_H
15 #define LLVM_MC_MCDWARF_H
16
17 #include "llvm/ADT/MapVector.h"
18 #include "llvm/ADT/Optional.h"
19 #include "llvm/ADT/SmallVector.h"
20 #include "llvm/ADT/StringMap.h"
21 #include "llvm/ADT/StringRef.h"
22 #include "llvm/MC/MCSection.h"
23 #include "llvm/Support/Error.h"
24 #include "llvm/Support/MD5.h"
25 #include <cassert>
26 #include <cstdint>
27 #include <string>
28 #include <utility>
29 #include <vector>
30
31 namespace llvm {
32
33 template <typename T> class ArrayRef;
34 class MCAsmBackend;
35 class MCContext;
36 class MCDwarfLineStr;
37 class MCObjectStreamer;
38 class MCStreamer;
39 class MCSymbol;
40 class raw_ostream;
41 class SMLoc;
42 class SourceMgr;
43
44 /// Instances of this class represent the name of the dwarf .file directive and
45 /// its associated dwarf file number in the MC file. MCDwarfFile's are created
46 /// and uniqued by the MCContext class. In Dwarf 4 file numbers start from 1;
47 /// i.e. the entry with file number 1 is the first element in the vector of
48 /// DwarfFiles and there is no MCDwarfFile with file number 0. In Dwarf 5 file
49 /// numbers start from 0, with the MCDwarfFile with file number 0 being the
50 /// primary source file, and file numbers correspond to their index in the
51 /// vector.
52 struct MCDwarfFile {
53   // The base name of the file without its directory path.
54   std::string Name;
55
56   // The index into the list of directory names for this file name.
57   unsigned DirIndex;
58
59   /// The MD5 checksum, if there is one. Non-owning pointer to data allocated
60   /// in MCContext.
61   Optional<MD5::MD5Result> Checksum;
62
63   /// The source code of the file. Non-owning reference to data allocated in
64   /// MCContext.
65   Optional<StringRef> Source;
66 };
67
68 /// Instances of this class represent the information from a
69 /// dwarf .loc directive.
70 class MCDwarfLoc {
71   uint32_t FileNum;
72   uint32_t Line;
73   uint16_t Column;
74   // Flags (see #define's below)
75   uint8_t Flags;
76   uint8_t Isa;
77   uint32_t Discriminator;
78
79 // Flag that indicates the initial value of the is_stmt_start flag.
80 #define DWARF2_LINE_DEFAULT_IS_STMT 1
81
82 #define DWARF2_FLAG_IS_STMT (1 << 0)
83 #define DWARF2_FLAG_BASIC_BLOCK (1 << 1)
84 #define DWARF2_FLAG_PROLOGUE_END (1 << 2)
85 #define DWARF2_FLAG_EPILOGUE_BEGIN (1 << 3)
86
87 private: // MCContext manages these
88   friend class MCContext;
89   friend class MCDwarfLineEntry;
90
91   MCDwarfLoc(unsigned fileNum, unsigned line, unsigned column, unsigned flags,
92              unsigned isa, unsigned discriminator)
93       : FileNum(fileNum), Line(line), Column(column), Flags(flags), Isa(isa),
94         Discriminator(discriminator) {}
95
96   // Allow the default copy constructor and assignment operator to be used
97   // for an MCDwarfLoc object.
98
99 public:
100   /// Get the FileNum of this MCDwarfLoc.
101   unsigned getFileNum() const { return FileNum; }
102
103   /// Get the Line of this MCDwarfLoc.
104   unsigned getLine() const { return Line; }
105
106   /// Get the Column of this MCDwarfLoc.
107   unsigned getColumn() const { return Column; }
108
109   /// Get the Flags of this MCDwarfLoc.
110   unsigned getFlags() const { return Flags; }
111
112   /// Get the Isa of this MCDwarfLoc.
113   unsigned getIsa() const { return Isa; }
114
115   /// Get the Discriminator of this MCDwarfLoc.
116   unsigned getDiscriminator() const { return Discriminator; }
117
118   /// Set the FileNum of this MCDwarfLoc.
119   void setFileNum(unsigned fileNum) { FileNum = fileNum; }
120
121   /// Set the Line of this MCDwarfLoc.
122   void setLine(unsigned line) { Line = line; }
123
124   /// Set the Column of this MCDwarfLoc.
125   void setColumn(unsigned column) {
126     assert(column <= UINT16_MAX);
127     Column = column;
128   }
129
130   /// Set the Flags of this MCDwarfLoc.
131   void setFlags(unsigned flags) {
132     assert(flags <= UINT8_MAX);
133     Flags = flags;
134   }
135
136   /// Set the Isa of this MCDwarfLoc.
137   void setIsa(unsigned isa) {
138     assert(isa <= UINT8_MAX);
139     Isa = isa;
140   }
141
142   /// Set the Discriminator of this MCDwarfLoc.
143   void setDiscriminator(unsigned discriminator) {
144     Discriminator = discriminator;
145   }
146 };
147
148 /// Instances of this class represent the line information for
149 /// the dwarf line table entries.  Which is created after a machine
150 /// instruction is assembled and uses an address from a temporary label
151 /// created at the current address in the current section and the info from
152 /// the last .loc directive seen as stored in the context.
153 class MCDwarfLineEntry : public MCDwarfLoc {
154   MCSymbol *Label;
155
156 private:
157   // Allow the default copy constructor and assignment operator to be used
158   // for an MCDwarfLineEntry object.
159
160 public:
161   // Constructor to create an MCDwarfLineEntry given a symbol and the dwarf loc.
162   MCDwarfLineEntry(MCSymbol *label, const MCDwarfLoc loc)
163       : MCDwarfLoc(loc), Label(label) {}
164
165   MCSymbol *getLabel() const { return Label; }
166
167   // This is called when an instruction is assembled into the specified
168   // section and if there is information from the last .loc directive that
169   // has yet to have a line entry made for it is made.
170   static void Make(MCObjectStreamer *MCOS, MCSection *Section);
171 };
172
173 /// Instances of this class represent the line information for a compile
174 /// unit where machine instructions have been assembled after seeing .loc
175 /// directives.  This is the information used to build the dwarf line
176 /// table for a section.
177 class MCLineSection {
178 public:
179   // Add an entry to this MCLineSection's line entries.
180   void addLineEntry(const MCDwarfLineEntry &LineEntry, MCSection *Sec) {
181     MCLineDivisions[Sec].push_back(LineEntry);
182   }
183
184   using MCDwarfLineEntryCollection = std::vector<MCDwarfLineEntry>;
185   using iterator = MCDwarfLineEntryCollection::iterator;
186   using const_iterator = MCDwarfLineEntryCollection::const_iterator;
187   using MCLineDivisionMap = MapVector<MCSection *, MCDwarfLineEntryCollection>;
188
189 private:
190   // A collection of MCDwarfLineEntry for each section.
191   MCLineDivisionMap MCLineDivisions;
192
193 public:
194   // Returns the collection of MCDwarfLineEntry for a given Compile Unit ID.
195   const MCLineDivisionMap &getMCLineEntries() const {
196     return MCLineDivisions;
197   }
198 };
199
200 struct MCDwarfLineTableParams {
201   /// First special line opcode - leave room for the standard opcodes.
202   /// Note: If you want to change this, you'll have to update the
203   /// "StandardOpcodeLengths" table that is emitted in
204   /// \c Emit().
205   uint8_t DWARF2LineOpcodeBase = 13;
206   /// Minimum line offset in a special line info. opcode.  The value
207   /// -5 was chosen to give a reasonable range of values.
208   int8_t DWARF2LineBase = -5;
209   /// Range of line offsets in a special line info. opcode.
210   uint8_t DWARF2LineRange = 14;
211 };
212
213 struct MCDwarfLineTableHeader {
214   MCSymbol *Label = nullptr;
215   SmallVector<std::string, 3> MCDwarfDirs;
216   SmallVector<MCDwarfFile, 3> MCDwarfFiles;
217   StringMap<unsigned> SourceIdMap;
218   std::string CompilationDir;
219   MCDwarfFile RootFile;
220   bool HasSource = false;
221 private:
222   bool HasAllMD5 = true;
223   bool HasAnyMD5 = false;
224
225 public:
226   MCDwarfLineTableHeader() = default;
227
228   Expected<unsigned> tryGetFile(StringRef &Directory, StringRef &FileName,
229                                 Optional<MD5::MD5Result> Checksum,
230                                 Optional<StringRef> Source,
231                                 uint16_t DwarfVersion,
232                                 unsigned FileNumber = 0);
233   std::pair<MCSymbol *, MCSymbol *>
234   Emit(MCStreamer *MCOS, MCDwarfLineTableParams Params,
235        Optional<MCDwarfLineStr> &LineStr) const;
236   std::pair<MCSymbol *, MCSymbol *>
237   Emit(MCStreamer *MCOS, MCDwarfLineTableParams Params,
238        ArrayRef<char> SpecialOpcodeLengths,
239        Optional<MCDwarfLineStr> &LineStr) const;
240   void resetMD5Usage() {
241     HasAllMD5 = true;
242     HasAnyMD5 = false;
243   }
244   void trackMD5Usage(bool MD5Used) {
245     HasAllMD5 &= MD5Used;
246     HasAnyMD5 |= MD5Used;
247   }
248   bool isMD5UsageConsistent() const {
249     return MCDwarfFiles.empty() || (HasAllMD5 == HasAnyMD5);
250   }
251
252   void setRootFile(StringRef Directory, StringRef FileName,
253                    Optional<MD5::MD5Result> Checksum,
254                    Optional<StringRef> Source) {
255     CompilationDir = Directory;
256     RootFile.Name = FileName;
257     RootFile.DirIndex = 0;
258     RootFile.Checksum = Checksum;
259     RootFile.Source = Source;
260     trackMD5Usage(Checksum.hasValue());
261     HasSource = Source.hasValue();
262   }
263
264   void resetFileTable() {
265     MCDwarfDirs.clear();
266     MCDwarfFiles.clear();
267     RootFile.Name.clear();
268     resetMD5Usage();
269     HasSource = false;
270   }
271
272 private:
273   void emitV2FileDirTables(MCStreamer *MCOS) const;
274   void emitV5FileDirTables(MCStreamer *MCOS, Optional<MCDwarfLineStr> &LineStr) const;
275 };
276
277 class MCDwarfDwoLineTable {
278   MCDwarfLineTableHeader Header;
279   bool HasSplitLineTable = false;
280
281 public:
282   void maybeSetRootFile(StringRef Directory, StringRef FileName,
283                         Optional<MD5::MD5Result> Checksum,
284                         Optional<StringRef> Source) {
285     if (!Header.RootFile.Name.empty())
286       return;
287     Header.setRootFile(Directory, FileName, Checksum, Source);
288   }
289
290   unsigned getFile(StringRef Directory, StringRef FileName,
291                    Optional<MD5::MD5Result> Checksum, uint16_t DwarfVersion,
292                    Optional<StringRef> Source) {
293     HasSplitLineTable = true;
294     return cantFail(Header.tryGetFile(Directory, FileName, Checksum, Source,
295                                       DwarfVersion));
296   }
297
298   void Emit(MCStreamer &MCOS, MCDwarfLineTableParams Params,
299             MCSection *Section) const;
300 };
301
302 class MCDwarfLineTable {
303   MCDwarfLineTableHeader Header;
304   MCLineSection MCLineSections;
305
306 public:
307   // This emits the Dwarf file and the line tables for all Compile Units.
308   static void Emit(MCObjectStreamer *MCOS, MCDwarfLineTableParams Params);
309
310   // This emits the Dwarf file and the line tables for a given Compile Unit.
311   void EmitCU(MCObjectStreamer *MCOS, MCDwarfLineTableParams Params,
312               Optional<MCDwarfLineStr> &LineStr) const;
313
314   Expected<unsigned> tryGetFile(StringRef &Directory, StringRef &FileName,
315                                 Optional<MD5::MD5Result> Checksum,
316                                 Optional<StringRef> Source,
317                                 uint16_t DwarfVersion,
318                                 unsigned FileNumber = 0);
319   unsigned getFile(StringRef &Directory, StringRef &FileName,
320                    Optional<MD5::MD5Result> Checksum, Optional<StringRef> Source,
321                    uint16_t DwarfVersion, unsigned FileNumber = 0) {
322     return cantFail(tryGetFile(Directory, FileName, Checksum, Source,
323                                DwarfVersion, FileNumber));
324   }
325
326   void setRootFile(StringRef Directory, StringRef FileName,
327                    Optional<MD5::MD5Result> Checksum, Optional<StringRef> Source) {
328     Header.CompilationDir = Directory;
329     Header.RootFile.Name = FileName;
330     Header.RootFile.DirIndex = 0;
331     Header.RootFile.Checksum = Checksum;
332     Header.RootFile.Source = Source;
333     Header.trackMD5Usage(Checksum.hasValue());
334     Header.HasSource = Source.hasValue();
335   }
336
337   void resetFileTable() { Header.resetFileTable(); }
338
339   bool hasRootFile() const { return !Header.RootFile.Name.empty(); }
340
341   const MCDwarfFile &getRootFile() const { return Header.RootFile; }
342
343   // Report whether MD5 usage has been consistent (all-or-none).
344   bool isMD5UsageConsistent() const { return Header.isMD5UsageConsistent(); }
345
346   MCSymbol *getLabel() const {
347     return Header.Label;
348   }
349
350   void setLabel(MCSymbol *Label) {
351     Header.Label = Label;
352   }
353
354   const SmallVectorImpl<std::string> &getMCDwarfDirs() const {
355     return Header.MCDwarfDirs;
356   }
357
358   SmallVectorImpl<std::string> &getMCDwarfDirs() {
359     return Header.MCDwarfDirs;
360   }
361
362   const SmallVectorImpl<MCDwarfFile> &getMCDwarfFiles() const {
363     return Header.MCDwarfFiles;
364   }
365
366   SmallVectorImpl<MCDwarfFile> &getMCDwarfFiles() {
367     return Header.MCDwarfFiles;
368   }
369
370   const MCLineSection &getMCLineSections() const {
371     return MCLineSections;
372   }
373   MCLineSection &getMCLineSections() {
374     return MCLineSections;
375   }
376 };
377
378 class MCDwarfLineAddr {
379 public:
380   /// Utility function to encode a Dwarf pair of LineDelta and AddrDeltas.
381   static void Encode(MCContext &Context, MCDwarfLineTableParams Params,
382                      int64_t LineDelta, uint64_t AddrDelta, raw_ostream &OS);
383
384   /// Utility function to encode a Dwarf pair of LineDelta and AddrDeltas using
385   /// fixed length operands.
386   static bool FixedEncode(MCContext &Context,
387                           MCDwarfLineTableParams Params,
388                           int64_t LineDelta, uint64_t AddrDelta,
389                           raw_ostream &OS, uint32_t *Offset, uint32_t *Size);
390
391   /// Utility function to emit the encoding to a streamer.
392   static void Emit(MCStreamer *MCOS, MCDwarfLineTableParams Params,
393                    int64_t LineDelta, uint64_t AddrDelta);
394 };
395
396 class MCGenDwarfInfo {
397 public:
398   //
399   // When generating dwarf for assembly source files this emits the Dwarf
400   // sections.
401   //
402   static void Emit(MCStreamer *MCOS);
403 };
404
405 // When generating dwarf for assembly source files this is the info that is
406 // needed to be gathered for each symbol that will have a dwarf label.
407 class MCGenDwarfLabelEntry {
408 private:
409   // Name of the symbol without a leading underbar, if any.
410   StringRef Name;
411   // The dwarf file number this symbol is in.
412   unsigned FileNumber;
413   // The line number this symbol is at.
414   unsigned LineNumber;
415   // The low_pc for the dwarf label is taken from this symbol.
416   MCSymbol *Label;
417
418 public:
419   MCGenDwarfLabelEntry(StringRef name, unsigned fileNumber, unsigned lineNumber,
420                        MCSymbol *label)
421       : Name(name), FileNumber(fileNumber), LineNumber(lineNumber),
422         Label(label) {}
423
424   StringRef getName() const { return Name; }
425   unsigned getFileNumber() const { return FileNumber; }
426   unsigned getLineNumber() const { return LineNumber; }
427   MCSymbol *getLabel() const { return Label; }
428
429   // This is called when label is created when we are generating dwarf for
430   // assembly source files.
431   static void Make(MCSymbol *Symbol, MCStreamer *MCOS, SourceMgr &SrcMgr,
432                    SMLoc &Loc);
433 };
434
435 class MCCFIInstruction {
436 public:
437   enum OpType {
438     OpSameValue,
439     OpRememberState,
440     OpRestoreState,
441     OpOffset,
442     OpDefCfaRegister,
443     OpDefCfaOffset,
444     OpDefCfa,
445     OpRelOffset,
446     OpAdjustCfaOffset,
447     OpEscape,
448     OpRestore,
449     OpUndefined,
450     OpRegister,
451     OpWindowSave,
452     OpNegateRAState,
453     OpGnuArgsSize
454   };
455
456 private:
457   OpType Operation;
458   MCSymbol *Label;
459   unsigned Register;
460   union {
461     int Offset;
462     unsigned Register2;
463   };
464   std::vector<char> Values;
465
466   MCCFIInstruction(OpType Op, MCSymbol *L, unsigned R, int O, StringRef V)
467       : Operation(Op), Label(L), Register(R), Offset(O),
468         Values(V.begin(), V.end()) {
469     assert(Op != OpRegister);
470   }
471
472   MCCFIInstruction(OpType Op, MCSymbol *L, unsigned R1, unsigned R2)
473       : Operation(Op), Label(L), Register(R1), Register2(R2) {
474     assert(Op == OpRegister);
475   }
476
477 public:
478   /// .cfi_def_cfa defines a rule for computing CFA as: take address from
479   /// Register and add Offset to it.
480   static MCCFIInstruction createDefCfa(MCSymbol *L, unsigned Register,
481                                        int Offset) {
482     return MCCFIInstruction(OpDefCfa, L, Register, -Offset, "");
483   }
484
485   /// .cfi_def_cfa_register modifies a rule for computing CFA. From now
486   /// on Register will be used instead of the old one. Offset remains the same.
487   static MCCFIInstruction createDefCfaRegister(MCSymbol *L, unsigned Register) {
488     return MCCFIInstruction(OpDefCfaRegister, L, Register, 0, "");
489   }
490
491   /// .cfi_def_cfa_offset modifies a rule for computing CFA. Register
492   /// remains the same, but offset is new. Note that it is the absolute offset
493   /// that will be added to a defined register to the compute CFA address.
494   static MCCFIInstruction createDefCfaOffset(MCSymbol *L, int Offset) {
495     return MCCFIInstruction(OpDefCfaOffset, L, 0, -Offset, "");
496   }
497
498   /// .cfi_adjust_cfa_offset Same as .cfi_def_cfa_offset, but
499   /// Offset is a relative value that is added/subtracted from the previous
500   /// offset.
501   static MCCFIInstruction createAdjustCfaOffset(MCSymbol *L, int Adjustment) {
502     return MCCFIInstruction(OpAdjustCfaOffset, L, 0, Adjustment, "");
503   }
504
505   /// .cfi_offset Previous value of Register is saved at offset Offset
506   /// from CFA.
507   static MCCFIInstruction createOffset(MCSymbol *L, unsigned Register,
508                                        int Offset) {
509     return MCCFIInstruction(OpOffset, L, Register, Offset, "");
510   }
511
512   /// .cfi_rel_offset Previous value of Register is saved at offset
513   /// Offset from the current CFA register. This is transformed to .cfi_offset
514   /// using the known displacement of the CFA register from the CFA.
515   static MCCFIInstruction createRelOffset(MCSymbol *L, unsigned Register,
516                                           int Offset) {
517     return MCCFIInstruction(OpRelOffset, L, Register, Offset, "");
518   }
519
520   /// .cfi_register Previous value of Register1 is saved in
521   /// register Register2.
522   static MCCFIInstruction createRegister(MCSymbol *L, unsigned Register1,
523                                          unsigned Register2) {
524     return MCCFIInstruction(OpRegister, L, Register1, Register2);
525   }
526
527   /// .cfi_window_save SPARC register window is saved.
528   static MCCFIInstruction createWindowSave(MCSymbol *L) {
529     return MCCFIInstruction(OpWindowSave, L, 0, 0, "");
530   }
531
532   /// .cfi_negate_ra_state AArch64 negate RA state.
533   static MCCFIInstruction createNegateRAState(MCSymbol *L) {
534     return MCCFIInstruction(OpNegateRAState, L, 0, 0, "");
535   }
536
537   /// .cfi_restore says that the rule for Register is now the same as it
538   /// was at the beginning of the function, after all initial instructions added
539   /// by .cfi_startproc were executed.
540   static MCCFIInstruction createRestore(MCSymbol *L, unsigned Register) {
541     return MCCFIInstruction(OpRestore, L, Register, 0, "");
542   }
543
544   /// .cfi_undefined From now on the previous value of Register can't be
545   /// restored anymore.
546   static MCCFIInstruction createUndefined(MCSymbol *L, unsigned Register) {
547     return MCCFIInstruction(OpUndefined, L, Register, 0, "");
548   }
549
550   /// .cfi_same_value Current value of Register is the same as in the
551   /// previous frame. I.e., no restoration is needed.
552   static MCCFIInstruction createSameValue(MCSymbol *L, unsigned Register) {
553     return MCCFIInstruction(OpSameValue, L, Register, 0, "");
554   }
555
556   /// .cfi_remember_state Save all current rules for all registers.
557   static MCCFIInstruction createRememberState(MCSymbol *L) {
558     return MCCFIInstruction(OpRememberState, L, 0, 0, "");
559   }
560
561   /// .cfi_restore_state Restore the previously saved state.
562   static MCCFIInstruction createRestoreState(MCSymbol *L) {
563     return MCCFIInstruction(OpRestoreState, L, 0, 0, "");
564   }
565
566   /// .cfi_escape Allows the user to add arbitrary bytes to the unwind
567   /// info.
568   static MCCFIInstruction createEscape(MCSymbol *L, StringRef Vals) {
569     return MCCFIInstruction(OpEscape, L, 0, 0, Vals);
570   }
571
572   /// A special wrapper for .cfi_escape that indicates GNU_ARGS_SIZE
573   static MCCFIInstruction createGnuArgsSize(MCSymbol *L, int Size) {
574     return MCCFIInstruction(OpGnuArgsSize, L, 0, Size, "");
575   }
576
577   OpType getOperation() const { return Operation; }
578   MCSymbol *getLabel() const { return Label; }
579
580   unsigned getRegister() const {
581     assert(Operation == OpDefCfa || Operation == OpOffset ||
582            Operation == OpRestore || Operation == OpUndefined ||
583            Operation == OpSameValue || Operation == OpDefCfaRegister ||
584            Operation == OpRelOffset || Operation == OpRegister);
585     return Register;
586   }
587
588   unsigned getRegister2() const {
589     assert(Operation == OpRegister);
590     return Register2;
591   }
592
593   int getOffset() const {
594     assert(Operation == OpDefCfa || Operation == OpOffset ||
595            Operation == OpRelOffset || Operation == OpDefCfaOffset ||
596            Operation == OpAdjustCfaOffset || Operation == OpGnuArgsSize);
597     return Offset;
598   }
599
600   StringRef getValues() const {
601     assert(Operation == OpEscape);
602     return StringRef(&Values[0], Values.size());
603   }
604 };
605
606 struct MCDwarfFrameInfo {
607   MCDwarfFrameInfo() = default;
608
609   MCSymbol *Begin = nullptr;
610   MCSymbol *End = nullptr;
611   const MCSymbol *Personality = nullptr;
612   const MCSymbol *Lsda = nullptr;
613   std::vector<MCCFIInstruction> Instructions;
614   unsigned CurrentCfaRegister = 0;
615   unsigned PersonalityEncoding = 0;
616   unsigned LsdaEncoding = 0;
617   uint32_t CompactUnwindEncoding = 0;
618   bool IsSignalFrame = false;
619   bool IsSimple = false;
620   unsigned RAReg = static_cast<unsigned>(INT_MAX);
621   bool IsBKeyFrame = false;
622 };
623
624 class MCDwarfFrameEmitter {
625 public:
626   //
627   // This emits the frame info section.
628   //
629   static void Emit(MCObjectStreamer &streamer, MCAsmBackend *MAB, bool isEH);
630   static void EmitAdvanceLoc(MCObjectStreamer &Streamer, uint64_t AddrDelta);
631   static void EncodeAdvanceLoc(MCContext &Context, uint64_t AddrDelta,
632                                raw_ostream &OS, uint32_t *Offset = nullptr,
633                                uint32_t *Size = nullptr);
634 };
635
636 } // end namespace llvm
637
638 #endif // LLVM_MC_MCDWARF_H