clang: lib/AST/ByteCode/InterpFrame.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

22

23using namespace clang;

25

28 : Caller(Caller), S(S), Depth(Caller ? Caller->Depth + 1 : 0), Func(Func),

29 RetPC(RetPC), ArgSize(ArgSize), Args(static_cast<char *>(S.Stk.top())),

30 FrameOffset(S.Stk.size()) {

32 return;

33

34 unsigned FrameSize = Func->getFrameSize();

35 if (FrameSize == 0)

36 return;

37

38 Locals = std::make_unique<char[]>(FrameSize);

39 for (auto &Scope : Func->scopes()) {

41 new (localBlock(Local.Offset)) Block(S.Ctx.getEvalID(), Local.Desc);

42

43

44 new (localInlineDesc(Local.Offset)) InlineDescriptor(Local.Desc);

45 }

46 }

47}

48

50 unsigned VarArgSize)

51 : InterpFrame(S, Func, S.Current, RetPC, Func->getArgSize() + VarArgSize) {

52

53

54

55

56

57

58 if (Func->hasRVO())

59 RVOPtr = stackRef(0);

60

61 if (Func->hasThisPointer()) {

62 if (Func->hasRVO())

63 This = stackRef(sizeof(Pointer));

64 else

65 This = stackRef(0);

66 }

67}

68

70 for (auto &Param : Params)

71 S.deallocate(reinterpret_cast<Block *>(Param.second.get()));

72

73

74

75

76 if (Func) {

79 S.deallocate(localBlock(Local.Offset));

80 }

81 }

82 }

83}

84

86 if (!Func)

87 return;

89 localBlock(Local.Offset)->invokeCtor();

90 }

91}

92

95 S.deallocate(localBlock(Local.Offset));

96 }

97}

98

99template

102 V.toAPValue(ASTCtx).printPretty(OS, ASTCtx, Ty);

103}

104

107 return true;

109 return true;

110

114 return true;

115 return false;

116}

117

119

120

121

122

123

125 return;

126

129 bool IsMemberCall = isa(F) && !isa(F) &&

130 cast(F)->isImplicitObjectMemberFunction();

132 if (const auto *MCE = dyn_cast_if_present(CallExpr)) {

133 const Expr *Object = MCE->getImplicitObjectArgument();

134 Object->printPretty(OS, nullptr,

136 0);

137 if (Object->getType()->isPointerType())

138 OS << "->";

139 else

140 OS << ".";

141 } else if (const auto *OCE =

142 dyn_cast_if_present(CallExpr)) {

143 OCE->getArg(0)->printPretty(OS, nullptr,

145 0);

146 OS << ".";

147 } else if (const auto *M = dyn_cast(F)) {

151 OS << ".";

152 }

153 }

154

156 false);

157 OS << '(';

158 unsigned Off = 0;

159

162

163 for (unsigned I = 0, N = F->getNumParams(); I < N; ++I) {

165

167

170 if (I + 1 != N)

171 OS << ", ";

172 }

173 OS << ")";

174}

175

180}

181

185 return NullRange;

187 }

189}

190

192 if (!Func)

193 return nullptr;

195}

196

198 assert(Offset < Func->getFrameSize() && "Invalid local offset.");

199 return Pointer(localBlock(Offset));

200}

201

203

204 if (auto Pt = Params.find(Off); Pt != Params.end())

205 return Pointer(reinterpret_cast<Block *>(Pt->second.get()));

206

207

209 size_t BlockSize = sizeof(Block) + Desc.second->getAllocSize();

210 auto Memory = std::make_unique<char[]>(BlockSize);

211 auto *B = new (Memory.get()) Block(S.Ctx.getEvalID(), Desc.second);

213

214

215 TYPE_SWITCH(Desc.first, new (B->data()) T(stackRef(Off)));

216

217

218 Params.insert({Off, std::move(Memory)});

220}

221

223 assert(F);

224

226 return true;

227

229}

230

232

233

236

237

238

243}

244

248

249 return S.getExpr(Func, PC);

250}

251

255

257}

258

262

264}

265

267 if (!Func)

268 return false;

270 if (DC->isStdNamespace())

271 return true;

272

273 return false;

274}

Defines the clang::ASTContext interface.

Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....

Defines the clang::Expr interface and subclasses for C++ expressions.

static void print(llvm::raw_ostream &OS, const T &V, ASTContext &ASTCtx, QualType Ty)

static bool shouldSkipInBacktrace(const Function *F)

static bool funcHasUsableBody(const Function *F)

#define TYPE_SWITCH(Expr, B)

Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...

