1259698Sdim//===-- llvm/CodeGen/DIEHash.h - Dwarf Hashing Framework -------*- C++ -*--===//
2259698Sdim//
3259698Sdim//                     The LLVM Compiler Infrastructure
4259698Sdim//
5259698Sdim// This file is distributed under the University of Illinois Open Source
6259698Sdim// License. See LICENSE.TXT for details.
7259698Sdim//
8259698Sdim//===----------------------------------------------------------------------===//
9259698Sdim//
10259698Sdim// This file contains support for DWARF4 hashing of DIEs.
11259698Sdim//
12259698Sdim//===----------------------------------------------------------------------===//
13259698Sdim
14259698Sdim#include "DIE.h"
15259698Sdim#include "llvm/ADT/DenseMap.h"
16259698Sdim#include "llvm/Support/MD5.h"
17259698Sdim
18259698Sdimnamespace llvm {
19259698Sdim
20259698Sdimclass CompileUnit;
21259698Sdim
22259698Sdim/// \brief An object containing the capability of hashing and adding hash
23259698Sdim/// attributes onto a DIE.
24259698Sdimclass DIEHash {
25259698Sdim  // The entry for a particular attribute.
26259698Sdim  struct AttrEntry {
27259698Sdim    const DIEValue *Val;
28259698Sdim    const DIEAbbrevData *Desc;
29259698Sdim  };
30259698Sdim
31259698Sdim  // Collection of all attributes used in hashing a particular DIE.
32259698Sdim  struct DIEAttrs {
33259698Sdim    AttrEntry DW_AT_name;
34259698Sdim    AttrEntry DW_AT_accessibility;
35259698Sdim    AttrEntry DW_AT_address_class;
36259698Sdim    AttrEntry DW_AT_allocated;
37259698Sdim    AttrEntry DW_AT_artificial;
38259698Sdim    AttrEntry DW_AT_associated;
39259698Sdim    AttrEntry DW_AT_binary_scale;
40259698Sdim    AttrEntry DW_AT_bit_offset;
41259698Sdim    AttrEntry DW_AT_bit_size;
42259698Sdim    AttrEntry DW_AT_bit_stride;
43259698Sdim    AttrEntry DW_AT_byte_size;
44259698Sdim    AttrEntry DW_AT_byte_stride;
45259698Sdim    AttrEntry DW_AT_const_expr;
46259698Sdim    AttrEntry DW_AT_const_value;
47259698Sdim    AttrEntry DW_AT_containing_type;
48259698Sdim    AttrEntry DW_AT_count;
49259698Sdim    AttrEntry DW_AT_data_bit_offset;
50259698Sdim    AttrEntry DW_AT_data_location;
51259698Sdim    AttrEntry DW_AT_data_member_location;
52259698Sdim    AttrEntry DW_AT_decimal_scale;
53259698Sdim    AttrEntry DW_AT_decimal_sign;
54259698Sdim    AttrEntry DW_AT_default_value;
55259698Sdim    AttrEntry DW_AT_digit_count;
56259698Sdim    AttrEntry DW_AT_discr;
57259698Sdim    AttrEntry DW_AT_discr_list;
58259698Sdim    AttrEntry DW_AT_discr_value;
59259698Sdim    AttrEntry DW_AT_encoding;
60259698Sdim    AttrEntry DW_AT_enum_class;
61259698Sdim    AttrEntry DW_AT_endianity;
62259698Sdim    AttrEntry DW_AT_explicit;
63259698Sdim    AttrEntry DW_AT_is_optional;
64259698Sdim    AttrEntry DW_AT_location;
65259698Sdim    AttrEntry DW_AT_lower_bound;
66259698Sdim    AttrEntry DW_AT_mutable;
67259698Sdim    AttrEntry DW_AT_ordering;
68259698Sdim    AttrEntry DW_AT_picture_string;
69259698Sdim    AttrEntry DW_AT_prototyped;
70259698Sdim    AttrEntry DW_AT_small;
71259698Sdim    AttrEntry DW_AT_segment;
72259698Sdim    AttrEntry DW_AT_string_length;
73259698Sdim    AttrEntry DW_AT_threads_scaled;
74259698Sdim    AttrEntry DW_AT_upper_bound;
75259698Sdim    AttrEntry DW_AT_use_location;
76259698Sdim    AttrEntry DW_AT_use_UTF8;
77259698Sdim    AttrEntry DW_AT_variable_parameter;
78259698Sdim    AttrEntry DW_AT_virtuality;
79259698Sdim    AttrEntry DW_AT_visibility;
80259698Sdim    AttrEntry DW_AT_vtable_elem_location;
81259698Sdim    AttrEntry DW_AT_type;
82259698Sdim
83259698Sdim    // Insert any additional ones here...
84259698Sdim  };
85259698Sdim
86259698Sdimpublic:
87259698Sdim  /// \brief Computes the ODR signature.
88259698Sdim  uint64_t computeDIEODRSignature(const DIE &Die);
89259698Sdim
90259698Sdim  /// \brief Computes the CU signature.
91259698Sdim  uint64_t computeCUSignature(const DIE &Die);
92259698Sdim
93259698Sdim  /// \brief Computes the type signature.
94259698Sdim  uint64_t computeTypeSignature(const DIE &Die);
95259698Sdim
96259698Sdim  // Helper routines to process parts of a DIE.
97259698Sdimprivate:
98259698Sdim  /// \brief Adds the parent context of \param Die to the hash.
99259698Sdim  void addParentContext(const DIE &Die);
100259698Sdim
101259698Sdim  /// \brief Adds the attributes of \param Die to the hash.
102259698Sdim  void addAttributes(const DIE &Die);
103259698Sdim
104259698Sdim  /// \brief Computes the full DWARF4 7.27 hash of the DIE.
105259698Sdim  void computeHash(const DIE &Die);
106259698Sdim
107259698Sdim  // Routines that add DIEValues to the hash.
108259698Sdimprivate:
109259698Sdim  /// \brief Encodes and adds \param Value to the hash as a ULEB128.
110259698Sdim  void addULEB128(uint64_t Value);
111259698Sdim
112259698Sdim  /// \brief Encodes and adds \param Value to the hash as a SLEB128.
113259698Sdim  void addSLEB128(int64_t Value);
114259698Sdim
115259698Sdim  /// \brief Adds \param Str to the hash and includes a NULL byte.
116259698Sdim  void addString(StringRef Str);
117259698Sdim
118259698Sdim  /// \brief Collects the attributes of DIE \param Die into the \param Attrs
119259698Sdim  /// structure.
120259698Sdim  void collectAttributes(const DIE &Die, DIEAttrs &Attrs);
121259698Sdim
122259698Sdim  /// \brief Hashes the attributes in \param Attrs in order.
123259698Sdim  void hashAttributes(const DIEAttrs &Attrs, dwarf::Tag Tag);
124259698Sdim
125259698Sdim  /// \brief Hashes an individual attribute.
126259698Sdim  void hashAttribute(AttrEntry Attr, dwarf::Tag Tag);
127259698Sdim
128259698Sdim  /// \brief Hashes an attribute that refers to another DIE.
129259698Sdim  void hashDIEEntry(dwarf::Attribute Attribute, dwarf::Tag Tag,
130259698Sdim                    const DIE &Entry);
131259698Sdim
132259698Sdim  /// \brief Hashes a reference to a named type in such a way that is
133259698Sdim  /// independent of whether that type is described by a declaration or a
134259698Sdim  /// definition.
135259698Sdim  void hashShallowTypeReference(dwarf::Attribute Attribute, const DIE &Entry,
136259698Sdim                                StringRef Name);
137259698Sdim
138259698Sdim  /// \brief Hashes a reference to a previously referenced type DIE.
139259698Sdim  void hashRepeatedTypeReference(dwarf::Attribute Attribute, unsigned DieNumber);
140259698Sdim
141259698Sdim  void hashNestedType(const DIE &Die, StringRef Name);
142259698Sdim
143259698Sdimprivate:
144259698Sdim  MD5 Hash;
145259698Sdim  DenseMap<const DIE *, unsigned> Numbering;
146259698Sdim};
147259698Sdim}
148