diff --git a/clang/lib/AST/Interp/ByteCodeEmitter.h b/clang/lib/AST/Interp/ByteCodeEmitter.h --- a/clang/lib/AST/Interp/ByteCodeEmitter.h +++ b/clang/lib/AST/Interp/ByteCodeEmitter.h @@ -69,10 +69,9 @@ Local createLocal(Descriptor *D); /// Parameter indices. - llvm::DenseMap Params; + llvm::DenseMap Params; /// Lambda captures. - /// Map from Decl* to [Offset, IsReference] pair. - llvm::DenseMap> LambdaCaptures; + llvm::DenseMap LambdaCaptures; unsigned LambdaThisCapture; /// Local descriptors. llvm::SmallVector, 2> Descriptors; diff --git a/clang/lib/AST/Interp/ByteCodeEmitter.cpp b/clang/lib/AST/Interp/ByteCodeEmitter.cpp --- a/clang/lib/AST/Interp/ByteCodeEmitter.cpp +++ b/clang/lib/AST/Interp/ByteCodeEmitter.cpp @@ -74,13 +74,14 @@ // Assign descriptors to all parameters. // Composite objects are lowered to pointers. for (const ParmVarDecl *PD : FuncDecl->parameters()) { - PrimType Ty = Ctx.classify(PD->getType()).value_or(PT_Ptr); - Descriptor *Desc = P.createDescriptor(PD, Ty); - ParamDescriptors.insert({ParamOffset, {Ty, Desc}}); - Params.insert({PD, ParamOffset}); + std::optional T = Ctx.classify(PD->getType()); + PrimType PT = T.value_or(PT_Ptr); + Descriptor *Desc = P.createDescriptor(PD, PT); + ParamDescriptors.insert({ParamOffset, {PT, Desc}}); + Params.insert({PD, {ParamOffset, T != std::nullopt}}); ParamOffsets.push_back(ParamOffset); - ParamOffset += align(primSize(Ty)); - ParamTypes.push_back(Ty); + ParamOffset += align(primSize(PT)); + ParamTypes.push_back(PT); } // Create a handle over the emitted code. diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -1195,7 +1195,7 @@ llvm::function_ref Indirect) { auto It = this->Params.find(PD); if (It != this->Params.end()) { - unsigned Idx = It->second; + unsigned Idx = It->second.Offset; switch (AK) { case DerefKind::Read: return DiscardResult ? true : this->emitGetParam(T, Idx, LV); @@ -2153,18 +2153,19 @@ return this->emitGetPtrGlobal(*GlobalIndex, E); } else if (const auto *PVD = dyn_cast(D)) { if (auto It = this->Params.find(PVD); It != this->Params.end()) { - if (IsReference) - return this->emitGetParamPtr(It->second, E); - return this->emitGetPtrParam(It->second, E); + if (IsReference || !It->second.IsPtr) + return this->emitGetParamPtr(It->second.Offset, E); + + return this->emitGetPtrParam(It->second.Offset, E); } } // Handle lambda captures. if (auto It = this->LambdaCaptures.find(D); It != this->LambdaCaptures.end()) { - auto [Offset, IsReference] = It->second; + auto [Offset, IsPtr] = It->second; - if (IsReference) + if (IsPtr) return this->emitGetThisFieldPtr(Offset, E); return this->emitGetPtrThisField(Offset, E); } diff --git a/clang/lib/AST/Interp/ByteCodeStmtGen.cpp b/clang/lib/AST/Interp/ByteCodeStmtGen.cpp --- a/clang/lib/AST/Interp/ByteCodeStmtGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeStmtGen.cpp @@ -125,7 +125,7 @@ // We do the lvalue-to-rvalue conversion manually here, so no need // to care about references. PrimType ParamType = this->classify(PVD->getType()).value_or(PT_Ptr); - if (!this->emitGetParam(ParamType, It->second, MD)) + if (!this->emitGetParam(ParamType, It->second.Offset, MD)) return false; } diff --git a/clang/lib/AST/Interp/Context.h b/clang/lib/AST/Interp/Context.h --- a/clang/lib/AST/Interp/Context.h +++ b/clang/lib/AST/Interp/Context.h @@ -31,6 +31,11 @@ class State; enum PrimType : unsigned; +struct ParamOffset { + unsigned Offset; + bool IsPtr; +}; + /// Holds all information required to evaluate constexpr code in a module. class Context final { public: diff --git a/clang/lib/AST/Interp/EvalEmitter.h b/clang/lib/AST/Interp/EvalEmitter.h --- a/clang/lib/AST/Interp/EvalEmitter.h +++ b/clang/lib/AST/Interp/EvalEmitter.h @@ -75,10 +75,9 @@ } /// Parameter indices. - llvm::DenseMap Params; + llvm::DenseMap Params; /// Lambda captures. - /// Map from Decl* to [Offset, IsReference] pair. - llvm::DenseMap> LambdaCaptures; + llvm::DenseMap LambdaCaptures; unsigned LambdaThisCapture; /// Local descriptors. llvm::SmallVector, 2> Descriptors;