Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion clang/lib/AST/ByteCode/ByteCodeEmitter.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ class ByteCodeEmitter {
/// Methods implemented by the compiler.
virtual bool visitFunc(const FunctionDecl *E) = 0;
virtual bool visitExpr(const Expr *E, bool DestroyToplevelScope) = 0;
virtual bool visitDeclAndReturn(const VarDecl *E, bool ConstantContext) = 0;
virtual bool visitDeclAndReturn(const VarDecl *VD, const Expr *Init,
bool ConstantContext) = 0;
virtual bool visit(const Expr *E) = 0;
virtual bool emitBool(bool V, const Expr *E) = 0;

Expand Down
21 changes: 10 additions & 11 deletions clang/lib/AST/ByteCode/Compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4714,7 +4714,8 @@ template <class Emitter>
VarCreationState Compiler<Emitter>::visitDecl(const VarDecl *VD,
bool IsConstexprUnknown) {

auto R = this->visitVarDecl(VD, /*Toplevel=*/true, IsConstexprUnknown);
auto R = this->visitVarDecl(VD, VD->getInit(), /*Toplevel=*/true,
IsConstexprUnknown);

if (R.notCreated())
return R;
Expand All @@ -4740,22 +4741,20 @@ VarCreationState Compiler<Emitter>::visitDecl(const VarDecl *VD,
/// We get here from evaluateAsInitializer().
/// We need to evaluate the initializer and return its value.
template <class Emitter>
bool Compiler<Emitter>::visitDeclAndReturn(const VarDecl *VD,
bool Compiler<Emitter>::visitDeclAndReturn(const VarDecl *VD, const Expr *Init,
bool ConstantContext) {

// We only create variables if we're evaluating in a constant context.
// Otherwise, just evaluate the initializer and return it.
if (!ConstantContext) {
DeclScope<Emitter> LS(this, VD);
const Expr *Init = VD->getInit();
if (!this->visit(Init))
return false;
return this->emitRet(classify(Init).value_or(PT_Ptr), VD) &&
LS.destroyLocals() && this->emitCheckAllocations(VD);
}

LocalScope<Emitter> VDScope(this, VD);
if (!this->visitVarDecl(VD, /*Toplevel=*/true))
if (!this->visitVarDecl(VD, Init, /*Toplevel=*/true))
return false;

OptPrimType VarT = classify(VD->getType());
Expand Down Expand Up @@ -4802,9 +4801,9 @@ bool Compiler<Emitter>::visitDeclAndReturn(const VarDecl *VD,
}

template <class Emitter>
VarCreationState Compiler<Emitter>::visitVarDecl(const VarDecl *VD,
bool Toplevel,
bool IsConstexprUnknown) {
VarCreationState
Compiler<Emitter>::visitVarDecl(const VarDecl *VD, const Expr *Init,
bool Toplevel, bool IsConstexprUnknown) {
// We don't know what to do with these, so just return false.
if (VD->getType().isNull())
return false;
Expand All @@ -4814,7 +4813,6 @@ VarCreationState Compiler<Emitter>::visitVarDecl(const VarDecl *VD,
if (!this->isActive())
return VarCreationState::NotCreated();

const Expr *Init = VD->getInit();
OptPrimType VarT = classify(VD->getType());

if (Init && Init->isValueDependent())
Expand Down Expand Up @@ -5488,7 +5486,8 @@ template <class Emitter>
bool Compiler<Emitter>::maybeEmitDeferredVarInit(const VarDecl *VD) {
if (auto *DD = dyn_cast_if_present<DecompositionDecl>(VD)) {
for (auto *BD : DD->flat_bindings())
if (auto *KD = BD->getHoldingVar(); KD && !this->visitVarDecl(KD))
if (auto *KD = BD->getHoldingVar();
KD && !this->visitVarDecl(KD, KD->getInit()))
return false;
}
return true;
Expand Down Expand Up @@ -5552,7 +5551,7 @@ bool Compiler<Emitter>::visitDeclStmt(const DeclStmt *DS,
const auto *VD = dyn_cast<VarDecl>(D);
if (!VD)
return false;
if (!this->visitVarDecl(VD))
if (!this->visitVarDecl(VD, VD->getInit()))
return false;

// Register decomposition decl holding vars.
Expand Down
6 changes: 4 additions & 2 deletions clang/lib/AST/ByteCode/Compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,8 @@ class Compiler : public ConstStmtVisitor<Compiler<Emitter>, bool>,
bool visitExpr(const Expr *E, bool DestroyToplevelScope) override;
bool visitFunc(const FunctionDecl *F) override;

bool visitDeclAndReturn(const VarDecl *VD, bool ConstantContext) override;
bool visitDeclAndReturn(const VarDecl *VD, const Expr *Init,
bool ConstantContext) override;

protected:
/// Emits scope cleanup instructions.
Expand Down Expand Up @@ -303,7 +304,8 @@ class Compiler : public ConstStmtVisitor<Compiler<Emitter>, bool>,
/// intact.
bool delegate(const Expr *E);
/// Creates and initializes a variable from the given decl.
VarCreationState visitVarDecl(const VarDecl *VD, bool Toplevel = false,
VarCreationState visitVarDecl(const VarDecl *VD, const Expr *Init,
bool Toplevel = false,
bool IsConstexprUnknown = false);
VarCreationState visitDecl(const VarDecl *VD,
bool IsConstexprUnknown = false);
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/AST/ByteCode/Context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ bool Context::evaluate(State &Parent, const Expr *E, APValue &Result,
}

bool Context::evaluateAsInitializer(State &Parent, const VarDecl *VD,
APValue &Result) {
const Expr *Init, APValue &Result) {
++EvalID;
bool Recursing = !Stk.empty();
size_t StackSizeBefore = Stk.size();
Expand All @@ -135,7 +135,7 @@ bool Context::evaluateAsInitializer(State &Parent, const VarDecl *VD,
bool CheckGlobalInitialized =
shouldBeGloballyIndexed(VD) &&
(VD->getType()->isRecordType() || VD->getType()->isArrayType());
auto Res = C.interpretDecl(VD, CheckGlobalInitialized);
auto Res = C.interpretDecl(VD, Init, CheckGlobalInitialized);
if (Res.isInvalid()) {
C.cleanup();
Stk.clearTo(StackSizeBefore);
Expand Down
3 changes: 2 additions & 1 deletion clang/lib/AST/ByteCode/Context.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ class Context final {
ConstantExprKind Kind);

/// Evaluates a toplevel initializer.
bool evaluateAsInitializer(State &Parent, const VarDecl *VD, APValue &Result);
bool evaluateAsInitializer(State &Parent, const VarDecl *VD, const Expr *Init,
APValue &Result);

bool evaluateCharRange(State &Parent, const Expr *SizeExpr,
const Expr *PtrExpr, APValue &Result);
Expand Down
7 changes: 4 additions & 3 deletions clang/lib/AST/ByteCode/EvalEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,15 @@ EvaluationResult EvalEmitter::interpretExpr(const Expr *E,
return std::move(this->EvalResult);
}

EvaluationResult EvalEmitter::interpretDecl(const VarDecl *VD,
EvaluationResult EvalEmitter::interpretDecl(const VarDecl *VD, const Expr *Init,
bool CheckFullyInitialized) {
this->CheckFullyInitialized = CheckFullyInitialized;
S.EvaluatingDecl = VD;
S.setEvalLocation(VD->getLocation());
EvalResult.setSource(VD);

if (const Expr *Init = VD->getAnyInitializer()) {
// FIXME: I think Init is never null.
if (Init) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could add an assert and if it crashes, then this is incorrect, it does not prove it but it could show the negative and then you have a test case.

QualType T = VD->getType();
this->ConvertResultToRValue = !Init->isGLValue() && !T->isPointerType() &&
!T->isObjCObjectPointerType();
Expand All @@ -65,7 +66,7 @@ EvaluationResult EvalEmitter::interpretDecl(const VarDecl *VD,

EvalResult.setSource(VD);

if (!this->visitDeclAndReturn(VD, S.inConstantContext()))
if (!this->visitDeclAndReturn(VD, Init, S.inConstantContext()))
EvalResult.setInvalid();

S.EvaluatingDecl = nullptr;
Expand Down
6 changes: 4 additions & 2 deletions clang/lib/AST/ByteCode/EvalEmitter.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ class EvalEmitter : public SourceMapper {
EvaluationResult interpretExpr(const Expr *E,
bool ConvertResultToRValue = false,
bool DestroyToplevelScope = false);
EvaluationResult interpretDecl(const VarDecl *VD, bool CheckFullyInitialized);
EvaluationResult interpretDecl(const VarDecl *VD, const Expr *Init,
bool CheckFullyInitialized);
/// Interpret the given Expr to a Pointer.
EvaluationResult interpretAsPointer(const Expr *E, PtrCallback PtrCB);
/// Interpret the given expression as if it was in the body of the given
Expand All @@ -59,7 +60,8 @@ class EvalEmitter : public SourceMapper {

/// Methods implemented by the compiler.
virtual bool visitExpr(const Expr *E, bool DestroyToplevelScope) = 0;
virtual bool visitDeclAndReturn(const VarDecl *VD, bool ConstantContext) = 0;
virtual bool visitDeclAndReturn(const VarDecl *VD, const Expr *Init,
bool ConstantContext) = 0;
virtual bool visitFunc(const FunctionDecl *F) = 0;
virtual bool visit(const Expr *E) = 0;
virtual bool emitBool(bool V, const Expr *E) = 0;
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/AST/ExprConstant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17755,7 +17755,7 @@ bool Expr::EvaluateAsInitializer(APValue &Value, const ASTContext &Ctx,

if (Info.EnableNewConstInterp) {
auto &InterpCtx = const_cast<ASTContext &>(Ctx).getInterpContext();
if (!InterpCtx.evaluateAsInitializer(Info, VD, Value))
if (!InterpCtx.evaluateAsInitializer(Info, VD, this, Value))
return false;

return CheckConstantExpression(Info, DeclLoc, DeclTy, Value,
Expand Down
1 change: 1 addition & 0 deletions clang/test/Modules/added-visible-decls.cppm
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// RUN: %clang_cc1 -std=c++20 %t/b.cppm -emit-reduced-module-interface -o %t/b.pcm -fprebuilt-module-path=%t
// RUN: %clang_cc1 -std=c++20 %t/c.cppm -emit-reduced-module-interface -o %t/c.pcm -fprebuilt-module-path=%t
// RUN: %clang_cc1 -std=c++20 %t/d.cpp -fprebuilt-module-path=%t -fsyntax-only -verify
// RUN: %clang_cc1 -std=c++20 %t/d.cpp -fprebuilt-module-path=%t -fsyntax-only -verify -fexperimental-new-constant-interpreter
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ChuanqiXu9 Is it okay to add this line?


//--- a.h
template <typename T>
Expand Down