LLVM  16.0.0git
DWARFLinkerDeclContext.h
Go to the documentation of this file.
1 //===- DWARFLinkerDeclContext.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 #ifndef LLVM_DWARFLINKER_DWARFLINKERDECLCONTEXT_H
10 #define LLVM_DWARFLINKER_DWARFLINKERDECLCONTEXT_H
11 
12 #include "llvm/ADT/DenseMap.h"
13 #include "llvm/ADT/DenseMapInfo.h"
14 #include "llvm/ADT/DenseSet.h"
15 #include "llvm/ADT/StringRef.h"
20 #include "llvm/Support/Path.h"
21 #include <atomic>
22 
23 namespace llvm {
24 
25 class CompileUnit;
26 struct DeclMapInfo;
27 
28 /// Small helper that resolves and caches file paths. This helps reduce the
29 /// number of calls to realpath which is expensive. We assume the input are
30 /// files, and cache the realpath of their parent. This way we can quickly
31 /// resolve different files under the same path.
33 public:
34  /// Resolve a path by calling realpath and cache its result. The returned
35  /// StringRef is interned in the given \p StringPool.
36  StringRef resolve(const std::string &Path,
37  NonRelocatableStringpool &StringPool) {
38  StringRef FileName = sys::path::filename(Path);
39  StringRef ParentPath = sys::path::parent_path(Path);
40 
41  // If the ParentPath has not yet been resolved, resolve and cache it for
42  // future look-ups.
43  if (!ResolvedPaths.count(ParentPath)) {
44  SmallString<256> RealPath;
45  sys::fs::real_path(ParentPath, RealPath);
46  ResolvedPaths.insert(
47  {ParentPath, std::string(RealPath.c_str(), RealPath.size())});
48  }
49 
50  // Join the file name again with the resolved path.
51  SmallString<256> ResolvedPath(ResolvedPaths[ParentPath]);
52  sys::path::append(ResolvedPath, FileName);
53  return StringPool.internString(ResolvedPath);
54  }
55 
56 private:
57  StringMap<std::string> ResolvedPaths;
58 };
59 
60 /// A DeclContext is a named program scope that is used for ODR uniquing of
61 /// types.
62 ///
63 /// The set of DeclContext for the ODR-subject parts of a Dwarf link is
64 /// expanded (and uniqued) with each new object file processed. We need to
65 /// determine the context of each DIE in an linked object file to see if the
66 /// corresponding type has already been emitted.
67 ///
68 /// The contexts are conceptually organized as a tree (eg. a function scope is
69 /// contained in a namespace scope that contains other scopes), but
70 /// storing/accessing them in an actual tree is too inefficient: we need to be
71 /// able to very quickly query a context for a given child context by name.
72 /// Storing a StringMap in each DeclContext would be too space inefficient.
73 ///
74 /// The solution here is to give each DeclContext a link to its parent (this
75 /// allows to walk up the tree), but to query the existence of a specific
76 /// DeclContext using a separate DenseMap keyed on the hash of the fully
77 /// qualified name of the context.
78 class DeclContext {
79 public:
81 
82  DeclContext() : DefinedInClangModule(0), Parent(*this) {}
83 
84  DeclContext(unsigned Hash, uint32_t Line, uint32_t ByteSize, uint16_t Tag,
85  StringRef Name, StringRef File, const DeclContext &Parent,
86  DWARFDie LastSeenDIE = DWARFDie(), unsigned CUId = 0)
87  : QualifiedNameHash(Hash), Line(Line), ByteSize(ByteSize), Tag(Tag),
88  DefinedInClangModule(0), Name(Name), File(File), Parent(Parent),
89  LastSeenDIE(LastSeenDIE), LastSeenCompileUnitID(CUId) {}
90 
91  uint32_t getQualifiedNameHash() const { return QualifiedNameHash; }
92 
93  bool setLastSeenDIE(CompileUnit &U, const DWARFDie &Die);
94 
95  void setHasCanonicalDIE() { HasCanonicalDIE = true; }
96 
97  bool hasCanonicalDIE() const { return HasCanonicalDIE; }
98 
99  uint32_t getCanonicalDIEOffset() const { return CanonicalDIEOffset; }
100  void setCanonicalDIEOffset(uint32_t Offset) { CanonicalDIEOffset = Offset; }
101 
102  bool isDefinedInClangModule() const { return DefinedInClangModule; }
103  void setDefinedInClangModule(bool Val) { DefinedInClangModule = Val; }
104 
105  uint16_t getTag() const { return Tag; }
106 
107 private:
108  friend DeclMapInfo;
109 
110  unsigned QualifiedNameHash = 0;
111  uint32_t Line = 0;
112  uint32_t ByteSize = 0;
113  uint16_t Tag = dwarf::DW_TAG_compile_unit;
114  unsigned DefinedInClangModule : 1;
115  StringRef Name;
116  StringRef File;
117  const DeclContext &Parent;
118  DWARFDie LastSeenDIE;
119  uint32_t LastSeenCompileUnitID = 0;
120  std::atomic<uint32_t> CanonicalDIEOffset = {0};
121  bool HasCanonicalDIE = false;
122 };
123 
124 /// This class gives a tree-like API to the DenseMap that stores the
125 /// DeclContext objects. It holds the BumpPtrAllocator where these objects will
126 /// be allocated.
128 public:
129  /// Get the child of \a Context described by \a DIE in \a Unit. The
130  /// required strings will be interned in \a StringPool.
131  /// \returns The child DeclContext along with one bit that is set if
132  /// this context is invalid.
133  ///
134  /// An invalid context means it shouldn't be considered for uniquing, but its
135  /// not returning null, because some children of that context might be
136  /// uniquing candidates.
137  ///
138  /// FIXME: The invalid bit along the return value is to emulate some
139  /// dsymutil-classic functionality.
141  const DWARFDie &DIE,
142  CompileUnit &Unit,
143  bool InClangModule);
144 
145  DeclContext &getRoot() { return Root; }
146 
147 private:
148  BumpPtrAllocator Allocator;
149  DeclContext Root;
150  DeclContext::Map Contexts;
151 
152  /// Cached resolved paths from the line table.
153  /// The key is <UniqueUnitID, FileIdx>.
154  using ResolvedPathsMap = DenseMap<std::pair<unsigned, unsigned>, StringRef>;
155  ResolvedPathsMap ResolvedPaths;
156 
157  /// Helper that resolves and caches fragments of file paths.
158  CachedPathResolver PathResolver;
159 
160  /// String pool keeping real path bodies.
161  NonRelocatableStringpool StringPool;
162 
163  StringRef getResolvedPath(CompileUnit &CU, unsigned FileNum,
164  const DWARFDebugLine::LineTable &LineTable);
165 };
166 
167 /// Info type for the DenseMap storing the DeclContext pointers.
168 struct DeclMapInfo : private DenseMapInfo<DeclContext *> {
171 
172  static unsigned getHashValue(const DeclContext *Ctxt) {
173  return Ctxt->QualifiedNameHash;
174  }
175 
176  static bool isEqual(const DeclContext *LHS, const DeclContext *RHS) {
177  if (RHS == getEmptyKey() || RHS == getTombstoneKey())
178  return RHS == LHS;
179  return LHS->QualifiedNameHash == RHS->QualifiedNameHash &&
180  LHS->Line == RHS->Line && LHS->ByteSize == RHS->ByteSize &&
181  LHS->Name.data() == RHS->Name.data() &&
182  LHS->File.data() == RHS->File.data() &&
183  LHS->Parent.QualifiedNameHash == RHS->Parent.QualifiedNameHash;
184  }
185 };
186 
187 } // end namespace llvm
188 
189 #endif // LLVM_DWARFLINKER_DWARFLINKERDECLCONTEXT_H
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::DeclContext::isDefinedInClangModule
bool isDefinedInClangModule() const
Definition: DWARFLinkerDeclContext.h:102
FileSystem.h
llvm::DeclContext
A DeclContext is a named program scope that is used for ODR uniquing of types.
Definition: DWARFLinkerDeclContext.h:78
llvm::DeclContext::setDefinedInClangModule
void setDefinedInClangModule(bool Val)
Definition: DWARFLinkerDeclContext.h:103
StringRef.h
Path.h
llvm::DeclContext::DeclContext
DeclContext()
Definition: DWARFLinkerDeclContext.h:82
DWARFDebugLine.h
llvm::CachedPathResolver::resolve
StringRef resolve(const std::string &Path, NonRelocatableStringpool &StringPool)
Resolve a path by calling realpath and cache its result.
Definition: DWARFLinkerDeclContext.h:36
DenseMap.h
llvm::DIE
A structured debug information entry.
Definition: DIE.h:739
RHS
Value * RHS
Definition: X86PartialReduction.cpp:76
llvm::dwarf::Tag
Tag
Definition: Dwarf.h:105
llvm::DeclContextTree::getRoot
DeclContext & getRoot()
Definition: DWARFLinkerDeclContext.h:145
llvm::sys::path::append
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
Definition: Path.cpp:456
Context
LLVMContext & Context
Definition: NVVMIntrRange.cpp:66
LHS
Value * LHS
Definition: X86PartialReduction.cpp:75
llvm::DenseMapInfo
An information struct used to provide DenseMap with the various necessary components for a given valu...
Definition: APInt.h:34
NonRelocatableStringpool.h
llvm::StringMap::insert
bool insert(MapEntryTy *KeyValue)
insert - Insert the specified key/value pair into the map.
Definition: StringMap.h:275
llvm::DeclContext::getQualifiedNameHash
uint32_t getQualifiedNameHash() const
Definition: DWARFLinkerDeclContext.h:91
llvm::sys::fs::real_path
std::error_code real_path(const Twine &path, SmallVectorImpl< char > &output, bool expand_tilde=false)
Collapse all .
DWARFDie.h
DenseSet.h
llvm::DeclContext::setLastSeenDIE
bool setLastSeenDIE(CompileUnit &U, const DWARFDie &Die)
Set the last DIE/CU a context was seen in and, possibly invalidate the context if it is ambiguous.
Definition: DWARFLinkerDeclContext.cpp:31
llvm::DeclContext::getTag
uint16_t getTag() const
Definition: DWARFLinkerDeclContext.h:105
llvm::NonRelocatableStringpool::internString
StringRef internString(StringRef S)
Get permanent storage for S (but do not necessarily emit S in the output section).
Definition: NonRelocatableStringpool.cpp:31
llvm::DeclContext::setHasCanonicalDIE
void setHasCanonicalDIE()
Definition: DWARFLinkerDeclContext.h:95
llvm::DeclContextTree::getChildDeclContext
PointerIntPair< DeclContext *, 1 > getChildDeclContext(DeclContext &Context, const DWARFDie &DIE, CompileUnit &Unit, bool InClangModule)
Get the child of Context described by DIE in Unit.
Definition: DWARFLinkerDeclContext.cpp:45
llvm::StringMap< std::string >
llvm::SmallString< 256 >
llvm::DeclContext::getCanonicalDIEOffset
uint32_t getCanonicalDIEOffset() const
Definition: DWARFLinkerDeclContext.h:99
llvm::CachedPathResolver
Small helper that resolves and caches file paths.
Definition: DWARFLinkerDeclContext.h:32
llvm::DenseSet< DeclContext *, DeclMapInfo >
llvm::SmallString::c_str
const char * c_str()
Definition: SmallString.h:263
llvm::DeclMapInfo::getHashValue
static unsigned getHashValue(const DeclContext *Ctxt)
Definition: DWARFLinkerDeclContext.h:172
llvm::BumpPtrAllocatorImpl
Allocate memory in an ever growing pool, as if by bump-pointer.
Definition: Allocator.h:63
llvm::CompileUnit
Stores all information relating to a compile unit, be it in its original instance in the object file ...
Definition: DWARFLinkerCompileUnit.h:47
llvm::DenseMap
Definition: DenseMap.h:714
llvm::DeclContextTree
This class gives a tree-like API to the DenseMap that stores the DeclContext objects.
Definition: DWARFLinkerDeclContext.h:127
llvm::DeclMapInfo::isEqual
static bool isEqual(const DeclContext *LHS, const DeclContext *RHS)
Definition: DWARFLinkerDeclContext.h:176
llvm::sys::path::parent_path
StringRef parent_path(StringRef path, Style style=Style::native)
Get parent path.
Definition: Path.cpp:467
llvm::DeclContext::setCanonicalDIEOffset
void setCanonicalDIEOffset(uint32_t Offset)
Definition: DWARFLinkerDeclContext.h:100
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
this
Analysis the ScalarEvolution expression for r is this
Definition: README.txt:8
uint32_t
uint16_t
llvm::NonRelocatableStringpool
A string table that doesn't need relocations.
Definition: NonRelocatableStringpool.h:23
llvm::DeclContext::DeclContext
DeclContext(unsigned Hash, uint32_t Line, uint32_t ByteSize, uint16_t Tag, StringRef Name, StringRef File, const DeclContext &Parent, DWARFDie LastSeenDIE=DWARFDie(), unsigned CUId=0)
Definition: DWARFLinkerDeclContext.h:84
llvm::StringMap::count
size_type count(StringRef Key) const
count - Return 1 if the element is in the map, 0 otherwise.
Definition: StringMap.h:245
llvm::DeclMapInfo
Info type for the DenseMap storing the DeclContext pointers.
Definition: DWARFLinkerDeclContext.h:168
llvm::PointerIntPair
PointerIntPair - This class implements a pair of a pointer and small integer.
Definition: PointerIntPair.h:46
llvm::sys::path::filename
StringRef filename(StringRef path, Style style=Style::native)
Get filename.
Definition: Path.cpp:577
llvm::DeclContext::hasCanonicalDIE
bool hasCanonicalDIE() const
Definition: DWARFLinkerDeclContext.h:97
llvm::DWARFDebugLine::LineTable
Definition: DWARFDebugLine.h:226
DenseMapInfo.h
llvm::DWARFDie
Utility class that carries the DWARF compile/type unit and the debug info entry in an object.
Definition: DWARFDie.h:43
CU
Definition: AArch64AsmBackend.cpp:504