diff --git a/gen/declarations.cpp b/gen/declarations.cpp index b1eeffb95d..f52a7dc176 100644 --- a/gen/declarations.cpp +++ b/gen/declarations.cpp @@ -256,10 +256,6 @@ class CodegenVisitor : public Visitor { if (decl->ir->isDefined()) return; - // skip external declarations (IR-declared lazily) - if (decl->storage_class & STCextern) - return; - if (decl->type->ty == TY::Terror) { error(decl->loc, "%s `%s` had semantic errors when compiling", decl->kind(), decl->toPrettyChars()); @@ -267,9 +263,6 @@ class CodegenVisitor : public Visitor { return; } - DtoResolveVariable(decl); - decl->ir->setDefined(); - // just forward aliases if (decl->aliasTuple) { Logger::println("aliasTuple"); @@ -277,14 +270,25 @@ class CodegenVisitor : public Visitor { return; } + if (!decl->canTakeAddressOf()) { + Logger::println("manifest constant, skipping"); + return; + } + // global variable if (decl->isDataseg()) { - Logger::println("data segment"); + // skip external declarations (IR-declared lazily) + if (decl->storage_class & STCextern) { + Logger::println("external global, skipping"); + return; + } - assert(!(decl->storage_class & STCmanifest) && - "manifest constant being codegen'd!"); + Logger::println("global variable"); assert(!irs->dcomputetarget); + DtoResolveVariable(decl); + decl->ir->setDefined(); + getIrGlobal(decl)->getValue(/*define=*/true); } } diff --git a/gen/llvmhelpers.cpp b/gen/llvmhelpers.cpp index 4ff6bf60bf..90ca639a8f 100644 --- a/gen/llvmhelpers.cpp +++ b/gen/llvmhelpers.cpp @@ -935,66 +935,63 @@ void DtoVarDeclaration(VarDeclaration *vd) { } } -DValue *DtoDeclarationExp(Dsymbol *declaration) { +void DtoDeclarationExp(Dsymbol *declaration) { IF_LOG Logger::print("DtoDeclarationExp: %s\n", declaration->toChars()); LOG_SCOPE; - if (VarDeclaration *vd = declaration->isVarDeclaration()) { + if (auto vd = declaration->isVarDeclaration()) { Logger::println("VarDeclaration"); - // if aliasTuple is set, this VarDecl is redone as an alias to another symbol - // this seems to be done to rewrite Tuple!(...) v; - // as a TupleDecl that contains a bunch of individual VarDecls if (vd->aliasTuple) { - return DtoDeclarationExp(vd->aliasTuple); + Logger::println("aliasTuple"); + DtoDeclarationExp(vd->toAlias()); + return; } - if (vd->storage_class & STCmanifest) { - IF_LOG Logger::println("Manifest constant, nothing to do."); - return nullptr; + if (!vd->canTakeAddressOf()) { + Logger::println("Manifest constant, nothing to do."); + return; } - // static - if (vd->isDataseg()) { + if (vd->isDataseg()) { // global variable Declaration_codegen(vd); - if (vd->storage_class & STCextern) { - DtoResolveVariable(vd); // make sure there's an IR declaration - } - } else { + } else { // local variable DtoVarDeclaration(vd); + if (vd->needsScopeDtor()) { + gIR->funcGen().scopes.pushVarDtorCleanup(vd); + } } - return makeVarDValue(vd->type, vd); - } - - if (StructDeclaration *s = declaration->isStructDeclaration()) { + } else if (auto cd = declaration->isClassDeclaration()) { + Logger::println("ClassDeclaration"); + Declaration_codegen(cd); + } else if (auto sd = declaration->isStructDeclaration()) { Logger::println("StructDeclaration"); - Declaration_codegen(s); - } else if (FuncDeclaration *f = declaration->isFuncDeclaration()) { + Declaration_codegen(sd); + } else if (auto fd = declaration->isFuncDeclaration()) { Logger::println("FuncDeclaration"); - Declaration_codegen(f); - } else if (ClassDeclaration *e = declaration->isClassDeclaration()) { - Logger::println("ClassDeclaration"); - Declaration_codegen(e); - } else if (AttribDeclaration *a = declaration->isAttribDeclaration()) { + Declaration_codegen(fd); + } else if (auto ad = declaration->isAttribDeclaration()) { Logger::println("AttribDeclaration"); // choose the right set in case this is a conditional declaration - if (auto d = include(a, nullptr)) { - for (unsigned i = 0; i < d->length; ++i) { - DtoDeclarationExp((*d)[i]); + if (auto d = include(ad, nullptr)) { + for (auto sym : *d) { + DtoDeclarationExp(sym); } } - } else if (TemplateMixin *m = declaration->isTemplateMixin()) { + } else if (auto tm = declaration->isTemplateMixin()) { Logger::println("TemplateMixin"); - for (Dsymbol *mdsym : *m->members) { - DtoDeclarationExp(mdsym); + for (auto sym : *tm->members) { + DtoDeclarationExp(sym); } - } else if (TupleDeclaration *tupled = declaration->isTupleDeclaration()) { + } else if (auto td = declaration->isTupleDeclaration()) { Logger::println("TupleDeclaration"); - assert(tupled->isexp && "Non-expression tuple decls not handled yet."); - assert(tupled->objects); - for (unsigned i = 0; i < tupled->objects->length; ++i) { - auto exp = static_cast((*tupled->objects)[i]); - DtoDeclarationExp(exp->s); + // mimicking `foreachVar()` + for (auto o : *td->objects) { + if (auto e = isExpression(o)) { + if (auto ve = e->isVarExp()) { + DtoDeclarationExp(ve->var); + } + } } } else { // Do nothing for template/alias/enum declarations and static @@ -1002,8 +999,6 @@ DValue *DtoDeclarationExp(Dsymbol *declaration) { // even bother to check. IF_LOG Logger::println("Ignoring Symbol: %s", declaration->kind()); } - - return nullptr; } // does pretty much the same as DtoDeclarationExp, except it doesn't initialize, diff --git a/gen/llvmhelpers.h b/gen/llvmhelpers.h index 1a340c5336..c3d207435c 100644 --- a/gen/llvmhelpers.h +++ b/gen/llvmhelpers.h @@ -113,7 +113,7 @@ void DtoResolveVariable(VarDeclaration *var); // declaration inside a declarationexp void DtoVarDeclaration(VarDeclaration *var); -DValue *DtoDeclarationExp(Dsymbol *declaration); +void DtoDeclarationExp(Dsymbol *declaration); LLValue *DtoRawVarDeclaration(VarDeclaration *var, LLValue *addr = nullptr); // initializer helpers diff --git a/gen/toir.cpp b/gen/toir.cpp index 39bd75a3d0..905cf00fb1 100644 --- a/gen/toir.cpp +++ b/gen/toir.cpp @@ -211,15 +211,6 @@ static void write_struct_literal(Loc loc, LLValue *mem, StructDeclaration *sd, } namespace { -void pushVarDtorCleanup(IRState *p, VarDeclaration *vd) { - llvm::BasicBlock *beginBB = p->insertBB(llvm::Twine("dtor.") + vd->toChars()); - - const auto savedInsertPoint = p->saveInsertPoint(); - p->ir->SetInsertPoint(beginBB); - toElemDtor(vd->edtor); - p->funcGen().scopes.pushCleanup(beginBB, p->scopebb()); -} - // Zero-extends a scalar i1 to an integer type, or creates a vector mask from an // i1 vector. DImValue *zextBool(LLValue *val, Type *to) { @@ -318,13 +309,7 @@ class ToElemVisitor : public Visitor { auto &PGO = gIR->funcGen().pgo; PGO.setCurrentStmt(e); - result = DtoDeclarationExp(e->declaration); - - if (auto vd = e->declaration->isVarDeclaration()) { - if (!vd->isDataseg() && vd->needsScopeDtor()) { - pushVarDtorCleanup(p, vd); - } - } + DtoDeclarationExp(e->declaration); } ////////////////////////////////////////////////////////////////////////////// @@ -838,7 +823,7 @@ class ToElemVisitor : public Visitor { if (delayedDtorVar) { delayedDtorVar->edtor = delayedDtorExp; - pushVarDtorCleanup(p, delayedDtorVar); + p->funcGen().scopes.pushVarDtorCleanup(delayedDtorVar); } return result; diff --git a/gen/trycatchfinally.cpp b/gen/trycatchfinally.cpp index fea4389d46..ef35715cc1 100644 --- a/gen/trycatchfinally.cpp +++ b/gen/trycatchfinally.cpp @@ -92,7 +92,7 @@ void TryCatchScope::emitCatchBodies(IRState &irs, llvm::Value *ehPtrSlot) { if (c->var) { // This will alloca if we haven't already and take care of nested refs // if there are any. - DtoDeclarationExp(c->var); + DtoVarDeclaration(c->var); // Copy the exception reference over from the _d_eh_enter_catch return // value. @@ -214,7 +214,7 @@ void emitBeginCatchMSVC(IRState &irs, Catch *ctch, // catchpad const auto savedInsertPoint = irs.saveInsertPoint(); irs.ir->SetInsertPoint(gIR->topallocapoint()); - DtoDeclarationExp(var); + DtoVarDeclaration(var); // catch handler will be outlined, so always treat as a nested reference exnObj = getIrValue(var); @@ -524,6 +524,17 @@ void TryCatchFinallyScopes::pushCleanup(llvm::BasicBlock *beginBlock, landingPadsPerCleanupScope.emplace_back(); } +void TryCatchFinallyScopes::pushVarDtorCleanup(VarDeclaration *vd) { + llvm::BasicBlock *beginBB = irs.insertBB(llvm::Twine("dtor.") + vd->toChars()); + + const auto savedInsertPoint = irs.saveInsertPoint(); + + irs.ir->SetInsertPoint(beginBB); + toElemDtor(vd->edtor); + + pushCleanup(beginBB, irs.scopebb()); +} + void TryCatchFinallyScopes::popCleanups(CleanupCursor targetScope) { assert(targetScope <= currentCleanupScope()); if (targetScope == currentCleanupScope()) diff --git a/gen/trycatchfinally.h b/gen/trycatchfinally.h index 5a3e26a623..07aeda7d3e 100644 --- a/gen/trycatchfinally.h +++ b/gen/trycatchfinally.h @@ -1,6 +1,6 @@ //===-- gen/trycatchfinally.h - Try/catch/finally scopes --------*- C++ -*-===// // -// LDC � the LLVM D compiler +// LDC – the LLVM D compiler // // This file is distributed under the BSD-style LDC license. See the LICENSE // file for details. @@ -16,6 +16,7 @@ class Identifier; struct IRState; class TryCatchStatement; +class VarDeclaration; namespace llvm { class AllocaInst; @@ -206,6 +207,8 @@ class TryCatchFinallyScopes { /// scope will branch to. void pushCleanup(llvm::BasicBlock *beginBlock, llvm::BasicBlock *endBlock); + void pushVarDtorCleanup(VarDeclaration *vd); + /// Terminates the current basic block with a branch to the cleanups needed /// for leaving the current scope and continuing execution at the target /// scope stack level.