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