File indexing completed on 2026-05-10 08:43:49
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LLVM_DWARFLINKER_CLASSIC_DWARFLINKERDECLCONTEXT_H
0010 #define LLVM_DWARFLINKER_CLASSIC_DWARFLINKERDECLCONTEXT_H
0011
0012 #include "llvm/ADT/DenseMap.h"
0013 #include "llvm/ADT/DenseMapInfo.h"
0014 #include "llvm/ADT/DenseSet.h"
0015 #include "llvm/ADT/StringRef.h"
0016 #include "llvm/CodeGen/NonRelocatableStringpool.h"
0017 #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
0018 #include "llvm/DebugInfo/DWARF/DWARFDie.h"
0019 #include "llvm/Support/FileSystem.h"
0020 #include "llvm/Support/Path.h"
0021 #include <atomic>
0022
0023 namespace llvm {
0024 namespace dwarf_linker {
0025 namespace classic {
0026
0027 class CompileUnit;
0028 struct DeclMapInfo;
0029
0030
0031
0032
0033
0034 class CachedPathResolver {
0035 public:
0036
0037
0038 StringRef resolve(const std::string &Path,
0039 NonRelocatableStringpool &StringPool) {
0040 StringRef FileName = sys::path::filename(Path);
0041 StringRef ParentPath = sys::path::parent_path(Path);
0042
0043
0044
0045 auto [It, Inserted] = ResolvedPaths.try_emplace(ParentPath);
0046 if (Inserted) {
0047 SmallString<256> RealPath;
0048 sys::fs::real_path(ParentPath, RealPath);
0049 It->second = std::string(RealPath);
0050 }
0051
0052
0053 SmallString<256> ResolvedPath(It->second);
0054 sys::path::append(ResolvedPath, FileName);
0055 return StringPool.internString(ResolvedPath);
0056 }
0057
0058 private:
0059 StringMap<std::string> ResolvedPaths;
0060 };
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080 class DeclContext {
0081 public:
0082 using Map = DenseSet<DeclContext *, DeclMapInfo>;
0083
0084 DeclContext() : DefinedInClangModule(0), Parent(*this) {}
0085
0086 DeclContext(unsigned Hash, uint32_t Line, uint32_t ByteSize, uint16_t Tag,
0087 StringRef Name, StringRef File, const DeclContext &Parent,
0088 DWARFDie LastSeenDIE = DWARFDie(), unsigned CUId = 0)
0089 : QualifiedNameHash(Hash), Line(Line), ByteSize(ByteSize), Tag(Tag),
0090 DefinedInClangModule(0), Name(Name), File(File), Parent(Parent),
0091 LastSeenDIE(LastSeenDIE), LastSeenCompileUnitID(CUId) {}
0092
0093 uint32_t getQualifiedNameHash() const { return QualifiedNameHash; }
0094
0095 bool setLastSeenDIE(CompileUnit &U, const DWARFDie &Die);
0096
0097 void setHasCanonicalDIE() { HasCanonicalDIE = true; }
0098
0099 bool hasCanonicalDIE() const { return HasCanonicalDIE; }
0100
0101 uint32_t getCanonicalDIEOffset() const { return CanonicalDIEOffset; }
0102 void setCanonicalDIEOffset(uint32_t Offset) { CanonicalDIEOffset = Offset; }
0103
0104 bool isDefinedInClangModule() const { return DefinedInClangModule; }
0105 void setDefinedInClangModule(bool Val) { DefinedInClangModule = Val; }
0106
0107 uint16_t getTag() const { return Tag; }
0108
0109 private:
0110 friend DeclMapInfo;
0111
0112 unsigned QualifiedNameHash = 0;
0113 uint32_t Line = 0;
0114 uint32_t ByteSize = 0;
0115 uint16_t Tag = dwarf::DW_TAG_compile_unit;
0116 unsigned DefinedInClangModule : 1;
0117 StringRef Name;
0118 StringRef File;
0119 const DeclContext &Parent;
0120 DWARFDie LastSeenDIE;
0121 uint32_t LastSeenCompileUnitID = 0;
0122 std::atomic<uint32_t> CanonicalDIEOffset = {0};
0123 bool HasCanonicalDIE = false;
0124 };
0125
0126
0127
0128
0129 class DeclContextTree {
0130 public:
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142 PointerIntPair<DeclContext *, 1> getChildDeclContext(DeclContext &Context,
0143 const DWARFDie &DIE,
0144 CompileUnit &Unit,
0145 bool InClangModule);
0146
0147 DeclContext &getRoot() { return Root; }
0148
0149 private:
0150 BumpPtrAllocator Allocator;
0151 DeclContext Root;
0152 DeclContext::Map Contexts;
0153
0154
0155
0156 using ResolvedPathsMap = DenseMap<std::pair<unsigned, unsigned>, StringRef>;
0157 ResolvedPathsMap ResolvedPaths;
0158
0159
0160 CachedPathResolver PathResolver;
0161
0162
0163 NonRelocatableStringpool StringPool;
0164
0165 StringRef getResolvedPath(CompileUnit &CU, unsigned FileNum,
0166 const DWARFDebugLine::LineTable &LineTable);
0167 };
0168
0169
0170 struct DeclMapInfo : private DenseMapInfo<DeclContext *> {
0171 using DenseMapInfo<DeclContext *>::getEmptyKey;
0172 using DenseMapInfo<DeclContext *>::getTombstoneKey;
0173
0174 static unsigned getHashValue(const DeclContext *Ctxt) {
0175 return Ctxt->QualifiedNameHash;
0176 }
0177
0178 static bool isEqual(const DeclContext *LHS, const DeclContext *RHS) {
0179 if (RHS == getEmptyKey() || RHS == getTombstoneKey())
0180 return RHS == LHS;
0181 return LHS->QualifiedNameHash == RHS->QualifiedNameHash &&
0182 LHS->Line == RHS->Line && LHS->ByteSize == RHS->ByteSize &&
0183 LHS->Name.data() == RHS->Name.data() &&
0184 LHS->File.data() == RHS->File.data() &&
0185 LHS->Parent.QualifiedNameHash == RHS->Parent.QualifiedNameHash;
0186 }
0187 };
0188
0189 }
0190 }
0191 }
0192
0193 #endif