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