1d9901ff5SDuncan P. N. Exon Smith //===- DebugInfoMetadata.cpp - Implement debug info metadata --------------===//
2d9901ff5SDuncan P. N. Exon Smith //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6d9901ff5SDuncan P. N. Exon Smith //
7d9901ff5SDuncan P. N. Exon Smith //===----------------------------------------------------------------------===//
8d9901ff5SDuncan P. N. Exon Smith //
9d9901ff5SDuncan P. N. Exon Smith // This file implements the debug info Metadata classes.
10d9901ff5SDuncan P. N. Exon Smith //
11d9901ff5SDuncan P. N. Exon Smith //===----------------------------------------------------------------------===//
12d9901ff5SDuncan P. N. Exon Smith 
13d9901ff5SDuncan P. N. Exon Smith #include "llvm/IR/DebugInfoMetadata.h"
14d9901ff5SDuncan P. N. Exon Smith #include "LLVMContextImpl.h"
15d9901ff5SDuncan P. N. Exon Smith #include "MetadataImpl.h"
162a813ef2SDavid Blaikie #include "llvm/ADT/SmallSet.h"
175261e4beSDuncan P. N. Exon Smith #include "llvm/ADT/StringSwitch.h"
18ffe8720aSserge-sans-paille #include "llvm/BinaryFormat/Dwarf.h"
19df52349bSDuncan P. N. Exon Smith #include "llvm/IR/Function.h"
20e188aae4Sserge-sans-paille #include "llvm/IR/Type.h"
21e188aae4Sserge-sans-paille #include "llvm/IR/Value.h"
22d9901ff5SDuncan P. N. Exon Smith 
23b53eeb6fSMircea Trofin #include <numeric>
24b53eeb6fSMircea Trofin 
25d9901ff5SDuncan P. N. Exon Smith using namespace llvm;
26d9901ff5SDuncan P. N. Exon Smith 
27886629a8SRong Xu namespace llvm {
28886629a8SRong Xu // Use FS-AFDO discriminator.
29886629a8SRong Xu cl::opt<bool> EnableFSDiscriminator(
30557efc9aSFangrui Song     "enable-fs-discriminator", cl::Hidden,
31886629a8SRong Xu     cl::desc("Enable adding flow sensitive discriminators"));
32886629a8SRong Xu } // namespace llvm
33886629a8SRong Xu 
34269a9afeSstozer const DIExpression::FragmentInfo DebugVariable::DefaultFragment = {
35269a9afeSstozer     std::numeric_limits<uint64_t>::max(), std::numeric_limits<uint64_t>::min()};
36269a9afeSstozer 
DILocation(LLVMContext & C,StorageType Storage,unsigned Line,unsigned Column,ArrayRef<Metadata * > MDs,bool ImplicitCode)37a9308c49SDuncan P. N. Exon Smith DILocation::DILocation(LLVMContext &C, StorageType Storage, unsigned Line,
38eb7f6020SCalixte Denizet                        unsigned Column, ArrayRef<Metadata *> MDs,
39eb7f6020SCalixte Denizet                        bool ImplicitCode)
40a9308c49SDuncan P. N. Exon Smith     : MDNode(C, DILocationKind, Storage, MDs) {
41d9901ff5SDuncan P. N. Exon Smith   assert((MDs.size() == 1 || MDs.size() == 2) &&
42d9901ff5SDuncan P. N. Exon Smith          "Expected a scope and optional inlined-at");
43d9901ff5SDuncan P. N. Exon Smith 
44d9901ff5SDuncan P. N. Exon Smith   // Set line and column.
45d9901ff5SDuncan P. N. Exon Smith   assert(Column < (1u << 16) && "Expected 16-bit column");
46d9901ff5SDuncan P. N. Exon Smith 
47d9901ff5SDuncan P. N. Exon Smith   SubclassData32 = Line;
48d9901ff5SDuncan P. N. Exon Smith   SubclassData16 = Column;
49eb7f6020SCalixte Denizet 
50eb7f6020SCalixte Denizet   setImplicitCode(ImplicitCode);
51d9901ff5SDuncan P. N. Exon Smith }
52d9901ff5SDuncan P. N. Exon Smith 
adjustColumn(unsigned & Column)53d9901ff5SDuncan P. N. Exon Smith static void adjustColumn(unsigned &Column) {
54d9901ff5SDuncan P. N. Exon Smith   // Set to unknown on overflow.  We only have 16 bits to play with here.
55d9901ff5SDuncan P. N. Exon Smith   if (Column >= (1u << 16))
56d9901ff5SDuncan P. N. Exon Smith     Column = 0;
57d9901ff5SDuncan P. N. Exon Smith }
58d9901ff5SDuncan P. N. Exon Smith 
getImpl(LLVMContext & Context,unsigned Line,unsigned Column,Metadata * Scope,Metadata * InlinedAt,bool ImplicitCode,StorageType Storage,bool ShouldCreate)59a9308c49SDuncan P. N. Exon Smith DILocation *DILocation::getImpl(LLVMContext &Context, unsigned Line,
60d9901ff5SDuncan P. N. Exon Smith                                 unsigned Column, Metadata *Scope,
61eb7f6020SCalixte Denizet                                 Metadata *InlinedAt, bool ImplicitCode,
62eb7f6020SCalixte Denizet                                 StorageType Storage, bool ShouldCreate) {
63af677ebbSDuncan P. N. Exon Smith   // Fixup column.
64d9901ff5SDuncan P. N. Exon Smith   adjustColumn(Column);
65d9901ff5SDuncan P. N. Exon Smith 
66d9901ff5SDuncan P. N. Exon Smith   if (Storage == Uniqued) {
67eb7f6020SCalixte Denizet     if (auto *N = getUniqued(Context.pImpl->DILocations,
68eb7f6020SCalixte Denizet                              DILocationInfo::KeyTy(Line, Column, Scope,
69eb7f6020SCalixte Denizet                                                    InlinedAt, ImplicitCode)))
70d9901ff5SDuncan P. N. Exon Smith       return N;
71d9901ff5SDuncan P. N. Exon Smith     if (!ShouldCreate)
72d9901ff5SDuncan P. N. Exon Smith       return nullptr;
73d9901ff5SDuncan P. N. Exon Smith   } else {
74d9901ff5SDuncan P. N. Exon Smith     assert(ShouldCreate && "Expected non-uniqued nodes to always be created");
75d9901ff5SDuncan P. N. Exon Smith   }
76d9901ff5SDuncan P. N. Exon Smith 
77d9901ff5SDuncan P. N. Exon Smith   SmallVector<Metadata *, 2> Ops;
78d9901ff5SDuncan P. N. Exon Smith   Ops.push_back(Scope);
79d9901ff5SDuncan P. N. Exon Smith   if (InlinedAt)
80d9901ff5SDuncan P. N. Exon Smith     Ops.push_back(InlinedAt);
812740c187SWolfgang Pieb   return storeImpl(new (Ops.size(), Storage) DILocation(
822740c187SWolfgang Pieb                        Context, Storage, Line, Column, Ops, ImplicitCode),
83a9308c49SDuncan P. N. Exon Smith                    Storage, Context.pImpl->DILocations);
84d9901ff5SDuncan P. N. Exon Smith }
85d9901ff5SDuncan P. N. Exon Smith 
86665b4138SLuís Ferreira const DILocation *
getMergedLocations(ArrayRef<const DILocation * > Locs)87665b4138SLuís Ferreira DILocation::getMergedLocations(ArrayRef<const DILocation *> Locs) {
885f87415eSDavide Italiano   if (Locs.empty())
895f87415eSDavide Italiano     return nullptr;
905f87415eSDavide Italiano   if (Locs.size() == 1)
915f87415eSDavide Italiano     return Locs[0];
925f87415eSDavide Italiano   auto *Merged = Locs[0];
936a337f85SKazu Hirata   for (const DILocation *L : llvm::drop_begin(Locs)) {
946a337f85SKazu Hirata     Merged = getMergedLocation(Merged, L);
955f87415eSDavide Italiano     if (Merged == nullptr)
965f87415eSDavide Italiano       break;
975f87415eSDavide Italiano   }
985f87415eSDavide Italiano   return Merged;
995f87415eSDavide Italiano }
1005f87415eSDavide Italiano 
getMergedLocation(const DILocation * LocA,const DILocation * LocB)10165b0d4dfSVedant Kumar const DILocation *DILocation::getMergedLocation(const DILocation *LocA,
1022a813ef2SDavid Blaikie                                                 const DILocation *LocB) {
1032b881f56SVedant Kumar   if (!LocA || !LocB)
1042b881f56SVedant Kumar     return nullptr;
1052b881f56SVedant Kumar 
1062a813ef2SDavid Blaikie   if (LocA == LocB)
1072b881f56SVedant Kumar     return LocA;
1082b881f56SVedant Kumar 
1092b881f56SVedant Kumar   SmallPtrSet<DILocation *, 5> InlinedLocationsA;
1102b881f56SVedant Kumar   for (DILocation *L = LocA->getInlinedAt(); L; L = L->getInlinedAt())
1112b881f56SVedant Kumar     InlinedLocationsA.insert(L);
1122a813ef2SDavid Blaikie   SmallSet<std::pair<DIScope *, DILocation *>, 5> Locations;
1132a813ef2SDavid Blaikie   DIScope *S = LocA->getScope();
1142a813ef2SDavid Blaikie   DILocation *L = LocA->getInlinedAt();
1152a813ef2SDavid Blaikie   while (S) {
1162a813ef2SDavid Blaikie     Locations.insert(std::make_pair(S, L));
117da82ce99SFangrui Song     S = S->getScope();
1182a813ef2SDavid Blaikie     if (!S && L) {
1192a813ef2SDavid Blaikie       S = L->getScope();
1202a813ef2SDavid Blaikie       L = L->getInlinedAt();
1212b881f56SVedant Kumar     }
1222a813ef2SDavid Blaikie   }
1232a813ef2SDavid Blaikie   const DILocation *Result = LocB;
1242a813ef2SDavid Blaikie   S = LocB->getScope();
1252a813ef2SDavid Blaikie   L = LocB->getInlinedAt();
1262a813ef2SDavid Blaikie   while (S) {
1272a813ef2SDavid Blaikie     if (Locations.count(std::make_pair(S, L)))
1282a813ef2SDavid Blaikie       break;
129da82ce99SFangrui Song     S = S->getScope();
1302a813ef2SDavid Blaikie     if (!S && L) {
1312a813ef2SDavid Blaikie       S = L->getScope();
1322a813ef2SDavid Blaikie       L = L->getInlinedAt();
1332a813ef2SDavid Blaikie     }
1342a813ef2SDavid Blaikie   }
1354ddd0596SAdrian Prantl 
1364ddd0596SAdrian Prantl   // If the two locations are irreconsilable, just pick one. This is misleading,
1374ddd0596SAdrian Prantl   // but on the other hand, it's a "line 0" location.
1384ddd0596SAdrian Prantl   if (!S || !isa<DILocalScope>(S))
1394ddd0596SAdrian Prantl     S = LocA->getScope();
1402a813ef2SDavid Blaikie   return DILocation::get(Result->getContext(), 0, 0, S, L);
1412b881f56SVedant Kumar }
1422b881f56SVedant Kumar 
encodeDiscriminator(unsigned BD,unsigned DF,unsigned CI)143665b4138SLuís Ferreira Optional<unsigned> DILocation::encodeDiscriminator(unsigned BD, unsigned DF,
144665b4138SLuís Ferreira                                                    unsigned CI) {
1458782c727SBenjamin Kramer   std::array<unsigned, 3> Components = {BD, DF, CI};
146b53eeb6fSMircea Trofin   uint64_t RemainingWork = 0U;
147b53eeb6fSMircea Trofin   // We use RemainingWork to figure out if we have no remaining components to
148b53eeb6fSMircea Trofin   // encode. For example: if BD != 0 but DF == 0 && CI == 0, we don't need to
149b53eeb6fSMircea Trofin   // encode anything for the latter 2.
150b53eeb6fSMircea Trofin   // Since any of the input components is at most 32 bits, their sum will be
151b53eeb6fSMircea Trofin   // less than 34 bits, and thus RemainingWork won't overflow.
152665b4138SLuís Ferreira   RemainingWork =
153665b4138SLuís Ferreira       std::accumulate(Components.begin(), Components.end(), RemainingWork);
154b53eeb6fSMircea Trofin 
155b53eeb6fSMircea Trofin   int I = 0;
156b53eeb6fSMircea Trofin   unsigned Ret = 0;
157b53eeb6fSMircea Trofin   unsigned NextBitInsertionIndex = 0;
158b53eeb6fSMircea Trofin   while (RemainingWork > 0) {
159b53eeb6fSMircea Trofin     unsigned C = Components[I++];
160b53eeb6fSMircea Trofin     RemainingWork -= C;
161b53eeb6fSMircea Trofin     unsigned EC = encodeComponent(C);
162b53eeb6fSMircea Trofin     Ret |= (EC << NextBitInsertionIndex);
163b53eeb6fSMircea Trofin     NextBitInsertionIndex += encodingBits(C);
164b53eeb6fSMircea Trofin   }
165b53eeb6fSMircea Trofin 
166b53eeb6fSMircea Trofin   // Encoding may be unsuccessful because of overflow. We determine success by
167b53eeb6fSMircea Trofin   // checking equivalence of components before & after encoding. Alternatively,
168b53eeb6fSMircea Trofin   // we could determine Success during encoding, but the current alternative is
169b53eeb6fSMircea Trofin   // simpler.
170b53eeb6fSMircea Trofin   unsigned TBD, TDF, TCI = 0;
171b53eeb6fSMircea Trofin   decodeDiscriminator(Ret, TBD, TDF, TCI);
172b53eeb6fSMircea Trofin   if (TBD == BD && TDF == DF && TCI == CI)
173b53eeb6fSMircea Trofin     return Ret;
174b53eeb6fSMircea Trofin   return None;
175b53eeb6fSMircea Trofin }
176b53eeb6fSMircea Trofin 
decodeDiscriminator(unsigned D,unsigned & BD,unsigned & DF,unsigned & CI)177b53eeb6fSMircea Trofin void DILocation::decodeDiscriminator(unsigned D, unsigned &BD, unsigned &DF,
178b53eeb6fSMircea Trofin                                      unsigned &CI) {
179b53eeb6fSMircea Trofin   BD = getUnsignedFromPrefixEncoding(D);
180b53eeb6fSMircea Trofin   DF = getUnsignedFromPrefixEncoding(getNextComponentInDiscriminator(D));
181b53eeb6fSMircea Trofin   CI = getUnsignedFromPrefixEncoding(
182b53eeb6fSMircea Trofin       getNextComponentInDiscriminator(getNextComponentInDiscriminator(D)));
183b53eeb6fSMircea Trofin }
getTag() const184ffe8720aSserge-sans-paille dwarf::Tag DINode::getTag() const { return (dwarf::Tag)SubclassData16; }
185b53eeb6fSMircea Trofin 
getFlag(StringRef Flag)1865fcc4185SLeny Kholodov DINode::DIFlags DINode::getFlag(StringRef Flag) {
1875fcc4185SLeny Kholodov   return StringSwitch<DIFlags>(Flag)
1885261e4beSDuncan P. N. Exon Smith #define HANDLE_DI_FLAG(ID, NAME) .Case("DIFlag" #NAME, Flag##NAME)
1895261e4beSDuncan P. N. Exon Smith #include "llvm/IR/DebugInfoFlags.def"
1905fcc4185SLeny Kholodov       .Default(DINode::FlagZero);
1915261e4beSDuncan P. N. Exon Smith }
1925261e4beSDuncan P. N. Exon Smith 
getFlagString(DIFlags Flag)193f42ec790SMehdi Amini StringRef DINode::getFlagString(DIFlags Flag) {
1945261e4beSDuncan P. N. Exon Smith   switch (Flag) {
1955261e4beSDuncan P. N. Exon Smith #define HANDLE_DI_FLAG(ID, NAME)                                               \
1965261e4beSDuncan P. N. Exon Smith   case Flag##NAME:                                                             \
1975261e4beSDuncan P. N. Exon Smith     return "DIFlag" #NAME;
1985261e4beSDuncan P. N. Exon Smith #include "llvm/IR/DebugInfoFlags.def"
1995261e4beSDuncan P. N. Exon Smith   }
2005fcc4185SLeny Kholodov   return "";
2015261e4beSDuncan P. N. Exon Smith }
2025261e4beSDuncan P. N. Exon Smith 
splitFlags(DIFlags Flags,SmallVectorImpl<DIFlags> & SplitFlags)2035fcc4185SLeny Kholodov DINode::DIFlags DINode::splitFlags(DIFlags Flags,
2045fcc4185SLeny Kholodov                                    SmallVectorImpl<DIFlags> &SplitFlags) {
20526a87bd0SBob Haarman   // Flags that are packed together need to be specially handled, so
20626a87bd0SBob Haarman   // that, for example, we emit "DIFlagPublic" and not
20726a87bd0SBob Haarman   // "DIFlagPrivate | DIFlagProtected".
2085fcc4185SLeny Kholodov   if (DIFlags A = Flags & FlagAccessibility) {
2095261e4beSDuncan P. N. Exon Smith     if (A == FlagPrivate)
2105261e4beSDuncan P. N. Exon Smith       SplitFlags.push_back(FlagPrivate);
2115261e4beSDuncan P. N. Exon Smith     else if (A == FlagProtected)
2125261e4beSDuncan P. N. Exon Smith       SplitFlags.push_back(FlagProtected);
2135261e4beSDuncan P. N. Exon Smith     else
2145261e4beSDuncan P. N. Exon Smith       SplitFlags.push_back(FlagPublic);
2155261e4beSDuncan P. N. Exon Smith     Flags &= ~A;
2165261e4beSDuncan P. N. Exon Smith   }
2175fcc4185SLeny Kholodov   if (DIFlags R = Flags & FlagPtrToMemberRep) {
218604105bbSReid Kleckner     if (R == FlagSingleInheritance)
219604105bbSReid Kleckner       SplitFlags.push_back(FlagSingleInheritance);
220604105bbSReid Kleckner     else if (R == FlagMultipleInheritance)
221604105bbSReid Kleckner       SplitFlags.push_back(FlagMultipleInheritance);
222604105bbSReid Kleckner     else
223604105bbSReid Kleckner       SplitFlags.push_back(FlagVirtualInheritance);
224604105bbSReid Kleckner     Flags &= ~R;
225604105bbSReid Kleckner   }
22626a87bd0SBob Haarman   if ((Flags & FlagIndirectVirtualBase) == FlagIndirectVirtualBase) {
22726a87bd0SBob Haarman     Flags &= ~FlagIndirectVirtualBase;
22826a87bd0SBob Haarman     SplitFlags.push_back(FlagIndirectVirtualBase);
22926a87bd0SBob Haarman   }
2305261e4beSDuncan P. N. Exon Smith 
2315261e4beSDuncan P. N. Exon Smith #define HANDLE_DI_FLAG(ID, NAME)                                               \
2325fcc4185SLeny Kholodov   if (DIFlags Bit = Flags & Flag##NAME) {                                      \
2335261e4beSDuncan P. N. Exon Smith     SplitFlags.push_back(Bit);                                                 \
2345261e4beSDuncan P. N. Exon Smith     Flags &= ~Bit;                                                             \
2355261e4beSDuncan P. N. Exon Smith   }
2365261e4beSDuncan P. N. Exon Smith #include "llvm/IR/DebugInfoFlags.def"
2375261e4beSDuncan P. N. Exon Smith   return Flags;
2385261e4beSDuncan P. N. Exon Smith }
2395261e4beSDuncan P. N. Exon Smith 
getScope() const240da82ce99SFangrui Song DIScope *DIScope::getScope() const {
241a9308c49SDuncan P. N. Exon Smith   if (auto *T = dyn_cast<DIType>(this))
242f0d81a50SDuncan P. N. Exon Smith     return T->getScope();
243f0d81a50SDuncan P. N. Exon Smith 
244a9308c49SDuncan P. N. Exon Smith   if (auto *SP = dyn_cast<DISubprogram>(this))
245f0d81a50SDuncan P. N. Exon Smith     return SP->getScope();
246f0d81a50SDuncan P. N. Exon Smith 
247a9308c49SDuncan P. N. Exon Smith   if (auto *LB = dyn_cast<DILexicalBlockBase>(this))
248a59d3e5aSDuncan P. N. Exon Smith     return LB->getScope();
249f0d81a50SDuncan P. N. Exon Smith 
250a9308c49SDuncan P. N. Exon Smith   if (auto *NS = dyn_cast<DINamespace>(this))
251a59d3e5aSDuncan P. N. Exon Smith     return NS->getScope();
252f0d81a50SDuncan P. N. Exon Smith 
2536ed5706aSAdrian Prantl   if (auto *CB = dyn_cast<DICommonBlock>(this))
2546ed5706aSAdrian Prantl     return CB->getScope();
2556ed5706aSAdrian Prantl 
256ab1243feSAdrian Prantl   if (auto *M = dyn_cast<DIModule>(this))
257a59d3e5aSDuncan P. N. Exon Smith     return M->getScope();
258ab1243feSAdrian Prantl 
259a9308c49SDuncan P. N. Exon Smith   assert((isa<DIFile>(this) || isa<DICompileUnit>(this)) &&
260f0d81a50SDuncan P. N. Exon Smith          "Unhandled type of scope.");
261f0d81a50SDuncan P. N. Exon Smith   return nullptr;
262f0d81a50SDuncan P. N. Exon Smith }
263f0d81a50SDuncan P. N. Exon Smith 
getName() const264a9308c49SDuncan P. N. Exon Smith StringRef DIScope::getName() const {
265a9308c49SDuncan P. N. Exon Smith   if (auto *T = dyn_cast<DIType>(this))
266f0d81a50SDuncan P. N. Exon Smith     return T->getName();
267a9308c49SDuncan P. N. Exon Smith   if (auto *SP = dyn_cast<DISubprogram>(this))
268f0d81a50SDuncan P. N. Exon Smith     return SP->getName();
269a9308c49SDuncan P. N. Exon Smith   if (auto *NS = dyn_cast<DINamespace>(this))
270f0d81a50SDuncan P. N. Exon Smith     return NS->getName();
2716ed5706aSAdrian Prantl   if (auto *CB = dyn_cast<DICommonBlock>(this))
2726ed5706aSAdrian Prantl     return CB->getName();
273ab1243feSAdrian Prantl   if (auto *M = dyn_cast<DIModule>(this))
274ab1243feSAdrian Prantl     return M->getName();
275a9308c49SDuncan P. N. Exon Smith   assert((isa<DILexicalBlockBase>(this) || isa<DIFile>(this) ||
276a9308c49SDuncan P. N. Exon Smith           isa<DICompileUnit>(this)) &&
277f0d81a50SDuncan P. N. Exon Smith          "Unhandled type of scope.");
278f0d81a50SDuncan P. N. Exon Smith   return "";
279f0d81a50SDuncan P. N. Exon Smith }
2805261e4beSDuncan P. N. Exon Smith 
281c7e0813dSDuncan P. N. Exon Smith #ifndef NDEBUG
isCanonical(const MDString * S)2829146fc8fSDuncan P. N. Exon Smith static bool isCanonical(const MDString *S) {
2839146fc8fSDuncan P. N. Exon Smith   return !S || !S->getString().empty();
284442ec022SDuncan P. N. Exon Smith }
285c7e0813dSDuncan P. N. Exon Smith #endif
286442ec022SDuncan P. N. Exon Smith 
getTag() const287ffe8720aSserge-sans-paille dwarf::Tag GenericDINode::getTag() const { return (dwarf::Tag)SubclassData16; }
getImpl(LLVMContext & Context,unsigned Tag,MDString * Header,ArrayRef<Metadata * > DwarfOps,StorageType Storage,bool ShouldCreate)288a9308c49SDuncan P. N. Exon Smith GenericDINode *GenericDINode::getImpl(LLVMContext &Context, unsigned Tag,
2899146fc8fSDuncan P. N. Exon Smith                                       MDString *Header,
290d9901ff5SDuncan P. N. Exon Smith                                       ArrayRef<Metadata *> DwarfOps,
291a9308c49SDuncan P. N. Exon Smith                                       StorageType Storage, bool ShouldCreate) {
292d9901ff5SDuncan P. N. Exon Smith   unsigned Hash = 0;
293d9901ff5SDuncan P. N. Exon Smith   if (Storage == Uniqued) {
2945d99c4efSMehdi Amini     GenericDINodeInfo::KeyTy Key(Tag, Header, DwarfOps);
295a9308c49SDuncan P. N. Exon Smith     if (auto *N = getUniqued(Context.pImpl->GenericDINodes, Key))
296d9901ff5SDuncan P. N. Exon Smith       return N;
297d9901ff5SDuncan P. N. Exon Smith     if (!ShouldCreate)
298d9901ff5SDuncan P. N. Exon Smith       return nullptr;
299d9901ff5SDuncan P. N. Exon Smith     Hash = Key.getHash();
300d9901ff5SDuncan P. N. Exon Smith   } else {
301d9901ff5SDuncan P. N. Exon Smith     assert(ShouldCreate && "Expected non-uniqued nodes to always be created");
302d9901ff5SDuncan P. N. Exon Smith   }
303d9901ff5SDuncan P. N. Exon Smith 
304d9901ff5SDuncan P. N. Exon Smith   // Use a nullptr for empty headers.
3059146fc8fSDuncan P. N. Exon Smith   assert(isCanonical(Header) && "Expected canonical MDString");
3069146fc8fSDuncan P. N. Exon Smith   Metadata *PreOps[] = {Header};
3072740c187SWolfgang Pieb   return storeImpl(new (DwarfOps.size() + 1, Storage) GenericDINode(
308d9901ff5SDuncan P. N. Exon Smith                        Context, Storage, Hash, Tag, PreOps, DwarfOps),
309a9308c49SDuncan P. N. Exon Smith                    Storage, Context.pImpl->GenericDINodes);
310d9901ff5SDuncan P. N. Exon Smith }
311d9901ff5SDuncan P. N. Exon Smith 
recalculateHash()312a9308c49SDuncan P. N. Exon Smith void GenericDINode::recalculateHash() {
313a9308c49SDuncan P. N. Exon Smith   setHash(GenericDINodeInfo::KeyTy::calculateHash(this));
314d9901ff5SDuncan P. N. Exon Smith }
31501fc1769SDuncan P. N. Exon Smith 
31601fc1769SDuncan P. N. Exon Smith #define UNWRAP_ARGS_IMPL(...) __VA_ARGS__
31701fc1769SDuncan P. N. Exon Smith #define UNWRAP_ARGS(ARGS) UNWRAP_ARGS_IMPL ARGS
31801fc1769SDuncan P. N. Exon Smith #define DEFINE_GETIMPL_LOOKUP(CLASS, ARGS)                                     \
31901fc1769SDuncan P. N. Exon Smith   do {                                                                         \
32001fc1769SDuncan P. N. Exon Smith     if (Storage == Uniqued) {                                                  \
32101fc1769SDuncan P. N. Exon Smith       if (auto *N = getUniqued(Context.pImpl->CLASS##s,                        \
32201fc1769SDuncan P. N. Exon Smith                                CLASS##Info::KeyTy(UNWRAP_ARGS(ARGS))))         \
32301fc1769SDuncan P. N. Exon Smith         return N;                                                              \
32401fc1769SDuncan P. N. Exon Smith       if (!ShouldCreate)                                                       \
32501fc1769SDuncan P. N. Exon Smith         return nullptr;                                                        \
32601fc1769SDuncan P. N. Exon Smith     } else {                                                                   \
32701fc1769SDuncan P. N. Exon Smith       assert(ShouldCreate &&                                                   \
32801fc1769SDuncan P. N. Exon Smith              "Expected non-uniqued nodes to always be created");               \
32901fc1769SDuncan P. N. Exon Smith     }                                                                          \
33001fc1769SDuncan P. N. Exon Smith   } while (false)
33101fc1769SDuncan P. N. Exon Smith #define DEFINE_GETIMPL_STORE(CLASS, ARGS, OPS)                                 \
3322740c187SWolfgang Pieb   return storeImpl(new (array_lengthof(OPS), Storage)                          \
33301fc1769SDuncan P. N. Exon Smith                        CLASS(Context, Storage, UNWRAP_ARGS(ARGS), OPS),        \
33401fc1769SDuncan P. N. Exon Smith                    Storage, Context.pImpl->CLASS##s)
33501fc1769SDuncan P. N. Exon Smith #define DEFINE_GETIMPL_STORE_NO_OPS(CLASS, ARGS)                               \
3362740c187SWolfgang Pieb   return storeImpl(new (0u, Storage)                                           \
3372740c187SWolfgang Pieb                        CLASS(Context, Storage, UNWRAP_ARGS(ARGS)),             \
33801fc1769SDuncan P. N. Exon Smith                    Storage, Context.pImpl->CLASS##s)
339bd33d375SDuncan P. N. Exon Smith #define DEFINE_GETIMPL_STORE_NO_CONSTRUCTOR_ARGS(CLASS, OPS)                   \
3402740c187SWolfgang Pieb   return storeImpl(new (array_lengthof(OPS), Storage)                          \
3412740c187SWolfgang Pieb                        CLASS(Context, Storage, OPS),                           \
342bd33d375SDuncan P. N. Exon Smith                    Storage, Context.pImpl->CLASS##s)
3439d2f019fSAdrian Prantl #define DEFINE_GETIMPL_STORE_N(CLASS, ARGS, OPS, NUM_OPS)                      \
3442740c187SWolfgang Pieb   return storeImpl(new (NUM_OPS, Storage)                                      \
3459d2f019fSAdrian Prantl                        CLASS(Context, Storage, UNWRAP_ARGS(ARGS), OPS),        \
3469d2f019fSAdrian Prantl                    Storage, Context.pImpl->CLASS##s)
34701fc1769SDuncan P. N. Exon Smith 
DISubrange(LLVMContext & C,StorageType Storage,ArrayRef<Metadata * > Ops)348ffe8720aSserge-sans-paille DISubrange::DISubrange(LLVMContext &C, StorageType Storage,
349ffe8720aSserge-sans-paille                        ArrayRef<Metadata *> Ops)
350ffe8720aSserge-sans-paille     : DINode(C, DISubrangeKind, Storage, dwarf::DW_TAG_subrange_type, Ops) {}
getImpl(LLVMContext & Context,int64_t Count,int64_t Lo,StorageType Storage,bool ShouldCreate)351a9308c49SDuncan P. N. Exon Smith DISubrange *DISubrange::getImpl(LLVMContext &Context, int64_t Count, int64_t Lo,
35201fc1769SDuncan P. N. Exon Smith                                 StorageType Storage, bool ShouldCreate) {
353fdf40917SSander de Smalen   auto *CountNode = ConstantAsMetadata::get(
354fdf40917SSander de Smalen       ConstantInt::getSigned(Type::getInt64Ty(Context), Count));
355d20bf5a7SAlok Kumar Sharma   auto *LB = ConstantAsMetadata::get(
356d20bf5a7SAlok Kumar Sharma       ConstantInt::getSigned(Type::getInt64Ty(Context), Lo));
357d20bf5a7SAlok Kumar Sharma   return getImpl(Context, CountNode, LB, nullptr, nullptr, Storage,
358d20bf5a7SAlok Kumar Sharma                  ShouldCreate);
359fdf40917SSander de Smalen }
360fdf40917SSander de Smalen 
getImpl(LLVMContext & Context,Metadata * CountNode,int64_t Lo,StorageType Storage,bool ShouldCreate)361fdf40917SSander de Smalen DISubrange *DISubrange::getImpl(LLVMContext &Context, Metadata *CountNode,
362fdf40917SSander de Smalen                                 int64_t Lo, StorageType Storage,
363fdf40917SSander de Smalen                                 bool ShouldCreate) {
364d20bf5a7SAlok Kumar Sharma   auto *LB = ConstantAsMetadata::get(
365d20bf5a7SAlok Kumar Sharma       ConstantInt::getSigned(Type::getInt64Ty(Context), Lo));
366d20bf5a7SAlok Kumar Sharma   return getImpl(Context, CountNode, LB, nullptr, nullptr, Storage,
367d20bf5a7SAlok Kumar Sharma                  ShouldCreate);
368d20bf5a7SAlok Kumar Sharma }
369d20bf5a7SAlok Kumar Sharma 
getImpl(LLVMContext & Context,Metadata * CountNode,Metadata * LB,Metadata * UB,Metadata * Stride,StorageType Storage,bool ShouldCreate)370d20bf5a7SAlok Kumar Sharma DISubrange *DISubrange::getImpl(LLVMContext &Context, Metadata *CountNode,
371d20bf5a7SAlok Kumar Sharma                                 Metadata *LB, Metadata *UB, Metadata *Stride,
372d20bf5a7SAlok Kumar Sharma                                 StorageType Storage, bool ShouldCreate) {
373d20bf5a7SAlok Kumar Sharma   DEFINE_GETIMPL_LOOKUP(DISubrange, (CountNode, LB, UB, Stride));
374d20bf5a7SAlok Kumar Sharma   Metadata *Ops[] = {CountNode, LB, UB, Stride};
375d20bf5a7SAlok Kumar Sharma   DEFINE_GETIMPL_STORE_NO_CONSTRUCTOR_ARGS(DISubrange, Ops);
376d20bf5a7SAlok Kumar Sharma }
377d20bf5a7SAlok Kumar Sharma 
getCount() const3789fb0025fSAlok Kumar Sharma DISubrange::BoundType DISubrange::getCount() const {
3799fb0025fSAlok Kumar Sharma   Metadata *CB = getRawCountNode();
3809fb0025fSAlok Kumar Sharma   if (!CB)
3819fb0025fSAlok Kumar Sharma     return BoundType();
382d20bf5a7SAlok Kumar Sharma 
3839fb0025fSAlok Kumar Sharma   assert((isa<ConstantAsMetadata>(CB) || isa<DIVariable>(CB) ||
3849fb0025fSAlok Kumar Sharma           isa<DIExpression>(CB)) &&
3859fb0025fSAlok Kumar Sharma          "Count must be signed constant or DIVariable or DIExpression");
386d20bf5a7SAlok Kumar Sharma 
3879fb0025fSAlok Kumar Sharma   if (auto *MD = dyn_cast<ConstantAsMetadata>(CB))
3889fb0025fSAlok Kumar Sharma     return BoundType(cast<ConstantInt>(MD->getValue()));
389d20bf5a7SAlok Kumar Sharma 
3909fb0025fSAlok Kumar Sharma   if (auto *MD = dyn_cast<DIVariable>(CB))
3919fb0025fSAlok Kumar Sharma     return BoundType(MD);
3929fb0025fSAlok Kumar Sharma 
3939fb0025fSAlok Kumar Sharma   if (auto *MD = dyn_cast<DIExpression>(CB))
3949fb0025fSAlok Kumar Sharma     return BoundType(MD);
3959fb0025fSAlok Kumar Sharma 
3969fb0025fSAlok Kumar Sharma   return BoundType();
397d20bf5a7SAlok Kumar Sharma }
398d20bf5a7SAlok Kumar Sharma 
getLowerBound() const399d20bf5a7SAlok Kumar Sharma DISubrange::BoundType DISubrange::getLowerBound() const {
400d20bf5a7SAlok Kumar Sharma   Metadata *LB = getRawLowerBound();
401d20bf5a7SAlok Kumar Sharma   if (!LB)
402d20bf5a7SAlok Kumar Sharma     return BoundType();
403d20bf5a7SAlok Kumar Sharma 
404d20bf5a7SAlok Kumar Sharma   assert((isa<ConstantAsMetadata>(LB) || isa<DIVariable>(LB) ||
405d20bf5a7SAlok Kumar Sharma           isa<DIExpression>(LB)) &&
406d20bf5a7SAlok Kumar Sharma          "LowerBound must be signed constant or DIVariable or DIExpression");
407d20bf5a7SAlok Kumar Sharma 
408d20bf5a7SAlok Kumar Sharma   if (auto *MD = dyn_cast<ConstantAsMetadata>(LB))
409d20bf5a7SAlok Kumar Sharma     return BoundType(cast<ConstantInt>(MD->getValue()));
410d20bf5a7SAlok Kumar Sharma 
411d20bf5a7SAlok Kumar Sharma   if (auto *MD = dyn_cast<DIVariable>(LB))
412d20bf5a7SAlok Kumar Sharma     return BoundType(MD);
413d20bf5a7SAlok Kumar Sharma 
414d20bf5a7SAlok Kumar Sharma   if (auto *MD = dyn_cast<DIExpression>(LB))
415d20bf5a7SAlok Kumar Sharma     return BoundType(MD);
416d20bf5a7SAlok Kumar Sharma 
417d20bf5a7SAlok Kumar Sharma   return BoundType();
418d20bf5a7SAlok Kumar Sharma }
419d20bf5a7SAlok Kumar Sharma 
getUpperBound() const420d20bf5a7SAlok Kumar Sharma DISubrange::BoundType DISubrange::getUpperBound() const {
421d20bf5a7SAlok Kumar Sharma   Metadata *UB = getRawUpperBound();
422d20bf5a7SAlok Kumar Sharma   if (!UB)
423d20bf5a7SAlok Kumar Sharma     return BoundType();
424d20bf5a7SAlok Kumar Sharma 
425d20bf5a7SAlok Kumar Sharma   assert((isa<ConstantAsMetadata>(UB) || isa<DIVariable>(UB) ||
426d20bf5a7SAlok Kumar Sharma           isa<DIExpression>(UB)) &&
427d20bf5a7SAlok Kumar Sharma          "UpperBound must be signed constant or DIVariable or DIExpression");
428d20bf5a7SAlok Kumar Sharma 
429d20bf5a7SAlok Kumar Sharma   if (auto *MD = dyn_cast<ConstantAsMetadata>(UB))
430d20bf5a7SAlok Kumar Sharma     return BoundType(cast<ConstantInt>(MD->getValue()));
431d20bf5a7SAlok Kumar Sharma 
432d20bf5a7SAlok Kumar Sharma   if (auto *MD = dyn_cast<DIVariable>(UB))
433d20bf5a7SAlok Kumar Sharma     return BoundType(MD);
434d20bf5a7SAlok Kumar Sharma 
435d20bf5a7SAlok Kumar Sharma   if (auto *MD = dyn_cast<DIExpression>(UB))
436d20bf5a7SAlok Kumar Sharma     return BoundType(MD);
437d20bf5a7SAlok Kumar Sharma 
438d20bf5a7SAlok Kumar Sharma   return BoundType();
439d20bf5a7SAlok Kumar Sharma }
440d20bf5a7SAlok Kumar Sharma 
getStride() const441d20bf5a7SAlok Kumar Sharma DISubrange::BoundType DISubrange::getStride() const {
442d20bf5a7SAlok Kumar Sharma   Metadata *ST = getRawStride();
443d20bf5a7SAlok Kumar Sharma   if (!ST)
444d20bf5a7SAlok Kumar Sharma     return BoundType();
445d20bf5a7SAlok Kumar Sharma 
446d20bf5a7SAlok Kumar Sharma   assert((isa<ConstantAsMetadata>(ST) || isa<DIVariable>(ST) ||
447d20bf5a7SAlok Kumar Sharma           isa<DIExpression>(ST)) &&
448d20bf5a7SAlok Kumar Sharma          "Stride must be signed constant or DIVariable or DIExpression");
449d20bf5a7SAlok Kumar Sharma 
450d20bf5a7SAlok Kumar Sharma   if (auto *MD = dyn_cast<ConstantAsMetadata>(ST))
451d20bf5a7SAlok Kumar Sharma     return BoundType(cast<ConstantInt>(MD->getValue()));
452d20bf5a7SAlok Kumar Sharma 
453d20bf5a7SAlok Kumar Sharma   if (auto *MD = dyn_cast<DIVariable>(ST))
454d20bf5a7SAlok Kumar Sharma     return BoundType(MD);
455d20bf5a7SAlok Kumar Sharma 
456d20bf5a7SAlok Kumar Sharma   if (auto *MD = dyn_cast<DIExpression>(ST))
457d20bf5a7SAlok Kumar Sharma     return BoundType(MD);
458d20bf5a7SAlok Kumar Sharma 
459d20bf5a7SAlok Kumar Sharma   return BoundType();
46001fc1769SDuncan P. N. Exon Smith }
DIGenericSubrange(LLVMContext & C,StorageType Storage,ArrayRef<Metadata * > Ops)461ffe8720aSserge-sans-paille DIGenericSubrange::DIGenericSubrange(LLVMContext &C, StorageType Storage,
462ffe8720aSserge-sans-paille                                      ArrayRef<Metadata *> Ops)
463ffe8720aSserge-sans-paille     : DINode(C, DIGenericSubrangeKind, Storage, dwarf::DW_TAG_generic_subrange,
464ffe8720aSserge-sans-paille              Ops) {}
46501fc1769SDuncan P. N. Exon Smith 
getImpl(LLVMContext & Context,Metadata * CountNode,Metadata * LB,Metadata * UB,Metadata * Stride,StorageType Storage,bool ShouldCreate)466a6dd01afSAlok Kumar Sharma DIGenericSubrange *DIGenericSubrange::getImpl(LLVMContext &Context,
467a6dd01afSAlok Kumar Sharma                                               Metadata *CountNode, Metadata *LB,
468a6dd01afSAlok Kumar Sharma                                               Metadata *UB, Metadata *Stride,
469a6dd01afSAlok Kumar Sharma                                               StorageType Storage,
470a6dd01afSAlok Kumar Sharma                                               bool ShouldCreate) {
471a6dd01afSAlok Kumar Sharma   DEFINE_GETIMPL_LOOKUP(DIGenericSubrange, (CountNode, LB, UB, Stride));
472a6dd01afSAlok Kumar Sharma   Metadata *Ops[] = {CountNode, LB, UB, Stride};
473a6dd01afSAlok Kumar Sharma   DEFINE_GETIMPL_STORE_NO_CONSTRUCTOR_ARGS(DIGenericSubrange, Ops);
474a6dd01afSAlok Kumar Sharma }
475a6dd01afSAlok Kumar Sharma 
getCount() const476a6dd01afSAlok Kumar Sharma DIGenericSubrange::BoundType DIGenericSubrange::getCount() const {
477a6dd01afSAlok Kumar Sharma   Metadata *CB = getRawCountNode();
478a6dd01afSAlok Kumar Sharma   if (!CB)
479a6dd01afSAlok Kumar Sharma     return BoundType();
480a6dd01afSAlok Kumar Sharma 
481a6dd01afSAlok Kumar Sharma   assert((isa<DIVariable>(CB) || isa<DIExpression>(CB)) &&
482a6dd01afSAlok Kumar Sharma          "Count must be signed constant or DIVariable or DIExpression");
483a6dd01afSAlok Kumar Sharma 
484a6dd01afSAlok Kumar Sharma   if (auto *MD = dyn_cast<DIVariable>(CB))
485a6dd01afSAlok Kumar Sharma     return BoundType(MD);
486a6dd01afSAlok Kumar Sharma 
487a6dd01afSAlok Kumar Sharma   if (auto *MD = dyn_cast<DIExpression>(CB))
488a6dd01afSAlok Kumar Sharma     return BoundType(MD);
489a6dd01afSAlok Kumar Sharma 
490a6dd01afSAlok Kumar Sharma   return BoundType();
491a6dd01afSAlok Kumar Sharma }
492a6dd01afSAlok Kumar Sharma 
getLowerBound() const493a6dd01afSAlok Kumar Sharma DIGenericSubrange::BoundType DIGenericSubrange::getLowerBound() const {
494a6dd01afSAlok Kumar Sharma   Metadata *LB = getRawLowerBound();
495a6dd01afSAlok Kumar Sharma   if (!LB)
496a6dd01afSAlok Kumar Sharma     return BoundType();
497a6dd01afSAlok Kumar Sharma 
498a6dd01afSAlok Kumar Sharma   assert((isa<DIVariable>(LB) || isa<DIExpression>(LB)) &&
499a6dd01afSAlok Kumar Sharma          "LowerBound must be signed constant or DIVariable or DIExpression");
500a6dd01afSAlok Kumar Sharma 
501a6dd01afSAlok Kumar Sharma   if (auto *MD = dyn_cast<DIVariable>(LB))
502a6dd01afSAlok Kumar Sharma     return BoundType(MD);
503a6dd01afSAlok Kumar Sharma 
504a6dd01afSAlok Kumar Sharma   if (auto *MD = dyn_cast<DIExpression>(LB))
505a6dd01afSAlok Kumar Sharma     return BoundType(MD);
506a6dd01afSAlok Kumar Sharma 
507a6dd01afSAlok Kumar Sharma   return BoundType();
508a6dd01afSAlok Kumar Sharma }
509a6dd01afSAlok Kumar Sharma 
getUpperBound() const510a6dd01afSAlok Kumar Sharma DIGenericSubrange::BoundType DIGenericSubrange::getUpperBound() const {
511a6dd01afSAlok Kumar Sharma   Metadata *UB = getRawUpperBound();
512a6dd01afSAlok Kumar Sharma   if (!UB)
513a6dd01afSAlok Kumar Sharma     return BoundType();
514a6dd01afSAlok Kumar Sharma 
515a6dd01afSAlok Kumar Sharma   assert((isa<DIVariable>(UB) || isa<DIExpression>(UB)) &&
516a6dd01afSAlok Kumar Sharma          "UpperBound must be signed constant or DIVariable or DIExpression");
517a6dd01afSAlok Kumar Sharma 
518a6dd01afSAlok Kumar Sharma   if (auto *MD = dyn_cast<DIVariable>(UB))
519a6dd01afSAlok Kumar Sharma     return BoundType(MD);
520a6dd01afSAlok Kumar Sharma 
521a6dd01afSAlok Kumar Sharma   if (auto *MD = dyn_cast<DIExpression>(UB))
522a6dd01afSAlok Kumar Sharma     return BoundType(MD);
523a6dd01afSAlok Kumar Sharma 
524a6dd01afSAlok Kumar Sharma   return BoundType();
525a6dd01afSAlok Kumar Sharma }
526a6dd01afSAlok Kumar Sharma 
getStride() const527a6dd01afSAlok Kumar Sharma DIGenericSubrange::BoundType DIGenericSubrange::getStride() const {
528a6dd01afSAlok Kumar Sharma   Metadata *ST = getRawStride();
529a6dd01afSAlok Kumar Sharma   if (!ST)
530a6dd01afSAlok Kumar Sharma     return BoundType();
531a6dd01afSAlok Kumar Sharma 
532a6dd01afSAlok Kumar Sharma   assert((isa<DIVariable>(ST) || isa<DIExpression>(ST)) &&
533a6dd01afSAlok Kumar Sharma          "Stride must be signed constant or DIVariable or DIExpression");
534a6dd01afSAlok Kumar Sharma 
535a6dd01afSAlok Kumar Sharma   if (auto *MD = dyn_cast<DIVariable>(ST))
536a6dd01afSAlok Kumar Sharma     return BoundType(MD);
537a6dd01afSAlok Kumar Sharma 
538a6dd01afSAlok Kumar Sharma   if (auto *MD = dyn_cast<DIExpression>(ST))
539a6dd01afSAlok Kumar Sharma     return BoundType(MD);
540a6dd01afSAlok Kumar Sharma 
541a6dd01afSAlok Kumar Sharma   return BoundType();
542a6dd01afSAlok Kumar Sharma }
543a6dd01afSAlok Kumar Sharma 
DIEnumerator(LLVMContext & C,StorageType Storage,const APInt & Value,bool IsUnsigned,ArrayRef<Metadata * > Ops)544ffe8720aSserge-sans-paille DIEnumerator::DIEnumerator(LLVMContext &C, StorageType Storage,
545ffe8720aSserge-sans-paille                            const APInt &Value, bool IsUnsigned,
546ffe8720aSserge-sans-paille                            ArrayRef<Metadata *> Ops)
547ffe8720aSserge-sans-paille     : DINode(C, DIEnumeratorKind, Storage, dwarf::DW_TAG_enumerator, Ops),
548ffe8720aSserge-sans-paille       Value(Value) {
549ffe8720aSserge-sans-paille   SubclassData32 = IsUnsigned;
550ffe8720aSserge-sans-paille }
getImpl(LLVMContext & Context,const APInt & Value,bool IsUnsigned,MDString * Name,StorageType Storage,bool ShouldCreate)55165647ed1SSimon Pilgrim DIEnumerator *DIEnumerator::getImpl(LLVMContext &Context, const APInt &Value,
55208dc66efSMomchil Velikov                                     bool IsUnsigned, MDString *Name,
55308dc66efSMomchil Velikov                                     StorageType Storage, bool ShouldCreate) {
55401fc1769SDuncan P. N. Exon Smith   assert(isCanonical(Name) && "Expected canonical MDString");
55508dc66efSMomchil Velikov   DEFINE_GETIMPL_LOOKUP(DIEnumerator, (Value, IsUnsigned, Name));
55601fc1769SDuncan P. N. Exon Smith   Metadata *Ops[] = {Name};
55708dc66efSMomchil Velikov   DEFINE_GETIMPL_STORE(DIEnumerator, (Value, IsUnsigned), Ops);
55801fc1769SDuncan P. N. Exon Smith }
55901fc1769SDuncan P. N. Exon Smith 
getImpl(LLVMContext & Context,unsigned Tag,MDString * Name,uint64_t SizeInBits,uint32_t AlignInBits,unsigned Encoding,DIFlags Flags,StorageType Storage,bool ShouldCreate)560a9308c49SDuncan P. N. Exon Smith DIBasicType *DIBasicType::getImpl(LLVMContext &Context, unsigned Tag,
561d34db171SDuncan P. N. Exon Smith                                   MDString *Name, uint64_t SizeInBits,
562197aa319SVictor Leschuk                                   uint32_t AlignInBits, unsigned Encoding,
56355f42629SAdrian Prantl                                   DIFlags Flags, StorageType Storage,
56455f42629SAdrian Prantl                                   bool ShouldCreate) {
56501fc1769SDuncan P. N. Exon Smith   assert(isCanonical(Name) && "Expected canonical MDString");
5665d99c4efSMehdi Amini   DEFINE_GETIMPL_LOOKUP(DIBasicType,
56755f42629SAdrian Prantl                         (Tag, Name, SizeInBits, AlignInBits, Encoding, Flags));
56801fc1769SDuncan P. N. Exon Smith   Metadata *Ops[] = {nullptr, nullptr, Name};
569665b4138SLuís Ferreira   DEFINE_GETIMPL_STORE(DIBasicType,
570665b4138SLuís Ferreira                        (Tag, SizeInBits, AlignInBits, Encoding, Flags), Ops);
57101fc1769SDuncan P. N. Exon Smith }
57201fc1769SDuncan P. N. Exon Smith 
getSignedness() const5736379a622SVedant Kumar Optional<DIBasicType::Signedness> DIBasicType::getSignedness() const {
5746379a622SVedant Kumar   switch (getEncoding()) {
5756379a622SVedant Kumar   case dwarf::DW_ATE_signed:
5766379a622SVedant Kumar   case dwarf::DW_ATE_signed_char:
5776379a622SVedant Kumar     return Signedness::Signed;
5786379a622SVedant Kumar   case dwarf::DW_ATE_unsigned:
5796379a622SVedant Kumar   case dwarf::DW_ATE_unsigned_char:
5806379a622SVedant Kumar     return Signedness::Unsigned;
5816379a622SVedant Kumar   default:
5826379a622SVedant Kumar     return None;
5836379a622SVedant Kumar   }
5846379a622SVedant Kumar }
5856379a622SVedant Kumar 
getImpl(LLVMContext & Context,unsigned Tag,MDString * Name,Metadata * StringLength,Metadata * StringLengthExp,Metadata * StringLocationExp,uint64_t SizeInBits,uint32_t AlignInBits,unsigned Encoding,StorageType Storage,bool ShouldCreate)586f91d18eaSSourabh Singh Tomar DIStringType *DIStringType::getImpl(LLVMContext &Context, unsigned Tag,
587f91d18eaSSourabh Singh Tomar                                     MDString *Name, Metadata *StringLength,
588f91d18eaSSourabh Singh Tomar                                     Metadata *StringLengthExp,
58928bfa57aSChih-Ping Chen                                     Metadata *StringLocationExp,
590f91d18eaSSourabh Singh Tomar                                     uint64_t SizeInBits, uint32_t AlignInBits,
591f91d18eaSSourabh Singh Tomar                                     unsigned Encoding, StorageType Storage,
592f91d18eaSSourabh Singh Tomar                                     bool ShouldCreate) {
593f91d18eaSSourabh Singh Tomar   assert(isCanonical(Name) && "Expected canonical MDString");
59428bfa57aSChih-Ping Chen   DEFINE_GETIMPL_LOOKUP(DIStringType,
59528bfa57aSChih-Ping Chen                         (Tag, Name, StringLength, StringLengthExp,
59628bfa57aSChih-Ping Chen                          StringLocationExp, SizeInBits, AlignInBits, Encoding));
59728bfa57aSChih-Ping Chen   Metadata *Ops[] = {nullptr,      nullptr,         Name,
59828bfa57aSChih-Ping Chen                      StringLength, StringLengthExp, StringLocationExp};
599f91d18eaSSourabh Singh Tomar   DEFINE_GETIMPL_STORE(DIStringType, (Tag, SizeInBits, AlignInBits, Encoding),
600f91d18eaSSourabh Singh Tomar                        Ops);
601f91d18eaSSourabh Singh Tomar }
getClassType() const602ffe8720aSserge-sans-paille DIType *DIDerivedType::getClassType() const {
603ffe8720aSserge-sans-paille   assert(getTag() == dwarf::DW_TAG_ptr_to_member_type);
604ffe8720aSserge-sans-paille   return cast_or_null<DIType>(getExtraData());
605ffe8720aSserge-sans-paille }
getVBPtrOffset() const606ffe8720aSserge-sans-paille uint32_t DIDerivedType::getVBPtrOffset() const {
607ffe8720aSserge-sans-paille   assert(getTag() == dwarf::DW_TAG_inheritance);
608ffe8720aSserge-sans-paille   if (auto *CM = cast_or_null<ConstantAsMetadata>(getExtraData()))
609ffe8720aSserge-sans-paille     if (auto *CI = dyn_cast_or_null<ConstantInt>(CM->getValue()))
610ffe8720aSserge-sans-paille       return static_cast<uint32_t>(CI->getZExtValue());
611ffe8720aSserge-sans-paille   return 0;
612ffe8720aSserge-sans-paille }
getStorageOffsetInBits() const613ffe8720aSserge-sans-paille Constant *DIDerivedType::getStorageOffsetInBits() const {
614ffe8720aSserge-sans-paille   assert(getTag() == dwarf::DW_TAG_member && isBitField());
615ffe8720aSserge-sans-paille   if (auto *C = cast_or_null<ConstantAsMetadata>(getExtraData()))
616ffe8720aSserge-sans-paille     return C->getValue();
617ffe8720aSserge-sans-paille   return nullptr;
618ffe8720aSserge-sans-paille }
619ffe8720aSserge-sans-paille 
getConstant() const620ffe8720aSserge-sans-paille Constant *DIDerivedType::getConstant() const {
621ffe8720aSserge-sans-paille   assert(getTag() == dwarf::DW_TAG_member && isStaticMember());
622ffe8720aSserge-sans-paille   if (auto *C = cast_or_null<ConstantAsMetadata>(getExtraData()))
623ffe8720aSserge-sans-paille     return C->getValue();
624ffe8720aSserge-sans-paille   return nullptr;
625ffe8720aSserge-sans-paille }
getDiscriminantValue() const626ffe8720aSserge-sans-paille Constant *DIDerivedType::getDiscriminantValue() const {
627ffe8720aSserge-sans-paille   assert(getTag() == dwarf::DW_TAG_member && !isStaticMember());
628ffe8720aSserge-sans-paille   if (auto *C = cast_or_null<ConstantAsMetadata>(getExtraData()))
629ffe8720aSserge-sans-paille     return C->getValue();
630ffe8720aSserge-sans-paille   return nullptr;
631ffe8720aSserge-sans-paille }
632f91d18eaSSourabh Singh Tomar 
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,Metadata * Annotations,StorageType Storage,bool ShouldCreate)633a9308c49SDuncan P. N. Exon Smith DIDerivedType *DIDerivedType::getImpl(
63401fc1769SDuncan P. N. Exon Smith     LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
635d34db171SDuncan P. N. Exon Smith     unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits,
636d5561e0aSKonstantin Zhuravlyov     uint32_t AlignInBits, uint64_t OffsetInBits,
637d5561e0aSKonstantin Zhuravlyov     Optional<unsigned> DWARFAddressSpace, DIFlags Flags, Metadata *ExtraData,
638430e2238SYonghong Song     Metadata *Annotations, StorageType Storage, bool ShouldCreate) {
63901fc1769SDuncan P. N. Exon Smith   assert(isCanonical(Name) && "Expected canonical MDString");
6405d99c4efSMehdi Amini   DEFINE_GETIMPL_LOOKUP(DIDerivedType,
6415d99c4efSMehdi Amini                         (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
642d5561e0aSKonstantin Zhuravlyov                          AlignInBits, OffsetInBits, DWARFAddressSpace, Flags,
643430e2238SYonghong Song                          ExtraData, Annotations));
644430e2238SYonghong Song   Metadata *Ops[] = {File, Scope, Name, BaseType, ExtraData, Annotations};
645665b4138SLuís Ferreira   DEFINE_GETIMPL_STORE(DIDerivedType,
646665b4138SLuís Ferreira                        (Tag, Line, SizeInBits, AlignInBits, OffsetInBits,
647665b4138SLuís Ferreira                         DWARFAddressSpace, Flags),
648665b4138SLuís Ferreira                        Ops);
64901fc1769SDuncan P. N. Exon Smith }
65001fc1769SDuncan P. N. Exon Smith 
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,Metadata * DataLocation,Metadata * Associated,Metadata * Allocated,Metadata * Rank,Metadata * Annotations,StorageType Storage,bool ShouldCreate)651a9308c49SDuncan P. N. Exon Smith DICompositeType *DICompositeType::getImpl(
65201fc1769SDuncan P. N. Exon Smith     LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
653d34db171SDuncan P. N. Exon Smith     unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits,
654197aa319SVictor Leschuk     uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags,
65501fc1769SDuncan P. N. Exon Smith     Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder,
6568c59921cSAdrian Prantl     Metadata *TemplateParams, MDString *Identifier, Metadata *Discriminator,
6572d10258aSAlok Kumar Sharma     Metadata *DataLocation, Metadata *Associated, Metadata *Allocated,
6580b32dca1SYonghong Song     Metadata *Rank, Metadata *Annotations, StorageType Storage,
6590b32dca1SYonghong Song     bool ShouldCreate) {
66001fc1769SDuncan P. N. Exon Smith   assert(isCanonical(Name) && "Expected canonical MDString");
6615ab2be09SDuncan P. N. Exon Smith 
66297386028SDuncan P. N. Exon Smith   // Keep this in sync with buildODRType.
6630b32dca1SYonghong Song   DEFINE_GETIMPL_LOOKUP(DICompositeType,
6640b32dca1SYonghong Song                         (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
6650b32dca1SYonghong Song                          AlignInBits, OffsetInBits, Flags, Elements,
6660b32dca1SYonghong Song                          RuntimeLang, VTableHolder, TemplateParams, Identifier,
6670b32dca1SYonghong Song                          Discriminator, DataLocation, Associated, Allocated,
6680b32dca1SYonghong Song                          Rank, Annotations));
66901fc1769SDuncan P. N. Exon Smith   Metadata *Ops[] = {File,          Scope,        Name,           BaseType,
6708c59921cSAdrian Prantl                      Elements,      VTableHolder, TemplateParams, Identifier,
67196bd4d34SAlok Kumar Sharma                      Discriminator, DataLocation, Associated,     Allocated,
6720b32dca1SYonghong Song                      Rank,          Annotations};
673665b4138SLuís Ferreira   DEFINE_GETIMPL_STORE(
674665b4138SLuís Ferreira       DICompositeType,
675665b4138SLuís Ferreira       (Tag, Line, RuntimeLang, SizeInBits, AlignInBits, OffsetInBits, Flags),
67601fc1769SDuncan P. N. Exon Smith       Ops);
67701fc1769SDuncan P. N. Exon Smith }
67801fc1769SDuncan P. N. Exon Smith 
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,Metadata * DataLocation,Metadata * Associated,Metadata * Allocated,Metadata * Rank,Metadata * Annotations)67997386028SDuncan P. N. Exon Smith DICompositeType *DICompositeType::buildODRType(
68097386028SDuncan P. N. Exon Smith     LLVMContext &Context, MDString &Identifier, unsigned Tag, MDString *Name,
68197386028SDuncan P. N. Exon Smith     Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType,
682197aa319SVictor Leschuk     uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
6835fcc4185SLeny Kholodov     DIFlags Flags, Metadata *Elements, unsigned RuntimeLang,
6844042ada1SAlok Kumar Sharma     Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator,
68596bd4d34SAlok Kumar Sharma     Metadata *DataLocation, Metadata *Associated, Metadata *Allocated,
6860b32dca1SYonghong Song     Metadata *Rank, Metadata *Annotations) {
68797386028SDuncan P. N. Exon Smith   assert(!Identifier.getString().empty() && "Expected valid identifier");
68897386028SDuncan P. N. Exon Smith   if (!Context.isODRUniquingDebugTypes())
68997386028SDuncan P. N. Exon Smith     return nullptr;
69097386028SDuncan P. N. Exon Smith   auto *&CT = (*Context.pImpl->DITypeMap)[&Identifier];
69197386028SDuncan P. N. Exon Smith   if (!CT)
69297386028SDuncan P. N. Exon Smith     return CT = DICompositeType::getDistinct(
69397386028SDuncan P. N. Exon Smith                Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits,
69497386028SDuncan P. N. Exon Smith                AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
6954042ada1SAlok Kumar Sharma                VTableHolder, TemplateParams, &Identifier, Discriminator,
6960b32dca1SYonghong Song                DataLocation, Associated, Allocated, Rank, Annotations);
69797386028SDuncan P. N. Exon Smith 
6987c3fa527SYuanfang Chen   if (CT->getTag() != Tag)
6997c3fa527SYuanfang Chen     return nullptr;
7007c3fa527SYuanfang Chen 
70197386028SDuncan P. N. Exon Smith   // Only mutate CT if it's a forward declaration and the new operands aren't.
70297386028SDuncan P. N. Exon Smith   assert(CT->getRawIdentifier() == &Identifier && "Wrong ODR identifier?");
70397386028SDuncan P. N. Exon Smith   if (!CT->isForwardDecl() || (Flags & DINode::FlagFwdDecl))
70497386028SDuncan P. N. Exon Smith     return CT;
70597386028SDuncan P. N. Exon Smith 
70697386028SDuncan P. N. Exon Smith   // Mutate CT in place.  Keep this in sync with getImpl.
70797386028SDuncan P. N. Exon Smith   CT->mutate(Tag, Line, RuntimeLang, SizeInBits, AlignInBits, OffsetInBits,
70897386028SDuncan P. N. Exon Smith              Flags);
70997386028SDuncan P. N. Exon Smith   Metadata *Ops[] = {File,          Scope,        Name,           BaseType,
7108c59921cSAdrian Prantl                      Elements,      VTableHolder, TemplateParams, &Identifier,
71196bd4d34SAlok Kumar Sharma                      Discriminator, DataLocation, Associated,     Allocated,
7120b32dca1SYonghong Song                      Rank,          Annotations};
7131ec7dc77SSimon Pilgrim   assert((std::end(Ops) - std::begin(Ops)) == (int)CT->getNumOperands() &&
71497386028SDuncan P. N. Exon Smith          "Mismatched number of operands");
71597386028SDuncan P. N. Exon Smith   for (unsigned I = 0, E = CT->getNumOperands(); I != E; ++I)
71697386028SDuncan P. N. Exon Smith     if (Ops[I] != CT->getOperand(I))
71797386028SDuncan P. N. Exon Smith       CT->setOperand(I, Ops[I]);
71897386028SDuncan P. N. Exon Smith   return CT;
71997386028SDuncan P. N. Exon Smith }
72097386028SDuncan P. N. Exon Smith 
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,Metadata * DataLocation,Metadata * Associated,Metadata * Allocated,Metadata * Rank,Metadata * Annotations)7210b0271efSDuncan P. N. Exon Smith DICompositeType *DICompositeType::getODRType(
7220b0271efSDuncan P. N. Exon Smith     LLVMContext &Context, MDString &Identifier, unsigned Tag, MDString *Name,
7230b0271efSDuncan P. N. Exon Smith     Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType,
724197aa319SVictor Leschuk     uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
7255fcc4185SLeny Kholodov     DIFlags Flags, Metadata *Elements, unsigned RuntimeLang,
7264042ada1SAlok Kumar Sharma     Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator,
72796bd4d34SAlok Kumar Sharma     Metadata *DataLocation, Metadata *Associated, Metadata *Allocated,
7280b32dca1SYonghong Song     Metadata *Rank, Metadata *Annotations) {
7290b0271efSDuncan P. N. Exon Smith   assert(!Identifier.getString().empty() && "Expected valid identifier");
7300b0271efSDuncan P. N. Exon Smith   if (!Context.isODRUniquingDebugTypes())
7310b0271efSDuncan P. N. Exon Smith     return nullptr;
7320b0271efSDuncan P. N. Exon Smith   auto *&CT = (*Context.pImpl->DITypeMap)[&Identifier];
7337c3fa527SYuanfang Chen   if (!CT) {
7340b0271efSDuncan P. N. Exon Smith     CT = DICompositeType::getDistinct(
7350b0271efSDuncan P. N. Exon Smith         Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits,
7360b0271efSDuncan P. N. Exon Smith         AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder,
7372d10258aSAlok Kumar Sharma         TemplateParams, &Identifier, Discriminator, DataLocation, Associated,
7380b32dca1SYonghong Song         Allocated, Rank, Annotations);
7397c3fa527SYuanfang Chen   } else {
7407c3fa527SYuanfang Chen     if (CT->getTag() != Tag)
7417c3fa527SYuanfang Chen       return nullptr;
7427c3fa527SYuanfang Chen   }
7430b0271efSDuncan P. N. Exon Smith   return CT;
7440b0271efSDuncan P. N. Exon Smith }
7450b0271efSDuncan P. N. Exon Smith 
getODRTypeIfExists(LLVMContext & Context,MDString & Identifier)7460b0271efSDuncan P. N. Exon Smith DICompositeType *DICompositeType::getODRTypeIfExists(LLVMContext &Context,
7470b0271efSDuncan P. N. Exon Smith                                                      MDString &Identifier) {
7480b0271efSDuncan P. N. Exon Smith   assert(!Identifier.getString().empty() && "Expected valid identifier");
7490b0271efSDuncan P. N. Exon Smith   if (!Context.isODRUniquingDebugTypes())
7500b0271efSDuncan P. N. Exon Smith     return nullptr;
7510b0271efSDuncan P. N. Exon Smith   return Context.pImpl->DITypeMap->lookup(&Identifier);
7520b0271efSDuncan P. N. Exon Smith }
DISubroutineType(LLVMContext & C,StorageType Storage,DIFlags Flags,uint8_t CC,ArrayRef<Metadata * > Ops)753ffe8720aSserge-sans-paille DISubroutineType::DISubroutineType(LLVMContext &C, StorageType Storage,
754ffe8720aSserge-sans-paille                                    DIFlags Flags, uint8_t CC,
755ffe8720aSserge-sans-paille                                    ArrayRef<Metadata *> Ops)
756ffe8720aSserge-sans-paille     : DIType(C, DISubroutineTypeKind, Storage, dwarf::DW_TAG_subroutine_type, 0,
757ffe8720aSserge-sans-paille              0, 0, 0, Flags, Ops),
758ffe8720aSserge-sans-paille       CC(CC) {}
7590b0271efSDuncan P. N. Exon Smith 
getImpl(LLVMContext & Context,DIFlags Flags,uint8_t CC,Metadata * TypeArray,StorageType Storage,bool ShouldCreate)76040c6235bSLeny Kholodov DISubroutineType *DISubroutineType::getImpl(LLVMContext &Context, DIFlags Flags,
76140c6235bSLeny Kholodov                                             uint8_t CC, Metadata *TypeArray,
76201fc1769SDuncan P. N. Exon Smith                                             StorageType Storage,
76301fc1769SDuncan P. N. Exon Smith                                             bool ShouldCreate) {
764de3d8b50SReid Kleckner   DEFINE_GETIMPL_LOOKUP(DISubroutineType, (Flags, CC, TypeArray));
765b9e045afSDuncan P. N. Exon Smith   Metadata *Ops[] = {nullptr, nullptr, nullptr, TypeArray};
766de3d8b50SReid Kleckner   DEFINE_GETIMPL_STORE(DISubroutineType, (Flags, CC), Ops);
76701fc1769SDuncan P. N. Exon Smith }
76801fc1769SDuncan P. N. Exon Smith 
DIFile(LLVMContext & C,StorageType Storage,Optional<ChecksumInfo<MDString * >> CS,Optional<MDString * > Src,ArrayRef<Metadata * > Ops)769ffe8720aSserge-sans-paille DIFile::DIFile(LLVMContext &C, StorageType Storage,
770ffe8720aSserge-sans-paille                Optional<ChecksumInfo<MDString *>> CS, Optional<MDString *> Src,
771ffe8720aSserge-sans-paille                ArrayRef<Metadata *> Ops)
772ffe8720aSserge-sans-paille     : DIScope(C, DIFileKind, Storage, dwarf::DW_TAG_file_type, Ops),
773ffe8720aSserge-sans-paille       Checksum(CS), Source(Src) {}
774ffe8720aSserge-sans-paille 
77526fa1bf4SReid Kleckner // FIXME: Implement this string-enum correspondence with a .def file and macros,
77626fa1bf4SReid Kleckner // so that the association is explicit rather than implied.
7777160384dSScott Linder static const char *ChecksumKindName[DIFile::CSK_Last] = {
7787faeecc8SAmjad Aboud     "CSK_MD5",
7791478ed69SArlo Siemsen     "CSK_SHA1",
7801478ed69SArlo Siemsen     "CSK_SHA256",
7817faeecc8SAmjad Aboud };
7827faeecc8SAmjad Aboud 
getChecksumKindAsString(ChecksumKind CSKind)7837160384dSScott Linder StringRef DIFile::getChecksumKindAsString(ChecksumKind CSKind) {
7847160384dSScott Linder   assert(CSKind <= DIFile::CSK_Last && "Invalid checksum kind");
7857160384dSScott Linder   // The first space was originally the CSK_None variant, which is now
7867160384dSScott Linder   // obsolete, but the space is still reserved in ChecksumKind, so we account
7877160384dSScott Linder   // for it here.
7887160384dSScott Linder   return ChecksumKindName[CSKind - 1];
7897faeecc8SAmjad Aboud }
7907faeecc8SAmjad Aboud 
getChecksumKind(StringRef CSKindStr)7917160384dSScott Linder Optional<DIFile::ChecksumKind> DIFile::getChecksumKind(StringRef CSKindStr) {
7927160384dSScott Linder   return StringSwitch<Optional<DIFile::ChecksumKind>>(CSKindStr)
7937160384dSScott Linder       .Case("CSK_MD5", DIFile::CSK_MD5)
7947160384dSScott Linder       .Case("CSK_SHA1", DIFile::CSK_SHA1)
7951478ed69SArlo Siemsen       .Case("CSK_SHA256", DIFile::CSK_SHA256)
7967160384dSScott Linder       .Default(None);
7977faeecc8SAmjad Aboud }
7987faeecc8SAmjad Aboud 
getImpl(LLVMContext & Context,MDString * Filename,MDString * Directory,Optional<DIFile::ChecksumInfo<MDString * >> CS,Optional<MDString * > Source,StorageType Storage,bool ShouldCreate)799a9308c49SDuncan P. N. Exon Smith DIFile *DIFile::getImpl(LLVMContext &Context, MDString *Filename,
8007160384dSScott Linder                         MDString *Directory,
8017160384dSScott Linder                         Optional<DIFile::ChecksumInfo<MDString *>> CS,
80216c7bdafSScott Linder                         Optional<MDString *> Source, StorageType Storage,
80316c7bdafSScott Linder                         bool ShouldCreate) {
80401fc1769SDuncan P. N. Exon Smith   assert(isCanonical(Filename) && "Expected canonical MDString");
80501fc1769SDuncan P. N. Exon Smith   assert(isCanonical(Directory) && "Expected canonical MDString");
8067160384dSScott Linder   assert((!CS || isCanonical(CS->Value)) && "Expected canonical MDString");
80716c7bdafSScott Linder   assert((!Source || isCanonical(*Source)) && "Expected canonical MDString");
80816c7bdafSScott Linder   DEFINE_GETIMPL_LOOKUP(DIFile, (Filename, Directory, CS, Source));
80916c7bdafSScott Linder   Metadata *Ops[] = {Filename, Directory, CS ? CS->Value : nullptr,
810129b531cSKazu Hirata                      Source.value_or(nullptr)};
81116c7bdafSScott Linder   DEFINE_GETIMPL_STORE(DIFile, (CS, Source), Ops);
81201fc1769SDuncan P. N. Exon Smith }
DICompileUnit(LLVMContext & C,StorageType Storage,unsigned SourceLanguage,bool IsOptimized,unsigned RuntimeVersion,unsigned EmissionKind,uint64_t DWOId,bool SplitDebugInlining,bool DebugInfoForProfiling,unsigned NameTableKind,bool RangesBaseAddress,ArrayRef<Metadata * > Ops)813ffe8720aSserge-sans-paille DICompileUnit::DICompileUnit(LLVMContext &C, StorageType Storage,
814ffe8720aSserge-sans-paille                              unsigned SourceLanguage, bool IsOptimized,
815ffe8720aSserge-sans-paille                              unsigned RuntimeVersion, unsigned EmissionKind,
816ffe8720aSserge-sans-paille                              uint64_t DWOId, bool SplitDebugInlining,
817ffe8720aSserge-sans-paille                              bool DebugInfoForProfiling, unsigned NameTableKind,
818ffe8720aSserge-sans-paille                              bool RangesBaseAddress, ArrayRef<Metadata *> Ops)
819ffe8720aSserge-sans-paille     : DIScope(C, DICompileUnitKind, Storage, dwarf::DW_TAG_compile_unit, Ops),
820ffe8720aSserge-sans-paille       SourceLanguage(SourceLanguage), IsOptimized(IsOptimized),
821ffe8720aSserge-sans-paille       RuntimeVersion(RuntimeVersion), EmissionKind(EmissionKind), DWOId(DWOId),
822ffe8720aSserge-sans-paille       SplitDebugInlining(SplitDebugInlining),
823ffe8720aSserge-sans-paille       DebugInfoForProfiling(DebugInfoForProfiling),
824ffe8720aSserge-sans-paille       NameTableKind(NameTableKind), RangesBaseAddress(RangesBaseAddress) {
825ffe8720aSserge-sans-paille   assert(Storage != Uniqued);
826ffe8720aSserge-sans-paille }
82701fc1769SDuncan P. N. Exon Smith 
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,MDString * SysRoot,MDString * SDK,StorageType Storage,bool ShouldCreate)828a9308c49SDuncan P. N. Exon Smith DICompileUnit *DICompileUnit::getImpl(
82901fc1769SDuncan P. N. Exon Smith     LLVMContext &Context, unsigned SourceLanguage, Metadata *File,
83001fc1769SDuncan P. N. Exon Smith     MDString *Producer, bool IsOptimized, MDString *Flags,
83101fc1769SDuncan P. N. Exon Smith     unsigned RuntimeVersion, MDString *SplitDebugFilename,
83201fc1769SDuncan P. N. Exon Smith     unsigned EmissionKind, Metadata *EnumTypes, Metadata *RetainedTypes,
83375819aedSAdrian Prantl     Metadata *GlobalVariables, Metadata *ImportedEntities, Metadata *Macros,
8340944a8c2SDehao Chen     uint64_t DWOId, bool SplitDebugInlining, bool DebugInfoForProfiling,
8357b30370eSAdrian Prantl     unsigned NameTableKind, bool RangesBaseAddress, MDString *SysRoot,
836e4e7e447SAdrian Prantl     MDString *SDK, StorageType Storage, bool ShouldCreate) {
83755ca964eSDuncan P. N. Exon Smith   assert(Storage != Uniqued && "Cannot unique DICompileUnit");
83801fc1769SDuncan P. N. Exon Smith   assert(isCanonical(Producer) && "Expected canonical MDString");
83901fc1769SDuncan P. N. Exon Smith   assert(isCanonical(Flags) && "Expected canonical MDString");
84001fc1769SDuncan P. N. Exon Smith   assert(isCanonical(SplitDebugFilename) && "Expected canonical MDString");
84155ca964eSDuncan P. N. Exon Smith 
842e4e7e447SAdrian Prantl   Metadata *Ops[] = {File,
843e4e7e447SAdrian Prantl                      Producer,
844e4e7e447SAdrian Prantl                      Flags,
845e4e7e447SAdrian Prantl                      SplitDebugFilename,
846e4e7e447SAdrian Prantl                      EnumTypes,
847e4e7e447SAdrian Prantl                      RetainedTypes,
848e4e7e447SAdrian Prantl                      GlobalVariables,
849e4e7e447SAdrian Prantl                      ImportedEntities,
850e4e7e447SAdrian Prantl                      Macros,
851e4e7e447SAdrian Prantl                      SysRoot,
852e4e7e447SAdrian Prantl                      SDK};
8532740c187SWolfgang Pieb   return storeImpl(new (array_lengthof(Ops), Storage) DICompileUnit(
854b52e2366SPeter Collingbourne                        Context, Storage, SourceLanguage, IsOptimized,
855b52e2366SPeter Collingbourne                        RuntimeVersion, EmissionKind, DWOId, SplitDebugInlining,
856bb279116SDavid Blaikie                        DebugInfoForProfiling, NameTableKind, RangesBaseAddress,
857bb279116SDavid Blaikie                        Ops),
85855ca964eSDuncan P. N. Exon Smith                    Storage);
85901fc1769SDuncan P. N. Exon Smith }
86001fc1769SDuncan P. N. Exon Smith 
861b939a257SAdrian Prantl Optional<DICompileUnit::DebugEmissionKind>
getEmissionKind(StringRef Str)862b939a257SAdrian Prantl DICompileUnit::getEmissionKind(StringRef Str) {
863b939a257SAdrian Prantl   return StringSwitch<Optional<DebugEmissionKind>>(Str)
864b939a257SAdrian Prantl       .Case("NoDebug", NoDebug)
865b939a257SAdrian Prantl       .Case("FullDebug", FullDebug)
866b939a257SAdrian Prantl       .Case("LineTablesOnly", LineTablesOnly)
867d4dd7215SAlexey Bataev       .Case("DebugDirectivesOnly", DebugDirectivesOnly)
868b939a257SAdrian Prantl       .Default(None);
869b939a257SAdrian Prantl }
870b939a257SAdrian Prantl 
87166cf14d0SDavid Blaikie Optional<DICompileUnit::DebugNameTableKind>
getNameTableKind(StringRef Str)87266cf14d0SDavid Blaikie DICompileUnit::getNameTableKind(StringRef Str) {
87366cf14d0SDavid Blaikie   return StringSwitch<Optional<DebugNameTableKind>>(Str)
87466cf14d0SDavid Blaikie       .Case("Default", DebugNameTableKind::Default)
87566cf14d0SDavid Blaikie       .Case("GNU", DebugNameTableKind::GNU)
87666cf14d0SDavid Blaikie       .Case("None", DebugNameTableKind::None)
87766cf14d0SDavid Blaikie       .Default(None);
87866cf14d0SDavid Blaikie }
87966cf14d0SDavid Blaikie 
emissionKindString(DebugEmissionKind EK)8803c1b5dbbSFangrui Song const char *DICompileUnit::emissionKindString(DebugEmissionKind EK) {
881b939a257SAdrian Prantl   switch (EK) {
882665b4138SLuís Ferreira   case NoDebug:
883665b4138SLuís Ferreira     return "NoDebug";
884665b4138SLuís Ferreira   case FullDebug:
885665b4138SLuís Ferreira     return "FullDebug";
886665b4138SLuís Ferreira   case LineTablesOnly:
887665b4138SLuís Ferreira     return "LineTablesOnly";
888665b4138SLuís Ferreira   case DebugDirectivesOnly:
889665b4138SLuís Ferreira     return "DebugDirectivesOnly";
890b939a257SAdrian Prantl   }
891b939a257SAdrian Prantl   return nullptr;
892b939a257SAdrian Prantl }
893b939a257SAdrian Prantl 
nameTableKindString(DebugNameTableKind NTK)89466cf14d0SDavid Blaikie const char *DICompileUnit::nameTableKindString(DebugNameTableKind NTK) {
89566cf14d0SDavid Blaikie   switch (NTK) {
89666cf14d0SDavid Blaikie   case DebugNameTableKind::Default:
89766cf14d0SDavid Blaikie     return nullptr;
89866cf14d0SDavid Blaikie   case DebugNameTableKind::GNU:
89966cf14d0SDavid Blaikie     return "GNU";
90066cf14d0SDavid Blaikie   case DebugNameTableKind::None:
90166cf14d0SDavid Blaikie     return "None";
90266cf14d0SDavid Blaikie   }
90366cf14d0SDavid Blaikie   return nullptr;
90466cf14d0SDavid Blaikie }
DISubprogram(LLVMContext & C,StorageType Storage,unsigned Line,unsigned ScopeLine,unsigned VirtualIndex,int ThisAdjustment,DIFlags Flags,DISPFlags SPFlags,ArrayRef<Metadata * > Ops)905ffe8720aSserge-sans-paille DISubprogram::DISubprogram(LLVMContext &C, StorageType Storage, unsigned Line,
906ffe8720aSserge-sans-paille                            unsigned ScopeLine, unsigned VirtualIndex,
907ffe8720aSserge-sans-paille                            int ThisAdjustment, DIFlags Flags, DISPFlags SPFlags,
908ffe8720aSserge-sans-paille                            ArrayRef<Metadata *> Ops)
909ffe8720aSserge-sans-paille     : DILocalScope(C, DISubprogramKind, Storage, dwarf::DW_TAG_subprogram, Ops),
910ffe8720aSserge-sans-paille       Line(Line), ScopeLine(ScopeLine), VirtualIndex(VirtualIndex),
911ffe8720aSserge-sans-paille       ThisAdjustment(ThisAdjustment), Flags(Flags), SPFlags(SPFlags) {
912ffe8720aSserge-sans-paille   static_assert(dwarf::DW_VIRTUALITY_max < 4, "Virtuality out of range");
913ffe8720aSserge-sans-paille }
914ffe8720aSserge-sans-paille DISubprogram::DISPFlags
toSPFlags(bool IsLocalToUnit,bool IsDefinition,bool IsOptimized,unsigned Virtuality,bool IsMainSubprogram)915ffe8720aSserge-sans-paille DISubprogram::toSPFlags(bool IsLocalToUnit, bool IsDefinition, bool IsOptimized,
916ffe8720aSserge-sans-paille                         unsigned Virtuality, bool IsMainSubprogram) {
917ffe8720aSserge-sans-paille   // We're assuming virtuality is the low-order field.
918ffe8720aSserge-sans-paille   static_assert(int(SPFlagVirtual) == int(dwarf::DW_VIRTUALITY_virtual) &&
919ffe8720aSserge-sans-paille                     int(SPFlagPureVirtual) ==
920ffe8720aSserge-sans-paille                         int(dwarf::DW_VIRTUALITY_pure_virtual),
921ffe8720aSserge-sans-paille                 "Virtuality constant mismatch");
922ffe8720aSserge-sans-paille   return static_cast<DISPFlags>(
923ffe8720aSserge-sans-paille       (Virtuality & SPFlagVirtuality) |
924ffe8720aSserge-sans-paille       (IsLocalToUnit ? SPFlagLocalToUnit : SPFlagZero) |
925ffe8720aSserge-sans-paille       (IsDefinition ? SPFlagDefinition : SPFlagZero) |
926ffe8720aSserge-sans-paille       (IsOptimized ? SPFlagOptimized : SPFlagZero) |
927ffe8720aSserge-sans-paille       (IsMainSubprogram ? SPFlagMainSubprogram : SPFlagZero));
928ffe8720aSserge-sans-paille }
92966cf14d0SDavid Blaikie 
getSubprogram() const930a9308c49SDuncan P. N. Exon Smith DISubprogram *DILocalScope::getSubprogram() const {
931a9308c49SDuncan P. N. Exon Smith   if (auto *Block = dyn_cast<DILexicalBlockBase>(this))
932fd07a2afSDuncan P. N. Exon Smith     return Block->getScope()->getSubprogram();
933a9308c49SDuncan P. N. Exon Smith   return const_cast<DISubprogram *>(cast<DISubprogram>(this));
934fd07a2afSDuncan P. N. Exon Smith }
935fd07a2afSDuncan P. N. Exon Smith 
getNonLexicalBlockFileScope() const936a5ba9914SAmjad Aboud DILocalScope *DILocalScope::getNonLexicalBlockFileScope() const {
937a5ba9914SAmjad Aboud   if (auto *File = dyn_cast<DILexicalBlockFile>(this))
938a5ba9914SAmjad Aboud     return File->getScope()->getNonLexicalBlockFileScope();
939a5ba9914SAmjad Aboud   return const_cast<DILocalScope *>(this);
940a5ba9914SAmjad Aboud }
941a5ba9914SAmjad Aboud 
getFlag(StringRef Flag)942adcdc1bdSPaul Robinson DISubprogram::DISPFlags DISubprogram::getFlag(StringRef Flag) {
943adcdc1bdSPaul Robinson   return StringSwitch<DISPFlags>(Flag)
944adcdc1bdSPaul Robinson #define HANDLE_DISP_FLAG(ID, NAME) .Case("DISPFlag" #NAME, SPFlag##NAME)
945adcdc1bdSPaul Robinson #include "llvm/IR/DebugInfoFlags.def"
946adcdc1bdSPaul Robinson       .Default(SPFlagZero);
947adcdc1bdSPaul Robinson }
948adcdc1bdSPaul Robinson 
getFlagString(DISPFlags Flag)949adcdc1bdSPaul Robinson StringRef DISubprogram::getFlagString(DISPFlags Flag) {
950adcdc1bdSPaul Robinson   switch (Flag) {
95149f51bccSPaul Robinson   // Appease a warning.
95249f51bccSPaul Robinson   case SPFlagVirtuality:
953adcdc1bdSPaul Robinson     return "";
954adcdc1bdSPaul Robinson #define HANDLE_DISP_FLAG(ID, NAME)                                             \
955adcdc1bdSPaul Robinson   case SPFlag##NAME:                                                           \
956adcdc1bdSPaul Robinson     return "DISPFlag" #NAME;
957adcdc1bdSPaul Robinson #include "llvm/IR/DebugInfoFlags.def"
958adcdc1bdSPaul Robinson   }
959adcdc1bdSPaul Robinson   return "";
960adcdc1bdSPaul Robinson }
961adcdc1bdSPaul Robinson 
962adcdc1bdSPaul Robinson DISubprogram::DISPFlags
splitFlags(DISPFlags Flags,SmallVectorImpl<DISPFlags> & SplitFlags)963adcdc1bdSPaul Robinson DISubprogram::splitFlags(DISPFlags Flags,
964adcdc1bdSPaul Robinson                          SmallVectorImpl<DISPFlags> &SplitFlags) {
965adcdc1bdSPaul Robinson   // Multi-bit fields can require special handling. In our case, however, the
966adcdc1bdSPaul Robinson   // only multi-bit field is virtuality, and all its values happen to be
967adcdc1bdSPaul Robinson   // single-bit values, so the right behavior just falls out.
968adcdc1bdSPaul Robinson #define HANDLE_DISP_FLAG(ID, NAME)                                             \
969adcdc1bdSPaul Robinson   if (DISPFlags Bit = Flags & SPFlag##NAME) {                                  \
970adcdc1bdSPaul Robinson     SplitFlags.push_back(Bit);                                                 \
971adcdc1bdSPaul Robinson     Flags &= ~Bit;                                                             \
972adcdc1bdSPaul Robinson   }
973adcdc1bdSPaul Robinson #include "llvm/IR/DebugInfoFlags.def"
974adcdc1bdSPaul Robinson   return Flags;
975adcdc1bdSPaul Robinson }
976adcdc1bdSPaul Robinson 
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,Metadata * Annotations,MDString * TargetFuncName,StorageType Storage,bool ShouldCreate)977a9308c49SDuncan P. N. Exon Smith DISubprogram *DISubprogram::getImpl(
97801fc1769SDuncan P. N. Exon Smith     LLVMContext &Context, Metadata *Scope, MDString *Name,
97901fc1769SDuncan P. N. Exon Smith     MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type,
980cda54210SPaul Robinson     unsigned ScopeLine, Metadata *ContainingType, unsigned VirtualIndex,
981cda54210SPaul Robinson     int ThisAdjustment, DIFlags Flags, DISPFlags SPFlags, Metadata *Unit,
9822c864551SShiva Chen     Metadata *TemplateParams, Metadata *Declaration, Metadata *RetainedNodes,
983eab6e94fSChih-Ping Chen     Metadata *ThrownTypes, Metadata *Annotations, MDString *TargetFuncName,
984eab6e94fSChih-Ping Chen     StorageType Storage, bool ShouldCreate) {
98501fc1769SDuncan P. N. Exon Smith   assert(isCanonical(Name) && "Expected canonical MDString");
98601fc1769SDuncan P. N. Exon Smith   assert(isCanonical(LinkageName) && "Expected canonical MDString");
987eab6e94fSChih-Ping Chen   assert(isCanonical(TargetFuncName) && "Expected canonical MDString");
988cda54210SPaul Robinson   DEFINE_GETIMPL_LOOKUP(DISubprogram,
989cda54210SPaul Robinson                         (Scope, Name, LinkageName, File, Line, Type, ScopeLine,
990cda54210SPaul Robinson                          ContainingType, VirtualIndex, ThisAdjustment, Flags,
991cda54210SPaul Robinson                          SPFlags, Unit, TemplateParams, Declaration,
992eab6e94fSChih-Ping Chen                          RetainedNodes, ThrownTypes, Annotations,
993eab6e94fSChih-Ping Chen                          TargetFuncName));
994eab6e94fSChih-Ping Chen   SmallVector<Metadata *, 13> Ops = {
995665b4138SLuís Ferreira       File,           Scope,          Name,        LinkageName,
996665b4138SLuís Ferreira       Type,           Unit,           Declaration, RetainedNodes,
997eab6e94fSChih-Ping Chen       ContainingType, TemplateParams, ThrownTypes, Annotations,
998eab6e94fSChih-Ping Chen       TargetFuncName};
999eab6e94fSChih-Ping Chen   if (!TargetFuncName) {
1000eab6e94fSChih-Ping Chen     Ops.pop_back();
1001d383df32SYonghong Song     if (!Annotations) {
1002d383df32SYonghong Song       Ops.pop_back();
10039d2f019fSAdrian Prantl       if (!ThrownTypes) {
10049d2f019fSAdrian Prantl         Ops.pop_back();
10059d2f019fSAdrian Prantl         if (!TemplateParams) {
10069d2f019fSAdrian Prantl           Ops.pop_back();
10079d2f019fSAdrian Prantl           if (!ContainingType)
10089d2f019fSAdrian Prantl             Ops.pop_back();
10099d2f019fSAdrian Prantl         }
10109d2f019fSAdrian Prantl       }
1011d383df32SYonghong Song     }
1012eab6e94fSChih-Ping Chen   }
1013cda54210SPaul Robinson   DEFINE_GETIMPL_STORE_N(
1014cda54210SPaul Robinson       DISubprogram,
1015cda54210SPaul Robinson       (Line, ScopeLine, VirtualIndex, ThisAdjustment, Flags, SPFlags), Ops,
1016cda54210SPaul Robinson       Ops.size());
101701fc1769SDuncan P. N. Exon Smith }
101801fc1769SDuncan P. N. Exon Smith 
describes(const Function * F) const1019a9308c49SDuncan P. N. Exon Smith bool DISubprogram::describes(const Function *F) const {
10203c2d7043SDuncan P. N. Exon Smith   assert(F && "Invalid function");
10215c83bedeSAdrian Prantl   return F->getSubprogram() == this;
10223c2d7043SDuncan P. N. Exon Smith }
DILexicalBlockBase(LLVMContext & C,unsigned ID,StorageType Storage,ArrayRef<Metadata * > Ops)1023ffe8720aSserge-sans-paille DILexicalBlockBase::DILexicalBlockBase(LLVMContext &C, unsigned ID,
1024ffe8720aSserge-sans-paille                                        StorageType Storage,
1025ffe8720aSserge-sans-paille                                        ArrayRef<Metadata *> Ops)
1026ffe8720aSserge-sans-paille     : DILocalScope(C, ID, Storage, dwarf::DW_TAG_lexical_block, Ops) {}
10273c2d7043SDuncan P. N. Exon Smith 
getImpl(LLVMContext & Context,Metadata * Scope,Metadata * File,unsigned Line,unsigned Column,StorageType Storage,bool ShouldCreate)1028a9308c49SDuncan P. N. Exon Smith DILexicalBlock *DILexicalBlock::getImpl(LLVMContext &Context, Metadata *Scope,
102901fc1769SDuncan P. N. Exon Smith                                         Metadata *File, unsigned Line,
103001fc1769SDuncan P. N. Exon Smith                                         unsigned Column, StorageType Storage,
103101fc1769SDuncan P. N. Exon Smith                                         bool ShouldCreate) {
1032b09eb9f1SDuncan P. N. Exon Smith   // Fixup column.
1033b09eb9f1SDuncan P. N. Exon Smith   adjustColumn(Column);
1034b09eb9f1SDuncan P. N. Exon Smith 
10350e202b95SDuncan P. N. Exon Smith   assert(Scope && "Expected scope");
1036a9308c49SDuncan P. N. Exon Smith   DEFINE_GETIMPL_LOOKUP(DILexicalBlock, (Scope, File, Line, Column));
103701fc1769SDuncan P. N. Exon Smith   Metadata *Ops[] = {File, Scope};
1038a9308c49SDuncan P. N. Exon Smith   DEFINE_GETIMPL_STORE(DILexicalBlock, (Line, Column), Ops);
103901fc1769SDuncan P. N. Exon Smith }
104001fc1769SDuncan P. N. Exon Smith 
getImpl(LLVMContext & Context,Metadata * Scope,Metadata * File,unsigned Discriminator,StorageType Storage,bool ShouldCreate)1041a9308c49SDuncan P. N. Exon Smith DILexicalBlockFile *DILexicalBlockFile::getImpl(LLVMContext &Context,
104201fc1769SDuncan P. N. Exon Smith                                                 Metadata *Scope, Metadata *File,
104301fc1769SDuncan P. N. Exon Smith                                                 unsigned Discriminator,
104401fc1769SDuncan P. N. Exon Smith                                                 StorageType Storage,
104501fc1769SDuncan P. N. Exon Smith                                                 bool ShouldCreate) {
10460e202b95SDuncan P. N. Exon Smith   assert(Scope && "Expected scope");
1047a9308c49SDuncan P. N. Exon Smith   DEFINE_GETIMPL_LOOKUP(DILexicalBlockFile, (Scope, File, Discriminator));
104801fc1769SDuncan P. N. Exon Smith   Metadata *Ops[] = {File, Scope};
1049a9308c49SDuncan P. N. Exon Smith   DEFINE_GETIMPL_STORE(DILexicalBlockFile, (Discriminator), Ops);
105001fc1769SDuncan P. N. Exon Smith }
105101fc1769SDuncan P. N. Exon Smith 
DINamespace(LLVMContext & Context,StorageType Storage,bool ExportSymbols,ArrayRef<Metadata * > Ops)1052ffe8720aSserge-sans-paille DINamespace::DINamespace(LLVMContext &Context, StorageType Storage,
1053ffe8720aSserge-sans-paille                          bool ExportSymbols, ArrayRef<Metadata *> Ops)
1054ffe8720aSserge-sans-paille     : DIScope(Context, DINamespaceKind, Storage, dwarf::DW_TAG_namespace, Ops),
1055ffe8720aSserge-sans-paille       ExportSymbols(ExportSymbols) {}
getImpl(LLVMContext & Context,Metadata * Scope,MDString * Name,bool ExportSymbols,StorageType Storage,bool ShouldCreate)1056a9308c49SDuncan P. N. Exon Smith DINamespace *DINamespace::getImpl(LLVMContext &Context, Metadata *Scope,
1057fed4f399SAdrian Prantl                                   MDString *Name, bool ExportSymbols,
1058fed4f399SAdrian Prantl                                   StorageType Storage, bool ShouldCreate) {
105901fc1769SDuncan P. N. Exon Smith   assert(isCanonical(Name) && "Expected canonical MDString");
1060fed4f399SAdrian Prantl   DEFINE_GETIMPL_LOOKUP(DINamespace, (Scope, Name, ExportSymbols));
1061fed4f399SAdrian Prantl   // The nullptr is for DIScope's File operand. This should be refactored.
1062fed4f399SAdrian Prantl   Metadata *Ops[] = {nullptr, Scope, Name};
1063fed4f399SAdrian Prantl   DEFINE_GETIMPL_STORE(DINamespace, (ExportSymbols), Ops);
106401fc1769SDuncan P. N. Exon Smith }
106501fc1769SDuncan P. N. Exon Smith 
DICommonBlock(LLVMContext & Context,StorageType Storage,unsigned LineNo,ArrayRef<Metadata * > Ops)1066ffe8720aSserge-sans-paille DICommonBlock::DICommonBlock(LLVMContext &Context, StorageType Storage,
1067ffe8720aSserge-sans-paille                              unsigned LineNo, ArrayRef<Metadata *> Ops)
1068ffe8720aSserge-sans-paille     : DIScope(Context, DICommonBlockKind, Storage, dwarf::DW_TAG_common_block,
1069ffe8720aSserge-sans-paille               Ops),
1070ffe8720aSserge-sans-paille       LineNo(LineNo) {}
getImpl(LLVMContext & Context,Metadata * Scope,Metadata * Decl,MDString * Name,Metadata * File,unsigned LineNo,StorageType Storage,bool ShouldCreate)10716ed5706aSAdrian Prantl DICommonBlock *DICommonBlock::getImpl(LLVMContext &Context, Metadata *Scope,
10726ed5706aSAdrian Prantl                                       Metadata *Decl, MDString *Name,
10736ed5706aSAdrian Prantl                                       Metadata *File, unsigned LineNo,
10746ed5706aSAdrian Prantl                                       StorageType Storage, bool ShouldCreate) {
10756ed5706aSAdrian Prantl   assert(isCanonical(Name) && "Expected canonical MDString");
10766ed5706aSAdrian Prantl   DEFINE_GETIMPL_LOOKUP(DICommonBlock, (Scope, Decl, Name, File, LineNo));
10776ed5706aSAdrian Prantl   // The nullptr is for DIScope's File operand. This should be refactored.
10786ed5706aSAdrian Prantl   Metadata *Ops[] = {Scope, Decl, Name, File};
10796ed5706aSAdrian Prantl   DEFINE_GETIMPL_STORE(DICommonBlock, (LineNo), Ops);
10806ed5706aSAdrian Prantl }
10816ed5706aSAdrian Prantl 
DIModule(LLVMContext & Context,StorageType Storage,unsigned LineNo,bool IsDecl,ArrayRef<Metadata * > Ops)1082ffe8720aSserge-sans-paille DIModule::DIModule(LLVMContext &Context, StorageType Storage, unsigned LineNo,
1083ffe8720aSserge-sans-paille                    bool IsDecl, ArrayRef<Metadata *> Ops)
1084ffe8720aSserge-sans-paille     : DIScope(Context, DIModuleKind, Storage, dwarf::DW_TAG_module, Ops),
1085ffe8720aSserge-sans-paille       LineNo(LineNo), IsDecl(IsDecl) {}
getImpl(LLVMContext & Context,Metadata * File,Metadata * Scope,MDString * Name,MDString * ConfigurationMacros,MDString * IncludePath,MDString * APINotesFile,unsigned LineNo,bool IsDecl,StorageType Storage,bool ShouldCreate)1086e59744fdSSourabh Singh Tomar DIModule *DIModule::getImpl(LLVMContext &Context, Metadata *File,
1087e59744fdSSourabh Singh Tomar                             Metadata *Scope, MDString *Name,
1088e59744fdSSourabh Singh Tomar                             MDString *ConfigurationMacros,
1089d5180ea1SAdrian Prantl                             MDString *IncludePath, MDString *APINotesFile,
10905f75dcf5SChih-Ping Chen                             unsigned LineNo, bool IsDecl, StorageType Storage,
1091e59744fdSSourabh Singh Tomar                             bool ShouldCreate) {
1092ab1243feSAdrian Prantl   assert(isCanonical(Name) && "Expected canonical MDString");
1093e59744fdSSourabh Singh Tomar   DEFINE_GETIMPL_LOOKUP(DIModule, (File, Scope, Name, ConfigurationMacros,
10945f75dcf5SChih-Ping Chen                                    IncludePath, APINotesFile, LineNo, IsDecl));
1095e59744fdSSourabh Singh Tomar   Metadata *Ops[] = {File,        Scope,       Name, ConfigurationMacros,
1096e59744fdSSourabh Singh Tomar                      IncludePath, APINotesFile};
10975f75dcf5SChih-Ping Chen   DEFINE_GETIMPL_STORE(DIModule, (LineNo, IsDecl), Ops);
1098ab1243feSAdrian Prantl }
DITemplateTypeParameter(LLVMContext & Context,StorageType Storage,bool IsDefault,ArrayRef<Metadata * > Ops)1099ffe8720aSserge-sans-paille DITemplateTypeParameter::DITemplateTypeParameter(LLVMContext &Context,
1100ffe8720aSserge-sans-paille                                                  StorageType Storage,
1101ffe8720aSserge-sans-paille                                                  bool IsDefault,
1102ffe8720aSserge-sans-paille                                                  ArrayRef<Metadata *> Ops)
1103ffe8720aSserge-sans-paille     : DITemplateParameter(Context, DITemplateTypeParameterKind, Storage,
1104ffe8720aSserge-sans-paille                           dwarf::DW_TAG_template_type_parameter, IsDefault,
1105ffe8720aSserge-sans-paille                           Ops) {}
1106ab1243feSAdrian Prantl 
11077a42babeSAwanish Pandey DITemplateTypeParameter *
getImpl(LLVMContext & Context,MDString * Name,Metadata * Type,bool isDefault,StorageType Storage,bool ShouldCreate)11087a42babeSAwanish Pandey DITemplateTypeParameter::getImpl(LLVMContext &Context, MDString *Name,
11097a42babeSAwanish Pandey                                  Metadata *Type, bool isDefault,
11107a42babeSAwanish Pandey                                  StorageType Storage, bool ShouldCreate) {
111101fc1769SDuncan P. N. Exon Smith   assert(isCanonical(Name) && "Expected canonical MDString");
11127a42babeSAwanish Pandey   DEFINE_GETIMPL_LOOKUP(DITemplateTypeParameter, (Name, Type, isDefault));
11133d62bbacSDuncan P. N. Exon Smith   Metadata *Ops[] = {Name, Type};
11147a42babeSAwanish Pandey   DEFINE_GETIMPL_STORE(DITemplateTypeParameter, (isDefault), Ops);
111501fc1769SDuncan P. N. Exon Smith }
111601fc1769SDuncan P. N. Exon Smith 
getImpl(LLVMContext & Context,unsigned Tag,MDString * Name,Metadata * Type,bool isDefault,Metadata * Value,StorageType Storage,bool ShouldCreate)1117a9308c49SDuncan P. N. Exon Smith DITemplateValueParameter *DITemplateValueParameter::getImpl(
11183d62bbacSDuncan P. N. Exon Smith     LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *Type,
11197a42babeSAwanish Pandey     bool isDefault, Metadata *Value, StorageType Storage, bool ShouldCreate) {
112001fc1769SDuncan P. N. Exon Smith   assert(isCanonical(Name) && "Expected canonical MDString");
11217a42babeSAwanish Pandey   DEFINE_GETIMPL_LOOKUP(DITemplateValueParameter,
11227a42babeSAwanish Pandey                         (Tag, Name, Type, isDefault, Value));
11233d62bbacSDuncan P. N. Exon Smith   Metadata *Ops[] = {Name, Type, Value};
11247a42babeSAwanish Pandey   DEFINE_GETIMPL_STORE(DITemplateValueParameter, (Tag, isDefault), Ops);
112501fc1769SDuncan P. N. Exon Smith }
112601fc1769SDuncan P. N. Exon Smith 
1127a9308c49SDuncan P. N. Exon Smith 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,Metadata * Annotations,StorageType Storage,bool ShouldCreate)1128a9308c49SDuncan P. N. Exon Smith DIGlobalVariable::getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
112901fc1769SDuncan P. N. Exon Smith                           MDString *LinkageName, Metadata *File, unsigned Line,
113001fc1769SDuncan P. N. Exon Smith                           Metadata *Type, bool IsLocalToUnit, bool IsDefinition,
113101fc1769SDuncan P. N. Exon Smith                           Metadata *StaticDataMemberDeclaration,
1132f8ab35a4SMatthew Voss                           Metadata *TemplateParams, uint32_t AlignInBits,
113330c28848SYonghong Song                           Metadata *Annotations, StorageType Storage,
113430c28848SYonghong Song                           bool ShouldCreate) {
113501fc1769SDuncan P. N. Exon Smith   assert(isCanonical(Name) && "Expected canonical MDString");
113601fc1769SDuncan P. N. Exon Smith   assert(isCanonical(LinkageName) && "Expected canonical MDString");
1137665b4138SLuís Ferreira   DEFINE_GETIMPL_LOOKUP(
1138665b4138SLuís Ferreira       DIGlobalVariable,
1139665b4138SLuís Ferreira       (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition,
1140665b4138SLuís Ferreira        StaticDataMemberDeclaration, TemplateParams, AlignInBits, Annotations));
1141f8ab35a4SMatthew Voss   Metadata *Ops[] = {Scope,
1142f8ab35a4SMatthew Voss                      Name,
1143f8ab35a4SMatthew Voss                      File,
1144f8ab35a4SMatthew Voss                      Type,
1145f8ab35a4SMatthew Voss                      Name,
1146f8ab35a4SMatthew Voss                      LinkageName,
1147f8ab35a4SMatthew Voss                      StaticDataMemberDeclaration,
114830c28848SYonghong Song                      TemplateParams,
114930c28848SYonghong Song                      Annotations};
11502ede126bSVictor Leschuk   DEFINE_GETIMPL_STORE(DIGlobalVariable,
1151f8ab35a4SMatthew Voss                        (Line, IsLocalToUnit, IsDefinition, AlignInBits), Ops);
115201fc1769SDuncan P. N. Exon Smith }
115301fc1769SDuncan P. N. Exon Smith 
1154665b4138SLuís Ferreira DILocalVariable *
getImpl(LLVMContext & Context,Metadata * Scope,MDString * Name,Metadata * File,unsigned Line,Metadata * Type,unsigned Arg,DIFlags Flags,uint32_t AlignInBits,Metadata * Annotations,StorageType Storage,bool ShouldCreate)1155665b4138SLuís Ferreira DILocalVariable::getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
1156665b4138SLuís Ferreira                          Metadata *File, unsigned Line, Metadata *Type,
1157665b4138SLuís Ferreira                          unsigned Arg, DIFlags Flags, uint32_t AlignInBits,
1158665b4138SLuís Ferreira                          Metadata *Annotations, StorageType Storage,
115962e0f454SDuncan P. N. Exon Smith                          bool ShouldCreate) {
11601ec75ae9SDuncan P. N. Exon Smith   // 64K ought to be enough for any frontend.
11611ec75ae9SDuncan P. N. Exon Smith   assert(Arg <= UINT16_MAX && "Expected argument number to fit in 16-bits");
116272fe2d0bSDuncan P. N. Exon Smith 
1163e2c61d9eSDuncan P. N. Exon Smith   assert(Scope && "Expected scope");
116401fc1769SDuncan P. N. Exon Smith   assert(isCanonical(Name) && "Expected canonical MDString");
1165665b4138SLuís Ferreira   DEFINE_GETIMPL_LOOKUP(DILocalVariable, (Scope, Name, File, Line, Type, Arg,
1166665b4138SLuís Ferreira                                           Flags, AlignInBits, Annotations));
11671bebc31cSYonghong Song   Metadata *Ops[] = {Scope, Name, File, Type, Annotations};
11682ede126bSVictor Leschuk   DEFINE_GETIMPL_STORE(DILocalVariable, (Line, Arg, Flags, AlignInBits), Ops);
116901fc1769SDuncan P. N. Exon Smith }
117001fc1769SDuncan P. N. Exon Smith 
DIVariable(LLVMContext & C,unsigned ID,StorageType Storage,signed Line,ArrayRef<Metadata * > Ops,uint32_t AlignInBits)1171ffe8720aSserge-sans-paille DIVariable::DIVariable(LLVMContext &C, unsigned ID, StorageType Storage,
1172ffe8720aSserge-sans-paille                        signed Line, ArrayRef<Metadata *> Ops,
1173ffe8720aSserge-sans-paille                        uint32_t AlignInBits)
1174ffe8720aSserge-sans-paille     : DINode(C, ID, Storage, dwarf::DW_TAG_variable, Ops), Line(Line),
1175ffe8720aSserge-sans-paille       AlignInBits(AlignInBits) {}
getSizeInBits() const11763e0e1d09SAdrian Prantl Optional<uint64_t> DIVariable::getSizeInBits() const {
11773e0e1d09SAdrian Prantl   // This is used by the Verifier so be mindful of broken types.
11783e0e1d09SAdrian Prantl   const Metadata *RawType = getRawType();
11793e0e1d09SAdrian Prantl   while (RawType) {
11803e0e1d09SAdrian Prantl     // Try to get the size directly.
11813e0e1d09SAdrian Prantl     if (auto *T = dyn_cast<DIType>(RawType))
11823e0e1d09SAdrian Prantl       if (uint64_t Size = T->getSizeInBits())
11833e0e1d09SAdrian Prantl         return Size;
11843e0e1d09SAdrian Prantl 
11853e0e1d09SAdrian Prantl     if (auto *DT = dyn_cast<DIDerivedType>(RawType)) {
11863e0e1d09SAdrian Prantl       // Look at the base type.
11873e0e1d09SAdrian Prantl       RawType = DT->getRawBaseType();
11883e0e1d09SAdrian Prantl       continue;
11893e0e1d09SAdrian Prantl     }
11903e0e1d09SAdrian Prantl 
11913e0e1d09SAdrian Prantl     // Missing type or size.
11923e0e1d09SAdrian Prantl     break;
11933e0e1d09SAdrian Prantl   }
11943e0e1d09SAdrian Prantl 
11953e0e1d09SAdrian Prantl   // Fail gracefully.
11963e0e1d09SAdrian Prantl   return None;
11973e0e1d09SAdrian Prantl }
11983e0e1d09SAdrian Prantl 
DILabel(LLVMContext & C,StorageType Storage,unsigned Line,ArrayRef<Metadata * > Ops)1199ffe8720aSserge-sans-paille DILabel::DILabel(LLVMContext &C, StorageType Storage, unsigned Line,
1200ffe8720aSserge-sans-paille                  ArrayRef<Metadata *> Ops)
1201ffe8720aSserge-sans-paille     : DINode(C, DILabelKind, Storage, dwarf::DW_TAG_label, Ops), Line(Line) {}
getImpl(LLVMContext & Context,Metadata * Scope,MDString * Name,Metadata * File,unsigned Line,StorageType Storage,bool ShouldCreate)1202665b4138SLuís Ferreira DILabel *DILabel::getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
1203665b4138SLuís Ferreira                           Metadata *File, unsigned Line, StorageType Storage,
12042c864551SShiva Chen                           bool ShouldCreate) {
12052c864551SShiva Chen   assert(Scope && "Expected scope");
12062c864551SShiva Chen   assert(isCanonical(Name) && "Expected canonical MDString");
1207665b4138SLuís Ferreira   DEFINE_GETIMPL_LOOKUP(DILabel, (Scope, Name, File, Line));
12082c864551SShiva Chen   Metadata *Ops[] = {Scope, Name, File};
12092c864551SShiva Chen   DEFINE_GETIMPL_STORE(DILabel, (Line), Ops);
12102c864551SShiva Chen }
12112c864551SShiva Chen 
getImpl(LLVMContext & Context,ArrayRef<uint64_t> Elements,StorageType Storage,bool ShouldCreate)1212a9308c49SDuncan P. N. Exon Smith DIExpression *DIExpression::getImpl(LLVMContext &Context,
121301fc1769SDuncan P. N. Exon Smith                                     ArrayRef<uint64_t> Elements,
121401fc1769SDuncan P. N. Exon Smith                                     StorageType Storage, bool ShouldCreate) {
1215a9308c49SDuncan P. N. Exon Smith   DEFINE_GETIMPL_LOOKUP(DIExpression, (Elements));
1216a9308c49SDuncan P. N. Exon Smith   DEFINE_GETIMPL_STORE_NO_OPS(DIExpression, (Elements));
121701fc1769SDuncan P. N. Exon Smith }
isEntryValue() const1218ffe8720aSserge-sans-paille bool DIExpression::isEntryValue() const {
1219ffe8720aSserge-sans-paille   return getNumElements() > 0 && getElement(0) == dwarf::DW_OP_LLVM_entry_value;
1220ffe8720aSserge-sans-paille }
startsWithDeref() const1221ffe8720aSserge-sans-paille bool DIExpression::startsWithDeref() const {
1222ffe8720aSserge-sans-paille   return getNumElements() > 0 && getElement(0) == dwarf::DW_OP_deref;
1223ffe8720aSserge-sans-paille }
122401fc1769SDuncan P. N. Exon Smith 
getSize() const1225a9308c49SDuncan P. N. Exon Smith unsigned DIExpression::ExprOperand::getSize() const {
1226b9973f87SDjordje Todorovic   uint64_t Op = getOp();
1227b9973f87SDjordje Todorovic 
1228b9973f87SDjordje Todorovic   if (Op >= dwarf::DW_OP_breg0 && Op <= dwarf::DW_OP_breg31)
1229b9973f87SDjordje Todorovic     return 2;
1230b9973f87SDjordje Todorovic 
1231b9973f87SDjordje Todorovic   switch (Op) {
1232b86ce219SMarkus Lavin   case dwarf::DW_OP_LLVM_convert:
1233941fa758SAdrian Prantl   case dwarf::DW_OP_LLVM_fragment:
1234b9973f87SDjordje Todorovic   case dwarf::DW_OP_bregx:
1235193a4fdaSDuncan P. N. Exon Smith     return 3;
1236d4135bbcSPeter Collingbourne   case dwarf::DW_OP_constu:
1237b9973f87SDjordje Todorovic   case dwarf::DW_OP_consts:
1238a475da36SMarkus Lavin   case dwarf::DW_OP_deref_size:
1239c9c403c0SFlorian Hahn   case dwarf::DW_OP_plus_uconst:
1240fb9ce100SPeter Collingbourne   case dwarf::DW_OP_LLVM_tag_offset:
12411ae2d9a2SDavid Stenberg   case dwarf::DW_OP_LLVM_entry_value:
1242f6774130SStephen Tozer   case dwarf::DW_OP_LLVM_arg:
1243b9973f87SDjordje Todorovic   case dwarf::DW_OP_regx:
1244193a4fdaSDuncan P. N. Exon Smith     return 2;
1245193a4fdaSDuncan P. N. Exon Smith   default:
1246193a4fdaSDuncan P. N. Exon Smith     return 1;
1247193a4fdaSDuncan P. N. Exon Smith   }
1248193a4fdaSDuncan P. N. Exon Smith }
1249193a4fdaSDuncan P. N. Exon Smith 
isValid() const1250a9308c49SDuncan P. N. Exon Smith bool DIExpression::isValid() const {
1251193a4fdaSDuncan P. N. Exon Smith   for (auto I = expr_op_begin(), E = expr_op_end(); I != E; ++I) {
1252193a4fdaSDuncan P. N. Exon Smith     // Check that there's space for the operand.
1253193a4fdaSDuncan P. N. Exon Smith     if (I->get() + I->getSize() > E->get())
1254193a4fdaSDuncan P. N. Exon Smith       return false;
1255193a4fdaSDuncan P. N. Exon Smith 
1256b9973f87SDjordje Todorovic     uint64_t Op = I->getOp();
1257b9973f87SDjordje Todorovic     if ((Op >= dwarf::DW_OP_reg0 && Op <= dwarf::DW_OP_reg31) ||
1258b9973f87SDjordje Todorovic         (Op >= dwarf::DW_OP_breg0 && Op <= dwarf::DW_OP_breg31))
1259b9973f87SDjordje Todorovic       return true;
1260b9973f87SDjordje Todorovic 
1261193a4fdaSDuncan P. N. Exon Smith     // Check that the operand is valid.
1262b9973f87SDjordje Todorovic     switch (Op) {
1263193a4fdaSDuncan P. N. Exon Smith     default:
1264193a4fdaSDuncan P. N. Exon Smith       return false;
1265941fa758SAdrian Prantl     case dwarf::DW_OP_LLVM_fragment:
1266bceaaa96SAdrian Prantl       // A fragment operator must appear at the end.
1267193a4fdaSDuncan P. N. Exon Smith       return I->get() + I->getSize() == E->get();
1268bceaaa96SAdrian Prantl     case dwarf::DW_OP_stack_value: {
1269bceaaa96SAdrian Prantl       // Must be the last one or followed by a DW_OP_LLVM_fragment.
1270bceaaa96SAdrian Prantl       if (I->get() + I->getSize() == E->get())
1271bceaaa96SAdrian Prantl         break;
1272bceaaa96SAdrian Prantl       auto J = I;
1273bceaaa96SAdrian Prantl       if ((++J)->getOp() != dwarf::DW_OP_LLVM_fragment)
1274bceaaa96SAdrian Prantl         return false;
1275bceaaa96SAdrian Prantl       break;
1276bceaaa96SAdrian Prantl     }
1277f9b41cd3SKonstantin Zhuravlyov     case dwarf::DW_OP_swap: {
1278f9b41cd3SKonstantin Zhuravlyov       // Must be more than one implicit element on the stack.
1279f9b41cd3SKonstantin Zhuravlyov 
1280f9b41cd3SKonstantin Zhuravlyov       // FIXME: A better way to implement this would be to add a local variable
1281f9b41cd3SKonstantin Zhuravlyov       // that keeps track of the stack depth and introduce something like a
1282f9b41cd3SKonstantin Zhuravlyov       // DW_LLVM_OP_implicit_location as a placeholder for the location this
1283f9b41cd3SKonstantin Zhuravlyov       // DIExpression is attached to, or else pass the number of implicit stack
1284f9b41cd3SKonstantin Zhuravlyov       // elements into isValid.
1285f9b41cd3SKonstantin Zhuravlyov       if (getNumElements() == 1)
1286f9b41cd3SKonstantin Zhuravlyov         return false;
1287f9b41cd3SKonstantin Zhuravlyov       break;
1288f9b41cd3SKonstantin Zhuravlyov     }
12891ae2d9a2SDavid Stenberg     case dwarf::DW_OP_LLVM_entry_value: {
12901ae2d9a2SDavid Stenberg       // An entry value operator must appear at the beginning and the number of
12911ae2d9a2SDavid Stenberg       // operations it cover can currently only be 1, because we support only
12921ae2d9a2SDavid Stenberg       // entry values of a simple register location. One reason for this is that
12931ae2d9a2SDavid Stenberg       // we currently can't calculate the size of the resulting DWARF block for
12941ae2d9a2SDavid Stenberg       // other expressions.
129557a371d7SAdrian Prantl       return I->get() == expr_op_begin()->get() && I->getArg(0) == 1;
1296a0d45058SDjordje Todorovic     }
1297104a9f99SAlok Kumar Sharma     case dwarf::DW_OP_LLVM_implicit_pointer:
1298b86ce219SMarkus Lavin     case dwarf::DW_OP_LLVM_convert:
1299f6774130SStephen Tozer     case dwarf::DW_OP_LLVM_arg:
1300fb9ce100SPeter Collingbourne     case dwarf::DW_OP_LLVM_tag_offset:
1301d4135bbcSPeter Collingbourne     case dwarf::DW_OP_constu:
1302c9c403c0SFlorian Hahn     case dwarf::DW_OP_plus_uconst:
1303193a4fdaSDuncan P. N. Exon Smith     case dwarf::DW_OP_plus:
1304f608111dSEvgeniy Stepanov     case dwarf::DW_OP_minus:
130529202f6dSStrahinja Petrovic     case dwarf::DW_OP_mul:
13064011c26cSVedant Kumar     case dwarf::DW_OP_div:
13074011c26cSVedant Kumar     case dwarf::DW_OP_mod:
130804386d8eSVedant Kumar     case dwarf::DW_OP_or:
13091768957cSPetar Jovanovic     case dwarf::DW_OP_and:
131096b7dc04SVedant Kumar     case dwarf::DW_OP_xor:
131131ec356aSVedant Kumar     case dwarf::DW_OP_shl:
131231ec356aSVedant Kumar     case dwarf::DW_OP_shr:
131331ec356aSVedant Kumar     case dwarf::DW_OP_shra:
1314193a4fdaSDuncan P. N. Exon Smith     case dwarf::DW_OP_deref:
1315a475da36SMarkus Lavin     case dwarf::DW_OP_deref_size:
1316f9b41cd3SKonstantin Zhuravlyov     case dwarf::DW_OP_xderef:
13176379a622SVedant Kumar     case dwarf::DW_OP_lit0:
13186379a622SVedant Kumar     case dwarf::DW_OP_not:
13196379a622SVedant Kumar     case dwarf::DW_OP_dup:
1320b9973f87SDjordje Todorovic     case dwarf::DW_OP_regx:
1321b9973f87SDjordje Todorovic     case dwarf::DW_OP_bregx:
1322ab699d78SAlok Kumar Sharma     case dwarf::DW_OP_push_object_address:
13230538353bSAlok Kumar Sharma     case dwarf::DW_OP_over:
1324a6dd01afSAlok Kumar Sharma     case dwarf::DW_OP_consts:
1325193a4fdaSDuncan P. N. Exon Smith       break;
1326193a4fdaSDuncan P. N. Exon Smith     }
1327193a4fdaSDuncan P. N. Exon Smith   }
1328193a4fdaSDuncan P. N. Exon Smith   return true;
1329193a4fdaSDuncan P. N. Exon Smith }
1330193a4fdaSDuncan P. N. Exon Smith 
isImplicit() const1331a475da36SMarkus Lavin bool DIExpression::isImplicit() const {
1332e2549a0aSBjorn Pettersson   if (!isValid())
1333e2549a0aSBjorn Pettersson     return false;
1334e2549a0aSBjorn Pettersson 
1335e2549a0aSBjorn Pettersson   if (getNumElements() == 0)
1336e2549a0aSBjorn Pettersson     return false;
1337e2549a0aSBjorn Pettersson 
1338e2549a0aSBjorn Pettersson   for (const auto &It : expr_ops()) {
1339e2549a0aSBjorn Pettersson     switch (It.getOp()) {
1340e2549a0aSBjorn Pettersson     default:
1341e2549a0aSBjorn Pettersson       break;
1342fb9ce100SPeter Collingbourne     case dwarf::DW_OP_stack_value:
1343fb9ce100SPeter Collingbourne     case dwarf::DW_OP_LLVM_tag_offset:
1344fb9ce100SPeter Collingbourne       return true;
1345a475da36SMarkus Lavin     }
1346a475da36SMarkus Lavin   }
1347e2549a0aSBjorn Pettersson 
1348a475da36SMarkus Lavin   return false;
1349a475da36SMarkus Lavin }
1350a475da36SMarkus Lavin 
isComplex() const1351d2b6665eSJeremy Morse bool DIExpression::isComplex() const {
1352d2b6665eSJeremy Morse   if (!isValid())
1353d2b6665eSJeremy Morse     return false;
1354d2b6665eSJeremy Morse 
1355d2b6665eSJeremy Morse   if (getNumElements() == 0)
1356d2b6665eSJeremy Morse     return false;
1357d2b6665eSJeremy Morse 
1358d2b6665eSJeremy Morse   // If there are any elements other than fragment or tag_offset, then some
1359d2b6665eSJeremy Morse   // kind of complex computation occurs.
1360d2b6665eSJeremy Morse   for (const auto &It : expr_ops()) {
1361d2b6665eSJeremy Morse     switch (It.getOp()) {
1362d2b6665eSJeremy Morse     case dwarf::DW_OP_LLVM_tag_offset:
1363d2b6665eSJeremy Morse     case dwarf::DW_OP_LLVM_fragment:
1364d2b6665eSJeremy Morse       continue;
1365665b4138SLuís Ferreira     default:
1366665b4138SLuís Ferreira       return true;
1367d2b6665eSJeremy Morse     }
1368d2b6665eSJeremy Morse   }
1369d2b6665eSJeremy Morse 
1370d2b6665eSJeremy Morse   return false;
1371d2b6665eSJeremy Morse }
1372d2b6665eSJeremy Morse 
137349797ca6SAdrian Prantl Optional<DIExpression::FragmentInfo>
getFragmentInfo(expr_op_iterator Start,expr_op_iterator End)137449797ca6SAdrian Prantl DIExpression::getFragmentInfo(expr_op_iterator Start, expr_op_iterator End) {
137549797ca6SAdrian Prantl   for (auto I = Start; I != End; ++I)
137649797ca6SAdrian Prantl     if (I->getOp() == dwarf::DW_OP_LLVM_fragment) {
137749797ca6SAdrian Prantl       DIExpression::FragmentInfo Info = {I->getArg(1), I->getArg(0)};
137849797ca6SAdrian Prantl       return Info;
137986cc3324SDuncan P. N. Exon Smith     }
138049797ca6SAdrian Prantl   return None;
138186cc3324SDuncan P. N. Exon Smith }
138286cc3324SDuncan P. N. Exon Smith 
appendOffset(SmallVectorImpl<uint64_t> & Ops,int64_t Offset)138303e35b6bSAndrew Ng void DIExpression::appendOffset(SmallVectorImpl<uint64_t> &Ops,
138403e35b6bSAndrew Ng                                 int64_t Offset) {
138503e35b6bSAndrew Ng   if (Offset > 0) {
1386ffc498dfSFlorian Hahn     Ops.push_back(dwarf::DW_OP_plus_uconst);
138703e35b6bSAndrew Ng     Ops.push_back(Offset);
138803e35b6bSAndrew Ng   } else if (Offset < 0) {
1389ffc498dfSFlorian Hahn     Ops.push_back(dwarf::DW_OP_constu);
139003e35b6bSAndrew Ng     Ops.push_back(-Offset);
1391ffc498dfSFlorian Hahn     Ops.push_back(dwarf::DW_OP_minus);
139203e35b6bSAndrew Ng   }
139303e35b6bSAndrew Ng }
139403e35b6bSAndrew Ng 
extractIfOffset(int64_t & Offset) const1395b5fced73SReid Kleckner bool DIExpression::extractIfOffset(int64_t &Offset) const {
1396b5fced73SReid Kleckner   if (getNumElements() == 0) {
1397b5fced73SReid Kleckner     Offset = 0;
1398b5fced73SReid Kleckner     return true;
1399b5fced73SReid Kleckner   }
1400ffc498dfSFlorian Hahn 
1401ffc498dfSFlorian Hahn   if (getNumElements() == 2 && Elements[0] == dwarf::DW_OP_plus_uconst) {
1402b5fced73SReid Kleckner     Offset = Elements[1];
1403b5fced73SReid Kleckner     return true;
1404b5fced73SReid Kleckner   }
1405ffc498dfSFlorian Hahn 
1406ffc498dfSFlorian Hahn   if (getNumElements() == 3 && Elements[0] == dwarf::DW_OP_constu) {
1407ffc498dfSFlorian Hahn     if (Elements[2] == dwarf::DW_OP_plus) {
1408ffc498dfSFlorian Hahn       Offset = Elements[1];
1409ffc498dfSFlorian Hahn       return true;
1410ffc498dfSFlorian Hahn     }
1411ffc498dfSFlorian Hahn     if (Elements[2] == dwarf::DW_OP_minus) {
1412b5fced73SReid Kleckner       Offset = -Elements[1];
1413b5fced73SReid Kleckner       return true;
1414b5fced73SReid Kleckner     }
1415ffc498dfSFlorian Hahn   }
1416ffc498dfSFlorian Hahn 
1417b5fced73SReid Kleckner   return false;
1418b5fced73SReid Kleckner }
1419b5fced73SReid Kleckner 
hasAllLocationOps(unsigned N) const1420c7270567SStephen Tozer bool DIExpression::hasAllLocationOps(unsigned N) const {
1421c7270567SStephen Tozer   SmallDenseSet<uint64_t, 4> SeenOps;
1422c7270567SStephen Tozer   for (auto ExprOp : expr_ops())
1423c7270567SStephen Tozer     if (ExprOp.getOp() == dwarf::DW_OP_LLVM_arg)
1424c7270567SStephen Tozer       SeenOps.insert(ExprOp.getArg(0));
1425c7270567SStephen Tozer   for (uint64_t Idx = 0; Idx < N; ++Idx)
1426c7270567SStephen Tozer     if (!is_contained(SeenOps, Idx))
1427c7270567SStephen Tozer       return false;
1428c7270567SStephen Tozer   return true;
1429c7270567SStephen Tozer }
1430c7270567SStephen Tozer 
extractAddressClass(const DIExpression * Expr,unsigned & AddrClass)1431f3a91503SAlexey Bataev const DIExpression *DIExpression::extractAddressClass(const DIExpression *Expr,
1432f3a91503SAlexey Bataev                                                       unsigned &AddrClass) {
1433e2549a0aSBjorn Pettersson   // FIXME: This seems fragile. Nothing that verifies that these elements
1434e2549a0aSBjorn Pettersson   // actually map to ops and not operands.
1435f3a91503SAlexey Bataev   const unsigned PatternSize = 4;
1436f3a91503SAlexey Bataev   if (Expr->Elements.size() >= PatternSize &&
1437f3a91503SAlexey Bataev       Expr->Elements[PatternSize - 4] == dwarf::DW_OP_constu &&
1438f3a91503SAlexey Bataev       Expr->Elements[PatternSize - 2] == dwarf::DW_OP_swap &&
1439f3a91503SAlexey Bataev       Expr->Elements[PatternSize - 1] == dwarf::DW_OP_xderef) {
1440f3a91503SAlexey Bataev     AddrClass = Expr->Elements[PatternSize - 3];
1441f3a91503SAlexey Bataev 
1442f3a91503SAlexey Bataev     if (Expr->Elements.size() == PatternSize)
1443f3a91503SAlexey Bataev       return nullptr;
1444f3a91503SAlexey Bataev     return DIExpression::get(Expr->getContext(),
1445f3a91503SAlexey Bataev                              makeArrayRef(&*Expr->Elements.begin(),
1446f3a91503SAlexey Bataev                                           Expr->Elements.size() - PatternSize));
1447f3a91503SAlexey Bataev   }
1448f3a91503SAlexey Bataev   return Expr;
1449f3a91503SAlexey Bataev }
1450f3a91503SAlexey Bataev 
prepend(const DIExpression * Expr,uint8_t Flags,int64_t Offset)1451e85bbf56SPetar Jovanovic DIExpression *DIExpression::prepend(const DIExpression *Expr, uint8_t Flags,
1452e85bbf56SPetar Jovanovic                                     int64_t Offset) {
145303e35b6bSAndrew Ng   SmallVector<uint64_t, 8> Ops;
1454e85bbf56SPetar Jovanovic   if (Flags & DIExpression::DerefBefore)
145503e35b6bSAndrew Ng     Ops.push_back(dwarf::DW_OP_deref);
1456d1317017SAdrian Prantl 
1457d1317017SAdrian Prantl   appendOffset(Ops, Offset);
1458e85bbf56SPetar Jovanovic   if (Flags & DIExpression::DerefAfter)
1459d1317017SAdrian Prantl     Ops.push_back(dwarf::DW_OP_deref);
1460d1317017SAdrian Prantl 
1461e85bbf56SPetar Jovanovic   bool StackValue = Flags & DIExpression::StackValue;
1462a0d45058SDjordje Todorovic   bool EntryValue = Flags & DIExpression::EntryValue;
1463e85bbf56SPetar Jovanovic 
1464a0d45058SDjordje Todorovic   return prependOpcodes(Expr, Ops, StackValue, EntryValue);
146504386d8eSVedant Kumar }
146604386d8eSVedant Kumar 
appendOpsToArg(const DIExpression * Expr,ArrayRef<uint64_t> Ops,unsigned ArgNo,bool StackValue)1467f6774130SStephen Tozer DIExpression *DIExpression::appendOpsToArg(const DIExpression *Expr,
1468f6774130SStephen Tozer                                            ArrayRef<uint64_t> Ops,
1469f6774130SStephen Tozer                                            unsigned ArgNo, bool StackValue) {
1470f6774130SStephen Tozer   assert(Expr && "Can't add ops to this expression");
1471f6774130SStephen Tozer 
1472f6774130SStephen Tozer   // Handle non-variadic intrinsics by prepending the opcodes.
1473f6774130SStephen Tozer   if (!any_of(Expr->expr_ops(),
1474f6774130SStephen Tozer               [](auto Op) { return Op.getOp() == dwarf::DW_OP_LLVM_arg; })) {
1475f6774130SStephen Tozer     assert(ArgNo == 0 &&
1476f6774130SStephen Tozer            "Location Index must be 0 for a non-variadic expression.");
1477f6774130SStephen Tozer     SmallVector<uint64_t, 8> NewOps(Ops.begin(), Ops.end());
1478f6774130SStephen Tozer     return DIExpression::prependOpcodes(Expr, NewOps, StackValue);
1479f6774130SStephen Tozer   }
1480f6774130SStephen Tozer 
1481f6774130SStephen Tozer   SmallVector<uint64_t, 8> NewOps;
1482f6774130SStephen Tozer   for (auto Op : Expr->expr_ops()) {
1483f6774130SStephen Tozer     Op.appendToVector(NewOps);
1484f6774130SStephen Tozer     if (Op.getOp() == dwarf::DW_OP_LLVM_arg && Op.getArg(0) == ArgNo)
1485f6774130SStephen Tozer       NewOps.insert(NewOps.end(), Ops.begin(), Ops.end());
1486f6774130SStephen Tozer   }
1487f6774130SStephen Tozer 
1488f6774130SStephen Tozer   return DIExpression::get(Expr->getContext(), NewOps);
1489f6774130SStephen Tozer }
1490f6774130SStephen Tozer 
replaceArg(const DIExpression * Expr,uint64_t OldArg,uint64_t NewArg)1491f0513413Sgbtozers DIExpression *DIExpression::replaceArg(const DIExpression *Expr,
1492f0513413Sgbtozers                                        uint64_t OldArg, uint64_t NewArg) {
1493f0513413Sgbtozers   assert(Expr && "Can't replace args in this expression");
1494f0513413Sgbtozers 
1495f0513413Sgbtozers   SmallVector<uint64_t, 8> NewOps;
1496f0513413Sgbtozers 
1497f0513413Sgbtozers   for (auto Op : Expr->expr_ops()) {
1498f0513413Sgbtozers     if (Op.getOp() != dwarf::DW_OP_LLVM_arg || Op.getArg(0) < OldArg) {
1499f0513413Sgbtozers       Op.appendToVector(NewOps);
1500f0513413Sgbtozers       continue;
1501f0513413Sgbtozers     }
1502f0513413Sgbtozers     NewOps.push_back(dwarf::DW_OP_LLVM_arg);
1503f0513413Sgbtozers     uint64_t Arg = Op.getArg(0) == OldArg ? NewArg : Op.getArg(0);
1504f0513413Sgbtozers     // OldArg has been deleted from the Op list, so decrement all indices
1505f0513413Sgbtozers     // greater than it.
1506f0513413Sgbtozers     if (Arg > OldArg)
1507f0513413Sgbtozers       --Arg;
1508f0513413Sgbtozers     NewOps.push_back(Arg);
1509f0513413Sgbtozers   }
1510f0513413Sgbtozers   return DIExpression::get(Expr->getContext(), NewOps);
1511f0513413Sgbtozers }
1512f0513413Sgbtozers 
prependOpcodes(const DIExpression * Expr,SmallVectorImpl<uint64_t> & Ops,bool StackValue,bool EntryValue)1513210a29deSAdrian Prantl DIExpression *DIExpression::prependOpcodes(const DIExpression *Expr,
151404386d8eSVedant Kumar                                            SmallVectorImpl<uint64_t> &Ops,
1515665b4138SLuís Ferreira                                            bool StackValue, bool EntryValue) {
15168a368085SVedant Kumar   assert(Expr && "Can't prepend ops to this expression");
15178a368085SVedant Kumar 
1518a0d45058SDjordje Todorovic   if (EntryValue) {
15191ae2d9a2SDavid Stenberg     Ops.push_back(dwarf::DW_OP_LLVM_entry_value);
152057a371d7SAdrian Prantl     // Use a block size of 1 for the target register operand.  The
152157a371d7SAdrian Prantl     // DWARF backend currently cannot emit entry values with a block
152257a371d7SAdrian Prantl     // size > 1.
152357a371d7SAdrian Prantl     Ops.push_back(1);
1524a0d45058SDjordje Todorovic   }
1525a0d45058SDjordje Todorovic 
15268dd6cf71SBjorn Pettersson   // If there are no ops to prepend, do not even add the DW_OP_stack_value.
15278dd6cf71SBjorn Pettersson   if (Ops.empty())
15288dd6cf71SBjorn Pettersson     StackValue = false;
1529109b2368SAdrian Prantl   for (auto Op : Expr->expr_ops()) {
153003e35b6bSAndrew Ng     // A DW_OP_stack_value comes at the end, but before a DW_OP_LLVM_fragment.
153103e35b6bSAndrew Ng     if (StackValue) {
153203e35b6bSAndrew Ng       if (Op.getOp() == dwarf::DW_OP_stack_value)
153303e35b6bSAndrew Ng         StackValue = false;
153403e35b6bSAndrew Ng       else if (Op.getOp() == dwarf::DW_OP_LLVM_fragment) {
153503e35b6bSAndrew Ng         Ops.push_back(dwarf::DW_OP_stack_value);
153603e35b6bSAndrew Ng         StackValue = false;
153703e35b6bSAndrew Ng       }
153803e35b6bSAndrew Ng     }
153971c7c436SVedant Kumar     Op.appendToVector(Ops);
154003e35b6bSAndrew Ng   }
154103e35b6bSAndrew Ng   if (StackValue)
154203e35b6bSAndrew Ng     Ops.push_back(dwarf::DW_OP_stack_value);
1543109b2368SAdrian Prantl   return DIExpression::get(Expr->getContext(), Ops);
154403e35b6bSAndrew Ng }
154503e35b6bSAndrew Ng 
append(const DIExpression * Expr,ArrayRef<uint64_t> Ops)1546b572f642SVedant Kumar DIExpression *DIExpression::append(const DIExpression *Expr,
1547b572f642SVedant Kumar                                    ArrayRef<uint64_t> Ops) {
1548b572f642SVedant Kumar   assert(Expr && !Ops.empty() && "Can't append ops to this expression");
1549b572f642SVedant Kumar 
1550b572f642SVedant Kumar   // Copy Expr's current op list.
1551b572f642SVedant Kumar   SmallVector<uint64_t, 16> NewOps;
1552b572f642SVedant Kumar   for (auto Op : Expr->expr_ops()) {
1553b572f642SVedant Kumar     // Append new opcodes before DW_OP_{stack_value, LLVM_fragment}.
1554b572f642SVedant Kumar     if (Op.getOp() == dwarf::DW_OP_stack_value ||
1555b572f642SVedant Kumar         Op.getOp() == dwarf::DW_OP_LLVM_fragment) {
1556b572f642SVedant Kumar       NewOps.append(Ops.begin(), Ops.end());
1557b572f642SVedant Kumar 
1558b572f642SVedant Kumar       // Ensure that the new opcodes are only appended once.
1559b572f642SVedant Kumar       Ops = None;
1560b572f642SVedant Kumar     }
1561b572f642SVedant Kumar     Op.appendToVector(NewOps);
1562b572f642SVedant Kumar   }
1563b572f642SVedant Kumar 
1564b572f642SVedant Kumar   NewOps.append(Ops.begin(), Ops.end());
1565526c51e6SVedant Kumar   auto *result = DIExpression::get(Expr->getContext(), NewOps);
1566526c51e6SVedant Kumar   assert(result->isValid() && "concatenated expression is not valid");
1567526c51e6SVedant Kumar   return result;
1568b572f642SVedant Kumar }
1569b572f642SVedant Kumar 
appendToStack(const DIExpression * Expr,ArrayRef<uint64_t> Ops)15706379a622SVedant Kumar DIExpression *DIExpression::appendToStack(const DIExpression *Expr,
15716379a622SVedant Kumar                                           ArrayRef<uint64_t> Ops) {
15726379a622SVedant Kumar   assert(Expr && !Ops.empty() && "Can't append ops to this expression");
1573b572f642SVedant Kumar   assert(none_of(Ops,
1574b572f642SVedant Kumar                  [](uint64_t Op) {
1575b572f642SVedant Kumar                    return Op == dwarf::DW_OP_stack_value ||
1576b572f642SVedant Kumar                           Op == dwarf::DW_OP_LLVM_fragment;
1577b572f642SVedant Kumar                  }) &&
1578b572f642SVedant Kumar          "Can't append this op");
15796379a622SVedant Kumar 
15806379a622SVedant Kumar   // Append a DW_OP_deref after Expr's current op list if it's non-empty and
15816379a622SVedant Kumar   // has no DW_OP_stack_value.
15826379a622SVedant Kumar   //
15836379a622SVedant Kumar   // Match .* DW_OP_stack_value (DW_OP_LLVM_fragment A B)?.
15846379a622SVedant Kumar   Optional<FragmentInfo> FI = Expr->getFragmentInfo();
1585*0916d96dSKazu Hirata   unsigned DropUntilStackValue = FI ? 3 : 0;
1586b572f642SVedant Kumar   ArrayRef<uint64_t> ExprOpsBeforeFragment =
1587b572f642SVedant Kumar       Expr->getElements().drop_back(DropUntilStackValue);
1588b572f642SVedant Kumar   bool NeedsDeref = (Expr->getNumElements() > DropUntilStackValue) &&
1589b572f642SVedant Kumar                     (ExprOpsBeforeFragment.back() != dwarf::DW_OP_stack_value);
1590b572f642SVedant Kumar   bool NeedsStackValue = NeedsDeref || ExprOpsBeforeFragment.empty();
15916379a622SVedant Kumar 
1592b572f642SVedant Kumar   // Append a DW_OP_deref after Expr's current op list if needed, then append
1593b572f642SVedant Kumar   // the new ops, and finally ensure that a single DW_OP_stack_value is present.
15946379a622SVedant Kumar   SmallVector<uint64_t, 16> NewOps;
15956379a622SVedant Kumar   if (NeedsDeref)
15966379a622SVedant Kumar     NewOps.push_back(dwarf::DW_OP_deref);
15976379a622SVedant Kumar   NewOps.append(Ops.begin(), Ops.end());
1598b572f642SVedant Kumar   if (NeedsStackValue)
15996379a622SVedant Kumar     NewOps.push_back(dwarf::DW_OP_stack_value);
1600b572f642SVedant Kumar   return DIExpression::append(Expr, NewOps);
16016379a622SVedant Kumar }
16026379a622SVedant Kumar 
createFragmentExpression(const DIExpression * Expr,unsigned OffsetInBits,unsigned SizeInBits)160325a09dd4SAdrian Prantl Optional<DIExpression *> DIExpression::createFragmentExpression(
160425a09dd4SAdrian Prantl     const DIExpression *Expr, unsigned OffsetInBits, unsigned SizeInBits) {
1605b192b545SAdrian Prantl   SmallVector<uint64_t, 8> Ops;
1606b192b545SAdrian Prantl   // Copy over the expression, but leave off any trailing DW_OP_LLVM_fragment.
1607b192b545SAdrian Prantl   if (Expr) {
1608b192b545SAdrian Prantl     for (auto Op : Expr->expr_ops()) {
160925a09dd4SAdrian Prantl       switch (Op.getOp()) {
1610665b4138SLuís Ferreira       default:
1611665b4138SLuís Ferreira         break;
1612184d72a7Sstozer       case dwarf::DW_OP_shr:
1613184d72a7Sstozer       case dwarf::DW_OP_shra:
1614184d72a7Sstozer       case dwarf::DW_OP_shl:
161525a09dd4SAdrian Prantl       case dwarf::DW_OP_plus:
1616184d72a7Sstozer       case dwarf::DW_OP_plus_uconst:
161725a09dd4SAdrian Prantl       case dwarf::DW_OP_minus:
1618184d72a7Sstozer         // We can't safely split arithmetic or shift operations into multiple
1619184d72a7Sstozer         // fragments because we can't express carry-over between fragments.
162025a09dd4SAdrian Prantl         //
162125a09dd4SAdrian Prantl         // FIXME: We *could* preserve the lowest fragment of a constant offset
162225a09dd4SAdrian Prantl         // operation if the offset fits into SizeInBits.
162325a09dd4SAdrian Prantl         return None;
162425a09dd4SAdrian Prantl       case dwarf::DW_OP_LLVM_fragment: {
1625b192b545SAdrian Prantl         // Make the new offset point into the existing fragment.
1626b192b545SAdrian Prantl         uint64_t FragmentOffsetInBits = Op.getArg(0);
16275479ad29SBjorn Pettersson         uint64_t FragmentSizeInBits = Op.getArg(1);
16285479ad29SBjorn Pettersson         (void)FragmentSizeInBits;
16295479ad29SBjorn Pettersson         assert((OffsetInBits + SizeInBits <= FragmentSizeInBits) &&
1630b192b545SAdrian Prantl                "new fragment outside of original fragment");
1631b192b545SAdrian Prantl         OffsetInBits += FragmentOffsetInBits;
163225a09dd4SAdrian Prantl         continue;
163325a09dd4SAdrian Prantl       }
1634b192b545SAdrian Prantl       }
163571c7c436SVedant Kumar       Op.appendToVector(Ops);
1636b192b545SAdrian Prantl     }
1637b192b545SAdrian Prantl   }
163830f76caaSSimon Pilgrim   assert(Expr && "Unknown DIExpression");
1639b192b545SAdrian Prantl   Ops.push_back(dwarf::DW_OP_LLVM_fragment);
1640b192b545SAdrian Prantl   Ops.push_back(OffsetInBits);
1641b192b545SAdrian Prantl   Ops.push_back(SizeInBits);
1642b192b545SAdrian Prantl   return DIExpression::get(Expr->getContext(), Ops);
1643b192b545SAdrian Prantl }
1644b192b545SAdrian Prantl 
164575aa3d52SPaul Robinson std::pair<DIExpression *, const ConstantInt *>
constantFold(const ConstantInt * CI)164675aa3d52SPaul Robinson DIExpression::constantFold(const ConstantInt *CI) {
164775aa3d52SPaul Robinson   // Copy the APInt so we can modify it.
164875aa3d52SPaul Robinson   APInt NewInt = CI->getValue();
164975aa3d52SPaul Robinson   SmallVector<uint64_t, 8> Ops;
165075aa3d52SPaul Robinson 
165175aa3d52SPaul Robinson   // Fold operators only at the beginning of the expression.
165275aa3d52SPaul Robinson   bool First = true;
165375aa3d52SPaul Robinson   bool Changed = false;
165475aa3d52SPaul Robinson   for (auto Op : expr_ops()) {
165575aa3d52SPaul Robinson     switch (Op.getOp()) {
165675aa3d52SPaul Robinson     default:
165775aa3d52SPaul Robinson       // We fold only the leading part of the expression; if we get to a part
165875aa3d52SPaul Robinson       // that we're going to copy unchanged, and haven't done any folding,
165975aa3d52SPaul Robinson       // then the entire expression is unchanged and we can return early.
166075aa3d52SPaul Robinson       if (!Changed)
166175aa3d52SPaul Robinson         return {this, CI};
166275aa3d52SPaul Robinson       First = false;
166375aa3d52SPaul Robinson       break;
166475aa3d52SPaul Robinson     case dwarf::DW_OP_LLVM_convert:
166575aa3d52SPaul Robinson       if (!First)
166675aa3d52SPaul Robinson         break;
166775aa3d52SPaul Robinson       Changed = true;
166875aa3d52SPaul Robinson       if (Op.getArg(1) == dwarf::DW_ATE_signed)
166975aa3d52SPaul Robinson         NewInt = NewInt.sextOrTrunc(Op.getArg(0));
167075aa3d52SPaul Robinson       else {
167175aa3d52SPaul Robinson         assert(Op.getArg(1) == dwarf::DW_ATE_unsigned && "Unexpected operand");
167275aa3d52SPaul Robinson         NewInt = NewInt.zextOrTrunc(Op.getArg(0));
167375aa3d52SPaul Robinson       }
167475aa3d52SPaul Robinson       continue;
167575aa3d52SPaul Robinson     }
167675aa3d52SPaul Robinson     Op.appendToVector(Ops);
167775aa3d52SPaul Robinson   }
167875aa3d52SPaul Robinson   if (!Changed)
167975aa3d52SPaul Robinson     return {this, CI};
168075aa3d52SPaul Robinson   return {DIExpression::get(getContext(), Ops),
168175aa3d52SPaul Robinson           ConstantInt::get(getContext(), NewInt)};
168275aa3d52SPaul Robinson }
168375aa3d52SPaul Robinson 
getNumLocationOperands() const1684c7270567SStephen Tozer uint64_t DIExpression::getNumLocationOperands() const {
1685c7270567SStephen Tozer   uint64_t Result = 0;
1686c7270567SStephen Tozer   for (auto ExprOp : expr_ops())
1687c7270567SStephen Tozer     if (ExprOp.getOp() == dwarf::DW_OP_LLVM_arg)
1688c7270567SStephen Tozer       Result = std::max(Result, ExprOp.getArg(0) + 1);
1689c7270567SStephen Tozer   assert(hasAllLocationOps(Result) &&
1690c7270567SStephen Tozer          "Expression is missing one or more location operands.");
1691c7270567SStephen Tozer   return Result;
1692c7270567SStephen Tozer }
1693c7270567SStephen Tozer 
1694f13f0505SSourabh Singh Tomar llvm::Optional<DIExpression::SignedOrUnsignedConstant>
isConstant() const1695f13f0505SSourabh Singh Tomar DIExpression::isConstant() const {
1696bceaaa96SAdrian Prantl 
1697f13f0505SSourabh Singh Tomar   // Recognize signed and unsigned constants.
1698f13f0505SSourabh Singh Tomar   // An signed constants can be represented as DW_OP_consts C DW_OP_stack_value
1699f13f0505SSourabh Singh Tomar   // (DW_OP_LLVM_fragment of Len).
1700f13f0505SSourabh Singh Tomar   // An unsigned constant can be represented as
1701f13f0505SSourabh Singh Tomar   // DW_OP_constu C DW_OP_stack_value (DW_OP_LLVM_fragment of Len).
1702f13f0505SSourabh Singh Tomar 
1703f13f0505SSourabh Singh Tomar   if ((getNumElements() != 2 && getNumElements() != 3 &&
1704f13f0505SSourabh Singh Tomar        getNumElements() != 6) ||
1705f13f0505SSourabh Singh Tomar       (getElement(0) != dwarf::DW_OP_consts &&
1706f13f0505SSourabh Singh Tomar        getElement(0) != dwarf::DW_OP_constu))
1707f13f0505SSourabh Singh Tomar     return None;
1708f13f0505SSourabh Singh Tomar 
1709f13f0505SSourabh Singh Tomar   if (getNumElements() == 2 && getElement(0) == dwarf::DW_OP_consts)
1710f13f0505SSourabh Singh Tomar     return SignedOrUnsignedConstant::SignedConstant;
1711f13f0505SSourabh Singh Tomar 
1712f13f0505SSourabh Singh Tomar   if ((getNumElements() == 3 && getElement(2) != dwarf::DW_OP_stack_value) ||
1713f13f0505SSourabh Singh Tomar       (getNumElements() == 6 && (getElement(2) != dwarf::DW_OP_stack_value ||
1714f13f0505SSourabh Singh Tomar                                  getElement(3) != dwarf::DW_OP_LLVM_fragment)))
1715f13f0505SSourabh Singh Tomar     return None;
1716f13f0505SSourabh Singh Tomar   return getElement(0) == dwarf::DW_OP_constu
1717f13f0505SSourabh Singh Tomar              ? SignedOrUnsignedConstant::UnsignedConstant
1718f13f0505SSourabh Singh Tomar              : SignedOrUnsignedConstant::SignedConstant;
1719a6dd01afSAlok Kumar Sharma }
1720a6dd01afSAlok Kumar Sharma 
getExtOps(unsigned FromSize,unsigned ToSize,bool Signed)172189d19d60Sstozer DIExpression::ExtOps DIExpression::getExtOps(unsigned FromSize, unsigned ToSize,
172289d19d60Sstozer                                              bool Signed) {
172389d19d60Sstozer   dwarf::TypeKind TK = Signed ? dwarf::DW_ATE_signed : dwarf::DW_ATE_unsigned;
172489d19d60Sstozer   DIExpression::ExtOps Ops{{dwarf::DW_OP_LLVM_convert, FromSize, TK,
172589d19d60Sstozer                             dwarf::DW_OP_LLVM_convert, ToSize, TK}};
172689d19d60Sstozer   return Ops;
172789d19d60Sstozer }
172889d19d60Sstozer 
appendExt(const DIExpression * Expr,unsigned FromSize,unsigned ToSize,bool Signed)17293889ff82SDavid Stenberg DIExpression *DIExpression::appendExt(const DIExpression *Expr,
17303889ff82SDavid Stenberg                                       unsigned FromSize, unsigned ToSize,
17313889ff82SDavid Stenberg                                       bool Signed) {
173289d19d60Sstozer   return appendToStack(Expr, getExtOps(FromSize, ToSize, Signed));
17333889ff82SDavid Stenberg }
17343889ff82SDavid Stenberg 
1735bceaaa96SAdrian Prantl DIGlobalVariableExpression *
getImpl(LLVMContext & Context,Metadata * Variable,Metadata * Expression,StorageType Storage,bool ShouldCreate)1736bceaaa96SAdrian Prantl DIGlobalVariableExpression::getImpl(LLVMContext &Context, Metadata *Variable,
1737bceaaa96SAdrian Prantl                                     Metadata *Expression, StorageType Storage,
1738bceaaa96SAdrian Prantl                                     bool ShouldCreate) {
1739bceaaa96SAdrian Prantl   DEFINE_GETIMPL_LOOKUP(DIGlobalVariableExpression, (Variable, Expression));
1740bceaaa96SAdrian Prantl   Metadata *Ops[] = {Variable, Expression};
1741bceaaa96SAdrian Prantl   DEFINE_GETIMPL_STORE_NO_CONSTRUCTOR_ARGS(DIGlobalVariableExpression, Ops);
1742bceaaa96SAdrian Prantl }
DIObjCProperty(LLVMContext & C,StorageType Storage,unsigned Line,unsigned Attributes,ArrayRef<Metadata * > Ops)1743ffe8720aSserge-sans-paille DIObjCProperty::DIObjCProperty(LLVMContext &C, StorageType Storage,
1744ffe8720aSserge-sans-paille                                unsigned Line, unsigned Attributes,
1745ffe8720aSserge-sans-paille                                ArrayRef<Metadata *> Ops)
1746ffe8720aSserge-sans-paille     : DINode(C, DIObjCPropertyKind, Storage, dwarf::DW_TAG_APPLE_property, Ops),
1747ffe8720aSserge-sans-paille       Line(Line), Attributes(Attributes) {}
1748bceaaa96SAdrian Prantl 
getImpl(LLVMContext & Context,MDString * Name,Metadata * File,unsigned Line,MDString * GetterName,MDString * SetterName,unsigned Attributes,Metadata * Type,StorageType Storage,bool ShouldCreate)1749a9308c49SDuncan P. N. Exon Smith DIObjCProperty *DIObjCProperty::getImpl(
175001fc1769SDuncan P. N. Exon Smith     LLVMContext &Context, MDString *Name, Metadata *File, unsigned Line,
175101fc1769SDuncan P. N. Exon Smith     MDString *GetterName, MDString *SetterName, unsigned Attributes,
175201fc1769SDuncan P. N. Exon Smith     Metadata *Type, StorageType Storage, bool ShouldCreate) {
175301fc1769SDuncan P. N. Exon Smith   assert(isCanonical(Name) && "Expected canonical MDString");
175401fc1769SDuncan P. N. Exon Smith   assert(isCanonical(GetterName) && "Expected canonical MDString");
175501fc1769SDuncan P. N. Exon Smith   assert(isCanonical(SetterName) && "Expected canonical MDString");
17565d99c4efSMehdi Amini   DEFINE_GETIMPL_LOOKUP(DIObjCProperty, (Name, File, Line, GetterName,
17575d99c4efSMehdi Amini                                          SetterName, Attributes, Type));
175801fc1769SDuncan P. N. Exon Smith   Metadata *Ops[] = {Name, File, GetterName, SetterName, Type};
1759a9308c49SDuncan P. N. Exon Smith   DEFINE_GETIMPL_STORE(DIObjCProperty, (Line, Attributes), Ops);
176001fc1769SDuncan P. N. Exon Smith }
176101fc1769SDuncan P. N. Exon Smith 
getImpl(LLVMContext & Context,unsigned Tag,Metadata * Scope,Metadata * Entity,Metadata * File,unsigned Line,MDString * Name,Metadata * Elements,StorageType Storage,bool ShouldCreate)1762a9308c49SDuncan P. N. Exon Smith DIImportedEntity *DIImportedEntity::getImpl(LLVMContext &Context, unsigned Tag,
176301fc1769SDuncan P. N. Exon Smith                                             Metadata *Scope, Metadata *Entity,
1764d63bfd21SAdrian Prantl                                             Metadata *File, unsigned Line,
1765a5b72abcSAlok Kumar Sharma                                             MDString *Name, Metadata *Elements,
1766a5b72abcSAlok Kumar Sharma                                             StorageType Storage,
176701fc1769SDuncan P. N. Exon Smith                                             bool ShouldCreate) {
176801fc1769SDuncan P. N. Exon Smith   assert(isCanonical(Name) && "Expected canonical MDString");
1769d63bfd21SAdrian Prantl   DEFINE_GETIMPL_LOOKUP(DIImportedEntity,
1770a5b72abcSAlok Kumar Sharma                         (Tag, Scope, Entity, File, Line, Name, Elements));
1771a5b72abcSAlok Kumar Sharma   Metadata *Ops[] = {Scope, Entity, Name, File, Elements};
1772a9308c49SDuncan P. N. Exon Smith   DEFINE_GETIMPL_STORE(DIImportedEntity, (Tag, Line), Ops);
177301fc1769SDuncan P. N. Exon Smith }
1774a9bcf16eSAmjad Aboud 
getImpl(LLVMContext & Context,unsigned MIType,unsigned Line,MDString * Name,MDString * Value,StorageType Storage,bool ShouldCreate)1775665b4138SLuís Ferreira DIMacro *DIMacro::getImpl(LLVMContext &Context, unsigned MIType, unsigned Line,
1776665b4138SLuís Ferreira                           MDString *Name, MDString *Value, StorageType Storage,
1777665b4138SLuís Ferreira                           bool ShouldCreate) {
1778a9bcf16eSAmjad Aboud   assert(isCanonical(Name) && "Expected canonical MDString");
17795d99c4efSMehdi Amini   DEFINE_GETIMPL_LOOKUP(DIMacro, (MIType, Line, Name, Value));
1780a9bcf16eSAmjad Aboud   Metadata *Ops[] = {Name, Value};
1781a9bcf16eSAmjad Aboud   DEFINE_GETIMPL_STORE(DIMacro, (MIType, Line), Ops);
1782a9bcf16eSAmjad Aboud }
1783a9bcf16eSAmjad Aboud 
getImpl(LLVMContext & Context,unsigned MIType,unsigned Line,Metadata * File,Metadata * Elements,StorageType Storage,bool ShouldCreate)1784a9bcf16eSAmjad Aboud DIMacroFile *DIMacroFile::getImpl(LLVMContext &Context, unsigned MIType,
1785a9bcf16eSAmjad Aboud                                   unsigned Line, Metadata *File,
1786a9bcf16eSAmjad Aboud                                   Metadata *Elements, StorageType Storage,
1787a9bcf16eSAmjad Aboud                                   bool ShouldCreate) {
1788665b4138SLuís Ferreira   DEFINE_GETIMPL_LOOKUP(DIMacroFile, (MIType, Line, File, Elements));
1789a9bcf16eSAmjad Aboud   Metadata *Ops[] = {File, Elements};
1790a9bcf16eSAmjad Aboud   DEFINE_GETIMPL_STORE(DIMacroFile, (MIType, Line), Ops);
1791a9bcf16eSAmjad Aboud }
179265600cb2Sgbtozers 
getImpl(LLVMContext & Context,ArrayRef<ValueAsMetadata * > Args,StorageType Storage,bool ShouldCreate)179365600cb2Sgbtozers DIArgList *DIArgList::getImpl(LLVMContext &Context,
179465600cb2Sgbtozers                               ArrayRef<ValueAsMetadata *> Args,
179565600cb2Sgbtozers                               StorageType Storage, bool ShouldCreate) {
179665600cb2Sgbtozers   DEFINE_GETIMPL_LOOKUP(DIArgList, (Args));
179765600cb2Sgbtozers   DEFINE_GETIMPL_STORE_NO_OPS(DIArgList, (Args));
179865600cb2Sgbtozers }
179965600cb2Sgbtozers 
handleChangedOperand(void * Ref,Metadata * New)180065600cb2Sgbtozers void DIArgList::handleChangedOperand(void *Ref, Metadata *New) {
180165600cb2Sgbtozers   ValueAsMetadata **OldVMPtr = static_cast<ValueAsMetadata **>(Ref);
180265600cb2Sgbtozers   assert((!New || isa<ValueAsMetadata>(New)) &&
180365600cb2Sgbtozers          "DIArgList must be passed a ValueAsMetadata");
180465600cb2Sgbtozers   untrack();
1805badcd585STeresa Johnson   bool Uniq = isUniqued();
1806badcd585STeresa Johnson   if (Uniq) {
1807badcd585STeresa Johnson     // We need to update the uniqueness once the Args are updated since they
1808badcd585STeresa Johnson     // form the key to the DIArgLists store.
1809badcd585STeresa Johnson     eraseFromStore();
1810badcd585STeresa Johnson   }
181165600cb2Sgbtozers   ValueAsMetadata *NewVM = cast_or_null<ValueAsMetadata>(New);
181265600cb2Sgbtozers   for (ValueAsMetadata *&VM : Args) {
181365600cb2Sgbtozers     if (&VM == OldVMPtr) {
181465600cb2Sgbtozers       if (NewVM)
181565600cb2Sgbtozers         VM = NewVM;
181665600cb2Sgbtozers       else
181765600cb2Sgbtozers         VM = ValueAsMetadata::get(UndefValue::get(VM->getValue()->getType()));
181865600cb2Sgbtozers     }
181965600cb2Sgbtozers   }
1820badcd585STeresa Johnson   if (Uniq) {
1821badcd585STeresa Johnson     if (uniquify() != this)
1822badcd585STeresa Johnson       storeDistinctInContext();
1823badcd585STeresa Johnson   }
182465600cb2Sgbtozers   track();
182565600cb2Sgbtozers }
track()182665600cb2Sgbtozers void DIArgList::track() {
182765600cb2Sgbtozers   for (ValueAsMetadata *&VAM : Args)
182865600cb2Sgbtozers     if (VAM)
182965600cb2Sgbtozers       MetadataTracking::track(&VAM, *VAM, *this);
183065600cb2Sgbtozers }
untrack()183165600cb2Sgbtozers void DIArgList::untrack() {
183265600cb2Sgbtozers   for (ValueAsMetadata *&VAM : Args)
183365600cb2Sgbtozers     if (VAM)
183465600cb2Sgbtozers       MetadataTracking::untrack(&VAM, *VAM);
183565600cb2Sgbtozers }
dropAllReferences()183665600cb2Sgbtozers void DIArgList::dropAllReferences() {
183765600cb2Sgbtozers   untrack();
183865600cb2Sgbtozers   Args.clear();
183965600cb2Sgbtozers   MDNode::dropAllReferences();
184065600cb2Sgbtozers }
1841