2020using namespace clang ;
2121using namespace clang ::interp;
2222
23- Function *ByteCodeEmitter::compileFunc (const FunctionDecl *FuncDecl) {
23+ void ByteCodeEmitter::compileFunc (const FunctionDecl *FuncDecl,
24+ Function *Func) {
25+ assert (FuncDecl);
26+ assert (Func);
2427
2528 // Manually created functions that haven't been assigned proper
2629 // parameters yet.
2730 if (!FuncDecl->param_empty () && !FuncDecl->param_begin ())
28- return nullptr ;
31+ return ;
32+
33+ if (!FuncDecl->isDefined ())
34+ return ;
2935
30- bool IsLambdaStaticInvoker = false ;
36+ // Set up lambda captures.
3137 if (const auto *MD = dyn_cast<CXXMethodDecl>(FuncDecl);
32- MD && MD->isLambdaStaticInvoker ()) {
33- // For a lambda static invoker, we might have to pick a specialized
34- // version if the lambda is generic. In that case, the picked function
35- // will *NOT* be a static invoker anymore. However, it will still
36- // be a non-static member function, this (usually) requiring an
37- // instance pointer. We suppress that later in this function.
38- IsLambdaStaticInvoker = true ;
39-
40- const CXXRecordDecl *ClosureClass = MD->getParent ();
41- assert (ClosureClass->captures_begin () == ClosureClass->captures_end ());
42- if (ClosureClass->isGenericLambda ()) {
43- const CXXMethodDecl *LambdaCallOp = ClosureClass->getLambdaCallOperator ();
44- assert (MD->isFunctionTemplateSpecialization () &&
45- " A generic lambda's static-invoker function must be a "
46- " template specialization" );
47- const TemplateArgumentList *TAL = MD->getTemplateSpecializationArgs ();
48- FunctionTemplateDecl *CallOpTemplate =
49- LambdaCallOp->getDescribedFunctionTemplate ();
50- void *InsertPos = nullptr ;
51- const FunctionDecl *CorrespondingCallOpSpecialization =
52- CallOpTemplate->findSpecialization (TAL->asArray (), InsertPos);
53- assert (CorrespondingCallOpSpecialization);
54- FuncDecl = cast<CXXMethodDecl>(CorrespondingCallOpSpecialization);
55- }
56- }
38+ MD && isLambdaCallOperator (MD)) {
39+ // Set up lambda capture to closure record field mapping.
40+ const Record *R = P.getOrCreateRecord (MD->getParent ());
41+ assert (R);
42+ llvm::DenseMap<const ValueDecl *, FieldDecl *> LC;
43+ FieldDecl *LTC;
5744
58- // Set up argument indices.
59- unsigned ParamOffset = 0 ;
60- SmallVector<PrimType, 8 > ParamTypes;
61- SmallVector<unsigned , 8 > ParamOffsets;
62- llvm::DenseMap<unsigned , Function::ParamDescriptor> ParamDescriptors;
63-
64- // If the return is not a primitive, a pointer to the storage where the
65- // value is initialized in is passed as the first argument. See 'RVO'
66- // elsewhere in the code.
67- QualType Ty = FuncDecl->getReturnType ();
68- bool HasRVO = false ;
69- if (!Ty->isVoidType () && !Ctx.classify (Ty)) {
70- HasRVO = true ;
71- ParamTypes.push_back (PT_Ptr);
72- ParamOffsets.push_back (ParamOffset);
73- ParamOffset += align (primSize (PT_Ptr));
74- }
45+ MD->getParent ()->getCaptureFields (LC, LTC);
7546
76- // If the function decl is a member decl, the next parameter is
77- // the 'this' pointer. This parameter is pop()ed from the
78- // InterpStack when calling the function.
79- bool HasThisPointer = false ;
80- if (const auto *MD = dyn_cast<CXXMethodDecl>(FuncDecl)) {
81- if (!IsLambdaStaticInvoker) {
82- HasThisPointer = MD->isInstance ();
83- if (MD->isImplicitObjectMemberFunction ()) {
84- ParamTypes.push_back (PT_Ptr);
85- ParamOffsets.push_back (ParamOffset);
86- ParamOffset += align (primSize (PT_Ptr));
87- }
47+ for (auto Cap : LC) {
48+ unsigned Offset = R->getField (Cap.second )->Offset ;
49+ this ->LambdaCaptures [Cap.first ] = {
50+ Offset, Cap.second ->getType ()->isReferenceType ()};
8851 }
89-
90- // Set up lambda capture to closure record field mapping.
91- if (isLambdaCallOperator (MD)) {
92- // The parent record needs to be complete, we need to know about all
93- // the lambda captures.
94- if (!MD->getParent ()->isCompleteDefinition ())
95- return nullptr ;
96-
97- const Record *R = P.getOrCreateRecord (MD->getParent ());
98- llvm::DenseMap<const ValueDecl *, FieldDecl *> LC;
99- FieldDecl *LTC;
100-
101- MD->getParent ()->getCaptureFields (LC, LTC);
102-
103- for (auto Cap : LC) {
104- // Static lambdas cannot have any captures. If this one does,
105- // it has already been diagnosed and we can only ignore it.
106- if (MD->isStatic ())
107- return nullptr ;
108-
109- unsigned Offset = R->getField (Cap.second )->Offset ;
110- this ->LambdaCaptures [Cap.first ] = {
111- Offset, Cap.second ->getType ()->isReferenceType ()};
112- }
113- if (LTC) {
114- QualType CaptureType = R->getField (LTC)->Decl ->getType ();
115- this ->LambdaThisCapture = {R->getField (LTC)->Offset ,
116- CaptureType->isReferenceType () ||
117- CaptureType->isPointerType ()};
118- }
52+ if (LTC) {
53+ QualType CaptureType = R->getField (LTC)->Decl ->getType ();
54+ this ->LambdaThisCapture = {R->getField (LTC)->Offset ,
55+ CaptureType->isPointerOrReferenceType ()};
11956 }
12057 }
12158
122- // Assign descriptors to all parameters.
123- // Composite objects are lowered to pointers.
124- for (const ParmVarDecl *PD : FuncDecl->parameters ()) {
59+ // Register parameters with their offset.
60+ unsigned ParamIndex = 0 ;
61+ unsigned Drop = Func->hasRVO () +
62+ (Func->hasThisPointer () && !Func->isThisPointerExplicit ());
63+ for (auto ParamOffset : llvm::drop_begin (Func->ParamOffsets , Drop)) {
64+ const ParmVarDecl *PD = FuncDecl->parameters ()[ParamIndex];
12565 std::optional<PrimType> T = Ctx.classify (PD->getType ());
126- PrimType PT = T.value_or (PT_Ptr);
127- Descriptor *Desc = P.createDescriptor (PD, PT);
128- ParamDescriptors.insert ({ParamOffset, {PT, Desc}});
129- Params.insert ({PD, {ParamOffset, T != std::nullopt }});
130- ParamOffsets.push_back (ParamOffset);
131- ParamOffset += align (primSize (PT));
132- ParamTypes.push_back (PT);
133- }
134-
135- // Create a handle over the emitted code.
136- Function *Func = P.getFunction (FuncDecl);
137- if (!Func) {
138- Func = P.createFunction (FuncDecl, ParamOffset, std::move (ParamTypes),
139- std::move (ParamDescriptors),
140- std::move (ParamOffsets), HasThisPointer, HasRVO);
141- }
142-
143- assert (Func);
144- // For not-yet-defined functions, we only create a Function instance and
145- // compile their body later.
146- if (!FuncDecl->isDefined () ||
147- (FuncDecl->willHaveBody () && !FuncDecl->hasBody ())) {
148- Func->setDefined (false );
149- return Func;
66+ this ->Params .insert ({PD, {ParamOffset, T != std::nullopt }});
67+ ++ParamIndex;
15068 }
15169
15270 Func->setDefined (true );
15371
15472 // Lambda static invokers are a special case that we emit custom code for.
155- bool IsEligibleForCompilation = false ;
156- if (const auto *MD = dyn_cast<CXXMethodDecl>(FuncDecl))
157- IsEligibleForCompilation = MD->isLambdaStaticInvoker ();
158- if (!IsEligibleForCompilation)
159- IsEligibleForCompilation =
160- FuncDecl->isConstexpr () || FuncDecl->hasAttr <MSConstexprAttr>();
73+ bool IsEligibleForCompilation = Func->isLambdaStaticInvoker () ||
74+ FuncDecl->isConstexpr () ||
75+ FuncDecl->hasAttr <MSConstexprAttr>();
16176
16277 // Compile the function body.
16378 if (!IsEligibleForCompilation || !visitFunc (FuncDecl)) {
16479 Func->setIsFullyCompiled (true );
165- return Func ;
80+ return ;
16681 }
16782
16883 // Create scopes from descriptors.
@@ -175,48 +90,6 @@ Function *ByteCodeEmitter::compileFunc(const FunctionDecl *FuncDecl) {
17590 Func->setCode (NextLocalOffset, std::move (Code), std::move (SrcMap),
17691 std::move (Scopes), FuncDecl->hasBody ());
17792 Func->setIsFullyCompiled (true );
178- return Func;
179- }
180-
181- // / Compile an ObjC block, i.e. ^(){}, that thing.
182- // /
183- // / FIXME: We do not support calling the block though, so we create a function
184- // / here but do not compile any code for it.
185- Function *ByteCodeEmitter::compileObjCBlock (const BlockExpr *BE) {
186- const BlockDecl *BD = BE->getBlockDecl ();
187- // Set up argument indices.
188- unsigned ParamOffset = 0 ;
189- SmallVector<PrimType, 8 > ParamTypes;
190- SmallVector<unsigned , 8 > ParamOffsets;
191- llvm::DenseMap<unsigned , Function::ParamDescriptor> ParamDescriptors;
192-
193- // Assign descriptors to all parameters.
194- // Composite objects are lowered to pointers.
195- for (const ParmVarDecl *PD : BD->parameters ()) {
196- std::optional<PrimType> T = Ctx.classify (PD->getType ());
197- PrimType PT = T.value_or (PT_Ptr);
198- Descriptor *Desc = P.createDescriptor (PD, PT);
199- ParamDescriptors.insert ({ParamOffset, {PT, Desc}});
200- Params.insert ({PD, {ParamOffset, T != std::nullopt }});
201- ParamOffsets.push_back (ParamOffset);
202- ParamOffset += align (primSize (PT));
203- ParamTypes.push_back (PT);
204- }
205-
206- if (BD->hasCaptures ())
207- return nullptr ;
208-
209- // Create a handle over the emitted code.
210- Function *Func =
211- P.createFunction (BE, ParamOffset, std::move (ParamTypes),
212- std::move (ParamDescriptors), std::move (ParamOffsets),
213- /* HasThisPointer=*/ false , /* HasRVO=*/ false );
214-
215- assert (Func);
216- Func->setDefined (true );
217- // We don't compile the BlockDecl code at all right now.
218- Func->setIsFullyCompiled (true );
219- return Func;
22093}
22194
22295Scope::Local ByteCodeEmitter::createLocal (Descriptor *D) {
0 commit comments