1//===-- llvm/CodeGen/DebugHandlerBase.h -----------------------*- 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// Common functionality for different debug information format backends.
10// LLVM currently supports DWARF and CodeView.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CODEGEN_DEBUGHANDLERBASE_H
15#define LLVM_CODEGEN_DEBUGHANDLERBASE_H
16
17#include "llvm/ADT/Optional.h"
18#include "llvm/CodeGen/AsmPrinterHandler.h"
19#include "llvm/CodeGen/DbgEntityHistoryCalculator.h"
20#include "llvm/CodeGen/LexicalScopes.h"
21#include "llvm/CodeGen/MachineInstr.h"
22#include "llvm/IR/DebugInfoMetadata.h"
23
24namespace llvm {
25
26class AsmPrinter;
27class MachineInstr;
28class MachineModuleInfo;
29
30/// Represents the location at which a variable is stored.
31struct DbgVariableLocation {
32  /// Base register.
33  unsigned Register;
34
35  /// Chain of offsetted loads necessary to load the value if it lives in
36  /// memory. Every load except for the last is pointer-sized.
37  SmallVector<int64_t, 1> LoadChain;
38
39  /// Present if the location is part of a larger variable.
40  llvm::Optional<llvm::DIExpression::FragmentInfo> FragmentInfo;
41
42  /// Extract a VariableLocation from a MachineInstr.
43  /// This will only work if Instruction is a debug value instruction
44  /// and the associated DIExpression is in one of the supported forms.
45  /// If these requirements are not met, the returned Optional will not
46  /// have a value.
47  static Optional<DbgVariableLocation>
48  extractFromMachineInstruction(const MachineInstr &Instruction);
49};
50
51/// Base class for debug information backends. Common functionality related to
52/// tracking which variables and scopes are alive at a given PC live here.
53class DebugHandlerBase : public AsmPrinterHandler {
54protected:
55  DebugHandlerBase(AsmPrinter *A);
56
57  /// Target of debug info emission.
58  AsmPrinter *Asm;
59
60  /// Collected machine module information.
61  MachineModuleInfo *MMI;
62
63  /// Previous instruction's location information. This is used to
64  /// determine label location to indicate scope boundaries in debug info.
65  /// We track the previous instruction's source location (if not line 0),
66  /// whether it was a label, and its parent BB.
67  DebugLoc PrevInstLoc;
68  MCSymbol *PrevLabel = nullptr;
69  const MachineBasicBlock *PrevInstBB = nullptr;
70
71  /// This location indicates end of function prologue and beginning of
72  /// function body.
73  DebugLoc PrologEndLoc;
74
75  /// If nonnull, stores the current machine instruction we're processing.
76  const MachineInstr *CurMI = nullptr;
77
78  LexicalScopes LScopes;
79
80  /// History of DBG_VALUE and clobber instructions for each user
81  /// variable.  Variables are listed in order of appearance.
82  DbgValueHistoryMap DbgValues;
83
84  /// Mapping of inlined labels and DBG_LABEL machine instruction.
85  DbgLabelInstrMap DbgLabels;
86
87  /// Maps instruction with label emitted before instruction.
88  /// FIXME: Make this private from DwarfDebug, we have the necessary accessors
89  /// for it.
90  DenseMap<const MachineInstr *, MCSymbol *> LabelsBeforeInsn;
91
92  /// Maps instruction with label emitted after instruction.
93  DenseMap<const MachineInstr *, MCSymbol *> LabelsAfterInsn;
94
95  /// Indentify instructions that are marking the beginning of or
96  /// ending of a scope.
97  void identifyScopeMarkers();
98
99  /// Ensure that a label will be emitted before MI.
100  void requestLabelBeforeInsn(const MachineInstr *MI) {
101    LabelsBeforeInsn.insert(std::make_pair(MI, nullptr));
102  }
103
104  /// Ensure that a label will be emitted after MI.
105  void requestLabelAfterInsn(const MachineInstr *MI) {
106    LabelsAfterInsn.insert(std::make_pair(MI, nullptr));
107  }
108
109  virtual void beginFunctionImpl(const MachineFunction *MF) = 0;
110  virtual void endFunctionImpl(const MachineFunction *MF) = 0;
111  virtual void skippedNonDebugFunction() {}
112
113  // AsmPrinterHandler overrides.
114public:
115  void beginInstruction(const MachineInstr *MI) override;
116  void endInstruction() override;
117
118  void beginFunction(const MachineFunction *MF) override;
119  void endFunction(const MachineFunction *MF) override;
120
121  /// Return Label preceding the instruction.
122  MCSymbol *getLabelBeforeInsn(const MachineInstr *MI);
123
124  /// Return Label immediately following the instruction.
125  MCSymbol *getLabelAfterInsn(const MachineInstr *MI);
126
127  /// Return the function-local offset of an instruction. A label for the
128  /// instruction \p MI should exist (\ref getLabelAfterInsn).
129  const MCExpr *getFunctionLocalOffsetAfterInsn(const MachineInstr *MI);
130
131  /// If this type is derived from a base type then return base type size.
132  static uint64_t getBaseTypeSize(const DIType *Ty);
133};
134
135}
136
137#endif
138