xref: /freebsd/contrib/llvm-project/clang/lib/AST/ByteCode/Context.cpp (revision 700637cbb5e582861067a11aaca4d053546871d2)
1*700637cbSDimitry Andric //===--- Context.cpp - Context for the constexpr VM -------------*- C++ -*-===//
2*700637cbSDimitry Andric //
3*700637cbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*700637cbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*700637cbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*700637cbSDimitry Andric //
7*700637cbSDimitry Andric //===----------------------------------------------------------------------===//
8*700637cbSDimitry Andric 
9*700637cbSDimitry Andric #include "Context.h"
10*700637cbSDimitry Andric #include "ByteCodeEmitter.h"
11*700637cbSDimitry Andric #include "Compiler.h"
12*700637cbSDimitry Andric #include "EvalEmitter.h"
13*700637cbSDimitry Andric #include "Interp.h"
14*700637cbSDimitry Andric #include "InterpFrame.h"
15*700637cbSDimitry Andric #include "InterpStack.h"
16*700637cbSDimitry Andric #include "PrimType.h"
17*700637cbSDimitry Andric #include "Program.h"
18*700637cbSDimitry Andric #include "clang/AST/Expr.h"
19*700637cbSDimitry Andric #include "clang/Basic/TargetInfo.h"
20*700637cbSDimitry Andric 
21*700637cbSDimitry Andric using namespace clang;
22*700637cbSDimitry Andric using namespace clang::interp;
23*700637cbSDimitry Andric 
Context(ASTContext & Ctx)24*700637cbSDimitry Andric Context::Context(ASTContext &Ctx) : Ctx(Ctx), P(new Program(*this)) {
25*700637cbSDimitry Andric   this->ShortWidth = Ctx.getTargetInfo().getShortWidth();
26*700637cbSDimitry Andric   this->IntWidth = Ctx.getTargetInfo().getIntWidth();
27*700637cbSDimitry Andric   this->LongWidth = Ctx.getTargetInfo().getLongWidth();
28*700637cbSDimitry Andric   this->LongLongWidth = Ctx.getTargetInfo().getLongLongWidth();
29*700637cbSDimitry Andric   assert(Ctx.getTargetInfo().getCharWidth() == 8 &&
30*700637cbSDimitry Andric          "We're assuming 8 bit chars");
31*700637cbSDimitry Andric }
32*700637cbSDimitry Andric 
~Context()33*700637cbSDimitry Andric Context::~Context() {}
34*700637cbSDimitry Andric 
isPotentialConstantExpr(State & Parent,const FunctionDecl * FD)35*700637cbSDimitry Andric bool Context::isPotentialConstantExpr(State &Parent, const FunctionDecl *FD) {
36*700637cbSDimitry Andric   assert(Stk.empty());
37*700637cbSDimitry Andric 
38*700637cbSDimitry Andric   // Get a function handle.
39*700637cbSDimitry Andric   const Function *Func = getOrCreateFunction(FD);
40*700637cbSDimitry Andric   if (!Func)
41*700637cbSDimitry Andric     return false;
42*700637cbSDimitry Andric 
43*700637cbSDimitry Andric   // Compile the function.
44*700637cbSDimitry Andric   Compiler<ByteCodeEmitter>(*this, *P).compileFunc(
45*700637cbSDimitry Andric       FD, const_cast<Function *>(Func));
46*700637cbSDimitry Andric 
47*700637cbSDimitry Andric   ++EvalID;
48*700637cbSDimitry Andric   // And run it.
49*700637cbSDimitry Andric   if (!Run(Parent, Func))
50*700637cbSDimitry Andric     return false;
51*700637cbSDimitry Andric 
52*700637cbSDimitry Andric   return Func->isValid();
53*700637cbSDimitry Andric }
54*700637cbSDimitry Andric 
evaluateAsRValue(State & Parent,const Expr * E,APValue & Result)55*700637cbSDimitry Andric bool Context::evaluateAsRValue(State &Parent, const Expr *E, APValue &Result) {
56*700637cbSDimitry Andric   ++EvalID;
57*700637cbSDimitry Andric   bool Recursing = !Stk.empty();
58*700637cbSDimitry Andric   size_t StackSizeBefore = Stk.size();
59*700637cbSDimitry Andric   Compiler<EvalEmitter> C(*this, *P, Parent, Stk);
60*700637cbSDimitry Andric 
61*700637cbSDimitry Andric   auto Res = C.interpretExpr(E, /*ConvertResultToRValue=*/E->isGLValue());
62*700637cbSDimitry Andric 
63*700637cbSDimitry Andric   if (Res.isInvalid()) {
64*700637cbSDimitry Andric     C.cleanup();
65*700637cbSDimitry Andric     Stk.clearTo(StackSizeBefore);
66*700637cbSDimitry Andric     return false;
67*700637cbSDimitry Andric   }
68*700637cbSDimitry Andric 
69*700637cbSDimitry Andric   if (!Recursing) {
70*700637cbSDimitry Andric     // We *can* actually get here with a non-empty stack, since
71*700637cbSDimitry Andric     // things like InterpState::noteSideEffect() exist.
72*700637cbSDimitry Andric     C.cleanup();
73*700637cbSDimitry Andric #ifndef NDEBUG
74*700637cbSDimitry Andric     // Make sure we don't rely on some value being still alive in
75*700637cbSDimitry Andric     // InterpStack memory.
76*700637cbSDimitry Andric     Stk.clearTo(StackSizeBefore);
77*700637cbSDimitry Andric #endif
78*700637cbSDimitry Andric   }
79*700637cbSDimitry Andric 
80*700637cbSDimitry Andric   Result = Res.toAPValue();
81*700637cbSDimitry Andric 
82*700637cbSDimitry Andric   return true;
83*700637cbSDimitry Andric }
84*700637cbSDimitry Andric 
evaluate(State & Parent,const Expr * E,APValue & Result,ConstantExprKind Kind)85*700637cbSDimitry Andric bool Context::evaluate(State &Parent, const Expr *E, APValue &Result,
86*700637cbSDimitry Andric                        ConstantExprKind Kind) {
87*700637cbSDimitry Andric   ++EvalID;
88*700637cbSDimitry Andric   bool Recursing = !Stk.empty();
89*700637cbSDimitry Andric   size_t StackSizeBefore = Stk.size();
90*700637cbSDimitry Andric   Compiler<EvalEmitter> C(*this, *P, Parent, Stk);
91*700637cbSDimitry Andric 
92*700637cbSDimitry Andric   auto Res = C.interpretExpr(E, /*ConvertResultToRValue=*/false,
93*700637cbSDimitry Andric                              /*DestroyToplevelScope=*/true);
94*700637cbSDimitry Andric   if (Res.isInvalid()) {
95*700637cbSDimitry Andric     C.cleanup();
96*700637cbSDimitry Andric     Stk.clearTo(StackSizeBefore);
97*700637cbSDimitry Andric     return false;
98*700637cbSDimitry Andric   }
99*700637cbSDimitry Andric 
100*700637cbSDimitry Andric   if (!Recursing) {
101*700637cbSDimitry Andric     assert(Stk.empty());
102*700637cbSDimitry Andric     C.cleanup();
103*700637cbSDimitry Andric #ifndef NDEBUG
104*700637cbSDimitry Andric     // Make sure we don't rely on some value being still alive in
105*700637cbSDimitry Andric     // InterpStack memory.
106*700637cbSDimitry Andric     Stk.clearTo(StackSizeBefore);
107*700637cbSDimitry Andric #endif
108*700637cbSDimitry Andric   }
109*700637cbSDimitry Andric 
110*700637cbSDimitry Andric   Result = Res.toAPValue();
111*700637cbSDimitry Andric   return true;
112*700637cbSDimitry Andric }
113*700637cbSDimitry Andric 
evaluateAsInitializer(State & Parent,const VarDecl * VD,APValue & Result)114*700637cbSDimitry Andric bool Context::evaluateAsInitializer(State &Parent, const VarDecl *VD,
115*700637cbSDimitry Andric                                     APValue &Result) {
116*700637cbSDimitry Andric   ++EvalID;
117*700637cbSDimitry Andric   bool Recursing = !Stk.empty();
118*700637cbSDimitry Andric   size_t StackSizeBefore = Stk.size();
119*700637cbSDimitry Andric   Compiler<EvalEmitter> C(*this, *P, Parent, Stk);
120*700637cbSDimitry Andric 
121*700637cbSDimitry Andric   bool CheckGlobalInitialized =
122*700637cbSDimitry Andric       shouldBeGloballyIndexed(VD) &&
123*700637cbSDimitry Andric       (VD->getType()->isRecordType() || VD->getType()->isArrayType());
124*700637cbSDimitry Andric   auto Res = C.interpretDecl(VD, CheckGlobalInitialized);
125*700637cbSDimitry Andric   if (Res.isInvalid()) {
126*700637cbSDimitry Andric     C.cleanup();
127*700637cbSDimitry Andric     Stk.clearTo(StackSizeBefore);
128*700637cbSDimitry Andric 
129*700637cbSDimitry Andric     return false;
130*700637cbSDimitry Andric   }
131*700637cbSDimitry Andric 
132*700637cbSDimitry Andric   if (!Recursing) {
133*700637cbSDimitry Andric     assert(Stk.empty());
134*700637cbSDimitry Andric     C.cleanup();
135*700637cbSDimitry Andric #ifndef NDEBUG
136*700637cbSDimitry Andric     // Make sure we don't rely on some value being still alive in
137*700637cbSDimitry Andric     // InterpStack memory.
138*700637cbSDimitry Andric     Stk.clearTo(StackSizeBefore);
139*700637cbSDimitry Andric #endif
140*700637cbSDimitry Andric   }
141*700637cbSDimitry Andric 
142*700637cbSDimitry Andric   Result = Res.toAPValue();
143*700637cbSDimitry Andric   return true;
144*700637cbSDimitry Andric }
145*700637cbSDimitry Andric 
146*700637cbSDimitry Andric template <typename ResultT>
evaluateStringRepr(State & Parent,const Expr * SizeExpr,const Expr * PtrExpr,ResultT & Result)147*700637cbSDimitry Andric bool Context::evaluateStringRepr(State &Parent, const Expr *SizeExpr,
148*700637cbSDimitry Andric                                  const Expr *PtrExpr, ResultT &Result) {
149*700637cbSDimitry Andric   assert(Stk.empty());
150*700637cbSDimitry Andric   Compiler<EvalEmitter> C(*this, *P, Parent, Stk);
151*700637cbSDimitry Andric 
152*700637cbSDimitry Andric   // Evaluate size value.
153*700637cbSDimitry Andric   APValue SizeValue;
154*700637cbSDimitry Andric   if (!evaluateAsRValue(Parent, SizeExpr, SizeValue))
155*700637cbSDimitry Andric     return false;
156*700637cbSDimitry Andric 
157*700637cbSDimitry Andric   if (!SizeValue.isInt())
158*700637cbSDimitry Andric     return false;
159*700637cbSDimitry Andric   uint64_t Size = SizeValue.getInt().getZExtValue();
160*700637cbSDimitry Andric 
161*700637cbSDimitry Andric   auto PtrRes = C.interpretAsPointer(PtrExpr, [&](const Pointer &Ptr) {
162*700637cbSDimitry Andric     if (Size == 0) {
163*700637cbSDimitry Andric       if constexpr (std::is_same_v<ResultT, APValue>)
164*700637cbSDimitry Andric         Result = APValue(APValue::UninitArray{}, 0, 0);
165*700637cbSDimitry Andric       return true;
166*700637cbSDimitry Andric     }
167*700637cbSDimitry Andric 
168*700637cbSDimitry Andric     if (!Ptr.isLive() || !Ptr.getFieldDesc()->isPrimitiveArray())
169*700637cbSDimitry Andric       return false;
170*700637cbSDimitry Andric 
171*700637cbSDimitry Andric     // Must be char.
172*700637cbSDimitry Andric     if (Ptr.getFieldDesc()->getElemSize() != 1 /*bytes*/)
173*700637cbSDimitry Andric       return false;
174*700637cbSDimitry Andric 
175*700637cbSDimitry Andric     if (Size > Ptr.getNumElems()) {
176*700637cbSDimitry Andric       Parent.FFDiag(SizeExpr, diag::note_constexpr_access_past_end) << AK_Read;
177*700637cbSDimitry Andric       Size = Ptr.getNumElems();
178*700637cbSDimitry Andric     }
179*700637cbSDimitry Andric 
180*700637cbSDimitry Andric     if constexpr (std::is_same_v<ResultT, APValue>) {
181*700637cbSDimitry Andric       QualType CharTy = PtrExpr->getType()->getPointeeType();
182*700637cbSDimitry Andric       Result = APValue(APValue::UninitArray{}, Size, Size);
183*700637cbSDimitry Andric       for (uint64_t I = 0; I != Size; ++I) {
184*700637cbSDimitry Andric         if (std::optional<APValue> ElemVal =
185*700637cbSDimitry Andric                 Ptr.atIndex(I).toRValue(*this, CharTy))
186*700637cbSDimitry Andric           Result.getArrayInitializedElt(I) = *ElemVal;
187*700637cbSDimitry Andric         else
188*700637cbSDimitry Andric           return false;
189*700637cbSDimitry Andric       }
190*700637cbSDimitry Andric     } else {
191*700637cbSDimitry Andric       assert((std::is_same_v<ResultT, std::string>));
192*700637cbSDimitry Andric       if (Size < Result.max_size())
193*700637cbSDimitry Andric         Result.resize(Size);
194*700637cbSDimitry Andric       Result.assign(reinterpret_cast<const char *>(Ptr.getRawAddress()), Size);
195*700637cbSDimitry Andric     }
196*700637cbSDimitry Andric 
197*700637cbSDimitry Andric     return true;
198*700637cbSDimitry Andric   });
199*700637cbSDimitry Andric 
200*700637cbSDimitry Andric   if (PtrRes.isInvalid()) {
201*700637cbSDimitry Andric     C.cleanup();
202*700637cbSDimitry Andric     Stk.clear();
203*700637cbSDimitry Andric     return false;
204*700637cbSDimitry Andric   }
205*700637cbSDimitry Andric 
206*700637cbSDimitry Andric   return true;
207*700637cbSDimitry Andric }
208*700637cbSDimitry Andric 
evaluateCharRange(State & Parent,const Expr * SizeExpr,const Expr * PtrExpr,APValue & Result)209*700637cbSDimitry Andric bool Context::evaluateCharRange(State &Parent, const Expr *SizeExpr,
210*700637cbSDimitry Andric                                 const Expr *PtrExpr, APValue &Result) {
211*700637cbSDimitry Andric   assert(SizeExpr);
212*700637cbSDimitry Andric   assert(PtrExpr);
213*700637cbSDimitry Andric 
214*700637cbSDimitry Andric   return evaluateStringRepr(Parent, SizeExpr, PtrExpr, Result);
215*700637cbSDimitry Andric }
216*700637cbSDimitry Andric 
evaluateCharRange(State & Parent,const Expr * SizeExpr,const Expr * PtrExpr,std::string & Result)217*700637cbSDimitry Andric bool Context::evaluateCharRange(State &Parent, const Expr *SizeExpr,
218*700637cbSDimitry Andric                                 const Expr *PtrExpr, std::string &Result) {
219*700637cbSDimitry Andric   assert(SizeExpr);
220*700637cbSDimitry Andric   assert(PtrExpr);
221*700637cbSDimitry Andric 
222*700637cbSDimitry Andric   return evaluateStringRepr(Parent, SizeExpr, PtrExpr, Result);
223*700637cbSDimitry Andric }
224*700637cbSDimitry Andric 
getLangOpts() const225*700637cbSDimitry Andric const LangOptions &Context::getLangOpts() const { return Ctx.getLangOpts(); }
226*700637cbSDimitry Andric 
integralTypeToPrimTypeS(unsigned BitWidth)227*700637cbSDimitry Andric static PrimType integralTypeToPrimTypeS(unsigned BitWidth) {
228*700637cbSDimitry Andric   switch (BitWidth) {
229*700637cbSDimitry Andric   case 64:
230*700637cbSDimitry Andric     return PT_Sint64;
231*700637cbSDimitry Andric   case 32:
232*700637cbSDimitry Andric     return PT_Sint32;
233*700637cbSDimitry Andric   case 16:
234*700637cbSDimitry Andric     return PT_Sint16;
235*700637cbSDimitry Andric   case 8:
236*700637cbSDimitry Andric     return PT_Sint8;
237*700637cbSDimitry Andric   default:
238*700637cbSDimitry Andric     return PT_IntAPS;
239*700637cbSDimitry Andric   }
240*700637cbSDimitry Andric   llvm_unreachable("Unhandled BitWidth");
241*700637cbSDimitry Andric }
242*700637cbSDimitry Andric 
integralTypeToPrimTypeU(unsigned BitWidth)243*700637cbSDimitry Andric static PrimType integralTypeToPrimTypeU(unsigned BitWidth) {
244*700637cbSDimitry Andric   switch (BitWidth) {
245*700637cbSDimitry Andric   case 64:
246*700637cbSDimitry Andric     return PT_Uint64;
247*700637cbSDimitry Andric   case 32:
248*700637cbSDimitry Andric     return PT_Uint32;
249*700637cbSDimitry Andric   case 16:
250*700637cbSDimitry Andric     return PT_Uint16;
251*700637cbSDimitry Andric   case 8:
252*700637cbSDimitry Andric     return PT_Uint8;
253*700637cbSDimitry Andric   default:
254*700637cbSDimitry Andric     return PT_IntAP;
255*700637cbSDimitry Andric   }
256*700637cbSDimitry Andric   llvm_unreachable("Unhandled BitWidth");
257*700637cbSDimitry Andric }
258*700637cbSDimitry Andric 
classify(QualType T) const259*700637cbSDimitry Andric std::optional<PrimType> Context::classify(QualType T) const {
260*700637cbSDimitry Andric 
261*700637cbSDimitry Andric   if (const auto *BT = dyn_cast<BuiltinType>(T.getCanonicalType())) {
262*700637cbSDimitry Andric     auto Kind = BT->getKind();
263*700637cbSDimitry Andric     if (Kind == BuiltinType::Bool)
264*700637cbSDimitry Andric       return PT_Bool;
265*700637cbSDimitry Andric     if (Kind == BuiltinType::NullPtr)
266*700637cbSDimitry Andric       return PT_Ptr;
267*700637cbSDimitry Andric     if (Kind == BuiltinType::BoundMember)
268*700637cbSDimitry Andric       return PT_MemberPtr;
269*700637cbSDimitry Andric 
270*700637cbSDimitry Andric     // Just trying to avoid the ASTContext::getIntWidth call below.
271*700637cbSDimitry Andric     if (Kind == BuiltinType::Short)
272*700637cbSDimitry Andric       return integralTypeToPrimTypeS(this->ShortWidth);
273*700637cbSDimitry Andric     if (Kind == BuiltinType::UShort)
274*700637cbSDimitry Andric       return integralTypeToPrimTypeU(this->ShortWidth);
275*700637cbSDimitry Andric 
276*700637cbSDimitry Andric     if (Kind == BuiltinType::Int)
277*700637cbSDimitry Andric       return integralTypeToPrimTypeS(this->IntWidth);
278*700637cbSDimitry Andric     if (Kind == BuiltinType::UInt)
279*700637cbSDimitry Andric       return integralTypeToPrimTypeU(this->IntWidth);
280*700637cbSDimitry Andric     if (Kind == BuiltinType::Long)
281*700637cbSDimitry Andric       return integralTypeToPrimTypeS(this->LongWidth);
282*700637cbSDimitry Andric     if (Kind == BuiltinType::ULong)
283*700637cbSDimitry Andric       return integralTypeToPrimTypeU(this->LongWidth);
284*700637cbSDimitry Andric     if (Kind == BuiltinType::LongLong)
285*700637cbSDimitry Andric       return integralTypeToPrimTypeS(this->LongLongWidth);
286*700637cbSDimitry Andric     if (Kind == BuiltinType::ULongLong)
287*700637cbSDimitry Andric       return integralTypeToPrimTypeU(this->LongLongWidth);
288*700637cbSDimitry Andric 
289*700637cbSDimitry Andric     if (Kind == BuiltinType::SChar || Kind == BuiltinType::Char_S)
290*700637cbSDimitry Andric       return integralTypeToPrimTypeS(8);
291*700637cbSDimitry Andric     if (Kind == BuiltinType::UChar || Kind == BuiltinType::Char_U ||
292*700637cbSDimitry Andric         Kind == BuiltinType::Char8)
293*700637cbSDimitry Andric       return integralTypeToPrimTypeU(8);
294*700637cbSDimitry Andric 
295*700637cbSDimitry Andric     if (BT->isSignedInteger())
296*700637cbSDimitry Andric       return integralTypeToPrimTypeS(Ctx.getIntWidth(T));
297*700637cbSDimitry Andric     if (BT->isUnsignedInteger())
298*700637cbSDimitry Andric       return integralTypeToPrimTypeU(Ctx.getIntWidth(T));
299*700637cbSDimitry Andric 
300*700637cbSDimitry Andric     if (BT->isFloatingPoint())
301*700637cbSDimitry Andric       return PT_Float;
302*700637cbSDimitry Andric   }
303*700637cbSDimitry Andric 
304*700637cbSDimitry Andric   if (T->isPointerOrReferenceType())
305*700637cbSDimitry Andric     return PT_Ptr;
306*700637cbSDimitry Andric 
307*700637cbSDimitry Andric   if (T->isMemberPointerType())
308*700637cbSDimitry Andric     return PT_MemberPtr;
309*700637cbSDimitry Andric 
310*700637cbSDimitry Andric   if (const auto *BT = T->getAs<BitIntType>()) {
311*700637cbSDimitry Andric     if (BT->isSigned())
312*700637cbSDimitry Andric       return integralTypeToPrimTypeS(BT->getNumBits());
313*700637cbSDimitry Andric     return integralTypeToPrimTypeU(BT->getNumBits());
314*700637cbSDimitry Andric   }
315*700637cbSDimitry Andric 
316*700637cbSDimitry Andric   if (const auto *ET = T->getAs<EnumType>()) {
317*700637cbSDimitry Andric     const auto *D = ET->getDecl();
318*700637cbSDimitry Andric     if (!D->isComplete())
319*700637cbSDimitry Andric       return std::nullopt;
320*700637cbSDimitry Andric     return classify(D->getIntegerType());
321*700637cbSDimitry Andric   }
322*700637cbSDimitry Andric 
323*700637cbSDimitry Andric   if (const auto *AT = T->getAs<AtomicType>())
324*700637cbSDimitry Andric     return classify(AT->getValueType());
325*700637cbSDimitry Andric 
326*700637cbSDimitry Andric   if (const auto *DT = dyn_cast<DecltypeType>(T))
327*700637cbSDimitry Andric     return classify(DT->getUnderlyingType());
328*700637cbSDimitry Andric 
329*700637cbSDimitry Andric   if (T->isObjCObjectPointerType() || T->isBlockPointerType())
330*700637cbSDimitry Andric     return PT_Ptr;
331*700637cbSDimitry Andric 
332*700637cbSDimitry Andric   if (T->isFixedPointType())
333*700637cbSDimitry Andric     return PT_FixedPoint;
334*700637cbSDimitry Andric 
335*700637cbSDimitry Andric   // Vector and complex types get here.
336*700637cbSDimitry Andric   return std::nullopt;
337*700637cbSDimitry Andric }
338*700637cbSDimitry Andric 
getCharBit() const339*700637cbSDimitry Andric unsigned Context::getCharBit() const {
340*700637cbSDimitry Andric   return Ctx.getTargetInfo().getCharWidth();
341*700637cbSDimitry Andric }
342*700637cbSDimitry Andric 
343*700637cbSDimitry Andric /// Simple wrapper around getFloatTypeSemantics() to make code a
344*700637cbSDimitry Andric /// little shorter.
getFloatSemantics(QualType T) const345*700637cbSDimitry Andric const llvm::fltSemantics &Context::getFloatSemantics(QualType T) const {
346*700637cbSDimitry Andric   return Ctx.getFloatTypeSemantics(T);
347*700637cbSDimitry Andric }
348*700637cbSDimitry Andric 
Run(State & Parent,const Function * Func)349*700637cbSDimitry Andric bool Context::Run(State &Parent, const Function *Func) {
350*700637cbSDimitry Andric 
351*700637cbSDimitry Andric   {
352*700637cbSDimitry Andric     InterpState State(Parent, *P, Stk, *this, Func);
353*700637cbSDimitry Andric     if (Interpret(State)) {
354*700637cbSDimitry Andric       assert(Stk.empty());
355*700637cbSDimitry Andric       return true;
356*700637cbSDimitry Andric     }
357*700637cbSDimitry Andric     // State gets destroyed here, so the Stk.clear() below doesn't accidentally
358*700637cbSDimitry Andric     // remove values the State's destructor might access.
359*700637cbSDimitry Andric   }
360*700637cbSDimitry Andric 
361*700637cbSDimitry Andric   Stk.clear();
362*700637cbSDimitry Andric   return false;
363*700637cbSDimitry Andric }
364*700637cbSDimitry Andric 
365*700637cbSDimitry Andric // TODO: Virtual bases?
366*700637cbSDimitry Andric const CXXMethodDecl *
getOverridingFunction(const CXXRecordDecl * DynamicDecl,const CXXRecordDecl * StaticDecl,const CXXMethodDecl * InitialFunction) const367*700637cbSDimitry Andric Context::getOverridingFunction(const CXXRecordDecl *DynamicDecl,
368*700637cbSDimitry Andric                                const CXXRecordDecl *StaticDecl,
369*700637cbSDimitry Andric                                const CXXMethodDecl *InitialFunction) const {
370*700637cbSDimitry Andric   assert(DynamicDecl);
371*700637cbSDimitry Andric   assert(StaticDecl);
372*700637cbSDimitry Andric   assert(InitialFunction);
373*700637cbSDimitry Andric 
374*700637cbSDimitry Andric   const CXXRecordDecl *CurRecord = DynamicDecl;
375*700637cbSDimitry Andric   const CXXMethodDecl *FoundFunction = InitialFunction;
376*700637cbSDimitry Andric   for (;;) {
377*700637cbSDimitry Andric     const CXXMethodDecl *Overrider =
378*700637cbSDimitry Andric         FoundFunction->getCorrespondingMethodDeclaredInClass(CurRecord, false);
379*700637cbSDimitry Andric     if (Overrider)
380*700637cbSDimitry Andric       return Overrider;
381*700637cbSDimitry Andric 
382*700637cbSDimitry Andric     // Common case of only one base class.
383*700637cbSDimitry Andric     if (CurRecord->getNumBases() == 1) {
384*700637cbSDimitry Andric       CurRecord = CurRecord->bases_begin()->getType()->getAsCXXRecordDecl();
385*700637cbSDimitry Andric       continue;
386*700637cbSDimitry Andric     }
387*700637cbSDimitry Andric 
388*700637cbSDimitry Andric     // Otherwise, go to the base class that will lead to the StaticDecl.
389*700637cbSDimitry Andric     for (const CXXBaseSpecifier &Spec : CurRecord->bases()) {
390*700637cbSDimitry Andric       const CXXRecordDecl *Base = Spec.getType()->getAsCXXRecordDecl();
391*700637cbSDimitry Andric       if (Base == StaticDecl || Base->isDerivedFrom(StaticDecl)) {
392*700637cbSDimitry Andric         CurRecord = Base;
393*700637cbSDimitry Andric         break;
394*700637cbSDimitry Andric       }
395*700637cbSDimitry Andric     }
396*700637cbSDimitry Andric   }
397*700637cbSDimitry Andric 
398*700637cbSDimitry Andric   llvm_unreachable(
399*700637cbSDimitry Andric       "Couldn't find an overriding function in the class hierarchy?");
400*700637cbSDimitry Andric   return nullptr;
401*700637cbSDimitry Andric }
402*700637cbSDimitry Andric 
getOrCreateFunction(const FunctionDecl * FuncDecl)403*700637cbSDimitry Andric const Function *Context::getOrCreateFunction(const FunctionDecl *FuncDecl) {
404*700637cbSDimitry Andric   assert(FuncDecl);
405*700637cbSDimitry Andric   FuncDecl = FuncDecl->getMostRecentDecl();
406*700637cbSDimitry Andric 
407*700637cbSDimitry Andric   if (const Function *Func = P->getFunction(FuncDecl))
408*700637cbSDimitry Andric     return Func;
409*700637cbSDimitry Andric 
410*700637cbSDimitry Andric   // Manually created functions that haven't been assigned proper
411*700637cbSDimitry Andric   // parameters yet.
412*700637cbSDimitry Andric   if (!FuncDecl->param_empty() && !FuncDecl->param_begin())
413*700637cbSDimitry Andric     return nullptr;
414*700637cbSDimitry Andric 
415*700637cbSDimitry Andric   bool IsLambdaStaticInvoker = false;
416*700637cbSDimitry Andric   if (const auto *MD = dyn_cast<CXXMethodDecl>(FuncDecl);
417*700637cbSDimitry Andric       MD && MD->isLambdaStaticInvoker()) {
418*700637cbSDimitry Andric     // For a lambda static invoker, we might have to pick a specialized
419*700637cbSDimitry Andric     // version if the lambda is generic. In that case, the picked function
420*700637cbSDimitry Andric     // will *NOT* be a static invoker anymore. However, it will still
421*700637cbSDimitry Andric     // be a non-static member function, this (usually) requiring an
422*700637cbSDimitry Andric     // instance pointer. We suppress that later in this function.
423*700637cbSDimitry Andric     IsLambdaStaticInvoker = true;
424*700637cbSDimitry Andric 
425*700637cbSDimitry Andric     const CXXRecordDecl *ClosureClass = MD->getParent();
426*700637cbSDimitry Andric     assert(ClosureClass->captures_begin() == ClosureClass->captures_end());
427*700637cbSDimitry Andric     if (ClosureClass->isGenericLambda()) {
428*700637cbSDimitry Andric       const CXXMethodDecl *LambdaCallOp = ClosureClass->getLambdaCallOperator();
429*700637cbSDimitry Andric       assert(MD->isFunctionTemplateSpecialization() &&
430*700637cbSDimitry Andric              "A generic lambda's static-invoker function must be a "
431*700637cbSDimitry Andric              "template specialization");
432*700637cbSDimitry Andric       const TemplateArgumentList *TAL = MD->getTemplateSpecializationArgs();
433*700637cbSDimitry Andric       FunctionTemplateDecl *CallOpTemplate =
434*700637cbSDimitry Andric           LambdaCallOp->getDescribedFunctionTemplate();
435*700637cbSDimitry Andric       void *InsertPos = nullptr;
436*700637cbSDimitry Andric       const FunctionDecl *CorrespondingCallOpSpecialization =
437*700637cbSDimitry Andric           CallOpTemplate->findSpecialization(TAL->asArray(), InsertPos);
438*700637cbSDimitry Andric       assert(CorrespondingCallOpSpecialization);
439*700637cbSDimitry Andric       FuncDecl = CorrespondingCallOpSpecialization;
440*700637cbSDimitry Andric     }
441*700637cbSDimitry Andric   }
442*700637cbSDimitry Andric   // Set up argument indices.
443*700637cbSDimitry Andric   unsigned ParamOffset = 0;
444*700637cbSDimitry Andric   SmallVector<PrimType, 8> ParamTypes;
445*700637cbSDimitry Andric   SmallVector<unsigned, 8> ParamOffsets;
446*700637cbSDimitry Andric   llvm::DenseMap<unsigned, Function::ParamDescriptor> ParamDescriptors;
447*700637cbSDimitry Andric 
448*700637cbSDimitry Andric   // If the return is not a primitive, a pointer to the storage where the
449*700637cbSDimitry Andric   // value is initialized in is passed as the first argument. See 'RVO'
450*700637cbSDimitry Andric   // elsewhere in the code.
451*700637cbSDimitry Andric   QualType Ty = FuncDecl->getReturnType();
452*700637cbSDimitry Andric   bool HasRVO = false;
453*700637cbSDimitry Andric   if (!Ty->isVoidType() && !classify(Ty)) {
454*700637cbSDimitry Andric     HasRVO = true;
455*700637cbSDimitry Andric     ParamTypes.push_back(PT_Ptr);
456*700637cbSDimitry Andric     ParamOffsets.push_back(ParamOffset);
457*700637cbSDimitry Andric     ParamOffset += align(primSize(PT_Ptr));
458*700637cbSDimitry Andric   }
459*700637cbSDimitry Andric 
460*700637cbSDimitry Andric   // If the function decl is a member decl, the next parameter is
461*700637cbSDimitry Andric   // the 'this' pointer. This parameter is pop()ed from the
462*700637cbSDimitry Andric   // InterpStack when calling the function.
463*700637cbSDimitry Andric   bool HasThisPointer = false;
464*700637cbSDimitry Andric   if (const auto *MD = dyn_cast<CXXMethodDecl>(FuncDecl)) {
465*700637cbSDimitry Andric     if (!IsLambdaStaticInvoker) {
466*700637cbSDimitry Andric       HasThisPointer = MD->isInstance();
467*700637cbSDimitry Andric       if (MD->isImplicitObjectMemberFunction()) {
468*700637cbSDimitry Andric         ParamTypes.push_back(PT_Ptr);
469*700637cbSDimitry Andric         ParamOffsets.push_back(ParamOffset);
470*700637cbSDimitry Andric         ParamOffset += align(primSize(PT_Ptr));
471*700637cbSDimitry Andric       }
472*700637cbSDimitry Andric     }
473*700637cbSDimitry Andric 
474*700637cbSDimitry Andric     if (isLambdaCallOperator(MD)) {
475*700637cbSDimitry Andric       // The parent record needs to be complete, we need to know about all
476*700637cbSDimitry Andric       // the lambda captures.
477*700637cbSDimitry Andric       if (!MD->getParent()->isCompleteDefinition())
478*700637cbSDimitry Andric         return nullptr;
479*700637cbSDimitry Andric       llvm::DenseMap<const ValueDecl *, FieldDecl *> LC;
480*700637cbSDimitry Andric       FieldDecl *LTC;
481*700637cbSDimitry Andric 
482*700637cbSDimitry Andric       MD->getParent()->getCaptureFields(LC, LTC);
483*700637cbSDimitry Andric 
484*700637cbSDimitry Andric       if (MD->isStatic() && !LC.empty()) {
485*700637cbSDimitry Andric         // Static lambdas cannot have any captures. If this one does,
486*700637cbSDimitry Andric         // it has already been diagnosed and we can only ignore it.
487*700637cbSDimitry Andric         return nullptr;
488*700637cbSDimitry Andric       }
489*700637cbSDimitry Andric     }
490*700637cbSDimitry Andric   }
491*700637cbSDimitry Andric 
492*700637cbSDimitry Andric   // Assign descriptors to all parameters.
493*700637cbSDimitry Andric   // Composite objects are lowered to pointers.
494*700637cbSDimitry Andric   for (const ParmVarDecl *PD : FuncDecl->parameters()) {
495*700637cbSDimitry Andric     std::optional<PrimType> T = classify(PD->getType());
496*700637cbSDimitry Andric     PrimType PT = T.value_or(PT_Ptr);
497*700637cbSDimitry Andric     Descriptor *Desc = P->createDescriptor(PD, PT);
498*700637cbSDimitry Andric     ParamDescriptors.insert({ParamOffset, {PT, Desc}});
499*700637cbSDimitry Andric     ParamOffsets.push_back(ParamOffset);
500*700637cbSDimitry Andric     ParamOffset += align(primSize(PT));
501*700637cbSDimitry Andric     ParamTypes.push_back(PT);
502*700637cbSDimitry Andric   }
503*700637cbSDimitry Andric 
504*700637cbSDimitry Andric   // Create a handle over the emitted code.
505*700637cbSDimitry Andric   assert(!P->getFunction(FuncDecl));
506*700637cbSDimitry Andric   const Function *Func = P->createFunction(
507*700637cbSDimitry Andric       FuncDecl, ParamOffset, std::move(ParamTypes), std::move(ParamDescriptors),
508*700637cbSDimitry Andric       std::move(ParamOffsets), HasThisPointer, HasRVO, IsLambdaStaticInvoker);
509*700637cbSDimitry Andric   return Func;
510*700637cbSDimitry Andric }
511*700637cbSDimitry Andric 
getOrCreateObjCBlock(const BlockExpr * E)512*700637cbSDimitry Andric const Function *Context::getOrCreateObjCBlock(const BlockExpr *E) {
513*700637cbSDimitry Andric   const BlockDecl *BD = E->getBlockDecl();
514*700637cbSDimitry Andric   // Set up argument indices.
515*700637cbSDimitry Andric   unsigned ParamOffset = 0;
516*700637cbSDimitry Andric   SmallVector<PrimType, 8> ParamTypes;
517*700637cbSDimitry Andric   SmallVector<unsigned, 8> ParamOffsets;
518*700637cbSDimitry Andric   llvm::DenseMap<unsigned, Function::ParamDescriptor> ParamDescriptors;
519*700637cbSDimitry Andric 
520*700637cbSDimitry Andric   // Assign descriptors to all parameters.
521*700637cbSDimitry Andric   // Composite objects are lowered to pointers.
522*700637cbSDimitry Andric   for (const ParmVarDecl *PD : BD->parameters()) {
523*700637cbSDimitry Andric     std::optional<PrimType> T = classify(PD->getType());
524*700637cbSDimitry Andric     PrimType PT = T.value_or(PT_Ptr);
525*700637cbSDimitry Andric     Descriptor *Desc = P->createDescriptor(PD, PT);
526*700637cbSDimitry Andric     ParamDescriptors.insert({ParamOffset, {PT, Desc}});
527*700637cbSDimitry Andric     ParamOffsets.push_back(ParamOffset);
528*700637cbSDimitry Andric     ParamOffset += align(primSize(PT));
529*700637cbSDimitry Andric     ParamTypes.push_back(PT);
530*700637cbSDimitry Andric   }
531*700637cbSDimitry Andric 
532*700637cbSDimitry Andric   if (BD->hasCaptures())
533*700637cbSDimitry Andric     return nullptr;
534*700637cbSDimitry Andric 
535*700637cbSDimitry Andric   // Create a handle over the emitted code.
536*700637cbSDimitry Andric   Function *Func =
537*700637cbSDimitry Andric       P->createFunction(E, ParamOffset, std::move(ParamTypes),
538*700637cbSDimitry Andric                         std::move(ParamDescriptors), std::move(ParamOffsets),
539*700637cbSDimitry Andric                         /*HasThisPointer=*/false, /*HasRVO=*/false,
540*700637cbSDimitry Andric                         /*IsLambdaStaticInvoker=*/false);
541*700637cbSDimitry Andric 
542*700637cbSDimitry Andric   assert(Func);
543*700637cbSDimitry Andric   Func->setDefined(true);
544*700637cbSDimitry Andric   // We don't compile the BlockDecl code at all right now.
545*700637cbSDimitry Andric   Func->setIsFullyCompiled(true);
546*700637cbSDimitry Andric   return Func;
547*700637cbSDimitry Andric }
548*700637cbSDimitry Andric 
collectBaseOffset(const RecordDecl * BaseDecl,const RecordDecl * DerivedDecl) const549*700637cbSDimitry Andric unsigned Context::collectBaseOffset(const RecordDecl *BaseDecl,
550*700637cbSDimitry Andric                                     const RecordDecl *DerivedDecl) const {
551*700637cbSDimitry Andric   assert(BaseDecl);
552*700637cbSDimitry Andric   assert(DerivedDecl);
553*700637cbSDimitry Andric   const auto *FinalDecl = cast<CXXRecordDecl>(BaseDecl);
554*700637cbSDimitry Andric   const RecordDecl *CurDecl = DerivedDecl;
555*700637cbSDimitry Andric   const Record *CurRecord = P->getOrCreateRecord(CurDecl);
556*700637cbSDimitry Andric   assert(CurDecl && FinalDecl);
557*700637cbSDimitry Andric 
558*700637cbSDimitry Andric   unsigned OffsetSum = 0;
559*700637cbSDimitry Andric   for (;;) {
560*700637cbSDimitry Andric     assert(CurRecord->getNumBases() > 0);
561*700637cbSDimitry Andric     // One level up
562*700637cbSDimitry Andric     for (const Record::Base &B : CurRecord->bases()) {
563*700637cbSDimitry Andric       const auto *BaseDecl = cast<CXXRecordDecl>(B.Decl);
564*700637cbSDimitry Andric 
565*700637cbSDimitry Andric       if (BaseDecl == FinalDecl || BaseDecl->isDerivedFrom(FinalDecl)) {
566*700637cbSDimitry Andric         OffsetSum += B.Offset;
567*700637cbSDimitry Andric         CurRecord = B.R;
568*700637cbSDimitry Andric         CurDecl = BaseDecl;
569*700637cbSDimitry Andric         break;
570*700637cbSDimitry Andric       }
571*700637cbSDimitry Andric     }
572*700637cbSDimitry Andric     if (CurDecl == FinalDecl)
573*700637cbSDimitry Andric       break;
574*700637cbSDimitry Andric   }
575*700637cbSDimitry Andric 
576*700637cbSDimitry Andric   assert(OffsetSum > 0);
577*700637cbSDimitry Andric   return OffsetSum;
578*700637cbSDimitry Andric }
579*700637cbSDimitry Andric 
getRecord(const RecordDecl * D) const580*700637cbSDimitry Andric const Record *Context::getRecord(const RecordDecl *D) const {
581*700637cbSDimitry Andric   return P->getOrCreateRecord(D);
582*700637cbSDimitry Andric }
583*700637cbSDimitry Andric 
isUnevaluatedBuiltin(unsigned ID)584*700637cbSDimitry Andric bool Context::isUnevaluatedBuiltin(unsigned ID) {
585*700637cbSDimitry Andric   return ID == Builtin::BI__builtin_classify_type ||
586*700637cbSDimitry Andric          ID == Builtin::BI__builtin_os_log_format_buffer_size ||
587*700637cbSDimitry Andric          ID == Builtin::BI__builtin_constant_p || ID == Builtin::BI__noop;
588*700637cbSDimitry Andric }
589