1f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//===- MCCodeView.h - Machine Code CodeView support -------------*- C++ -*-===//
2f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
3f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//                     The LLVM Compiler Infrastructure
4f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
5f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// This file is distributed under the University of Illinois Open Source
6f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// License. See LICENSE.TXT for details.
7f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
8f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//===----------------------------------------------------------------------===//
9f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
10f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// Holds state from .cv_file and .cv_loc directives for later emission.
11f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
12f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//===----------------------------------------------------------------------===//
13f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
14f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#ifndef LLVM_MC_MCCODEVIEW_H
15f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#define LLVM_MC_MCCODEVIEW_H
16f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
17f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/ADT/StringMap.h"
18f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/ADT/StringRef.h"
19f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/MC/MCFragment.h"
20f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/MC/MCObjectStreamer.h"
21f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include <map>
22f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include <vector>
23f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
24f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotnamespace llvm {
25f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass MCContext;
26f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass MCObjectStreamer;
27f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass MCStreamer;
28f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass CodeViewContext;
29f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
30f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Instances of this class represent the information from a
31f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// .cv_loc directive.
32f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass MCCVLoc {
33f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  uint32_t FunctionId;
34f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  uint32_t FileNum;
35f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  uint32_t Line;
36f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  uint16_t Column;
37f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  uint16_t PrologueEnd : 1;
38f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  uint16_t IsStmt : 1;
39f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
40f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotprivate: // CodeViewContext manages these
41f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  friend class CodeViewContext;
42f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  MCCVLoc(unsigned functionid, unsigned fileNum, unsigned line, unsigned column,
43f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot          bool prologueend, bool isstmt)
44f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      : FunctionId(functionid), FileNum(fileNum), Line(line), Column(column),
45f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        PrologueEnd(prologueend), IsStmt(isstmt) {}
46f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
47f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // Allow the default copy constructor and assignment operator to be used
48f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // for an MCCVLoc object.
49f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
50f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotpublic:
51f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  unsigned getFunctionId() const { return FunctionId; }
52f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
53f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// \brief Get the FileNum of this MCCVLoc.
54f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  unsigned getFileNum() const { return FileNum; }
55f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
56f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// \brief Get the Line of this MCCVLoc.
57f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  unsigned getLine() const { return Line; }
58f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
59f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// \brief Get the Column of this MCCVLoc.
60f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  unsigned getColumn() const { return Column; }
61f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
62f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool isPrologueEnd() const { return PrologueEnd; }
63f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool isStmt() const { return IsStmt; }
64f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
65f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void setFunctionId(unsigned FID) { FunctionId = FID; }
66f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
67f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// \brief Set the FileNum of this MCCVLoc.
68f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void setFileNum(unsigned fileNum) { FileNum = fileNum; }
69f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
70f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// \brief Set the Line of this MCCVLoc.
71f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void setLine(unsigned line) { Line = line; }
72f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
73f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// \brief Set the Column of this MCCVLoc.
74f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void setColumn(unsigned column) {
75f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    assert(column <= UINT16_MAX);
76f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    Column = column;
77f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
78f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
79f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void setPrologueEnd(bool PE) { PrologueEnd = PE; }
80f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void setIsStmt(bool IS) { IsStmt = IS; }
81f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
82f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
83f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Instances of this class represent the line information for
84f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// the CodeView line table entries.  Which is created after a machine
85f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// instruction is assembled and uses an address from a temporary label
86f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// created at the current address in the current section and the info from
87f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// the last .cv_loc directive seen as stored in the context.
88f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass MCCVLineEntry : public MCCVLoc {
89f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  const MCSymbol *Label;
90f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
91f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotprivate:
92f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // Allow the default copy constructor and assignment operator to be used
93f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // for an MCCVLineEntry object.
94f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
95f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotpublic:
96f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // Constructor to create an MCCVLineEntry given a symbol and the dwarf loc.
97f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  MCCVLineEntry(const MCSymbol *Label, const MCCVLoc loc)
98f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      : MCCVLoc(loc), Label(Label) {}
99f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
100f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  const MCSymbol *getLabel() const { return Label; }
101f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
102f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // This is called when an instruction is assembled into the specified
103f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // section and if there is information from the last .cv_loc directive that
104f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // has yet to have a line entry made for it is made.
105f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  static void Make(MCObjectStreamer *MCOS);
106f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
107f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
108f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// Information describing a function or inlined call site introduced by
109f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// .cv_func_id or .cv_inline_site_id. Accumulates information from .cv_loc
110f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// directives used with this function's id or the id of an inlined call site
111f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// within this function or inlined call site.
112f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotstruct MCCVFunctionInfo {
113f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// If this represents an inlined call site, then ParentFuncIdPlusOne will be
114f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// the parent function id plus one. If this represents a normal function,
115f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// then there is no parent, and ParentFuncIdPlusOne will be FunctionSentinel.
116f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// If this struct is an unallocated slot in the function info vector, then
117f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// ParentFuncIdPlusOne will be zero.
118f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  unsigned ParentFuncIdPlusOne = 0;
119f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
120f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  enum : unsigned { FunctionSentinel = ~0U };
121f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
122f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  struct LineInfo {
123f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    unsigned File;
124f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    unsigned Line;
125f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    unsigned Col;
126f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  };
127f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
128f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  LineInfo InlinedAt;
129f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
130f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// The section of the first .cv_loc directive used for this function, or null
131f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// if none has been seen yet.
132f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  MCSection *Section = nullptr;
133f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
134f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Map from inlined call site id to the inlined at location to use for that
135f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// call site. Call chains are collapsed, so for the call chain 'f -> g -> h',
136f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// the InlinedAtMap of 'f' will contain entries for 'g' and 'h' that both
137f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// list the line info for the 'g' call site.
138f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  DenseMap<unsigned, LineInfo> InlinedAtMap;
139f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
140f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Returns true if this is function info has not yet been used in a
141f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// .cv_func_id or .cv_inline_site_id directive.
142f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool isUnallocatedFunctionInfo() const { return ParentFuncIdPlusOne == 0; }
143f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
144f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Returns true if this represents an inlined call site, meaning
145f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// ParentFuncIdPlusOne is neither zero nor ~0U.
146f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool isInlinedCallSite() const {
147f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return !isUnallocatedFunctionInfo() &&
148f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot           ParentFuncIdPlusOne != FunctionSentinel;
149f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
150f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
151f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  unsigned getParentFuncId() const {
152f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    assert(isInlinedCallSite());
153f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return ParentFuncIdPlusOne - 1;
154f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
155f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
156f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
157f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// Holds state from .cv_file and .cv_loc directives for later emission.
158f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass CodeViewContext {
159f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotpublic:
160f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  CodeViewContext();
161f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  ~CodeViewContext();
162f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
163f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool isValidFileNumber(unsigned FileNumber) const;
164f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool addFile(unsigned FileNumber, StringRef Filename);
165f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  ArrayRef<StringRef> getFilenames() { return Filenames; }
166f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
167f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Records the function id of a normal function. Returns false if the
168f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// function id has already been used, and true otherwise.
169f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool recordFunctionId(unsigned FuncId);
170f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
171f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Records the function id of an inlined call site. Records the "inlined at"
172f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// location info of the call site, including what function or inlined call
173f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// site it was inlined into. Returns false if the function id has already
174f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// been used, and true otherwise.
175f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool recordInlinedCallSiteId(unsigned FuncId, unsigned IAFunc,
176f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                               unsigned IAFile, unsigned IALine,
177f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                               unsigned IACol);
178f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
179f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Retreive the function info if this is a valid function id, or nullptr.
180f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  MCCVFunctionInfo *getCVFunctionInfo(unsigned FuncId) {
181f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (FuncId >= Functions.size())
182f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return nullptr;
183f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (Functions[FuncId].isUnallocatedFunctionInfo())
184f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return nullptr;
185f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return &Functions[FuncId];
186f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
187f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
188f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Saves the information from the currently parsed .cv_loc directive
189f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// and sets CVLocSeen.  When the next instruction is assembled an entry
190f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// in the line number table with this information and the address of the
191f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// instruction will be created.
192f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void setCurrentCVLoc(unsigned FunctionId, unsigned FileNo, unsigned Line,
193f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                       unsigned Column, bool PrologueEnd, bool IsStmt) {
194f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    CurrentCVLoc.setFunctionId(FunctionId);
195f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    CurrentCVLoc.setFileNum(FileNo);
196f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    CurrentCVLoc.setLine(Line);
197f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    CurrentCVLoc.setColumn(Column);
198f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    CurrentCVLoc.setPrologueEnd(PrologueEnd);
199f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    CurrentCVLoc.setIsStmt(IsStmt);
200f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    CVLocSeen = true;
201f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
202f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void clearCVLocSeen() { CVLocSeen = false; }
203f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
204f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool getCVLocSeen() { return CVLocSeen; }
205f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  const MCCVLoc &getCurrentCVLoc() { return CurrentCVLoc; }
206f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
207f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool isValidCVFileNumber(unsigned FileNumber);
208f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
209f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// \brief Add a line entry.
210f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void addLineEntry(const MCCVLineEntry &LineEntry) {
211f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    size_t Offset = MCCVLines.size();
212f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    auto I = MCCVLineStartStop.insert(
213f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        {LineEntry.getFunctionId(), {Offset, Offset + 1}});
214f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (!I.second)
215f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      I.first->second.second = Offset + 1;
216f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    MCCVLines.push_back(LineEntry);
217f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
218f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
219f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  std::vector<MCCVLineEntry> getFunctionLineEntries(unsigned FuncId) {
220f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    std::vector<MCCVLineEntry> FilteredLines;
221f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
222f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    auto I = MCCVLineStartStop.find(FuncId);
223f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (I != MCCVLineStartStop.end())
224f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      for (size_t Idx = I->second.first, End = I->second.second; Idx != End;
225f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot           ++Idx)
226f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        if (MCCVLines[Idx].getFunctionId() == FuncId)
227f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot          FilteredLines.push_back(MCCVLines[Idx]);
228f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return FilteredLines;
229f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
230f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
231f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  std::pair<size_t, size_t> getLineExtent(unsigned FuncId) {
232f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    auto I = MCCVLineStartStop.find(FuncId);
233f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    // Return an empty extent if there are no cv_locs for this function id.
234f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (I == MCCVLineStartStop.end())
235f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return {~0ULL, 0};
236f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return I->second;
237f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
238f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
239f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  ArrayRef<MCCVLineEntry> getLinesForExtent(size_t L, size_t R) {
240f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (R <= L)
241f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return None;
242f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (L >= MCCVLines.size())
243f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return None;
244f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return makeArrayRef(&MCCVLines[L], R - L);
245f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
246f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
247f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Emits a line table substream.
248f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void emitLineTableForFunction(MCObjectStreamer &OS, unsigned FuncId,
249f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                const MCSymbol *FuncBegin,
250f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                const MCSymbol *FuncEnd);
251f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
252f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void emitInlineLineTableForFunction(MCObjectStreamer &OS,
253f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                      unsigned PrimaryFunctionId,
254f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                      unsigned SourceFileId,
255f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                      unsigned SourceLineNum,
256f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                      const MCSymbol *FnStartSym,
257f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                      const MCSymbol *FnEndSym);
258f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
259f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Encodes the binary annotations once we have a layout.
260f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void encodeInlineLineTable(MCAsmLayout &Layout,
261f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                             MCCVInlineLineTableFragment &F);
262f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
263f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void
264f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  emitDefRange(MCObjectStreamer &OS,
265f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot               ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
266f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot               StringRef FixedSizePortion);
267f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
268f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void encodeDefRange(MCAsmLayout &Layout, MCCVDefRangeFragment &F);
269f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
270f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Emits the string table substream.
271f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void emitStringTable(MCObjectStreamer &OS);
272f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
273f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Emits the file checksum substream.
274f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void emitFileChecksums(MCObjectStreamer &OS);
275f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
276f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotprivate:
277f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// The current CodeView line information from the last .cv_loc directive.
278f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  MCCVLoc CurrentCVLoc = MCCVLoc(0, 0, 0, 0, false, true);
279f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool CVLocSeen = false;
280f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
281f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Map from string to string table offset.
282f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  StringMap<unsigned> StringTable;
283f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
284f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// The fragment that ultimately holds our strings.
285f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  MCDataFragment *StrTabFragment = nullptr;
286f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool InsertedStrTabFragment = false;
287f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
288f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  MCDataFragment *getStringTableFragment();
289f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
290f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Add something to the string table.
291f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  StringRef addToStringTable(StringRef S);
292f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
293f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Get a string table offset.
294f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  unsigned getStringTableOffset(StringRef S);
295f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
296f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// An array of absolute paths. Eventually this may include the file checksum.
297f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  SmallVector<StringRef, 4> Filenames;
298f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
299f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// The offset of the first and last .cv_loc directive for a given function
300f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// id.
301f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  std::map<unsigned, std::pair<size_t, size_t>> MCCVLineStartStop;
302f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
303f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// A collection of MCCVLineEntry for each section.
304f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  std::vector<MCCVLineEntry> MCCVLines;
305f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
306f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// All known functions and inlined call sites, indexed by function id.
307f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  std::vector<MCCVFunctionInfo> Functions;
308f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
309f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
310f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot} // end namespace llvm
311f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#endif
312