LLVM 24.0.0git
Utils.h
Go to the documentation of this file.
1//===- Utils.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_UTILS_H
10#define LLVM_DWARFLINKER_UTILS_H
11
12#include "llvm/ADT/ArrayRef.h"
13#include "llvm/ADT/DenseMap.h"
15#include "llvm/ADT/Twine.h"
18#include "llvm/Support/Error.h"
20#include "llvm/Support/Path.h"
21
22namespace llvm {
23class DWARFDie;
24class DWARFFormValue;
25
26namespace dwarf_linker {
27
28/// Test if the location of variable \p Die contains a global address
29/// but only uses to compute the variable's value, for example
30/// DW_OP_addr DW_OP_stack_value.
31LLVM_ABI bool hasImplicitAddressLocation(const DWARFDie &Die);
32
33/// Test if the DW_TAG_member \p Die is a DWARF 2-4 style static data member: a
34/// declaration with no storage in the record. DWARF 5 uses a DW_TAG_variable
35/// instead.
36LLVM_ABI bool isStaticDataMember(const DWARFDie &Die);
37
38/// Test if an unnamed type with tag \p Tag is identified by its children, which
39/// tell it apart from other unnamed types declared on the same line. Other
40/// unnamed types, like pointer types, have no such children.
42
43/// Test if \p Die is a child that identifies its unnamed parent type.
44LLVM_ABI bool isIdentifyingChild(const DWARFDie &Die);
45
46/// Hash the fully qualified name of type \p Die for the Apple accelerator
47/// tables. \p ResolveRef returns the DIE that a DW_AT_specification or
48/// DW_AT_abstract_origin of its first argument refers to, or an invalid DIE.
49/// A DW_TAG_module ends the name like the unit does, because LLDB leaves
50/// modules out of the qualified names it looks up.
52 DWARFDie Die,
53 function_ref<DWARFDie(const DWARFDie &, const DWARFFormValue &)>
54 ResolveRef);
55
56/// Build a map from an input DW_AT_LLVM_stmt_sequence byte offset to
57/// the first-row index (in \p LT.Rows) of the corresponding line-table
58/// sequence. Seeds the map from \p LT.Sequences (the DWARF parser's
59/// discovered sequences), then augments it by walking row boundaries
60/// (DW_LNE_end_sequence markers) and matching them against the sorted
61/// input offsets in \p SortedStmtSeqOffsets, using the parser's results
62/// as ground-truth anchors. This recovers sequences the parser may not
63/// have registered and keeps the classic and parallel DWARFLinkers in
64/// lockstep. Caller passes \p SortedStmtSeqOffsets sorted ascending
65/// and deduplicated.
67 const DWARFDebugLine::LineTable &LT,
68 ArrayRef<uint64_t> SortedStmtSeqOffsets,
69 DenseMap<uint64_t, uint64_t> &SeqOffToFirstRow);
70
71/// This function calls \p Iteration() until it returns false.
72/// If number of iterations exceeds \p MaxCounter then an Error is returned.
73/// This function should be used for loops which assumed to have number of
74/// iterations significantly smaller than \p MaxCounter to avoid infinite
75/// looping in error cases.
77 size_t MaxCounter = 100000) {
78 size_t iterationsCounter = 0;
79 while (iterationsCounter++ < MaxCounter) {
80 Expected<bool> IterationResultOrError = Iteration();
81 if (!IterationResultOrError)
82 return IterationResultOrError.takeError();
83 if (!IterationResultOrError.get())
84 return Error::success();
85 }
86 return createStringError(std::errc::invalid_argument, "Infinite recursion");
87}
88
89/// Make a best effort to guess the
90/// Xcode.app/Contents/Developer path from an SDK path.
92 // Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk
93 auto it = sys::path::rbegin(SysRoot);
94 auto end = sys::path::rend(SysRoot);
95 if (it == end || !it->ends_with(".sdk"))
96 return {};
97 ++it;
98 // Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs
99 if (it == end || *it != "SDKs")
100 return {};
101 auto developerEnd = it;
102 ++it;
103 while (it != end) {
104 // Contents/Developer/Platforms/MacOSX.platform/Developer
105 if (*it != "Developer")
106 return {};
107 ++it;
108 if (it == end)
109 return {};
110 if (*it == "Contents")
111 return StringRef(SysRoot.data(),
112 developerEnd - sys::path::rend(SysRoot) - 1);
113 // Contents/Developer/Platforms/MacOSX.platform
114 if (!it->ends_with(".platform"))
115 return {};
116 ++it;
117 // Contents/Developer/Platforms
118 if (it == end || *it != "Platforms")
119 return {};
120 developerEnd = it;
121 ++it;
122 }
123 return {};
124}
125
126/// Make a best effort to determine whether Path is inside a toolchain.
127inline bool isInToolchainDir(StringRef Path) {
128 // Library/Developer/Toolchains/swift-DEVELOPMENT-SNAPSHOT-2024-05-15-a.xctoolchain/usr/lib/swift/macosx/_StringProcessing.swiftmodule/arm64-apple-macos.private.swiftinterface
129 for (auto it = sys::path::rbegin(Path), end = sys::path::rend(Path);
130 it != end; ++it) {
131 if (it->ends_with(".xctoolchain")) {
132 ++it;
133 if (it == end)
134 return false;
135 if (*it != "Toolchains")
136 return false;
137 ++it;
138 if (it == end)
139 return false;
140 if (*it != "Developer")
141 return false;
142 return true;
143 }
144 }
145 return false;
146}
147
148inline bool isPathAbsoluteOnWindowsOrPosix(const Twine &Path) {
149 // Debug info can contain paths from any OS, not necessarily
150 // an OS we're currently running on. Moreover different compilation units can
151 // be compiled on different operating systems and linked together later.
154}
155
156} // end of namespace dwarf_linker
157} // end of namespace llvm
158
159#endif // LLVM_DWARFLINKER_UTILS_H
#define LLVM_ABI
Definition Compiler.h:211
This file defines the DenseMap class.
This file contains constants used for implementing Dwarf debug support.
This file defines the SmallString class.
Utility class that carries the DWARF compile/type unit and the debug info entry in an object.
Definition DWARFDie.h:43
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
static ErrorSuccess success()
Create a success value.
Definition Error.h:336
Tagged union holding either a T or a Error.
Definition Error.h:485
Error takeError()
Take ownership of the stored error.
Definition Error.h:612
reference get()
Returns a reference to the stored T value.
Definition Error.h:582
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
constexpr const char * data() const
Get a pointer to the start of the string (which may not be null terminated).
Definition StringRef.h:138
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
An efficient, type-erasing, non-owning reference to a callable.
LLVM_ABI bool isIdentifiedByChildren(dwarf::Tag Tag)
Test if an unnamed type with tag Tag is identified by its children, which tell it apart from other un...
Definition Utils.cpp:57
StringRef guessDeveloperDir(StringRef SysRoot)
Make a best effort to guess the Xcode.app/Contents/Developer path from an SDK path.
Definition Utils.h:91
LLVM_ABI bool hasImplicitAddressLocation(const DWARFDie &Die)
Test if the location of variable Die contains a global address but only uses to compute the variable'...
Definition Utils.cpp:23
LLVM_ABI void buildStmtSeqOffsetToFirstRowIndex(const DWARFDebugLine::LineTable &LT, ArrayRef< uint64_t > SortedStmtSeqOffsets, DenseMap< uint64_t, uint64_t > &SeqOffToFirstRow)
Build a map from an input DW_AT_LLVM_stmt_sequence byte offset to the first-row index (in LT....
Definition Utils.cpp:135
LLVM_ABI uint32_t hashFullyQualifiedName(DWARFDie Die, function_ref< DWARFDie(const DWARFDie &, const DWARFFormValue &)> ResolveRef)
Hash the fully qualified name of type Die for the Apple accelerator tables.
Definition Utils.cpp:127
bool isInToolchainDir(StringRef Path)
Make a best effort to determine whether Path is inside a toolchain.
Definition Utils.h:127
Error finiteLoop(function_ref< Expected< bool >()> Iteration, size_t MaxCounter=100000)
This function calls Iteration() until it returns false.
Definition Utils.h:76
LLVM_ABI bool isStaticDataMember(const DWARFDie &Die)
Test if the DW_TAG_member Die is a DWARF 2-4 style static data member: a declaration with no storage ...
Definition Utils.cpp:43
bool isPathAbsoluteOnWindowsOrPosix(const Twine &Path)
Definition Utils.h:148
LLVM_ABI bool isIdentifyingChild(const DWARFDie &Die)
Test if Die is a child that identifies its unnamed parent type.
Definition Utils.cpp:70
LLVM_ABI bool is_absolute(const Twine &path, Style style=Style::native)
Is path absolute?
Definition Path.cpp:688
LLVM_ABI reverse_iterator rend(StringRef path LLVM_LIFETIME_BOUND)
Get reverse end iterator over path.
LLVM_ABI reverse_iterator rbegin(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get reverse begin iterator over path.
This is an optimization pass for GlobalISel generic memory operations.
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition Error.h:1321