1ff0cc061SDimitry Andric //===- DebugInfoMetadata.cpp - Implement debug info metadata --------------===//
2ff0cc061SDimitry Andric //
3ff0cc061SDimitry Andric // The LLVM Compiler Infrastructure
4ff0cc061SDimitry Andric //
5ff0cc061SDimitry Andric // This file is distributed under the University of Illinois Open Source
6ff0cc061SDimitry Andric // License. See LICENSE.TXT for details.
7ff0cc061SDimitry Andric //
8ff0cc061SDimitry Andric //===----------------------------------------------------------------------===//
9ff0cc061SDimitry Andric //
10ff0cc061SDimitry Andric // This file implements the debug info Metadata classes.
11ff0cc061SDimitry Andric //
12ff0cc061SDimitry Andric //===----------------------------------------------------------------------===//
13ff0cc061SDimitry Andric
14ff0cc061SDimitry Andric #include "llvm/IR/DebugInfoMetadata.h"
15ff0cc061SDimitry Andric #include "LLVMContextImpl.h"
16ff0cc061SDimitry Andric #include "MetadataImpl.h"
17*b5893f02SDimitry Andric #include "llvm/ADT/SmallSet.h"
18ff0cc061SDimitry Andric #include "llvm/ADT/StringSwitch.h"
19f37b6182SDimitry Andric #include "llvm/IR/DIBuilder.h"
20ff0cc061SDimitry Andric #include "llvm/IR/Function.h"
212cab237bSDimitry Andric #include "llvm/IR/Instructions.h"
22ff0cc061SDimitry Andric
23*b5893f02SDimitry Andric #include <numeric>
24*b5893f02SDimitry Andric
25ff0cc061SDimitry Andric using namespace llvm;
26ff0cc061SDimitry Andric
DILocation(LLVMContext & C,StorageType Storage,unsigned Line,unsigned Column,ArrayRef<Metadata * > MDs,bool ImplicitCode)27ff0cc061SDimitry Andric DILocation::DILocation(LLVMContext &C, StorageType Storage, unsigned Line,
28*b5893f02SDimitry Andric unsigned Column, ArrayRef<Metadata *> MDs,
29*b5893f02SDimitry Andric bool ImplicitCode)
30ff0cc061SDimitry Andric : MDNode(C, DILocationKind, Storage, MDs) {
31ff0cc061SDimitry Andric assert((MDs.size() == 1 || MDs.size() == 2) &&
32ff0cc061SDimitry Andric "Expected a scope and optional inlined-at");
33ff0cc061SDimitry Andric
34ff0cc061SDimitry Andric // Set line and column.
35ff0cc061SDimitry Andric assert(Column < (1u << 16) && "Expected 16-bit column");
36ff0cc061SDimitry Andric
37ff0cc061SDimitry Andric SubclassData32 = Line;
38ff0cc061SDimitry Andric SubclassData16 = Column;
39*b5893f02SDimitry Andric
40*b5893f02SDimitry Andric setImplicitCode(ImplicitCode);
41ff0cc061SDimitry Andric }
42ff0cc061SDimitry Andric
adjustColumn(unsigned & Column)43ff0cc061SDimitry Andric static void adjustColumn(unsigned &Column) {
44ff0cc061SDimitry Andric // Set to unknown on overflow. We only have 16 bits to play with here.
45ff0cc061SDimitry Andric if (Column >= (1u << 16))
46ff0cc061SDimitry Andric Column = 0;
47ff0cc061SDimitry Andric }
48ff0cc061SDimitry Andric
getImpl(LLVMContext & Context,unsigned Line,unsigned Column,Metadata * Scope,Metadata * InlinedAt,bool ImplicitCode,StorageType Storage,bool ShouldCreate)49ff0cc061SDimitry Andric DILocation *DILocation::getImpl(LLVMContext &Context, unsigned Line,
50ff0cc061SDimitry Andric unsigned Column, Metadata *Scope,
51*b5893f02SDimitry Andric Metadata *InlinedAt, bool ImplicitCode,
52*b5893f02SDimitry Andric StorageType Storage, bool ShouldCreate) {
53ff0cc061SDimitry Andric // Fixup column.
54ff0cc061SDimitry Andric adjustColumn(Column);
55ff0cc061SDimitry Andric
56ff0cc061SDimitry Andric if (Storage == Uniqued) {
57*b5893f02SDimitry Andric if (auto *N = getUniqued(Context.pImpl->DILocations,
58*b5893f02SDimitry Andric DILocationInfo::KeyTy(Line, Column, Scope,
59*b5893f02SDimitry Andric InlinedAt, ImplicitCode)))
60ff0cc061SDimitry Andric return N;
61ff0cc061SDimitry Andric if (!ShouldCreate)
62ff0cc061SDimitry Andric return nullptr;
63ff0cc061SDimitry Andric } else {
64ff0cc061SDimitry Andric assert(ShouldCreate && "Expected non-uniqued nodes to always be created");
65ff0cc061SDimitry Andric }
66ff0cc061SDimitry Andric
67ff0cc061SDimitry Andric SmallVector<Metadata *, 2> Ops;
68ff0cc061SDimitry Andric Ops.push_back(Scope);
69ff0cc061SDimitry Andric if (InlinedAt)
70ff0cc061SDimitry Andric Ops.push_back(InlinedAt);
71*b5893f02SDimitry Andric return storeImpl(new (Ops.size()) DILocation(Context, Storage, Line, Column,
72*b5893f02SDimitry Andric Ops, ImplicitCode),
73ff0cc061SDimitry Andric Storage, Context.pImpl->DILocations);
74ff0cc061SDimitry Andric }
75ff0cc061SDimitry Andric
getMergedLocation(const DILocation * LocA,const DILocation * LocB)764ba319b5SDimitry Andric const DILocation *DILocation::getMergedLocation(const DILocation *LocA,
77*b5893f02SDimitry Andric const DILocation *LocB) {
782cab237bSDimitry Andric if (!LocA || !LocB)
792cab237bSDimitry Andric return nullptr;
802cab237bSDimitry Andric
81*b5893f02SDimitry Andric if (LocA == LocB)
822cab237bSDimitry Andric return LocA;
832cab237bSDimitry Andric
842cab237bSDimitry Andric SmallPtrSet<DILocation *, 5> InlinedLocationsA;
852cab237bSDimitry Andric for (DILocation *L = LocA->getInlinedAt(); L; L = L->getInlinedAt())
862cab237bSDimitry Andric InlinedLocationsA.insert(L);
87*b5893f02SDimitry Andric SmallSet<std::pair<DIScope *, DILocation *>, 5> Locations;
88*b5893f02SDimitry Andric DIScope *S = LocA->getScope();
89*b5893f02SDimitry Andric DILocation *L = LocA->getInlinedAt();
90*b5893f02SDimitry Andric while (S) {
91*b5893f02SDimitry Andric Locations.insert(std::make_pair(S, L));
92*b5893f02SDimitry Andric S = S->getScope().resolve();
93*b5893f02SDimitry Andric if (!S && L) {
94*b5893f02SDimitry Andric S = L->getScope();
95*b5893f02SDimitry Andric L = L->getInlinedAt();
96*b5893f02SDimitry Andric }
97*b5893f02SDimitry Andric }
982cab237bSDimitry Andric const DILocation *Result = LocB;
99*b5893f02SDimitry Andric S = LocB->getScope();
100*b5893f02SDimitry Andric L = LocB->getInlinedAt();
101*b5893f02SDimitry Andric while (S) {
102*b5893f02SDimitry Andric if (Locations.count(std::make_pair(S, L)))
1032cab237bSDimitry Andric break;
104*b5893f02SDimitry Andric S = S->getScope().resolve();
105*b5893f02SDimitry Andric if (!S && L) {
106*b5893f02SDimitry Andric S = L->getScope();
107*b5893f02SDimitry Andric L = L->getInlinedAt();
1082cab237bSDimitry Andric }
1092cab237bSDimitry Andric }
1102cab237bSDimitry Andric
111*b5893f02SDimitry Andric // If the two locations are irreconsilable, just pick one. This is misleading,
112*b5893f02SDimitry Andric // but on the other hand, it's a "line 0" location.
113*b5893f02SDimitry Andric if (!S || !isa<DILocalScope>(S))
114*b5893f02SDimitry Andric S = LocA->getScope();
115*b5893f02SDimitry Andric return DILocation::get(Result->getContext(), 0, 0, S, L);
116*b5893f02SDimitry Andric }
117*b5893f02SDimitry Andric
encodeDiscriminator(unsigned BD,unsigned DF,unsigned CI)118*b5893f02SDimitry Andric Optional<unsigned> DILocation::encodeDiscriminator(unsigned BD, unsigned DF, unsigned CI) {
119*b5893f02SDimitry Andric SmallVector<unsigned, 3> Components = {BD, DF, CI};
120*b5893f02SDimitry Andric uint64_t RemainingWork = 0U;
121*b5893f02SDimitry Andric // We use RemainingWork to figure out if we have no remaining components to
122*b5893f02SDimitry Andric // encode. For example: if BD != 0 but DF == 0 && CI == 0, we don't need to
123*b5893f02SDimitry Andric // encode anything for the latter 2.
124*b5893f02SDimitry Andric // Since any of the input components is at most 32 bits, their sum will be
125*b5893f02SDimitry Andric // less than 34 bits, and thus RemainingWork won't overflow.
126*b5893f02SDimitry Andric RemainingWork = std::accumulate(Components.begin(), Components.end(), RemainingWork);
127*b5893f02SDimitry Andric
128*b5893f02SDimitry Andric int I = 0;
129*b5893f02SDimitry Andric unsigned Ret = 0;
130*b5893f02SDimitry Andric unsigned NextBitInsertionIndex = 0;
131*b5893f02SDimitry Andric while (RemainingWork > 0) {
132*b5893f02SDimitry Andric unsigned C = Components[I++];
133*b5893f02SDimitry Andric RemainingWork -= C;
134*b5893f02SDimitry Andric unsigned EC = encodeComponent(C);
135*b5893f02SDimitry Andric Ret |= (EC << NextBitInsertionIndex);
136*b5893f02SDimitry Andric NextBitInsertionIndex += encodingBits(C);
137*b5893f02SDimitry Andric }
138*b5893f02SDimitry Andric
139*b5893f02SDimitry Andric // Encoding may be unsuccessful because of overflow. We determine success by
140*b5893f02SDimitry Andric // checking equivalence of components before & after encoding. Alternatively,
141*b5893f02SDimitry Andric // we could determine Success during encoding, but the current alternative is
142*b5893f02SDimitry Andric // simpler.
143*b5893f02SDimitry Andric unsigned TBD, TDF, TCI = 0;
144*b5893f02SDimitry Andric decodeDiscriminator(Ret, TBD, TDF, TCI);
145*b5893f02SDimitry Andric if (TBD == BD && TDF == DF && TCI == CI)
146*b5893f02SDimitry Andric return Ret;
147*b5893f02SDimitry Andric return None;
148*b5893f02SDimitry Andric }
149*b5893f02SDimitry Andric
decodeDiscriminator(unsigned D,unsigned & BD,unsigned & DF,unsigned & CI)150*b5893f02SDimitry Andric void DILocation::decodeDiscriminator(unsigned D, unsigned &BD, unsigned &DF,
151*b5893f02SDimitry Andric unsigned &CI) {
152*b5893f02SDimitry Andric BD = getUnsignedFromPrefixEncoding(D);
153*b5893f02SDimitry Andric DF = getUnsignedFromPrefixEncoding(getNextComponentInDiscriminator(D));
154*b5893f02SDimitry Andric CI = getUnsignedFromPrefixEncoding(
155*b5893f02SDimitry Andric getNextComponentInDiscriminator(getNextComponentInDiscriminator(D)));
156*b5893f02SDimitry Andric }
157*b5893f02SDimitry Andric
158*b5893f02SDimitry Andric
getFlag(StringRef Flag)159d88c1a5aSDimitry Andric DINode::DIFlags DINode::getFlag(StringRef Flag) {
160d88c1a5aSDimitry Andric return StringSwitch<DIFlags>(Flag)
161ff0cc061SDimitry Andric #define HANDLE_DI_FLAG(ID, NAME) .Case("DIFlag" #NAME, Flag##NAME)
162ff0cc061SDimitry Andric #include "llvm/IR/DebugInfoFlags.def"
163d88c1a5aSDimitry Andric .Default(DINode::FlagZero);
164ff0cc061SDimitry Andric }
165ff0cc061SDimitry Andric
getFlagString(DIFlags Flag)166d88c1a5aSDimitry Andric StringRef DINode::getFlagString(DIFlags Flag) {
167ff0cc061SDimitry Andric switch (Flag) {
168ff0cc061SDimitry Andric #define HANDLE_DI_FLAG(ID, NAME) \
169ff0cc061SDimitry Andric case Flag##NAME: \
170ff0cc061SDimitry Andric return "DIFlag" #NAME;
171ff0cc061SDimitry Andric #include "llvm/IR/DebugInfoFlags.def"
172ff0cc061SDimitry Andric }
173d88c1a5aSDimitry Andric return "";
174ff0cc061SDimitry Andric }
175ff0cc061SDimitry Andric
splitFlags(DIFlags Flags,SmallVectorImpl<DIFlags> & SplitFlags)176d88c1a5aSDimitry Andric DINode::DIFlags DINode::splitFlags(DIFlags Flags,
177d88c1a5aSDimitry Andric SmallVectorImpl<DIFlags> &SplitFlags) {
178d88c1a5aSDimitry Andric // Flags that are packed together need to be specially handled, so
179d88c1a5aSDimitry Andric // that, for example, we emit "DIFlagPublic" and not
180d88c1a5aSDimitry Andric // "DIFlagPrivate | DIFlagProtected".
181d88c1a5aSDimitry Andric if (DIFlags A = Flags & FlagAccessibility) {
182ff0cc061SDimitry Andric if (A == FlagPrivate)
183ff0cc061SDimitry Andric SplitFlags.push_back(FlagPrivate);
184ff0cc061SDimitry Andric else if (A == FlagProtected)
185ff0cc061SDimitry Andric SplitFlags.push_back(FlagProtected);
186ff0cc061SDimitry Andric else
187ff0cc061SDimitry Andric SplitFlags.push_back(FlagPublic);
188ff0cc061SDimitry Andric Flags &= ~A;
189ff0cc061SDimitry Andric }
190d88c1a5aSDimitry Andric if (DIFlags R = Flags & FlagPtrToMemberRep) {
1913ca95b02SDimitry Andric if (R == FlagSingleInheritance)
1923ca95b02SDimitry Andric SplitFlags.push_back(FlagSingleInheritance);
1933ca95b02SDimitry Andric else if (R == FlagMultipleInheritance)
1943ca95b02SDimitry Andric SplitFlags.push_back(FlagMultipleInheritance);
1953ca95b02SDimitry Andric else
1963ca95b02SDimitry Andric SplitFlags.push_back(FlagVirtualInheritance);
1973ca95b02SDimitry Andric Flags &= ~R;
1983ca95b02SDimitry Andric }
199d88c1a5aSDimitry Andric if ((Flags & FlagIndirectVirtualBase) == FlagIndirectVirtualBase) {
200d88c1a5aSDimitry Andric Flags &= ~FlagIndirectVirtualBase;
201d88c1a5aSDimitry Andric SplitFlags.push_back(FlagIndirectVirtualBase);
202d88c1a5aSDimitry Andric }
203ff0cc061SDimitry Andric
204ff0cc061SDimitry Andric #define HANDLE_DI_FLAG(ID, NAME) \
205d88c1a5aSDimitry Andric if (DIFlags Bit = Flags & Flag##NAME) { \
206ff0cc061SDimitry Andric SplitFlags.push_back(Bit); \
207ff0cc061SDimitry Andric Flags &= ~Bit; \
208ff0cc061SDimitry Andric }
209ff0cc061SDimitry Andric #include "llvm/IR/DebugInfoFlags.def"
210ff0cc061SDimitry Andric return Flags;
211ff0cc061SDimitry Andric }
212ff0cc061SDimitry Andric
getScope() const213ff0cc061SDimitry Andric DIScopeRef DIScope::getScope() const {
214ff0cc061SDimitry Andric if (auto *T = dyn_cast<DIType>(this))
215ff0cc061SDimitry Andric return T->getScope();
216ff0cc061SDimitry Andric
217ff0cc061SDimitry Andric if (auto *SP = dyn_cast<DISubprogram>(this))
218ff0cc061SDimitry Andric return SP->getScope();
219ff0cc061SDimitry Andric
220ff0cc061SDimitry Andric if (auto *LB = dyn_cast<DILexicalBlockBase>(this))
2213ca95b02SDimitry Andric return LB->getScope();
222ff0cc061SDimitry Andric
223ff0cc061SDimitry Andric if (auto *NS = dyn_cast<DINamespace>(this))
2243ca95b02SDimitry Andric return NS->getScope();
225ff0cc061SDimitry Andric
2263dac3a9bSDimitry Andric if (auto *M = dyn_cast<DIModule>(this))
2273ca95b02SDimitry Andric return M->getScope();
2283dac3a9bSDimitry Andric
229ff0cc061SDimitry Andric assert((isa<DIFile>(this) || isa<DICompileUnit>(this)) &&
230ff0cc061SDimitry Andric "Unhandled type of scope.");
231ff0cc061SDimitry Andric return nullptr;
232ff0cc061SDimitry Andric }
233ff0cc061SDimitry Andric
getName() const234ff0cc061SDimitry Andric StringRef DIScope::getName() const {
235ff0cc061SDimitry Andric if (auto *T = dyn_cast<DIType>(this))
236ff0cc061SDimitry Andric return T->getName();
237ff0cc061SDimitry Andric if (auto *SP = dyn_cast<DISubprogram>(this))
238ff0cc061SDimitry Andric return SP->getName();
239ff0cc061SDimitry Andric if (auto *NS = dyn_cast<DINamespace>(this))
240ff0cc061SDimitry Andric return NS->getName();
2413dac3a9bSDimitry Andric if (auto *M = dyn_cast<DIModule>(this))
2423dac3a9bSDimitry Andric return M->getName();
243ff0cc061SDimitry Andric assert((isa<DILexicalBlockBase>(this) || isa<DIFile>(this) ||
244ff0cc061SDimitry Andric isa<DICompileUnit>(this)) &&
245ff0cc061SDimitry Andric "Unhandled type of scope.");
246ff0cc061SDimitry Andric return "";
247ff0cc061SDimitry Andric }
248ff0cc061SDimitry Andric
249ff0cc061SDimitry Andric #ifndef NDEBUG
isCanonical(const MDString * S)250ff0cc061SDimitry Andric static bool isCanonical(const MDString *S) {
251ff0cc061SDimitry Andric return !S || !S->getString().empty();
252ff0cc061SDimitry Andric }
253ff0cc061SDimitry Andric #endif
254ff0cc061SDimitry Andric
getImpl(LLVMContext & Context,unsigned Tag,MDString * Header,ArrayRef<Metadata * > DwarfOps,StorageType Storage,bool ShouldCreate)255ff0cc061SDimitry Andric GenericDINode *GenericDINode::getImpl(LLVMContext &Context, unsigned Tag,
256ff0cc061SDimitry Andric MDString *Header,
257ff0cc061SDimitry Andric ArrayRef<Metadata *> DwarfOps,
258ff0cc061SDimitry Andric StorageType Storage, bool ShouldCreate) {
259ff0cc061SDimitry Andric unsigned Hash = 0;
260ff0cc061SDimitry Andric if (Storage == Uniqued) {
2613ca95b02SDimitry Andric GenericDINodeInfo::KeyTy Key(Tag, Header, DwarfOps);
262ff0cc061SDimitry Andric if (auto *N = getUniqued(Context.pImpl->GenericDINodes, Key))
263ff0cc061SDimitry Andric return N;
264ff0cc061SDimitry Andric if (!ShouldCreate)
265ff0cc061SDimitry Andric return nullptr;
266ff0cc061SDimitry Andric Hash = Key.getHash();
267ff0cc061SDimitry Andric } else {
268ff0cc061SDimitry Andric assert(ShouldCreate && "Expected non-uniqued nodes to always be created");
269ff0cc061SDimitry Andric }
270ff0cc061SDimitry Andric
271ff0cc061SDimitry Andric // Use a nullptr for empty headers.
272ff0cc061SDimitry Andric assert(isCanonical(Header) && "Expected canonical MDString");
273ff0cc061SDimitry Andric Metadata *PreOps[] = {Header};
274ff0cc061SDimitry Andric return storeImpl(new (DwarfOps.size() + 1) GenericDINode(
275ff0cc061SDimitry Andric Context, Storage, Hash, Tag, PreOps, DwarfOps),
276ff0cc061SDimitry Andric Storage, Context.pImpl->GenericDINodes);
277ff0cc061SDimitry Andric }
278ff0cc061SDimitry Andric
recalculateHash()279ff0cc061SDimitry Andric void GenericDINode::recalculateHash() {
280ff0cc061SDimitry Andric setHash(GenericDINodeInfo::KeyTy::calculateHash(this));
281ff0cc061SDimitry Andric }
282ff0cc061SDimitry Andric
283ff0cc061SDimitry Andric #define UNWRAP_ARGS_IMPL(...) __VA_ARGS__
284ff0cc061SDimitry Andric #define UNWRAP_ARGS(ARGS) UNWRAP_ARGS_IMPL ARGS
285ff0cc061SDimitry Andric #define DEFINE_GETIMPL_LOOKUP(CLASS, ARGS) \
286ff0cc061SDimitry Andric do { \
287ff0cc061SDimitry Andric if (Storage == Uniqued) { \
288ff0cc061SDimitry Andric if (auto *N = getUniqued(Context.pImpl->CLASS##s, \
289ff0cc061SDimitry Andric CLASS##Info::KeyTy(UNWRAP_ARGS(ARGS)))) \
290ff0cc061SDimitry Andric return N; \
291ff0cc061SDimitry Andric if (!ShouldCreate) \
292ff0cc061SDimitry Andric return nullptr; \
293ff0cc061SDimitry Andric } else { \
294ff0cc061SDimitry Andric assert(ShouldCreate && \
295ff0cc061SDimitry Andric "Expected non-uniqued nodes to always be created"); \
296ff0cc061SDimitry Andric } \
297ff0cc061SDimitry Andric } while (false)
298ff0cc061SDimitry Andric #define DEFINE_GETIMPL_STORE(CLASS, ARGS, OPS) \
2993ca95b02SDimitry Andric return storeImpl(new (array_lengthof(OPS)) \
300ff0cc061SDimitry Andric CLASS(Context, Storage, UNWRAP_ARGS(ARGS), OPS), \
301ff0cc061SDimitry Andric Storage, Context.pImpl->CLASS##s)
302ff0cc061SDimitry Andric #define DEFINE_GETIMPL_STORE_NO_OPS(CLASS, ARGS) \
303ff0cc061SDimitry Andric return storeImpl(new (0u) CLASS(Context, Storage, UNWRAP_ARGS(ARGS)), \
304ff0cc061SDimitry Andric Storage, Context.pImpl->CLASS##s)
305ff0cc061SDimitry Andric #define DEFINE_GETIMPL_STORE_NO_CONSTRUCTOR_ARGS(CLASS, OPS) \
3063ca95b02SDimitry Andric return storeImpl(new (array_lengthof(OPS)) CLASS(Context, Storage, OPS), \
307ff0cc061SDimitry Andric Storage, Context.pImpl->CLASS##s)
308f37b6182SDimitry Andric #define DEFINE_GETIMPL_STORE_N(CLASS, ARGS, OPS, NUM_OPS) \
309f37b6182SDimitry Andric return storeImpl(new (NUM_OPS) \
310f37b6182SDimitry Andric CLASS(Context, Storage, UNWRAP_ARGS(ARGS), OPS), \
311f37b6182SDimitry Andric Storage, Context.pImpl->CLASS##s)
312ff0cc061SDimitry Andric
getImpl(LLVMContext & Context,int64_t Count,int64_t Lo,StorageType Storage,bool ShouldCreate)313ff0cc061SDimitry Andric DISubrange *DISubrange::getImpl(LLVMContext &Context, int64_t Count, int64_t Lo,
314ff0cc061SDimitry Andric StorageType Storage, bool ShouldCreate) {
3154ba319b5SDimitry Andric auto *CountNode = ConstantAsMetadata::get(
3164ba319b5SDimitry Andric ConstantInt::getSigned(Type::getInt64Ty(Context), Count));
3174ba319b5SDimitry Andric return getImpl(Context, CountNode, Lo, Storage, ShouldCreate);
3184ba319b5SDimitry Andric }
3194ba319b5SDimitry Andric
getImpl(LLVMContext & Context,Metadata * CountNode,int64_t Lo,StorageType Storage,bool ShouldCreate)3204ba319b5SDimitry Andric DISubrange *DISubrange::getImpl(LLVMContext &Context, Metadata *CountNode,
3214ba319b5SDimitry Andric int64_t Lo, StorageType Storage,
3224ba319b5SDimitry Andric bool ShouldCreate) {
3234ba319b5SDimitry Andric DEFINE_GETIMPL_LOOKUP(DISubrange, (CountNode, Lo));
3244ba319b5SDimitry Andric Metadata *Ops[] = { CountNode };
3254ba319b5SDimitry Andric DEFINE_GETIMPL_STORE(DISubrange, (CountNode, Lo), Ops);
326ff0cc061SDimitry Andric }
327ff0cc061SDimitry Andric
getImpl(LLVMContext & Context,int64_t Value,bool IsUnsigned,MDString * Name,StorageType Storage,bool ShouldCreate)328ff0cc061SDimitry Andric DIEnumerator *DIEnumerator::getImpl(LLVMContext &Context, int64_t Value,
3294ba319b5SDimitry Andric bool IsUnsigned, MDString *Name,
3304ba319b5SDimitry Andric StorageType Storage, bool ShouldCreate) {
331ff0cc061SDimitry Andric assert(isCanonical(Name) && "Expected canonical MDString");
3324ba319b5SDimitry Andric DEFINE_GETIMPL_LOOKUP(DIEnumerator, (Value, IsUnsigned, Name));
333ff0cc061SDimitry Andric Metadata *Ops[] = {Name};
3344ba319b5SDimitry Andric DEFINE_GETIMPL_STORE(DIEnumerator, (Value, IsUnsigned), Ops);
335ff0cc061SDimitry Andric }
336ff0cc061SDimitry Andric
getImpl(LLVMContext & Context,unsigned Tag,MDString * Name,uint64_t SizeInBits,uint32_t AlignInBits,unsigned Encoding,DIFlags Flags,StorageType Storage,bool ShouldCreate)337ff0cc061SDimitry Andric DIBasicType *DIBasicType::getImpl(LLVMContext &Context, unsigned Tag,
338ff0cc061SDimitry Andric MDString *Name, uint64_t SizeInBits,
339d88c1a5aSDimitry Andric uint32_t AlignInBits, unsigned Encoding,
340*b5893f02SDimitry Andric DIFlags Flags, StorageType Storage,
341*b5893f02SDimitry Andric bool ShouldCreate) {
342ff0cc061SDimitry Andric assert(isCanonical(Name) && "Expected canonical MDString");
3433ca95b02SDimitry Andric DEFINE_GETIMPL_LOOKUP(DIBasicType,
344*b5893f02SDimitry Andric (Tag, Name, SizeInBits, AlignInBits, Encoding, Flags));
345ff0cc061SDimitry Andric Metadata *Ops[] = {nullptr, nullptr, Name};
346*b5893f02SDimitry Andric DEFINE_GETIMPL_STORE(DIBasicType, (Tag, SizeInBits, AlignInBits, Encoding,
347*b5893f02SDimitry Andric Flags), Ops);
348ff0cc061SDimitry Andric }
349ff0cc061SDimitry Andric
getSignedness() const3504ba319b5SDimitry Andric Optional<DIBasicType::Signedness> DIBasicType::getSignedness() const {
3514ba319b5SDimitry Andric switch (getEncoding()) {
3524ba319b5SDimitry Andric case dwarf::DW_ATE_signed:
3534ba319b5SDimitry Andric case dwarf::DW_ATE_signed_char:
3544ba319b5SDimitry Andric return Signedness::Signed;
3554ba319b5SDimitry Andric case dwarf::DW_ATE_unsigned:
3564ba319b5SDimitry Andric case dwarf::DW_ATE_unsigned_char:
3574ba319b5SDimitry Andric return Signedness::Unsigned;
3584ba319b5SDimitry Andric default:
3594ba319b5SDimitry Andric return None;
3604ba319b5SDimitry Andric }
3614ba319b5SDimitry Andric }
3624ba319b5SDimitry Andric
getImpl(LLVMContext & Context,unsigned Tag,MDString * Name,Metadata * File,unsigned Line,Metadata * Scope,Metadata * BaseType,uint64_t SizeInBits,uint32_t AlignInBits,uint64_t OffsetInBits,Optional<unsigned> DWARFAddressSpace,DIFlags Flags,Metadata * ExtraData,StorageType Storage,bool ShouldCreate)363ff0cc061SDimitry Andric DIDerivedType *DIDerivedType::getImpl(
364ff0cc061SDimitry Andric LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
365ff0cc061SDimitry Andric unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits,
3667a7e6055SDimitry Andric uint32_t AlignInBits, uint64_t OffsetInBits,
3677a7e6055SDimitry Andric Optional<unsigned> DWARFAddressSpace, DIFlags Flags, Metadata *ExtraData,
3687a7e6055SDimitry Andric StorageType Storage, bool ShouldCreate) {
369ff0cc061SDimitry Andric assert(isCanonical(Name) && "Expected canonical MDString");
3703ca95b02SDimitry Andric DEFINE_GETIMPL_LOOKUP(DIDerivedType,
3713ca95b02SDimitry Andric (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
3727a7e6055SDimitry Andric AlignInBits, OffsetInBits, DWARFAddressSpace, Flags,
3737a7e6055SDimitry Andric ExtraData));
374ff0cc061SDimitry Andric Metadata *Ops[] = {File, Scope, Name, BaseType, ExtraData};
375ff0cc061SDimitry Andric DEFINE_GETIMPL_STORE(
3767a7e6055SDimitry Andric DIDerivedType, (Tag, Line, SizeInBits, AlignInBits, OffsetInBits,
3777a7e6055SDimitry Andric DWARFAddressSpace, Flags), Ops);
378ff0cc061SDimitry Andric }
379ff0cc061SDimitry Andric
getImpl(LLVMContext & Context,unsigned Tag,MDString * Name,Metadata * File,unsigned Line,Metadata * Scope,Metadata * BaseType,uint64_t SizeInBits,uint32_t AlignInBits,uint64_t OffsetInBits,DIFlags Flags,Metadata * Elements,unsigned RuntimeLang,Metadata * VTableHolder,Metadata * TemplateParams,MDString * Identifier,Metadata * Discriminator,StorageType Storage,bool ShouldCreate)380ff0cc061SDimitry Andric DICompositeType *DICompositeType::getImpl(
381ff0cc061SDimitry Andric LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
382ff0cc061SDimitry Andric unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits,
383d88c1a5aSDimitry Andric uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags,
384ff0cc061SDimitry Andric Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder,
3854ba319b5SDimitry Andric Metadata *TemplateParams, MDString *Identifier, Metadata *Discriminator,
3864ba319b5SDimitry Andric StorageType Storage, bool ShouldCreate) {
387ff0cc061SDimitry Andric assert(isCanonical(Name) && "Expected canonical MDString");
3883ca95b02SDimitry Andric
3893ca95b02SDimitry Andric // Keep this in sync with buildODRType.
3903ca95b02SDimitry Andric DEFINE_GETIMPL_LOOKUP(
3913ca95b02SDimitry Andric DICompositeType, (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
3923ca95b02SDimitry Andric AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
3934ba319b5SDimitry Andric VTableHolder, TemplateParams, Identifier, Discriminator));
394ff0cc061SDimitry Andric Metadata *Ops[] = {File, Scope, Name, BaseType,
3954ba319b5SDimitry Andric Elements, VTableHolder, TemplateParams, Identifier,
3964ba319b5SDimitry Andric Discriminator};
397ff0cc061SDimitry Andric DEFINE_GETIMPL_STORE(DICompositeType, (Tag, Line, RuntimeLang, SizeInBits,
398ff0cc061SDimitry Andric AlignInBits, OffsetInBits, Flags),
399ff0cc061SDimitry Andric Ops);
400ff0cc061SDimitry Andric }
401ff0cc061SDimitry Andric
buildODRType(LLVMContext & Context,MDString & Identifier,unsigned Tag,MDString * Name,Metadata * File,unsigned Line,Metadata * Scope,Metadata * BaseType,uint64_t SizeInBits,uint32_t AlignInBits,uint64_t OffsetInBits,DIFlags Flags,Metadata * Elements,unsigned RuntimeLang,Metadata * VTableHolder,Metadata * TemplateParams,Metadata * Discriminator)4023ca95b02SDimitry Andric DICompositeType *DICompositeType::buildODRType(
4033ca95b02SDimitry Andric LLVMContext &Context, MDString &Identifier, unsigned Tag, MDString *Name,
4043ca95b02SDimitry Andric Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType,
405d88c1a5aSDimitry Andric uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
406d88c1a5aSDimitry Andric DIFlags Flags, Metadata *Elements, unsigned RuntimeLang,
4074ba319b5SDimitry Andric Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator) {
4083ca95b02SDimitry Andric assert(!Identifier.getString().empty() && "Expected valid identifier");
4093ca95b02SDimitry Andric if (!Context.isODRUniquingDebugTypes())
4103ca95b02SDimitry Andric return nullptr;
4113ca95b02SDimitry Andric auto *&CT = (*Context.pImpl->DITypeMap)[&Identifier];
4123ca95b02SDimitry Andric if (!CT)
4133ca95b02SDimitry Andric return CT = DICompositeType::getDistinct(
4143ca95b02SDimitry Andric Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits,
4153ca95b02SDimitry Andric AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
4164ba319b5SDimitry Andric VTableHolder, TemplateParams, &Identifier, Discriminator);
4173ca95b02SDimitry Andric
4183ca95b02SDimitry Andric // Only mutate CT if it's a forward declaration and the new operands aren't.
4193ca95b02SDimitry Andric assert(CT->getRawIdentifier() == &Identifier && "Wrong ODR identifier?");
4203ca95b02SDimitry Andric if (!CT->isForwardDecl() || (Flags & DINode::FlagFwdDecl))
4213ca95b02SDimitry Andric return CT;
4223ca95b02SDimitry Andric
4233ca95b02SDimitry Andric // Mutate CT in place. Keep this in sync with getImpl.
4243ca95b02SDimitry Andric CT->mutate(Tag, Line, RuntimeLang, SizeInBits, AlignInBits, OffsetInBits,
4253ca95b02SDimitry Andric Flags);
4263ca95b02SDimitry Andric Metadata *Ops[] = {File, Scope, Name, BaseType,
4274ba319b5SDimitry Andric Elements, VTableHolder, TemplateParams, &Identifier,
4284ba319b5SDimitry Andric Discriminator};
4293ca95b02SDimitry Andric assert((std::end(Ops) - std::begin(Ops)) == (int)CT->getNumOperands() &&
4303ca95b02SDimitry Andric "Mismatched number of operands");
4313ca95b02SDimitry Andric for (unsigned I = 0, E = CT->getNumOperands(); I != E; ++I)
4323ca95b02SDimitry Andric if (Ops[I] != CT->getOperand(I))
4333ca95b02SDimitry Andric CT->setOperand(I, Ops[I]);
4343ca95b02SDimitry Andric return CT;
4353ca95b02SDimitry Andric }
4363ca95b02SDimitry Andric
getODRType(LLVMContext & Context,MDString & Identifier,unsigned Tag,MDString * Name,Metadata * File,unsigned Line,Metadata * Scope,Metadata * BaseType,uint64_t SizeInBits,uint32_t AlignInBits,uint64_t OffsetInBits,DIFlags Flags,Metadata * Elements,unsigned RuntimeLang,Metadata * VTableHolder,Metadata * TemplateParams,Metadata * Discriminator)4373ca95b02SDimitry Andric DICompositeType *DICompositeType::getODRType(
4383ca95b02SDimitry Andric LLVMContext &Context, MDString &Identifier, unsigned Tag, MDString *Name,
4393ca95b02SDimitry Andric Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType,
440d88c1a5aSDimitry Andric uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
441d88c1a5aSDimitry Andric DIFlags Flags, Metadata *Elements, unsigned RuntimeLang,
4424ba319b5SDimitry Andric Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator) {
4433ca95b02SDimitry Andric assert(!Identifier.getString().empty() && "Expected valid identifier");
4443ca95b02SDimitry Andric if (!Context.isODRUniquingDebugTypes())
4453ca95b02SDimitry Andric return nullptr;
4463ca95b02SDimitry Andric auto *&CT = (*Context.pImpl->DITypeMap)[&Identifier];
4473ca95b02SDimitry Andric if (!CT)
4483ca95b02SDimitry Andric CT = DICompositeType::getDistinct(
4493ca95b02SDimitry Andric Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits,
4503ca95b02SDimitry Andric AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder,
4514ba319b5SDimitry Andric TemplateParams, &Identifier, Discriminator);
4523ca95b02SDimitry Andric return CT;
4533ca95b02SDimitry Andric }
4543ca95b02SDimitry Andric
getODRTypeIfExists(LLVMContext & Context,MDString & Identifier)4553ca95b02SDimitry Andric DICompositeType *DICompositeType::getODRTypeIfExists(LLVMContext &Context,
4563ca95b02SDimitry Andric MDString &Identifier) {
4573ca95b02SDimitry Andric assert(!Identifier.getString().empty() && "Expected valid identifier");
4583ca95b02SDimitry Andric if (!Context.isODRUniquingDebugTypes())
4593ca95b02SDimitry Andric return nullptr;
4603ca95b02SDimitry Andric return Context.pImpl->DITypeMap->lookup(&Identifier);
4613ca95b02SDimitry Andric }
4623ca95b02SDimitry Andric
getImpl(LLVMContext & Context,DIFlags Flags,uint8_t CC,Metadata * TypeArray,StorageType Storage,bool ShouldCreate)463d88c1a5aSDimitry Andric DISubroutineType *DISubroutineType::getImpl(LLVMContext &Context, DIFlags Flags,
464d88c1a5aSDimitry Andric uint8_t CC, Metadata *TypeArray,
465ff0cc061SDimitry Andric StorageType Storage,
466ff0cc061SDimitry Andric bool ShouldCreate) {
4673ca95b02SDimitry Andric DEFINE_GETIMPL_LOOKUP(DISubroutineType, (Flags, CC, TypeArray));
4687d523365SDimitry Andric Metadata *Ops[] = {nullptr, nullptr, nullptr, TypeArray};
4693ca95b02SDimitry Andric DEFINE_GETIMPL_STORE(DISubroutineType, (Flags, CC), Ops);
470ff0cc061SDimitry Andric }
471ff0cc061SDimitry Andric
4722cab237bSDimitry Andric // FIXME: Implement this string-enum correspondence with a .def file and macros,
4732cab237bSDimitry Andric // so that the association is explicit rather than implied.
4744ba319b5SDimitry Andric static const char *ChecksumKindName[DIFile::CSK_Last] = {
475d88c1a5aSDimitry Andric "CSK_MD5",
476d88c1a5aSDimitry Andric "CSK_SHA1"
477d88c1a5aSDimitry Andric };
478d88c1a5aSDimitry Andric
getChecksumKindAsString(ChecksumKind CSKind)4794ba319b5SDimitry Andric StringRef DIFile::getChecksumKindAsString(ChecksumKind CSKind) {
4804ba319b5SDimitry Andric assert(CSKind <= DIFile::CSK_Last && "Invalid checksum kind");
4814ba319b5SDimitry Andric // The first space was originally the CSK_None variant, which is now
4824ba319b5SDimitry Andric // obsolete, but the space is still reserved in ChecksumKind, so we account
4834ba319b5SDimitry Andric // for it here.
4844ba319b5SDimitry Andric return ChecksumKindName[CSKind - 1];
485d88c1a5aSDimitry Andric }
486d88c1a5aSDimitry Andric
getChecksumKind(StringRef CSKindStr)4874ba319b5SDimitry Andric Optional<DIFile::ChecksumKind> DIFile::getChecksumKind(StringRef CSKindStr) {
4884ba319b5SDimitry Andric return StringSwitch<Optional<DIFile::ChecksumKind>>(CSKindStr)
4894ba319b5SDimitry Andric .Case("CSK_MD5", DIFile::CSK_MD5)
4904ba319b5SDimitry Andric .Case("CSK_SHA1", DIFile::CSK_SHA1)
4914ba319b5SDimitry Andric .Default(None);
492d88c1a5aSDimitry Andric }
493d88c1a5aSDimitry Andric
getImpl(LLVMContext & Context,MDString * Filename,MDString * Directory,Optional<DIFile::ChecksumInfo<MDString * >> CS,Optional<MDString * > Source,StorageType Storage,bool ShouldCreate)494ff0cc061SDimitry Andric DIFile *DIFile::getImpl(LLVMContext &Context, MDString *Filename,
4954ba319b5SDimitry Andric MDString *Directory,
4964ba319b5SDimitry Andric Optional<DIFile::ChecksumInfo<MDString *>> CS,
4974ba319b5SDimitry Andric Optional<MDString *> Source, StorageType Storage,
498ff0cc061SDimitry Andric bool ShouldCreate) {
499ff0cc061SDimitry Andric assert(isCanonical(Filename) && "Expected canonical MDString");
500ff0cc061SDimitry Andric assert(isCanonical(Directory) && "Expected canonical MDString");
5014ba319b5SDimitry Andric assert((!CS || isCanonical(CS->Value)) && "Expected canonical MDString");
5024ba319b5SDimitry Andric assert((!Source || isCanonical(*Source)) && "Expected canonical MDString");
5034ba319b5SDimitry Andric DEFINE_GETIMPL_LOOKUP(DIFile, (Filename, Directory, CS, Source));
5044ba319b5SDimitry Andric Metadata *Ops[] = {Filename, Directory, CS ? CS->Value : nullptr,
5054ba319b5SDimitry Andric Source.getValueOr(nullptr)};
5064ba319b5SDimitry Andric DEFINE_GETIMPL_STORE(DIFile, (CS, Source), Ops);
507ff0cc061SDimitry Andric }
508ff0cc061SDimitry Andric
getImpl(LLVMContext & Context,unsigned SourceLanguage,Metadata * File,MDString * Producer,bool IsOptimized,MDString * Flags,unsigned RuntimeVersion,MDString * SplitDebugFilename,unsigned EmissionKind,Metadata * EnumTypes,Metadata * RetainedTypes,Metadata * GlobalVariables,Metadata * ImportedEntities,Metadata * Macros,uint64_t DWOId,bool SplitDebugInlining,bool DebugInfoForProfiling,unsigned NameTableKind,bool RangesBaseAddress,StorageType Storage,bool ShouldCreate)509ff0cc061SDimitry Andric DICompileUnit *DICompileUnit::getImpl(
510ff0cc061SDimitry Andric LLVMContext &Context, unsigned SourceLanguage, Metadata *File,
511ff0cc061SDimitry Andric MDString *Producer, bool IsOptimized, MDString *Flags,
512ff0cc061SDimitry Andric unsigned RuntimeVersion, MDString *SplitDebugFilename,
513ff0cc061SDimitry Andric unsigned EmissionKind, Metadata *EnumTypes, Metadata *RetainedTypes,
5143ca95b02SDimitry Andric Metadata *GlobalVariables, Metadata *ImportedEntities, Metadata *Macros,
5157a7e6055SDimitry Andric uint64_t DWOId, bool SplitDebugInlining, bool DebugInfoForProfiling,
516*b5893f02SDimitry Andric unsigned NameTableKind, bool RangesBaseAddress, StorageType Storage,
517*b5893f02SDimitry Andric bool ShouldCreate) {
5187d523365SDimitry Andric assert(Storage != Uniqued && "Cannot unique DICompileUnit");
519ff0cc061SDimitry Andric assert(isCanonical(Producer) && "Expected canonical MDString");
520ff0cc061SDimitry Andric assert(isCanonical(Flags) && "Expected canonical MDString");
521ff0cc061SDimitry Andric assert(isCanonical(SplitDebugFilename) && "Expected canonical MDString");
5227d523365SDimitry Andric
5233ca95b02SDimitry Andric Metadata *Ops[] = {
5243ca95b02SDimitry Andric File, Producer, Flags, SplitDebugFilename,
5253ca95b02SDimitry Andric EnumTypes, RetainedTypes, GlobalVariables, ImportedEntities,
5263ca95b02SDimitry Andric Macros};
5272cab237bSDimitry Andric return storeImpl(new (array_lengthof(Ops)) DICompileUnit(
5282cab237bSDimitry Andric Context, Storage, SourceLanguage, IsOptimized,
5292cab237bSDimitry Andric RuntimeVersion, EmissionKind, DWOId, SplitDebugInlining,
530*b5893f02SDimitry Andric DebugInfoForProfiling, NameTableKind, RangesBaseAddress,
531*b5893f02SDimitry Andric Ops),
5327d523365SDimitry Andric Storage);
533ff0cc061SDimitry Andric }
534ff0cc061SDimitry Andric
5353ca95b02SDimitry Andric Optional<DICompileUnit::DebugEmissionKind>
getEmissionKind(StringRef Str)5363ca95b02SDimitry Andric DICompileUnit::getEmissionKind(StringRef Str) {
5373ca95b02SDimitry Andric return StringSwitch<Optional<DebugEmissionKind>>(Str)
5383ca95b02SDimitry Andric .Case("NoDebug", NoDebug)
5393ca95b02SDimitry Andric .Case("FullDebug", FullDebug)
5403ca95b02SDimitry Andric .Case("LineTablesOnly", LineTablesOnly)
541*b5893f02SDimitry Andric .Case("DebugDirectivesOnly", DebugDirectivesOnly)
542*b5893f02SDimitry Andric .Default(None);
543*b5893f02SDimitry Andric }
544*b5893f02SDimitry Andric
545*b5893f02SDimitry Andric Optional<DICompileUnit::DebugNameTableKind>
getNameTableKind(StringRef Str)546*b5893f02SDimitry Andric DICompileUnit::getNameTableKind(StringRef Str) {
547*b5893f02SDimitry Andric return StringSwitch<Optional<DebugNameTableKind>>(Str)
548*b5893f02SDimitry Andric .Case("Default", DebugNameTableKind::Default)
549*b5893f02SDimitry Andric .Case("GNU", DebugNameTableKind::GNU)
550*b5893f02SDimitry Andric .Case("None", DebugNameTableKind::None)
5513ca95b02SDimitry Andric .Default(None);
5523ca95b02SDimitry Andric }
5533ca95b02SDimitry Andric
emissionKindString(DebugEmissionKind EK)5544ba319b5SDimitry Andric const char *DICompileUnit::emissionKindString(DebugEmissionKind EK) {
5553ca95b02SDimitry Andric switch (EK) {
5563ca95b02SDimitry Andric case NoDebug: return "NoDebug";
5573ca95b02SDimitry Andric case FullDebug: return "FullDebug";
5583ca95b02SDimitry Andric case LineTablesOnly: return "LineTablesOnly";
559*b5893f02SDimitry Andric case DebugDirectivesOnly: return "DebugDirectivesOnly";
560*b5893f02SDimitry Andric }
561*b5893f02SDimitry Andric return nullptr;
562*b5893f02SDimitry Andric }
563*b5893f02SDimitry Andric
nameTableKindString(DebugNameTableKind NTK)564*b5893f02SDimitry Andric const char *DICompileUnit::nameTableKindString(DebugNameTableKind NTK) {
565*b5893f02SDimitry Andric switch (NTK) {
566*b5893f02SDimitry Andric case DebugNameTableKind::Default:
567*b5893f02SDimitry Andric return nullptr;
568*b5893f02SDimitry Andric case DebugNameTableKind::GNU:
569*b5893f02SDimitry Andric return "GNU";
570*b5893f02SDimitry Andric case DebugNameTableKind::None:
571*b5893f02SDimitry Andric return "None";
5723ca95b02SDimitry Andric }
5733ca95b02SDimitry Andric return nullptr;
5743ca95b02SDimitry Andric }
5753ca95b02SDimitry Andric
getSubprogram() const576ff0cc061SDimitry Andric DISubprogram *DILocalScope::getSubprogram() const {
577ff0cc061SDimitry Andric if (auto *Block = dyn_cast<DILexicalBlockBase>(this))
578ff0cc061SDimitry Andric return Block->getScope()->getSubprogram();
579ff0cc061SDimitry Andric return const_cast<DISubprogram *>(cast<DISubprogram>(this));
580ff0cc061SDimitry Andric }
581ff0cc061SDimitry Andric
getNonLexicalBlockFileScope() const5823ca95b02SDimitry Andric DILocalScope *DILocalScope::getNonLexicalBlockFileScope() const {
5833ca95b02SDimitry Andric if (auto *File = dyn_cast<DILexicalBlockFile>(this))
5843ca95b02SDimitry Andric return File->getScope()->getNonLexicalBlockFileScope();
5853ca95b02SDimitry Andric return const_cast<DILocalScope *>(this);
5863ca95b02SDimitry Andric }
5873ca95b02SDimitry Andric
getFlag(StringRef Flag)588*b5893f02SDimitry Andric DISubprogram::DISPFlags DISubprogram::getFlag(StringRef Flag) {
589*b5893f02SDimitry Andric return StringSwitch<DISPFlags>(Flag)
590*b5893f02SDimitry Andric #define HANDLE_DISP_FLAG(ID, NAME) .Case("DISPFlag" #NAME, SPFlag##NAME)
591*b5893f02SDimitry Andric #include "llvm/IR/DebugInfoFlags.def"
592*b5893f02SDimitry Andric .Default(SPFlagZero);
593*b5893f02SDimitry Andric }
594*b5893f02SDimitry Andric
getFlagString(DISPFlags Flag)595*b5893f02SDimitry Andric StringRef DISubprogram::getFlagString(DISPFlags Flag) {
596*b5893f02SDimitry Andric switch (Flag) {
597*b5893f02SDimitry Andric // Appease a warning.
598*b5893f02SDimitry Andric case SPFlagVirtuality:
599*b5893f02SDimitry Andric return "";
600*b5893f02SDimitry Andric #define HANDLE_DISP_FLAG(ID, NAME) \
601*b5893f02SDimitry Andric case SPFlag##NAME: \
602*b5893f02SDimitry Andric return "DISPFlag" #NAME;
603*b5893f02SDimitry Andric #include "llvm/IR/DebugInfoFlags.def"
604*b5893f02SDimitry Andric }
605*b5893f02SDimitry Andric return "";
606*b5893f02SDimitry Andric }
607*b5893f02SDimitry Andric
608*b5893f02SDimitry Andric DISubprogram::DISPFlags
splitFlags(DISPFlags Flags,SmallVectorImpl<DISPFlags> & SplitFlags)609*b5893f02SDimitry Andric DISubprogram::splitFlags(DISPFlags Flags,
610*b5893f02SDimitry Andric SmallVectorImpl<DISPFlags> &SplitFlags) {
611*b5893f02SDimitry Andric // Multi-bit fields can require special handling. In our case, however, the
612*b5893f02SDimitry Andric // only multi-bit field is virtuality, and all its values happen to be
613*b5893f02SDimitry Andric // single-bit values, so the right behavior just falls out.
614*b5893f02SDimitry Andric #define HANDLE_DISP_FLAG(ID, NAME) \
615*b5893f02SDimitry Andric if (DISPFlags Bit = Flags & SPFlag##NAME) { \
616*b5893f02SDimitry Andric SplitFlags.push_back(Bit); \
617*b5893f02SDimitry Andric Flags &= ~Bit; \
618*b5893f02SDimitry Andric }
619*b5893f02SDimitry Andric #include "llvm/IR/DebugInfoFlags.def"
620*b5893f02SDimitry Andric return Flags;
621*b5893f02SDimitry Andric }
622*b5893f02SDimitry Andric
getImpl(LLVMContext & Context,Metadata * Scope,MDString * Name,MDString * LinkageName,Metadata * File,unsigned Line,Metadata * Type,unsigned ScopeLine,Metadata * ContainingType,unsigned VirtualIndex,int ThisAdjustment,DIFlags Flags,DISPFlags SPFlags,Metadata * Unit,Metadata * TemplateParams,Metadata * Declaration,Metadata * RetainedNodes,Metadata * ThrownTypes,StorageType Storage,bool ShouldCreate)623ff0cc061SDimitry Andric DISubprogram *DISubprogram::getImpl(
624ff0cc061SDimitry Andric LLVMContext &Context, Metadata *Scope, MDString *Name,
625ff0cc061SDimitry Andric MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type,
626*b5893f02SDimitry Andric unsigned ScopeLine, Metadata *ContainingType, unsigned VirtualIndex,
627*b5893f02SDimitry Andric int ThisAdjustment, DIFlags Flags, DISPFlags SPFlags, Metadata *Unit,
6284ba319b5SDimitry Andric Metadata *TemplateParams, Metadata *Declaration, Metadata *RetainedNodes,
629f37b6182SDimitry Andric Metadata *ThrownTypes, StorageType Storage, bool ShouldCreate) {
630ff0cc061SDimitry Andric assert(isCanonical(Name) && "Expected canonical MDString");
631ff0cc061SDimitry Andric assert(isCanonical(LinkageName) && "Expected canonical MDString");
632*b5893f02SDimitry Andric DEFINE_GETIMPL_LOOKUP(DISubprogram,
633*b5893f02SDimitry Andric (Scope, Name, LinkageName, File, Line, Type, ScopeLine,
634*b5893f02SDimitry Andric ContainingType, VirtualIndex, ThisAdjustment, Flags,
635*b5893f02SDimitry Andric SPFlags, Unit, TemplateParams, Declaration,
636*b5893f02SDimitry Andric RetainedNodes, ThrownTypes));
637f37b6182SDimitry Andric SmallVector<Metadata *, 11> Ops = {
638f37b6182SDimitry Andric File, Scope, Name, LinkageName, Type, Unit,
6394ba319b5SDimitry Andric Declaration, RetainedNodes, ContainingType, TemplateParams, ThrownTypes};
640f37b6182SDimitry Andric if (!ThrownTypes) {
641f37b6182SDimitry Andric Ops.pop_back();
642f37b6182SDimitry Andric if (!TemplateParams) {
643f37b6182SDimitry Andric Ops.pop_back();
644f37b6182SDimitry Andric if (!ContainingType)
645f37b6182SDimitry Andric Ops.pop_back();
646f37b6182SDimitry Andric }
647f37b6182SDimitry Andric }
648*b5893f02SDimitry Andric DEFINE_GETIMPL_STORE_N(
649*b5893f02SDimitry Andric DISubprogram,
650*b5893f02SDimitry Andric (Line, ScopeLine, VirtualIndex, ThisAdjustment, Flags, SPFlags), Ops,
651*b5893f02SDimitry Andric Ops.size());
652ff0cc061SDimitry Andric }
653ff0cc061SDimitry Andric
describes(const Function * F) const654ff0cc061SDimitry Andric bool DISubprogram::describes(const Function *F) const {
655ff0cc061SDimitry Andric assert(F && "Invalid function");
6567d523365SDimitry Andric if (F->getSubprogram() == this)
657ff0cc061SDimitry Andric return true;
658ff0cc061SDimitry Andric StringRef Name = getLinkageName();
659ff0cc061SDimitry Andric if (Name.empty())
660ff0cc061SDimitry Andric Name = getName();
661ff0cc061SDimitry Andric return F->getName() == Name;
662ff0cc061SDimitry Andric }
663ff0cc061SDimitry Andric
getImpl(LLVMContext & Context,Metadata * Scope,Metadata * File,unsigned Line,unsigned Column,StorageType Storage,bool ShouldCreate)664ff0cc061SDimitry Andric DILexicalBlock *DILexicalBlock::getImpl(LLVMContext &Context, Metadata *Scope,
665ff0cc061SDimitry Andric Metadata *File, unsigned Line,
666ff0cc061SDimitry Andric unsigned Column, StorageType Storage,
667ff0cc061SDimitry Andric bool ShouldCreate) {
6687d523365SDimitry Andric // Fixup column.
6697d523365SDimitry Andric adjustColumn(Column);
6707d523365SDimitry Andric
671ff0cc061SDimitry Andric assert(Scope && "Expected scope");
672ff0cc061SDimitry Andric DEFINE_GETIMPL_LOOKUP(DILexicalBlock, (Scope, File, Line, Column));
673ff0cc061SDimitry Andric Metadata *Ops[] = {File, Scope};
674ff0cc061SDimitry Andric DEFINE_GETIMPL_STORE(DILexicalBlock, (Line, Column), Ops);
675ff0cc061SDimitry Andric }
676ff0cc061SDimitry Andric
getImpl(LLVMContext & Context,Metadata * Scope,Metadata * File,unsigned Discriminator,StorageType Storage,bool ShouldCreate)677ff0cc061SDimitry Andric DILexicalBlockFile *DILexicalBlockFile::getImpl(LLVMContext &Context,
678ff0cc061SDimitry Andric Metadata *Scope, Metadata *File,
679ff0cc061SDimitry Andric unsigned Discriminator,
680ff0cc061SDimitry Andric StorageType Storage,
681ff0cc061SDimitry Andric bool ShouldCreate) {
682ff0cc061SDimitry Andric assert(Scope && "Expected scope");
683ff0cc061SDimitry Andric DEFINE_GETIMPL_LOOKUP(DILexicalBlockFile, (Scope, File, Discriminator));
684ff0cc061SDimitry Andric Metadata *Ops[] = {File, Scope};
685ff0cc061SDimitry Andric DEFINE_GETIMPL_STORE(DILexicalBlockFile, (Discriminator), Ops);
686ff0cc061SDimitry Andric }
687ff0cc061SDimitry Andric
getImpl(LLVMContext & Context,Metadata * Scope,MDString * Name,bool ExportSymbols,StorageType Storage,bool ShouldCreate)688ff0cc061SDimitry Andric DINamespace *DINamespace::getImpl(LLVMContext &Context, Metadata *Scope,
689f37b6182SDimitry Andric MDString *Name, bool ExportSymbols,
690f37b6182SDimitry Andric StorageType Storage, bool ShouldCreate) {
691ff0cc061SDimitry Andric assert(isCanonical(Name) && "Expected canonical MDString");
692f37b6182SDimitry Andric DEFINE_GETIMPL_LOOKUP(DINamespace, (Scope, Name, ExportSymbols));
693f37b6182SDimitry Andric // The nullptr is for DIScope's File operand. This should be refactored.
694f37b6182SDimitry Andric Metadata *Ops[] = {nullptr, Scope, Name};
695f37b6182SDimitry Andric DEFINE_GETIMPL_STORE(DINamespace, (ExportSymbols), Ops);
696ff0cc061SDimitry Andric }
697ff0cc061SDimitry Andric
getImpl(LLVMContext & Context,Metadata * Scope,MDString * Name,MDString * ConfigurationMacros,MDString * IncludePath,MDString * ISysRoot,StorageType Storage,bool ShouldCreate)6983dac3a9bSDimitry Andric DIModule *DIModule::getImpl(LLVMContext &Context, Metadata *Scope,
6993dac3a9bSDimitry Andric MDString *Name, MDString *ConfigurationMacros,
7003dac3a9bSDimitry Andric MDString *IncludePath, MDString *ISysRoot,
7013dac3a9bSDimitry Andric StorageType Storage, bool ShouldCreate) {
7023dac3a9bSDimitry Andric assert(isCanonical(Name) && "Expected canonical MDString");
7033ca95b02SDimitry Andric DEFINE_GETIMPL_LOOKUP(
7043ca95b02SDimitry Andric DIModule, (Scope, Name, ConfigurationMacros, IncludePath, ISysRoot));
7053dac3a9bSDimitry Andric Metadata *Ops[] = {Scope, Name, ConfigurationMacros, IncludePath, ISysRoot};
7063dac3a9bSDimitry Andric DEFINE_GETIMPL_STORE_NO_CONSTRUCTOR_ARGS(DIModule, Ops);
7073dac3a9bSDimitry Andric }
7083dac3a9bSDimitry Andric
getImpl(LLVMContext & Context,MDString * Name,Metadata * Type,StorageType Storage,bool ShouldCreate)709ff0cc061SDimitry Andric DITemplateTypeParameter *DITemplateTypeParameter::getImpl(LLVMContext &Context,
710ff0cc061SDimitry Andric MDString *Name,
711ff0cc061SDimitry Andric Metadata *Type,
712ff0cc061SDimitry Andric StorageType Storage,
713ff0cc061SDimitry Andric bool ShouldCreate) {
714ff0cc061SDimitry Andric assert(isCanonical(Name) && "Expected canonical MDString");
7153ca95b02SDimitry Andric DEFINE_GETIMPL_LOOKUP(DITemplateTypeParameter, (Name, Type));
716ff0cc061SDimitry Andric Metadata *Ops[] = {Name, Type};
717ff0cc061SDimitry Andric DEFINE_GETIMPL_STORE_NO_CONSTRUCTOR_ARGS(DITemplateTypeParameter, Ops);
718ff0cc061SDimitry Andric }
719ff0cc061SDimitry Andric
getImpl(LLVMContext & Context,unsigned Tag,MDString * Name,Metadata * Type,Metadata * Value,StorageType Storage,bool ShouldCreate)720ff0cc061SDimitry Andric DITemplateValueParameter *DITemplateValueParameter::getImpl(
721ff0cc061SDimitry Andric LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *Type,
722ff0cc061SDimitry Andric Metadata *Value, StorageType Storage, bool ShouldCreate) {
723ff0cc061SDimitry Andric assert(isCanonical(Name) && "Expected canonical MDString");
7243ca95b02SDimitry Andric DEFINE_GETIMPL_LOOKUP(DITemplateValueParameter, (Tag, Name, Type, Value));
725ff0cc061SDimitry Andric Metadata *Ops[] = {Name, Type, Value};
726ff0cc061SDimitry Andric DEFINE_GETIMPL_STORE(DITemplateValueParameter, (Tag), Ops);
727ff0cc061SDimitry Andric }
728ff0cc061SDimitry Andric
729ff0cc061SDimitry Andric DIGlobalVariable *
getImpl(LLVMContext & Context,Metadata * Scope,MDString * Name,MDString * LinkageName,Metadata * File,unsigned Line,Metadata * Type,bool IsLocalToUnit,bool IsDefinition,Metadata * StaticDataMemberDeclaration,Metadata * TemplateParams,uint32_t AlignInBits,StorageType Storage,bool ShouldCreate)730ff0cc061SDimitry Andric DIGlobalVariable::getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
731ff0cc061SDimitry Andric MDString *LinkageName, Metadata *File, unsigned Line,
732ff0cc061SDimitry Andric Metadata *Type, bool IsLocalToUnit, bool IsDefinition,
733ff0cc061SDimitry Andric Metadata *StaticDataMemberDeclaration,
734*b5893f02SDimitry Andric Metadata *TemplateParams, uint32_t AlignInBits,
735*b5893f02SDimitry Andric StorageType Storage, bool ShouldCreate) {
736ff0cc061SDimitry Andric assert(isCanonical(Name) && "Expected canonical MDString");
737ff0cc061SDimitry Andric assert(isCanonical(LinkageName) && "Expected canonical MDString");
738*b5893f02SDimitry Andric DEFINE_GETIMPL_LOOKUP(DIGlobalVariable, (Scope, Name, LinkageName, File, Line,
739*b5893f02SDimitry Andric Type, IsLocalToUnit, IsDefinition,
740*b5893f02SDimitry Andric StaticDataMemberDeclaration,
741*b5893f02SDimitry Andric TemplateParams, AlignInBits));
742*b5893f02SDimitry Andric Metadata *Ops[] = {Scope,
743*b5893f02SDimitry Andric Name,
744*b5893f02SDimitry Andric File,
745*b5893f02SDimitry Andric Type,
746*b5893f02SDimitry Andric Name,
747*b5893f02SDimitry Andric LinkageName,
748*b5893f02SDimitry Andric StaticDataMemberDeclaration,
749*b5893f02SDimitry Andric TemplateParams};
750d88c1a5aSDimitry Andric DEFINE_GETIMPL_STORE(DIGlobalVariable,
751*b5893f02SDimitry Andric (Line, IsLocalToUnit, IsDefinition, AlignInBits), Ops);
752ff0cc061SDimitry Andric }
753ff0cc061SDimitry Andric
getImpl(LLVMContext & Context,Metadata * Scope,MDString * Name,Metadata * File,unsigned Line,Metadata * Type,unsigned Arg,DIFlags Flags,uint32_t AlignInBits,StorageType Storage,bool ShouldCreate)7547d523365SDimitry Andric DILocalVariable *DILocalVariable::getImpl(LLVMContext &Context, Metadata *Scope,
7557d523365SDimitry Andric MDString *Name, Metadata *File,
7567d523365SDimitry Andric unsigned Line, Metadata *Type,
757d88c1a5aSDimitry Andric unsigned Arg, DIFlags Flags,
758d88c1a5aSDimitry Andric uint32_t AlignInBits,
7597d523365SDimitry Andric StorageType Storage,
760ff0cc061SDimitry Andric bool ShouldCreate) {
761ff0cc061SDimitry Andric // 64K ought to be enough for any frontend.
762ff0cc061SDimitry Andric assert(Arg <= UINT16_MAX && "Expected argument number to fit in 16-bits");
763ff0cc061SDimitry Andric
764ff0cc061SDimitry Andric assert(Scope && "Expected scope");
765ff0cc061SDimitry Andric assert(isCanonical(Name) && "Expected canonical MDString");
7667d523365SDimitry Andric DEFINE_GETIMPL_LOOKUP(DILocalVariable,
767d88c1a5aSDimitry Andric (Scope, Name, File, Line, Type, Arg, Flags,
768d88c1a5aSDimitry Andric AlignInBits));
769ff0cc061SDimitry Andric Metadata *Ops[] = {Scope, Name, File, Type};
770d88c1a5aSDimitry Andric DEFINE_GETIMPL_STORE(DILocalVariable, (Line, Arg, Flags, AlignInBits), Ops);
771ff0cc061SDimitry Andric }
772ff0cc061SDimitry Andric
getSizeInBits() const7732cab237bSDimitry Andric Optional<uint64_t> DIVariable::getSizeInBits() const {
7742cab237bSDimitry Andric // This is used by the Verifier so be mindful of broken types.
7752cab237bSDimitry Andric const Metadata *RawType = getRawType();
7762cab237bSDimitry Andric while (RawType) {
7772cab237bSDimitry Andric // Try to get the size directly.
7782cab237bSDimitry Andric if (auto *T = dyn_cast<DIType>(RawType))
7792cab237bSDimitry Andric if (uint64_t Size = T->getSizeInBits())
7802cab237bSDimitry Andric return Size;
7812cab237bSDimitry Andric
7822cab237bSDimitry Andric if (auto *DT = dyn_cast<DIDerivedType>(RawType)) {
7832cab237bSDimitry Andric // Look at the base type.
7842cab237bSDimitry Andric RawType = DT->getRawBaseType();
7852cab237bSDimitry Andric continue;
7862cab237bSDimitry Andric }
7872cab237bSDimitry Andric
7882cab237bSDimitry Andric // Missing type or size.
7892cab237bSDimitry Andric break;
7902cab237bSDimitry Andric }
7912cab237bSDimitry Andric
7922cab237bSDimitry Andric // Fail gracefully.
7932cab237bSDimitry Andric return None;
7942cab237bSDimitry Andric }
7952cab237bSDimitry Andric
getImpl(LLVMContext & Context,Metadata * Scope,MDString * Name,Metadata * File,unsigned Line,StorageType Storage,bool ShouldCreate)7964ba319b5SDimitry Andric DILabel *DILabel::getImpl(LLVMContext &Context, Metadata *Scope,
7974ba319b5SDimitry Andric MDString *Name, Metadata *File, unsigned Line,
7984ba319b5SDimitry Andric StorageType Storage,
7994ba319b5SDimitry Andric bool ShouldCreate) {
8004ba319b5SDimitry Andric assert(Scope && "Expected scope");
8014ba319b5SDimitry Andric assert(isCanonical(Name) && "Expected canonical MDString");
8024ba319b5SDimitry Andric DEFINE_GETIMPL_LOOKUP(DILabel,
8034ba319b5SDimitry Andric (Scope, Name, File, Line));
8044ba319b5SDimitry Andric Metadata *Ops[] = {Scope, Name, File};
8054ba319b5SDimitry Andric DEFINE_GETIMPL_STORE(DILabel, (Line), Ops);
8064ba319b5SDimitry Andric }
8074ba319b5SDimitry Andric
getImpl(LLVMContext & Context,ArrayRef<uint64_t> Elements,StorageType Storage,bool ShouldCreate)808ff0cc061SDimitry Andric DIExpression *DIExpression::getImpl(LLVMContext &Context,
809ff0cc061SDimitry Andric ArrayRef<uint64_t> Elements,
810ff0cc061SDimitry Andric StorageType Storage, bool ShouldCreate) {
811ff0cc061SDimitry Andric DEFINE_GETIMPL_LOOKUP(DIExpression, (Elements));
812ff0cc061SDimitry Andric DEFINE_GETIMPL_STORE_NO_OPS(DIExpression, (Elements));
813ff0cc061SDimitry Andric }
814ff0cc061SDimitry Andric
getSize() const815ff0cc061SDimitry Andric unsigned DIExpression::ExprOperand::getSize() const {
816ff0cc061SDimitry Andric switch (getOp()) {
817d88c1a5aSDimitry Andric case dwarf::DW_OP_LLVM_fragment:
818ff0cc061SDimitry Andric return 3;
819d88c1a5aSDimitry Andric case dwarf::DW_OP_constu:
82024d58133SDimitry Andric case dwarf::DW_OP_plus_uconst:
821ff0cc061SDimitry Andric return 2;
822ff0cc061SDimitry Andric default:
823ff0cc061SDimitry Andric return 1;
824ff0cc061SDimitry Andric }
825ff0cc061SDimitry Andric }
826ff0cc061SDimitry Andric
isValid() const827ff0cc061SDimitry Andric bool DIExpression::isValid() const {
828ff0cc061SDimitry Andric for (auto I = expr_op_begin(), E = expr_op_end(); I != E; ++I) {
829ff0cc061SDimitry Andric // Check that there's space for the operand.
830ff0cc061SDimitry Andric if (I->get() + I->getSize() > E->get())
831ff0cc061SDimitry Andric return false;
832ff0cc061SDimitry Andric
833ff0cc061SDimitry Andric // Check that the operand is valid.
834ff0cc061SDimitry Andric switch (I->getOp()) {
835ff0cc061SDimitry Andric default:
836ff0cc061SDimitry Andric return false;
837d88c1a5aSDimitry Andric case dwarf::DW_OP_LLVM_fragment:
838d88c1a5aSDimitry Andric // A fragment operator must appear at the end.
839ff0cc061SDimitry Andric return I->get() + I->getSize() == E->get();
840d88c1a5aSDimitry Andric case dwarf::DW_OP_stack_value: {
841d88c1a5aSDimitry Andric // Must be the last one or followed by a DW_OP_LLVM_fragment.
842d88c1a5aSDimitry Andric if (I->get() + I->getSize() == E->get())
843d88c1a5aSDimitry Andric break;
844d88c1a5aSDimitry Andric auto J = I;
845d88c1a5aSDimitry Andric if ((++J)->getOp() != dwarf::DW_OP_LLVM_fragment)
846d88c1a5aSDimitry Andric return false;
847d88c1a5aSDimitry Andric break;
848d88c1a5aSDimitry Andric }
8497a7e6055SDimitry Andric case dwarf::DW_OP_swap: {
8507a7e6055SDimitry Andric // Must be more than one implicit element on the stack.
8517a7e6055SDimitry Andric
8527a7e6055SDimitry Andric // FIXME: A better way to implement this would be to add a local variable
8537a7e6055SDimitry Andric // that keeps track of the stack depth and introduce something like a
8547a7e6055SDimitry Andric // DW_LLVM_OP_implicit_location as a placeholder for the location this
8557a7e6055SDimitry Andric // DIExpression is attached to, or else pass the number of implicit stack
8567a7e6055SDimitry Andric // elements into isValid.
8577a7e6055SDimitry Andric if (getNumElements() == 1)
8587a7e6055SDimitry Andric return false;
8597a7e6055SDimitry Andric break;
8607a7e6055SDimitry Andric }
861d88c1a5aSDimitry Andric case dwarf::DW_OP_constu:
86224d58133SDimitry Andric case dwarf::DW_OP_plus_uconst:
863ff0cc061SDimitry Andric case dwarf::DW_OP_plus:
8647d523365SDimitry Andric case dwarf::DW_OP_minus:
8652cab237bSDimitry Andric case dwarf::DW_OP_mul:
8664ba319b5SDimitry Andric case dwarf::DW_OP_div:
8674ba319b5SDimitry Andric case dwarf::DW_OP_mod:
8684ba319b5SDimitry Andric case dwarf::DW_OP_or:
8694ba319b5SDimitry Andric case dwarf::DW_OP_and:
8704ba319b5SDimitry Andric case dwarf::DW_OP_xor:
8714ba319b5SDimitry Andric case dwarf::DW_OP_shl:
8724ba319b5SDimitry Andric case dwarf::DW_OP_shr:
8734ba319b5SDimitry Andric case dwarf::DW_OP_shra:
874ff0cc061SDimitry Andric case dwarf::DW_OP_deref:
8757a7e6055SDimitry Andric case dwarf::DW_OP_xderef:
8764ba319b5SDimitry Andric case dwarf::DW_OP_lit0:
8774ba319b5SDimitry Andric case dwarf::DW_OP_not:
8784ba319b5SDimitry Andric case dwarf::DW_OP_dup:
879ff0cc061SDimitry Andric break;
880ff0cc061SDimitry Andric }
881ff0cc061SDimitry Andric }
882ff0cc061SDimitry Andric return true;
883ff0cc061SDimitry Andric }
884ff0cc061SDimitry Andric
885d88c1a5aSDimitry Andric Optional<DIExpression::FragmentInfo>
getFragmentInfo(expr_op_iterator Start,expr_op_iterator End)886d88c1a5aSDimitry Andric DIExpression::getFragmentInfo(expr_op_iterator Start, expr_op_iterator End) {
887d88c1a5aSDimitry Andric for (auto I = Start; I != End; ++I)
888d88c1a5aSDimitry Andric if (I->getOp() == dwarf::DW_OP_LLVM_fragment) {
889d88c1a5aSDimitry Andric DIExpression::FragmentInfo Info = {I->getArg(1), I->getArg(0)};
890d88c1a5aSDimitry Andric return Info;
891d88c1a5aSDimitry Andric }
892d88c1a5aSDimitry Andric return None;
893d88c1a5aSDimitry Andric }
894d88c1a5aSDimitry Andric
appendOffset(SmallVectorImpl<uint64_t> & Ops,int64_t Offset)895f37b6182SDimitry Andric void DIExpression::appendOffset(SmallVectorImpl<uint64_t> &Ops,
896f37b6182SDimitry Andric int64_t Offset) {
897f37b6182SDimitry Andric if (Offset > 0) {
89824d58133SDimitry Andric Ops.push_back(dwarf::DW_OP_plus_uconst);
899f37b6182SDimitry Andric Ops.push_back(Offset);
900f37b6182SDimitry Andric } else if (Offset < 0) {
90124d58133SDimitry Andric Ops.push_back(dwarf::DW_OP_constu);
902f37b6182SDimitry Andric Ops.push_back(-Offset);
90324d58133SDimitry Andric Ops.push_back(dwarf::DW_OP_minus);
904f37b6182SDimitry Andric }
905f37b6182SDimitry Andric }
906f37b6182SDimitry Andric
extractIfOffset(int64_t & Offset) const9075517e702SDimitry Andric bool DIExpression::extractIfOffset(int64_t &Offset) const {
9085517e702SDimitry Andric if (getNumElements() == 0) {
9095517e702SDimitry Andric Offset = 0;
9105517e702SDimitry Andric return true;
9115517e702SDimitry Andric }
91224d58133SDimitry Andric
91324d58133SDimitry Andric if (getNumElements() == 2 && Elements[0] == dwarf::DW_OP_plus_uconst) {
9145517e702SDimitry Andric Offset = Elements[1];
9155517e702SDimitry Andric return true;
9165517e702SDimitry Andric }
91724d58133SDimitry Andric
91824d58133SDimitry Andric if (getNumElements() == 3 && Elements[0] == dwarf::DW_OP_constu) {
91924d58133SDimitry Andric if (Elements[2] == dwarf::DW_OP_plus) {
92024d58133SDimitry Andric Offset = Elements[1];
92124d58133SDimitry Andric return true;
92224d58133SDimitry Andric }
92324d58133SDimitry Andric if (Elements[2] == dwarf::DW_OP_minus) {
9245517e702SDimitry Andric Offset = -Elements[1];
9255517e702SDimitry Andric return true;
9265517e702SDimitry Andric }
92724d58133SDimitry Andric }
92824d58133SDimitry Andric
9295517e702SDimitry Andric return false;
9305517e702SDimitry Andric }
9315517e702SDimitry Andric
prepend(const DIExpression * Expr,bool DerefBefore,int64_t Offset,bool DerefAfter,bool StackValue)9322cab237bSDimitry Andric DIExpression *DIExpression::prepend(const DIExpression *Expr, bool DerefBefore,
9332cab237bSDimitry Andric int64_t Offset, bool DerefAfter,
9342cab237bSDimitry Andric bool StackValue) {
935f37b6182SDimitry Andric SmallVector<uint64_t, 8> Ops;
9362cab237bSDimitry Andric if (DerefBefore)
937f37b6182SDimitry Andric Ops.push_back(dwarf::DW_OP_deref);
9382cab237bSDimitry Andric
9392cab237bSDimitry Andric appendOffset(Ops, Offset);
9402cab237bSDimitry Andric if (DerefAfter)
9412cab237bSDimitry Andric Ops.push_back(dwarf::DW_OP_deref);
9422cab237bSDimitry Andric
9434ba319b5SDimitry Andric return prependOpcodes(Expr, Ops, StackValue);
9444ba319b5SDimitry Andric }
9454ba319b5SDimitry Andric
prependOpcodes(const DIExpression * Expr,SmallVectorImpl<uint64_t> & Ops,bool StackValue)9464ba319b5SDimitry Andric DIExpression *DIExpression::prependOpcodes(const DIExpression *Expr,
9474ba319b5SDimitry Andric SmallVectorImpl<uint64_t> &Ops,
9484ba319b5SDimitry Andric bool StackValue) {
9494ba319b5SDimitry Andric assert(Expr && "Can't prepend ops to this expression");
9504ba319b5SDimitry Andric
9514ba319b5SDimitry Andric // If there are no ops to prepend, do not even add the DW_OP_stack_value.
9524ba319b5SDimitry Andric if (Ops.empty())
9534ba319b5SDimitry Andric StackValue = false;
954f37b6182SDimitry Andric for (auto Op : Expr->expr_ops()) {
955f37b6182SDimitry Andric // A DW_OP_stack_value comes at the end, but before a DW_OP_LLVM_fragment.
956f37b6182SDimitry Andric if (StackValue) {
957f37b6182SDimitry Andric if (Op.getOp() == dwarf::DW_OP_stack_value)
958f37b6182SDimitry Andric StackValue = false;
959f37b6182SDimitry Andric else if (Op.getOp() == dwarf::DW_OP_LLVM_fragment) {
960f37b6182SDimitry Andric Ops.push_back(dwarf::DW_OP_stack_value);
961f37b6182SDimitry Andric StackValue = false;
962f37b6182SDimitry Andric }
963f37b6182SDimitry Andric }
9644ba319b5SDimitry Andric Op.appendToVector(Ops);
965f37b6182SDimitry Andric }
966f37b6182SDimitry Andric if (StackValue)
967f37b6182SDimitry Andric Ops.push_back(dwarf::DW_OP_stack_value);
968f37b6182SDimitry Andric return DIExpression::get(Expr->getContext(), Ops);
969f37b6182SDimitry Andric }
970f37b6182SDimitry Andric
append(const DIExpression * Expr,ArrayRef<uint64_t> Ops)9714ba319b5SDimitry Andric DIExpression *DIExpression::append(const DIExpression *Expr,
9724ba319b5SDimitry Andric ArrayRef<uint64_t> Ops) {
9734ba319b5SDimitry Andric assert(Expr && !Ops.empty() && "Can't append ops to this expression");
9744ba319b5SDimitry Andric
9754ba319b5SDimitry Andric // Copy Expr's current op list.
9764ba319b5SDimitry Andric SmallVector<uint64_t, 16> NewOps;
9774ba319b5SDimitry Andric for (auto Op : Expr->expr_ops()) {
9784ba319b5SDimitry Andric // Append new opcodes before DW_OP_{stack_value, LLVM_fragment}.
9794ba319b5SDimitry Andric if (Op.getOp() == dwarf::DW_OP_stack_value ||
9804ba319b5SDimitry Andric Op.getOp() == dwarf::DW_OP_LLVM_fragment) {
9814ba319b5SDimitry Andric NewOps.append(Ops.begin(), Ops.end());
9824ba319b5SDimitry Andric
9834ba319b5SDimitry Andric // Ensure that the new opcodes are only appended once.
9844ba319b5SDimitry Andric Ops = None;
9854ba319b5SDimitry Andric }
9864ba319b5SDimitry Andric Op.appendToVector(NewOps);
9874ba319b5SDimitry Andric }
9884ba319b5SDimitry Andric
9894ba319b5SDimitry Andric NewOps.append(Ops.begin(), Ops.end());
9904ba319b5SDimitry Andric return DIExpression::get(Expr->getContext(), NewOps);
9914ba319b5SDimitry Andric }
9924ba319b5SDimitry Andric
appendToStack(const DIExpression * Expr,ArrayRef<uint64_t> Ops)9934ba319b5SDimitry Andric DIExpression *DIExpression::appendToStack(const DIExpression *Expr,
9944ba319b5SDimitry Andric ArrayRef<uint64_t> Ops) {
9954ba319b5SDimitry Andric assert(Expr && !Ops.empty() && "Can't append ops to this expression");
9964ba319b5SDimitry Andric assert(none_of(Ops,
9974ba319b5SDimitry Andric [](uint64_t Op) {
9984ba319b5SDimitry Andric return Op == dwarf::DW_OP_stack_value ||
9994ba319b5SDimitry Andric Op == dwarf::DW_OP_LLVM_fragment;
10004ba319b5SDimitry Andric }) &&
10014ba319b5SDimitry Andric "Can't append this op");
10024ba319b5SDimitry Andric
10034ba319b5SDimitry Andric // Append a DW_OP_deref after Expr's current op list if it's non-empty and
10044ba319b5SDimitry Andric // has no DW_OP_stack_value.
10054ba319b5SDimitry Andric //
10064ba319b5SDimitry Andric // Match .* DW_OP_stack_value (DW_OP_LLVM_fragment A B)?.
10074ba319b5SDimitry Andric Optional<FragmentInfo> FI = Expr->getFragmentInfo();
10084ba319b5SDimitry Andric unsigned DropUntilStackValue = FI.hasValue() ? 3 : 0;
10094ba319b5SDimitry Andric ArrayRef<uint64_t> ExprOpsBeforeFragment =
10104ba319b5SDimitry Andric Expr->getElements().drop_back(DropUntilStackValue);
10114ba319b5SDimitry Andric bool NeedsDeref = (Expr->getNumElements() > DropUntilStackValue) &&
10124ba319b5SDimitry Andric (ExprOpsBeforeFragment.back() != dwarf::DW_OP_stack_value);
10134ba319b5SDimitry Andric bool NeedsStackValue = NeedsDeref || ExprOpsBeforeFragment.empty();
10144ba319b5SDimitry Andric
10154ba319b5SDimitry Andric // Append a DW_OP_deref after Expr's current op list if needed, then append
10164ba319b5SDimitry Andric // the new ops, and finally ensure that a single DW_OP_stack_value is present.
10174ba319b5SDimitry Andric SmallVector<uint64_t, 16> NewOps;
10184ba319b5SDimitry Andric if (NeedsDeref)
10194ba319b5SDimitry Andric NewOps.push_back(dwarf::DW_OP_deref);
10204ba319b5SDimitry Andric NewOps.append(Ops.begin(), Ops.end());
10214ba319b5SDimitry Andric if (NeedsStackValue)
10224ba319b5SDimitry Andric NewOps.push_back(dwarf::DW_OP_stack_value);
10234ba319b5SDimitry Andric return DIExpression::append(Expr, NewOps);
10244ba319b5SDimitry Andric }
10254ba319b5SDimitry Andric
createFragmentExpression(const DIExpression * Expr,unsigned OffsetInBits,unsigned SizeInBits)10262cab237bSDimitry Andric Optional<DIExpression *> DIExpression::createFragmentExpression(
10272cab237bSDimitry Andric const DIExpression *Expr, unsigned OffsetInBits, unsigned SizeInBits) {
10282cab237bSDimitry Andric SmallVector<uint64_t, 8> Ops;
10292cab237bSDimitry Andric // Copy over the expression, but leave off any trailing DW_OP_LLVM_fragment.
10302cab237bSDimitry Andric if (Expr) {
10312cab237bSDimitry Andric for (auto Op : Expr->expr_ops()) {
10322cab237bSDimitry Andric switch (Op.getOp()) {
10332cab237bSDimitry Andric default: break;
10342cab237bSDimitry Andric case dwarf::DW_OP_plus:
10352cab237bSDimitry Andric case dwarf::DW_OP_minus:
10362cab237bSDimitry Andric // We can't safely split arithmetic into multiple fragments because we
10372cab237bSDimitry Andric // can't express carry-over between fragments.
10382cab237bSDimitry Andric //
10392cab237bSDimitry Andric // FIXME: We *could* preserve the lowest fragment of a constant offset
10402cab237bSDimitry Andric // operation if the offset fits into SizeInBits.
10412cab237bSDimitry Andric return None;
10422cab237bSDimitry Andric case dwarf::DW_OP_LLVM_fragment: {
10432cab237bSDimitry Andric // Make the new offset point into the existing fragment.
10442cab237bSDimitry Andric uint64_t FragmentOffsetInBits = Op.getArg(0);
10454ba319b5SDimitry Andric uint64_t FragmentSizeInBits = Op.getArg(1);
10464ba319b5SDimitry Andric (void)FragmentSizeInBits;
10474ba319b5SDimitry Andric assert((OffsetInBits + SizeInBits <= FragmentSizeInBits) &&
10482cab237bSDimitry Andric "new fragment outside of original fragment");
10492cab237bSDimitry Andric OffsetInBits += FragmentOffsetInBits;
10502cab237bSDimitry Andric continue;
10512cab237bSDimitry Andric }
10522cab237bSDimitry Andric }
10534ba319b5SDimitry Andric Op.appendToVector(Ops);
10542cab237bSDimitry Andric }
10552cab237bSDimitry Andric }
10562cab237bSDimitry Andric Ops.push_back(dwarf::DW_OP_LLVM_fragment);
10572cab237bSDimitry Andric Ops.push_back(OffsetInBits);
10582cab237bSDimitry Andric Ops.push_back(SizeInBits);
10592cab237bSDimitry Andric return DIExpression::get(Expr->getContext(), Ops);
10602cab237bSDimitry Andric }
10612cab237bSDimitry Andric
isConstant() const1062d88c1a5aSDimitry Andric bool DIExpression::isConstant() const {
1063d88c1a5aSDimitry Andric // Recognize DW_OP_constu C DW_OP_stack_value (DW_OP_LLVM_fragment Len Ofs)?.
1064d88c1a5aSDimitry Andric if (getNumElements() != 3 && getNumElements() != 6)
1065ff0cc061SDimitry Andric return false;
1066d88c1a5aSDimitry Andric if (getElement(0) != dwarf::DW_OP_constu ||
1067d88c1a5aSDimitry Andric getElement(2) != dwarf::DW_OP_stack_value)
1068d88c1a5aSDimitry Andric return false;
1069d88c1a5aSDimitry Andric if (getNumElements() == 6 && getElement(3) != dwarf::DW_OP_LLVM_fragment)
1070d88c1a5aSDimitry Andric return false;
1071d88c1a5aSDimitry Andric return true;
1072ff0cc061SDimitry Andric }
1073ff0cc061SDimitry Andric
1074d88c1a5aSDimitry Andric DIGlobalVariableExpression *
getImpl(LLVMContext & Context,Metadata * Variable,Metadata * Expression,StorageType Storage,bool ShouldCreate)1075d88c1a5aSDimitry Andric DIGlobalVariableExpression::getImpl(LLVMContext &Context, Metadata *Variable,
1076d88c1a5aSDimitry Andric Metadata *Expression, StorageType Storage,
1077d88c1a5aSDimitry Andric bool ShouldCreate) {
1078d88c1a5aSDimitry Andric DEFINE_GETIMPL_LOOKUP(DIGlobalVariableExpression, (Variable, Expression));
1079d88c1a5aSDimitry Andric Metadata *Ops[] = {Variable, Expression};
1080d88c1a5aSDimitry Andric DEFINE_GETIMPL_STORE_NO_CONSTRUCTOR_ARGS(DIGlobalVariableExpression, Ops);
1081ff0cc061SDimitry Andric }
1082ff0cc061SDimitry Andric
getImpl(LLVMContext & Context,MDString * Name,Metadata * File,unsigned Line,MDString * GetterName,MDString * SetterName,unsigned Attributes,Metadata * Type,StorageType Storage,bool ShouldCreate)1083ff0cc061SDimitry Andric DIObjCProperty *DIObjCProperty::getImpl(
1084ff0cc061SDimitry Andric LLVMContext &Context, MDString *Name, Metadata *File, unsigned Line,
1085ff0cc061SDimitry Andric MDString *GetterName, MDString *SetterName, unsigned Attributes,
1086ff0cc061SDimitry Andric Metadata *Type, StorageType Storage, bool ShouldCreate) {
1087ff0cc061SDimitry Andric assert(isCanonical(Name) && "Expected canonical MDString");
1088ff0cc061SDimitry Andric assert(isCanonical(GetterName) && "Expected canonical MDString");
1089ff0cc061SDimitry Andric assert(isCanonical(SetterName) && "Expected canonical MDString");
10903ca95b02SDimitry Andric DEFINE_GETIMPL_LOOKUP(DIObjCProperty, (Name, File, Line, GetterName,
10913ca95b02SDimitry Andric SetterName, Attributes, Type));
1092ff0cc061SDimitry Andric Metadata *Ops[] = {Name, File, GetterName, SetterName, Type};
1093ff0cc061SDimitry Andric DEFINE_GETIMPL_STORE(DIObjCProperty, (Line, Attributes), Ops);
1094ff0cc061SDimitry Andric }
1095ff0cc061SDimitry Andric
getImpl(LLVMContext & Context,unsigned Tag,Metadata * Scope,Metadata * Entity,Metadata * File,unsigned Line,MDString * Name,StorageType Storage,bool ShouldCreate)1096ff0cc061SDimitry Andric DIImportedEntity *DIImportedEntity::getImpl(LLVMContext &Context, unsigned Tag,
1097ff0cc061SDimitry Andric Metadata *Scope, Metadata *Entity,
1098b40b48b8SDimitry Andric Metadata *File, unsigned Line,
1099b40b48b8SDimitry Andric MDString *Name, StorageType Storage,
1100ff0cc061SDimitry Andric bool ShouldCreate) {
1101ff0cc061SDimitry Andric assert(isCanonical(Name) && "Expected canonical MDString");
1102b40b48b8SDimitry Andric DEFINE_GETIMPL_LOOKUP(DIImportedEntity,
1103b40b48b8SDimitry Andric (Tag, Scope, Entity, File, Line, Name));
1104b40b48b8SDimitry Andric Metadata *Ops[] = {Scope, Entity, Name, File};
1105ff0cc061SDimitry Andric DEFINE_GETIMPL_STORE(DIImportedEntity, (Tag, Line), Ops);
1106ff0cc061SDimitry Andric }
11077d523365SDimitry Andric
getImpl(LLVMContext & Context,unsigned MIType,unsigned Line,MDString * Name,MDString * Value,StorageType Storage,bool ShouldCreate)11087d523365SDimitry Andric DIMacro *DIMacro::getImpl(LLVMContext &Context, unsigned MIType,
11097d523365SDimitry Andric unsigned Line, MDString *Name, MDString *Value,
11107d523365SDimitry Andric StorageType Storage, bool ShouldCreate) {
11117d523365SDimitry Andric assert(isCanonical(Name) && "Expected canonical MDString");
11123ca95b02SDimitry Andric DEFINE_GETIMPL_LOOKUP(DIMacro, (MIType, Line, Name, Value));
11137d523365SDimitry Andric Metadata *Ops[] = { Name, Value };
11147d523365SDimitry Andric DEFINE_GETIMPL_STORE(DIMacro, (MIType, Line), Ops);
11157d523365SDimitry Andric }
11167d523365SDimitry Andric
getImpl(LLVMContext & Context,unsigned MIType,unsigned Line,Metadata * File,Metadata * Elements,StorageType Storage,bool ShouldCreate)11177d523365SDimitry Andric DIMacroFile *DIMacroFile::getImpl(LLVMContext &Context, unsigned MIType,
11187d523365SDimitry Andric unsigned Line, Metadata *File,
11197d523365SDimitry Andric Metadata *Elements, StorageType Storage,
11207d523365SDimitry Andric bool ShouldCreate) {
11217d523365SDimitry Andric DEFINE_GETIMPL_LOOKUP(DIMacroFile,
11227d523365SDimitry Andric (MIType, Line, File, Elements));
11237d523365SDimitry Andric Metadata *Ops[] = { File, Elements };
11247d523365SDimitry Andric DEFINE_GETIMPL_STORE(DIMacroFile, (MIType, Line), Ops);
11257d523365SDimitry Andric }
1126