Mercurial > hg > CbC > CbC_llvm
comparison lib/IR/DebugInfoMetadata.cpp @ 148:63bd29f05246
merged
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 14 Aug 2019 19:46:37 +0900 |
parents | c2174574ed3a |
children |
comparison
equal
deleted
inserted
replaced
146:3fc4d5c3e21e | 148:63bd29f05246 |
---|---|
1 //===- DebugInfoMetadata.cpp - Implement debug info metadata --------------===// | 1 //===- DebugInfoMetadata.cpp - Implement debug info metadata --------------===// |
2 // | 2 // |
3 // The LLVM Compiler Infrastructure | 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 // | 4 // See https://llvm.org/LICENSE.txt for license information. |
5 // This file is distributed under the University of Illinois Open Source | 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 // License. See LICENSE.TXT for details. | |
7 // | 6 // |
8 //===----------------------------------------------------------------------===// | 7 //===----------------------------------------------------------------------===// |
9 // | 8 // |
10 // This file implements the debug info Metadata classes. | 9 // This file implements the debug info Metadata classes. |
11 // | 10 // |
12 //===----------------------------------------------------------------------===// | 11 //===----------------------------------------------------------------------===// |
13 | 12 |
14 #include "llvm/IR/DebugInfoMetadata.h" | 13 #include "llvm/IR/DebugInfoMetadata.h" |
15 #include "LLVMContextImpl.h" | 14 #include "LLVMContextImpl.h" |
16 #include "MetadataImpl.h" | 15 #include "MetadataImpl.h" |
17 #include "llvm/ADT/SmallPtrSet.h" | 16 #include "llvm/ADT/SmallSet.h" |
18 #include "llvm/ADT/StringSwitch.h" | 17 #include "llvm/ADT/StringSwitch.h" |
19 #include "llvm/IR/DIBuilder.h" | 18 #include "llvm/IR/DIBuilder.h" |
20 #include "llvm/IR/Function.h" | 19 #include "llvm/IR/Function.h" |
21 #include "llvm/IR/Instructions.h" | 20 #include "llvm/IR/Instructions.h" |
22 | 21 |
22 #include <numeric> | |
23 | |
23 using namespace llvm; | 24 using namespace llvm; |
24 | 25 |
25 DILocation::DILocation(LLVMContext &C, StorageType Storage, unsigned Line, | 26 DILocation::DILocation(LLVMContext &C, StorageType Storage, unsigned Line, |
26 unsigned Column, ArrayRef<Metadata *> MDs) | 27 unsigned Column, ArrayRef<Metadata *> MDs, |
28 bool ImplicitCode) | |
27 : MDNode(C, DILocationKind, Storage, MDs) { | 29 : MDNode(C, DILocationKind, Storage, MDs) { |
28 assert((MDs.size() == 1 || MDs.size() == 2) && | 30 assert((MDs.size() == 1 || MDs.size() == 2) && |
29 "Expected a scope and optional inlined-at"); | 31 "Expected a scope and optional inlined-at"); |
30 | 32 |
31 // Set line and column. | 33 // Set line and column. |
32 assert(Column < (1u << 16) && "Expected 16-bit column"); | 34 assert(Column < (1u << 16) && "Expected 16-bit column"); |
33 | 35 |
34 SubclassData32 = Line; | 36 SubclassData32 = Line; |
35 SubclassData16 = Column; | 37 SubclassData16 = Column; |
38 | |
39 setImplicitCode(ImplicitCode); | |
36 } | 40 } |
37 | 41 |
38 static void adjustColumn(unsigned &Column) { | 42 static void adjustColumn(unsigned &Column) { |
39 // Set to unknown on overflow. We only have 16 bits to play with here. | 43 // Set to unknown on overflow. We only have 16 bits to play with here. |
40 if (Column >= (1u << 16)) | 44 if (Column >= (1u << 16)) |
41 Column = 0; | 45 Column = 0; |
42 } | 46 } |
43 | 47 |
44 DILocation *DILocation::getImpl(LLVMContext &Context, unsigned Line, | 48 DILocation *DILocation::getImpl(LLVMContext &Context, unsigned Line, |
45 unsigned Column, Metadata *Scope, | 49 unsigned Column, Metadata *Scope, |
46 Metadata *InlinedAt, StorageType Storage, | 50 Metadata *InlinedAt, bool ImplicitCode, |
47 bool ShouldCreate) { | 51 StorageType Storage, bool ShouldCreate) { |
48 // Fixup column. | 52 // Fixup column. |
49 adjustColumn(Column); | 53 adjustColumn(Column); |
50 | 54 |
51 if (Storage == Uniqued) { | 55 if (Storage == Uniqued) { |
52 if (auto *N = | 56 if (auto *N = getUniqued(Context.pImpl->DILocations, |
53 getUniqued(Context.pImpl->DILocations, | 57 DILocationInfo::KeyTy(Line, Column, Scope, |
54 DILocationInfo::KeyTy(Line, Column, Scope, InlinedAt))) | 58 InlinedAt, ImplicitCode))) |
55 return N; | 59 return N; |
56 if (!ShouldCreate) | 60 if (!ShouldCreate) |
57 return nullptr; | 61 return nullptr; |
58 } else { | 62 } else { |
59 assert(ShouldCreate && "Expected non-uniqued nodes to always be created"); | 63 assert(ShouldCreate && "Expected non-uniqued nodes to always be created"); |
61 | 65 |
62 SmallVector<Metadata *, 2> Ops; | 66 SmallVector<Metadata *, 2> Ops; |
63 Ops.push_back(Scope); | 67 Ops.push_back(Scope); |
64 if (InlinedAt) | 68 if (InlinedAt) |
65 Ops.push_back(InlinedAt); | 69 Ops.push_back(InlinedAt); |
66 return storeImpl(new (Ops.size()) | 70 return storeImpl(new (Ops.size()) DILocation(Context, Storage, Line, Column, |
67 DILocation(Context, Storage, Line, Column, Ops), | 71 Ops, ImplicitCode), |
68 Storage, Context.pImpl->DILocations); | 72 Storage, Context.pImpl->DILocations); |
69 } | 73 } |
70 | 74 |
71 const DILocation * | 75 const DILocation *DILocation::getMergedLocation(const DILocation *LocA, |
72 DILocation::getMergedLocation(const DILocation *LocA, const DILocation *LocB, | 76 const DILocation *LocB) { |
73 const Instruction *ForInst) { | |
74 if (!LocA || !LocB) | 77 if (!LocA || !LocB) |
75 return nullptr; | 78 return nullptr; |
76 | 79 |
77 if (LocA == LocB || !LocA->canDiscriminate(*LocB)) | 80 if (LocA == LocB) |
78 return LocA; | 81 return LocA; |
79 | |
80 if (!dyn_cast_or_null<CallInst>(ForInst)) | |
81 return nullptr; | |
82 | 82 |
83 SmallPtrSet<DILocation *, 5> InlinedLocationsA; | 83 SmallPtrSet<DILocation *, 5> InlinedLocationsA; |
84 for (DILocation *L = LocA->getInlinedAt(); L; L = L->getInlinedAt()) | 84 for (DILocation *L = LocA->getInlinedAt(); L; L = L->getInlinedAt()) |
85 InlinedLocationsA.insert(L); | 85 InlinedLocationsA.insert(L); |
86 SmallSet<std::pair<DIScope *, DILocation *>, 5> Locations; | |
87 DIScope *S = LocA->getScope(); | |
88 DILocation *L = LocA->getInlinedAt(); | |
89 while (S) { | |
90 Locations.insert(std::make_pair(S, L)); | |
91 S = S->getScope(); | |
92 if (!S && L) { | |
93 S = L->getScope(); | |
94 L = L->getInlinedAt(); | |
95 } | |
96 } | |
86 const DILocation *Result = LocB; | 97 const DILocation *Result = LocB; |
87 for (DILocation *L = LocB->getInlinedAt(); L; L = L->getInlinedAt()) { | 98 S = LocB->getScope(); |
88 Result = L; | 99 L = LocB->getInlinedAt(); |
89 if (InlinedLocationsA.count(L)) | 100 while (S) { |
101 if (Locations.count(std::make_pair(S, L))) | |
90 break; | 102 break; |
91 } | 103 S = S->getScope(); |
92 return DILocation::get(Result->getContext(), 0, 0, Result->getScope(), | 104 if (!S && L) { |
93 Result->getInlinedAt()); | 105 S = L->getScope(); |
94 } | 106 L = L->getInlinedAt(); |
107 } | |
108 } | |
109 | |
110 // If the two locations are irreconsilable, just pick one. This is misleading, | |
111 // but on the other hand, it's a "line 0" location. | |
112 if (!S || !isa<DILocalScope>(S)) | |
113 S = LocA->getScope(); | |
114 return DILocation::get(Result->getContext(), 0, 0, S, L); | |
115 } | |
116 | |
117 Optional<unsigned> DILocation::encodeDiscriminator(unsigned BD, unsigned DF, unsigned CI) { | |
118 SmallVector<unsigned, 3> Components = {BD, DF, CI}; | |
119 uint64_t RemainingWork = 0U; | |
120 // We use RemainingWork to figure out if we have no remaining components to | |
121 // encode. For example: if BD != 0 but DF == 0 && CI == 0, we don't need to | |
122 // encode anything for the latter 2. | |
123 // Since any of the input components is at most 32 bits, their sum will be | |
124 // less than 34 bits, and thus RemainingWork won't overflow. | |
125 RemainingWork = std::accumulate(Components.begin(), Components.end(), RemainingWork); | |
126 | |
127 int I = 0; | |
128 unsigned Ret = 0; | |
129 unsigned NextBitInsertionIndex = 0; | |
130 while (RemainingWork > 0) { | |
131 unsigned C = Components[I++]; | |
132 RemainingWork -= C; | |
133 unsigned EC = encodeComponent(C); | |
134 Ret |= (EC << NextBitInsertionIndex); | |
135 NextBitInsertionIndex += encodingBits(C); | |
136 } | |
137 | |
138 // Encoding may be unsuccessful because of overflow. We determine success by | |
139 // checking equivalence of components before & after encoding. Alternatively, | |
140 // we could determine Success during encoding, but the current alternative is | |
141 // simpler. | |
142 unsigned TBD, TDF, TCI = 0; | |
143 decodeDiscriminator(Ret, TBD, TDF, TCI); | |
144 if (TBD == BD && TDF == DF && TCI == CI) | |
145 return Ret; | |
146 return None; | |
147 } | |
148 | |
149 void DILocation::decodeDiscriminator(unsigned D, unsigned &BD, unsigned &DF, | |
150 unsigned &CI) { | |
151 BD = getUnsignedFromPrefixEncoding(D); | |
152 DF = getUnsignedFromPrefixEncoding(getNextComponentInDiscriminator(D)); | |
153 CI = getUnsignedFromPrefixEncoding( | |
154 getNextComponentInDiscriminator(getNextComponentInDiscriminator(D))); | |
155 } | |
156 | |
95 | 157 |
96 DINode::DIFlags DINode::getFlag(StringRef Flag) { | 158 DINode::DIFlags DINode::getFlag(StringRef Flag) { |
97 return StringSwitch<DIFlags>(Flag) | 159 return StringSwitch<DIFlags>(Flag) |
98 #define HANDLE_DI_FLAG(ID, NAME) .Case("DIFlag" #NAME, Flag##NAME) | 160 #define HANDLE_DI_FLAG(ID, NAME) .Case("DIFlag" #NAME, Flag##NAME) |
99 #include "llvm/IR/DebugInfoFlags.def" | 161 #include "llvm/IR/DebugInfoFlags.def" |
145 } | 207 } |
146 #include "llvm/IR/DebugInfoFlags.def" | 208 #include "llvm/IR/DebugInfoFlags.def" |
147 return Flags; | 209 return Flags; |
148 } | 210 } |
149 | 211 |
150 DIScopeRef DIScope::getScope() const { | 212 DIScope *DIScope::getScope() const { |
151 if (auto *T = dyn_cast<DIType>(this)) | 213 if (auto *T = dyn_cast<DIType>(this)) |
152 return T->getScope(); | 214 return T->getScope(); |
153 | 215 |
154 if (auto *SP = dyn_cast<DISubprogram>(this)) | 216 if (auto *SP = dyn_cast<DISubprogram>(this)) |
155 return SP->getScope(); | 217 return SP->getScope(); |
157 if (auto *LB = dyn_cast<DILexicalBlockBase>(this)) | 219 if (auto *LB = dyn_cast<DILexicalBlockBase>(this)) |
158 return LB->getScope(); | 220 return LB->getScope(); |
159 | 221 |
160 if (auto *NS = dyn_cast<DINamespace>(this)) | 222 if (auto *NS = dyn_cast<DINamespace>(this)) |
161 return NS->getScope(); | 223 return NS->getScope(); |
224 | |
225 if (auto *CB = dyn_cast<DICommonBlock>(this)) | |
226 return CB->getScope(); | |
162 | 227 |
163 if (auto *M = dyn_cast<DIModule>(this)) | 228 if (auto *M = dyn_cast<DIModule>(this)) |
164 return M->getScope(); | 229 return M->getScope(); |
165 | 230 |
166 assert((isa<DIFile>(this) || isa<DICompileUnit>(this)) && | 231 assert((isa<DIFile>(this) || isa<DICompileUnit>(this)) && |
173 return T->getName(); | 238 return T->getName(); |
174 if (auto *SP = dyn_cast<DISubprogram>(this)) | 239 if (auto *SP = dyn_cast<DISubprogram>(this)) |
175 return SP->getName(); | 240 return SP->getName(); |
176 if (auto *NS = dyn_cast<DINamespace>(this)) | 241 if (auto *NS = dyn_cast<DINamespace>(this)) |
177 return NS->getName(); | 242 return NS->getName(); |
243 if (auto *CB = dyn_cast<DICommonBlock>(this)) | |
244 return CB->getName(); | |
178 if (auto *M = dyn_cast<DIModule>(this)) | 245 if (auto *M = dyn_cast<DIModule>(this)) |
179 return M->getName(); | 246 return M->getName(); |
180 assert((isa<DILexicalBlockBase>(this) || isa<DIFile>(this) || | 247 assert((isa<DILexicalBlockBase>(this) || isa<DIFile>(this) || |
181 isa<DICompileUnit>(this)) && | 248 isa<DICompileUnit>(this)) && |
182 "Unhandled type of scope."); | 249 "Unhandled type of scope."); |
272 } | 339 } |
273 | 340 |
274 DIBasicType *DIBasicType::getImpl(LLVMContext &Context, unsigned Tag, | 341 DIBasicType *DIBasicType::getImpl(LLVMContext &Context, unsigned Tag, |
275 MDString *Name, uint64_t SizeInBits, | 342 MDString *Name, uint64_t SizeInBits, |
276 uint32_t AlignInBits, unsigned Encoding, | 343 uint32_t AlignInBits, unsigned Encoding, |
277 StorageType Storage, bool ShouldCreate) { | 344 DIFlags Flags, StorageType Storage, |
345 bool ShouldCreate) { | |
278 assert(isCanonical(Name) && "Expected canonical MDString"); | 346 assert(isCanonical(Name) && "Expected canonical MDString"); |
279 DEFINE_GETIMPL_LOOKUP(DIBasicType, | 347 DEFINE_GETIMPL_LOOKUP(DIBasicType, |
280 (Tag, Name, SizeInBits, AlignInBits, Encoding)); | 348 (Tag, Name, SizeInBits, AlignInBits, Encoding, Flags)); |
281 Metadata *Ops[] = {nullptr, nullptr, Name}; | 349 Metadata *Ops[] = {nullptr, nullptr, Name}; |
282 DEFINE_GETIMPL_STORE(DIBasicType, (Tag, SizeInBits, AlignInBits, Encoding), | 350 DEFINE_GETIMPL_STORE(DIBasicType, (Tag, SizeInBits, AlignInBits, Encoding, |
283 Ops); | 351 Flags), Ops); |
352 } | |
353 | |
354 Optional<DIBasicType::Signedness> DIBasicType::getSignedness() const { | |
355 switch (getEncoding()) { | |
356 case dwarf::DW_ATE_signed: | |
357 case dwarf::DW_ATE_signed_char: | |
358 return Signedness::Signed; | |
359 case dwarf::DW_ATE_unsigned: | |
360 case dwarf::DW_ATE_unsigned_char: | |
361 return Signedness::Unsigned; | |
362 default: | |
363 return None; | |
364 } | |
284 } | 365 } |
285 | 366 |
286 DIDerivedType *DIDerivedType::getImpl( | 367 DIDerivedType *DIDerivedType::getImpl( |
287 LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File, | 368 LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File, |
288 unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, | 369 unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, |
415 } | 496 } |
416 | 497 |
417 DIFile *DIFile::getImpl(LLVMContext &Context, MDString *Filename, | 498 DIFile *DIFile::getImpl(LLVMContext &Context, MDString *Filename, |
418 MDString *Directory, | 499 MDString *Directory, |
419 Optional<DIFile::ChecksumInfo<MDString *>> CS, | 500 Optional<DIFile::ChecksumInfo<MDString *>> CS, |
420 StorageType Storage, bool ShouldCreate) { | 501 Optional<MDString *> Source, StorageType Storage, |
502 bool ShouldCreate) { | |
421 assert(isCanonical(Filename) && "Expected canonical MDString"); | 503 assert(isCanonical(Filename) && "Expected canonical MDString"); |
422 assert(isCanonical(Directory) && "Expected canonical MDString"); | 504 assert(isCanonical(Directory) && "Expected canonical MDString"); |
423 assert((!CS || isCanonical(CS->Value)) && "Expected canonical MDString"); | 505 assert((!CS || isCanonical(CS->Value)) && "Expected canonical MDString"); |
424 DEFINE_GETIMPL_LOOKUP(DIFile, (Filename, Directory, CS)); | 506 assert((!Source || isCanonical(*Source)) && "Expected canonical MDString"); |
425 Metadata *Ops[] = {Filename, Directory, CS ? CS->Value : nullptr}; | 507 DEFINE_GETIMPL_LOOKUP(DIFile, (Filename, Directory, CS, Source)); |
426 DEFINE_GETIMPL_STORE(DIFile, (CS), Ops); | 508 Metadata *Ops[] = {Filename, Directory, CS ? CS->Value : nullptr, |
509 Source.getValueOr(nullptr)}; | |
510 DEFINE_GETIMPL_STORE(DIFile, (CS, Source), Ops); | |
427 } | 511 } |
428 | 512 |
429 DICompileUnit *DICompileUnit::getImpl( | 513 DICompileUnit *DICompileUnit::getImpl( |
430 LLVMContext &Context, unsigned SourceLanguage, Metadata *File, | 514 LLVMContext &Context, unsigned SourceLanguage, Metadata *File, |
431 MDString *Producer, bool IsOptimized, MDString *Flags, | 515 MDString *Producer, bool IsOptimized, MDString *Flags, |
432 unsigned RuntimeVersion, MDString *SplitDebugFilename, | 516 unsigned RuntimeVersion, MDString *SplitDebugFilename, |
433 unsigned EmissionKind, Metadata *EnumTypes, Metadata *RetainedTypes, | 517 unsigned EmissionKind, Metadata *EnumTypes, Metadata *RetainedTypes, |
434 Metadata *GlobalVariables, Metadata *ImportedEntities, Metadata *Macros, | 518 Metadata *GlobalVariables, Metadata *ImportedEntities, Metadata *Macros, |
435 uint64_t DWOId, bool SplitDebugInlining, bool DebugInfoForProfiling, | 519 uint64_t DWOId, bool SplitDebugInlining, bool DebugInfoForProfiling, |
436 bool GnuPubnames, StorageType Storage, bool ShouldCreate) { | 520 unsigned NameTableKind, bool RangesBaseAddress, StorageType Storage, |
521 bool ShouldCreate) { | |
437 assert(Storage != Uniqued && "Cannot unique DICompileUnit"); | 522 assert(Storage != Uniqued && "Cannot unique DICompileUnit"); |
438 assert(isCanonical(Producer) && "Expected canonical MDString"); | 523 assert(isCanonical(Producer) && "Expected canonical MDString"); |
439 assert(isCanonical(Flags) && "Expected canonical MDString"); | 524 assert(isCanonical(Flags) && "Expected canonical MDString"); |
440 assert(isCanonical(SplitDebugFilename) && "Expected canonical MDString"); | 525 assert(isCanonical(SplitDebugFilename) && "Expected canonical MDString"); |
441 | 526 |
444 EnumTypes, RetainedTypes, GlobalVariables, ImportedEntities, | 529 EnumTypes, RetainedTypes, GlobalVariables, ImportedEntities, |
445 Macros}; | 530 Macros}; |
446 return storeImpl(new (array_lengthof(Ops)) DICompileUnit( | 531 return storeImpl(new (array_lengthof(Ops)) DICompileUnit( |
447 Context, Storage, SourceLanguage, IsOptimized, | 532 Context, Storage, SourceLanguage, IsOptimized, |
448 RuntimeVersion, EmissionKind, DWOId, SplitDebugInlining, | 533 RuntimeVersion, EmissionKind, DWOId, SplitDebugInlining, |
449 DebugInfoForProfiling, GnuPubnames, Ops), | 534 DebugInfoForProfiling, NameTableKind, RangesBaseAddress, |
535 Ops), | |
450 Storage); | 536 Storage); |
451 } | 537 } |
452 | 538 |
453 Optional<DICompileUnit::DebugEmissionKind> | 539 Optional<DICompileUnit::DebugEmissionKind> |
454 DICompileUnit::getEmissionKind(StringRef Str) { | 540 DICompileUnit::getEmissionKind(StringRef Str) { |
455 return StringSwitch<Optional<DebugEmissionKind>>(Str) | 541 return StringSwitch<Optional<DebugEmissionKind>>(Str) |
456 .Case("NoDebug", NoDebug) | 542 .Case("NoDebug", NoDebug) |
457 .Case("FullDebug", FullDebug) | 543 .Case("FullDebug", FullDebug) |
458 .Case("LineTablesOnly", LineTablesOnly) | 544 .Case("LineTablesOnly", LineTablesOnly) |
545 .Case("DebugDirectivesOnly", DebugDirectivesOnly) | |
459 .Default(None); | 546 .Default(None); |
460 } | 547 } |
461 | 548 |
462 const char *DICompileUnit::EmissionKindString(DebugEmissionKind EK) { | 549 Optional<DICompileUnit::DebugNameTableKind> |
550 DICompileUnit::getNameTableKind(StringRef Str) { | |
551 return StringSwitch<Optional<DebugNameTableKind>>(Str) | |
552 .Case("Default", DebugNameTableKind::Default) | |
553 .Case("GNU", DebugNameTableKind::GNU) | |
554 .Case("None", DebugNameTableKind::None) | |
555 .Default(None); | |
556 } | |
557 | |
558 const char *DICompileUnit::emissionKindString(DebugEmissionKind EK) { | |
463 switch (EK) { | 559 switch (EK) { |
464 case NoDebug: return "NoDebug"; | 560 case NoDebug: return "NoDebug"; |
465 case FullDebug: return "FullDebug"; | 561 case FullDebug: return "FullDebug"; |
466 case LineTablesOnly: return "LineTablesOnly"; | 562 case LineTablesOnly: return "LineTablesOnly"; |
563 case DebugDirectivesOnly: return "DebugDirectivesOnly"; | |
564 } | |
565 return nullptr; | |
566 } | |
567 | |
568 const char *DICompileUnit::nameTableKindString(DebugNameTableKind NTK) { | |
569 switch (NTK) { | |
570 case DebugNameTableKind::Default: | |
571 return nullptr; | |
572 case DebugNameTableKind::GNU: | |
573 return "GNU"; | |
574 case DebugNameTableKind::None: | |
575 return "None"; | |
467 } | 576 } |
468 return nullptr; | 577 return nullptr; |
469 } | 578 } |
470 | 579 |
471 DISubprogram *DILocalScope::getSubprogram() const { | 580 DISubprogram *DILocalScope::getSubprogram() const { |
478 if (auto *File = dyn_cast<DILexicalBlockFile>(this)) | 587 if (auto *File = dyn_cast<DILexicalBlockFile>(this)) |
479 return File->getScope()->getNonLexicalBlockFileScope(); | 588 return File->getScope()->getNonLexicalBlockFileScope(); |
480 return const_cast<DILocalScope *>(this); | 589 return const_cast<DILocalScope *>(this); |
481 } | 590 } |
482 | 591 |
592 DISubprogram::DISPFlags DISubprogram::getFlag(StringRef Flag) { | |
593 return StringSwitch<DISPFlags>(Flag) | |
594 #define HANDLE_DISP_FLAG(ID, NAME) .Case("DISPFlag" #NAME, SPFlag##NAME) | |
595 #include "llvm/IR/DebugInfoFlags.def" | |
596 .Default(SPFlagZero); | |
597 } | |
598 | |
599 StringRef DISubprogram::getFlagString(DISPFlags Flag) { | |
600 switch (Flag) { | |
601 // Appease a warning. | |
602 case SPFlagVirtuality: | |
603 return ""; | |
604 #define HANDLE_DISP_FLAG(ID, NAME) \ | |
605 case SPFlag##NAME: \ | |
606 return "DISPFlag" #NAME; | |
607 #include "llvm/IR/DebugInfoFlags.def" | |
608 } | |
609 return ""; | |
610 } | |
611 | |
612 DISubprogram::DISPFlags | |
613 DISubprogram::splitFlags(DISPFlags Flags, | |
614 SmallVectorImpl<DISPFlags> &SplitFlags) { | |
615 // Multi-bit fields can require special handling. In our case, however, the | |
616 // only multi-bit field is virtuality, and all its values happen to be | |
617 // single-bit values, so the right behavior just falls out. | |
618 #define HANDLE_DISP_FLAG(ID, NAME) \ | |
619 if (DISPFlags Bit = Flags & SPFlag##NAME) { \ | |
620 SplitFlags.push_back(Bit); \ | |
621 Flags &= ~Bit; \ | |
622 } | |
623 #include "llvm/IR/DebugInfoFlags.def" | |
624 return Flags; | |
625 } | |
626 | |
483 DISubprogram *DISubprogram::getImpl( | 627 DISubprogram *DISubprogram::getImpl( |
484 LLVMContext &Context, Metadata *Scope, MDString *Name, | 628 LLVMContext &Context, Metadata *Scope, MDString *Name, |
485 MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type, | 629 MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type, |
486 bool IsLocalToUnit, bool IsDefinition, unsigned ScopeLine, | 630 unsigned ScopeLine, Metadata *ContainingType, unsigned VirtualIndex, |
487 Metadata *ContainingType, unsigned Virtuality, unsigned VirtualIndex, | 631 int ThisAdjustment, DIFlags Flags, DISPFlags SPFlags, Metadata *Unit, |
488 int ThisAdjustment, DIFlags Flags, bool IsOptimized, Metadata *Unit, | 632 Metadata *TemplateParams, Metadata *Declaration, Metadata *RetainedNodes, |
489 Metadata *TemplateParams, Metadata *Declaration, Metadata *Variables, | |
490 Metadata *ThrownTypes, StorageType Storage, bool ShouldCreate) { | 633 Metadata *ThrownTypes, StorageType Storage, bool ShouldCreate) { |
491 assert(isCanonical(Name) && "Expected canonical MDString"); | 634 assert(isCanonical(Name) && "Expected canonical MDString"); |
492 assert(isCanonical(LinkageName) && "Expected canonical MDString"); | 635 assert(isCanonical(LinkageName) && "Expected canonical MDString"); |
493 DEFINE_GETIMPL_LOOKUP( | 636 DEFINE_GETIMPL_LOOKUP(DISubprogram, |
494 DISubprogram, (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, | 637 (Scope, Name, LinkageName, File, Line, Type, ScopeLine, |
495 IsDefinition, ScopeLine, ContainingType, Virtuality, | 638 ContainingType, VirtualIndex, ThisAdjustment, Flags, |
496 VirtualIndex, ThisAdjustment, Flags, IsOptimized, Unit, | 639 SPFlags, Unit, TemplateParams, Declaration, |
497 TemplateParams, Declaration, Variables, ThrownTypes)); | 640 RetainedNodes, ThrownTypes)); |
498 SmallVector<Metadata *, 11> Ops = { | 641 SmallVector<Metadata *, 11> Ops = { |
499 File, Scope, Name, LinkageName, Type, Unit, | 642 File, Scope, Name, LinkageName, Type, Unit, |
500 Declaration, Variables, ContainingType, TemplateParams, ThrownTypes}; | 643 Declaration, RetainedNodes, ContainingType, TemplateParams, ThrownTypes}; |
501 if (!ThrownTypes) { | 644 if (!ThrownTypes) { |
502 Ops.pop_back(); | 645 Ops.pop_back(); |
503 if (!TemplateParams) { | 646 if (!TemplateParams) { |
504 Ops.pop_back(); | 647 Ops.pop_back(); |
505 if (!ContainingType) | 648 if (!ContainingType) |
506 Ops.pop_back(); | 649 Ops.pop_back(); |
507 } | 650 } |
508 } | 651 } |
509 DEFINE_GETIMPL_STORE_N(DISubprogram, | 652 DEFINE_GETIMPL_STORE_N( |
510 (Line, ScopeLine, Virtuality, VirtualIndex, | 653 DISubprogram, |
511 ThisAdjustment, Flags, IsLocalToUnit, IsDefinition, | 654 (Line, ScopeLine, VirtualIndex, ThisAdjustment, Flags, SPFlags), Ops, |
512 IsOptimized), | 655 Ops.size()); |
513 Ops, Ops.size()); | |
514 } | 656 } |
515 | 657 |
516 bool DISubprogram::describes(const Function *F) const { | 658 bool DISubprogram::describes(const Function *F) const { |
517 assert(F && "Invalid function"); | 659 assert(F && "Invalid function"); |
518 if (F->getSubprogram() == this) | 660 if (F->getSubprogram() == this) |
555 // The nullptr is for DIScope's File operand. This should be refactored. | 697 // The nullptr is for DIScope's File operand. This should be refactored. |
556 Metadata *Ops[] = {nullptr, Scope, Name}; | 698 Metadata *Ops[] = {nullptr, Scope, Name}; |
557 DEFINE_GETIMPL_STORE(DINamespace, (ExportSymbols), Ops); | 699 DEFINE_GETIMPL_STORE(DINamespace, (ExportSymbols), Ops); |
558 } | 700 } |
559 | 701 |
702 DICommonBlock *DICommonBlock::getImpl(LLVMContext &Context, Metadata *Scope, | |
703 Metadata *Decl, MDString *Name, | |
704 Metadata *File, unsigned LineNo, | |
705 StorageType Storage, bool ShouldCreate) { | |
706 assert(isCanonical(Name) && "Expected canonical MDString"); | |
707 DEFINE_GETIMPL_LOOKUP(DICommonBlock, (Scope, Decl, Name, File, LineNo)); | |
708 // The nullptr is for DIScope's File operand. This should be refactored. | |
709 Metadata *Ops[] = {Scope, Decl, Name, File}; | |
710 DEFINE_GETIMPL_STORE(DICommonBlock, (LineNo), Ops); | |
711 } | |
712 | |
560 DIModule *DIModule::getImpl(LLVMContext &Context, Metadata *Scope, | 713 DIModule *DIModule::getImpl(LLVMContext &Context, Metadata *Scope, |
561 MDString *Name, MDString *ConfigurationMacros, | 714 MDString *Name, MDString *ConfigurationMacros, |
562 MDString *IncludePath, MDString *ISysRoot, | 715 MDString *IncludePath, MDString *ISysRoot, |
563 StorageType Storage, bool ShouldCreate) { | 716 StorageType Storage, bool ShouldCreate) { |
564 assert(isCanonical(Name) && "Expected canonical MDString"); | 717 assert(isCanonical(Name) && "Expected canonical MDString"); |
591 DIGlobalVariable * | 744 DIGlobalVariable * |
592 DIGlobalVariable::getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name, | 745 DIGlobalVariable::getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name, |
593 MDString *LinkageName, Metadata *File, unsigned Line, | 746 MDString *LinkageName, Metadata *File, unsigned Line, |
594 Metadata *Type, bool IsLocalToUnit, bool IsDefinition, | 747 Metadata *Type, bool IsLocalToUnit, bool IsDefinition, |
595 Metadata *StaticDataMemberDeclaration, | 748 Metadata *StaticDataMemberDeclaration, |
596 uint32_t AlignInBits, StorageType Storage, | 749 Metadata *TemplateParams, uint32_t AlignInBits, |
597 bool ShouldCreate) { | 750 StorageType Storage, bool ShouldCreate) { |
598 assert(isCanonical(Name) && "Expected canonical MDString"); | 751 assert(isCanonical(Name) && "Expected canonical MDString"); |
599 assert(isCanonical(LinkageName) && "Expected canonical MDString"); | 752 assert(isCanonical(LinkageName) && "Expected canonical MDString"); |
600 DEFINE_GETIMPL_LOOKUP(DIGlobalVariable, | 753 DEFINE_GETIMPL_LOOKUP(DIGlobalVariable, (Scope, Name, LinkageName, File, Line, |
601 (Scope, Name, LinkageName, File, Line, Type, | 754 Type, IsLocalToUnit, IsDefinition, |
602 IsLocalToUnit, IsDefinition, | 755 StaticDataMemberDeclaration, |
603 StaticDataMemberDeclaration, AlignInBits)); | 756 TemplateParams, AlignInBits)); |
604 Metadata *Ops[] = { | 757 Metadata *Ops[] = {Scope, |
605 Scope, Name, File, Type, Name, LinkageName, StaticDataMemberDeclaration}; | 758 Name, |
759 File, | |
760 Type, | |
761 Name, | |
762 LinkageName, | |
763 StaticDataMemberDeclaration, | |
764 TemplateParams}; | |
606 DEFINE_GETIMPL_STORE(DIGlobalVariable, | 765 DEFINE_GETIMPL_STORE(DIGlobalVariable, |
607 (Line, IsLocalToUnit, IsDefinition, AlignInBits), | 766 (Line, IsLocalToUnit, IsDefinition, AlignInBits), Ops); |
608 Ops); | |
609 } | 767 } |
610 | 768 |
611 DILocalVariable *DILocalVariable::getImpl(LLVMContext &Context, Metadata *Scope, | 769 DILocalVariable *DILocalVariable::getImpl(LLVMContext &Context, Metadata *Scope, |
612 MDString *Name, Metadata *File, | 770 MDString *Name, Metadata *File, |
613 unsigned Line, Metadata *Type, | 771 unsigned Line, Metadata *Type, |
648 | 806 |
649 // Fail gracefully. | 807 // Fail gracefully. |
650 return None; | 808 return None; |
651 } | 809 } |
652 | 810 |
811 DILabel *DILabel::getImpl(LLVMContext &Context, Metadata *Scope, | |
812 MDString *Name, Metadata *File, unsigned Line, | |
813 StorageType Storage, | |
814 bool ShouldCreate) { | |
815 assert(Scope && "Expected scope"); | |
816 assert(isCanonical(Name) && "Expected canonical MDString"); | |
817 DEFINE_GETIMPL_LOOKUP(DILabel, | |
818 (Scope, Name, File, Line)); | |
819 Metadata *Ops[] = {Scope, Name, File}; | |
820 DEFINE_GETIMPL_STORE(DILabel, (Line), Ops); | |
821 } | |
822 | |
653 DIExpression *DIExpression::getImpl(LLVMContext &Context, | 823 DIExpression *DIExpression::getImpl(LLVMContext &Context, |
654 ArrayRef<uint64_t> Elements, | 824 ArrayRef<uint64_t> Elements, |
655 StorageType Storage, bool ShouldCreate) { | 825 StorageType Storage, bool ShouldCreate) { |
656 DEFINE_GETIMPL_LOOKUP(DIExpression, (Elements)); | 826 DEFINE_GETIMPL_LOOKUP(DIExpression, (Elements)); |
657 DEFINE_GETIMPL_STORE_NO_OPS(DIExpression, (Elements)); | 827 DEFINE_GETIMPL_STORE_NO_OPS(DIExpression, (Elements)); |
658 } | 828 } |
659 | 829 |
660 unsigned DIExpression::ExprOperand::getSize() const { | 830 unsigned DIExpression::ExprOperand::getSize() const { |
661 switch (getOp()) { | 831 uint64_t Op = getOp(); |
832 | |
833 if (Op >= dwarf::DW_OP_breg0 && Op <= dwarf::DW_OP_breg31) | |
834 return 2; | |
835 | |
836 switch (Op) { | |
837 case dwarf::DW_OP_LLVM_convert: | |
662 case dwarf::DW_OP_LLVM_fragment: | 838 case dwarf::DW_OP_LLVM_fragment: |
839 case dwarf::DW_OP_bregx: | |
663 return 3; | 840 return 3; |
664 case dwarf::DW_OP_constu: | 841 case dwarf::DW_OP_constu: |
842 case dwarf::DW_OP_consts: | |
843 case dwarf::DW_OP_deref_size: | |
665 case dwarf::DW_OP_plus_uconst: | 844 case dwarf::DW_OP_plus_uconst: |
845 case dwarf::DW_OP_LLVM_tag_offset: | |
846 case dwarf::DW_OP_entry_value: | |
847 case dwarf::DW_OP_regx: | |
666 return 2; | 848 return 2; |
667 default: | 849 default: |
668 return 1; | 850 return 1; |
669 } | 851 } |
670 } | 852 } |
673 for (auto I = expr_op_begin(), E = expr_op_end(); I != E; ++I) { | 855 for (auto I = expr_op_begin(), E = expr_op_end(); I != E; ++I) { |
674 // Check that there's space for the operand. | 856 // Check that there's space for the operand. |
675 if (I->get() + I->getSize() > E->get()) | 857 if (I->get() + I->getSize() > E->get()) |
676 return false; | 858 return false; |
677 | 859 |
860 uint64_t Op = I->getOp(); | |
861 if ((Op >= dwarf::DW_OP_reg0 && Op <= dwarf::DW_OP_reg31) || | |
862 (Op >= dwarf::DW_OP_breg0 && Op <= dwarf::DW_OP_breg31)) | |
863 return true; | |
864 | |
678 // Check that the operand is valid. | 865 // Check that the operand is valid. |
679 switch (I->getOp()) { | 866 switch (Op) { |
680 default: | 867 default: |
681 return false; | 868 return false; |
682 case dwarf::DW_OP_LLVM_fragment: | 869 case dwarf::DW_OP_LLVM_fragment: |
683 // A fragment operator must appear at the end. | 870 // A fragment operator must appear at the end. |
684 return I->get() + I->getSize() == E->get(); | 871 return I->get() + I->getSize() == E->get(); |
701 // elements into isValid. | 888 // elements into isValid. |
702 if (getNumElements() == 1) | 889 if (getNumElements() == 1) |
703 return false; | 890 return false; |
704 break; | 891 break; |
705 } | 892 } |
893 case dwarf::DW_OP_entry_value: { | |
894 // An entry value operator must appear at the begin and the size | |
895 // of following expression should be 1, because we support only | |
896 // entry values of a simple register location. | |
897 return I->get() == expr_op_begin()->get() && I->getArg(0) == 1 && | |
898 getNumElements() == 2; | |
899 } | |
900 case dwarf::DW_OP_LLVM_convert: | |
901 case dwarf::DW_OP_LLVM_tag_offset: | |
706 case dwarf::DW_OP_constu: | 902 case dwarf::DW_OP_constu: |
707 case dwarf::DW_OP_plus_uconst: | 903 case dwarf::DW_OP_plus_uconst: |
708 case dwarf::DW_OP_plus: | 904 case dwarf::DW_OP_plus: |
709 case dwarf::DW_OP_minus: | 905 case dwarf::DW_OP_minus: |
710 case dwarf::DW_OP_mul: | 906 case dwarf::DW_OP_mul: |
715 case dwarf::DW_OP_xor: | 911 case dwarf::DW_OP_xor: |
716 case dwarf::DW_OP_shl: | 912 case dwarf::DW_OP_shl: |
717 case dwarf::DW_OP_shr: | 913 case dwarf::DW_OP_shr: |
718 case dwarf::DW_OP_shra: | 914 case dwarf::DW_OP_shra: |
719 case dwarf::DW_OP_deref: | 915 case dwarf::DW_OP_deref: |
916 case dwarf::DW_OP_deref_size: | |
720 case dwarf::DW_OP_xderef: | 917 case dwarf::DW_OP_xderef: |
918 case dwarf::DW_OP_lit0: | |
919 case dwarf::DW_OP_not: | |
920 case dwarf::DW_OP_dup: | |
921 case dwarf::DW_OP_regx: | |
922 case dwarf::DW_OP_bregx: | |
721 break; | 923 break; |
722 } | 924 } |
723 } | 925 } |
724 return true; | 926 return true; |
927 } | |
928 | |
929 bool DIExpression::isImplicit() const { | |
930 unsigned N = getNumElements(); | |
931 if (isValid() && N > 0) { | |
932 switch (getElement(N-1)) { | |
933 case dwarf::DW_OP_stack_value: | |
934 case dwarf::DW_OP_LLVM_tag_offset: | |
935 return true; | |
936 case dwarf::DW_OP_LLVM_fragment: | |
937 return N > 1 && getElement(N-2) == dwarf::DW_OP_stack_value; | |
938 default: break; | |
939 } | |
940 } | |
941 return false; | |
942 } | |
943 | |
944 bool DIExpression::isComplex() const { | |
945 if (!isValid()) | |
946 return false; | |
947 | |
948 if (getNumElements() == 0) | |
949 return false; | |
950 | |
951 // If there are any elements other than fragment or tag_offset, then some | |
952 // kind of complex computation occurs. | |
953 for (const auto &It : expr_ops()) { | |
954 switch (It.getOp()) { | |
955 case dwarf::DW_OP_LLVM_tag_offset: | |
956 case dwarf::DW_OP_LLVM_fragment: | |
957 continue; | |
958 default: return true; | |
959 } | |
960 } | |
961 | |
962 return false; | |
725 } | 963 } |
726 | 964 |
727 Optional<DIExpression::FragmentInfo> | 965 Optional<DIExpression::FragmentInfo> |
728 DIExpression::getFragmentInfo(expr_op_iterator Start, expr_op_iterator End) { | 966 DIExpression::getFragmentInfo(expr_op_iterator Start, expr_op_iterator End) { |
729 for (auto I = Start; I != End; ++I) | 967 for (auto I = Start; I != End; ++I) |
769 } | 1007 } |
770 | 1008 |
771 return false; | 1009 return false; |
772 } | 1010 } |
773 | 1011 |
774 DIExpression *DIExpression::prepend(const DIExpression *Expr, bool DerefBefore, | 1012 const DIExpression *DIExpression::extractAddressClass(const DIExpression *Expr, |
775 int64_t Offset, bool DerefAfter, | 1013 unsigned &AddrClass) { |
776 bool StackValue) { | 1014 const unsigned PatternSize = 4; |
1015 if (Expr->Elements.size() >= PatternSize && | |
1016 Expr->Elements[PatternSize - 4] == dwarf::DW_OP_constu && | |
1017 Expr->Elements[PatternSize - 2] == dwarf::DW_OP_swap && | |
1018 Expr->Elements[PatternSize - 1] == dwarf::DW_OP_xderef) { | |
1019 AddrClass = Expr->Elements[PatternSize - 3]; | |
1020 | |
1021 if (Expr->Elements.size() == PatternSize) | |
1022 return nullptr; | |
1023 return DIExpression::get(Expr->getContext(), | |
1024 makeArrayRef(&*Expr->Elements.begin(), | |
1025 Expr->Elements.size() - PatternSize)); | |
1026 } | |
1027 return Expr; | |
1028 } | |
1029 | |
1030 DIExpression *DIExpression::prepend(const DIExpression *Expr, uint8_t Flags, | |
1031 int64_t Offset) { | |
777 SmallVector<uint64_t, 8> Ops; | 1032 SmallVector<uint64_t, 8> Ops; |
778 if (DerefBefore) | 1033 if (Flags & DIExpression::DerefBefore) |
779 Ops.push_back(dwarf::DW_OP_deref); | 1034 Ops.push_back(dwarf::DW_OP_deref); |
780 | 1035 |
781 appendOffset(Ops, Offset); | 1036 appendOffset(Ops, Offset); |
782 if (DerefAfter) | 1037 if (Flags & DIExpression::DerefAfter) |
783 Ops.push_back(dwarf::DW_OP_deref); | 1038 Ops.push_back(dwarf::DW_OP_deref); |
784 | 1039 |
785 return doPrepend(Expr, Ops, StackValue); | 1040 bool StackValue = Flags & DIExpression::StackValue; |
786 } | 1041 bool EntryValue = Flags & DIExpression::EntryValue; |
787 | 1042 |
788 DIExpression *DIExpression::doPrepend(const DIExpression *Expr, | 1043 return prependOpcodes(Expr, Ops, StackValue, EntryValue); |
789 SmallVectorImpl<uint64_t> &Ops, | 1044 } |
790 bool StackValue) { | 1045 |
791 if (Expr) | 1046 DIExpression *DIExpression::prependOpcodes(const DIExpression *Expr, |
792 for (auto Op : Expr->expr_ops()) { | 1047 SmallVectorImpl<uint64_t> &Ops, |
793 // A DW_OP_stack_value comes at the end, but before a DW_OP_LLVM_fragment. | 1048 bool StackValue, |
794 if (StackValue) { | 1049 bool EntryValue) { |
795 if (Op.getOp() == dwarf::DW_OP_stack_value) | 1050 assert(Expr && "Can't prepend ops to this expression"); |
796 StackValue = false; | 1051 |
797 else if (Op.getOp() == dwarf::DW_OP_LLVM_fragment) { | 1052 if (EntryValue) { |
798 Ops.push_back(dwarf::DW_OP_stack_value); | 1053 Ops.push_back(dwarf::DW_OP_entry_value); |
799 StackValue = false; | 1054 // Add size info needed for entry value expression. |
800 } | 1055 // Add plus one for target register operand. |
1056 Ops.push_back(Expr->getNumElements() + 1); | |
1057 } | |
1058 | |
1059 // If there are no ops to prepend, do not even add the DW_OP_stack_value. | |
1060 if (Ops.empty()) | |
1061 StackValue = false; | |
1062 for (auto Op : Expr->expr_ops()) { | |
1063 // A DW_OP_stack_value comes at the end, but before a DW_OP_LLVM_fragment. | |
1064 if (StackValue) { | |
1065 if (Op.getOp() == dwarf::DW_OP_stack_value) | |
1066 StackValue = false; | |
1067 else if (Op.getOp() == dwarf::DW_OP_LLVM_fragment) { | |
1068 Ops.push_back(dwarf::DW_OP_stack_value); | |
1069 StackValue = false; | |
801 } | 1070 } |
802 Ops.push_back(Op.getOp()); | 1071 } |
803 for (unsigned I = 0; I < Op.getNumArgs(); ++I) | 1072 Op.appendToVector(Ops); |
804 Ops.push_back(Op.getArg(I)); | 1073 } |
805 } | |
806 if (StackValue) | 1074 if (StackValue) |
807 Ops.push_back(dwarf::DW_OP_stack_value); | 1075 Ops.push_back(dwarf::DW_OP_stack_value); |
808 return DIExpression::get(Expr->getContext(), Ops); | 1076 return DIExpression::get(Expr->getContext(), Ops); |
1077 } | |
1078 | |
1079 DIExpression *DIExpression::append(const DIExpression *Expr, | |
1080 ArrayRef<uint64_t> Ops) { | |
1081 assert(Expr && !Ops.empty() && "Can't append ops to this expression"); | |
1082 | |
1083 // Copy Expr's current op list. | |
1084 SmallVector<uint64_t, 16> NewOps; | |
1085 for (auto Op : Expr->expr_ops()) { | |
1086 // Append new opcodes before DW_OP_{stack_value, LLVM_fragment}. | |
1087 if (Op.getOp() == dwarf::DW_OP_stack_value || | |
1088 Op.getOp() == dwarf::DW_OP_LLVM_fragment) { | |
1089 NewOps.append(Ops.begin(), Ops.end()); | |
1090 | |
1091 // Ensure that the new opcodes are only appended once. | |
1092 Ops = None; | |
1093 } | |
1094 Op.appendToVector(NewOps); | |
1095 } | |
1096 | |
1097 NewOps.append(Ops.begin(), Ops.end()); | |
1098 return DIExpression::get(Expr->getContext(), NewOps); | |
1099 } | |
1100 | |
1101 DIExpression *DIExpression::appendToStack(const DIExpression *Expr, | |
1102 ArrayRef<uint64_t> Ops) { | |
1103 assert(Expr && !Ops.empty() && "Can't append ops to this expression"); | |
1104 assert(none_of(Ops, | |
1105 [](uint64_t Op) { | |
1106 return Op == dwarf::DW_OP_stack_value || | |
1107 Op == dwarf::DW_OP_LLVM_fragment; | |
1108 }) && | |
1109 "Can't append this op"); | |
1110 | |
1111 // Append a DW_OP_deref after Expr's current op list if it's non-empty and | |
1112 // has no DW_OP_stack_value. | |
1113 // | |
1114 // Match .* DW_OP_stack_value (DW_OP_LLVM_fragment A B)?. | |
1115 Optional<FragmentInfo> FI = Expr->getFragmentInfo(); | |
1116 unsigned DropUntilStackValue = FI.hasValue() ? 3 : 0; | |
1117 ArrayRef<uint64_t> ExprOpsBeforeFragment = | |
1118 Expr->getElements().drop_back(DropUntilStackValue); | |
1119 bool NeedsDeref = (Expr->getNumElements() > DropUntilStackValue) && | |
1120 (ExprOpsBeforeFragment.back() != dwarf::DW_OP_stack_value); | |
1121 bool NeedsStackValue = NeedsDeref || ExprOpsBeforeFragment.empty(); | |
1122 | |
1123 // Append a DW_OP_deref after Expr's current op list if needed, then append | |
1124 // the new ops, and finally ensure that a single DW_OP_stack_value is present. | |
1125 SmallVector<uint64_t, 16> NewOps; | |
1126 if (NeedsDeref) | |
1127 NewOps.push_back(dwarf::DW_OP_deref); | |
1128 NewOps.append(Ops.begin(), Ops.end()); | |
1129 if (NeedsStackValue) | |
1130 NewOps.push_back(dwarf::DW_OP_stack_value); | |
1131 return DIExpression::append(Expr, NewOps); | |
809 } | 1132 } |
810 | 1133 |
811 Optional<DIExpression *> DIExpression::createFragmentExpression( | 1134 Optional<DIExpression *> DIExpression::createFragmentExpression( |
812 const DIExpression *Expr, unsigned OffsetInBits, unsigned SizeInBits) { | 1135 const DIExpression *Expr, unsigned OffsetInBits, unsigned SizeInBits) { |
813 SmallVector<uint64_t, 8> Ops; | 1136 SmallVector<uint64_t, 8> Ops; |
825 // operation if the offset fits into SizeInBits. | 1148 // operation if the offset fits into SizeInBits. |
826 return None; | 1149 return None; |
827 case dwarf::DW_OP_LLVM_fragment: { | 1150 case dwarf::DW_OP_LLVM_fragment: { |
828 // Make the new offset point into the existing fragment. | 1151 // Make the new offset point into the existing fragment. |
829 uint64_t FragmentOffsetInBits = Op.getArg(0); | 1152 uint64_t FragmentOffsetInBits = Op.getArg(0); |
830 // Op.getArg(0) is FragmentOffsetInBits. | 1153 uint64_t FragmentSizeInBits = Op.getArg(1); |
831 // Op.getArg(1) is FragmentSizeInBits. | 1154 (void)FragmentSizeInBits; |
832 assert((OffsetInBits + SizeInBits <= Op.getArg(0) + Op.getArg(1)) && | 1155 assert((OffsetInBits + SizeInBits <= FragmentSizeInBits) && |
833 "new fragment outside of original fragment"); | 1156 "new fragment outside of original fragment"); |
834 OffsetInBits += FragmentOffsetInBits; | 1157 OffsetInBits += FragmentOffsetInBits; |
835 continue; | 1158 continue; |
836 } | 1159 } |
837 } | 1160 } |
838 Ops.push_back(Op.getOp()); | 1161 Op.appendToVector(Ops); |
839 for (unsigned I = 0; I < Op.getNumArgs(); ++I) | |
840 Ops.push_back(Op.getArg(I)); | |
841 } | 1162 } |
842 } | 1163 } |
843 Ops.push_back(dwarf::DW_OP_LLVM_fragment); | 1164 Ops.push_back(dwarf::DW_OP_LLVM_fragment); |
844 Ops.push_back(OffsetInBits); | 1165 Ops.push_back(OffsetInBits); |
845 Ops.push_back(SizeInBits); | 1166 Ops.push_back(SizeInBits); |