[clang] 8df7e81 - Revert "[clang][Interp] Unify visiting variable declarations"
Timm Bäder via cfe-commits
cfe-commits at lists.llvm.org
Thu Jan 19 04:54:41 PST 2023
Author: Timm Bäder
Date: 2023-01-19T13:52:47+01:00
New Revision: 8df7e818de45c367dc497e28d4d0e5a1fa1e64fe
URL: https://github.com/llvm/llvm-project/commit/8df7e818de45c367dc497e28d4d0e5a1fa1e64fe
DIFF: https://github.com/llvm/llvm-project/commit/8df7e818de45c367dc497e28d4d0e5a1fa1e64fe.diff
LOG: Revert "[clang][Interp] Unify visiting variable declarations"
This reverts commit 5b54cf1a2892767fe949826a32d7820732028a38.
This breaks a builder: https://lab.llvm.org/buildbot/#/builders/5/builds/30854
Added:
Modified:
clang/lib/AST/Interp/ByteCodeExprGen.cpp
clang/lib/AST/Interp/ByteCodeExprGen.h
clang/lib/AST/Interp/ByteCodeStmtGen.cpp
clang/lib/AST/Interp/ByteCodeStmtGen.h
clang/lib/AST/Interp/Program.cpp
clang/lib/AST/Interp/Program.h
Removed:
################################################################################
diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index d0140863c5d7..f4bf162a1454 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -802,13 +802,6 @@ unsigned ByteCodeExprGen<Emitter>::allocateLocalPrimitive(DeclTy &&Src,
PrimType Ty,
bool IsConst,
bool IsExtended) {
- // Make sure we don't accidentally register the same decl twice.
- if (const auto *VD =
- dyn_cast_if_present<ValueDecl>(Src.dyn_cast<const Decl *>())) {
- assert(!P.getGlobal(VD));
- assert(Locals.find(VD) == Locals.end());
- }
-
// FIXME: There are cases where Src.is<Expr*>() is wrong, e.g.
// (int){12} in C. Consider using Expr::isTemporaryObject() instead
// or isa<MaterializeTemporaryExpr>().
@@ -824,14 +817,8 @@ unsigned ByteCodeExprGen<Emitter>::allocateLocalPrimitive(DeclTy &&Src,
template <class Emitter>
std::optional<unsigned>
ByteCodeExprGen<Emitter>::allocateLocal(DeclTy &&Src, bool IsExtended) {
- // Make sure we don't accidentally register the same decl twice.
- if (const auto *VD =
- dyn_cast_if_present<ValueDecl>(Src.dyn_cast<const Decl *>())) {
- assert(!P.getGlobal(VD));
- assert(Locals.find(VD) == Locals.end());
- }
-
QualType Ty;
+
const ValueDecl *Key = nullptr;
const Expr *Init = nullptr;
bool IsTemporary = false;
@@ -1141,87 +1128,41 @@ bool ByteCodeExprGen<Emitter>::visitExpr(const Expr *Exp) {
return this->emitRetValue(Exp);
}
-/// Toplevel visitDecl().
-/// We get here from evaluateAsInitializer().
-/// We need to evaluate the initializer and return its value.
template <class Emitter>
bool ByteCodeExprGen<Emitter>::visitDecl(const VarDecl *VD) {
- std::optional<PrimType> VarT = classify(VD->getType());
-
- // Create and initialize the variable.
- if (!this->visitVarDecl(VD))
- return false;
-
- // Get a pointer to the variable
- if (shouldBeGloballyIndexed(VD)) {
- auto GlobalIndex = P.getGlobal(VD);
- assert(GlobalIndex); // visitVarDecl() didn't return false.
- if (!this->emitGetPtrGlobal(*GlobalIndex, VD))
- return false;
- } else {
- auto Local = Locals.find(VD);
- assert(Local != Locals.end()); // Same here.
- if (!this->emitGetPtrLocal(Local->second.Offset, VD))
- return false;
- }
-
- // Return the value
- if (VarT) {
- if (!this->emitLoadPop(*VarT, VD))
- return false;
-
- return this->emitRet(*VarT, VD);
- }
-
- return this->emitRetValue(VD);
-}
-
-template <class Emitter>
-bool ByteCodeExprGen<Emitter>::visitVarDecl(const VarDecl *VD) {
const Expr *Init = VD->getInit();
- std::optional<PrimType> VarT = classify(VD->getType());
-
- if (shouldBeGloballyIndexed(VD)) {
- std::optional<unsigned> GlobalIndex = P.getOrCreateGlobal(VD, Init);
-
- if (!GlobalIndex)
- return this->bail(VD);
-
- assert(Init);
- {
- DeclScope<Emitter> LocalScope(this, VD);
- if (VarT) {
- if (!this->visit(Init))
+ if (std::optional<unsigned> I = P.createGlobal(VD, Init)) {
+ if (std::optional<PrimType> T = classify(VD->getType())) {
+ {
+ // Primitive declarations - compute the value and set it.
+ DeclScope<Emitter> LocalScope(this, VD);
+ if (!visit(Init))
return false;
- return this->emitInitGlobal(*VarT, *GlobalIndex, VD);
}
- return this->visitGlobalInitializer(Init, *GlobalIndex);
- }
- } else {
- DeclScope<Emitter> LocalScope(this, VD);
-
- if (VarT) {
- unsigned Offset = this->allocateLocalPrimitive(
- VD, *VarT, VD->getType().isConstQualified());
- // Compile the initializer in its own scope.
- if (Init) {
- ExprScope<Emitter> Scope(this);
- if (!this->visit(Init))
- return false;
- return this->emitSetLocal(*VarT, Offset, VD);
- }
+ // If the declaration is global, save the value for later use.
+ if (!this->emitDup(*T, VD))
+ return false;
+ if (!this->emitInitGlobal(*T, *I, VD))
+ return false;
+ return this->emitRet(*T, VD);
} else {
- if (std::optional<unsigned> Offset = this->allocateLocal(VD)) {
- if (Init)
- return this->visitLocalInitializer(Init, *Offset);
+ {
+ // Composite declarations - allocate storage and initialize it.
+ DeclScope<Emitter> LocalScope(this, VD);
+ if (!visitGlobalInitializer(Init, *I))
+ return false;
}
+
+ // Return a pointer to the global.
+ if (!this->emitGetPtrGlobal(*I, VD))
+ return false;
+ return this->emitRetValue(VD);
}
- return true;
}
- return false;
+ return this->bail(VD);
}
template <class Emitter>
diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.h b/clang/lib/AST/Interp/ByteCodeExprGen.h
index 4ae70543973e..a8736314c01d 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.h
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.h
@@ -132,8 +132,6 @@ class ByteCodeExprGen : public ConstStmtVisitor<ByteCodeExprGen<Emitter>, bool>,
bool visitArrayInitializer(const Expr *Initializer);
/// Compiles a record initializer.
bool visitRecordInitializer(const Expr *Initializer);
- /// Creates and initializes a variable from the given decl.
- bool visitVarDecl(const VarDecl *VD);
/// Visits an expression and converts it to a boolean.
bool visitBool(const Expr *E);
@@ -236,12 +234,6 @@ class ByteCodeExprGen : public ConstStmtVisitor<ByteCodeExprGen<Emitter>, bool>,
return T->getAsCXXRecordDecl();
}
- /// Returns whether we should create a global variable for the
- /// given VarDecl.
- bool shouldBeGloballyIndexed(const VarDecl *VD) const {
- return VD->hasGlobalStorage() || VD->isConstexpr();
- }
-
protected:
/// Variable to storage mapping.
llvm::DenseMap<const ValueDecl *, Scope::Local> Locals;
diff --git a/clang/lib/AST/Interp/ByteCodeStmtGen.cpp b/clang/lib/AST/Interp/ByteCodeStmtGen.cpp
index af97c57c98b7..60506a759f45 100644
--- a/clang/lib/AST/Interp/ByteCodeStmtGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeStmtGen.cpp
@@ -207,7 +207,7 @@ bool ByteCodeStmtGen<Emitter>::visitDeclStmt(const DeclStmt *DS) {
for (auto *D : DS->decls()) {
// Variable declarator.
if (auto *VD = dyn_cast<VarDecl>(D)) {
- if (!this->visitVarDecl(VD))
+ if (!visitVarDecl(VD))
return false;
continue;
}
@@ -391,6 +391,41 @@ bool ByteCodeStmtGen<Emitter>::visitContinueStmt(const ContinueStmt *S) {
return this->jump(*ContinueLabel);
}
+template <class Emitter>
+bool ByteCodeStmtGen<Emitter>::visitVarDecl(const VarDecl *VD) {
+ if (!VD->hasLocalStorage()) {
+ // No code generation required.
+ return true;
+ }
+
+ // Integers, pointers, primitives.
+ if (std::optional<PrimType> T = this->classify(VD->getType())) {
+ const Expr *Init = VD->getInit();
+
+ unsigned Offset =
+ this->allocateLocalPrimitive(VD, *T, VD->getType().isConstQualified());
+ // Compile the initializer in its own scope.
+ if (Init) {
+ ExprScope<Emitter> Scope(this);
+ if (!this->visit(Init))
+ return false;
+
+ return this->emitSetLocal(*T, Offset, VD);
+ }
+ return true;
+ }
+
+ // Composite types - allocate storage and initialize it.
+ if (std::optional<unsigned> Offset = this->allocateLocal(VD)) {
+ if (!VD->getInit())
+ return true;
+
+ return this->visitLocalInitializer(VD->getInit(), *Offset);
+ }
+
+ return this->bail(VD);
+}
+
namespace clang {
namespace interp {
diff --git a/clang/lib/AST/Interp/ByteCodeStmtGen.h b/clang/lib/AST/Interp/ByteCodeStmtGen.h
index 7b6aa56276c8..2385c3e55c2f 100644
--- a/clang/lib/AST/Interp/ByteCodeStmtGen.h
+++ b/clang/lib/AST/Interp/ByteCodeStmtGen.h
@@ -64,6 +64,7 @@ class ByteCodeStmtGen final : public ByteCodeExprGen<Emitter> {
bool visitContinueStmt(const ContinueStmt *S);
/// Compiles a variable declaration.
+ bool visitVarDecl(const VarDecl *VD);
private:
/// Type of the expression returned by the function.
diff --git a/clang/lib/AST/Interp/Program.cpp b/clang/lib/AST/Interp/Program.cpp
index 5305ddd8de18..067f6d90b6c1 100644
--- a/clang/lib/AST/Interp/Program.cpp
+++ b/clang/lib/AST/Interp/Program.cpp
@@ -125,12 +125,11 @@ std::optional<unsigned> Program::getGlobal(const ValueDecl *VD) {
return Index;
}
-std::optional<unsigned> Program::getOrCreateGlobal(const ValueDecl *VD,
- const Expr *Init) {
+std::optional<unsigned> Program::getOrCreateGlobal(const ValueDecl *VD) {
if (auto Idx = getGlobal(VD))
return Idx;
- if (auto Idx = createGlobal(VD, Init)) {
+ if (auto Idx = createGlobal(VD, nullptr)) {
GlobalIndices[VD] = *Idx;
return Idx;
}
@@ -158,7 +157,6 @@ std::optional<unsigned> Program::getOrCreateDummy(const ParmVarDecl *PD) {
std::optional<unsigned> Program::createGlobal(const ValueDecl *VD,
const Expr *Init) {
- assert(!getGlobal(VD));
bool IsStatic, IsExtern;
if (auto *Var = dyn_cast<VarDecl>(VD)) {
IsStatic = !Var->hasLocalStorage();
diff --git a/clang/lib/AST/Interp/Program.h b/clang/lib/AST/Interp/Program.h
index 5a80dd1ed748..f49ca6db13e1 100644
--- a/clang/lib/AST/Interp/Program.h
+++ b/clang/lib/AST/Interp/Program.h
@@ -79,8 +79,7 @@ class Program final {
std::optional<unsigned> getGlobal(const ValueDecl *VD);
/// Returns or creates a global an creates an index to it.
- std::optional<unsigned> getOrCreateGlobal(const ValueDecl *VD,
- const Expr *Init = nullptr);
+ std::optional<unsigned> getOrCreateGlobal(const ValueDecl *VD);
/// Returns or creates a dummy value for parameters.
std::optional<unsigned> getOrCreateDummy(const ParmVarDecl *PD);
More information about the cfe-commits
mailing list