[clang] 27ed9b4 - [clang][Interp][NFC] Move ctor compilation to compileConstructor
Timm Bäder via cfe-commits
cfe-commits at lists.llvm.org
Sun Aug 11 23:48:13 PDT 2024
Author: Timm Bäder
Date: 2024-08-12T08:47:55+02:00
New Revision: 27ed9b47977ff99e182b74f653d4d125d2baa896
URL: https://github.com/llvm/llvm-project/commit/27ed9b47977ff99e182b74f653d4d125d2baa896
DIFF: https://github.com/llvm/llvm-project/commit/27ed9b47977ff99e182b74f653d4d125d2baa896.diff
LOG: [clang][Interp][NFC] Move ctor compilation to compileConstructor
In preparation for having a similar function for destructors.
Added:
Modified:
clang/lib/AST/Interp/Compiler.cpp
clang/lib/AST/Interp/Compiler.h
Removed:
################################################################################
diff --git a/clang/lib/AST/Interp/Compiler.cpp b/clang/lib/AST/Interp/Compiler.cpp
index ad1a2f96b9590..dd24cff1bab46 100644
--- a/clang/lib/AST/Interp/Compiler.cpp
+++ b/clang/lib/AST/Interp/Compiler.cpp
@@ -4733,9 +4733,8 @@ bool Compiler<Emitter>::checkLiteralType(const Expr *E) {
}
template <class Emitter>
-bool Compiler<Emitter>::visitFunc(const FunctionDecl *F) {
- // Classify the return type.
- ReturnType = this->classify(F->getReturnType());
+bool Compiler<Emitter>::compileConstructor(const CXXConstructorDecl *Ctor) {
+ assert(!ReturnType);
auto emitFieldInitializer = [&](const Record::Field *F, unsigned FieldOffset,
const Expr *InitExpr) -> bool {
@@ -4763,102 +4762,114 @@ bool Compiler<Emitter>::visitFunc(const FunctionDecl *F) {
return this->emitFinishInitPop(InitExpr);
};
- // Emit custom code if this is a lambda static invoker.
- if (const auto *MD = dyn_cast<CXXMethodDecl>(F);
- MD && MD->isLambdaStaticInvoker())
- return this->emitLambdaStaticInvokerBody(MD);
+ const RecordDecl *RD = Ctor->getParent();
+ const Record *R = this->getRecord(RD);
+ if (!R)
+ return false;
- // Constructor. Set up field initializers.
- if (const auto *Ctor = dyn_cast<CXXConstructorDecl>(F)) {
- const RecordDecl *RD = Ctor->getParent();
- const Record *R = this->getRecord(RD);
- if (!R)
+ if (R->isUnion() && Ctor->isCopyOrMoveConstructor()) {
+ // union copy and move ctors are special.
+ assert(cast<CompoundStmt>(Ctor->getBody())->body_empty());
+ if (!this->emitThis(Ctor))
return false;
- if (R->isUnion() && Ctor->isCopyOrMoveConstructor()) {
- // union copy and move ctors are special.
- assert(cast<CompoundStmt>(Ctor->getBody())->body_empty());
- if (!this->emitThis(Ctor))
- return false;
+ auto PVD = Ctor->getParamDecl(0);
+ ParamOffset PO = this->Params[PVD]; // Must exist.
- auto PVD = Ctor->getParamDecl(0);
- ParamOffset PO = this->Params[PVD]; // Must exist.
+ if (!this->emitGetParam(PT_Ptr, PO.Offset, Ctor))
+ return false;
- if (!this->emitGetParam(PT_Ptr, PO.Offset, Ctor))
- return false;
+ return this->emitMemcpy(Ctor) && this->emitPopPtr(Ctor) &&
+ this->emitRetVoid(Ctor);
+ }
- return this->emitMemcpy(Ctor) && this->emitPopPtr(Ctor) &&
- this->emitRetVoid(Ctor);
- }
+ InitLinkScope<Emitter> InitScope(this, InitLink::This());
+ for (const auto *Init : Ctor->inits()) {
+ // Scope needed for the initializers.
+ BlockScope<Emitter> Scope(this);
- InitLinkScope<Emitter> InitScope(this, InitLink::This());
- for (const auto *Init : Ctor->inits()) {
- // Scope needed for the initializers.
- BlockScope<Emitter> Scope(this);
+ const Expr *InitExpr = Init->getInit();
+ if (const FieldDecl *Member = Init->getMember()) {
+ const Record::Field *F = R->getField(Member);
- const Expr *InitExpr = Init->getInit();
- if (const FieldDecl *Member = Init->getMember()) {
- const Record::Field *F = R->getField(Member);
+ if (!emitFieldInitializer(F, F->Offset, InitExpr))
+ return false;
+ } else if (const Type *Base = Init->getBaseClass()) {
+ const auto *BaseDecl = Base->getAsCXXRecordDecl();
+ assert(BaseDecl);
- if (!emitFieldInitializer(F, F->Offset, InitExpr))
+ if (Init->isBaseVirtual()) {
+ assert(R->getVirtualBase(BaseDecl));
+ if (!this->emitGetPtrThisVirtBase(BaseDecl, InitExpr))
return false;
- } else if (const Type *Base = Init->getBaseClass()) {
- const auto *BaseDecl = Base->getAsCXXRecordDecl();
- assert(BaseDecl);
-
- if (Init->isBaseVirtual()) {
- assert(R->getVirtualBase(BaseDecl));
- if (!this->emitGetPtrThisVirtBase(BaseDecl, InitExpr))
- return false;
-
- } else {
- // Base class initializer.
- // Get This Base and call initializer on it.
- const Record::Base *B = R->getBase(BaseDecl);
- assert(B);
- if (!this->emitGetPtrThisBase(B->Offset, InitExpr))
- return false;
- }
- if (!this->visitInitializer(InitExpr))
- return false;
- if (!this->emitFinishInitPop(InitExpr))
+ } else {
+ // Base class initializer.
+ // Get This Base and call initializer on it.
+ const Record::Base *B = R->getBase(BaseDecl);
+ assert(B);
+ if (!this->emitGetPtrThisBase(B->Offset, InitExpr))
return false;
- } else if (const IndirectFieldDecl *IFD = Init->getIndirectMember()) {
- assert(IFD->getChainingSize() >= 2);
+ }
- unsigned NestedFieldOffset = 0;
- const Record::Field *NestedField = nullptr;
- for (const NamedDecl *ND : IFD->chain()) {
- const auto *FD = cast<FieldDecl>(ND);
- const Record *FieldRecord =
- this->P.getOrCreateRecord(FD->getParent());
- assert(FieldRecord);
+ if (!this->visitInitializer(InitExpr))
+ return false;
+ if (!this->emitFinishInitPop(InitExpr))
+ return false;
+ } else if (const IndirectFieldDecl *IFD = Init->getIndirectMember()) {
+ assert(IFD->getChainingSize() >= 2);
- NestedField = FieldRecord->getField(FD);
- assert(NestedField);
+ unsigned NestedFieldOffset = 0;
+ const Record::Field *NestedField = nullptr;
+ for (const NamedDecl *ND : IFD->chain()) {
+ const auto *FD = cast<FieldDecl>(ND);
+ const Record *FieldRecord = this->P.getOrCreateRecord(FD->getParent());
+ assert(FieldRecord);
- NestedFieldOffset += NestedField->Offset;
- }
+ NestedField = FieldRecord->getField(FD);
assert(NestedField);
- if (!emitFieldInitializer(NestedField, NestedFieldOffset, InitExpr))
- return false;
- } else {
- assert(Init->isDelegatingInitializer());
- if (!this->emitThis(InitExpr))
- return false;
- if (!this->visitInitializer(Init->getInit()))
- return false;
- if (!this->emitPopPtr(InitExpr))
- return false;
+ NestedFieldOffset += NestedField->Offset;
}
+ assert(NestedField);
- if (!Scope.destroyLocals())
+ if (!emitFieldInitializer(NestedField, NestedFieldOffset, InitExpr))
+ return false;
+ } else {
+ assert(Init->isDelegatingInitializer());
+ if (!this->emitThis(InitExpr))
+ return false;
+ if (!this->visitInitializer(Init->getInit()))
+ return false;
+ if (!this->emitPopPtr(InitExpr))
return false;
}
+
+ if (!Scope.destroyLocals())
+ return false;
}
+ if (const auto *Body = Ctor->getBody())
+ if (!visitStmt(Body))
+ return false;
+
+ return this->emitRetVoid(SourceInfo{});
+}
+
+template <class Emitter>
+bool Compiler<Emitter>::visitFunc(const FunctionDecl *F) {
+ // Classify the return type.
+ ReturnType = this->classify(F->getReturnType());
+
+ if (const auto *Ctor = dyn_cast<CXXConstructorDecl>(F))
+ return this->compileConstructor(Ctor);
+
+ // Emit custom code if this is a lambda static invoker.
+ if (const auto *MD = dyn_cast<CXXMethodDecl>(F);
+ MD && MD->isLambdaStaticInvoker())
+ return this->emitLambdaStaticInvokerBody(MD);
+
+ // Regular functions.
if (const auto *Body = F->getBody())
if (!visitStmt(Body))
return false;
diff --git a/clang/lib/AST/Interp/Compiler.h b/clang/lib/AST/Interp/Compiler.h
index 244a600d061f4..d94d3613775a1 100644
--- a/clang/lib/AST/Interp/Compiler.h
+++ b/clang/lib/AST/Interp/Compiler.h
@@ -357,6 +357,7 @@ class Compiler : public ConstStmtVisitor<Compiler<Emitter>, bool>,
unsigned collectBaseOffset(const QualType BaseType,
const QualType DerivedType);
bool emitLambdaStaticInvokerBody(const CXXMethodDecl *MD);
+ bool compileConstructor(const CXXConstructorDecl *Ctor);
bool checkLiteralType(const Expr *E);
More information about the cfe-commits
mailing list