10b57cec5SDimitry Andric //===- DebugInfoMetadata.cpp - Implement debug info metadata --------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file implements the debug info Metadata classes. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #include "llvm/IR/DebugInfoMetadata.h" 140b57cec5SDimitry Andric #include "LLVMContextImpl.h" 150b57cec5SDimitry Andric #include "MetadataImpl.h" 1606c3fb27SDimitry Andric #include "llvm/ADT/SmallPtrSet.h" 170b57cec5SDimitry Andric #include "llvm/ADT/StringSwitch.h" 1881ad6265SDimitry Andric #include "llvm/BinaryFormat/Dwarf.h" 195f757f3fSDimitry Andric #include "llvm/IR/DebugProgramInstruction.h" 200b57cec5SDimitry Andric #include "llvm/IR/Function.h" 21bdd1243dSDimitry Andric #include "llvm/IR/IntrinsicInst.h" 221fd87a68SDimitry Andric #include "llvm/IR/Type.h" 231fd87a68SDimitry Andric #include "llvm/IR/Value.h" 240b57cec5SDimitry Andric 250b57cec5SDimitry Andric #include <numeric> 26bdd1243dSDimitry Andric #include <optional> 270b57cec5SDimitry Andric 280b57cec5SDimitry Andric using namespace llvm; 290b57cec5SDimitry Andric 30fe6060f1SDimitry Andric namespace llvm { 31fe6060f1SDimitry Andric // Use FS-AFDO discriminator. 32fe6060f1SDimitry Andric cl::opt<bool> EnableFSDiscriminator( 3381ad6265SDimitry Andric "enable-fs-discriminator", cl::Hidden, 34fe6060f1SDimitry Andric cl::desc("Enable adding flow sensitive discriminators")); 35fe6060f1SDimitry Andric } // namespace llvm 36fe6060f1SDimitry Andric 37*0fca6ea1SDimitry Andric uint32_t DIType::getAlignInBits() const { 38*0fca6ea1SDimitry Andric return (getTag() == dwarf::DW_TAG_LLVM_ptrauth_type ? 0 : SubclassData32); 39*0fca6ea1SDimitry Andric } 40*0fca6ea1SDimitry Andric 41480093f4SDimitry Andric const DIExpression::FragmentInfo DebugVariable::DefaultFragment = { 42480093f4SDimitry Andric std::numeric_limits<uint64_t>::max(), std::numeric_limits<uint64_t>::min()}; 43480093f4SDimitry Andric 44bdd1243dSDimitry Andric DebugVariable::DebugVariable(const DbgVariableIntrinsic *DII) 45bdd1243dSDimitry Andric : Variable(DII->getVariable()), 46bdd1243dSDimitry Andric Fragment(DII->getExpression()->getFragmentInfo()), 47bdd1243dSDimitry Andric InlinedAt(DII->getDebugLoc().getInlinedAt()) {} 48bdd1243dSDimitry Andric 49*0fca6ea1SDimitry Andric DebugVariable::DebugVariable(const DbgVariableRecord *DVR) 50*0fca6ea1SDimitry Andric : Variable(DVR->getVariable()), 51*0fca6ea1SDimitry Andric Fragment(DVR->getExpression()->getFragmentInfo()), 52*0fca6ea1SDimitry Andric InlinedAt(DVR->getDebugLoc().getInlinedAt()) {} 535f757f3fSDimitry Andric 5406c3fb27SDimitry Andric DebugVariableAggregate::DebugVariableAggregate(const DbgVariableIntrinsic *DVI) 5506c3fb27SDimitry Andric : DebugVariable(DVI->getVariable(), std::nullopt, 5606c3fb27SDimitry Andric DVI->getDebugLoc()->getInlinedAt()) {} 5706c3fb27SDimitry Andric 580b57cec5SDimitry Andric DILocation::DILocation(LLVMContext &C, StorageType Storage, unsigned Line, 590b57cec5SDimitry Andric unsigned Column, ArrayRef<Metadata *> MDs, 600b57cec5SDimitry Andric bool ImplicitCode) 610b57cec5SDimitry Andric : MDNode(C, DILocationKind, Storage, MDs) { 620b57cec5SDimitry Andric assert((MDs.size() == 1 || MDs.size() == 2) && 630b57cec5SDimitry Andric "Expected a scope and optional inlined-at"); 640b57cec5SDimitry Andric 650b57cec5SDimitry Andric // Set line and column. 660b57cec5SDimitry Andric assert(Column < (1u << 16) && "Expected 16-bit column"); 670b57cec5SDimitry Andric 680b57cec5SDimitry Andric SubclassData32 = Line; 690b57cec5SDimitry Andric SubclassData16 = Column; 700b57cec5SDimitry Andric 710b57cec5SDimitry Andric setImplicitCode(ImplicitCode); 720b57cec5SDimitry Andric } 730b57cec5SDimitry Andric 740b57cec5SDimitry Andric static void adjustColumn(unsigned &Column) { 750b57cec5SDimitry Andric // Set to unknown on overflow. We only have 16 bits to play with here. 760b57cec5SDimitry Andric if (Column >= (1u << 16)) 770b57cec5SDimitry Andric Column = 0; 780b57cec5SDimitry Andric } 790b57cec5SDimitry Andric 800b57cec5SDimitry Andric DILocation *DILocation::getImpl(LLVMContext &Context, unsigned Line, 810b57cec5SDimitry Andric unsigned Column, Metadata *Scope, 820b57cec5SDimitry Andric Metadata *InlinedAt, bool ImplicitCode, 830b57cec5SDimitry Andric StorageType Storage, bool ShouldCreate) { 840b57cec5SDimitry Andric // Fixup column. 850b57cec5SDimitry Andric adjustColumn(Column); 860b57cec5SDimitry Andric 870b57cec5SDimitry Andric if (Storage == Uniqued) { 880b57cec5SDimitry Andric if (auto *N = getUniqued(Context.pImpl->DILocations, 890b57cec5SDimitry Andric DILocationInfo::KeyTy(Line, Column, Scope, 900b57cec5SDimitry Andric InlinedAt, ImplicitCode))) 910b57cec5SDimitry Andric return N; 920b57cec5SDimitry Andric if (!ShouldCreate) 930b57cec5SDimitry Andric return nullptr; 940b57cec5SDimitry Andric } else { 950b57cec5SDimitry Andric assert(ShouldCreate && "Expected non-uniqued nodes to always be created"); 960b57cec5SDimitry Andric } 970b57cec5SDimitry Andric 980b57cec5SDimitry Andric SmallVector<Metadata *, 2> Ops; 990b57cec5SDimitry Andric Ops.push_back(Scope); 1000b57cec5SDimitry Andric if (InlinedAt) 1010b57cec5SDimitry Andric Ops.push_back(InlinedAt); 10281ad6265SDimitry Andric return storeImpl(new (Ops.size(), Storage) DILocation( 10381ad6265SDimitry Andric Context, Storage, Line, Column, Ops, ImplicitCode), 1040b57cec5SDimitry Andric Storage, Context.pImpl->DILocations); 1050b57cec5SDimitry Andric } 1060b57cec5SDimitry Andric 10706c3fb27SDimitry Andric DILocation *DILocation::getMergedLocations(ArrayRef<DILocation *> Locs) { 1085ffd83dbSDimitry Andric if (Locs.empty()) 1095ffd83dbSDimitry Andric return nullptr; 1105ffd83dbSDimitry Andric if (Locs.size() == 1) 1115ffd83dbSDimitry Andric return Locs[0]; 1125ffd83dbSDimitry Andric auto *Merged = Locs[0]; 11306c3fb27SDimitry Andric for (DILocation *L : llvm::drop_begin(Locs)) { 114fe6060f1SDimitry Andric Merged = getMergedLocation(Merged, L); 1155ffd83dbSDimitry Andric if (Merged == nullptr) 1165ffd83dbSDimitry Andric break; 1175ffd83dbSDimitry Andric } 1185ffd83dbSDimitry Andric return Merged; 1195ffd83dbSDimitry Andric } 1205ffd83dbSDimitry Andric 12106c3fb27SDimitry Andric DILocation *DILocation::getMergedLocation(DILocation *LocA, DILocation *LocB) { 1220b57cec5SDimitry Andric if (!LocA || !LocB) 1230b57cec5SDimitry Andric return nullptr; 1240b57cec5SDimitry Andric 1250b57cec5SDimitry Andric if (LocA == LocB) 1260b57cec5SDimitry Andric return LocA; 1270b57cec5SDimitry Andric 128bdd1243dSDimitry Andric LLVMContext &C = LocA->getContext(); 129bdd1243dSDimitry Andric 13006c3fb27SDimitry Andric using LocVec = SmallVector<const DILocation *>; 13106c3fb27SDimitry Andric LocVec ALocs; 13206c3fb27SDimitry Andric LocVec BLocs; 13306c3fb27SDimitry Andric SmallDenseMap<std::pair<const DISubprogram *, const DILocation *>, unsigned, 13406c3fb27SDimitry Andric 4> 13506c3fb27SDimitry Andric ALookup; 136bdd1243dSDimitry Andric 13706c3fb27SDimitry Andric // Walk through LocA and its inlined-at locations, populate them in ALocs and 13806c3fb27SDimitry Andric // save the index for the subprogram and inlined-at pair, which we use to find 13906c3fb27SDimitry Andric // a matching starting location in LocB's chain. 14006c3fb27SDimitry Andric for (auto [L, I] = std::make_pair(LocA, 0U); L; L = L->getInlinedAt(), I++) { 14106c3fb27SDimitry Andric ALocs.push_back(L); 14206c3fb27SDimitry Andric auto Res = ALookup.try_emplace( 14306c3fb27SDimitry Andric {L->getScope()->getSubprogram(), L->getInlinedAt()}, I); 14406c3fb27SDimitry Andric assert(Res.second && "Multiple <SP, InlinedAt> pairs in a location chain?"); 14506c3fb27SDimitry Andric (void)Res; 1460b57cec5SDimitry Andric } 147bdd1243dSDimitry Andric 14806c3fb27SDimitry Andric LocVec::reverse_iterator ARIt = ALocs.rend(); 14906c3fb27SDimitry Andric LocVec::reverse_iterator BRIt = BLocs.rend(); 15006c3fb27SDimitry Andric 15106c3fb27SDimitry Andric // Populate BLocs and look for a matching starting location, the first 15206c3fb27SDimitry Andric // location with the same subprogram and inlined-at location as in LocA's 15306c3fb27SDimitry Andric // chain. Since the two locations have the same inlined-at location we do 15406c3fb27SDimitry Andric // not need to look at those parts of the chains. 15506c3fb27SDimitry Andric for (auto [L, I] = std::make_pair(LocB, 0U); L; L = L->getInlinedAt(), I++) { 15606c3fb27SDimitry Andric BLocs.push_back(L); 15706c3fb27SDimitry Andric 15806c3fb27SDimitry Andric if (ARIt != ALocs.rend()) 15906c3fb27SDimitry Andric // We have already found a matching starting location. 16006c3fb27SDimitry Andric continue; 16106c3fb27SDimitry Andric 16206c3fb27SDimitry Andric auto IT = ALookup.find({L->getScope()->getSubprogram(), L->getInlinedAt()}); 16306c3fb27SDimitry Andric if (IT == ALookup.end()) 16406c3fb27SDimitry Andric continue; 16506c3fb27SDimitry Andric 16606c3fb27SDimitry Andric // The + 1 is to account for the &*rev_it = &(it - 1) relationship. 16706c3fb27SDimitry Andric ARIt = LocVec::reverse_iterator(ALocs.begin() + IT->second + 1); 16806c3fb27SDimitry Andric BRIt = LocVec::reverse_iterator(BLocs.begin() + I + 1); 16906c3fb27SDimitry Andric 17006c3fb27SDimitry Andric // If we have found a matching starting location we do not need to add more 17106c3fb27SDimitry Andric // locations to BLocs, since we will only look at location pairs preceding 17206c3fb27SDimitry Andric // the matching starting location, and adding more elements to BLocs could 17306c3fb27SDimitry Andric // invalidate the iterator that we initialized here. 1740b57cec5SDimitry Andric break; 1750b57cec5SDimitry Andric } 17606c3fb27SDimitry Andric 17706c3fb27SDimitry Andric // Merge the two locations if possible, using the supplied 17806c3fb27SDimitry Andric // inlined-at location for the created location. 17906c3fb27SDimitry Andric auto MergeLocPair = [&C](const DILocation *L1, const DILocation *L2, 18006c3fb27SDimitry Andric DILocation *InlinedAt) -> DILocation * { 18106c3fb27SDimitry Andric if (L1 == L2) 18206c3fb27SDimitry Andric return DILocation::get(C, L1->getLine(), L1->getColumn(), L1->getScope(), 18306c3fb27SDimitry Andric InlinedAt); 18406c3fb27SDimitry Andric 18506c3fb27SDimitry Andric // If the locations originate from different subprograms we can't produce 18606c3fb27SDimitry Andric // a common location. 18706c3fb27SDimitry Andric if (L1->getScope()->getSubprogram() != L2->getScope()->getSubprogram()) 18806c3fb27SDimitry Andric return nullptr; 18906c3fb27SDimitry Andric 19006c3fb27SDimitry Andric // Return the nearest common scope inside a subprogram. 19106c3fb27SDimitry Andric auto GetNearestCommonScope = [](DIScope *S1, DIScope *S2) -> DIScope * { 19206c3fb27SDimitry Andric SmallPtrSet<DIScope *, 8> Scopes; 19306c3fb27SDimitry Andric for (; S1; S1 = S1->getScope()) { 19406c3fb27SDimitry Andric Scopes.insert(S1); 19506c3fb27SDimitry Andric if (isa<DISubprogram>(S1)) 19606c3fb27SDimitry Andric break; 197bdd1243dSDimitry Andric } 1980b57cec5SDimitry Andric 19906c3fb27SDimitry Andric for (; S2; S2 = S2->getScope()) { 20006c3fb27SDimitry Andric if (Scopes.count(S2)) 20106c3fb27SDimitry Andric return S2; 20206c3fb27SDimitry Andric if (isa<DISubprogram>(S2)) 20306c3fb27SDimitry Andric break; 2040b57cec5SDimitry Andric } 2050b57cec5SDimitry Andric 20606c3fb27SDimitry Andric return nullptr; 20706c3fb27SDimitry Andric }; 20806c3fb27SDimitry Andric 20906c3fb27SDimitry Andric auto Scope = GetNearestCommonScope(L1->getScope(), L2->getScope()); 21006c3fb27SDimitry Andric assert(Scope && "No common scope in the same subprogram?"); 21106c3fb27SDimitry Andric 21206c3fb27SDimitry Andric bool SameLine = L1->getLine() == L2->getLine(); 21306c3fb27SDimitry Andric bool SameCol = L1->getColumn() == L2->getColumn(); 21406c3fb27SDimitry Andric unsigned Line = SameLine ? L1->getLine() : 0; 21506c3fb27SDimitry Andric unsigned Col = SameLine && SameCol ? L1->getColumn() : 0; 21606c3fb27SDimitry Andric 21706c3fb27SDimitry Andric return DILocation::get(C, Line, Col, Scope, InlinedAt); 21806c3fb27SDimitry Andric }; 21906c3fb27SDimitry Andric 22006c3fb27SDimitry Andric DILocation *Result = ARIt != ALocs.rend() ? (*ARIt)->getInlinedAt() : nullptr; 22106c3fb27SDimitry Andric 22206c3fb27SDimitry Andric // If we have found a common starting location, walk up the inlined-at chains 22306c3fb27SDimitry Andric // and try to produce common locations. 22406c3fb27SDimitry Andric for (; ARIt != ALocs.rend() && BRIt != BLocs.rend(); ++ARIt, ++BRIt) { 22506c3fb27SDimitry Andric DILocation *Tmp = MergeLocPair(*ARIt, *BRIt, Result); 22606c3fb27SDimitry Andric 22706c3fb27SDimitry Andric if (!Tmp) 22806c3fb27SDimitry Andric // We have walked up to a point in the chains where the two locations 22906c3fb27SDimitry Andric // are irreconsilable. At this point Result contains the nearest common 23006c3fb27SDimitry Andric // location in the inlined-at chains of LocA and LocB, so we break here. 23106c3fb27SDimitry Andric break; 23206c3fb27SDimitry Andric 23306c3fb27SDimitry Andric Result = Tmp; 23406c3fb27SDimitry Andric } 23506c3fb27SDimitry Andric 23606c3fb27SDimitry Andric if (Result) 23706c3fb27SDimitry Andric return Result; 23806c3fb27SDimitry Andric 23906c3fb27SDimitry Andric // We ended up with LocA and LocB as irreconsilable locations. Produce a 24006c3fb27SDimitry Andric // location at 0:0 with one of the locations' scope. The function has 24106c3fb27SDimitry Andric // historically picked A's scope, and a nullptr inlined-at location, so that 24206c3fb27SDimitry Andric // behavior is mimicked here but I am not sure if this is always the correct 24306c3fb27SDimitry Andric // way to handle this. 24406c3fb27SDimitry Andric return DILocation::get(C, 0, 0, LocA->getScope(), nullptr); 245bdd1243dSDimitry Andric } 246bdd1243dSDimitry Andric 247bdd1243dSDimitry Andric std::optional<unsigned> 248bdd1243dSDimitry Andric DILocation::encodeDiscriminator(unsigned BD, unsigned DF, unsigned CI) { 249e8d8bef9SDimitry Andric std::array<unsigned, 3> Components = {BD, DF, CI}; 2500b57cec5SDimitry Andric uint64_t RemainingWork = 0U; 2510b57cec5SDimitry Andric // We use RemainingWork to figure out if we have no remaining components to 2520b57cec5SDimitry Andric // encode. For example: if BD != 0 but DF == 0 && CI == 0, we don't need to 2530b57cec5SDimitry Andric // encode anything for the latter 2. 2540b57cec5SDimitry Andric // Since any of the input components is at most 32 bits, their sum will be 2550b57cec5SDimitry Andric // less than 34 bits, and thus RemainingWork won't overflow. 256349cc55cSDimitry Andric RemainingWork = 257349cc55cSDimitry Andric std::accumulate(Components.begin(), Components.end(), RemainingWork); 2580b57cec5SDimitry Andric 2590b57cec5SDimitry Andric int I = 0; 2600b57cec5SDimitry Andric unsigned Ret = 0; 2610b57cec5SDimitry Andric unsigned NextBitInsertionIndex = 0; 2620b57cec5SDimitry Andric while (RemainingWork > 0) { 2630b57cec5SDimitry Andric unsigned C = Components[I++]; 2640b57cec5SDimitry Andric RemainingWork -= C; 2650b57cec5SDimitry Andric unsigned EC = encodeComponent(C); 2660b57cec5SDimitry Andric Ret |= (EC << NextBitInsertionIndex); 2670b57cec5SDimitry Andric NextBitInsertionIndex += encodingBits(C); 2680b57cec5SDimitry Andric } 2690b57cec5SDimitry Andric 2700b57cec5SDimitry Andric // Encoding may be unsuccessful because of overflow. We determine success by 2710b57cec5SDimitry Andric // checking equivalence of components before & after encoding. Alternatively, 2720b57cec5SDimitry Andric // we could determine Success during encoding, but the current alternative is 2730b57cec5SDimitry Andric // simpler. 2740b57cec5SDimitry Andric unsigned TBD, TDF, TCI = 0; 2750b57cec5SDimitry Andric decodeDiscriminator(Ret, TBD, TDF, TCI); 2760b57cec5SDimitry Andric if (TBD == BD && TDF == DF && TCI == CI) 2770b57cec5SDimitry Andric return Ret; 278bdd1243dSDimitry Andric return std::nullopt; 2790b57cec5SDimitry Andric } 2800b57cec5SDimitry Andric 2810b57cec5SDimitry Andric void DILocation::decodeDiscriminator(unsigned D, unsigned &BD, unsigned &DF, 2820b57cec5SDimitry Andric unsigned &CI) { 2830b57cec5SDimitry Andric BD = getUnsignedFromPrefixEncoding(D); 2840b57cec5SDimitry Andric DF = getUnsignedFromPrefixEncoding(getNextComponentInDiscriminator(D)); 2850b57cec5SDimitry Andric CI = getUnsignedFromPrefixEncoding( 2860b57cec5SDimitry Andric getNextComponentInDiscriminator(getNextComponentInDiscriminator(D))); 2870b57cec5SDimitry Andric } 28881ad6265SDimitry Andric dwarf::Tag DINode::getTag() const { return (dwarf::Tag)SubclassData16; } 2890b57cec5SDimitry Andric 2900b57cec5SDimitry Andric DINode::DIFlags DINode::getFlag(StringRef Flag) { 2910b57cec5SDimitry Andric return StringSwitch<DIFlags>(Flag) 2920b57cec5SDimitry Andric #define HANDLE_DI_FLAG(ID, NAME) .Case("DIFlag" #NAME, Flag##NAME) 2930b57cec5SDimitry Andric #include "llvm/IR/DebugInfoFlags.def" 2940b57cec5SDimitry Andric .Default(DINode::FlagZero); 2950b57cec5SDimitry Andric } 2960b57cec5SDimitry Andric 2970b57cec5SDimitry Andric StringRef DINode::getFlagString(DIFlags Flag) { 2980b57cec5SDimitry Andric switch (Flag) { 2990b57cec5SDimitry Andric #define HANDLE_DI_FLAG(ID, NAME) \ 3000b57cec5SDimitry Andric case Flag##NAME: \ 3010b57cec5SDimitry Andric return "DIFlag" #NAME; 3020b57cec5SDimitry Andric #include "llvm/IR/DebugInfoFlags.def" 3030b57cec5SDimitry Andric } 3040b57cec5SDimitry Andric return ""; 3050b57cec5SDimitry Andric } 3060b57cec5SDimitry Andric 3070b57cec5SDimitry Andric DINode::DIFlags DINode::splitFlags(DIFlags Flags, 3080b57cec5SDimitry Andric SmallVectorImpl<DIFlags> &SplitFlags) { 3090b57cec5SDimitry Andric // Flags that are packed together need to be specially handled, so 3100b57cec5SDimitry Andric // that, for example, we emit "DIFlagPublic" and not 3110b57cec5SDimitry Andric // "DIFlagPrivate | DIFlagProtected". 3120b57cec5SDimitry Andric if (DIFlags A = Flags & FlagAccessibility) { 3130b57cec5SDimitry Andric if (A == FlagPrivate) 3140b57cec5SDimitry Andric SplitFlags.push_back(FlagPrivate); 3150b57cec5SDimitry Andric else if (A == FlagProtected) 3160b57cec5SDimitry Andric SplitFlags.push_back(FlagProtected); 3170b57cec5SDimitry Andric else 3180b57cec5SDimitry Andric SplitFlags.push_back(FlagPublic); 3190b57cec5SDimitry Andric Flags &= ~A; 3200b57cec5SDimitry Andric } 3210b57cec5SDimitry Andric if (DIFlags R = Flags & FlagPtrToMemberRep) { 3220b57cec5SDimitry Andric if (R == FlagSingleInheritance) 3230b57cec5SDimitry Andric SplitFlags.push_back(FlagSingleInheritance); 3240b57cec5SDimitry Andric else if (R == FlagMultipleInheritance) 3250b57cec5SDimitry Andric SplitFlags.push_back(FlagMultipleInheritance); 3260b57cec5SDimitry Andric else 3270b57cec5SDimitry Andric SplitFlags.push_back(FlagVirtualInheritance); 3280b57cec5SDimitry Andric Flags &= ~R; 3290b57cec5SDimitry Andric } 3300b57cec5SDimitry Andric if ((Flags & FlagIndirectVirtualBase) == FlagIndirectVirtualBase) { 3310b57cec5SDimitry Andric Flags &= ~FlagIndirectVirtualBase; 3320b57cec5SDimitry Andric SplitFlags.push_back(FlagIndirectVirtualBase); 3330b57cec5SDimitry Andric } 3340b57cec5SDimitry Andric 3350b57cec5SDimitry Andric #define HANDLE_DI_FLAG(ID, NAME) \ 3360b57cec5SDimitry Andric if (DIFlags Bit = Flags & Flag##NAME) { \ 3370b57cec5SDimitry Andric SplitFlags.push_back(Bit); \ 3380b57cec5SDimitry Andric Flags &= ~Bit; \ 3390b57cec5SDimitry Andric } 3400b57cec5SDimitry Andric #include "llvm/IR/DebugInfoFlags.def" 3410b57cec5SDimitry Andric return Flags; 3420b57cec5SDimitry Andric } 3430b57cec5SDimitry Andric 3440b57cec5SDimitry Andric DIScope *DIScope::getScope() const { 3450b57cec5SDimitry Andric if (auto *T = dyn_cast<DIType>(this)) 3460b57cec5SDimitry Andric return T->getScope(); 3470b57cec5SDimitry Andric 3480b57cec5SDimitry Andric if (auto *SP = dyn_cast<DISubprogram>(this)) 3490b57cec5SDimitry Andric return SP->getScope(); 3500b57cec5SDimitry Andric 3510b57cec5SDimitry Andric if (auto *LB = dyn_cast<DILexicalBlockBase>(this)) 3520b57cec5SDimitry Andric return LB->getScope(); 3530b57cec5SDimitry Andric 3540b57cec5SDimitry Andric if (auto *NS = dyn_cast<DINamespace>(this)) 3550b57cec5SDimitry Andric return NS->getScope(); 3560b57cec5SDimitry Andric 3570b57cec5SDimitry Andric if (auto *CB = dyn_cast<DICommonBlock>(this)) 3580b57cec5SDimitry Andric return CB->getScope(); 3590b57cec5SDimitry Andric 3600b57cec5SDimitry Andric if (auto *M = dyn_cast<DIModule>(this)) 3610b57cec5SDimitry Andric return M->getScope(); 3620b57cec5SDimitry Andric 3630b57cec5SDimitry Andric assert((isa<DIFile>(this) || isa<DICompileUnit>(this)) && 3640b57cec5SDimitry Andric "Unhandled type of scope."); 3650b57cec5SDimitry Andric return nullptr; 3660b57cec5SDimitry Andric } 3670b57cec5SDimitry Andric 3680b57cec5SDimitry Andric StringRef DIScope::getName() const { 3690b57cec5SDimitry Andric if (auto *T = dyn_cast<DIType>(this)) 3700b57cec5SDimitry Andric return T->getName(); 3710b57cec5SDimitry Andric if (auto *SP = dyn_cast<DISubprogram>(this)) 3720b57cec5SDimitry Andric return SP->getName(); 3730b57cec5SDimitry Andric if (auto *NS = dyn_cast<DINamespace>(this)) 3740b57cec5SDimitry Andric return NS->getName(); 3750b57cec5SDimitry Andric if (auto *CB = dyn_cast<DICommonBlock>(this)) 3760b57cec5SDimitry Andric return CB->getName(); 3770b57cec5SDimitry Andric if (auto *M = dyn_cast<DIModule>(this)) 3780b57cec5SDimitry Andric return M->getName(); 3790b57cec5SDimitry Andric assert((isa<DILexicalBlockBase>(this) || isa<DIFile>(this) || 3800b57cec5SDimitry Andric isa<DICompileUnit>(this)) && 3810b57cec5SDimitry Andric "Unhandled type of scope."); 3820b57cec5SDimitry Andric return ""; 3830b57cec5SDimitry Andric } 3840b57cec5SDimitry Andric 3850b57cec5SDimitry Andric #ifndef NDEBUG 3860b57cec5SDimitry Andric static bool isCanonical(const MDString *S) { 3870b57cec5SDimitry Andric return !S || !S->getString().empty(); 3880b57cec5SDimitry Andric } 3890b57cec5SDimitry Andric #endif 3900b57cec5SDimitry Andric 39181ad6265SDimitry Andric dwarf::Tag GenericDINode::getTag() const { return (dwarf::Tag)SubclassData16; } 3920b57cec5SDimitry Andric GenericDINode *GenericDINode::getImpl(LLVMContext &Context, unsigned Tag, 3930b57cec5SDimitry Andric MDString *Header, 3940b57cec5SDimitry Andric ArrayRef<Metadata *> DwarfOps, 3950b57cec5SDimitry Andric StorageType Storage, bool ShouldCreate) { 3960b57cec5SDimitry Andric unsigned Hash = 0; 3970b57cec5SDimitry Andric if (Storage == Uniqued) { 3980b57cec5SDimitry Andric GenericDINodeInfo::KeyTy Key(Tag, Header, DwarfOps); 3990b57cec5SDimitry Andric if (auto *N = getUniqued(Context.pImpl->GenericDINodes, Key)) 4000b57cec5SDimitry Andric return N; 4010b57cec5SDimitry Andric if (!ShouldCreate) 4020b57cec5SDimitry Andric return nullptr; 4030b57cec5SDimitry Andric Hash = Key.getHash(); 4040b57cec5SDimitry Andric } else { 4050b57cec5SDimitry Andric assert(ShouldCreate && "Expected non-uniqued nodes to always be created"); 4060b57cec5SDimitry Andric } 4070b57cec5SDimitry Andric 4080b57cec5SDimitry Andric // Use a nullptr for empty headers. 4090b57cec5SDimitry Andric assert(isCanonical(Header) && "Expected canonical MDString"); 4100b57cec5SDimitry Andric Metadata *PreOps[] = {Header}; 41181ad6265SDimitry Andric return storeImpl(new (DwarfOps.size() + 1, Storage) GenericDINode( 4120b57cec5SDimitry Andric Context, Storage, Hash, Tag, PreOps, DwarfOps), 4130b57cec5SDimitry Andric Storage, Context.pImpl->GenericDINodes); 4140b57cec5SDimitry Andric } 4150b57cec5SDimitry Andric 4160b57cec5SDimitry Andric void GenericDINode::recalculateHash() { 4170b57cec5SDimitry Andric setHash(GenericDINodeInfo::KeyTy::calculateHash(this)); 4180b57cec5SDimitry Andric } 4190b57cec5SDimitry Andric 4200b57cec5SDimitry Andric #define UNWRAP_ARGS_IMPL(...) __VA_ARGS__ 4210b57cec5SDimitry Andric #define UNWRAP_ARGS(ARGS) UNWRAP_ARGS_IMPL ARGS 4220b57cec5SDimitry Andric #define DEFINE_GETIMPL_LOOKUP(CLASS, ARGS) \ 4230b57cec5SDimitry Andric do { \ 4240b57cec5SDimitry Andric if (Storage == Uniqued) { \ 4250b57cec5SDimitry Andric if (auto *N = getUniqued(Context.pImpl->CLASS##s, \ 4260b57cec5SDimitry Andric CLASS##Info::KeyTy(UNWRAP_ARGS(ARGS)))) \ 4270b57cec5SDimitry Andric return N; \ 4280b57cec5SDimitry Andric if (!ShouldCreate) \ 4290b57cec5SDimitry Andric return nullptr; \ 4300b57cec5SDimitry Andric } else { \ 4310b57cec5SDimitry Andric assert(ShouldCreate && \ 4320b57cec5SDimitry Andric "Expected non-uniqued nodes to always be created"); \ 4330b57cec5SDimitry Andric } \ 4340b57cec5SDimitry Andric } while (false) 4350b57cec5SDimitry Andric #define DEFINE_GETIMPL_STORE(CLASS, ARGS, OPS) \ 436bdd1243dSDimitry Andric return storeImpl(new (std::size(OPS), Storage) \ 4370b57cec5SDimitry Andric CLASS(Context, Storage, UNWRAP_ARGS(ARGS), OPS), \ 4380b57cec5SDimitry Andric Storage, Context.pImpl->CLASS##s) 4390b57cec5SDimitry Andric #define DEFINE_GETIMPL_STORE_NO_OPS(CLASS, ARGS) \ 44081ad6265SDimitry Andric return storeImpl(new (0u, Storage) \ 44181ad6265SDimitry Andric CLASS(Context, Storage, UNWRAP_ARGS(ARGS)), \ 4420b57cec5SDimitry Andric Storage, Context.pImpl->CLASS##s) 4430b57cec5SDimitry Andric #define DEFINE_GETIMPL_STORE_NO_CONSTRUCTOR_ARGS(CLASS, OPS) \ 444bdd1243dSDimitry Andric return storeImpl(new (std::size(OPS), Storage) CLASS(Context, Storage, OPS), \ 4450b57cec5SDimitry Andric Storage, Context.pImpl->CLASS##s) 4460b57cec5SDimitry Andric #define DEFINE_GETIMPL_STORE_N(CLASS, ARGS, OPS, NUM_OPS) \ 44781ad6265SDimitry Andric return storeImpl(new (NUM_OPS, Storage) \ 4480b57cec5SDimitry Andric CLASS(Context, Storage, UNWRAP_ARGS(ARGS), OPS), \ 4490b57cec5SDimitry Andric Storage, Context.pImpl->CLASS##s) 4500b57cec5SDimitry Andric 45181ad6265SDimitry Andric DISubrange::DISubrange(LLVMContext &C, StorageType Storage, 45281ad6265SDimitry Andric ArrayRef<Metadata *> Ops) 45381ad6265SDimitry Andric : DINode(C, DISubrangeKind, Storage, dwarf::DW_TAG_subrange_type, Ops) {} 4540b57cec5SDimitry Andric DISubrange *DISubrange::getImpl(LLVMContext &Context, int64_t Count, int64_t Lo, 4550b57cec5SDimitry Andric StorageType Storage, bool ShouldCreate) { 4560b57cec5SDimitry Andric auto *CountNode = ConstantAsMetadata::get( 4570b57cec5SDimitry Andric ConstantInt::getSigned(Type::getInt64Ty(Context), Count)); 4585ffd83dbSDimitry Andric auto *LB = ConstantAsMetadata::get( 4595ffd83dbSDimitry Andric ConstantInt::getSigned(Type::getInt64Ty(Context), Lo)); 4605ffd83dbSDimitry Andric return getImpl(Context, CountNode, LB, nullptr, nullptr, Storage, 4615ffd83dbSDimitry Andric ShouldCreate); 4620b57cec5SDimitry Andric } 4630b57cec5SDimitry Andric 4640b57cec5SDimitry Andric DISubrange *DISubrange::getImpl(LLVMContext &Context, Metadata *CountNode, 4650b57cec5SDimitry Andric int64_t Lo, StorageType Storage, 4660b57cec5SDimitry Andric bool ShouldCreate) { 4675ffd83dbSDimitry Andric auto *LB = ConstantAsMetadata::get( 4685ffd83dbSDimitry Andric ConstantInt::getSigned(Type::getInt64Ty(Context), Lo)); 4695ffd83dbSDimitry Andric return getImpl(Context, CountNode, LB, nullptr, nullptr, Storage, 4705ffd83dbSDimitry Andric ShouldCreate); 4710b57cec5SDimitry Andric } 4720b57cec5SDimitry Andric 4735ffd83dbSDimitry Andric DISubrange *DISubrange::getImpl(LLVMContext &Context, Metadata *CountNode, 4745ffd83dbSDimitry Andric Metadata *LB, Metadata *UB, Metadata *Stride, 4755ffd83dbSDimitry Andric StorageType Storage, bool ShouldCreate) { 4765ffd83dbSDimitry Andric DEFINE_GETIMPL_LOOKUP(DISubrange, (CountNode, LB, UB, Stride)); 4775ffd83dbSDimitry Andric Metadata *Ops[] = {CountNode, LB, UB, Stride}; 4785ffd83dbSDimitry Andric DEFINE_GETIMPL_STORE_NO_CONSTRUCTOR_ARGS(DISubrange, Ops); 4795ffd83dbSDimitry Andric } 4805ffd83dbSDimitry Andric 481fe6060f1SDimitry Andric DISubrange::BoundType DISubrange::getCount() const { 482fe6060f1SDimitry Andric Metadata *CB = getRawCountNode(); 483fe6060f1SDimitry Andric if (!CB) 484fe6060f1SDimitry Andric return BoundType(); 4855ffd83dbSDimitry Andric 486fe6060f1SDimitry Andric assert((isa<ConstantAsMetadata>(CB) || isa<DIVariable>(CB) || 487fe6060f1SDimitry Andric isa<DIExpression>(CB)) && 488fe6060f1SDimitry Andric "Count must be signed constant or DIVariable or DIExpression"); 4895ffd83dbSDimitry Andric 490fe6060f1SDimitry Andric if (auto *MD = dyn_cast<ConstantAsMetadata>(CB)) 491fe6060f1SDimitry Andric return BoundType(cast<ConstantInt>(MD->getValue())); 4925ffd83dbSDimitry Andric 493fe6060f1SDimitry Andric if (auto *MD = dyn_cast<DIVariable>(CB)) 494fe6060f1SDimitry Andric return BoundType(MD); 495fe6060f1SDimitry Andric 496fe6060f1SDimitry Andric if (auto *MD = dyn_cast<DIExpression>(CB)) 497fe6060f1SDimitry Andric return BoundType(MD); 498fe6060f1SDimitry Andric 499fe6060f1SDimitry Andric return BoundType(); 5005ffd83dbSDimitry Andric } 5015ffd83dbSDimitry Andric 5025ffd83dbSDimitry Andric DISubrange::BoundType DISubrange::getLowerBound() const { 5035ffd83dbSDimitry Andric Metadata *LB = getRawLowerBound(); 5045ffd83dbSDimitry Andric if (!LB) 5055ffd83dbSDimitry Andric return BoundType(); 5065ffd83dbSDimitry Andric 5075ffd83dbSDimitry Andric assert((isa<ConstantAsMetadata>(LB) || isa<DIVariable>(LB) || 5085ffd83dbSDimitry Andric isa<DIExpression>(LB)) && 5095ffd83dbSDimitry Andric "LowerBound must be signed constant or DIVariable or DIExpression"); 5105ffd83dbSDimitry Andric 5115ffd83dbSDimitry Andric if (auto *MD = dyn_cast<ConstantAsMetadata>(LB)) 5125ffd83dbSDimitry Andric return BoundType(cast<ConstantInt>(MD->getValue())); 5135ffd83dbSDimitry Andric 5145ffd83dbSDimitry Andric if (auto *MD = dyn_cast<DIVariable>(LB)) 5155ffd83dbSDimitry Andric return BoundType(MD); 5165ffd83dbSDimitry Andric 5175ffd83dbSDimitry Andric if (auto *MD = dyn_cast<DIExpression>(LB)) 5185ffd83dbSDimitry Andric return BoundType(MD); 5195ffd83dbSDimitry Andric 5205ffd83dbSDimitry Andric return BoundType(); 5215ffd83dbSDimitry Andric } 5225ffd83dbSDimitry Andric 5235ffd83dbSDimitry Andric DISubrange::BoundType DISubrange::getUpperBound() const { 5245ffd83dbSDimitry Andric Metadata *UB = getRawUpperBound(); 5255ffd83dbSDimitry Andric if (!UB) 5265ffd83dbSDimitry Andric return BoundType(); 5275ffd83dbSDimitry Andric 5285ffd83dbSDimitry Andric assert((isa<ConstantAsMetadata>(UB) || isa<DIVariable>(UB) || 5295ffd83dbSDimitry Andric isa<DIExpression>(UB)) && 5305ffd83dbSDimitry Andric "UpperBound must be signed constant or DIVariable or DIExpression"); 5315ffd83dbSDimitry Andric 5325ffd83dbSDimitry Andric if (auto *MD = dyn_cast<ConstantAsMetadata>(UB)) 5335ffd83dbSDimitry Andric return BoundType(cast<ConstantInt>(MD->getValue())); 5345ffd83dbSDimitry Andric 5355ffd83dbSDimitry Andric if (auto *MD = dyn_cast<DIVariable>(UB)) 5365ffd83dbSDimitry Andric return BoundType(MD); 5375ffd83dbSDimitry Andric 5385ffd83dbSDimitry Andric if (auto *MD = dyn_cast<DIExpression>(UB)) 5395ffd83dbSDimitry Andric return BoundType(MD); 5405ffd83dbSDimitry Andric 5415ffd83dbSDimitry Andric return BoundType(); 5425ffd83dbSDimitry Andric } 5435ffd83dbSDimitry Andric 5445ffd83dbSDimitry Andric DISubrange::BoundType DISubrange::getStride() const { 5455ffd83dbSDimitry Andric Metadata *ST = getRawStride(); 5465ffd83dbSDimitry Andric if (!ST) 5475ffd83dbSDimitry Andric return BoundType(); 5485ffd83dbSDimitry Andric 5495ffd83dbSDimitry Andric assert((isa<ConstantAsMetadata>(ST) || isa<DIVariable>(ST) || 5505ffd83dbSDimitry Andric isa<DIExpression>(ST)) && 5515ffd83dbSDimitry Andric "Stride must be signed constant or DIVariable or DIExpression"); 5525ffd83dbSDimitry Andric 5535ffd83dbSDimitry Andric if (auto *MD = dyn_cast<ConstantAsMetadata>(ST)) 5545ffd83dbSDimitry Andric return BoundType(cast<ConstantInt>(MD->getValue())); 5555ffd83dbSDimitry Andric 5565ffd83dbSDimitry Andric if (auto *MD = dyn_cast<DIVariable>(ST)) 5575ffd83dbSDimitry Andric return BoundType(MD); 5585ffd83dbSDimitry Andric 5595ffd83dbSDimitry Andric if (auto *MD = dyn_cast<DIExpression>(ST)) 5605ffd83dbSDimitry Andric return BoundType(MD); 5615ffd83dbSDimitry Andric 5625ffd83dbSDimitry Andric return BoundType(); 5635ffd83dbSDimitry Andric } 56481ad6265SDimitry Andric DIGenericSubrange::DIGenericSubrange(LLVMContext &C, StorageType Storage, 56581ad6265SDimitry Andric ArrayRef<Metadata *> Ops) 56681ad6265SDimitry Andric : DINode(C, DIGenericSubrangeKind, Storage, dwarf::DW_TAG_generic_subrange, 56781ad6265SDimitry Andric Ops) {} 5685ffd83dbSDimitry Andric 569e8d8bef9SDimitry Andric DIGenericSubrange *DIGenericSubrange::getImpl(LLVMContext &Context, 570e8d8bef9SDimitry Andric Metadata *CountNode, Metadata *LB, 571e8d8bef9SDimitry Andric Metadata *UB, Metadata *Stride, 572e8d8bef9SDimitry Andric StorageType Storage, 573e8d8bef9SDimitry Andric bool ShouldCreate) { 574e8d8bef9SDimitry Andric DEFINE_GETIMPL_LOOKUP(DIGenericSubrange, (CountNode, LB, UB, Stride)); 575e8d8bef9SDimitry Andric Metadata *Ops[] = {CountNode, LB, UB, Stride}; 576e8d8bef9SDimitry Andric DEFINE_GETIMPL_STORE_NO_CONSTRUCTOR_ARGS(DIGenericSubrange, Ops); 577e8d8bef9SDimitry Andric } 578e8d8bef9SDimitry Andric 579e8d8bef9SDimitry Andric DIGenericSubrange::BoundType DIGenericSubrange::getCount() const { 580e8d8bef9SDimitry Andric Metadata *CB = getRawCountNode(); 581e8d8bef9SDimitry Andric if (!CB) 582e8d8bef9SDimitry Andric return BoundType(); 583e8d8bef9SDimitry Andric 584e8d8bef9SDimitry Andric assert((isa<DIVariable>(CB) || isa<DIExpression>(CB)) && 585e8d8bef9SDimitry Andric "Count must be signed constant or DIVariable or DIExpression"); 586e8d8bef9SDimitry Andric 587e8d8bef9SDimitry Andric if (auto *MD = dyn_cast<DIVariable>(CB)) 588e8d8bef9SDimitry Andric return BoundType(MD); 589e8d8bef9SDimitry Andric 590e8d8bef9SDimitry Andric if (auto *MD = dyn_cast<DIExpression>(CB)) 591e8d8bef9SDimitry Andric return BoundType(MD); 592e8d8bef9SDimitry Andric 593e8d8bef9SDimitry Andric return BoundType(); 594e8d8bef9SDimitry Andric } 595e8d8bef9SDimitry Andric 596e8d8bef9SDimitry Andric DIGenericSubrange::BoundType DIGenericSubrange::getLowerBound() const { 597e8d8bef9SDimitry Andric Metadata *LB = getRawLowerBound(); 598e8d8bef9SDimitry Andric if (!LB) 599e8d8bef9SDimitry Andric return BoundType(); 600e8d8bef9SDimitry Andric 601e8d8bef9SDimitry Andric assert((isa<DIVariable>(LB) || isa<DIExpression>(LB)) && 602e8d8bef9SDimitry Andric "LowerBound must be signed constant or DIVariable or DIExpression"); 603e8d8bef9SDimitry Andric 604e8d8bef9SDimitry Andric if (auto *MD = dyn_cast<DIVariable>(LB)) 605e8d8bef9SDimitry Andric return BoundType(MD); 606e8d8bef9SDimitry Andric 607e8d8bef9SDimitry Andric if (auto *MD = dyn_cast<DIExpression>(LB)) 608e8d8bef9SDimitry Andric return BoundType(MD); 609e8d8bef9SDimitry Andric 610e8d8bef9SDimitry Andric return BoundType(); 611e8d8bef9SDimitry Andric } 612e8d8bef9SDimitry Andric 613e8d8bef9SDimitry Andric DIGenericSubrange::BoundType DIGenericSubrange::getUpperBound() const { 614e8d8bef9SDimitry Andric Metadata *UB = getRawUpperBound(); 615e8d8bef9SDimitry Andric if (!UB) 616e8d8bef9SDimitry Andric return BoundType(); 617e8d8bef9SDimitry Andric 618e8d8bef9SDimitry Andric assert((isa<DIVariable>(UB) || isa<DIExpression>(UB)) && 619e8d8bef9SDimitry Andric "UpperBound must be signed constant or DIVariable or DIExpression"); 620e8d8bef9SDimitry Andric 621e8d8bef9SDimitry Andric if (auto *MD = dyn_cast<DIVariable>(UB)) 622e8d8bef9SDimitry Andric return BoundType(MD); 623e8d8bef9SDimitry Andric 624e8d8bef9SDimitry Andric if (auto *MD = dyn_cast<DIExpression>(UB)) 625e8d8bef9SDimitry Andric return BoundType(MD); 626e8d8bef9SDimitry Andric 627e8d8bef9SDimitry Andric return BoundType(); 628e8d8bef9SDimitry Andric } 629e8d8bef9SDimitry Andric 630e8d8bef9SDimitry Andric DIGenericSubrange::BoundType DIGenericSubrange::getStride() const { 631e8d8bef9SDimitry Andric Metadata *ST = getRawStride(); 632e8d8bef9SDimitry Andric if (!ST) 633e8d8bef9SDimitry Andric return BoundType(); 634e8d8bef9SDimitry Andric 635e8d8bef9SDimitry Andric assert((isa<DIVariable>(ST) || isa<DIExpression>(ST)) && 636e8d8bef9SDimitry Andric "Stride must be signed constant or DIVariable or DIExpression"); 637e8d8bef9SDimitry Andric 638e8d8bef9SDimitry Andric if (auto *MD = dyn_cast<DIVariable>(ST)) 639e8d8bef9SDimitry Andric return BoundType(MD); 640e8d8bef9SDimitry Andric 641e8d8bef9SDimitry Andric if (auto *MD = dyn_cast<DIExpression>(ST)) 642e8d8bef9SDimitry Andric return BoundType(MD); 643e8d8bef9SDimitry Andric 644e8d8bef9SDimitry Andric return BoundType(); 645e8d8bef9SDimitry Andric } 646e8d8bef9SDimitry Andric 64781ad6265SDimitry Andric DIEnumerator::DIEnumerator(LLVMContext &C, StorageType Storage, 64881ad6265SDimitry Andric const APInt &Value, bool IsUnsigned, 64981ad6265SDimitry Andric ArrayRef<Metadata *> Ops) 65081ad6265SDimitry Andric : DINode(C, DIEnumeratorKind, Storage, dwarf::DW_TAG_enumerator, Ops), 65181ad6265SDimitry Andric Value(Value) { 65281ad6265SDimitry Andric SubclassData32 = IsUnsigned; 65381ad6265SDimitry Andric } 6545ffd83dbSDimitry Andric DIEnumerator *DIEnumerator::getImpl(LLVMContext &Context, const APInt &Value, 6550b57cec5SDimitry Andric bool IsUnsigned, MDString *Name, 6560b57cec5SDimitry Andric StorageType Storage, bool ShouldCreate) { 6570b57cec5SDimitry Andric assert(isCanonical(Name) && "Expected canonical MDString"); 6580b57cec5SDimitry Andric DEFINE_GETIMPL_LOOKUP(DIEnumerator, (Value, IsUnsigned, Name)); 6590b57cec5SDimitry Andric Metadata *Ops[] = {Name}; 6600b57cec5SDimitry Andric DEFINE_GETIMPL_STORE(DIEnumerator, (Value, IsUnsigned), Ops); 6610b57cec5SDimitry Andric } 6620b57cec5SDimitry Andric 6630b57cec5SDimitry Andric DIBasicType *DIBasicType::getImpl(LLVMContext &Context, unsigned Tag, 6640b57cec5SDimitry Andric MDString *Name, uint64_t SizeInBits, 6650b57cec5SDimitry Andric uint32_t AlignInBits, unsigned Encoding, 6660b57cec5SDimitry Andric DIFlags Flags, StorageType Storage, 6670b57cec5SDimitry Andric bool ShouldCreate) { 6680b57cec5SDimitry Andric assert(isCanonical(Name) && "Expected canonical MDString"); 6690b57cec5SDimitry Andric DEFINE_GETIMPL_LOOKUP(DIBasicType, 6700b57cec5SDimitry Andric (Tag, Name, SizeInBits, AlignInBits, Encoding, Flags)); 6710b57cec5SDimitry Andric Metadata *Ops[] = {nullptr, nullptr, Name}; 672349cc55cSDimitry Andric DEFINE_GETIMPL_STORE(DIBasicType, 673349cc55cSDimitry Andric (Tag, SizeInBits, AlignInBits, Encoding, Flags), Ops); 6740b57cec5SDimitry Andric } 6750b57cec5SDimitry Andric 676bdd1243dSDimitry Andric std::optional<DIBasicType::Signedness> DIBasicType::getSignedness() const { 6770b57cec5SDimitry Andric switch (getEncoding()) { 6780b57cec5SDimitry Andric case dwarf::DW_ATE_signed: 6790b57cec5SDimitry Andric case dwarf::DW_ATE_signed_char: 6800b57cec5SDimitry Andric return Signedness::Signed; 6810b57cec5SDimitry Andric case dwarf::DW_ATE_unsigned: 6820b57cec5SDimitry Andric case dwarf::DW_ATE_unsigned_char: 6830b57cec5SDimitry Andric return Signedness::Unsigned; 6840b57cec5SDimitry Andric default: 685bdd1243dSDimitry Andric return std::nullopt; 6860b57cec5SDimitry Andric } 6870b57cec5SDimitry Andric } 6880b57cec5SDimitry Andric 689e8d8bef9SDimitry Andric DIStringType *DIStringType::getImpl(LLVMContext &Context, unsigned Tag, 690e8d8bef9SDimitry Andric MDString *Name, Metadata *StringLength, 691e8d8bef9SDimitry Andric Metadata *StringLengthExp, 69204eeddc0SDimitry Andric Metadata *StringLocationExp, 693e8d8bef9SDimitry Andric uint64_t SizeInBits, uint32_t AlignInBits, 694e8d8bef9SDimitry Andric unsigned Encoding, StorageType Storage, 695e8d8bef9SDimitry Andric bool ShouldCreate) { 696e8d8bef9SDimitry Andric assert(isCanonical(Name) && "Expected canonical MDString"); 69704eeddc0SDimitry Andric DEFINE_GETIMPL_LOOKUP(DIStringType, 69804eeddc0SDimitry Andric (Tag, Name, StringLength, StringLengthExp, 69904eeddc0SDimitry Andric StringLocationExp, SizeInBits, AlignInBits, Encoding)); 70004eeddc0SDimitry Andric Metadata *Ops[] = {nullptr, nullptr, Name, 70104eeddc0SDimitry Andric StringLength, StringLengthExp, StringLocationExp}; 702e8d8bef9SDimitry Andric DEFINE_GETIMPL_STORE(DIStringType, (Tag, SizeInBits, AlignInBits, Encoding), 703e8d8bef9SDimitry Andric Ops); 704e8d8bef9SDimitry Andric } 70581ad6265SDimitry Andric DIType *DIDerivedType::getClassType() const { 70681ad6265SDimitry Andric assert(getTag() == dwarf::DW_TAG_ptr_to_member_type); 70781ad6265SDimitry Andric return cast_or_null<DIType>(getExtraData()); 70881ad6265SDimitry Andric } 70981ad6265SDimitry Andric uint32_t DIDerivedType::getVBPtrOffset() const { 71081ad6265SDimitry Andric assert(getTag() == dwarf::DW_TAG_inheritance); 71181ad6265SDimitry Andric if (auto *CM = cast_or_null<ConstantAsMetadata>(getExtraData())) 71281ad6265SDimitry Andric if (auto *CI = dyn_cast_or_null<ConstantInt>(CM->getValue())) 71381ad6265SDimitry Andric return static_cast<uint32_t>(CI->getZExtValue()); 71481ad6265SDimitry Andric return 0; 71581ad6265SDimitry Andric } 71681ad6265SDimitry Andric Constant *DIDerivedType::getStorageOffsetInBits() const { 71781ad6265SDimitry Andric assert(getTag() == dwarf::DW_TAG_member && isBitField()); 71881ad6265SDimitry Andric if (auto *C = cast_or_null<ConstantAsMetadata>(getExtraData())) 71981ad6265SDimitry Andric return C->getValue(); 72081ad6265SDimitry Andric return nullptr; 72181ad6265SDimitry Andric } 72281ad6265SDimitry Andric 72381ad6265SDimitry Andric Constant *DIDerivedType::getConstant() const { 7245f757f3fSDimitry Andric assert((getTag() == dwarf::DW_TAG_member || 7255f757f3fSDimitry Andric getTag() == dwarf::DW_TAG_variable) && 7265f757f3fSDimitry Andric isStaticMember()); 72781ad6265SDimitry Andric if (auto *C = cast_or_null<ConstantAsMetadata>(getExtraData())) 72881ad6265SDimitry Andric return C->getValue(); 72981ad6265SDimitry Andric return nullptr; 73081ad6265SDimitry Andric } 73181ad6265SDimitry Andric Constant *DIDerivedType::getDiscriminantValue() const { 73281ad6265SDimitry Andric assert(getTag() == dwarf::DW_TAG_member && !isStaticMember()); 73381ad6265SDimitry Andric if (auto *C = cast_or_null<ConstantAsMetadata>(getExtraData())) 73481ad6265SDimitry Andric return C->getValue(); 73581ad6265SDimitry Andric return nullptr; 73681ad6265SDimitry Andric } 737e8d8bef9SDimitry Andric 738*0fca6ea1SDimitry Andric DIDerivedType *DIDerivedType::getImpl( 739*0fca6ea1SDimitry Andric LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File, 740*0fca6ea1SDimitry Andric unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, 7410b57cec5SDimitry Andric uint32_t AlignInBits, uint64_t OffsetInBits, 742*0fca6ea1SDimitry Andric std::optional<unsigned> DWARFAddressSpace, 743*0fca6ea1SDimitry Andric std::optional<PtrAuthData> PtrAuthData, DIFlags Flags, Metadata *ExtraData, 744*0fca6ea1SDimitry Andric Metadata *Annotations, StorageType Storage, bool ShouldCreate) { 7450b57cec5SDimitry Andric assert(isCanonical(Name) && "Expected canonical MDString"); 7460b57cec5SDimitry Andric DEFINE_GETIMPL_LOOKUP(DIDerivedType, 7470b57cec5SDimitry Andric (Tag, Name, File, Line, Scope, BaseType, SizeInBits, 748*0fca6ea1SDimitry Andric AlignInBits, OffsetInBits, DWARFAddressSpace, 749*0fca6ea1SDimitry Andric PtrAuthData, Flags, ExtraData, Annotations)); 750349cc55cSDimitry Andric Metadata *Ops[] = {File, Scope, Name, BaseType, ExtraData, Annotations}; 751349cc55cSDimitry Andric DEFINE_GETIMPL_STORE(DIDerivedType, 752349cc55cSDimitry Andric (Tag, Line, SizeInBits, AlignInBits, OffsetInBits, 753*0fca6ea1SDimitry Andric DWARFAddressSpace, PtrAuthData, Flags), 754349cc55cSDimitry Andric Ops); 7550b57cec5SDimitry Andric } 7560b57cec5SDimitry Andric 757*0fca6ea1SDimitry Andric std::optional<DIDerivedType::PtrAuthData> 758*0fca6ea1SDimitry Andric DIDerivedType::getPtrAuthData() const { 759*0fca6ea1SDimitry Andric return getTag() == dwarf::DW_TAG_LLVM_ptrauth_type 760*0fca6ea1SDimitry Andric ? std::optional<PtrAuthData>(PtrAuthData(SubclassData32)) 761*0fca6ea1SDimitry Andric : std::nullopt; 762*0fca6ea1SDimitry Andric } 763*0fca6ea1SDimitry Andric 7640b57cec5SDimitry Andric DICompositeType *DICompositeType::getImpl( 7650b57cec5SDimitry Andric LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File, 7660b57cec5SDimitry Andric unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, 7670b57cec5SDimitry Andric uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags, 7680b57cec5SDimitry Andric Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder, 7690b57cec5SDimitry Andric Metadata *TemplateParams, MDString *Identifier, Metadata *Discriminator, 770e8d8bef9SDimitry Andric Metadata *DataLocation, Metadata *Associated, Metadata *Allocated, 771349cc55cSDimitry Andric Metadata *Rank, Metadata *Annotations, StorageType Storage, 772349cc55cSDimitry Andric bool ShouldCreate) { 7730b57cec5SDimitry Andric assert(isCanonical(Name) && "Expected canonical MDString"); 7740b57cec5SDimitry Andric 7750b57cec5SDimitry Andric // Keep this in sync with buildODRType. 776349cc55cSDimitry Andric DEFINE_GETIMPL_LOOKUP(DICompositeType, 777349cc55cSDimitry Andric (Tag, Name, File, Line, Scope, BaseType, SizeInBits, 778349cc55cSDimitry Andric AlignInBits, OffsetInBits, Flags, Elements, 779349cc55cSDimitry Andric RuntimeLang, VTableHolder, TemplateParams, Identifier, 780349cc55cSDimitry Andric Discriminator, DataLocation, Associated, Allocated, 781349cc55cSDimitry Andric Rank, Annotations)); 7820b57cec5SDimitry Andric Metadata *Ops[] = {File, Scope, Name, BaseType, 7830b57cec5SDimitry Andric Elements, VTableHolder, TemplateParams, Identifier, 784e8d8bef9SDimitry Andric Discriminator, DataLocation, Associated, Allocated, 785349cc55cSDimitry Andric Rank, Annotations}; 786349cc55cSDimitry Andric DEFINE_GETIMPL_STORE( 787349cc55cSDimitry Andric DICompositeType, 788349cc55cSDimitry Andric (Tag, Line, RuntimeLang, SizeInBits, AlignInBits, OffsetInBits, Flags), 7890b57cec5SDimitry Andric Ops); 7900b57cec5SDimitry Andric } 7910b57cec5SDimitry Andric 7920b57cec5SDimitry Andric DICompositeType *DICompositeType::buildODRType( 7930b57cec5SDimitry Andric LLVMContext &Context, MDString &Identifier, unsigned Tag, MDString *Name, 7940b57cec5SDimitry Andric Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType, 7950b57cec5SDimitry Andric uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, 7960b57cec5SDimitry Andric DIFlags Flags, Metadata *Elements, unsigned RuntimeLang, 7975ffd83dbSDimitry Andric Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator, 798e8d8bef9SDimitry Andric Metadata *DataLocation, Metadata *Associated, Metadata *Allocated, 799349cc55cSDimitry Andric Metadata *Rank, Metadata *Annotations) { 8000b57cec5SDimitry Andric assert(!Identifier.getString().empty() && "Expected valid identifier"); 8010b57cec5SDimitry Andric if (!Context.isODRUniquingDebugTypes()) 8020b57cec5SDimitry Andric return nullptr; 8030b57cec5SDimitry Andric auto *&CT = (*Context.pImpl->DITypeMap)[&Identifier]; 8040b57cec5SDimitry Andric if (!CT) 8050b57cec5SDimitry Andric return CT = DICompositeType::getDistinct( 8060b57cec5SDimitry Andric Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, 8070b57cec5SDimitry Andric AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, 8085ffd83dbSDimitry Andric VTableHolder, TemplateParams, &Identifier, Discriminator, 809349cc55cSDimitry Andric DataLocation, Associated, Allocated, Rank, Annotations); 810349cc55cSDimitry Andric 811349cc55cSDimitry Andric if (CT->getTag() != Tag) 812349cc55cSDimitry Andric return nullptr; 8130b57cec5SDimitry Andric 8140b57cec5SDimitry Andric // Only mutate CT if it's a forward declaration and the new operands aren't. 8150b57cec5SDimitry Andric assert(CT->getRawIdentifier() == &Identifier && "Wrong ODR identifier?"); 8160b57cec5SDimitry Andric if (!CT->isForwardDecl() || (Flags & DINode::FlagFwdDecl)) 8170b57cec5SDimitry Andric return CT; 8180b57cec5SDimitry Andric 8190b57cec5SDimitry Andric // Mutate CT in place. Keep this in sync with getImpl. 8200b57cec5SDimitry Andric CT->mutate(Tag, Line, RuntimeLang, SizeInBits, AlignInBits, OffsetInBits, 8210b57cec5SDimitry Andric Flags); 8220b57cec5SDimitry Andric Metadata *Ops[] = {File, Scope, Name, BaseType, 8230b57cec5SDimitry Andric Elements, VTableHolder, TemplateParams, &Identifier, 824e8d8bef9SDimitry Andric Discriminator, DataLocation, Associated, Allocated, 825349cc55cSDimitry Andric Rank, Annotations}; 8260b57cec5SDimitry Andric assert((std::end(Ops) - std::begin(Ops)) == (int)CT->getNumOperands() && 8270b57cec5SDimitry Andric "Mismatched number of operands"); 8280b57cec5SDimitry Andric for (unsigned I = 0, E = CT->getNumOperands(); I != E; ++I) 8290b57cec5SDimitry Andric if (Ops[I] != CT->getOperand(I)) 8300b57cec5SDimitry Andric CT->setOperand(I, Ops[I]); 8310b57cec5SDimitry Andric return CT; 8320b57cec5SDimitry Andric } 8330b57cec5SDimitry Andric 8340b57cec5SDimitry Andric DICompositeType *DICompositeType::getODRType( 8350b57cec5SDimitry Andric LLVMContext &Context, MDString &Identifier, unsigned Tag, MDString *Name, 8360b57cec5SDimitry Andric Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType, 8370b57cec5SDimitry Andric uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, 8380b57cec5SDimitry Andric DIFlags Flags, Metadata *Elements, unsigned RuntimeLang, 8395ffd83dbSDimitry Andric Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator, 840e8d8bef9SDimitry Andric Metadata *DataLocation, Metadata *Associated, Metadata *Allocated, 841349cc55cSDimitry Andric Metadata *Rank, Metadata *Annotations) { 8420b57cec5SDimitry Andric assert(!Identifier.getString().empty() && "Expected valid identifier"); 8430b57cec5SDimitry Andric if (!Context.isODRUniquingDebugTypes()) 8440b57cec5SDimitry Andric return nullptr; 8450b57cec5SDimitry Andric auto *&CT = (*Context.pImpl->DITypeMap)[&Identifier]; 846349cc55cSDimitry Andric if (!CT) { 8470b57cec5SDimitry Andric CT = DICompositeType::getDistinct( 8480b57cec5SDimitry Andric Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, 8490b57cec5SDimitry Andric AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, 850e8d8bef9SDimitry Andric TemplateParams, &Identifier, Discriminator, DataLocation, Associated, 851349cc55cSDimitry Andric Allocated, Rank, Annotations); 852349cc55cSDimitry Andric } else { 853349cc55cSDimitry Andric if (CT->getTag() != Tag) 854349cc55cSDimitry Andric return nullptr; 855349cc55cSDimitry Andric } 8560b57cec5SDimitry Andric return CT; 8570b57cec5SDimitry Andric } 8580b57cec5SDimitry Andric 8590b57cec5SDimitry Andric DICompositeType *DICompositeType::getODRTypeIfExists(LLVMContext &Context, 8600b57cec5SDimitry Andric MDString &Identifier) { 8610b57cec5SDimitry Andric assert(!Identifier.getString().empty() && "Expected valid identifier"); 8620b57cec5SDimitry Andric if (!Context.isODRUniquingDebugTypes()) 8630b57cec5SDimitry Andric return nullptr; 8640b57cec5SDimitry Andric return Context.pImpl->DITypeMap->lookup(&Identifier); 8650b57cec5SDimitry Andric } 86681ad6265SDimitry Andric DISubroutineType::DISubroutineType(LLVMContext &C, StorageType Storage, 86781ad6265SDimitry Andric DIFlags Flags, uint8_t CC, 86881ad6265SDimitry Andric ArrayRef<Metadata *> Ops) 86981ad6265SDimitry Andric : DIType(C, DISubroutineTypeKind, Storage, dwarf::DW_TAG_subroutine_type, 0, 87081ad6265SDimitry Andric 0, 0, 0, Flags, Ops), 87181ad6265SDimitry Andric CC(CC) {} 8720b57cec5SDimitry Andric 8730b57cec5SDimitry Andric DISubroutineType *DISubroutineType::getImpl(LLVMContext &Context, DIFlags Flags, 8740b57cec5SDimitry Andric uint8_t CC, Metadata *TypeArray, 8750b57cec5SDimitry Andric StorageType Storage, 8760b57cec5SDimitry Andric bool ShouldCreate) { 8770b57cec5SDimitry Andric DEFINE_GETIMPL_LOOKUP(DISubroutineType, (Flags, CC, TypeArray)); 8780b57cec5SDimitry Andric Metadata *Ops[] = {nullptr, nullptr, nullptr, TypeArray}; 8790b57cec5SDimitry Andric DEFINE_GETIMPL_STORE(DISubroutineType, (Flags, CC), Ops); 8800b57cec5SDimitry Andric } 8810b57cec5SDimitry Andric 88281ad6265SDimitry Andric DIFile::DIFile(LLVMContext &C, StorageType Storage, 883bdd1243dSDimitry Andric std::optional<ChecksumInfo<MDString *>> CS, MDString *Src, 88481ad6265SDimitry Andric ArrayRef<Metadata *> Ops) 88581ad6265SDimitry Andric : DIScope(C, DIFileKind, Storage, dwarf::DW_TAG_file_type, Ops), 88681ad6265SDimitry Andric Checksum(CS), Source(Src) {} 88781ad6265SDimitry Andric 8880b57cec5SDimitry Andric // FIXME: Implement this string-enum correspondence with a .def file and macros, 8890b57cec5SDimitry Andric // so that the association is explicit rather than implied. 8900b57cec5SDimitry Andric static const char *ChecksumKindName[DIFile::CSK_Last] = { 8910b57cec5SDimitry Andric "CSK_MD5", 8925ffd83dbSDimitry Andric "CSK_SHA1", 8935ffd83dbSDimitry Andric "CSK_SHA256", 8940b57cec5SDimitry Andric }; 8950b57cec5SDimitry Andric 8960b57cec5SDimitry Andric StringRef DIFile::getChecksumKindAsString(ChecksumKind CSKind) { 8970b57cec5SDimitry Andric assert(CSKind <= DIFile::CSK_Last && "Invalid checksum kind"); 8980b57cec5SDimitry Andric // The first space was originally the CSK_None variant, which is now 8990b57cec5SDimitry Andric // obsolete, but the space is still reserved in ChecksumKind, so we account 9000b57cec5SDimitry Andric // for it here. 9010b57cec5SDimitry Andric return ChecksumKindName[CSKind - 1]; 9020b57cec5SDimitry Andric } 9030b57cec5SDimitry Andric 904bdd1243dSDimitry Andric std::optional<DIFile::ChecksumKind> 905bdd1243dSDimitry Andric DIFile::getChecksumKind(StringRef CSKindStr) { 906bdd1243dSDimitry Andric return StringSwitch<std::optional<DIFile::ChecksumKind>>(CSKindStr) 9070b57cec5SDimitry Andric .Case("CSK_MD5", DIFile::CSK_MD5) 9080b57cec5SDimitry Andric .Case("CSK_SHA1", DIFile::CSK_SHA1) 9095ffd83dbSDimitry Andric .Case("CSK_SHA256", DIFile::CSK_SHA256) 910bdd1243dSDimitry Andric .Default(std::nullopt); 9110b57cec5SDimitry Andric } 9120b57cec5SDimitry Andric 9130b57cec5SDimitry Andric DIFile *DIFile::getImpl(LLVMContext &Context, MDString *Filename, 9140b57cec5SDimitry Andric MDString *Directory, 915bdd1243dSDimitry Andric std::optional<DIFile::ChecksumInfo<MDString *>> CS, 916bdd1243dSDimitry Andric MDString *Source, StorageType Storage, 9170b57cec5SDimitry Andric bool ShouldCreate) { 9180b57cec5SDimitry Andric assert(isCanonical(Filename) && "Expected canonical MDString"); 9190b57cec5SDimitry Andric assert(isCanonical(Directory) && "Expected canonical MDString"); 9200b57cec5SDimitry Andric assert((!CS || isCanonical(CS->Value)) && "Expected canonical MDString"); 921bdd1243dSDimitry Andric // We do *NOT* expect Source to be a canonical MDString because nullptr 922bdd1243dSDimitry Andric // means none, so we need something to represent the empty file. 9230b57cec5SDimitry Andric DEFINE_GETIMPL_LOOKUP(DIFile, (Filename, Directory, CS, Source)); 924bdd1243dSDimitry Andric Metadata *Ops[] = {Filename, Directory, CS ? CS->Value : nullptr, Source}; 9250b57cec5SDimitry Andric DEFINE_GETIMPL_STORE(DIFile, (CS, Source), Ops); 9260b57cec5SDimitry Andric } 92781ad6265SDimitry Andric DICompileUnit::DICompileUnit(LLVMContext &C, StorageType Storage, 92881ad6265SDimitry Andric unsigned SourceLanguage, bool IsOptimized, 92981ad6265SDimitry Andric unsigned RuntimeVersion, unsigned EmissionKind, 93081ad6265SDimitry Andric uint64_t DWOId, bool SplitDebugInlining, 93181ad6265SDimitry Andric bool DebugInfoForProfiling, unsigned NameTableKind, 93281ad6265SDimitry Andric bool RangesBaseAddress, ArrayRef<Metadata *> Ops) 93381ad6265SDimitry Andric : DIScope(C, DICompileUnitKind, Storage, dwarf::DW_TAG_compile_unit, Ops), 9345f757f3fSDimitry Andric SourceLanguage(SourceLanguage), RuntimeVersion(RuntimeVersion), 9355f757f3fSDimitry Andric DWOId(DWOId), EmissionKind(EmissionKind), NameTableKind(NameTableKind), 9365f757f3fSDimitry Andric IsOptimized(IsOptimized), SplitDebugInlining(SplitDebugInlining), 93781ad6265SDimitry Andric DebugInfoForProfiling(DebugInfoForProfiling), 9385f757f3fSDimitry Andric RangesBaseAddress(RangesBaseAddress) { 93981ad6265SDimitry Andric assert(Storage != Uniqued); 94081ad6265SDimitry Andric } 9410b57cec5SDimitry Andric 9420b57cec5SDimitry Andric DICompileUnit *DICompileUnit::getImpl( 9430b57cec5SDimitry Andric LLVMContext &Context, unsigned SourceLanguage, Metadata *File, 9440b57cec5SDimitry Andric MDString *Producer, bool IsOptimized, MDString *Flags, 9450b57cec5SDimitry Andric unsigned RuntimeVersion, MDString *SplitDebugFilename, 9460b57cec5SDimitry Andric unsigned EmissionKind, Metadata *EnumTypes, Metadata *RetainedTypes, 9470b57cec5SDimitry Andric Metadata *GlobalVariables, Metadata *ImportedEntities, Metadata *Macros, 9480b57cec5SDimitry Andric uint64_t DWOId, bool SplitDebugInlining, bool DebugInfoForProfiling, 9495ffd83dbSDimitry Andric unsigned NameTableKind, bool RangesBaseAddress, MDString *SysRoot, 9505ffd83dbSDimitry Andric MDString *SDK, StorageType Storage, bool ShouldCreate) { 9510b57cec5SDimitry Andric assert(Storage != Uniqued && "Cannot unique DICompileUnit"); 9520b57cec5SDimitry Andric assert(isCanonical(Producer) && "Expected canonical MDString"); 9530b57cec5SDimitry Andric assert(isCanonical(Flags) && "Expected canonical MDString"); 9540b57cec5SDimitry Andric assert(isCanonical(SplitDebugFilename) && "Expected canonical MDString"); 9550b57cec5SDimitry Andric 9565ffd83dbSDimitry Andric Metadata *Ops[] = {File, 9575ffd83dbSDimitry Andric Producer, 9585ffd83dbSDimitry Andric Flags, 9595ffd83dbSDimitry Andric SplitDebugFilename, 9605ffd83dbSDimitry Andric EnumTypes, 9615ffd83dbSDimitry Andric RetainedTypes, 9625ffd83dbSDimitry Andric GlobalVariables, 9635ffd83dbSDimitry Andric ImportedEntities, 9645ffd83dbSDimitry Andric Macros, 9655ffd83dbSDimitry Andric SysRoot, 9665ffd83dbSDimitry Andric SDK}; 967bdd1243dSDimitry Andric return storeImpl(new (std::size(Ops), Storage) DICompileUnit( 9680b57cec5SDimitry Andric Context, Storage, SourceLanguage, IsOptimized, 9690b57cec5SDimitry Andric RuntimeVersion, EmissionKind, DWOId, SplitDebugInlining, 9700b57cec5SDimitry Andric DebugInfoForProfiling, NameTableKind, RangesBaseAddress, 9710b57cec5SDimitry Andric Ops), 9720b57cec5SDimitry Andric Storage); 9730b57cec5SDimitry Andric } 9740b57cec5SDimitry Andric 975bdd1243dSDimitry Andric std::optional<DICompileUnit::DebugEmissionKind> 9760b57cec5SDimitry Andric DICompileUnit::getEmissionKind(StringRef Str) { 977bdd1243dSDimitry Andric return StringSwitch<std::optional<DebugEmissionKind>>(Str) 9780b57cec5SDimitry Andric .Case("NoDebug", NoDebug) 9790b57cec5SDimitry Andric .Case("FullDebug", FullDebug) 9800b57cec5SDimitry Andric .Case("LineTablesOnly", LineTablesOnly) 9810b57cec5SDimitry Andric .Case("DebugDirectivesOnly", DebugDirectivesOnly) 982bdd1243dSDimitry Andric .Default(std::nullopt); 9830b57cec5SDimitry Andric } 9840b57cec5SDimitry Andric 985bdd1243dSDimitry Andric std::optional<DICompileUnit::DebugNameTableKind> 9860b57cec5SDimitry Andric DICompileUnit::getNameTableKind(StringRef Str) { 987bdd1243dSDimitry Andric return StringSwitch<std::optional<DebugNameTableKind>>(Str) 9880b57cec5SDimitry Andric .Case("Default", DebugNameTableKind::Default) 9890b57cec5SDimitry Andric .Case("GNU", DebugNameTableKind::GNU) 99006c3fb27SDimitry Andric .Case("Apple", DebugNameTableKind::Apple) 9910b57cec5SDimitry Andric .Case("None", DebugNameTableKind::None) 992bdd1243dSDimitry Andric .Default(std::nullopt); 9930b57cec5SDimitry Andric } 9940b57cec5SDimitry Andric 9950b57cec5SDimitry Andric const char *DICompileUnit::emissionKindString(DebugEmissionKind EK) { 9960b57cec5SDimitry Andric switch (EK) { 997349cc55cSDimitry Andric case NoDebug: 998349cc55cSDimitry Andric return "NoDebug"; 999349cc55cSDimitry Andric case FullDebug: 1000349cc55cSDimitry Andric return "FullDebug"; 1001349cc55cSDimitry Andric case LineTablesOnly: 1002349cc55cSDimitry Andric return "LineTablesOnly"; 1003349cc55cSDimitry Andric case DebugDirectivesOnly: 1004349cc55cSDimitry Andric return "DebugDirectivesOnly"; 10050b57cec5SDimitry Andric } 10060b57cec5SDimitry Andric return nullptr; 10070b57cec5SDimitry Andric } 10080b57cec5SDimitry Andric 10090b57cec5SDimitry Andric const char *DICompileUnit::nameTableKindString(DebugNameTableKind NTK) { 10100b57cec5SDimitry Andric switch (NTK) { 10110b57cec5SDimitry Andric case DebugNameTableKind::Default: 10120b57cec5SDimitry Andric return nullptr; 10130b57cec5SDimitry Andric case DebugNameTableKind::GNU: 10140b57cec5SDimitry Andric return "GNU"; 101506c3fb27SDimitry Andric case DebugNameTableKind::Apple: 101606c3fb27SDimitry Andric return "Apple"; 10170b57cec5SDimitry Andric case DebugNameTableKind::None: 10180b57cec5SDimitry Andric return "None"; 10190b57cec5SDimitry Andric } 10200b57cec5SDimitry Andric return nullptr; 10210b57cec5SDimitry Andric } 102281ad6265SDimitry Andric DISubprogram::DISubprogram(LLVMContext &C, StorageType Storage, unsigned Line, 102381ad6265SDimitry Andric unsigned ScopeLine, unsigned VirtualIndex, 102481ad6265SDimitry Andric int ThisAdjustment, DIFlags Flags, DISPFlags SPFlags, 102581ad6265SDimitry Andric ArrayRef<Metadata *> Ops) 102681ad6265SDimitry Andric : DILocalScope(C, DISubprogramKind, Storage, dwarf::DW_TAG_subprogram, Ops), 102781ad6265SDimitry Andric Line(Line), ScopeLine(ScopeLine), VirtualIndex(VirtualIndex), 102881ad6265SDimitry Andric ThisAdjustment(ThisAdjustment), Flags(Flags), SPFlags(SPFlags) { 102981ad6265SDimitry Andric static_assert(dwarf::DW_VIRTUALITY_max < 4, "Virtuality out of range"); 103081ad6265SDimitry Andric } 103181ad6265SDimitry Andric DISubprogram::DISPFlags 103281ad6265SDimitry Andric DISubprogram::toSPFlags(bool IsLocalToUnit, bool IsDefinition, bool IsOptimized, 103381ad6265SDimitry Andric unsigned Virtuality, bool IsMainSubprogram) { 103481ad6265SDimitry Andric // We're assuming virtuality is the low-order field. 103581ad6265SDimitry Andric static_assert(int(SPFlagVirtual) == int(dwarf::DW_VIRTUALITY_virtual) && 103681ad6265SDimitry Andric int(SPFlagPureVirtual) == 103781ad6265SDimitry Andric int(dwarf::DW_VIRTUALITY_pure_virtual), 103881ad6265SDimitry Andric "Virtuality constant mismatch"); 103981ad6265SDimitry Andric return static_cast<DISPFlags>( 104081ad6265SDimitry Andric (Virtuality & SPFlagVirtuality) | 104181ad6265SDimitry Andric (IsLocalToUnit ? SPFlagLocalToUnit : SPFlagZero) | 104281ad6265SDimitry Andric (IsDefinition ? SPFlagDefinition : SPFlagZero) | 104381ad6265SDimitry Andric (IsOptimized ? SPFlagOptimized : SPFlagZero) | 104481ad6265SDimitry Andric (IsMainSubprogram ? SPFlagMainSubprogram : SPFlagZero)); 104581ad6265SDimitry Andric } 10460b57cec5SDimitry Andric 10470b57cec5SDimitry Andric DISubprogram *DILocalScope::getSubprogram() const { 10480b57cec5SDimitry Andric if (auto *Block = dyn_cast<DILexicalBlockBase>(this)) 10490b57cec5SDimitry Andric return Block->getScope()->getSubprogram(); 10500b57cec5SDimitry Andric return const_cast<DISubprogram *>(cast<DISubprogram>(this)); 10510b57cec5SDimitry Andric } 10520b57cec5SDimitry Andric 10530b57cec5SDimitry Andric DILocalScope *DILocalScope::getNonLexicalBlockFileScope() const { 10540b57cec5SDimitry Andric if (auto *File = dyn_cast<DILexicalBlockFile>(this)) 10550b57cec5SDimitry Andric return File->getScope()->getNonLexicalBlockFileScope(); 10560b57cec5SDimitry Andric return const_cast<DILocalScope *>(this); 10570b57cec5SDimitry Andric } 10580b57cec5SDimitry Andric 1059bdd1243dSDimitry Andric DILocalScope *DILocalScope::cloneScopeForSubprogram( 1060bdd1243dSDimitry Andric DILocalScope &RootScope, DISubprogram &NewSP, LLVMContext &Ctx, 1061bdd1243dSDimitry Andric DenseMap<const MDNode *, MDNode *> &Cache) { 1062bdd1243dSDimitry Andric SmallVector<DIScope *> ScopeChain; 1063bdd1243dSDimitry Andric DIScope *CachedResult = nullptr; 1064bdd1243dSDimitry Andric 1065bdd1243dSDimitry Andric for (DIScope *Scope = &RootScope; !isa<DISubprogram>(Scope); 1066bdd1243dSDimitry Andric Scope = Scope->getScope()) { 1067bdd1243dSDimitry Andric if (auto It = Cache.find(Scope); It != Cache.end()) { 1068bdd1243dSDimitry Andric CachedResult = cast<DIScope>(It->second); 1069bdd1243dSDimitry Andric break; 1070bdd1243dSDimitry Andric } 1071bdd1243dSDimitry Andric ScopeChain.push_back(Scope); 1072bdd1243dSDimitry Andric } 1073bdd1243dSDimitry Andric 1074bdd1243dSDimitry Andric // Recreate the scope chain, bottom-up, starting at the new subprogram (or a 1075bdd1243dSDimitry Andric // cached result). 1076bdd1243dSDimitry Andric DIScope *UpdatedScope = CachedResult ? CachedResult : &NewSP; 1077bdd1243dSDimitry Andric for (DIScope *ScopeToUpdate : reverse(ScopeChain)) { 1078bdd1243dSDimitry Andric TempMDNode ClonedScope = ScopeToUpdate->clone(); 1079bdd1243dSDimitry Andric cast<DILexicalBlockBase>(*ClonedScope).replaceScope(UpdatedScope); 1080bdd1243dSDimitry Andric UpdatedScope = 1081bdd1243dSDimitry Andric cast<DIScope>(MDNode::replaceWithUniqued(std::move(ClonedScope))); 1082bdd1243dSDimitry Andric Cache[ScopeToUpdate] = UpdatedScope; 1083bdd1243dSDimitry Andric } 1084bdd1243dSDimitry Andric 1085bdd1243dSDimitry Andric return cast<DILocalScope>(UpdatedScope); 1086bdd1243dSDimitry Andric } 1087bdd1243dSDimitry Andric 10880b57cec5SDimitry Andric DISubprogram::DISPFlags DISubprogram::getFlag(StringRef Flag) { 10890b57cec5SDimitry Andric return StringSwitch<DISPFlags>(Flag) 10900b57cec5SDimitry Andric #define HANDLE_DISP_FLAG(ID, NAME) .Case("DISPFlag" #NAME, SPFlag##NAME) 10910b57cec5SDimitry Andric #include "llvm/IR/DebugInfoFlags.def" 10920b57cec5SDimitry Andric .Default(SPFlagZero); 10930b57cec5SDimitry Andric } 10940b57cec5SDimitry Andric 10950b57cec5SDimitry Andric StringRef DISubprogram::getFlagString(DISPFlags Flag) { 10960b57cec5SDimitry Andric switch (Flag) { 10970b57cec5SDimitry Andric // Appease a warning. 10980b57cec5SDimitry Andric case SPFlagVirtuality: 10990b57cec5SDimitry Andric return ""; 11000b57cec5SDimitry Andric #define HANDLE_DISP_FLAG(ID, NAME) \ 11010b57cec5SDimitry Andric case SPFlag##NAME: \ 11020b57cec5SDimitry Andric return "DISPFlag" #NAME; 11030b57cec5SDimitry Andric #include "llvm/IR/DebugInfoFlags.def" 11040b57cec5SDimitry Andric } 11050b57cec5SDimitry Andric return ""; 11060b57cec5SDimitry Andric } 11070b57cec5SDimitry Andric 11080b57cec5SDimitry Andric DISubprogram::DISPFlags 11090b57cec5SDimitry Andric DISubprogram::splitFlags(DISPFlags Flags, 11100b57cec5SDimitry Andric SmallVectorImpl<DISPFlags> &SplitFlags) { 11110b57cec5SDimitry Andric // Multi-bit fields can require special handling. In our case, however, the 11120b57cec5SDimitry Andric // only multi-bit field is virtuality, and all its values happen to be 11130b57cec5SDimitry Andric // single-bit values, so the right behavior just falls out. 11140b57cec5SDimitry Andric #define HANDLE_DISP_FLAG(ID, NAME) \ 11150b57cec5SDimitry Andric if (DISPFlags Bit = Flags & SPFlag##NAME) { \ 11160b57cec5SDimitry Andric SplitFlags.push_back(Bit); \ 11170b57cec5SDimitry Andric Flags &= ~Bit; \ 11180b57cec5SDimitry Andric } 11190b57cec5SDimitry Andric #include "llvm/IR/DebugInfoFlags.def" 11200b57cec5SDimitry Andric return Flags; 11210b57cec5SDimitry Andric } 11220b57cec5SDimitry Andric 11230b57cec5SDimitry Andric DISubprogram *DISubprogram::getImpl( 11240b57cec5SDimitry Andric LLVMContext &Context, Metadata *Scope, MDString *Name, 11250b57cec5SDimitry Andric MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type, 11260b57cec5SDimitry Andric unsigned ScopeLine, Metadata *ContainingType, unsigned VirtualIndex, 11270b57cec5SDimitry Andric int ThisAdjustment, DIFlags Flags, DISPFlags SPFlags, Metadata *Unit, 11280b57cec5SDimitry Andric Metadata *TemplateParams, Metadata *Declaration, Metadata *RetainedNodes, 112981ad6265SDimitry Andric Metadata *ThrownTypes, Metadata *Annotations, MDString *TargetFuncName, 113081ad6265SDimitry Andric StorageType Storage, bool ShouldCreate) { 11310b57cec5SDimitry Andric assert(isCanonical(Name) && "Expected canonical MDString"); 11320b57cec5SDimitry Andric assert(isCanonical(LinkageName) && "Expected canonical MDString"); 113381ad6265SDimitry Andric assert(isCanonical(TargetFuncName) && "Expected canonical MDString"); 11340b57cec5SDimitry Andric DEFINE_GETIMPL_LOOKUP(DISubprogram, 11350b57cec5SDimitry Andric (Scope, Name, LinkageName, File, Line, Type, ScopeLine, 11360b57cec5SDimitry Andric ContainingType, VirtualIndex, ThisAdjustment, Flags, 11370b57cec5SDimitry Andric SPFlags, Unit, TemplateParams, Declaration, 113881ad6265SDimitry Andric RetainedNodes, ThrownTypes, Annotations, 113981ad6265SDimitry Andric TargetFuncName)); 114081ad6265SDimitry Andric SmallVector<Metadata *, 13> Ops = { 1141349cc55cSDimitry Andric File, Scope, Name, LinkageName, 1142349cc55cSDimitry Andric Type, Unit, Declaration, RetainedNodes, 114381ad6265SDimitry Andric ContainingType, TemplateParams, ThrownTypes, Annotations, 114481ad6265SDimitry Andric TargetFuncName}; 114581ad6265SDimitry Andric if (!TargetFuncName) { 114681ad6265SDimitry Andric Ops.pop_back(); 1147349cc55cSDimitry Andric if (!Annotations) { 1148349cc55cSDimitry Andric Ops.pop_back(); 11490b57cec5SDimitry Andric if (!ThrownTypes) { 11500b57cec5SDimitry Andric Ops.pop_back(); 11510b57cec5SDimitry Andric if (!TemplateParams) { 11520b57cec5SDimitry Andric Ops.pop_back(); 11530b57cec5SDimitry Andric if (!ContainingType) 11540b57cec5SDimitry Andric Ops.pop_back(); 11550b57cec5SDimitry Andric } 11560b57cec5SDimitry Andric } 1157349cc55cSDimitry Andric } 115881ad6265SDimitry Andric } 11590b57cec5SDimitry Andric DEFINE_GETIMPL_STORE_N( 11600b57cec5SDimitry Andric DISubprogram, 11610b57cec5SDimitry Andric (Line, ScopeLine, VirtualIndex, ThisAdjustment, Flags, SPFlags), Ops, 11620b57cec5SDimitry Andric Ops.size()); 11630b57cec5SDimitry Andric } 11640b57cec5SDimitry Andric 11650b57cec5SDimitry Andric bool DISubprogram::describes(const Function *F) const { 11660b57cec5SDimitry Andric assert(F && "Invalid function"); 11675ffd83dbSDimitry Andric return F->getSubprogram() == this; 11680b57cec5SDimitry Andric } 116981ad6265SDimitry Andric DILexicalBlockBase::DILexicalBlockBase(LLVMContext &C, unsigned ID, 117081ad6265SDimitry Andric StorageType Storage, 117181ad6265SDimitry Andric ArrayRef<Metadata *> Ops) 117281ad6265SDimitry Andric : DILocalScope(C, ID, Storage, dwarf::DW_TAG_lexical_block, Ops) {} 11730b57cec5SDimitry Andric 11740b57cec5SDimitry Andric DILexicalBlock *DILexicalBlock::getImpl(LLVMContext &Context, Metadata *Scope, 11750b57cec5SDimitry Andric Metadata *File, unsigned Line, 11760b57cec5SDimitry Andric unsigned Column, StorageType Storage, 11770b57cec5SDimitry Andric bool ShouldCreate) { 11780b57cec5SDimitry Andric // Fixup column. 11790b57cec5SDimitry Andric adjustColumn(Column); 11800b57cec5SDimitry Andric 11810b57cec5SDimitry Andric assert(Scope && "Expected scope"); 11820b57cec5SDimitry Andric DEFINE_GETIMPL_LOOKUP(DILexicalBlock, (Scope, File, Line, Column)); 11830b57cec5SDimitry Andric Metadata *Ops[] = {File, Scope}; 11840b57cec5SDimitry Andric DEFINE_GETIMPL_STORE(DILexicalBlock, (Line, Column), Ops); 11850b57cec5SDimitry Andric } 11860b57cec5SDimitry Andric 11870b57cec5SDimitry Andric DILexicalBlockFile *DILexicalBlockFile::getImpl(LLVMContext &Context, 11880b57cec5SDimitry Andric Metadata *Scope, Metadata *File, 11890b57cec5SDimitry Andric unsigned Discriminator, 11900b57cec5SDimitry Andric StorageType Storage, 11910b57cec5SDimitry Andric bool ShouldCreate) { 11920b57cec5SDimitry Andric assert(Scope && "Expected scope"); 11930b57cec5SDimitry Andric DEFINE_GETIMPL_LOOKUP(DILexicalBlockFile, (Scope, File, Discriminator)); 11940b57cec5SDimitry Andric Metadata *Ops[] = {File, Scope}; 11950b57cec5SDimitry Andric DEFINE_GETIMPL_STORE(DILexicalBlockFile, (Discriminator), Ops); 11960b57cec5SDimitry Andric } 11970b57cec5SDimitry Andric 119881ad6265SDimitry Andric DINamespace::DINamespace(LLVMContext &Context, StorageType Storage, 119981ad6265SDimitry Andric bool ExportSymbols, ArrayRef<Metadata *> Ops) 12005f757f3fSDimitry Andric : DIScope(Context, DINamespaceKind, Storage, dwarf::DW_TAG_namespace, Ops) { 12015f757f3fSDimitry Andric SubclassData1 = ExportSymbols; 12025f757f3fSDimitry Andric } 12030b57cec5SDimitry Andric DINamespace *DINamespace::getImpl(LLVMContext &Context, Metadata *Scope, 12040b57cec5SDimitry Andric MDString *Name, bool ExportSymbols, 12050b57cec5SDimitry Andric StorageType Storage, bool ShouldCreate) { 12060b57cec5SDimitry Andric assert(isCanonical(Name) && "Expected canonical MDString"); 12070b57cec5SDimitry Andric DEFINE_GETIMPL_LOOKUP(DINamespace, (Scope, Name, ExportSymbols)); 12080b57cec5SDimitry Andric // The nullptr is for DIScope's File operand. This should be refactored. 12090b57cec5SDimitry Andric Metadata *Ops[] = {nullptr, Scope, Name}; 12100b57cec5SDimitry Andric DEFINE_GETIMPL_STORE(DINamespace, (ExportSymbols), Ops); 12110b57cec5SDimitry Andric } 12120b57cec5SDimitry Andric 121381ad6265SDimitry Andric DICommonBlock::DICommonBlock(LLVMContext &Context, StorageType Storage, 121481ad6265SDimitry Andric unsigned LineNo, ArrayRef<Metadata *> Ops) 121581ad6265SDimitry Andric : DIScope(Context, DICommonBlockKind, Storage, dwarf::DW_TAG_common_block, 12165f757f3fSDimitry Andric Ops) { 12175f757f3fSDimitry Andric SubclassData32 = LineNo; 12185f757f3fSDimitry Andric } 12190b57cec5SDimitry Andric DICommonBlock *DICommonBlock::getImpl(LLVMContext &Context, Metadata *Scope, 12200b57cec5SDimitry Andric Metadata *Decl, MDString *Name, 12210b57cec5SDimitry Andric Metadata *File, unsigned LineNo, 12220b57cec5SDimitry Andric StorageType Storage, bool ShouldCreate) { 12230b57cec5SDimitry Andric assert(isCanonical(Name) && "Expected canonical MDString"); 12240b57cec5SDimitry Andric DEFINE_GETIMPL_LOOKUP(DICommonBlock, (Scope, Decl, Name, File, LineNo)); 12250b57cec5SDimitry Andric // The nullptr is for DIScope's File operand. This should be refactored. 12260b57cec5SDimitry Andric Metadata *Ops[] = {Scope, Decl, Name, File}; 12270b57cec5SDimitry Andric DEFINE_GETIMPL_STORE(DICommonBlock, (LineNo), Ops); 12280b57cec5SDimitry Andric } 12290b57cec5SDimitry Andric 123081ad6265SDimitry Andric DIModule::DIModule(LLVMContext &Context, StorageType Storage, unsigned LineNo, 123181ad6265SDimitry Andric bool IsDecl, ArrayRef<Metadata *> Ops) 12325f757f3fSDimitry Andric : DIScope(Context, DIModuleKind, Storage, dwarf::DW_TAG_module, Ops) { 12335f757f3fSDimitry Andric SubclassData1 = IsDecl; 12345f757f3fSDimitry Andric SubclassData32 = LineNo; 12355f757f3fSDimitry Andric } 12365ffd83dbSDimitry Andric DIModule *DIModule::getImpl(LLVMContext &Context, Metadata *File, 12375ffd83dbSDimitry Andric Metadata *Scope, MDString *Name, 12385ffd83dbSDimitry Andric MDString *ConfigurationMacros, 12395ffd83dbSDimitry Andric MDString *IncludePath, MDString *APINotesFile, 1240e8d8bef9SDimitry Andric unsigned LineNo, bool IsDecl, StorageType Storage, 12410b57cec5SDimitry Andric bool ShouldCreate) { 12420b57cec5SDimitry Andric assert(isCanonical(Name) && "Expected canonical MDString"); 12435ffd83dbSDimitry Andric DEFINE_GETIMPL_LOOKUP(DIModule, (File, Scope, Name, ConfigurationMacros, 1244e8d8bef9SDimitry Andric IncludePath, APINotesFile, LineNo, IsDecl)); 12455ffd83dbSDimitry Andric Metadata *Ops[] = {File, Scope, Name, ConfigurationMacros, 12465ffd83dbSDimitry Andric IncludePath, APINotesFile}; 1247e8d8bef9SDimitry Andric DEFINE_GETIMPL_STORE(DIModule, (LineNo, IsDecl), Ops); 12485ffd83dbSDimitry Andric } 124981ad6265SDimitry Andric DITemplateTypeParameter::DITemplateTypeParameter(LLVMContext &Context, 125081ad6265SDimitry Andric StorageType Storage, 125181ad6265SDimitry Andric bool IsDefault, 125281ad6265SDimitry Andric ArrayRef<Metadata *> Ops) 125381ad6265SDimitry Andric : DITemplateParameter(Context, DITemplateTypeParameterKind, Storage, 125481ad6265SDimitry Andric dwarf::DW_TAG_template_type_parameter, IsDefault, 125581ad6265SDimitry Andric Ops) {} 12565ffd83dbSDimitry Andric 12575ffd83dbSDimitry Andric DITemplateTypeParameter * 12585ffd83dbSDimitry Andric DITemplateTypeParameter::getImpl(LLVMContext &Context, MDString *Name, 12595ffd83dbSDimitry Andric Metadata *Type, bool isDefault, 12605ffd83dbSDimitry Andric StorageType Storage, bool ShouldCreate) { 12615ffd83dbSDimitry Andric assert(isCanonical(Name) && "Expected canonical MDString"); 12625ffd83dbSDimitry Andric DEFINE_GETIMPL_LOOKUP(DITemplateTypeParameter, (Name, Type, isDefault)); 12630b57cec5SDimitry Andric Metadata *Ops[] = {Name, Type}; 12645ffd83dbSDimitry Andric DEFINE_GETIMPL_STORE(DITemplateTypeParameter, (isDefault), Ops); 12650b57cec5SDimitry Andric } 12660b57cec5SDimitry Andric 12670b57cec5SDimitry Andric DITemplateValueParameter *DITemplateValueParameter::getImpl( 12680b57cec5SDimitry Andric LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *Type, 12695ffd83dbSDimitry Andric bool isDefault, Metadata *Value, StorageType Storage, bool ShouldCreate) { 12700b57cec5SDimitry Andric assert(isCanonical(Name) && "Expected canonical MDString"); 12715ffd83dbSDimitry Andric DEFINE_GETIMPL_LOOKUP(DITemplateValueParameter, 12725ffd83dbSDimitry Andric (Tag, Name, Type, isDefault, Value)); 12730b57cec5SDimitry Andric Metadata *Ops[] = {Name, Type, Value}; 12745ffd83dbSDimitry Andric DEFINE_GETIMPL_STORE(DITemplateValueParameter, (Tag, isDefault), Ops); 12750b57cec5SDimitry Andric } 12760b57cec5SDimitry Andric 12770b57cec5SDimitry Andric DIGlobalVariable * 12780b57cec5SDimitry Andric DIGlobalVariable::getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name, 12790b57cec5SDimitry Andric MDString *LinkageName, Metadata *File, unsigned Line, 12800b57cec5SDimitry Andric Metadata *Type, bool IsLocalToUnit, bool IsDefinition, 12810b57cec5SDimitry Andric Metadata *StaticDataMemberDeclaration, 12820b57cec5SDimitry Andric Metadata *TemplateParams, uint32_t AlignInBits, 1283349cc55cSDimitry Andric Metadata *Annotations, StorageType Storage, 1284349cc55cSDimitry Andric bool ShouldCreate) { 12850b57cec5SDimitry Andric assert(isCanonical(Name) && "Expected canonical MDString"); 12860b57cec5SDimitry Andric assert(isCanonical(LinkageName) && "Expected canonical MDString"); 1287349cc55cSDimitry Andric DEFINE_GETIMPL_LOOKUP( 1288349cc55cSDimitry Andric DIGlobalVariable, 1289349cc55cSDimitry Andric (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, 1290349cc55cSDimitry Andric StaticDataMemberDeclaration, TemplateParams, AlignInBits, Annotations)); 12910b57cec5SDimitry Andric Metadata *Ops[] = {Scope, 12920b57cec5SDimitry Andric Name, 12930b57cec5SDimitry Andric File, 12940b57cec5SDimitry Andric Type, 12950b57cec5SDimitry Andric Name, 12960b57cec5SDimitry Andric LinkageName, 12970b57cec5SDimitry Andric StaticDataMemberDeclaration, 1298349cc55cSDimitry Andric TemplateParams, 1299349cc55cSDimitry Andric Annotations}; 13000b57cec5SDimitry Andric DEFINE_GETIMPL_STORE(DIGlobalVariable, 13010b57cec5SDimitry Andric (Line, IsLocalToUnit, IsDefinition, AlignInBits), Ops); 13020b57cec5SDimitry Andric } 13030b57cec5SDimitry Andric 1304349cc55cSDimitry Andric DILocalVariable * 1305349cc55cSDimitry Andric DILocalVariable::getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name, 1306349cc55cSDimitry Andric Metadata *File, unsigned Line, Metadata *Type, 1307349cc55cSDimitry Andric unsigned Arg, DIFlags Flags, uint32_t AlignInBits, 1308349cc55cSDimitry Andric Metadata *Annotations, StorageType Storage, 13090b57cec5SDimitry Andric bool ShouldCreate) { 13100b57cec5SDimitry Andric // 64K ought to be enough for any frontend. 13110b57cec5SDimitry Andric assert(Arg <= UINT16_MAX && "Expected argument number to fit in 16-bits"); 13120b57cec5SDimitry Andric 13130b57cec5SDimitry Andric assert(Scope && "Expected scope"); 13140b57cec5SDimitry Andric assert(isCanonical(Name) && "Expected canonical MDString"); 1315349cc55cSDimitry Andric DEFINE_GETIMPL_LOOKUP(DILocalVariable, (Scope, Name, File, Line, Type, Arg, 1316349cc55cSDimitry Andric Flags, AlignInBits, Annotations)); 1317349cc55cSDimitry Andric Metadata *Ops[] = {Scope, Name, File, Type, Annotations}; 13180b57cec5SDimitry Andric DEFINE_GETIMPL_STORE(DILocalVariable, (Line, Arg, Flags, AlignInBits), Ops); 13190b57cec5SDimitry Andric } 13200b57cec5SDimitry Andric 132181ad6265SDimitry Andric DIVariable::DIVariable(LLVMContext &C, unsigned ID, StorageType Storage, 132281ad6265SDimitry Andric signed Line, ArrayRef<Metadata *> Ops, 132381ad6265SDimitry Andric uint32_t AlignInBits) 13245f757f3fSDimitry Andric : DINode(C, ID, Storage, dwarf::DW_TAG_variable, Ops), Line(Line) { 13255f757f3fSDimitry Andric SubclassData32 = AlignInBits; 13265f757f3fSDimitry Andric } 1327bdd1243dSDimitry Andric std::optional<uint64_t> DIVariable::getSizeInBits() const { 13280b57cec5SDimitry Andric // This is used by the Verifier so be mindful of broken types. 13290b57cec5SDimitry Andric const Metadata *RawType = getRawType(); 13300b57cec5SDimitry Andric while (RawType) { 13310b57cec5SDimitry Andric // Try to get the size directly. 13320b57cec5SDimitry Andric if (auto *T = dyn_cast<DIType>(RawType)) 13330b57cec5SDimitry Andric if (uint64_t Size = T->getSizeInBits()) 13340b57cec5SDimitry Andric return Size; 13350b57cec5SDimitry Andric 13360b57cec5SDimitry Andric if (auto *DT = dyn_cast<DIDerivedType>(RawType)) { 13370b57cec5SDimitry Andric // Look at the base type. 13380b57cec5SDimitry Andric RawType = DT->getRawBaseType(); 13390b57cec5SDimitry Andric continue; 13400b57cec5SDimitry Andric } 13410b57cec5SDimitry Andric 13420b57cec5SDimitry Andric // Missing type or size. 13430b57cec5SDimitry Andric break; 13440b57cec5SDimitry Andric } 13450b57cec5SDimitry Andric 13460b57cec5SDimitry Andric // Fail gracefully. 1347bdd1243dSDimitry Andric return std::nullopt; 13480b57cec5SDimitry Andric } 13490b57cec5SDimitry Andric 135081ad6265SDimitry Andric DILabel::DILabel(LLVMContext &C, StorageType Storage, unsigned Line, 135181ad6265SDimitry Andric ArrayRef<Metadata *> Ops) 13525f757f3fSDimitry Andric : DINode(C, DILabelKind, Storage, dwarf::DW_TAG_label, Ops) { 13535f757f3fSDimitry Andric SubclassData32 = Line; 13545f757f3fSDimitry Andric } 1355349cc55cSDimitry Andric DILabel *DILabel::getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name, 1356349cc55cSDimitry Andric Metadata *File, unsigned Line, StorageType Storage, 13570b57cec5SDimitry Andric bool ShouldCreate) { 13580b57cec5SDimitry Andric assert(Scope && "Expected scope"); 13590b57cec5SDimitry Andric assert(isCanonical(Name) && "Expected canonical MDString"); 1360349cc55cSDimitry Andric DEFINE_GETIMPL_LOOKUP(DILabel, (Scope, Name, File, Line)); 13610b57cec5SDimitry Andric Metadata *Ops[] = {Scope, Name, File}; 13620b57cec5SDimitry Andric DEFINE_GETIMPL_STORE(DILabel, (Line), Ops); 13630b57cec5SDimitry Andric } 13640b57cec5SDimitry Andric 13650b57cec5SDimitry Andric DIExpression *DIExpression::getImpl(LLVMContext &Context, 13660b57cec5SDimitry Andric ArrayRef<uint64_t> Elements, 13670b57cec5SDimitry Andric StorageType Storage, bool ShouldCreate) { 13680b57cec5SDimitry Andric DEFINE_GETIMPL_LOOKUP(DIExpression, (Elements)); 13690b57cec5SDimitry Andric DEFINE_GETIMPL_STORE_NO_OPS(DIExpression, (Elements)); 13700b57cec5SDimitry Andric } 137181ad6265SDimitry Andric bool DIExpression::isEntryValue() const { 13725f757f3fSDimitry Andric if (auto singleLocElts = getSingleLocationExpressionElements()) { 13735f757f3fSDimitry Andric return singleLocElts->size() > 0 && 13745f757f3fSDimitry Andric (*singleLocElts)[0] == dwarf::DW_OP_LLVM_entry_value; 13755f757f3fSDimitry Andric } 13765f757f3fSDimitry Andric return false; 137781ad6265SDimitry Andric } 137881ad6265SDimitry Andric bool DIExpression::startsWithDeref() const { 13795f757f3fSDimitry Andric if (auto singleLocElts = getSingleLocationExpressionElements()) 13805f757f3fSDimitry Andric return singleLocElts->size() > 0 && 13815f757f3fSDimitry Andric (*singleLocElts)[0] == dwarf::DW_OP_deref; 13825f757f3fSDimitry Andric return false; 138381ad6265SDimitry Andric } 138406c3fb27SDimitry Andric bool DIExpression::isDeref() const { 13855f757f3fSDimitry Andric if (auto singleLocElts = getSingleLocationExpressionElements()) 13865f757f3fSDimitry Andric return singleLocElts->size() == 1 && 13875f757f3fSDimitry Andric (*singleLocElts)[0] == dwarf::DW_OP_deref; 13885f757f3fSDimitry Andric return false; 138906c3fb27SDimitry Andric } 13900b57cec5SDimitry Andric 1391bdd1243dSDimitry Andric DIAssignID *DIAssignID::getImpl(LLVMContext &Context, StorageType Storage, 1392bdd1243dSDimitry Andric bool ShouldCreate) { 1393bdd1243dSDimitry Andric // Uniqued DIAssignID are not supported as the instance address *is* the ID. 1394bdd1243dSDimitry Andric assert(Storage != StorageType::Uniqued && "uniqued DIAssignID unsupported"); 1395bdd1243dSDimitry Andric return storeImpl(new (0u, Storage) DIAssignID(Context, Storage), Storage); 1396bdd1243dSDimitry Andric } 1397bdd1243dSDimitry Andric 13980b57cec5SDimitry Andric unsigned DIExpression::ExprOperand::getSize() const { 13998bcb0991SDimitry Andric uint64_t Op = getOp(); 14008bcb0991SDimitry Andric 14018bcb0991SDimitry Andric if (Op >= dwarf::DW_OP_breg0 && Op <= dwarf::DW_OP_breg31) 14028bcb0991SDimitry Andric return 2; 14038bcb0991SDimitry Andric 14048bcb0991SDimitry Andric switch (Op) { 14050b57cec5SDimitry Andric case dwarf::DW_OP_LLVM_convert: 14060b57cec5SDimitry Andric case dwarf::DW_OP_LLVM_fragment: 1407*0fca6ea1SDimitry Andric case dwarf::DW_OP_LLVM_extract_bits_sext: 1408*0fca6ea1SDimitry Andric case dwarf::DW_OP_LLVM_extract_bits_zext: 14098bcb0991SDimitry Andric case dwarf::DW_OP_bregx: 14100b57cec5SDimitry Andric return 3; 14110b57cec5SDimitry Andric case dwarf::DW_OP_constu: 14128bcb0991SDimitry Andric case dwarf::DW_OP_consts: 14130b57cec5SDimitry Andric case dwarf::DW_OP_deref_size: 14140b57cec5SDimitry Andric case dwarf::DW_OP_plus_uconst: 14150b57cec5SDimitry Andric case dwarf::DW_OP_LLVM_tag_offset: 14168bcb0991SDimitry Andric case dwarf::DW_OP_LLVM_entry_value: 1417fe6060f1SDimitry Andric case dwarf::DW_OP_LLVM_arg: 14188bcb0991SDimitry Andric case dwarf::DW_OP_regx: 14190b57cec5SDimitry Andric return 2; 14200b57cec5SDimitry Andric default: 14210b57cec5SDimitry Andric return 1; 14220b57cec5SDimitry Andric } 14230b57cec5SDimitry Andric } 14240b57cec5SDimitry Andric 14250b57cec5SDimitry Andric bool DIExpression::isValid() const { 14260b57cec5SDimitry Andric for (auto I = expr_op_begin(), E = expr_op_end(); I != E; ++I) { 14270b57cec5SDimitry Andric // Check that there's space for the operand. 14280b57cec5SDimitry Andric if (I->get() + I->getSize() > E->get()) 14290b57cec5SDimitry Andric return false; 14300b57cec5SDimitry Andric 14318bcb0991SDimitry Andric uint64_t Op = I->getOp(); 14328bcb0991SDimitry Andric if ((Op >= dwarf::DW_OP_reg0 && Op <= dwarf::DW_OP_reg31) || 14338bcb0991SDimitry Andric (Op >= dwarf::DW_OP_breg0 && Op <= dwarf::DW_OP_breg31)) 14348bcb0991SDimitry Andric return true; 14358bcb0991SDimitry Andric 14360b57cec5SDimitry Andric // Check that the operand is valid. 14378bcb0991SDimitry Andric switch (Op) { 14380b57cec5SDimitry Andric default: 14390b57cec5SDimitry Andric return false; 14400b57cec5SDimitry Andric case dwarf::DW_OP_LLVM_fragment: 14410b57cec5SDimitry Andric // A fragment operator must appear at the end. 14420b57cec5SDimitry Andric return I->get() + I->getSize() == E->get(); 14430b57cec5SDimitry Andric case dwarf::DW_OP_stack_value: { 14440b57cec5SDimitry Andric // Must be the last one or followed by a DW_OP_LLVM_fragment. 14450b57cec5SDimitry Andric if (I->get() + I->getSize() == E->get()) 14460b57cec5SDimitry Andric break; 14470b57cec5SDimitry Andric auto J = I; 14480b57cec5SDimitry Andric if ((++J)->getOp() != dwarf::DW_OP_LLVM_fragment) 14490b57cec5SDimitry Andric return false; 14500b57cec5SDimitry Andric break; 14510b57cec5SDimitry Andric } 14520b57cec5SDimitry Andric case dwarf::DW_OP_swap: { 14530b57cec5SDimitry Andric // Must be more than one implicit element on the stack. 14540b57cec5SDimitry Andric 14550b57cec5SDimitry Andric // FIXME: A better way to implement this would be to add a local variable 14560b57cec5SDimitry Andric // that keeps track of the stack depth and introduce something like a 14570b57cec5SDimitry Andric // DW_LLVM_OP_implicit_location as a placeholder for the location this 14580b57cec5SDimitry Andric // DIExpression is attached to, or else pass the number of implicit stack 14590b57cec5SDimitry Andric // elements into isValid. 14600b57cec5SDimitry Andric if (getNumElements() == 1) 14610b57cec5SDimitry Andric return false; 14620b57cec5SDimitry Andric break; 14630b57cec5SDimitry Andric } 14648bcb0991SDimitry Andric case dwarf::DW_OP_LLVM_entry_value: { 1465bdd1243dSDimitry Andric // An entry value operator must appear at the beginning or immediately 1466bdd1243dSDimitry Andric // following `DW_OP_LLVM_arg 0`, and the number of operations it cover can 1467bdd1243dSDimitry Andric // currently only be 1, because we support only entry values of a simple 1468bdd1243dSDimitry Andric // register location. One reason for this is that we currently can't 1469bdd1243dSDimitry Andric // calculate the size of the resulting DWARF block for other expressions. 1470bdd1243dSDimitry Andric auto FirstOp = expr_op_begin(); 1471bdd1243dSDimitry Andric if (FirstOp->getOp() == dwarf::DW_OP_LLVM_arg && FirstOp->getArg(0) == 0) 1472bdd1243dSDimitry Andric ++FirstOp; 1473bdd1243dSDimitry Andric return I->get() == FirstOp->get() && I->getArg(0) == 1; 14740b57cec5SDimitry Andric } 1475e8d8bef9SDimitry Andric case dwarf::DW_OP_LLVM_implicit_pointer: 14760b57cec5SDimitry Andric case dwarf::DW_OP_LLVM_convert: 1477fe6060f1SDimitry Andric case dwarf::DW_OP_LLVM_arg: 14780b57cec5SDimitry Andric case dwarf::DW_OP_LLVM_tag_offset: 1479*0fca6ea1SDimitry Andric case dwarf::DW_OP_LLVM_extract_bits_sext: 1480*0fca6ea1SDimitry Andric case dwarf::DW_OP_LLVM_extract_bits_zext: 14810b57cec5SDimitry Andric case dwarf::DW_OP_constu: 14820b57cec5SDimitry Andric case dwarf::DW_OP_plus_uconst: 14830b57cec5SDimitry Andric case dwarf::DW_OP_plus: 14840b57cec5SDimitry Andric case dwarf::DW_OP_minus: 14850b57cec5SDimitry Andric case dwarf::DW_OP_mul: 14860b57cec5SDimitry Andric case dwarf::DW_OP_div: 14870b57cec5SDimitry Andric case dwarf::DW_OP_mod: 14880b57cec5SDimitry Andric case dwarf::DW_OP_or: 14890b57cec5SDimitry Andric case dwarf::DW_OP_and: 14900b57cec5SDimitry Andric case dwarf::DW_OP_xor: 14910b57cec5SDimitry Andric case dwarf::DW_OP_shl: 14920b57cec5SDimitry Andric case dwarf::DW_OP_shr: 14930b57cec5SDimitry Andric case dwarf::DW_OP_shra: 14940b57cec5SDimitry Andric case dwarf::DW_OP_deref: 14950b57cec5SDimitry Andric case dwarf::DW_OP_deref_size: 14960b57cec5SDimitry Andric case dwarf::DW_OP_xderef: 14970b57cec5SDimitry Andric case dwarf::DW_OP_lit0: 14980b57cec5SDimitry Andric case dwarf::DW_OP_not: 14990b57cec5SDimitry Andric case dwarf::DW_OP_dup: 15008bcb0991SDimitry Andric case dwarf::DW_OP_regx: 15018bcb0991SDimitry Andric case dwarf::DW_OP_bregx: 15025ffd83dbSDimitry Andric case dwarf::DW_OP_push_object_address: 1503e8d8bef9SDimitry Andric case dwarf::DW_OP_over: 1504e8d8bef9SDimitry Andric case dwarf::DW_OP_consts: 150506c3fb27SDimitry Andric case dwarf::DW_OP_eq: 150606c3fb27SDimitry Andric case dwarf::DW_OP_ne: 150706c3fb27SDimitry Andric case dwarf::DW_OP_gt: 150806c3fb27SDimitry Andric case dwarf::DW_OP_ge: 150906c3fb27SDimitry Andric case dwarf::DW_OP_lt: 151006c3fb27SDimitry Andric case dwarf::DW_OP_le: 15110b57cec5SDimitry Andric break; 15120b57cec5SDimitry Andric } 15130b57cec5SDimitry Andric } 15140b57cec5SDimitry Andric return true; 15150b57cec5SDimitry Andric } 15160b57cec5SDimitry Andric 15170b57cec5SDimitry Andric bool DIExpression::isImplicit() const { 1518480093f4SDimitry Andric if (!isValid()) 1519480093f4SDimitry Andric return false; 1520480093f4SDimitry Andric 1521480093f4SDimitry Andric if (getNumElements() == 0) 1522480093f4SDimitry Andric return false; 1523480093f4SDimitry Andric 1524480093f4SDimitry Andric for (const auto &It : expr_ops()) { 1525480093f4SDimitry Andric switch (It.getOp()) { 1526480093f4SDimitry Andric default: 1527480093f4SDimitry Andric break; 15280b57cec5SDimitry Andric case dwarf::DW_OP_stack_value: 15290b57cec5SDimitry Andric return true; 15300b57cec5SDimitry Andric } 15310b57cec5SDimitry Andric } 1532480093f4SDimitry Andric 15330b57cec5SDimitry Andric return false; 15340b57cec5SDimitry Andric } 15350b57cec5SDimitry Andric 15360b57cec5SDimitry Andric bool DIExpression::isComplex() const { 15370b57cec5SDimitry Andric if (!isValid()) 15380b57cec5SDimitry Andric return false; 15390b57cec5SDimitry Andric 15400b57cec5SDimitry Andric if (getNumElements() == 0) 15410b57cec5SDimitry Andric return false; 15420b57cec5SDimitry Andric 15430b57cec5SDimitry Andric // If there are any elements other than fragment or tag_offset, then some 15440b57cec5SDimitry Andric // kind of complex computation occurs. 15450b57cec5SDimitry Andric for (const auto &It : expr_ops()) { 15460b57cec5SDimitry Andric switch (It.getOp()) { 15470b57cec5SDimitry Andric case dwarf::DW_OP_LLVM_tag_offset: 15480b57cec5SDimitry Andric case dwarf::DW_OP_LLVM_fragment: 1549bdd1243dSDimitry Andric case dwarf::DW_OP_LLVM_arg: 15500b57cec5SDimitry Andric continue; 1551349cc55cSDimitry Andric default: 1552349cc55cSDimitry Andric return true; 15530b57cec5SDimitry Andric } 15540b57cec5SDimitry Andric } 15550b57cec5SDimitry Andric 15560b57cec5SDimitry Andric return false; 15570b57cec5SDimitry Andric } 15580b57cec5SDimitry Andric 1559bdd1243dSDimitry Andric bool DIExpression::isSingleLocationExpression() const { 1560bdd1243dSDimitry Andric if (!isValid()) 1561bdd1243dSDimitry Andric return false; 1562bdd1243dSDimitry Andric 1563bdd1243dSDimitry Andric if (getNumElements() == 0) 1564bdd1243dSDimitry Andric return true; 1565bdd1243dSDimitry Andric 1566bdd1243dSDimitry Andric auto ExprOpBegin = expr_ops().begin(); 1567bdd1243dSDimitry Andric auto ExprOpEnd = expr_ops().end(); 15685f757f3fSDimitry Andric if (ExprOpBegin->getOp() == dwarf::DW_OP_LLVM_arg) { 15695f757f3fSDimitry Andric if (ExprOpBegin->getArg(0) != 0) 15705f757f3fSDimitry Andric return false; 1571bdd1243dSDimitry Andric ++ExprOpBegin; 15725f757f3fSDimitry Andric } 1573bdd1243dSDimitry Andric 1574bdd1243dSDimitry Andric return !std::any_of(ExprOpBegin, ExprOpEnd, [](auto Op) { 1575bdd1243dSDimitry Andric return Op.getOp() == dwarf::DW_OP_LLVM_arg; 1576bdd1243dSDimitry Andric }); 1577bdd1243dSDimitry Andric } 1578bdd1243dSDimitry Andric 15795f757f3fSDimitry Andric std::optional<ArrayRef<uint64_t>> 15805f757f3fSDimitry Andric DIExpression::getSingleLocationExpressionElements() const { 15815f757f3fSDimitry Andric // Check for `isValid` covered by `isSingleLocationExpression`. 15825f757f3fSDimitry Andric if (!isSingleLocationExpression()) 15835f757f3fSDimitry Andric return std::nullopt; 15845f757f3fSDimitry Andric 15855f757f3fSDimitry Andric // An empty expression is already non-variadic. 15865f757f3fSDimitry Andric if (!getNumElements()) 15875f757f3fSDimitry Andric return ArrayRef<uint64_t>(); 15885f757f3fSDimitry Andric 15895f757f3fSDimitry Andric // If Expr does not have a leading DW_OP_LLVM_arg then we don't need to do 15905f757f3fSDimitry Andric // anything. 15915f757f3fSDimitry Andric if (getElements()[0] == dwarf::DW_OP_LLVM_arg) 15925f757f3fSDimitry Andric return getElements().drop_front(2); 15935f757f3fSDimitry Andric return getElements(); 15945f757f3fSDimitry Andric } 15955f757f3fSDimitry Andric 1596bdd1243dSDimitry Andric const DIExpression * 1597bdd1243dSDimitry Andric DIExpression::convertToUndefExpression(const DIExpression *Expr) { 1598bdd1243dSDimitry Andric SmallVector<uint64_t, 3> UndefOps; 1599bdd1243dSDimitry Andric if (auto FragmentInfo = Expr->getFragmentInfo()) { 1600bdd1243dSDimitry Andric UndefOps.append({dwarf::DW_OP_LLVM_fragment, FragmentInfo->OffsetInBits, 1601bdd1243dSDimitry Andric FragmentInfo->SizeInBits}); 1602bdd1243dSDimitry Andric } 1603bdd1243dSDimitry Andric return DIExpression::get(Expr->getContext(), UndefOps); 1604bdd1243dSDimitry Andric } 1605bdd1243dSDimitry Andric 1606bdd1243dSDimitry Andric const DIExpression * 1607bdd1243dSDimitry Andric DIExpression::convertToVariadicExpression(const DIExpression *Expr) { 1608bdd1243dSDimitry Andric if (any_of(Expr->expr_ops(), [](auto ExprOp) { 1609bdd1243dSDimitry Andric return ExprOp.getOp() == dwarf::DW_OP_LLVM_arg; 1610bdd1243dSDimitry Andric })) 1611bdd1243dSDimitry Andric return Expr; 1612bdd1243dSDimitry Andric SmallVector<uint64_t> NewOps; 1613bdd1243dSDimitry Andric NewOps.reserve(Expr->getNumElements() + 2); 1614bdd1243dSDimitry Andric NewOps.append({dwarf::DW_OP_LLVM_arg, 0}); 1615bdd1243dSDimitry Andric NewOps.append(Expr->elements_begin(), Expr->elements_end()); 1616bdd1243dSDimitry Andric return DIExpression::get(Expr->getContext(), NewOps); 1617bdd1243dSDimitry Andric } 1618bdd1243dSDimitry Andric 1619bdd1243dSDimitry Andric std::optional<const DIExpression *> 1620bdd1243dSDimitry Andric DIExpression::convertToNonVariadicExpression(const DIExpression *Expr) { 16215f757f3fSDimitry Andric if (!Expr) 1622bdd1243dSDimitry Andric return std::nullopt; 1623bdd1243dSDimitry Andric 16245f757f3fSDimitry Andric if (auto Elts = Expr->getSingleLocationExpressionElements()) 16255f757f3fSDimitry Andric return DIExpression::get(Expr->getContext(), *Elts); 1626bdd1243dSDimitry Andric 16275f757f3fSDimitry Andric return std::nullopt; 1628bdd1243dSDimitry Andric } 1629bdd1243dSDimitry Andric 1630bdd1243dSDimitry Andric void DIExpression::canonicalizeExpressionOps(SmallVectorImpl<uint64_t> &Ops, 1631bdd1243dSDimitry Andric const DIExpression *Expr, 1632bdd1243dSDimitry Andric bool IsIndirect) { 1633bdd1243dSDimitry Andric // If Expr is not already variadic, insert the implied `DW_OP_LLVM_arg 0` 1634bdd1243dSDimitry Andric // to the existing expression ops. 1635bdd1243dSDimitry Andric if (none_of(Expr->expr_ops(), [](auto ExprOp) { 1636bdd1243dSDimitry Andric return ExprOp.getOp() == dwarf::DW_OP_LLVM_arg; 1637bdd1243dSDimitry Andric })) 1638bdd1243dSDimitry Andric Ops.append({dwarf::DW_OP_LLVM_arg, 0}); 1639bdd1243dSDimitry Andric // If Expr is not indirect, we only need to insert the expression elements and 1640bdd1243dSDimitry Andric // we're done. 1641bdd1243dSDimitry Andric if (!IsIndirect) { 1642bdd1243dSDimitry Andric Ops.append(Expr->elements_begin(), Expr->elements_end()); 1643bdd1243dSDimitry Andric return; 1644bdd1243dSDimitry Andric } 1645bdd1243dSDimitry Andric // If Expr is indirect, insert the implied DW_OP_deref at the end of the 1646bdd1243dSDimitry Andric // expression but before DW_OP_{stack_value, LLVM_fragment} if they are 1647bdd1243dSDimitry Andric // present. 1648bdd1243dSDimitry Andric for (auto Op : Expr->expr_ops()) { 1649bdd1243dSDimitry Andric if (Op.getOp() == dwarf::DW_OP_stack_value || 1650bdd1243dSDimitry Andric Op.getOp() == dwarf::DW_OP_LLVM_fragment) { 1651bdd1243dSDimitry Andric Ops.push_back(dwarf::DW_OP_deref); 1652bdd1243dSDimitry Andric IsIndirect = false; 1653bdd1243dSDimitry Andric } 1654bdd1243dSDimitry Andric Op.appendToVector(Ops); 1655bdd1243dSDimitry Andric } 1656bdd1243dSDimitry Andric if (IsIndirect) 1657bdd1243dSDimitry Andric Ops.push_back(dwarf::DW_OP_deref); 1658bdd1243dSDimitry Andric } 1659bdd1243dSDimitry Andric 1660bdd1243dSDimitry Andric bool DIExpression::isEqualExpression(const DIExpression *FirstExpr, 1661bdd1243dSDimitry Andric bool FirstIndirect, 1662bdd1243dSDimitry Andric const DIExpression *SecondExpr, 1663bdd1243dSDimitry Andric bool SecondIndirect) { 1664bdd1243dSDimitry Andric SmallVector<uint64_t> FirstOps; 1665bdd1243dSDimitry Andric DIExpression::canonicalizeExpressionOps(FirstOps, FirstExpr, FirstIndirect); 1666bdd1243dSDimitry Andric SmallVector<uint64_t> SecondOps; 1667bdd1243dSDimitry Andric DIExpression::canonicalizeExpressionOps(SecondOps, SecondExpr, 1668bdd1243dSDimitry Andric SecondIndirect); 1669bdd1243dSDimitry Andric return FirstOps == SecondOps; 1670bdd1243dSDimitry Andric } 1671bdd1243dSDimitry Andric 1672bdd1243dSDimitry Andric std::optional<DIExpression::FragmentInfo> 16730b57cec5SDimitry Andric DIExpression::getFragmentInfo(expr_op_iterator Start, expr_op_iterator End) { 16740b57cec5SDimitry Andric for (auto I = Start; I != End; ++I) 16750b57cec5SDimitry Andric if (I->getOp() == dwarf::DW_OP_LLVM_fragment) { 16760b57cec5SDimitry Andric DIExpression::FragmentInfo Info = {I->getArg(1), I->getArg(0)}; 16770b57cec5SDimitry Andric return Info; 16780b57cec5SDimitry Andric } 1679bdd1243dSDimitry Andric return std::nullopt; 16800b57cec5SDimitry Andric } 16810b57cec5SDimitry Andric 1682*0fca6ea1SDimitry Andric std::optional<uint64_t> DIExpression::getActiveBits(DIVariable *Var) { 1683*0fca6ea1SDimitry Andric std::optional<uint64_t> InitialActiveBits = Var->getSizeInBits(); 1684*0fca6ea1SDimitry Andric std::optional<uint64_t> ActiveBits = InitialActiveBits; 1685*0fca6ea1SDimitry Andric for (auto Op : expr_ops()) { 1686*0fca6ea1SDimitry Andric switch (Op.getOp()) { 1687*0fca6ea1SDimitry Andric default: 1688*0fca6ea1SDimitry Andric // We assume the worst case for anything we don't currently handle and 1689*0fca6ea1SDimitry Andric // revert to the initial active bits. 1690*0fca6ea1SDimitry Andric ActiveBits = InitialActiveBits; 1691*0fca6ea1SDimitry Andric break; 1692*0fca6ea1SDimitry Andric case dwarf::DW_OP_LLVM_extract_bits_zext: 1693*0fca6ea1SDimitry Andric case dwarf::DW_OP_LLVM_extract_bits_sext: { 1694*0fca6ea1SDimitry Andric // We can't handle an extract whose sign doesn't match that of the 1695*0fca6ea1SDimitry Andric // variable. 1696*0fca6ea1SDimitry Andric std::optional<DIBasicType::Signedness> VarSign = Var->getSignedness(); 1697*0fca6ea1SDimitry Andric bool VarSigned = (VarSign == DIBasicType::Signedness::Signed); 1698*0fca6ea1SDimitry Andric bool OpSigned = (Op.getOp() == dwarf::DW_OP_LLVM_extract_bits_sext); 1699*0fca6ea1SDimitry Andric if (!VarSign || VarSigned != OpSigned) { 1700*0fca6ea1SDimitry Andric ActiveBits = InitialActiveBits; 1701*0fca6ea1SDimitry Andric break; 1702*0fca6ea1SDimitry Andric } 1703*0fca6ea1SDimitry Andric [[fallthrough]]; 1704*0fca6ea1SDimitry Andric } 1705*0fca6ea1SDimitry Andric case dwarf::DW_OP_LLVM_fragment: 1706*0fca6ea1SDimitry Andric // Extract or fragment narrows the active bits 1707*0fca6ea1SDimitry Andric if (ActiveBits) 1708*0fca6ea1SDimitry Andric ActiveBits = std::min(*ActiveBits, Op.getArg(1)); 1709*0fca6ea1SDimitry Andric else 1710*0fca6ea1SDimitry Andric ActiveBits = Op.getArg(1); 1711*0fca6ea1SDimitry Andric break; 1712*0fca6ea1SDimitry Andric } 1713*0fca6ea1SDimitry Andric } 1714*0fca6ea1SDimitry Andric return ActiveBits; 1715*0fca6ea1SDimitry Andric } 1716*0fca6ea1SDimitry Andric 17170b57cec5SDimitry Andric void DIExpression::appendOffset(SmallVectorImpl<uint64_t> &Ops, 17180b57cec5SDimitry Andric int64_t Offset) { 17190b57cec5SDimitry Andric if (Offset > 0) { 17200b57cec5SDimitry Andric Ops.push_back(dwarf::DW_OP_plus_uconst); 17210b57cec5SDimitry Andric Ops.push_back(Offset); 17220b57cec5SDimitry Andric } else if (Offset < 0) { 17230b57cec5SDimitry Andric Ops.push_back(dwarf::DW_OP_constu); 1724bdd1243dSDimitry Andric // Avoid UB when encountering LLONG_MIN, because in 2's complement 1725bdd1243dSDimitry Andric // abs(LLONG_MIN) is LLONG_MAX+1. 1726bdd1243dSDimitry Andric uint64_t AbsMinusOne = -(Offset+1); 1727bdd1243dSDimitry Andric Ops.push_back(AbsMinusOne + 1); 17280b57cec5SDimitry Andric Ops.push_back(dwarf::DW_OP_minus); 17290b57cec5SDimitry Andric } 17300b57cec5SDimitry Andric } 17310b57cec5SDimitry Andric 17320b57cec5SDimitry Andric bool DIExpression::extractIfOffset(int64_t &Offset) const { 17335f757f3fSDimitry Andric auto SingleLocEltsOpt = getSingleLocationExpressionElements(); 17345f757f3fSDimitry Andric if (!SingleLocEltsOpt) 17355f757f3fSDimitry Andric return false; 17365f757f3fSDimitry Andric auto SingleLocElts = *SingleLocEltsOpt; 17375f757f3fSDimitry Andric 17385f757f3fSDimitry Andric if (SingleLocElts.size() == 0) { 17390b57cec5SDimitry Andric Offset = 0; 17400b57cec5SDimitry Andric return true; 17410b57cec5SDimitry Andric } 17420b57cec5SDimitry Andric 17435f757f3fSDimitry Andric if (SingleLocElts.size() == 2 && 17445f757f3fSDimitry Andric SingleLocElts[0] == dwarf::DW_OP_plus_uconst) { 17455f757f3fSDimitry Andric Offset = SingleLocElts[1]; 17460b57cec5SDimitry Andric return true; 17470b57cec5SDimitry Andric } 17480b57cec5SDimitry Andric 17495f757f3fSDimitry Andric if (SingleLocElts.size() == 3 && SingleLocElts[0] == dwarf::DW_OP_constu) { 17505f757f3fSDimitry Andric if (SingleLocElts[2] == dwarf::DW_OP_plus) { 17515f757f3fSDimitry Andric Offset = SingleLocElts[1]; 17520b57cec5SDimitry Andric return true; 17530b57cec5SDimitry Andric } 17545f757f3fSDimitry Andric if (SingleLocElts[2] == dwarf::DW_OP_minus) { 17555f757f3fSDimitry Andric Offset = -SingleLocElts[1]; 17560b57cec5SDimitry Andric return true; 17570b57cec5SDimitry Andric } 17580b57cec5SDimitry Andric } 17590b57cec5SDimitry Andric 17600b57cec5SDimitry Andric return false; 17610b57cec5SDimitry Andric } 17620b57cec5SDimitry Andric 1763*0fca6ea1SDimitry Andric bool DIExpression::extractLeadingOffset( 1764*0fca6ea1SDimitry Andric int64_t &OffsetInBytes, SmallVectorImpl<uint64_t> &RemainingOps) const { 1765*0fca6ea1SDimitry Andric OffsetInBytes = 0; 1766*0fca6ea1SDimitry Andric RemainingOps.clear(); 1767*0fca6ea1SDimitry Andric 1768*0fca6ea1SDimitry Andric auto SingleLocEltsOpt = getSingleLocationExpressionElements(); 1769*0fca6ea1SDimitry Andric if (!SingleLocEltsOpt) 1770*0fca6ea1SDimitry Andric return false; 1771*0fca6ea1SDimitry Andric 1772*0fca6ea1SDimitry Andric auto ExprOpEnd = expr_op_iterator(SingleLocEltsOpt->end()); 1773*0fca6ea1SDimitry Andric auto ExprOpIt = expr_op_iterator(SingleLocEltsOpt->begin()); 1774*0fca6ea1SDimitry Andric while (ExprOpIt != ExprOpEnd) { 1775*0fca6ea1SDimitry Andric uint64_t Op = ExprOpIt->getOp(); 1776*0fca6ea1SDimitry Andric if (Op == dwarf::DW_OP_deref || Op == dwarf::DW_OP_deref_size || 1777*0fca6ea1SDimitry Andric Op == dwarf::DW_OP_deref_type || Op == dwarf::DW_OP_LLVM_fragment || 1778*0fca6ea1SDimitry Andric Op == dwarf::DW_OP_LLVM_extract_bits_zext || 1779*0fca6ea1SDimitry Andric Op == dwarf::DW_OP_LLVM_extract_bits_sext) { 1780*0fca6ea1SDimitry Andric break; 1781*0fca6ea1SDimitry Andric } else if (Op == dwarf::DW_OP_plus_uconst) { 1782*0fca6ea1SDimitry Andric OffsetInBytes += ExprOpIt->getArg(0); 1783*0fca6ea1SDimitry Andric } else if (Op == dwarf::DW_OP_constu) { 1784*0fca6ea1SDimitry Andric uint64_t Value = ExprOpIt->getArg(0); 1785*0fca6ea1SDimitry Andric ++ExprOpIt; 1786*0fca6ea1SDimitry Andric if (ExprOpIt->getOp() == dwarf::DW_OP_plus) 1787*0fca6ea1SDimitry Andric OffsetInBytes += Value; 1788*0fca6ea1SDimitry Andric else if (ExprOpIt->getOp() == dwarf::DW_OP_minus) 1789*0fca6ea1SDimitry Andric OffsetInBytes -= Value; 1790*0fca6ea1SDimitry Andric else 1791*0fca6ea1SDimitry Andric return false; 1792*0fca6ea1SDimitry Andric } else { 1793*0fca6ea1SDimitry Andric // Not a const plus/minus operation or deref. 1794*0fca6ea1SDimitry Andric return false; 1795*0fca6ea1SDimitry Andric } 1796*0fca6ea1SDimitry Andric ++ExprOpIt; 1797*0fca6ea1SDimitry Andric } 1798*0fca6ea1SDimitry Andric RemainingOps.append(ExprOpIt.getBase(), ExprOpEnd.getBase()); 1799*0fca6ea1SDimitry Andric return true; 1800*0fca6ea1SDimitry Andric } 1801*0fca6ea1SDimitry Andric 1802fe6060f1SDimitry Andric bool DIExpression::hasAllLocationOps(unsigned N) const { 1803fe6060f1SDimitry Andric SmallDenseSet<uint64_t, 4> SeenOps; 1804fe6060f1SDimitry Andric for (auto ExprOp : expr_ops()) 1805fe6060f1SDimitry Andric if (ExprOp.getOp() == dwarf::DW_OP_LLVM_arg) 1806fe6060f1SDimitry Andric SeenOps.insert(ExprOp.getArg(0)); 1807fe6060f1SDimitry Andric for (uint64_t Idx = 0; Idx < N; ++Idx) 180806c3fb27SDimitry Andric if (!SeenOps.contains(Idx)) 1809fe6060f1SDimitry Andric return false; 1810fe6060f1SDimitry Andric return true; 1811fe6060f1SDimitry Andric } 1812fe6060f1SDimitry Andric 18130b57cec5SDimitry Andric const DIExpression *DIExpression::extractAddressClass(const DIExpression *Expr, 18140b57cec5SDimitry Andric unsigned &AddrClass) { 1815480093f4SDimitry Andric // FIXME: This seems fragile. Nothing that verifies that these elements 1816480093f4SDimitry Andric // actually map to ops and not operands. 18175f757f3fSDimitry Andric auto SingleLocEltsOpt = Expr->getSingleLocationExpressionElements(); 18185f757f3fSDimitry Andric if (!SingleLocEltsOpt) 18190b57cec5SDimitry Andric return nullptr; 18205f757f3fSDimitry Andric auto SingleLocElts = *SingleLocEltsOpt; 18215f757f3fSDimitry Andric 18225f757f3fSDimitry Andric const unsigned PatternSize = 4; 18235f757f3fSDimitry Andric if (SingleLocElts.size() >= PatternSize && 18245f757f3fSDimitry Andric SingleLocElts[PatternSize - 4] == dwarf::DW_OP_constu && 18255f757f3fSDimitry Andric SingleLocElts[PatternSize - 2] == dwarf::DW_OP_swap && 18265f757f3fSDimitry Andric SingleLocElts[PatternSize - 1] == dwarf::DW_OP_xderef) { 18275f757f3fSDimitry Andric AddrClass = SingleLocElts[PatternSize - 3]; 18285f757f3fSDimitry Andric 18295f757f3fSDimitry Andric if (SingleLocElts.size() == PatternSize) 18305f757f3fSDimitry Andric return nullptr; 18315f757f3fSDimitry Andric return DIExpression::get( 18325f757f3fSDimitry Andric Expr->getContext(), 18335f757f3fSDimitry Andric ArrayRef(&*SingleLocElts.begin(), SingleLocElts.size() - PatternSize)); 18340b57cec5SDimitry Andric } 18350b57cec5SDimitry Andric return Expr; 18360b57cec5SDimitry Andric } 18370b57cec5SDimitry Andric 18380b57cec5SDimitry Andric DIExpression *DIExpression::prepend(const DIExpression *Expr, uint8_t Flags, 18390b57cec5SDimitry Andric int64_t Offset) { 18400b57cec5SDimitry Andric SmallVector<uint64_t, 8> Ops; 18410b57cec5SDimitry Andric if (Flags & DIExpression::DerefBefore) 18420b57cec5SDimitry Andric Ops.push_back(dwarf::DW_OP_deref); 18430b57cec5SDimitry Andric 18440b57cec5SDimitry Andric appendOffset(Ops, Offset); 18450b57cec5SDimitry Andric if (Flags & DIExpression::DerefAfter) 18460b57cec5SDimitry Andric Ops.push_back(dwarf::DW_OP_deref); 18470b57cec5SDimitry Andric 18480b57cec5SDimitry Andric bool StackValue = Flags & DIExpression::StackValue; 18490b57cec5SDimitry Andric bool EntryValue = Flags & DIExpression::EntryValue; 18500b57cec5SDimitry Andric 18510b57cec5SDimitry Andric return prependOpcodes(Expr, Ops, StackValue, EntryValue); 18520b57cec5SDimitry Andric } 18530b57cec5SDimitry Andric 1854fe6060f1SDimitry Andric DIExpression *DIExpression::appendOpsToArg(const DIExpression *Expr, 1855fe6060f1SDimitry Andric ArrayRef<uint64_t> Ops, 1856fe6060f1SDimitry Andric unsigned ArgNo, bool StackValue) { 1857fe6060f1SDimitry Andric assert(Expr && "Can't add ops to this expression"); 1858fe6060f1SDimitry Andric 1859fe6060f1SDimitry Andric // Handle non-variadic intrinsics by prepending the opcodes. 1860fe6060f1SDimitry Andric if (!any_of(Expr->expr_ops(), 1861fe6060f1SDimitry Andric [](auto Op) { return Op.getOp() == dwarf::DW_OP_LLVM_arg; })) { 1862fe6060f1SDimitry Andric assert(ArgNo == 0 && 1863fe6060f1SDimitry Andric "Location Index must be 0 for a non-variadic expression."); 1864fe6060f1SDimitry Andric SmallVector<uint64_t, 8> NewOps(Ops.begin(), Ops.end()); 1865fe6060f1SDimitry Andric return DIExpression::prependOpcodes(Expr, NewOps, StackValue); 1866fe6060f1SDimitry Andric } 1867fe6060f1SDimitry Andric 1868fe6060f1SDimitry Andric SmallVector<uint64_t, 8> NewOps; 1869fe6060f1SDimitry Andric for (auto Op : Expr->expr_ops()) { 1870bdd1243dSDimitry Andric // A DW_OP_stack_value comes at the end, but before a DW_OP_LLVM_fragment. 1871bdd1243dSDimitry Andric if (StackValue) { 1872bdd1243dSDimitry Andric if (Op.getOp() == dwarf::DW_OP_stack_value) 1873bdd1243dSDimitry Andric StackValue = false; 1874bdd1243dSDimitry Andric else if (Op.getOp() == dwarf::DW_OP_LLVM_fragment) { 1875bdd1243dSDimitry Andric NewOps.push_back(dwarf::DW_OP_stack_value); 1876bdd1243dSDimitry Andric StackValue = false; 1877bdd1243dSDimitry Andric } 1878bdd1243dSDimitry Andric } 1879fe6060f1SDimitry Andric Op.appendToVector(NewOps); 1880fe6060f1SDimitry Andric if (Op.getOp() == dwarf::DW_OP_LLVM_arg && Op.getArg(0) == ArgNo) 1881fe6060f1SDimitry Andric NewOps.insert(NewOps.end(), Ops.begin(), Ops.end()); 1882fe6060f1SDimitry Andric } 1883bdd1243dSDimitry Andric if (StackValue) 1884bdd1243dSDimitry Andric NewOps.push_back(dwarf::DW_OP_stack_value); 1885fe6060f1SDimitry Andric 1886fe6060f1SDimitry Andric return DIExpression::get(Expr->getContext(), NewOps); 1887fe6060f1SDimitry Andric } 1888fe6060f1SDimitry Andric 1889fe6060f1SDimitry Andric DIExpression *DIExpression::replaceArg(const DIExpression *Expr, 1890fe6060f1SDimitry Andric uint64_t OldArg, uint64_t NewArg) { 1891fe6060f1SDimitry Andric assert(Expr && "Can't replace args in this expression"); 1892fe6060f1SDimitry Andric 1893fe6060f1SDimitry Andric SmallVector<uint64_t, 8> NewOps; 1894fe6060f1SDimitry Andric 1895fe6060f1SDimitry Andric for (auto Op : Expr->expr_ops()) { 1896fe6060f1SDimitry Andric if (Op.getOp() != dwarf::DW_OP_LLVM_arg || Op.getArg(0) < OldArg) { 1897fe6060f1SDimitry Andric Op.appendToVector(NewOps); 1898fe6060f1SDimitry Andric continue; 1899fe6060f1SDimitry Andric } 1900fe6060f1SDimitry Andric NewOps.push_back(dwarf::DW_OP_LLVM_arg); 1901fe6060f1SDimitry Andric uint64_t Arg = Op.getArg(0) == OldArg ? NewArg : Op.getArg(0); 1902fe6060f1SDimitry Andric // OldArg has been deleted from the Op list, so decrement all indices 1903fe6060f1SDimitry Andric // greater than it. 1904fe6060f1SDimitry Andric if (Arg > OldArg) 1905fe6060f1SDimitry Andric --Arg; 1906fe6060f1SDimitry Andric NewOps.push_back(Arg); 1907fe6060f1SDimitry Andric } 1908fe6060f1SDimitry Andric return DIExpression::get(Expr->getContext(), NewOps); 1909fe6060f1SDimitry Andric } 1910fe6060f1SDimitry Andric 19110b57cec5SDimitry Andric DIExpression *DIExpression::prependOpcodes(const DIExpression *Expr, 19120b57cec5SDimitry Andric SmallVectorImpl<uint64_t> &Ops, 1913349cc55cSDimitry Andric bool StackValue, bool EntryValue) { 19140b57cec5SDimitry Andric assert(Expr && "Can't prepend ops to this expression"); 19150b57cec5SDimitry Andric 19160b57cec5SDimitry Andric if (EntryValue) { 19178bcb0991SDimitry Andric Ops.push_back(dwarf::DW_OP_LLVM_entry_value); 1918fe6060f1SDimitry Andric // Use a block size of 1 for the target register operand. The 1919fe6060f1SDimitry Andric // DWARF backend currently cannot emit entry values with a block 1920fe6060f1SDimitry Andric // size > 1. 1921fe6060f1SDimitry Andric Ops.push_back(1); 19220b57cec5SDimitry Andric } 19230b57cec5SDimitry Andric 19240b57cec5SDimitry Andric // If there are no ops to prepend, do not even add the DW_OP_stack_value. 19250b57cec5SDimitry Andric if (Ops.empty()) 19260b57cec5SDimitry Andric StackValue = false; 19270b57cec5SDimitry Andric for (auto Op : Expr->expr_ops()) { 19280b57cec5SDimitry Andric // A DW_OP_stack_value comes at the end, but before a DW_OP_LLVM_fragment. 19290b57cec5SDimitry Andric if (StackValue) { 19300b57cec5SDimitry Andric if (Op.getOp() == dwarf::DW_OP_stack_value) 19310b57cec5SDimitry Andric StackValue = false; 19320b57cec5SDimitry Andric else if (Op.getOp() == dwarf::DW_OP_LLVM_fragment) { 19330b57cec5SDimitry Andric Ops.push_back(dwarf::DW_OP_stack_value); 19340b57cec5SDimitry Andric StackValue = false; 19350b57cec5SDimitry Andric } 19360b57cec5SDimitry Andric } 19370b57cec5SDimitry Andric Op.appendToVector(Ops); 19380b57cec5SDimitry Andric } 19390b57cec5SDimitry Andric if (StackValue) 19400b57cec5SDimitry Andric Ops.push_back(dwarf::DW_OP_stack_value); 19410b57cec5SDimitry Andric return DIExpression::get(Expr->getContext(), Ops); 19420b57cec5SDimitry Andric } 19430b57cec5SDimitry Andric 19440b57cec5SDimitry Andric DIExpression *DIExpression::append(const DIExpression *Expr, 19450b57cec5SDimitry Andric ArrayRef<uint64_t> Ops) { 19460b57cec5SDimitry Andric assert(Expr && !Ops.empty() && "Can't append ops to this expression"); 19470b57cec5SDimitry Andric 19480b57cec5SDimitry Andric // Copy Expr's current op list. 19490b57cec5SDimitry Andric SmallVector<uint64_t, 16> NewOps; 19500b57cec5SDimitry Andric for (auto Op : Expr->expr_ops()) { 19510b57cec5SDimitry Andric // Append new opcodes before DW_OP_{stack_value, LLVM_fragment}. 19520b57cec5SDimitry Andric if (Op.getOp() == dwarf::DW_OP_stack_value || 19530b57cec5SDimitry Andric Op.getOp() == dwarf::DW_OP_LLVM_fragment) { 19540b57cec5SDimitry Andric NewOps.append(Ops.begin(), Ops.end()); 19550b57cec5SDimitry Andric 19560b57cec5SDimitry Andric // Ensure that the new opcodes are only appended once. 1957bdd1243dSDimitry Andric Ops = std::nullopt; 19580b57cec5SDimitry Andric } 19590b57cec5SDimitry Andric Op.appendToVector(NewOps); 19600b57cec5SDimitry Andric } 19610b57cec5SDimitry Andric NewOps.append(Ops.begin(), Ops.end()); 1962*0fca6ea1SDimitry Andric auto *result = 1963*0fca6ea1SDimitry Andric DIExpression::get(Expr->getContext(), NewOps)->foldConstantMath(); 19645ffd83dbSDimitry Andric assert(result->isValid() && "concatenated expression is not valid"); 19655ffd83dbSDimitry Andric return result; 19660b57cec5SDimitry Andric } 19670b57cec5SDimitry Andric 19680b57cec5SDimitry Andric DIExpression *DIExpression::appendToStack(const DIExpression *Expr, 19690b57cec5SDimitry Andric ArrayRef<uint64_t> Ops) { 19700b57cec5SDimitry Andric assert(Expr && !Ops.empty() && "Can't append ops to this expression"); 1971*0fca6ea1SDimitry Andric assert(std::none_of(expr_op_iterator(Ops.begin()), 1972*0fca6ea1SDimitry Andric expr_op_iterator(Ops.end()), 1973*0fca6ea1SDimitry Andric [](auto Op) { 1974*0fca6ea1SDimitry Andric return Op.getOp() == dwarf::DW_OP_stack_value || 1975*0fca6ea1SDimitry Andric Op.getOp() == dwarf::DW_OP_LLVM_fragment; 19760b57cec5SDimitry Andric }) && 19770b57cec5SDimitry Andric "Can't append this op"); 19780b57cec5SDimitry Andric 19790b57cec5SDimitry Andric // Append a DW_OP_deref after Expr's current op list if it's non-empty and 19800b57cec5SDimitry Andric // has no DW_OP_stack_value. 19810b57cec5SDimitry Andric // 19820b57cec5SDimitry Andric // Match .* DW_OP_stack_value (DW_OP_LLVM_fragment A B)?. 1983bdd1243dSDimitry Andric std::optional<FragmentInfo> FI = Expr->getFragmentInfo(); 198481ad6265SDimitry Andric unsigned DropUntilStackValue = FI ? 3 : 0; 19850b57cec5SDimitry Andric ArrayRef<uint64_t> ExprOpsBeforeFragment = 19860b57cec5SDimitry Andric Expr->getElements().drop_back(DropUntilStackValue); 19870b57cec5SDimitry Andric bool NeedsDeref = (Expr->getNumElements() > DropUntilStackValue) && 19880b57cec5SDimitry Andric (ExprOpsBeforeFragment.back() != dwarf::DW_OP_stack_value); 19890b57cec5SDimitry Andric bool NeedsStackValue = NeedsDeref || ExprOpsBeforeFragment.empty(); 19900b57cec5SDimitry Andric 19910b57cec5SDimitry Andric // Append a DW_OP_deref after Expr's current op list if needed, then append 19920b57cec5SDimitry Andric // the new ops, and finally ensure that a single DW_OP_stack_value is present. 19930b57cec5SDimitry Andric SmallVector<uint64_t, 16> NewOps; 19940b57cec5SDimitry Andric if (NeedsDeref) 19950b57cec5SDimitry Andric NewOps.push_back(dwarf::DW_OP_deref); 19960b57cec5SDimitry Andric NewOps.append(Ops.begin(), Ops.end()); 19970b57cec5SDimitry Andric if (NeedsStackValue) 19980b57cec5SDimitry Andric NewOps.push_back(dwarf::DW_OP_stack_value); 19990b57cec5SDimitry Andric return DIExpression::append(Expr, NewOps); 20000b57cec5SDimitry Andric } 20010b57cec5SDimitry Andric 2002bdd1243dSDimitry Andric std::optional<DIExpression *> DIExpression::createFragmentExpression( 20030b57cec5SDimitry Andric const DIExpression *Expr, unsigned OffsetInBits, unsigned SizeInBits) { 20040b57cec5SDimitry Andric SmallVector<uint64_t, 8> Ops; 2005bdd1243dSDimitry Andric // Track whether it's safe to split the value at the top of the DWARF stack, 2006bdd1243dSDimitry Andric // assuming that it'll be used as an implicit location value. 2007bdd1243dSDimitry Andric bool CanSplitValue = true; 2008*0fca6ea1SDimitry Andric // Track whether we need to add a fragment expression to the end of Expr. 2009*0fca6ea1SDimitry Andric bool EmitFragment = true; 20100b57cec5SDimitry Andric // Copy over the expression, but leave off any trailing DW_OP_LLVM_fragment. 20110b57cec5SDimitry Andric if (Expr) { 20120b57cec5SDimitry Andric for (auto Op : Expr->expr_ops()) { 20130b57cec5SDimitry Andric switch (Op.getOp()) { 2014349cc55cSDimitry Andric default: 2015349cc55cSDimitry Andric break; 2016480093f4SDimitry Andric case dwarf::DW_OP_shr: 2017480093f4SDimitry Andric case dwarf::DW_OP_shra: 2018480093f4SDimitry Andric case dwarf::DW_OP_shl: 20190b57cec5SDimitry Andric case dwarf::DW_OP_plus: 2020480093f4SDimitry Andric case dwarf::DW_OP_plus_uconst: 20210b57cec5SDimitry Andric case dwarf::DW_OP_minus: 2022480093f4SDimitry Andric // We can't safely split arithmetic or shift operations into multiple 2023480093f4SDimitry Andric // fragments because we can't express carry-over between fragments. 20240b57cec5SDimitry Andric // 20250b57cec5SDimitry Andric // FIXME: We *could* preserve the lowest fragment of a constant offset 20260b57cec5SDimitry Andric // operation if the offset fits into SizeInBits. 2027bdd1243dSDimitry Andric CanSplitValue = false; 2028bdd1243dSDimitry Andric break; 2029bdd1243dSDimitry Andric case dwarf::DW_OP_deref: 2030bdd1243dSDimitry Andric case dwarf::DW_OP_deref_size: 2031bdd1243dSDimitry Andric case dwarf::DW_OP_deref_type: 2032bdd1243dSDimitry Andric case dwarf::DW_OP_xderef: 2033bdd1243dSDimitry Andric case dwarf::DW_OP_xderef_size: 2034bdd1243dSDimitry Andric case dwarf::DW_OP_xderef_type: 2035bdd1243dSDimitry Andric // Preceeding arithmetic operations have been applied to compute an 2036bdd1243dSDimitry Andric // address. It's okay to split the value loaded from that address. 2037bdd1243dSDimitry Andric CanSplitValue = true; 2038bdd1243dSDimitry Andric break; 2039bdd1243dSDimitry Andric case dwarf::DW_OP_stack_value: 2040bdd1243dSDimitry Andric // Bail if this expression computes a value that cannot be split. 2041bdd1243dSDimitry Andric if (!CanSplitValue) 2042bdd1243dSDimitry Andric return std::nullopt; 2043bdd1243dSDimitry Andric break; 20440b57cec5SDimitry Andric case dwarf::DW_OP_LLVM_fragment: { 2045*0fca6ea1SDimitry Andric // If we've decided we don't need a fragment then give up if we see that 2046*0fca6ea1SDimitry Andric // there's already a fragment expression. 2047*0fca6ea1SDimitry Andric // FIXME: We could probably do better here 2048*0fca6ea1SDimitry Andric if (!EmitFragment) 2049*0fca6ea1SDimitry Andric return std::nullopt; 20500b57cec5SDimitry Andric // Make the new offset point into the existing fragment. 20510b57cec5SDimitry Andric uint64_t FragmentOffsetInBits = Op.getArg(0); 20520b57cec5SDimitry Andric uint64_t FragmentSizeInBits = Op.getArg(1); 20530b57cec5SDimitry Andric (void)FragmentSizeInBits; 20540b57cec5SDimitry Andric assert((OffsetInBits + SizeInBits <= FragmentSizeInBits) && 20550b57cec5SDimitry Andric "new fragment outside of original fragment"); 20560b57cec5SDimitry Andric OffsetInBits += FragmentOffsetInBits; 20570b57cec5SDimitry Andric continue; 20580b57cec5SDimitry Andric } 2059*0fca6ea1SDimitry Andric case dwarf::DW_OP_LLVM_extract_bits_zext: 2060*0fca6ea1SDimitry Andric case dwarf::DW_OP_LLVM_extract_bits_sext: { 2061*0fca6ea1SDimitry Andric // If we're extracting bits from inside of the fragment that we're 2062*0fca6ea1SDimitry Andric // creating then we don't have a fragment after all, and just need to 2063*0fca6ea1SDimitry Andric // adjust the offset that we're extracting from. 2064*0fca6ea1SDimitry Andric uint64_t ExtractOffsetInBits = Op.getArg(0); 2065*0fca6ea1SDimitry Andric uint64_t ExtractSizeInBits = Op.getArg(1); 2066*0fca6ea1SDimitry Andric if (ExtractOffsetInBits >= OffsetInBits && 2067*0fca6ea1SDimitry Andric ExtractOffsetInBits + ExtractSizeInBits <= 2068*0fca6ea1SDimitry Andric OffsetInBits + SizeInBits) { 2069*0fca6ea1SDimitry Andric Ops.push_back(Op.getOp()); 2070*0fca6ea1SDimitry Andric Ops.push_back(ExtractOffsetInBits - OffsetInBits); 2071*0fca6ea1SDimitry Andric Ops.push_back(ExtractSizeInBits); 2072*0fca6ea1SDimitry Andric EmitFragment = false; 2073*0fca6ea1SDimitry Andric continue; 2074*0fca6ea1SDimitry Andric } 2075*0fca6ea1SDimitry Andric // If the extracted bits aren't fully contained within the fragment then 2076*0fca6ea1SDimitry Andric // give up. 2077*0fca6ea1SDimitry Andric // FIXME: We could probably do better here 2078*0fca6ea1SDimitry Andric return std::nullopt; 2079*0fca6ea1SDimitry Andric } 20800b57cec5SDimitry Andric } 20810b57cec5SDimitry Andric Op.appendToVector(Ops); 20820b57cec5SDimitry Andric } 20830b57cec5SDimitry Andric } 2084bdd1243dSDimitry Andric assert((!Expr->isImplicit() || CanSplitValue) && "Expr can't be split"); 20858bcb0991SDimitry Andric assert(Expr && "Unknown DIExpression"); 2086*0fca6ea1SDimitry Andric if (EmitFragment) { 20870b57cec5SDimitry Andric Ops.push_back(dwarf::DW_OP_LLVM_fragment); 20880b57cec5SDimitry Andric Ops.push_back(OffsetInBits); 20890b57cec5SDimitry Andric Ops.push_back(SizeInBits); 2090*0fca6ea1SDimitry Andric } 20910b57cec5SDimitry Andric return DIExpression::get(Expr->getContext(), Ops); 20920b57cec5SDimitry Andric } 20930b57cec5SDimitry Andric 2094*0fca6ea1SDimitry Andric /// See declaration for more info. 2095*0fca6ea1SDimitry Andric bool DIExpression::calculateFragmentIntersect( 2096*0fca6ea1SDimitry Andric const DataLayout &DL, const Value *SliceStart, uint64_t SliceOffsetInBits, 2097*0fca6ea1SDimitry Andric uint64_t SliceSizeInBits, const Value *DbgPtr, int64_t DbgPtrOffsetInBits, 2098*0fca6ea1SDimitry Andric int64_t DbgExtractOffsetInBits, DIExpression::FragmentInfo VarFrag, 2099*0fca6ea1SDimitry Andric std::optional<DIExpression::FragmentInfo> &Result, 2100*0fca6ea1SDimitry Andric int64_t &OffsetFromLocationInBits) { 2101*0fca6ea1SDimitry Andric 2102*0fca6ea1SDimitry Andric if (VarFrag.SizeInBits == 0) 2103*0fca6ea1SDimitry Andric return false; // Variable size is unknown. 2104*0fca6ea1SDimitry Andric 2105*0fca6ea1SDimitry Andric // Difference between mem slice start and the dbg location start. 2106*0fca6ea1SDimitry Andric // 0 4 8 12 16 ... 2107*0fca6ea1SDimitry Andric // | | 2108*0fca6ea1SDimitry Andric // dbg location start 2109*0fca6ea1SDimitry Andric // | 2110*0fca6ea1SDimitry Andric // mem slice start 2111*0fca6ea1SDimitry Andric // Here MemStartRelToDbgStartInBits is 8. Note this can be negative. 2112*0fca6ea1SDimitry Andric int64_t MemStartRelToDbgStartInBits; 2113*0fca6ea1SDimitry Andric { 2114*0fca6ea1SDimitry Andric auto MemOffsetFromDbgInBytes = SliceStart->getPointerOffsetFrom(DbgPtr, DL); 2115*0fca6ea1SDimitry Andric if (!MemOffsetFromDbgInBytes) 2116*0fca6ea1SDimitry Andric return false; // Can't calculate difference in addresses. 2117*0fca6ea1SDimitry Andric // Difference between the pointers. 2118*0fca6ea1SDimitry Andric MemStartRelToDbgStartInBits = *MemOffsetFromDbgInBytes * 8; 2119*0fca6ea1SDimitry Andric // Add the difference of the offsets. 2120*0fca6ea1SDimitry Andric MemStartRelToDbgStartInBits += 2121*0fca6ea1SDimitry Andric SliceOffsetInBits - (DbgPtrOffsetInBits + DbgExtractOffsetInBits); 2122*0fca6ea1SDimitry Andric } 2123*0fca6ea1SDimitry Andric 2124*0fca6ea1SDimitry Andric // Out-param. Invert offset to get offset from debug location. 2125*0fca6ea1SDimitry Andric OffsetFromLocationInBits = -MemStartRelToDbgStartInBits; 2126*0fca6ea1SDimitry Andric 2127*0fca6ea1SDimitry Andric // Check if the variable fragment sits outside (before) this memory slice. 2128*0fca6ea1SDimitry Andric int64_t MemEndRelToDbgStart = MemStartRelToDbgStartInBits + SliceSizeInBits; 2129*0fca6ea1SDimitry Andric if (MemEndRelToDbgStart < 0) { 2130*0fca6ea1SDimitry Andric Result = {0, 0}; // Out-param. 2131*0fca6ea1SDimitry Andric return true; 2132*0fca6ea1SDimitry Andric } 2133*0fca6ea1SDimitry Andric 2134*0fca6ea1SDimitry Andric // Work towards creating SliceOfVariable which is the bits of the variable 2135*0fca6ea1SDimitry Andric // that the memory region covers. 2136*0fca6ea1SDimitry Andric // 0 4 8 12 16 ... 2137*0fca6ea1SDimitry Andric // | | 2138*0fca6ea1SDimitry Andric // dbg location start with VarFrag offset=32 2139*0fca6ea1SDimitry Andric // | 2140*0fca6ea1SDimitry Andric // mem slice start: SliceOfVariable offset=40 2141*0fca6ea1SDimitry Andric int64_t MemStartRelToVarInBits = 2142*0fca6ea1SDimitry Andric MemStartRelToDbgStartInBits + VarFrag.OffsetInBits; 2143*0fca6ea1SDimitry Andric int64_t MemEndRelToVarInBits = MemStartRelToVarInBits + SliceSizeInBits; 2144*0fca6ea1SDimitry Andric // If the memory region starts before the debug location the fragment 2145*0fca6ea1SDimitry Andric // offset would be negative, which we can't encode. Limit those to 0. This 2146*0fca6ea1SDimitry Andric // is fine because those bits necessarily don't overlap with the existing 2147*0fca6ea1SDimitry Andric // variable fragment. 2148*0fca6ea1SDimitry Andric int64_t MemFragStart = std::max<int64_t>(0, MemStartRelToVarInBits); 2149*0fca6ea1SDimitry Andric int64_t MemFragSize = 2150*0fca6ea1SDimitry Andric std::max<int64_t>(0, MemEndRelToVarInBits - MemFragStart); 2151*0fca6ea1SDimitry Andric DIExpression::FragmentInfo SliceOfVariable(MemFragSize, MemFragStart); 2152*0fca6ea1SDimitry Andric 2153*0fca6ea1SDimitry Andric // Intersect the memory region fragment with the variable location fragment. 2154*0fca6ea1SDimitry Andric DIExpression::FragmentInfo TrimmedSliceOfVariable = 2155*0fca6ea1SDimitry Andric DIExpression::FragmentInfo::intersect(SliceOfVariable, VarFrag); 2156*0fca6ea1SDimitry Andric if (TrimmedSliceOfVariable == VarFrag) 2157*0fca6ea1SDimitry Andric Result = std::nullopt; // Out-param. 2158*0fca6ea1SDimitry Andric else 2159*0fca6ea1SDimitry Andric Result = TrimmedSliceOfVariable; // Out-param. 2160*0fca6ea1SDimitry Andric return true; 2161*0fca6ea1SDimitry Andric } 2162*0fca6ea1SDimitry Andric 2163349cc55cSDimitry Andric std::pair<DIExpression *, const ConstantInt *> 2164349cc55cSDimitry Andric DIExpression::constantFold(const ConstantInt *CI) { 2165349cc55cSDimitry Andric // Copy the APInt so we can modify it. 2166349cc55cSDimitry Andric APInt NewInt = CI->getValue(); 2167349cc55cSDimitry Andric SmallVector<uint64_t, 8> Ops; 2168349cc55cSDimitry Andric 2169349cc55cSDimitry Andric // Fold operators only at the beginning of the expression. 2170349cc55cSDimitry Andric bool First = true; 2171349cc55cSDimitry Andric bool Changed = false; 2172349cc55cSDimitry Andric for (auto Op : expr_ops()) { 2173349cc55cSDimitry Andric switch (Op.getOp()) { 2174349cc55cSDimitry Andric default: 2175349cc55cSDimitry Andric // We fold only the leading part of the expression; if we get to a part 2176349cc55cSDimitry Andric // that we're going to copy unchanged, and haven't done any folding, 2177349cc55cSDimitry Andric // then the entire expression is unchanged and we can return early. 2178349cc55cSDimitry Andric if (!Changed) 2179349cc55cSDimitry Andric return {this, CI}; 2180349cc55cSDimitry Andric First = false; 2181349cc55cSDimitry Andric break; 2182349cc55cSDimitry Andric case dwarf::DW_OP_LLVM_convert: 2183349cc55cSDimitry Andric if (!First) 2184349cc55cSDimitry Andric break; 2185349cc55cSDimitry Andric Changed = true; 2186349cc55cSDimitry Andric if (Op.getArg(1) == dwarf::DW_ATE_signed) 2187349cc55cSDimitry Andric NewInt = NewInt.sextOrTrunc(Op.getArg(0)); 2188349cc55cSDimitry Andric else { 2189349cc55cSDimitry Andric assert(Op.getArg(1) == dwarf::DW_ATE_unsigned && "Unexpected operand"); 2190349cc55cSDimitry Andric NewInt = NewInt.zextOrTrunc(Op.getArg(0)); 2191349cc55cSDimitry Andric } 2192349cc55cSDimitry Andric continue; 2193349cc55cSDimitry Andric } 2194349cc55cSDimitry Andric Op.appendToVector(Ops); 2195349cc55cSDimitry Andric } 2196349cc55cSDimitry Andric if (!Changed) 2197349cc55cSDimitry Andric return {this, CI}; 2198349cc55cSDimitry Andric return {DIExpression::get(getContext(), Ops), 2199349cc55cSDimitry Andric ConstantInt::get(getContext(), NewInt)}; 2200349cc55cSDimitry Andric } 2201349cc55cSDimitry Andric 2202fe6060f1SDimitry Andric uint64_t DIExpression::getNumLocationOperands() const { 2203fe6060f1SDimitry Andric uint64_t Result = 0; 2204fe6060f1SDimitry Andric for (auto ExprOp : expr_ops()) 2205fe6060f1SDimitry Andric if (ExprOp.getOp() == dwarf::DW_OP_LLVM_arg) 2206fe6060f1SDimitry Andric Result = std::max(Result, ExprOp.getArg(0) + 1); 2207fe6060f1SDimitry Andric assert(hasAllLocationOps(Result) && 2208fe6060f1SDimitry Andric "Expression is missing one or more location operands."); 2209fe6060f1SDimitry Andric return Result; 22100b57cec5SDimitry Andric } 22110b57cec5SDimitry Andric 2212bdd1243dSDimitry Andric std::optional<DIExpression::SignedOrUnsignedConstant> 2213fe6060f1SDimitry Andric DIExpression::isConstant() const { 2214fe6060f1SDimitry Andric 2215fe6060f1SDimitry Andric // Recognize signed and unsigned constants. 2216fe6060f1SDimitry Andric // An signed constants can be represented as DW_OP_consts C DW_OP_stack_value 2217fe6060f1SDimitry Andric // (DW_OP_LLVM_fragment of Len). 2218fe6060f1SDimitry Andric // An unsigned constant can be represented as 2219fe6060f1SDimitry Andric // DW_OP_constu C DW_OP_stack_value (DW_OP_LLVM_fragment of Len). 2220fe6060f1SDimitry Andric 2221fe6060f1SDimitry Andric if ((getNumElements() != 2 && getNumElements() != 3 && 2222fe6060f1SDimitry Andric getNumElements() != 6) || 2223fe6060f1SDimitry Andric (getElement(0) != dwarf::DW_OP_consts && 2224fe6060f1SDimitry Andric getElement(0) != dwarf::DW_OP_constu)) 2225bdd1243dSDimitry Andric return std::nullopt; 2226fe6060f1SDimitry Andric 2227fe6060f1SDimitry Andric if (getNumElements() == 2 && getElement(0) == dwarf::DW_OP_consts) 2228fe6060f1SDimitry Andric return SignedOrUnsignedConstant::SignedConstant; 2229fe6060f1SDimitry Andric 2230fe6060f1SDimitry Andric if ((getNumElements() == 3 && getElement(2) != dwarf::DW_OP_stack_value) || 2231fe6060f1SDimitry Andric (getNumElements() == 6 && (getElement(2) != dwarf::DW_OP_stack_value || 2232fe6060f1SDimitry Andric getElement(3) != dwarf::DW_OP_LLVM_fragment))) 2233bdd1243dSDimitry Andric return std::nullopt; 2234fe6060f1SDimitry Andric return getElement(0) == dwarf::DW_OP_constu 2235fe6060f1SDimitry Andric ? SignedOrUnsignedConstant::UnsignedConstant 2236fe6060f1SDimitry Andric : SignedOrUnsignedConstant::SignedConstant; 2237e8d8bef9SDimitry Andric } 2238e8d8bef9SDimitry Andric 2239480093f4SDimitry Andric DIExpression::ExtOps DIExpression::getExtOps(unsigned FromSize, unsigned ToSize, 2240480093f4SDimitry Andric bool Signed) { 2241480093f4SDimitry Andric dwarf::TypeKind TK = Signed ? dwarf::DW_ATE_signed : dwarf::DW_ATE_unsigned; 2242480093f4SDimitry Andric DIExpression::ExtOps Ops{{dwarf::DW_OP_LLVM_convert, FromSize, TK, 2243480093f4SDimitry Andric dwarf::DW_OP_LLVM_convert, ToSize, TK}}; 2244480093f4SDimitry Andric return Ops; 2245480093f4SDimitry Andric } 2246480093f4SDimitry Andric 2247480093f4SDimitry Andric DIExpression *DIExpression::appendExt(const DIExpression *Expr, 2248480093f4SDimitry Andric unsigned FromSize, unsigned ToSize, 2249480093f4SDimitry Andric bool Signed) { 2250480093f4SDimitry Andric return appendToStack(Expr, getExtOps(FromSize, ToSize, Signed)); 2251480093f4SDimitry Andric } 2252480093f4SDimitry Andric 22530b57cec5SDimitry Andric DIGlobalVariableExpression * 22540b57cec5SDimitry Andric DIGlobalVariableExpression::getImpl(LLVMContext &Context, Metadata *Variable, 22550b57cec5SDimitry Andric Metadata *Expression, StorageType Storage, 22560b57cec5SDimitry Andric bool ShouldCreate) { 22570b57cec5SDimitry Andric DEFINE_GETIMPL_LOOKUP(DIGlobalVariableExpression, (Variable, Expression)); 22580b57cec5SDimitry Andric Metadata *Ops[] = {Variable, Expression}; 22590b57cec5SDimitry Andric DEFINE_GETIMPL_STORE_NO_CONSTRUCTOR_ARGS(DIGlobalVariableExpression, Ops); 22600b57cec5SDimitry Andric } 226181ad6265SDimitry Andric DIObjCProperty::DIObjCProperty(LLVMContext &C, StorageType Storage, 226281ad6265SDimitry Andric unsigned Line, unsigned Attributes, 226381ad6265SDimitry Andric ArrayRef<Metadata *> Ops) 226481ad6265SDimitry Andric : DINode(C, DIObjCPropertyKind, Storage, dwarf::DW_TAG_APPLE_property, Ops), 226581ad6265SDimitry Andric Line(Line), Attributes(Attributes) {} 22660b57cec5SDimitry Andric 22670b57cec5SDimitry Andric DIObjCProperty *DIObjCProperty::getImpl( 22680b57cec5SDimitry Andric LLVMContext &Context, MDString *Name, Metadata *File, unsigned Line, 22690b57cec5SDimitry Andric MDString *GetterName, MDString *SetterName, unsigned Attributes, 22700b57cec5SDimitry Andric Metadata *Type, StorageType Storage, bool ShouldCreate) { 22710b57cec5SDimitry Andric assert(isCanonical(Name) && "Expected canonical MDString"); 22720b57cec5SDimitry Andric assert(isCanonical(GetterName) && "Expected canonical MDString"); 22730b57cec5SDimitry Andric assert(isCanonical(SetterName) && "Expected canonical MDString"); 22740b57cec5SDimitry Andric DEFINE_GETIMPL_LOOKUP(DIObjCProperty, (Name, File, Line, GetterName, 22750b57cec5SDimitry Andric SetterName, Attributes, Type)); 22760b57cec5SDimitry Andric Metadata *Ops[] = {Name, File, GetterName, SetterName, Type}; 22770b57cec5SDimitry Andric DEFINE_GETIMPL_STORE(DIObjCProperty, (Line, Attributes), Ops); 22780b57cec5SDimitry Andric } 22790b57cec5SDimitry Andric 22800b57cec5SDimitry Andric DIImportedEntity *DIImportedEntity::getImpl(LLVMContext &Context, unsigned Tag, 22810b57cec5SDimitry Andric Metadata *Scope, Metadata *Entity, 22820b57cec5SDimitry Andric Metadata *File, unsigned Line, 2283349cc55cSDimitry Andric MDString *Name, Metadata *Elements, 2284349cc55cSDimitry Andric StorageType Storage, 22850b57cec5SDimitry Andric bool ShouldCreate) { 22860b57cec5SDimitry Andric assert(isCanonical(Name) && "Expected canonical MDString"); 22870b57cec5SDimitry Andric DEFINE_GETIMPL_LOOKUP(DIImportedEntity, 2288349cc55cSDimitry Andric (Tag, Scope, Entity, File, Line, Name, Elements)); 2289349cc55cSDimitry Andric Metadata *Ops[] = {Scope, Entity, Name, File, Elements}; 22900b57cec5SDimitry Andric DEFINE_GETIMPL_STORE(DIImportedEntity, (Tag, Line), Ops); 22910b57cec5SDimitry Andric } 22920b57cec5SDimitry Andric 2293349cc55cSDimitry Andric DIMacro *DIMacro::getImpl(LLVMContext &Context, unsigned MIType, unsigned Line, 2294349cc55cSDimitry Andric MDString *Name, MDString *Value, StorageType Storage, 2295349cc55cSDimitry Andric bool ShouldCreate) { 22960b57cec5SDimitry Andric assert(isCanonical(Name) && "Expected canonical MDString"); 22970b57cec5SDimitry Andric DEFINE_GETIMPL_LOOKUP(DIMacro, (MIType, Line, Name, Value)); 22980b57cec5SDimitry Andric Metadata *Ops[] = {Name, Value}; 22990b57cec5SDimitry Andric DEFINE_GETIMPL_STORE(DIMacro, (MIType, Line), Ops); 23000b57cec5SDimitry Andric } 23010b57cec5SDimitry Andric 23020b57cec5SDimitry Andric DIMacroFile *DIMacroFile::getImpl(LLVMContext &Context, unsigned MIType, 23030b57cec5SDimitry Andric unsigned Line, Metadata *File, 23040b57cec5SDimitry Andric Metadata *Elements, StorageType Storage, 23050b57cec5SDimitry Andric bool ShouldCreate) { 2306349cc55cSDimitry Andric DEFINE_GETIMPL_LOOKUP(DIMacroFile, (MIType, Line, File, Elements)); 23070b57cec5SDimitry Andric Metadata *Ops[] = {File, Elements}; 23080b57cec5SDimitry Andric DEFINE_GETIMPL_STORE(DIMacroFile, (MIType, Line), Ops); 23090b57cec5SDimitry Andric } 2310fe6060f1SDimitry Andric 23115f757f3fSDimitry Andric DIArgList *DIArgList::get(LLVMContext &Context, 23125f757f3fSDimitry Andric ArrayRef<ValueAsMetadata *> Args) { 23135f757f3fSDimitry Andric auto ExistingIt = Context.pImpl->DIArgLists.find_as(DIArgListKeyInfo(Args)); 23145f757f3fSDimitry Andric if (ExistingIt != Context.pImpl->DIArgLists.end()) 23155f757f3fSDimitry Andric return *ExistingIt; 23165f757f3fSDimitry Andric DIArgList *NewArgList = new DIArgList(Context, Args); 23175f757f3fSDimitry Andric Context.pImpl->DIArgLists.insert(NewArgList); 23185f757f3fSDimitry Andric return NewArgList; 2319fe6060f1SDimitry Andric } 2320fe6060f1SDimitry Andric 2321fe6060f1SDimitry Andric void DIArgList::handleChangedOperand(void *Ref, Metadata *New) { 2322fe6060f1SDimitry Andric ValueAsMetadata **OldVMPtr = static_cast<ValueAsMetadata **>(Ref); 2323fe6060f1SDimitry Andric assert((!New || isa<ValueAsMetadata>(New)) && 2324fe6060f1SDimitry Andric "DIArgList must be passed a ValueAsMetadata"); 2325fe6060f1SDimitry Andric untrack(); 23265f757f3fSDimitry Andric // We need to update the set storage once the Args are updated since they 2327349cc55cSDimitry Andric // form the key to the DIArgLists store. 23285f757f3fSDimitry Andric getContext().pImpl->DIArgLists.erase(this); 2329fe6060f1SDimitry Andric ValueAsMetadata *NewVM = cast_or_null<ValueAsMetadata>(New); 2330fe6060f1SDimitry Andric for (ValueAsMetadata *&VM : Args) { 2331fe6060f1SDimitry Andric if (&VM == OldVMPtr) { 2332fe6060f1SDimitry Andric if (NewVM) 2333fe6060f1SDimitry Andric VM = NewVM; 2334fe6060f1SDimitry Andric else 233506c3fb27SDimitry Andric VM = ValueAsMetadata::get(PoisonValue::get(VM->getValue()->getType())); 2336fe6060f1SDimitry Andric } 2337fe6060f1SDimitry Andric } 23385f757f3fSDimitry Andric // We've changed the contents of this DIArgList, and the set storage may 23395f757f3fSDimitry Andric // already contain a DIArgList with our new set of args; if it does, then we 23405f757f3fSDimitry Andric // must RAUW this with the existing DIArgList, otherwise we simply insert this 23415f757f3fSDimitry Andric // back into the set storage. 23425f757f3fSDimitry Andric DIArgList *ExistingArgList = getUniqued(getContext().pImpl->DIArgLists, this); 23435f757f3fSDimitry Andric if (ExistingArgList) { 23445f757f3fSDimitry Andric replaceAllUsesWith(ExistingArgList); 23455f757f3fSDimitry Andric // Clear this here so we don't try to untrack in the destructor. 23465f757f3fSDimitry Andric Args.clear(); 23475f757f3fSDimitry Andric delete this; 23485f757f3fSDimitry Andric return; 2349349cc55cSDimitry Andric } 23505f757f3fSDimitry Andric getContext().pImpl->DIArgLists.insert(this); 2351fe6060f1SDimitry Andric track(); 2352fe6060f1SDimitry Andric } 2353fe6060f1SDimitry Andric void DIArgList::track() { 2354fe6060f1SDimitry Andric for (ValueAsMetadata *&VAM : Args) 2355fe6060f1SDimitry Andric if (VAM) 2356fe6060f1SDimitry Andric MetadataTracking::track(&VAM, *VAM, *this); 2357fe6060f1SDimitry Andric } 2358fe6060f1SDimitry Andric void DIArgList::untrack() { 2359fe6060f1SDimitry Andric for (ValueAsMetadata *&VAM : Args) 2360fe6060f1SDimitry Andric if (VAM) 2361fe6060f1SDimitry Andric MetadataTracking::untrack(&VAM, *VAM); 2362fe6060f1SDimitry Andric } 23635f757f3fSDimitry Andric void DIArgList::dropAllReferences(bool Untrack) { 23645f757f3fSDimitry Andric if (Untrack) 2365fe6060f1SDimitry Andric untrack(); 2366fe6060f1SDimitry Andric Args.clear(); 23675f757f3fSDimitry Andric ReplaceableMetadataImpl::resolveAllUses(/* ResolveUsers */ false); 2368fe6060f1SDimitry Andric } 2369