aboutsummaryrefslogtreecommitdiff
path: root/gcc/d/dmd/statement.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/d/dmd/statement.c')
-rw-r--r--gcc/d/dmd/statement.c1793
1 files changed, 0 insertions, 1793 deletions
diff --git a/gcc/d/dmd/statement.c b/gcc/d/dmd/statement.c
deleted file mode 100644
index 1f8e512..0000000
--- a/gcc/d/dmd/statement.c
+++ /dev/null
@@ -1,1793 +0,0 @@
-
-/* Compiler implementation of the D programming language
- * Copyright (C) 1999-2021 by The D Language Foundation, All Rights Reserved
- * written by Walter Bright
- * http://www.digitalmars.com
- * Distributed under the Boost Software License, Version 1.0.
- * http://www.boost.org/LICENSE_1_0.txt
- * https://github.com/D-Programming-Language/dmd/blob/master/src/statement.c
- */
-
-#include "root/dsystem.h"
-
-#include "statement.h"
-#include "errors.h"
-#include "expression.h"
-#include "cond.h"
-#include "init.h"
-#include "staticassert.h"
-#include "scope.h"
-#include "declaration.h"
-#include "aggregate.h"
-#include "id.h"
-#include "hdrgen.h"
-#include "parse.h"
-#include "template.h"
-#include "attrib.h"
-#include "import.h"
-
-bool walkPostorder(Statement *s, StoppableVisitor *v);
-StorageClass mergeFuncAttrs(StorageClass s1, FuncDeclaration *f);
-bool checkEscapeRef(Scope *sc, Expression *e, bool gag);
-VarDeclaration *copyToTemp(StorageClass stc, const char *name, Expression *e);
-Statement *makeTupleForeachStatic(Scope *sc, ForeachStatement *fs, bool needExpansion);
-bool expressionsToString(OutBuffer &buf, Scope *sc, Expressions *exps);
-
-Identifier *fixupLabelName(Scope *sc, Identifier *ident)
-{
- unsigned flags = (sc->flags & SCOPEcontract);
- const char *id = ident->toChars();
- if (flags && flags != SCOPEinvariant &&
- !(id[0] == '_' && id[1] == '_'))
- {
- /* CTFE requires FuncDeclaration::labtab for the interpretation.
- * So fixing the label name inside in/out contracts is necessary
- * for the uniqueness in labtab.
- */
- const char *prefix = flags == SCOPErequire ? "__in_" : "__out_";
- OutBuffer buf;
- buf.printf("%s%s", prefix, ident->toChars());
-
- const char *name = buf.extractChars();
- ident = Identifier::idPool(name);
- }
- return ident;
-}
-
-LabelStatement *checkLabeledLoop(Scope *sc, Statement *statement)
-{
- if (sc->slabel && sc->slabel->statement == statement)
- {
- return sc->slabel;
- }
- return NULL;
-}
-
-/***********************************************************
- * Check an assignment is used as a condition.
- * Intended to be use before the `semantic` call on `e`.
- * Params:
- * e = condition expression which is not yet run semantic analysis.
- * Returns:
- * `e` or ErrorExp.
- */
-Expression *checkAssignmentAsCondition(Expression *e)
-{
- Expression *ec = e;
- while (ec->op == TOKcomma)
- ec = ((CommaExp *)ec)->e2;
- if (ec->op == TOKassign)
- {
- ec->error("assignment cannot be used as a condition, perhaps == was meant?");
- return new ErrorExp();
- }
- return e;
-}
-
-/// Return a type identifier reference to 'object.Throwable'
-TypeIdentifier *getThrowable()
-{
- TypeIdentifier *tid = new TypeIdentifier(Loc(), Id::empty);
- tid->addIdent(Id::object);
- tid->addIdent(Id::Throwable);
- return tid;
-}
-
-/******************************** Statement ***************************/
-
-Statement::Statement(Loc loc)
- : loc(loc)
-{
- // If this is an in{} contract scope statement (skip for determining
- // inlineStatus of a function body for header content)
-}
-
-Statement *Statement::syntaxCopy()
-{
- assert(0);
- return NULL;
-}
-
-/*************************************
- * Do syntax copy of an array of Statement's.
- */
-Statements *Statement::arraySyntaxCopy(Statements *a)
-{
- Statements *b = NULL;
- if (a)
- {
- b = a->copy();
- for (size_t i = 0; i < a->length; i++)
- {
- Statement *s = (*a)[i];
- (*b)[i] = s ? s->syntaxCopy() : NULL;
- }
- }
- return b;
-}
-
-void Statement::print()
-{
- fprintf(stderr, "%s\n", toChars());
- fflush(stderr);
-}
-
-const char *Statement::toChars()
-{
- HdrGenState hgs;
-
- OutBuffer buf;
- ::toCBuffer(this, &buf, &hgs);
- return buf.extractChars();
-}
-
-
-void Statement::error(const char *format, ...)
-{
- va_list ap;
- va_start(ap, format);
- ::verror(loc, format, ap);
- va_end( ap );
-}
-
-void Statement::warning(const char *format, ...)
-{
- va_list ap;
- va_start(ap, format);
- ::vwarning(loc, format, ap);
- va_end( ap );
-}
-
-void Statement::deprecation(const char *format, ...)
-{
- va_list ap;
- va_start(ap, format);
- ::vdeprecation(loc, format, ap);
- va_end( ap );
-}
-
-bool Statement::hasBreak()
-{
- //printf("Statement::hasBreak()\n");
- return false;
-}
-
-bool Statement::hasContinue()
-{
- return false;
-}
-
-/* ============================================== */
-// true if statement uses exception handling
-
-bool Statement::usesEH()
-{
- class UsesEH : public StoppableVisitor
- {
- public:
- void visit(Statement *) {}
- void visit(TryCatchStatement *) { stop = true; }
- void visit(TryFinallyStatement *) { stop = true; }
- void visit(ScopeGuardStatement *) { stop = true; }
- void visit(SynchronizedStatement *) { stop = true; }
- };
-
- UsesEH ueh;
- return walkPostorder(this, &ueh);
-}
-
-/* ============================================== */
-// true if statement 'comes from' somewhere else, like a goto
-
-bool Statement::comeFrom()
-{
- class ComeFrom : public StoppableVisitor
- {
- public:
- void visit(Statement *) {}
- void visit(CaseStatement *) { stop = true; }
- void visit(DefaultStatement *) { stop = true; }
- void visit(LabelStatement *) { stop = true; }
- void visit(AsmStatement *) { stop = true; }
- };
-
- ComeFrom cf;
- return walkPostorder(this, &cf);
-}
-
-/* ============================================== */
-// Return true if statement has executable code.
-
-bool Statement::hasCode()
-{
- class HasCode : public StoppableVisitor
- {
- public:
- void visit(Statement *)
- {
- stop = true;
- }
-
- void visit(ExpStatement *s)
- {
- if (s->exp != NULL)
- {
- stop = s->exp->hasCode();
- }
- }
-
- void visit(CompoundStatement *) {}
- void visit(ScopeStatement *) {}
- void visit(ImportStatement *) {}
- };
-
- HasCode hc;
- return walkPostorder(this, &hc);
-}
-
-Statement *Statement::last()
-{
- return this;
-}
-
-/****************************************
- * If this statement has code that needs to run in a finally clause
- * at the end of the current scope, return that code in the form of
- * a Statement.
- * Output:
- * *sentry code executed upon entry to the scope
- * *sexception code executed upon exit from the scope via exception
- * *sfinally code executed in finally block
- */
-
-Statement *Statement::scopeCode(Scope *, Statement **sentry, Statement **sexception, Statement **sfinally)
-{
- //printf("Statement::scopeCode()\n");
- //print();
- *sentry = NULL;
- *sexception = NULL;
- *sfinally = NULL;
- return this;
-}
-
-/*********************************
- * Flatten out the scope by presenting the statement
- * as an array of statements.
- * Returns NULL if no flattening necessary.
- */
-
-Statements *Statement::flatten(Scope *)
-{
- return NULL;
-}
-
-
-/******************************** ErrorStatement ***************************/
-
-ErrorStatement::ErrorStatement()
- : Statement(Loc())
-{
- assert(global.gaggedErrors || global.errors);
-}
-
-Statement *ErrorStatement::syntaxCopy()
-{
- return this;
-}
-
-/******************************** PeelStatement ***************************/
-
-PeelStatement::PeelStatement(Statement *s)
- : Statement(s->loc)
-{
- this->s = s;
-}
-
-/******************************** ExpStatement ***************************/
-
-ExpStatement::ExpStatement(Loc loc, Expression *exp)
- : Statement(loc)
-{
- this->exp = exp;
-}
-
-ExpStatement::ExpStatement(Loc loc, Dsymbol *declaration)
- : Statement(loc)
-{
- this->exp = new DeclarationExp(loc, declaration);
-}
-
-ExpStatement *ExpStatement::create(Loc loc, Expression *exp)
-{
- return new ExpStatement(loc, exp);
-}
-
-Statement *ExpStatement::syntaxCopy()
-{
- return new ExpStatement(loc, exp ? exp->syntaxCopy() : NULL);
-}
-
-Statement *ExpStatement::scopeCode(Scope *, Statement **sentry, Statement **sexception, Statement **sfinally)
-{
- //printf("ExpStatement::scopeCode()\n");
- //print();
-
- *sentry = NULL;
- *sexception = NULL;
- *sfinally = NULL;
-
- if (exp)
- {
- if (exp->op == TOKdeclaration)
- {
- DeclarationExp *de = (DeclarationExp *)(exp);
- VarDeclaration *v = de->declaration->isVarDeclaration();
- if (v && !v->isDataseg())
- {
- if (v->needsScopeDtor())
- {
- //printf("dtor is: "); v->edtor->print();
- *sfinally = new DtorExpStatement(loc, v->edtor, v);
- v->storage_class |= STCnodtor; // don't add in dtor again
- }
- }
- }
- }
- return this;
-}
-
-/****************************************
- * Convert TemplateMixin members (== Dsymbols) to Statements.
- */
-Statement *toStatement(Dsymbol *s)
-{
- class ToStmt : public Visitor
- {
- public:
- Statement *result;
-
- ToStmt()
- {
- this->result = NULL;
- }
-
- Statement *visitMembers(Loc loc, Dsymbols *a)
- {
- if (!a)
- return NULL;
-
- Statements *statements = new Statements();
- for (size_t i = 0; i < a->length; i++)
- {
- statements->push(toStatement((*a)[i]));
- }
- return new CompoundStatement(loc, statements);
- }
-
- void visit(Dsymbol *s)
- {
- ::error(Loc(), "Internal Compiler Error: cannot mixin %s %s\n", s->kind(), s->toChars());
- result = new ErrorStatement();
- }
-
- void visit(TemplateMixin *tm)
- {
- Statements *a = new Statements();
- for (size_t i = 0; i < tm->members->length; i++)
- {
- Statement *s = toStatement((*tm->members)[i]);
- if (s)
- a->push(s);
- }
- result = new CompoundStatement(tm->loc, a);
- }
-
- /* An actual declaration symbol will be converted to DeclarationExp
- * with ExpStatement.
- */
- Statement *declStmt(Dsymbol *s)
- {
- DeclarationExp *de = new DeclarationExp(s->loc, s);
- de->type = Type::tvoid; // avoid repeated semantic
- return new ExpStatement(s->loc, de);
- }
- void visit(VarDeclaration *d) { result = declStmt(d); }
- void visit(AggregateDeclaration *d) { result = declStmt(d); }
- void visit(FuncDeclaration *d) { result = declStmt(d); }
- void visit(EnumDeclaration *d) { result = declStmt(d); }
- void visit(AliasDeclaration *d) { result = declStmt(d); }
- void visit(TemplateDeclaration *d) { result = declStmt(d); }
-
- /* All attributes have been already picked by the semantic analysis of
- * 'bottom' declarations (function, struct, class, etc).
- * So we don't have to copy them.
- */
- void visit(StorageClassDeclaration *d) { result = visitMembers(d->loc, d->decl); }
- void visit(DeprecatedDeclaration *d) { result = visitMembers(d->loc, d->decl); }
- void visit(LinkDeclaration *d) { result = visitMembers(d->loc, d->decl); }
- void visit(ProtDeclaration *d) { result = visitMembers(d->loc, d->decl); }
- void visit(AlignDeclaration *d) { result = visitMembers(d->loc, d->decl); }
- void visit(UserAttributeDeclaration *d) { result = visitMembers(d->loc, d->decl); }
- void visit(ForwardingAttribDeclaration *d) { result = visitMembers(d->loc, d->decl); }
-
- void visit(StaticAssert *) {}
- void visit(Import *) {}
- void visit(PragmaDeclaration *) {}
-
- void visit(ConditionalDeclaration *d)
- {
- result = visitMembers(d->loc, d->include(NULL));
- }
-
- void visit(StaticForeachDeclaration *d)
- {
- assert(d->sfe && !!d->sfe->aggrfe ^ !!d->sfe->rangefe);
- result = visitMembers(d->loc, d->include(NULL));
- }
-
- void visit(CompileDeclaration *d)
- {
- result = visitMembers(d->loc, d->include(NULL));
- }
- };
-
- if (!s)
- return NULL;
-
- ToStmt v;
- s->accept(&v);
- return v.result;
-}
-
-Statements *ExpStatement::flatten(Scope *sc)
-{
- /* Bugzilla 14243: expand template mixin in statement scope
- * to handle variable destructors.
- */
- if (exp && exp->op == TOKdeclaration)
- {
- Dsymbol *d = ((DeclarationExp *)exp)->declaration;
- if (TemplateMixin *tm = d->isTemplateMixin())
- {
- Expression *e = expressionSemantic(exp, sc);
- if (e->op == TOKerror || tm->errors)
- {
- Statements *a = new Statements();
- a->push(new ErrorStatement());
- return a;
- }
- assert(tm->members);
-
- Statement *s = toStatement(tm);
- Statements *a = new Statements();
- a->push(s);
- return a;
- }
- }
- return NULL;
-}
-
-/******************************** DtorExpStatement ***************************/
-
-DtorExpStatement::DtorExpStatement(Loc loc, Expression *exp, VarDeclaration *v)
- : ExpStatement(loc, exp)
-{
- this->var = v;
-}
-
-Statement *DtorExpStatement::syntaxCopy()
-{
- return new DtorExpStatement(loc, exp ? exp->syntaxCopy() : NULL, var);
-}
-
-/******************************** CompileStatement ***************************/
-
-CompileStatement::CompileStatement(Loc loc, Expression *exp)
- : Statement(loc)
-{
- this->exps = new Expressions();
- this->exps->push(exp);
-}
-
-CompileStatement::CompileStatement(Loc loc, Expressions *exps)
- : Statement(loc)
-{
- this->exps = exps;
-}
-
-Statement *CompileStatement::syntaxCopy()
-{
- return new CompileStatement(loc, Expression::arraySyntaxCopy(exps));
-}
-
-static Statements *errorStatements()
-{
- Statements *a = new Statements();
- a->push(new ErrorStatement());
- return a;
-}
-
-static Statements *compileIt(CompileStatement *cs, Scope *sc)
-{
- //printf("CompileStatement::compileIt() %s\n", exp->toChars());
- OutBuffer buf;
- if (expressionsToString(buf, sc, cs->exps))
- return errorStatements();
-
- unsigned errors = global.errors;
- const size_t len = buf.length();
- const char *str = buf.extractChars();
- Parser p(cs->loc, sc->_module, (const utf8_t *)str, len, false);
- p.nextToken();
-
- Statements *a = new Statements();
- while (p.token.value != TOKeof)
- {
- Statement *s = p.parseStatement(PSsemi | PScurlyscope);
- if (!s || global.errors != errors)
- return errorStatements();
- a->push(s);
- }
- return a;
-}
-
-Statements *CompileStatement::flatten(Scope *sc)
-{
- //printf("CompileStatement::flatten() %s\n", exp->toChars());
- return compileIt(this, sc);
-}
-
-/******************************** CompoundStatement ***************************/
-
-CompoundStatement::CompoundStatement(Loc loc, Statements *s)
- : Statement(loc)
-{
- statements = s;
-}
-
-CompoundStatement::CompoundStatement(Loc loc, Statement *s1, Statement *s2)
- : Statement(loc)
-{
- statements = new Statements();
- statements->reserve(2);
- statements->push(s1);
- statements->push(s2);
-}
-
-CompoundStatement::CompoundStatement(Loc loc, Statement *s1)
- : Statement(loc)
-{
- statements = new Statements();
- statements->push(s1);
-}
-
-CompoundStatement *CompoundStatement::create(Loc loc, Statement *s1, Statement *s2)
-{
- return new CompoundStatement(loc, s1, s2);
-}
-
-Statement *CompoundStatement::syntaxCopy()
-{
- return new CompoundStatement(loc, Statement::arraySyntaxCopy(statements));
-}
-
-Statements *CompoundStatement::flatten(Scope *)
-{
- return statements;
-}
-
-ReturnStatement *CompoundStatement::isReturnStatement()
-{
- ReturnStatement *rs = NULL;
-
- for (size_t i = 0; i < statements->length; i++)
- {
- Statement *s = (*statements)[i];
- if (s)
- {
- rs = s->isReturnStatement();
- if (rs)
- break;
- }
- }
- return rs;
-}
-
-Statement *CompoundStatement::last()
-{
- Statement *s = NULL;
-
- for (size_t i = statements->length; i; --i)
- { s = (*statements)[i - 1];
- if (s)
- {
- s = s->last();
- if (s)
- break;
- }
- }
- return s;
-}
-
-/******************************** CompoundDeclarationStatement ***************************/
-
-CompoundDeclarationStatement::CompoundDeclarationStatement(Loc loc, Statements *s)
- : CompoundStatement(loc, s)
-{
- statements = s;
-}
-
-Statement *CompoundDeclarationStatement::syntaxCopy()
-{
- Statements *a = new Statements();
- a->setDim(statements->length);
- for (size_t i = 0; i < statements->length; i++)
- {
- Statement *s = (*statements)[i];
- (*a)[i] = s ? s->syntaxCopy() : NULL;
- }
- return new CompoundDeclarationStatement(loc, a);
-}
-
-/**************************** UnrolledLoopStatement ***************************/
-
-UnrolledLoopStatement::UnrolledLoopStatement(Loc loc, Statements *s)
- : Statement(loc)
-{
- statements = s;
-}
-
-Statement *UnrolledLoopStatement::syntaxCopy()
-{
- Statements *a = new Statements();
- a->setDim(statements->length);
- for (size_t i = 0; i < statements->length; i++)
- {
- Statement *s = (*statements)[i];
- (*a)[i] = s ? s->syntaxCopy() : NULL;
- }
- return new UnrolledLoopStatement(loc, a);
-}
-
-bool UnrolledLoopStatement::hasBreak()
-{
- return true;
-}
-
-bool UnrolledLoopStatement::hasContinue()
-{
- return true;
-}
-
-/******************************** ScopeStatement ***************************/
-
-ScopeStatement::ScopeStatement(Loc loc, Statement *s, Loc endloc)
- : Statement(loc)
-{
- this->statement = s;
- this->endloc = endloc;
-}
-
-Statement *ScopeStatement::syntaxCopy()
-{
- return new ScopeStatement(loc, statement ? statement->syntaxCopy() : NULL, endloc);
-}
-
-ReturnStatement *ScopeStatement::isReturnStatement()
-{
- if (statement)
- return statement->isReturnStatement();
- return NULL;
-}
-
-bool ScopeStatement::hasBreak()
-{
- //printf("ScopeStatement::hasBreak() %s\n", toChars());
- return statement ? statement->hasBreak() : false;
-}
-
-bool ScopeStatement::hasContinue()
-{
- return statement ? statement->hasContinue() : false;
-}
-
-/******************************** ForwardingStatement **********************/
-
-/* Statement whose symbol table contains foreach index variables in a
- * local scope and forwards other members to the parent scope. This
- * wraps a statement.
- *
- * Also see: `ddmd.attrib.ForwardingAttribDeclaration`
- */
-
-ForwardingStatement::ForwardingStatement(Loc loc, ForwardingScopeDsymbol *sym, Statement *s)
- : Statement(loc)
-{
- this->sym = sym;
- assert(s);
- this->statement = s;
-}
-
-ForwardingStatement::ForwardingStatement(Loc loc, Statement *s)
- : Statement(loc)
-{
- this->sym = new ForwardingScopeDsymbol(NULL);
- this->sym->symtab = new DsymbolTable();
- assert(s);
- this->statement = s;
-}
-
-Statement *ForwardingStatement::syntaxCopy()
-{
- return new ForwardingStatement(loc, statement->syntaxCopy());
-}
-
-/***********************
- * ForwardingStatements are distributed over the flattened
- * sequence of statements. This prevents flattening to be
- * "blocked" by a ForwardingStatement and is necessary, for
- * example, to support generating scope guards with `static
- * foreach`:
- *
- * static foreach(i; 0 .. 10) scope(exit) writeln(i);
- * writeln("this is printed first");
- * // then, it prints 10, 9, 8, 7, ...
- */
-
-Statements *ForwardingStatement::flatten(Scope *sc)
-{
- if (!statement)
- {
- return NULL;
- }
- sc = sc->push(sym);
- Statements *a = statement->flatten(sc);
- sc = sc->pop();
- if (!a)
- {
- return a;
- }
- Statements *b = new Statements();
- b->setDim(a->length);
- for (size_t i = 0; i < a->length; i++)
- {
- Statement *s = (*a)[i];
- (*b)[i] = s ? new ForwardingStatement(s->loc, sym, s) : NULL;
- }
- return b;
-}
-
-/******************************** WhileStatement ***************************/
-
-WhileStatement::WhileStatement(Loc loc, Expression *c, Statement *b, Loc endloc)
- : Statement(loc)
-{
- condition = c;
- _body = b;
- this->endloc = endloc;
-}
-
-Statement *WhileStatement::syntaxCopy()
-{
- return new WhileStatement(loc,
- condition->syntaxCopy(),
- _body ? _body->syntaxCopy() : NULL,
- endloc);
-}
-
-bool WhileStatement::hasBreak()
-{
- return true;
-}
-
-bool WhileStatement::hasContinue()
-{
- return true;
-}
-
-/******************************** DoStatement ***************************/
-
-DoStatement::DoStatement(Loc loc, Statement *b, Expression *c, Loc endloc)
- : Statement(loc)
-{
- _body = b;
- condition = c;
- this->endloc = endloc;
-}
-
-Statement *DoStatement::syntaxCopy()
-{
- return new DoStatement(loc,
- _body ? _body->syntaxCopy() : NULL,
- condition->syntaxCopy(),
- endloc);
-}
-
-bool DoStatement::hasBreak()
-{
- return true;
-}
-
-bool DoStatement::hasContinue()
-{
- return true;
-}
-
-/******************************** ForStatement ***************************/
-
-ForStatement::ForStatement(Loc loc, Statement *init, Expression *condition, Expression *increment, Statement *body, Loc endloc)
- : Statement(loc)
-{
- this->_init = init;
- this->condition = condition;
- this->increment = increment;
- this->_body = body;
- this->endloc = endloc;
- this->relatedLabeled = NULL;
-}
-
-Statement *ForStatement::syntaxCopy()
-{
- return new ForStatement(loc,
- _init ? _init->syntaxCopy() : NULL,
- condition ? condition->syntaxCopy() : NULL,
- increment ? increment->syntaxCopy() : NULL,
- _body->syntaxCopy(),
- endloc);
-}
-
-Statement *ForStatement::scopeCode(Scope *sc, Statement **sentry, Statement **sexception, Statement **sfinally)
-{
- //printf("ForStatement::scopeCode()\n");
- Statement::scopeCode(sc, sentry, sexception, sfinally);
- return this;
-}
-
-bool ForStatement::hasBreak()
-{
- //printf("ForStatement::hasBreak()\n");
- return true;
-}
-
-bool ForStatement::hasContinue()
-{
- return true;
-}
-
-/******************************** ForeachStatement ***************************/
-
-ForeachStatement::ForeachStatement(Loc loc, TOK op, Parameters *parameters,
- Expression *aggr, Statement *body, Loc endloc)
- : Statement(loc)
-{
- this->op = op;
- this->parameters = parameters;
- this->aggr = aggr;
- this->_body = body;
- this->endloc = endloc;
-
- this->key = NULL;
- this->value = NULL;
-
- this->func = NULL;
-
- this->cases = NULL;
- this->gotos = NULL;
-}
-
-Statement *ForeachStatement::syntaxCopy()
-{
- return new ForeachStatement(loc, op,
- Parameter::arraySyntaxCopy(parameters),
- aggr->syntaxCopy(),
- _body ? _body->syntaxCopy() : NULL,
- endloc);
-}
-
-bool ForeachStatement::checkForArgTypes()
-{
- bool result = false;
-
- for (size_t i = 0; i < parameters->length; i++)
- {
- Parameter *p = (*parameters)[i];
- if (!p->type)
- {
- error("cannot infer type for %s", p->ident->toChars());
- p->type = Type::terror;
- result = true;
- }
- }
- return result;
-}
-
-bool ForeachStatement::hasBreak()
-{
- return true;
-}
-
-bool ForeachStatement::hasContinue()
-{
- return true;
-}
-
-/**************************** ForeachRangeStatement ***************************/
-
-
-ForeachRangeStatement::ForeachRangeStatement(Loc loc, TOK op, Parameter *prm,
- Expression *lwr, Expression *upr, Statement *body, Loc endloc)
- : Statement(loc)
-{
- this->op = op;
- this->prm = prm;
- this->lwr = lwr;
- this->upr = upr;
- this->_body = body;
- this->endloc = endloc;
-
- this->key = NULL;
-}
-
-Statement *ForeachRangeStatement::syntaxCopy()
-{
- return new ForeachRangeStatement(loc, op,
- prm->syntaxCopy(),
- lwr->syntaxCopy(),
- upr->syntaxCopy(),
- _body ? _body->syntaxCopy() : NULL,
- endloc);
-}
-
-bool ForeachRangeStatement::hasBreak()
-{
- return true;
-}
-
-bool ForeachRangeStatement::hasContinue()
-{
- return true;
-}
-
-/******************************** IfStatement ***************************/
-
-IfStatement::IfStatement(Loc loc, Parameter *prm, Expression *condition, Statement *ifbody, Statement *elsebody, Loc endloc)
- : Statement(loc)
-{
- this->prm = prm;
- this->condition = condition;
- this->ifbody = ifbody;
- this->elsebody = elsebody;
- this->endloc = endloc;
- this->match = NULL;
-}
-
-Statement *IfStatement::syntaxCopy()
-{
- return new IfStatement(loc,
- prm ? prm->syntaxCopy() : NULL,
- condition->syntaxCopy(),
- ifbody ? ifbody->syntaxCopy() : NULL,
- elsebody ? elsebody->syntaxCopy() : NULL,
- endloc);
-}
-
-/******************************** ConditionalStatement ***************************/
-
-ConditionalStatement::ConditionalStatement(Loc loc, Condition *condition, Statement *ifbody, Statement *elsebody)
- : Statement(loc)
-{
- this->condition = condition;
- this->ifbody = ifbody;
- this->elsebody = elsebody;
-}
-
-Statement *ConditionalStatement::syntaxCopy()
-{
- return new ConditionalStatement(loc,
- condition->syntaxCopy(),
- ifbody->syntaxCopy(),
- elsebody ? elsebody->syntaxCopy() : NULL);
-}
-
-Statements *ConditionalStatement::flatten(Scope *sc)
-{
- Statement *s;
-
- //printf("ConditionalStatement::flatten()\n");
- if (condition->include(sc))
- {
- DebugCondition *dc = condition->isDebugCondition();
- if (dc)
- s = new DebugStatement(loc, ifbody);
- else
- s = ifbody;
- }
- else
- s = elsebody;
-
- Statements *a = new Statements();
- a->push(s);
- return a;
-}
-
-/******************************** StaticForeachStatement ********************/
-
-/* Static foreach statements, like:
- * void main()
- * {
- * static foreach(i; 0 .. 10)
- * {
- * pragma(msg, i);
- * }
- * }
- */
-
-StaticForeachStatement::StaticForeachStatement(Loc loc, StaticForeach *sfe)
- : Statement(loc)
-{
- this->sfe = sfe;
-}
-
-Statement *StaticForeachStatement::syntaxCopy()
-{
- return new StaticForeachStatement(loc, sfe->syntaxCopy());
-}
-
-Statements *StaticForeachStatement::flatten(Scope *sc)
-{
- staticForeachPrepare(sfe, sc);
- if (staticForeachReady(sfe))
- {
- Statement *s = makeTupleForeachStatic(sc, sfe->aggrfe, sfe->needExpansion);
- Statements *result = s->flatten(sc);
- if (result)
- {
- return result;
- }
- result = new Statements();
- result->push(s);
- return result;
- }
- else
- {
- Statements *result = new Statements();
- result->push(new ErrorStatement());
- return result;
- }
-}
-
-/******************************** PragmaStatement ***************************/
-
-PragmaStatement::PragmaStatement(Loc loc, Identifier *ident, Expressions *args, Statement *body)
- : Statement(loc)
-{
- this->ident = ident;
- this->args = args;
- this->_body = body;
-}
-
-Statement *PragmaStatement::syntaxCopy()
-{
- return new PragmaStatement(loc, ident,
- Expression::arraySyntaxCopy(args),
- _body ? _body->syntaxCopy() : NULL);
-}
-
-/******************************** StaticAssertStatement ***************************/
-
-StaticAssertStatement::StaticAssertStatement(StaticAssert *sa)
- : Statement(sa->loc)
-{
- this->sa = sa;
-}
-
-Statement *StaticAssertStatement::syntaxCopy()
-{
- return new StaticAssertStatement((StaticAssert *)sa->syntaxCopy(NULL));
-}
-
-/******************************** SwitchStatement ***************************/
-
-SwitchStatement::SwitchStatement(Loc loc, Expression *c, Statement *b, bool isFinal)
- : Statement(loc)
-{
- this->condition = c;
- this->_body = b;
- this->isFinal = isFinal;
- sdefault = NULL;
- tf = NULL;
- cases = NULL;
- hasNoDefault = 0;
- hasVars = 0;
- lastVar = NULL;
-}
-
-Statement *SwitchStatement::syntaxCopy()
-{
- return new SwitchStatement(loc,
- condition->syntaxCopy(),
- _body->syntaxCopy(),
- isFinal);
-}
-
-bool SwitchStatement::hasBreak()
-{
- return true;
-}
-
-static bool checkVar(SwitchStatement *s, VarDeclaration *vd)
-{
- if (!vd || vd->isDataseg() || (vd->storage_class & STCmanifest))
- return false;
-
- VarDeclaration *last = s->lastVar;
- while (last && last != vd)
- last = last->lastVar;
- if (last == vd)
- {
- // All good, the label's scope has no variables
- }
- else if (vd->storage_class & STCexptemp)
- {
- // Lifetime ends at end of expression, so no issue with skipping the statement
- }
- else if (vd->ident == Id::withSym)
- {
- s->deprecation("`switch` skips declaration of `with` temporary at %s", vd->loc.toChars());
- return true;
- }
- else
- {
- s->deprecation("`switch` skips declaration of variable %s at %s", vd->toPrettyChars(), vd->loc.toChars());
- return true;
- }
-
- return false;
-}
-
-bool SwitchStatement::checkLabel()
-{
- const bool error = true;
-
- if (sdefault && checkVar(this, sdefault->lastVar))
- return !error; // return error once fully deprecated
-
- for (size_t i = 0; i < cases->length; i++)
- {
- CaseStatement *scase = (*cases)[i];
- if (scase && checkVar(this, scase->lastVar))
- return !error; // return error once fully deprecated
- }
- return !error;
-}
-
-/******************************** CaseStatement ***************************/
-
-CaseStatement::CaseStatement(Loc loc, Expression *exp, Statement *s)
- : Statement(loc)
-{
- this->exp = exp;
- this->statement = s;
- index = 0;
- lastVar = NULL;
-}
-
-Statement *CaseStatement::syntaxCopy()
-{
- return new CaseStatement(loc,
- exp->syntaxCopy(),
- statement->syntaxCopy());
-}
-
-int CaseStatement::compare(RootObject *obj)
-{
- // Sort cases so we can do an efficient lookup
- CaseStatement *cs2 = (CaseStatement *)(obj);
-
- return exp->compare(cs2->exp);
-}
-
-/******************************** CaseRangeStatement ***************************/
-
-
-CaseRangeStatement::CaseRangeStatement(Loc loc, Expression *first,
- Expression *last, Statement *s)
- : Statement(loc)
-{
- this->first = first;
- this->last = last;
- this->statement = s;
-}
-
-Statement *CaseRangeStatement::syntaxCopy()
-{
- return new CaseRangeStatement(loc,
- first->syntaxCopy(),
- last->syntaxCopy(),
- statement->syntaxCopy());
-}
-
-/******************************** DefaultStatement ***************************/
-
-DefaultStatement::DefaultStatement(Loc loc, Statement *s)
- : Statement(loc)
-{
- this->statement = s;
- this->lastVar = NULL;
-}
-
-Statement *DefaultStatement::syntaxCopy()
-{
- return new DefaultStatement(loc, statement->syntaxCopy());
-}
-
-/******************************** GotoDefaultStatement ***************************/
-
-GotoDefaultStatement::GotoDefaultStatement(Loc loc)
- : Statement(loc)
-{
- sw = NULL;
-}
-
-Statement *GotoDefaultStatement::syntaxCopy()
-{
- return new GotoDefaultStatement(loc);
-}
-
-/******************************** GotoCaseStatement ***************************/
-
-GotoCaseStatement::GotoCaseStatement(Loc loc, Expression *exp)
- : Statement(loc)
-{
- cs = NULL;
- this->exp = exp;
-}
-
-Statement *GotoCaseStatement::syntaxCopy()
-{
- return new GotoCaseStatement(loc, exp ? exp->syntaxCopy() : NULL);
-}
-
-/******************************** SwitchErrorStatement ***************************/
-
-SwitchErrorStatement::SwitchErrorStatement(Loc loc)
- : Statement(loc)
-{
-}
-
-/******************************** ReturnStatement ***************************/
-
-ReturnStatement::ReturnStatement(Loc loc, Expression *exp)
- : Statement(loc)
-{
- this->exp = exp;
- this->caseDim = 0;
-}
-
-Statement *ReturnStatement::syntaxCopy()
-{
- return new ReturnStatement(loc, exp ? exp->syntaxCopy() : NULL);
-}
-
-/******************************** BreakStatement ***************************/
-
-BreakStatement::BreakStatement(Loc loc, Identifier *ident)
- : Statement(loc)
-{
- this->ident = ident;
-}
-
-Statement *BreakStatement::syntaxCopy()
-{
- return new BreakStatement(loc, ident);
-}
-
-/******************************** ContinueStatement ***************************/
-
-ContinueStatement::ContinueStatement(Loc loc, Identifier *ident)
- : Statement(loc)
-{
- this->ident = ident;
-}
-
-Statement *ContinueStatement::syntaxCopy()
-{
- return new ContinueStatement(loc, ident);
-}
-
-/******************************** SynchronizedStatement ***************************/
-
-SynchronizedStatement::SynchronizedStatement(Loc loc, Expression *exp, Statement *body)
- : Statement(loc)
-{
- this->exp = exp;
- this->_body = body;
-}
-
-Statement *SynchronizedStatement::syntaxCopy()
-{
- return new SynchronizedStatement(loc,
- exp ? exp->syntaxCopy() : NULL,
- _body ? _body->syntaxCopy() : NULL);
-}
-
-bool SynchronizedStatement::hasBreak()
-{
- return false; //true;
-}
-
-bool SynchronizedStatement::hasContinue()
-{
- return false; //true;
-}
-
-/******************************** WithStatement ***************************/
-
-WithStatement::WithStatement(Loc loc, Expression *exp, Statement *body, Loc endloc)
- : Statement(loc)
-{
- this->exp = exp;
- this->_body = body;
- this->endloc = endloc;
- wthis = NULL;
-}
-
-Statement *WithStatement::syntaxCopy()
-{
- return new WithStatement(loc,
- exp->syntaxCopy(),
- _body ? _body->syntaxCopy() : NULL, endloc);
-}
-
-/******************************** TryCatchStatement ***************************/
-
-TryCatchStatement::TryCatchStatement(Loc loc, Statement *body, Catches *catches)
- : Statement(loc)
-{
- this->_body = body;
- this->catches = catches;
-}
-
-Statement *TryCatchStatement::syntaxCopy()
-{
- Catches *a = new Catches();
- a->setDim(catches->length);
- for (size_t i = 0; i < a->length; i++)
- {
- Catch *c = (*catches)[i];
- (*a)[i] = c->syntaxCopy();
- }
- return new TryCatchStatement(loc, _body->syntaxCopy(), a);
-}
-
-bool TryCatchStatement::hasBreak()
-{
- return false;
-}
-
-/******************************** Catch ***************************/
-
-Catch::Catch(Loc loc, Type *t, Identifier *id, Statement *handler)
-{
- //printf("Catch(%s, loc = %s)\n", id->toChars(), loc.toChars());
- this->loc = loc;
- this->type = t;
- this->ident = id;
- this->handler = handler;
- var = NULL;
- errors = false;
- internalCatch = false;
-}
-
-Catch *Catch::syntaxCopy()
-{
- Catch *c = new Catch(loc,
- type ? type->syntaxCopy() : getThrowable(),
- ident,
- (handler ? handler->syntaxCopy() : NULL));
- c->internalCatch = internalCatch;
- return c;
-}
-
-/****************************** TryFinallyStatement ***************************/
-
-TryFinallyStatement::TryFinallyStatement(Loc loc, Statement *body, Statement *finalbody)
- : Statement(loc)
-{
- this->_body = body;
- this->finalbody = finalbody;
-}
-
-TryFinallyStatement *TryFinallyStatement::create(Loc loc, Statement *body, Statement *finalbody)
-{
- return new TryFinallyStatement(loc, body, finalbody);
-}
-
-Statement *TryFinallyStatement::syntaxCopy()
-{
- return new TryFinallyStatement(loc,
- _body->syntaxCopy(), finalbody->syntaxCopy());
-}
-
-bool TryFinallyStatement::hasBreak()
-{
- return false; //true;
-}
-
-bool TryFinallyStatement::hasContinue()
-{
- return false; //true;
-}
-
-/****************************** ScopeGuardStatement ***************************/
-
-ScopeGuardStatement::ScopeGuardStatement(Loc loc, TOK tok, Statement *statement)
- : Statement(loc)
-{
- this->tok = tok;
- this->statement = statement;
-}
-
-Statement *ScopeGuardStatement::syntaxCopy()
-{
- return new ScopeGuardStatement(loc, tok, statement->syntaxCopy());
-}
-
-Statement *ScopeGuardStatement::scopeCode(Scope *sc, Statement **sentry, Statement **sexception, Statement **sfinally)
-{
- //printf("ScopeGuardStatement::scopeCode()\n");
- //print();
- *sentry = NULL;
- *sexception = NULL;
- *sfinally = NULL;
-
- Statement *s = new PeelStatement(statement);
-
- switch (tok)
- {
- case TOKon_scope_exit:
- *sfinally = s;
- break;
-
- case TOKon_scope_failure:
- *sexception = s;
- break;
-
- case TOKon_scope_success:
- {
- /* Create:
- * sentry: bool x = false;
- * sexception: x = true;
- * sfinally: if (!x) statement;
- */
- VarDeclaration *v = copyToTemp(0, "__os", new IntegerExp(Loc(), 0, Type::tbool));
- dsymbolSemantic(v, sc);
- *sentry = new ExpStatement(loc, v);
-
- Expression *e = new IntegerExp(Loc(), 1, Type::tbool);
- e = new AssignExp(Loc(), new VarExp(Loc(), v), e);
- *sexception = new ExpStatement(Loc(), e);
-
- e = new VarExp(Loc(), v);
- e = new NotExp(Loc(), e);
- *sfinally = new IfStatement(Loc(), NULL, e, s, NULL, Loc());
-
- break;
- }
-
- default:
- assert(0);
- }
- return NULL;
-}
-
-/******************************** ThrowStatement ***************************/
-
-ThrowStatement::ThrowStatement(Loc loc, Expression *exp)
- : Statement(loc)
-{
- this->exp = exp;
- this->internalThrow = false;
-}
-
-Statement *ThrowStatement::syntaxCopy()
-{
- ThrowStatement *s = new ThrowStatement(loc, exp->syntaxCopy());
- s->internalThrow = internalThrow;
- return s;
-}
-
-/******************************** DebugStatement **************************/
-
-DebugStatement::DebugStatement(Loc loc, Statement *statement)
- : Statement(loc)
-{
- this->statement = statement;
-}
-
-Statement *DebugStatement::syntaxCopy()
-{
- return new DebugStatement(loc,
- statement ? statement->syntaxCopy() : NULL);
-}
-
-Statements *DebugStatement::flatten(Scope *sc)
-{
- Statements *a = statement ? statement->flatten(sc) : NULL;
- if (a)
- {
- for (size_t i = 0; i < a->length; i++)
- { Statement *s = (*a)[i];
-
- s = new DebugStatement(loc, s);
- (*a)[i] = s;
- }
- }
-
- return a;
-}
-
-/******************************** GotoStatement ***************************/
-
-GotoStatement::GotoStatement(Loc loc, Identifier *ident)
- : Statement(loc)
-{
- this->ident = ident;
- this->label = NULL;
- this->tf = NULL;
- this->os = NULL;
- this->lastVar = NULL;
-}
-
-Statement *GotoStatement::syntaxCopy()
-{
- return new GotoStatement(loc, ident);
-}
-
-bool GotoStatement::checkLabel()
-{
- if (!label->statement)
- {
- error("label `%s` is undefined", label->toChars());
- return true;
- }
-
- if (label->statement->os != os)
- {
- if (os && os->tok == TOKon_scope_failure && !label->statement->os)
- {
- // Jump out from scope(failure) block is allowed.
- }
- else
- {
- if (label->statement->os)
- error("cannot goto in to %s block", Token::toChars(label->statement->os->tok));
- else
- error("cannot goto out of %s block", Token::toChars(os->tok));
- return true;
- }
- }
-
- if (label->statement->tf != tf)
- {
- error("cannot goto in or out of finally block");
- return true;
- }
-
- VarDeclaration *vd = label->statement->lastVar;
- if (!vd || vd->isDataseg() || (vd->storage_class & STCmanifest))
- return false;
-
- VarDeclaration *last = lastVar;
- while (last && last != vd)
- last = last->lastVar;
- if (last == vd)
- {
- // All good, the label's scope has no variables
- }
- else if (vd->ident == Id::withSym)
- {
- error("goto skips declaration of with temporary at %s", vd->loc.toChars());
- return true;
- }
- else
- {
- error("goto skips declaration of variable %s at %s", vd->toPrettyChars(), vd->loc.toChars());
- return true;
- }
-
- return false;
-}
-
-/******************************** LabelStatement ***************************/
-
-LabelStatement::LabelStatement(Loc loc, Identifier *ident, Statement *statement)
- : Statement(loc)
-{
- this->ident = ident;
- this->statement = statement;
- this->tf = NULL;
- this->os = NULL;
- this->lastVar = NULL;
- this->gotoTarget = NULL;
- this->breaks = false;
-}
-
-Statement *LabelStatement::syntaxCopy()
-{
- return new LabelStatement(loc, ident, statement ? statement->syntaxCopy() : NULL);
-}
-
-Statement *LabelStatement::scopeCode(Scope *sc, Statement **sentry, Statement **sexit, Statement **sfinally)
-{
- //printf("LabelStatement::scopeCode()\n");
- if (statement)
- statement = statement->scopeCode(sc, sentry, sexit, sfinally);
- else
- {
- *sentry = NULL;
- *sexit = NULL;
- *sfinally = NULL;
- }
- return this;
-}
-
-Statements *LabelStatement::flatten(Scope *sc)
-{
- Statements *a = NULL;
-
- if (statement)
- {
- a = statement->flatten(sc);
- if (a)
- {
- if (!a->length)
- {
- a->push(new ExpStatement(loc, (Expression *)NULL));
- }
-
- // reuse 'this' LabelStatement
- this->statement = (*a)[0];
- (*a)[0] = this;
- }
- }
-
- return a;
-}
-
-/******************************** LabelDsymbol ***************************/
-
-LabelDsymbol::LabelDsymbol(Identifier *ident)
- : Dsymbol(ident)
-{
- statement = NULL;
-}
-
-LabelDsymbol *LabelDsymbol::create(Identifier *ident)
-{
- return new LabelDsymbol(ident);
-}
-
-LabelDsymbol *LabelDsymbol::isLabel() // is this a LabelDsymbol()?
-{
- return this;
-}
-
-
-/************************ AsmStatement ***************************************/
-
-AsmStatement::AsmStatement(Loc loc, Token *tokens)
- : Statement(loc)
-{
- this->tokens = tokens;
-}
-
-Statement *AsmStatement::syntaxCopy()
-{
- return new AsmStatement(loc, tokens);
-}
-
-
-/************************ InlineAsmStatement **********************************/
-
-InlineAsmStatement::InlineAsmStatement(Loc loc, Token *tokens)
- : AsmStatement(loc, tokens)
-{
- asmcode = NULL;
- asmalign = 0;
- refparam = false;
- naked = false;
- regs = 0;
-}
-
-Statement *InlineAsmStatement::syntaxCopy()
-{
- return new InlineAsmStatement(loc, tokens);
-}
-
-
-/************************ GccAsmStatement ***************************************/
-
-GccAsmStatement::GccAsmStatement(Loc loc, Token *tokens)
- : AsmStatement(loc, tokens)
-{
- this->stc = STCundefined;
- this->insn = NULL;
- this->args = NULL;
- this->outputargs = 0;
- this->names = NULL;
- this->constraints = NULL;
- this->clobbers = NULL;
- this->labels = NULL;
- this->gotos = NULL;
-}
-
-Statement *GccAsmStatement::syntaxCopy()
-{
- return new GccAsmStatement(loc, tokens);
-}
-
-/************************ CompoundAsmStatement ***************************************/
-
-CompoundAsmStatement::CompoundAsmStatement(Loc loc, Statements *s, StorageClass stc)
- : CompoundStatement(loc, s)
-{
- this->stc = stc;
-}
-
-CompoundAsmStatement *CompoundAsmStatement::syntaxCopy()
-{
- Statements *a = new Statements();
- a->setDim(statements->length);
- for (size_t i = 0; i < statements->length; i++)
- {
- Statement *s = (*statements)[i];
- (*a)[i] = s ? s->syntaxCopy() : NULL;
- }
- return new CompoundAsmStatement(loc, a, stc);
-}
-
-Statements *CompoundAsmStatement::flatten(Scope *)
-{
- return NULL;
-}
-
-/************************ ImportStatement ***************************************/
-
-ImportStatement::ImportStatement(Loc loc, Dsymbols *imports)
- : Statement(loc)
-{
- this->imports = imports;
-}
-
-Statement *ImportStatement::syntaxCopy()
-{
- Dsymbols *m = new Dsymbols();
- m->setDim(imports->length);
- for (size_t i = 0; i < imports->length; i++)
- {
- Dsymbol *s = (*imports)[i];
- (*m)[i] = s->syntaxCopy(NULL);
- }
- return new ImportStatement(loc, m);
-}