QualType getRecordType(const RecordDecl *Decl) const

QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const

Return the uniqued reference to the type for an lvalue reference to the specified type.

const clang::PrintingPolicy & getPrintingPolicy() const

CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).

DeclContext - This is used only as base class of specific decl types that can act as declaration cont...

DeclContext * getParent()

getParent - Returns the containing DeclContext.

bool isImplicit() const

isImplicit - Indicates whether the declaration was implicitly generated by the implementation.

OverloadedOperatorKind getCXXOverloadedOperator() const

If this name is the name of an overloadable operator in C++ (e.g., operator+), retrieve the kind of o...

This represents one expression.

Represents a function declaration or definition.

const ParmVarDecl * getParamDecl(unsigned i) const

unsigned getNumParams() const

Return the number of parameters this function must have based on its FunctionType.

void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override

Appends a human-readable name for this declaration into the given stream.

DeclarationName getDeclName() const

Get the actual, stored name of the declaration, which may be a special name.

A (possibly-)qualified type.

Encodes a location in the source.

A trivial tuple used to represent a source range.

A memory block, either on the stack or in the heap.

void invokeCtor()

Invokes the constructor.

Pointer into the code segment.

std::optional< PrimType > classify(QualType T) const

Classifies a type.

unsigned getEvalID() const

Base class for stack frames, shared between VM and walker.

Scope & getScope(unsigned Idx)

Returns a specific scope.

bool isDestructor() const

Checks if the function is a destructor.

bool isConstructor() const

Checks if the function is a constructor.

const FunctionDecl * getDecl() const

Returns the original FunctionDecl.

bool hasThisPointer() const

bool isLambdaStaticInvoker() const

Returns whether this function is a lambda static invoker, which we generate custom byte code for.

ParamDescriptor getParamDescriptor(unsigned Offset) const

Returns a parameter descriptor.

llvm::iterator_range< llvm::SmallVector< Scope, 2 >::const_iterator > scopes() const

Range over the scope blocks.

bool hasRVO() const

Checks if the first argument is a RVO pointer.

Frame storing local variables.

const Expr * getExpr(CodePtr PC) const

InterpFrame * Caller

The frame of the previous function.

virtual SourceInfo getSource(CodePtr PC) const

Map a location to a source.

CodePtr getRetPC() const

Returns the return address of the frame.

SourceLocation getLocation(CodePtr PC) const

~InterpFrame()

Destroys the frame, killing all live pointers to stack slots.

const Function * getFunction() const

Returns the current function.

SourceRange getRange(CodePtr PC) const

Pointer getLocalPointer(unsigned Offset) const

Returns a pointer to a local variables.

Frame * getCaller() const override

Returns the parent frame object.

InterpFrame(InterpState &S, const Function *Func, InterpFrame *Caller, CodePtr RetPC, unsigned ArgSize)

Creates a new frame for a method call.

void destroy(unsigned Idx)

Invokes the destructors for a scope.

Pointer getParamPointer(unsigned Offset)

Returns a pointer to an argument - lazily creates a block.

const FunctionDecl * getCallee() const override

Returns the caller.

bool isStdFunction() const

void initScope(unsigned Idx)

SourceRange getCallRange() const override

Returns the location of the call to the frame.

void describe(llvm::raw_ostream &OS) const override

Describes the frame with arguments for diagnostic purposes.

Context & Ctx

Interpreter Context.

ASTContext & getASTContext() const override

SourceInfo getSource(const Function *F, CodePtr PC) const override

Delegates source mapping to the mapper.

SourceLocation EvalLocation

Source location of the evaluating expression.

void deallocate(Block *B)

Deallocates a pointer.

A pointer to a memory block, live or dead.

llvm::iterator_range< LocalVectorTy::const_iterator > locals() const

Describes the statement/declaration an opcode was generated from.

SourceLocation getLocation(const Function *F, CodePtr PC) const

Returns the location from which an opcode originates.

SourceRange getRange(const Function *F, CodePtr PC) const

const Expr * getExpr(const Function *F, CodePtr PC) const

Returns the expression if an opcode belongs to one, null otherwise.

constexpr size_t align(size_t Size)

Aligns a size to the pointer alignment.

PrimType

Enumeration of the primitive types of the VM.

size_t primSize(PrimType Type)

Returns the size of a primitive type in bytes.

The JSON file list parser is used to communicate input to InstallAPI.

@ Result

The result type of a method or function.

const FunctionProtoType * T

__UINTPTR_TYPE__ uintptr_t

An unsigned integer type with the property that any valid pointer to void can be converted to this ty...

Inline descriptor embedded in structures and arrays.