-
Notifications
You must be signed in to change notification settings - Fork 10.5k
/
Copy pathDebugTypeInfo.h
167 lines (143 loc) · 5.86 KB
/
DebugTypeInfo.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
//===--- DebugTypeInfo.h - Type Info for Debugging --------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file defines the data structure that holds all the debug info
// we want to emit for types.
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_IRGEN_DEBUGTYPEINFO_H
#define SWIFT_IRGEN_DEBUGTYPEINFO_H
#include "IRGen.h"
#include "swift/AST/Decl.h"
#include "swift/AST/Types.h"
namespace llvm {
class Type;
}
namespace swift {
class SILDebugScope;
class SILGlobalVariable;
namespace irgen {
class TypeInfo;
class IRGenModule;
/// This data structure holds everything needed to emit debug info
/// for a type.
class DebugTypeInfo {
protected:
/// The type we need to emit may be different from the type
/// mentioned in the Decl, for example, stripped of qualifiers.
TypeBase *Type = nullptr;
/// Needed to determine the size of basic types and to determine
/// the storage type for undefined variables.
llvm::Type *FragmentStorageType = nullptr;
std::optional<uint32_t> NumExtraInhabitants;
Alignment Align;
bool DefaultAlignment = true;
bool IsMetadataType = false;
bool IsFixedBuffer = false;
public:
DebugTypeInfo() = default;
DebugTypeInfo(swift::Type Ty, llvm::Type *StorageTy = nullptr,
Alignment AlignInBytes = Alignment(1),
bool HasDefaultAlignment = true, bool IsMetadataType = false,
bool IsFixedBuffer = false,
std::optional<uint32_t> NumExtraInhabitants = {});
/// Create type for a local variable.
static DebugTypeInfo getLocalVariable(VarDecl *Decl, swift::Type Ty,
const TypeInfo &Info, IRGenModule &IGM);
/// Create type for global type metadata.
static DebugTypeInfo getGlobalMetadata(swift::Type Ty, llvm::Type *StorageTy,
Size size, Alignment align);
/// Create type for an artificial metadata variable.
static DebugTypeInfo getTypeMetadata(swift::Type Ty, llvm::Type *StorageTy,
Size size, Alignment align);
/// Create a forward declaration for a type whose size is unknown.
static DebugTypeInfo getForwardDecl(swift::Type Ty);
/// Create a standalone type from a TypeInfo object.
static DebugTypeInfo getFromTypeInfo(swift::Type Ty, const TypeInfo &Info,
IRGenModule &IGM);
/// Global variables.
static DebugTypeInfo getGlobal(SILGlobalVariable *GV,
llvm::Type *StorageType, IRGenModule &IGM);
static DebugTypeInfo getGlobalFixedBuffer(SILGlobalVariable *GV,
llvm::Type *StorageType,
Size SizeInBytes, Alignment align);
/// ObjC classes.
static DebugTypeInfo getObjCClass(ClassDecl *theClass,
llvm::Type *StorageType, Size size,
Alignment align);
/// Error type.
static DebugTypeInfo getErrorResult(swift::Type Ty, IRGenModule &IGM);
TypeBase *getType() const { return Type; }
TypeDecl *getDecl() const;
// Determine whether this type is an Archetype dependent on a generic context.
bool isContextArchetype() const {
if (auto archetype =
Type->getWithoutSpecifierType()->getAs<ArchetypeType>()) {
return !isa<OpaqueTypeArchetypeType>(archetype);
}
return false;
}
llvm::Type *getFragmentStorageType() const { return FragmentStorageType; }
Alignment getAlignment() const { return Align; }
bool isNull() const { return Type == nullptr; }
bool isForwardDecl() const { return FragmentStorageType == nullptr; }
bool isMetadataType() const { return IsMetadataType; }
bool hasDefaultAlignment() const { return DefaultAlignment; }
bool isFixedBuffer() const { return IsFixedBuffer; }
std::optional<uint32_t> getNumExtraInhabitants() const {
return NumExtraInhabitants;
}
bool operator==(DebugTypeInfo T) const;
bool operator!=(DebugTypeInfo T) const;
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void dump() const;
#endif
};
/// A DebugTypeInfo with a defined size (that may be 0).
class CompletedDebugTypeInfo : public DebugTypeInfo {
Size::int_type SizeInBits;
CompletedDebugTypeInfo(DebugTypeInfo DbgTy, Size::int_type SizeInBits)
: DebugTypeInfo(DbgTy), SizeInBits(SizeInBits) {}
public:
static std::optional<CompletedDebugTypeInfo>
get(DebugTypeInfo DbgTy, std::optional<Size::int_type> SizeInBits) {
if (!SizeInBits)
return {};
return CompletedDebugTypeInfo(DbgTy, *SizeInBits);
}
static std::optional<CompletedDebugTypeInfo>
getFromTypeInfo(swift::Type Ty, const TypeInfo &Info, IRGenModule &IGM);
Size::int_type getSizeInBits() const { return SizeInBits; }
};
}
}
namespace llvm {
// Dense map specialization.
template <> struct DenseMapInfo<swift::irgen::DebugTypeInfo> {
static swift::irgen::DebugTypeInfo getEmptyKey() {
return {};
}
static swift::irgen::DebugTypeInfo getTombstoneKey() {
return swift::irgen::DebugTypeInfo(
llvm::DenseMapInfo<swift::TypeBase *>::getTombstoneKey(), nullptr,
swift::irgen::Alignment(), /* HasDefaultAlignment = */ false);
}
static unsigned getHashValue(swift::irgen::DebugTypeInfo Val) {
return DenseMapInfo<swift::CanType>::getHashValue(Val.getType());
}
static bool isEqual(swift::irgen::DebugTypeInfo LHS,
swift::irgen::DebugTypeInfo RHS) {
return LHS == RHS;
}
};
}
#endif