From: Timm Bäder Date: Thu, 19 Jan 2023 12:52:05 +0000 (+0100) Subject: Revert "[clang][Interp] Unify visiting variable declarations" X-Git-Tag: upstream/17.0.6~20448 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=8df7e818de45c367dc497e28d4d0e5a1fa1e64fe;p=platform%2Fupstream%2Fllvm.git Revert "[clang][Interp] Unify visiting variable declarations" This reverts commit 5b54cf1a2892767fe949826a32d7820732028a38. This breaks a builder: https://lab.llvm.org/buildbot/#/builders/5/builds/30854 --- diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index d014086..f4bf162 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -802,13 +802,6 @@ unsigned ByteCodeExprGen::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(Src.dyn_cast())) { - assert(!P.getGlobal(VD)); - assert(Locals.find(VD) == Locals.end()); - } - // FIXME: There are cases where Src.is() is wrong, e.g. // (int){12} in C. Consider using Expr::isTemporaryObject() instead // or isa(). @@ -824,14 +817,8 @@ unsigned ByteCodeExprGen::allocateLocalPrimitive(DeclTy &&Src, template std::optional ByteCodeExprGen::allocateLocal(DeclTy &&Src, bool IsExtended) { - // Make sure we don't accidentally register the same decl twice. - if (const auto *VD = - dyn_cast_if_present(Src.dyn_cast())) { - 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::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 bool ByteCodeExprGen::visitDecl(const VarDecl *VD) { - std::optional 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 -bool ByteCodeExprGen::visitVarDecl(const VarDecl *VD) { const Expr *Init = VD->getInit(); - std::optional VarT = classify(VD->getType()); - - if (shouldBeGloballyIndexed(VD)) { - std::optional GlobalIndex = P.getOrCreateGlobal(VD, Init); - - if (!GlobalIndex) - return this->bail(VD); - - assert(Init); - { - DeclScope LocalScope(this, VD); - if (VarT) { - if (!this->visit(Init)) + if (std::optional I = P.createGlobal(VD, Init)) { + if (std::optional T = classify(VD->getType())) { + { + // Primitive declarations - compute the value and set it. + DeclScope LocalScope(this, VD); + if (!visit(Init)) return false; - return this->emitInitGlobal(*VarT, *GlobalIndex, VD); } - return this->visitGlobalInitializer(Init, *GlobalIndex); - } - } else { - DeclScope LocalScope(this, VD); - - if (VarT) { - unsigned Offset = this->allocateLocalPrimitive( - VD, *VarT, VD->getType().isConstQualified()); - // Compile the initializer in its own scope. - if (Init) { - ExprScope 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 Offset = this->allocateLocal(VD)) { - if (Init) - return this->visitLocalInitializer(Init, *Offset); + { + // Composite declarations - allocate storage and initialize it. + DeclScope 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 diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.h b/clang/lib/AST/Interp/ByteCodeExprGen.h index 4ae7054..a873631 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.h +++ b/clang/lib/AST/Interp/ByteCodeExprGen.h @@ -132,8 +132,6 @@ protected: 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 @@ private: 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 Locals; diff --git a/clang/lib/AST/Interp/ByteCodeStmtGen.cpp b/clang/lib/AST/Interp/ByteCodeStmtGen.cpp index af97c57..60506a7 100644 --- a/clang/lib/AST/Interp/ByteCodeStmtGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeStmtGen.cpp @@ -207,7 +207,7 @@ bool ByteCodeStmtGen::visitDeclStmt(const DeclStmt *DS) { for (auto *D : DS->decls()) { // Variable declarator. if (auto *VD = dyn_cast(D)) { - if (!this->visitVarDecl(VD)) + if (!visitVarDecl(VD)) return false; continue; } @@ -391,6 +391,41 @@ bool ByteCodeStmtGen::visitContinueStmt(const ContinueStmt *S) { return this->jump(*ContinueLabel); } +template +bool ByteCodeStmtGen::visitVarDecl(const VarDecl *VD) { + if (!VD->hasLocalStorage()) { + // No code generation required. + return true; + } + + // Integers, pointers, primitives. + if (std::optional 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 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 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 7b6aa56..2385c3e 100644 --- a/clang/lib/AST/Interp/ByteCodeStmtGen.h +++ b/clang/lib/AST/Interp/ByteCodeStmtGen.h @@ -64,6 +64,7 @@ private: 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 5305ddd..067f6d9 100644 --- a/clang/lib/AST/Interp/Program.cpp +++ b/clang/lib/AST/Interp/Program.cpp @@ -125,12 +125,11 @@ std::optional Program::getGlobal(const ValueDecl *VD) { return Index; } -std::optional Program::getOrCreateGlobal(const ValueDecl *VD, - const Expr *Init) { +std::optional 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 Program::getOrCreateDummy(const ParmVarDecl *PD) { std::optional Program::createGlobal(const ValueDecl *VD, const Expr *Init) { - assert(!getGlobal(VD)); bool IsStatic, IsExtern; if (auto *Var = dyn_cast(VD)) { IsStatic = !Var->hasLocalStorage(); diff --git a/clang/lib/AST/Interp/Program.h b/clang/lib/AST/Interp/Program.h index 5a80dd1..f49ca6d 100644 --- a/clang/lib/AST/Interp/Program.h +++ b/clang/lib/AST/Interp/Program.h @@ -79,8 +79,7 @@ public: std::optional getGlobal(const ValueDecl *VD); /// Returns or creates a global an creates an index to it. - std::optional getOrCreateGlobal(const ValueDecl *VD, - const Expr *Init = nullptr); + std::optional getOrCreateGlobal(const ValueDecl *VD); /// Returns or creates a dummy value for parameters. std::optional getOrCreateDummy(const ParmVarDecl *PD);