Skip to content

Commit

Permalink
[clang][Interp][NFC] Move collectBaseOffset() to Context
Browse files Browse the repository at this point in the history
We will need this outside of ByteCodeExprGen later.
  • Loading branch information
tbaederr committed Apr 26, 2024
1 parent c2db883 commit bc8a4ea
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 34 deletions.
46 changes: 14 additions & 32 deletions clang/lib/AST/Interp/ByteCodeExprGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,8 @@ bool ByteCodeExprGen<Emitter>::VisitCastExpr(const CastExpr *CE) {
if (!this->visit(SubExpr))
return false;

unsigned DerivedOffset = collectBaseOffset(getRecordTy(CE->getType()),
getRecordTy(SubExpr->getType()));
unsigned DerivedOffset =
collectBaseOffset(CE->getType(), SubExpr->getType());

return this->emitGetPtrBasePop(DerivedOffset, CE);
}
Expand All @@ -120,8 +120,8 @@ bool ByteCodeExprGen<Emitter>::VisitCastExpr(const CastExpr *CE) {
if (!this->visit(SubExpr))
return false;

unsigned DerivedOffset = collectBaseOffset(getRecordTy(SubExpr->getType()),
getRecordTy(CE->getType()));
unsigned DerivedOffset =
collectBaseOffset(SubExpr->getType(), CE->getType());

return this->emitGetPtrDerivedPop(DerivedOffset, CE);
}
Expand Down Expand Up @@ -3529,35 +3529,17 @@ void ByteCodeExprGen<Emitter>::emitCleanup() {

template <class Emitter>
unsigned
ByteCodeExprGen<Emitter>::collectBaseOffset(const RecordType *BaseType,
const RecordType *DerivedType) {
assert(BaseType);
assert(DerivedType);
const auto *FinalDecl = cast<CXXRecordDecl>(BaseType->getDecl());
const RecordDecl *CurDecl = DerivedType->getDecl();
const Record *CurRecord = getRecord(CurDecl);
assert(CurDecl && FinalDecl);

unsigned OffsetSum = 0;
for (;;) {
assert(CurRecord->getNumBases() > 0);
// One level up
for (const Record::Base &B : CurRecord->bases()) {
const auto *BaseDecl = cast<CXXRecordDecl>(B.Decl);

if (BaseDecl == FinalDecl || BaseDecl->isDerivedFrom(FinalDecl)) {
OffsetSum += B.Offset;
CurRecord = B.R;
CurDecl = BaseDecl;
break;
}
}
if (CurDecl == FinalDecl)
break;
}
ByteCodeExprGen<Emitter>::collectBaseOffset(const QualType BaseType,
const QualType DerivedType) {
const auto extractRecordDecl = [](QualType Ty) -> const CXXRecordDecl * {
if (const auto *PT = dyn_cast<PointerType>(Ty))
return PT->getPointeeType()->getAsCXXRecordDecl();
return Ty->getAsCXXRecordDecl();
};
const CXXRecordDecl *BaseDecl = extractRecordDecl(BaseType);
const CXXRecordDecl *DerivedDecl = extractRecordDecl(DerivedType);

assert(OffsetSum > 0);
return OffsetSum;
return Ctx.collectBaseOffset(BaseDecl, DerivedDecl);
}

/// Emit casts from a PrimType to another PrimType.
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/AST/Interp/ByteCodeExprGen.h
Original file line number Diff line number Diff line change
Expand Up @@ -283,8 +283,8 @@ class ByteCodeExprGen : public ConstStmtVisitor<ByteCodeExprGen<Emitter>, bool>,

bool emitRecordDestruction(const Record *R);
bool emitDestruction(const Descriptor *Desc);
unsigned collectBaseOffset(const RecordType *BaseType,
const RecordType *DerivedType);
unsigned collectBaseOffset(const QualType BaseType,
const QualType DerivedType);

protected:
/// Variable to storage mapping.
Expand Down
33 changes: 33 additions & 0 deletions clang/lib/AST/Interp/Context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -262,3 +262,36 @@ const Function *Context::getOrCreateFunction(const FunctionDecl *FD) {

return Func;
}

unsigned Context::collectBaseOffset(const RecordDecl *BaseDecl,
const RecordDecl *DerivedDecl) const {
assert(BaseDecl);
assert(DerivedDecl);
const auto *FinalDecl = cast<CXXRecordDecl>(BaseDecl);
const RecordDecl *CurDecl = DerivedDecl;
const Record *CurRecord = P->getOrCreateRecord(CurDecl);
assert(CurDecl && FinalDecl);

unsigned OffsetSum = 0;
for (;;) {
assert(CurRecord->getNumBases() > 0);
// One level up
for (const Record::Base &B : CurRecord->bases()) {
const auto *BaseDecl = cast<CXXRecordDecl>(B.Decl);

if (BaseDecl == FinalDecl || BaseDecl->isDerivedFrom(FinalDecl)) {
OffsetSum += B.Offset;
CurRecord = B.R;
CurDecl = BaseDecl;
break;
}
}
if (CurDecl == FinalDecl)
break;

// break;
}

assert(OffsetSum > 0);
return OffsetSum;
}
3 changes: 3 additions & 0 deletions clang/lib/AST/Interp/Context.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@ class Context final {
/// Returns the program. This is only needed for unittests.
Program &getProgram() const { return *P.get(); }

unsigned collectBaseOffset(const RecordDecl *BaseDecl,
const RecordDecl *DerivedDecl) const;

private:
/// Runs a function.
bool Run(State &Parent, const Function *Func, APValue &Result);
Expand Down

0 comments on commit bc8a4ea

Please sign in to comment.