Thanks to visit codestin.com
Credit goes to clang.llvm.org

clang 22.0.0git
Disasm.cpp
Go to the documentation of this file.
1//===--- Disasm.cpp - Disassembler for bytecode functions -------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// Dump method for Function which disassembles the bytecode.
10//
11//===----------------------------------------------------------------------===//
12
13#include "Boolean.h"
14#include "Context.h"
15#include "EvaluationResult.h"
16#include "FixedPoint.h"
17#include "Floating.h"
18#include "Function.h"
19#include "FunctionPointer.h"
20#include "Integral.h"
21#include "IntegralAP.h"
22#include "InterpFrame.h"
23#include "MemberPointer.h"
24#include "Opcode.h"
25#include "PrimType.h"
26#include "Program.h"
28#include "clang/AST/DeclCXX.h"
29#include "clang/AST/ExprCXX.h"
30#include "llvm/Support/Compiler.h"
31
32using namespace clang;
33using namespace clang::interp;
34
35template <typename T>
36inline static std::string printArg(Program &P, CodePtr &OpPC) {
37 if constexpr (std::is_pointer_v<T>) {
38 uint32_t ID = OpPC.read<uint32_t>();
39 std::string Result;
40 llvm::raw_string_ostream SS(Result);
41 SS << reinterpret_cast<T>(P.getNativePointer(ID));
42 return Result;
43 } else {
44 std::string Result;
45 llvm::raw_string_ostream SS(Result);
46 auto Arg = OpPC.read<T>();
47 // Make sure we print the integral value of chars.
48 if constexpr (std::is_integral_v<T>) {
49 if constexpr (sizeof(T) == 1) {
50 if constexpr (std::is_signed_v<T>)
51 SS << static_cast<int32_t>(Arg);
52 else
53 SS << static_cast<uint32_t>(Arg);
54 } else {
55 SS << Arg;
56 }
57 } else {
58 SS << Arg;
59 }
60
61 return Result;
62 }
63}
64
65template <> inline std::string printArg<Floating>(Program &P, CodePtr &OpPC) {
66 auto Sem = Floating::deserializeSemantics(*OpPC);
67
68 unsigned BitWidth = llvm::APFloatBase::semanticsSizeInBits(
69 llvm::APFloatBase::EnumToSemantics(Sem));
70 auto Memory =
71 std::make_unique<uint64_t[]>(llvm::APInt::getNumWords(BitWidth));
72 Floating Result(Memory.get(), Sem);
73 Floating::deserialize(*OpPC, &Result);
74
75 OpPC += align(Result.bytesToSerialize());
76
77 std::string S;
78 llvm::raw_string_ostream SS(S);
79 SS << std::move(Result);
80 return S;
81}
82
83template <>
84inline std::string printArg<IntegralAP<false>>(Program &P, CodePtr &OpPC) {
85 using T = IntegralAP<false>;
86 uint32_t BitWidth = T::deserializeSize(*OpPC);
87 auto Memory =
88 std::make_unique<uint64_t[]>(llvm::APInt::getNumWords(BitWidth));
89
90 T Result(Memory.get(), BitWidth);
91 T::deserialize(*OpPC, &Result);
92
93 OpPC += align(Result.bytesToSerialize());
94
95 std::string Str;
96 llvm::raw_string_ostream SS(Str);
97 SS << std::move(Result);
98 return Str;
99}
100
101template <>
102inline std::string printArg<IntegralAP<true>>(Program &P, CodePtr &OpPC) {
103 using T = IntegralAP<true>;
104 uint32_t BitWidth = T::deserializeSize(*OpPC);
105 auto Memory =
106 std::make_unique<uint64_t[]>(llvm::APInt::getNumWords(BitWidth));
107
108 T Result(Memory.get(), BitWidth);
109 T::deserialize(*OpPC, &Result);
110
111 OpPC += align(Result.bytesToSerialize());
112
113 std::string Str;
114 llvm::raw_string_ostream SS(Str);
115 SS << std::move(Result);
116 return Str;
117}
118
119template <> inline std::string printArg<FixedPoint>(Program &P, CodePtr &OpPC) {
120 auto F = FixedPoint::deserialize(*OpPC);
121 OpPC += align(F.bytesToSerialize());
122
123 std::string Result;
124 llvm::raw_string_ostream SS(Result);
125 SS << std::move(F);
126 return Result;
127}
128
129static bool isJumpOpcode(Opcode Op) {
130 return Op == OP_Jmp || Op == OP_Jf || Op == OP_Jt;
131}
132
133static size_t getNumDisplayWidth(size_t N) {
134 unsigned L = 1u, M = 10u;
135 while (M <= N && ++L != std::numeric_limits<size_t>::digits10 + 1)
136 M *= 10u;
137
138 return L;
139}
140
141LLVM_DUMP_METHOD void Function::dump() const { dump(llvm::errs()); }
142
143LLVM_DUMP_METHOD void Function::dump(llvm::raw_ostream &OS) const {
144 {
145 ColorScope SC(OS, true, {llvm::raw_ostream::BRIGHT_GREEN, true});
146 OS << getName() << " " << (const void *)this << "\n";
147 }
148 OS << "frame size: " << getFrameSize() << "\n";
149 OS << "arg size: " << getArgSize() << "\n";
150 OS << "rvo: " << hasRVO() << "\n";
151 OS << "this arg: " << hasThisPointer() << "\n";
152
153 struct OpText {
154 size_t Addr;
155 std::string Op;
156 bool IsJump;
158 };
159
160 auto PrintName = [](const char *Name) -> std::string {
161 return std::string(Name);
162 };
163
165 size_t LongestAddr = 0;
166 size_t LongestOp = 0;
167
168 for (CodePtr Start = getCodeBegin(), PC = Start; PC != getCodeEnd();) {
169 size_t Addr = PC - Start;
170 OpText Text;
171 auto Op = PC.read<Opcode>();
172 Text.Addr = Addr;
173 Text.IsJump = isJumpOpcode(Op);
174 switch (Op) {
175#define GET_DISASM
176#include "Opcodes.inc"
177#undef GET_DISASM
178 }
179 Code.push_back(Text);
180 LongestOp = std::max(Text.Op.size(), LongestOp);
181 LongestAddr = std::max(getNumDisplayWidth(Addr), LongestAddr);
182 }
183
184 // Record jumps and their targets.
185 struct JmpData {
186 size_t From;
187 size_t To;
188 };
190 for (auto &Text : Code) {
191 if (Text.IsJump)
192 Jumps.push_back({Text.Addr, Text.Addr + std::stoi(Text.Args[0]) +
193 align(sizeof(Opcode)) +
194 align(sizeof(int32_t))});
195 }
196
198 Text.reserve(Code.size());
199 size_t LongestLine = 0;
200 // Print code to a string, one at a time.
201 for (auto C : Code) {
202 std::string Line;
203 llvm::raw_string_ostream LS(Line);
204 LS << C.Addr;
205 LS.indent(LongestAddr - getNumDisplayWidth(C.Addr) + 4);
206 LS << C.Op;
207 LS.indent(LongestOp - C.Op.size() + 4);
208 for (auto &Arg : C.Args) {
209 LS << Arg << ' ';
210 }
211 Text.push_back(Line);
212 LongestLine = std::max(Line.size(), LongestLine);
213 }
214
215 assert(Code.size() == Text.size());
216
217 auto spaces = [](unsigned N) -> std::string {
218 std::string S;
219 for (unsigned I = 0; I != N; ++I)
220 S += ' ';
221 return S;
222 };
223
224 // Now, draw the jump lines.
225 for (auto &J : Jumps) {
226 if (J.To > J.From) {
227 bool FoundStart = false;
228 for (size_t LineIndex = 0; LineIndex != Text.size(); ++LineIndex) {
229 Text[LineIndex] += spaces(LongestLine - Text[LineIndex].size());
230
231 if (Code[LineIndex].Addr == J.From) {
232 Text[LineIndex] += " --+";
233 FoundStart = true;
234 } else if (Code[LineIndex].Addr == J.To) {
235 Text[LineIndex] += " <-+";
236 break;
237 } else if (FoundStart) {
238 Text[LineIndex] += " |";
239 }
240 }
241 LongestLine += 5;
242 } else {
243 bool FoundStart = false;
244 for (ssize_t LineIndex = Text.size() - 1; LineIndex >= 0; --LineIndex) {
245 Text[LineIndex] += spaces(LongestLine - Text[LineIndex].size());
246 if (Code[LineIndex].Addr == J.From) {
247 Text[LineIndex] += " --+";
248 FoundStart = true;
249 } else if (Code[LineIndex].Addr == J.To) {
250 Text[LineIndex] += " <-+";
251 break;
252 } else if (FoundStart) {
253 Text[LineIndex] += " |";
254 }
255 }
256 LongestLine += 5;
257 }
258 }
259
260 for (auto &Line : Text)
261 OS << Line << '\n';
262}
263
264LLVM_DUMP_METHOD void Program::dump() const { dump(llvm::errs()); }
265
266static const char *primTypeToString(PrimType T) {
267 switch (T) {
268 case PT_Sint8:
269 return "Sint8";
270 case PT_Uint8:
271 return "Uint8";
272 case PT_Sint16:
273 return "Sint16";
274 case PT_Uint16:
275 return "Uint16";
276 case PT_Sint32:
277 return "Sint32";
278 case PT_Uint32:
279 return "Uint32";
280 case PT_Sint64:
281 return "Sint64";
282 case PT_Uint64:
283 return "Uint64";
284 case PT_IntAP:
285 return "IntAP";
286 case PT_IntAPS:
287 return "IntAPS";
288 case PT_Bool:
289 return "Bool";
290 case PT_Float:
291 return "Float";
292 case PT_Ptr:
293 return "Ptr";
294 case PT_MemberPtr:
295 return "MemberPtr";
296 case PT_FixedPoint:
297 return "FixedPoint";
298 }
299 llvm_unreachable("Unhandled PrimType");
300}
301
302LLVM_DUMP_METHOD void Program::dump(llvm::raw_ostream &OS) const {
303 {
304 ColorScope SC(OS, true, {llvm::raw_ostream::BRIGHT_RED, true});
305 OS << "\n:: Program\n";
306 }
307
308 {
309 ColorScope SC(OS, true, {llvm::raw_ostream::WHITE, true});
310 OS << "Total memory : " << Allocator.getTotalMemory() << " bytes\n";
311 OS << "Global Variables: " << Globals.size() << "\n";
312 }
313 unsigned GI = 0;
314 for (const Global *G : Globals) {
315 const Descriptor *Desc = G->block()->getDescriptor();
316 Pointer GP = getPtrGlobal(GI);
317
318 OS << GI << ": " << (const void *)G->block() << " ";
319 {
320 ColorScope SC(OS, true,
321 GP.isInitialized()
322 ? TerminalColor{llvm::raw_ostream::GREEN, false}
323 : TerminalColor{llvm::raw_ostream::RED, false});
324 OS << (GP.isInitialized() ? "initialized " : "uninitialized ");
325 }
326 if (GP.block()->isDummy())
327 OS << "dummy ";
328 Desc->dump(OS);
329
330 if (GP.isInitialized() && Desc->IsTemporary) {
331 if (const auto *MTE =
332 dyn_cast_if_present<MaterializeTemporaryExpr>(Desc->asExpr());
333 MTE && MTE->getLifetimeExtendedTemporaryDecl()) {
334 if (const APValue *V =
335 MTE->getLifetimeExtendedTemporaryDecl()->getValue()) {
336 OS << " (global temporary value: ";
337 {
338 ColorScope SC(OS, true, {llvm::raw_ostream::BRIGHT_MAGENTA, true});
339 std::string VStr;
340 llvm::raw_string_ostream SS(VStr);
341 V->dump(SS, Ctx.getASTContext());
342
343 for (unsigned I = 0; I != VStr.size(); ++I) {
344 if (VStr[I] == '\n')
345 VStr[I] = ' ';
346 }
347 VStr.pop_back(); // Remove the newline (or now space) at the end.
348 OS << VStr;
349 }
350 OS << ')';
351 }
352 }
353 }
354
355 OS << "\n";
356 if (GP.isInitialized() && Desc->isPrimitive() && !G->block()->isDummy()) {
357 OS << " ";
358 {
359 ColorScope SC(OS, true, {llvm::raw_ostream::BRIGHT_CYAN, false});
360 OS << primTypeToString(Desc->getPrimType()) << " ";
361 }
362 TYPE_SWITCH(Desc->getPrimType(), { GP.deref<T>().print(OS); });
363 OS << "\n";
364 }
365 ++GI;
366 }
367
368 {
369 ColorScope SC(OS, true, {llvm::raw_ostream::WHITE, true});
370 OS << "Functions: " << Funcs.size() << "\n";
371 }
372 for (const auto &Func : Funcs) {
373 Func.second->dump();
374 }
375 for (const auto &Anon : AnonFuncs) {
376 Anon->dump();
377 }
378}
379
380LLVM_DUMP_METHOD void Descriptor::dump() const {
381 dump(llvm::errs());
382 llvm::errs() << '\n';
383}
384
385LLVM_DUMP_METHOD void Descriptor::dump(llvm::raw_ostream &OS) const {
386 // Source
387 {
388 ColorScope SC(OS, true, {llvm::raw_ostream::BLUE, true});
389 if (const auto *ND = dyn_cast_if_present<NamedDecl>(asDecl()))
390 ND->printQualifiedName(OS);
391 else if (asExpr())
392 OS << "Expr " << (const void *)asExpr();
393 }
394
395 // Print a few interesting bits about the descriptor.
396 if (isPrimitiveArray())
397 OS << " primitive-array";
398 else if (isCompositeArray())
399 OS << " composite-array";
400 else if (isUnion())
401 OS << " union";
402 else if (isRecord())
403 OS << " record";
404 else if (isPrimitive())
405 OS << " primitive " << primTypeToString(getPrimType());
406
407 if (isZeroSizeArray())
408 OS << " zero-size-array";
409 else if (isUnknownSizeArray())
410 OS << " unknown-size-array";
411
413 OS << " constexpr-unknown";
414}
415
416/// Dump descriptor, including all valid offsets.
417LLVM_DUMP_METHOD void Descriptor::dumpFull(unsigned Offset,
418 unsigned Indent) const {
419 unsigned Spaces = Indent * 2;
420 llvm::raw_ostream &OS = llvm::errs();
421 OS.indent(Spaces);
422 dump(OS);
423 OS << '\n';
424 OS.indent(Spaces) << "Metadata: " << getMetadataSize() << " bytes\n";
425 OS.indent(Spaces) << "Size: " << getSize() << " bytes\n";
426 OS.indent(Spaces) << "AllocSize: " << getAllocSize() << " bytes\n";
427 Offset += getMetadataSize();
428 if (isCompositeArray()) {
429 OS.indent(Spaces) << "Elements: " << getNumElems() << '\n';
430 unsigned FO = Offset;
431 for (unsigned I = 0; I != getNumElems(); ++I) {
432 FO += sizeof(InlineDescriptor);
433 assert(ElemDesc->getMetadataSize() == 0);
434 OS.indent(Spaces) << "Element " << I << " offset: " << FO << '\n';
435 ElemDesc->dumpFull(FO, Indent + 1);
436
437 FO += ElemDesc->getAllocSize();
438 }
439 } else if (isRecord()) {
440 ElemRecord->dump(OS, Indent + 1, Offset);
441 } else if (isPrimitive()) {
442 } else {
443 }
444
445 OS << '\n';
446}
447
448LLVM_DUMP_METHOD void InlineDescriptor::dump(llvm::raw_ostream &OS) const {
449 {
450 ColorScope SC(OS, true, {llvm::raw_ostream::BLUE, true});
451 OS << "InlineDescriptor " << (const void *)this << "\n";
452 }
453 OS << "Offset: " << Offset << "\n";
454 OS << "IsConst: " << IsConst << "\n";
455 OS << "IsInitialized: " << IsInitialized << "\n";
456 OS << "IsBase: " << IsBase << "\n";
457 OS << "IsActive: " << IsActive << "\n";
458 OS << "InUnion: " << InUnion << "\n";
459 OS << "IsFieldMutable: " << IsFieldMutable << "\n";
460 OS << "IsArrayElement: " << IsArrayElement << "\n";
461 OS << "IsConstInMutable: " << IsConstInMutable << '\n';
462 OS << "Desc: ";
463 if (Desc)
464 Desc->dump(OS);
465 else
466 OS << "nullptr";
467 OS << "\n";
468}
469
470LLVM_DUMP_METHOD void InterpFrame::dump(llvm::raw_ostream &OS,
471 unsigned Indent) const {
472 unsigned Spaces = Indent * 2;
473 {
474 ColorScope SC(OS, true, {llvm::raw_ostream::BLUE, true});
475 OS.indent(Spaces);
476 if (getCallee())
477 describe(OS);
478 else
479 OS << "Frame (Depth: " << getDepth() << ")";
480 OS << "\n";
481 }
482 OS.indent(Spaces) << "Function: " << getFunction();
483 if (const Function *F = getFunction()) {
484 OS << " (" << F->getName() << ")";
485 }
486 OS << "\n";
487 OS.indent(Spaces) << "This: " << getThis() << "\n";
488 OS.indent(Spaces) << "RVO: " << getRVOPtr() << "\n";
489 OS.indent(Spaces) << "Depth: " << Depth << "\n";
490 OS.indent(Spaces) << "ArgSize: " << ArgSize << "\n";
491 OS.indent(Spaces) << "Args: " << (void *)Args << "\n";
492 OS.indent(Spaces) << "FrameOffset: " << FrameOffset << "\n";
493 OS.indent(Spaces) << "FrameSize: " << (Func ? Func->getFrameSize() : 0)
494 << "\n";
495
496 for (const InterpFrame *F = this->Caller; F; F = F->Caller) {
497 F->dump(OS, Indent + 1);
498 }
499}
500
501LLVM_DUMP_METHOD void Record::dump(llvm::raw_ostream &OS, unsigned Indentation,
502 unsigned Offset) const {
503 unsigned Indent = Indentation * 2;
504 OS.indent(Indent);
505 {
506 ColorScope SC(OS, true, {llvm::raw_ostream::BLUE, true});
507 OS << getName() << "\n";
508 }
509
510 unsigned I = 0;
511 for (const Record::Base &B : bases()) {
512 OS.indent(Indent) << "- Base " << I << ". Offset " << (Offset + B.Offset)
513 << "\n";
514 B.R->dump(OS, Indentation + 1, Offset + B.Offset);
515 ++I;
516 }
517
518 I = 0;
519 for (const Record::Field &F : fields()) {
520 OS.indent(Indent) << "- Field " << I << ": ";
521 {
522 ColorScope SC(OS, true, {llvm::raw_ostream::BRIGHT_RED, true});
523 OS << F.Decl->getName();
524 }
525 OS << ". Offset " << (Offset + F.Offset) << "\n";
526 ++I;
527 }
528
529 I = 0;
530 for (const Record::Base &B : virtual_bases()) {
531 OS.indent(Indent) << "- Virtual Base " << I << ". Offset "
532 << (Offset + B.Offset) << "\n";
533 B.R->dump(OS, Indentation + 1, Offset + B.Offset);
534 ++I;
535 }
536}
537
538LLVM_DUMP_METHOD void Block::dump(llvm::raw_ostream &OS) const {
539 {
540 ColorScope SC(OS, true, {llvm::raw_ostream::BRIGHT_BLUE, true});
541 OS << "Block " << (const void *)this;
542 }
543 OS << " (";
544 Desc->dump(OS);
545 OS << ")\n";
546 unsigned NPointers = 0;
547 for (const Pointer *P = Pointers; P; P = P->asBlockPointer().Next) {
548 ++NPointers;
549 }
550 OS << " EvalID: " << EvalID << '\n';
551 OS << " DeclID: ";
552 if (DeclID)
553 OS << *DeclID << '\n';
554 else
555 OS << "-\n";
556 OS << " Pointers: " << NPointers << "\n";
557 OS << " Dead: " << isDead() << "\n";
558 OS << " Static: " << IsStatic << "\n";
559 OS << " Extern: " << isExtern() << "\n";
560 OS << " Initialized: " << IsInitialized << "\n";
561 OS << " Weak: " << isWeak() << "\n";
562 OS << " Dummy: " << isDummy() << '\n';
563 OS << " Dynamic: " << isDynamic() << "\n";
564}
565
566LLVM_DUMP_METHOD void EvaluationResult::dump() const {
567 auto &OS = llvm::errs();
568
569 if (empty()) {
570 OS << "Empty\n";
571 } else if (isInvalid()) {
572 OS << "Invalid\n";
573 } else {
574 OS << "Value: ";
575#ifndef NDEBUG
576 assert(Ctx);
577 Value.dump(OS, Ctx->getASTContext());
578#endif
579 }
580}
#define V(N, I)
static void dump(llvm::raw_ostream &OS, StringRef FunctionName, ArrayRef< CounterExpression > Expressions, ArrayRef< CounterMappingRegion > Regions)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
std::string printArg< Floating >(Program &P, CodePtr &OpPC)
Definition Disasm.cpp:65
static const char * primTypeToString(PrimType T)
Definition Disasm.cpp:266
static size_t getNumDisplayWidth(size_t N)
Definition Disasm.cpp:133
static bool isJumpOpcode(Opcode Op)
Definition Disasm.cpp:129
std::string printArg< FixedPoint >(Program &P, CodePtr &OpPC)
Definition Disasm.cpp:119
static std::string printArg(Program &P, CodePtr &OpPC)
Definition Disasm.cpp:36
Defines the clang::Expr interface and subclasses for C++ expressions.
FormatToken * Next
The next token in the unwrapped line.
#define TYPE_SWITCH(Expr, B)
Definition PrimType.h:207
static bool isInvalid(LocType Loc, bool *Invalid)
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Definition APValue.h:122
bool isExtern() const
Checks if the block is extern.
Definition InterpBlock.h:77
friend class Pointer
bool isDead() const
Definition InterpBlock.h:85
bool isDynamic() const
Definition InterpBlock.h:83
bool isDummy() const
Definition InterpBlock.h:84
bool isWeak() const
Definition InterpBlock.h:82
Pointer into the code segment.
Definition Source.h:30
std::enable_if_t<!std::is_pointer< T >::value, T > read()
Reads data and advances the pointer.
Definition Source.h:56
void dump() const
Dump to stderr.
Definition Disasm.cpp:566
static FixedPoint deserialize(const std::byte *Buff)
Definition FixedPoint.h:108
If a Floating is constructed from Memory, it DOES NOT OWN THAT MEMORY.
Definition Floating.h:35
static llvm::APFloatBase::Semantics deserializeSemantics(const std::byte *Buff)
Definition Floating.h:211
static void deserialize(const std::byte *Buff, Floating *Result)
Definition Floating.h:215
Bytecode function.
Definition Function.h:86
CodePtr getCodeBegin() const
Returns a pointer to the start of the code.
Definition Function.h:104
CodePtr getCodeEnd() const
Returns a pointer to the end of the code.
Definition Function.h:106
std::string getName() const
Returns the name of the function decl this code was generated for.
Definition Function.h:118
unsigned getFrameSize() const
Returns the size of the function's local stack.
Definition Function.h:99
bool hasThisPointer() const
Definition Function.h:193
void dump() const
Dumps the disassembled bytecode to llvm::errs().
Definition Disasm.cpp:141
unsigned getArgSize() const
Returns the size of the argument stack.
Definition Function.h:101
bool hasRVO() const
Checks if the first argument is a RVO pointer.
Definition Function.h:129
If an IntegralAP is constructed from Memory, it DOES NOT OWN THAT MEMORY.
Definition IntegralAP.h:36
InterpFrame(InterpState &S)
Bottom Frame.
InterpFrame * Caller
The frame of the previous function.
Definition InterpFrame.h:29
const Pointer & getThis() const
Returns the 'this' pointer.
const Function * getFunction() const
Returns the current function.
Definition InterpFrame.h:71
unsigned getDepth() const
const Pointer & getRVOPtr() const
Returns the RVO pointer, if the Function has one.
void describe(llvm::raw_ostream &OS) const override
Describes the frame with arguments for diagnostic purposes.
A pointer to a memory block, live or dead.
Definition Pointer.h:91
bool isInitialized() const
Checks if an object was initialized.
Definition Pointer.cpp:432
const Block * block() const
Definition Pointer.h:599
The program contains and links the bytecode for all functions.
Definition Program.h:36
const void * getNativePointer(unsigned Idx)
Returns the value of a marshalled native pointer.
Definition Program.cpp:30
Pointer getPtrGlobal(unsigned Idx) const
Returns a pointer to a global.
Definition Program.cpp:109
void dump() const
Dumps the disassembled bytecode to llvm::errs().
Definition Disasm.cpp:264
std::string getName() const
Returns the name of the underlying declaration.
Definition Record.cpp:32
llvm::iterator_range< const_virtual_iter > virtual_bases() const
Definition Record.h:103
llvm::iterator_range< const_base_iter > bases() const
Definition Record.h:92
llvm::iterator_range< const_field_iter > fields() const
Definition Record.h:84
static const FunctionDecl * getCallee(const CXXConstructExpr &D)
constexpr size_t align(size_t Size)
Aligns a size to the pointer alignment.
Definition PrimType.h:185
PrimType
Enumeration of the primitive types of the VM.
Definition PrimType.h:34
The JSON file list parser is used to communicate input to InstallAPI.
raw_ostream & Indent(raw_ostream &Out, const unsigned int Space, bool IsDot)
Definition JsonSupport.h:21
@ Result
The result type of a method or function.
Definition TypeBase.h:905
const FunctionProtoType * T
Describes a memory block created by an allocation site.
Definition Descriptor.h:122
unsigned getAllocSize() const
Returns the allocated size, including metadata.
Definition Descriptor.h:242
unsigned getNumElems() const
Returns the number of elements stored in the block.
Definition Descriptor.h:249
unsigned getSize() const
Returns the size of the object without metadata.
Definition Descriptor.h:231
void dumpFull(unsigned Offset=0, unsigned Indent=0) const
Dump descriptor, including all valid offsets.
Definition Disasm.cpp:417
bool isPrimitive() const
Checks if the descriptor is of a primitive.
Definition Descriptor.h:263
bool isCompositeArray() const
Checks if the descriptor is of an array of composites.
Definition Descriptor.h:256
const Decl * asDecl() const
Definition Descriptor.h:210
const Descriptor *const ElemDesc
Descriptor of the array element.
Definition Descriptor.h:155
unsigned getMetadataSize() const
Returns the size of the metadata.
Definition Descriptor.h:246
bool isUnknownSizeArray() const
Checks if the descriptor is of an array of unknown size.
Definition Descriptor.h:260
bool isPrimitiveArray() const
Checks if the descriptor is of an array of primitives.
Definition Descriptor.h:254
bool isZeroSizeArray() const
Checks if the descriptor is of an array of zero size.
Definition Descriptor.h:258
PrimType getPrimType() const
Definition Descriptor.h:236
bool isRecord() const
Checks if the descriptor is of a record.
Definition Descriptor.h:268
const bool IsTemporary
Flag indicating if the block is a temporary.
Definition Descriptor.h:165
const Record *const ElemRecord
Pointer to the record, if block contains records.
Definition Descriptor.h:153
bool isUnion() const
Checks if the descriptor is of a union.
const Expr * asExpr() const
Definition Descriptor.h:211
Inline descriptor embedded in structures and arrays.
Definition Descriptor.h:67
unsigned IsActive
Flag indicating if the field is the active member of a union.
Definition Descriptor.h:89
unsigned IsConstInMutable
Flag indicating if this field is a const field nested in a mutable parent field.
Definition Descriptor.h:99
unsigned IsBase
Flag indicating if the field is an embedded base class.
Definition Descriptor.h:83
unsigned InUnion
Flag indicating if this field is in a union (even if nested).
Definition Descriptor.h:92
unsigned Offset
Offset inside the structure/array.
Definition Descriptor.h:69
unsigned IsInitialized
For primitive fields, it indicates if the field was initialized.
Definition Descriptor.h:80
unsigned IsConst
Flag indicating if the storage is constant or not.
Definition Descriptor.h:74
unsigned IsArrayElement
Flag indicating if the field is an element of a composite array.
Definition Descriptor.h:102
unsigned IsFieldMutable
Flag indicating if the field is mutable (if in a record).
Definition Descriptor.h:95