447 changes: 0 additions & 447 deletions src/access.c

This file was deleted.

400 changes: 400 additions & 0 deletions src/access.d

Large diffs are not rendered by default.

500 changes: 500 additions & 0 deletions src/aggregate.d

Large diffs are not rendered by default.

149 changes: 0 additions & 149 deletions src/aliasthis.c

This file was deleted.

147 changes: 147 additions & 0 deletions src/aliasthis.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2015 by Digital Mars
// 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

module ddmd.aliasthis;

import ddmd.aggregate, ddmd.declaration, ddmd.dscope, ddmd.dsymbol, ddmd.errors, ddmd.expression, ddmd.func, ddmd.globals, ddmd.hdrgen, ddmd.identifier, ddmd.mtype, ddmd.opover, ddmd.root.outbuffer, ddmd.tokens, ddmd.visitor;

/**************************************************************/
extern (C++) final class AliasThis : Dsymbol
{
public:
// alias Identifier this;
Identifier ident;

// it's anonymous (no identifier)
extern (D) this(Loc loc, Identifier ident)
{
super(null);
this.loc = loc;
this.ident = ident;
}

Dsymbol syntaxCopy(Dsymbol s)
{
assert(!s);
/* Since there is no semantic information stored here,
* we don't need to copy it.
*/
return this;
}

void semantic(Scope* sc)
{
Dsymbol p = sc.parent.pastMixin();
AggregateDeclaration ad = p.isAggregateDeclaration();
if (!ad)
{
.error(loc, "alias this can only be a member of aggregate, not %s %s", p.kind(), p.toChars());
return;
}
assert(ad.members);
Dsymbol s = ad.search(loc, ident);
if (!s)
{
s = sc.search(loc, ident, null);
if (s)
.error(loc, "%s is not a member of %s", s.toChars(), ad.toChars());
else
.error(loc, "undefined identifier %s", ident.toChars());
return;
}
else if (ad.aliasthis && s != ad.aliasthis)
{
.error(loc, "there can be only one alias this");
return;
}
if (ad.type.ty == Tstruct && (cast(TypeStruct)ad.type).sym != ad)
{
AggregateDeclaration ad2 = (cast(TypeStruct)ad.type).sym;
assert(ad2.type == Type.terror);
ad.aliasthis = ad2.aliasthis;
return;
}
/* disable the alias this conversion so the implicit conversion check
* doesn't use it.
*/
ad.aliasthis = null;
Dsymbol sx = s;
if (sx.isAliasDeclaration())
sx = sx.toAlias();
Declaration d = sx.isDeclaration();
if (d && !d.isTupleDeclaration())
{
Type t = d.type;
assert(t);
if (ad.type.implicitConvTo(t) > MATCHnomatch)
{
.error(loc, "alias this is not reachable as %s already converts to %s", ad.toChars(), t.toChars());
}
}
ad.aliasthis = s;
}

const(char)* kind()
{
return "alias this";
}

AliasThis isAliasThis()
{
return this;
}

void accept(Visitor v)
{
v.visit(this);
}
}

extern (C++) Expression resolveAliasThis(Scope* sc, Expression e)
{
AggregateDeclaration ad = isAggregate(e.type);
if (ad && ad.aliasthis)
{
Loc loc = e.loc;
Type tthis = (e.op == TOKtype ? e.type : null);
e = new DotIdExp(loc, e, ad.aliasthis.ident);
e = e.semantic(sc);
if (tthis && ad.aliasthis.needThis())
{
if (e.op == TOKvar)
{
if (FuncDeclaration f = (cast(VarExp)e).var.isFuncDeclaration())
{
// Bugzilla 13009: Support better match for the overloaded alias this.
Type t;
f = f.overloadModMatch(loc, tthis, t);
if (f && t)
{
e = new VarExp(loc, f, 0); // use better match
e = new CallExp(loc, e);
goto L1;
}
}
}
/* non-@property function is not called inside typeof(),
* so resolve it ahead.
*/
{
int save = sc.intypeof;
sc.intypeof = 1; // bypass "need this" error check
e = resolveProperties(sc, e);
sc.intypeof = save;
}
L1:
e = new TypeExp(loc, new TypeTypeof(loc, e));
e = e.semantic(sc);
}
e = resolveProperties(sc, e);
}
return e;
}
145 changes: 0 additions & 145 deletions src/apply.c

This file was deleted.

143 changes: 143 additions & 0 deletions src/apply.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2015 by Digital Mars
// 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

module ddmd.apply;

import ddmd.arraytypes, ddmd.expression, ddmd.visitor;

/**************************************
* An Expression tree walker that will visit each Expression e in the tree,
* in depth-first evaluation order, and call fp(e,param) on it.
* fp() signals whether the walking continues with its return value:
* Returns:
* 0 continue
* 1 done
* It's a bit slower than using virtual functions, but more encapsulated and less brittle.
* Creating an iterator for this would be much more complex.
*/
extern (C++) final class PostorderExpressionVisitor : StoppableVisitor
{
alias visit = super.visit;
public:
StoppableVisitor v;

extern (D) this(StoppableVisitor v)
{
this.v = v;
}

bool doCond(Expression e)
{
if (!stop && e)
e.accept(this);
return stop;
}

bool doCond(Expressions* e)
{
if (!e)
return false;
for (size_t i = 0; i < e.dim && !stop; i++)
doCond((*e)[i]);
return stop;
}

bool applyTo(Expression e)
{
e.accept(v);
stop = v.stop;
return true;
}

void visit(Expression e)
{
applyTo(e);
}

void visit(NewExp e)
{
//printf("NewExp::apply(): %s\n", toChars());
doCond(e.thisexp) || doCond(e.newargs) || doCond(e.arguments) || applyTo(e);
}

void visit(NewAnonClassExp e)
{
//printf("NewAnonClassExp::apply(): %s\n", toChars());
doCond(e.thisexp) || doCond(e.newargs) || doCond(e.arguments) || applyTo(e);
}

void visit(UnaExp e)
{
doCond(e.e1) || applyTo(e);
}

void visit(BinExp e)
{
doCond(e.e1) || doCond(e.e2) || applyTo(e);
}

void visit(AssertExp e)
{
//printf("CallExp::apply(apply_fp_t fp, void *param): %s\n", toChars());
doCond(e.e1) || doCond(e.msg) || applyTo(e);
}

void visit(CallExp e)
{
//printf("CallExp::apply(apply_fp_t fp, void *param): %s\n", toChars());
doCond(e.e1) || doCond(e.arguments) || applyTo(e);
}

void visit(ArrayExp e)
{
//printf("ArrayExp::apply(apply_fp_t fp, void *param): %s\n", toChars());
doCond(e.e1) || doCond(e.arguments) || applyTo(e);
}

void visit(SliceExp e)
{
doCond(e.e1) || doCond(e.lwr) || doCond(e.upr) || applyTo(e);
}

void visit(ArrayLiteralExp e)
{
doCond(e.elements) || applyTo(e);
}

void visit(AssocArrayLiteralExp e)
{
doCond(e.keys) || doCond(e.values) || applyTo(e);
}

void visit(StructLiteralExp e)
{
if (e.stageflags & stageApply)
return;
int old = e.stageflags;
e.stageflags |= stageApply;
doCond(e.elements) || applyTo(e);
e.stageflags = old;
}

void visit(TupleExp e)
{
doCond(e.e0) || doCond(e.exps) || applyTo(e);
}

void visit(CondExp e)
{
doCond(e.econd) || doCond(e.e1) || doCond(e.e2) || applyTo(e);
}
}

extern (C++) bool walkPostorder(Expression e, StoppableVisitor v)
{
scope PostorderExpressionVisitor pv = new PostorderExpressionVisitor(v);
e.accept(pv);
return v.stop;
}
491 changes: 0 additions & 491 deletions src/argtypes.c

This file was deleted.

450 changes: 450 additions & 0 deletions src/argtypes.d

Large diffs are not rendered by default.

642 changes: 0 additions & 642 deletions src/arrayop.c

This file was deleted.

637 changes: 637 additions & 0 deletions src/arrayop.d

Large diffs are not rendered by default.

37 changes: 37 additions & 0 deletions src/arraytypes.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2015 by Digital Mars
// 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

module ddmd.arraytypes;

import ddmd.aggregate, ddmd.backend, ddmd.dclass, ddmd.declaration, ddmd.dmodule, ddmd.dsymbol, ddmd.dtemplate, ddmd.expression, ddmd.func, ddmd.globals, ddmd.identifier, ddmd.init, ddmd.mtype, ddmd.root.array, ddmd.root.file, ddmd.root.rootobject, ddmd.statement;

alias Strings = Array!(const(char)*);
alias Identifiers = Array!(Identifier);
alias TemplateParameters = Array!(TemplateParameter);
alias Expressions = Array!(Expression);
alias Statements = Array!(Statement);
alias BaseClasses = Array!(BaseClass*);
alias ClassDeclarations = Array!(ClassDeclaration);
alias Dsymbols = Array!(Dsymbol);
alias Objects = Array!(RootObject);
alias FuncDeclarations = Array!(FuncDeclaration);
alias Parameters = Array!(Parameter);
alias Initializers = Array!(Initializer);
alias VarDeclarations = Array!(VarDeclaration);
alias Types = Array!(Type);
alias Catches = Array!(Catch);
alias StaticDtorDeclarations = Array!(StaticDtorDeclaration);
alias SharedStaticDtorDeclarations = Array!(SharedStaticDtorDeclaration);
alias AliasDeclarations = Array!(AliasDeclaration);
alias Modules = Array!(Module);
alias CaseStatements = Array!(CaseStatement);
alias ScopeStatements = Array!(ScopeStatement);
alias GotoCaseStatements = Array!(GotoCaseStatement);
alias ReturnStatements = Array!(ReturnStatement);
alias GotoStatements = Array!(GotoStatement);
alias TemplateInstances = Array!(TemplateInstance);
1,408 changes: 0 additions & 1,408 deletions src/attrib.c

This file was deleted.

1,408 changes: 1,408 additions & 0 deletions src/attrib.d

Large diffs are not rendered by default.

240 changes: 103 additions & 137 deletions src/builtin.c → src/builtin.d

Large diffs are not rendered by default.

239 changes: 0 additions & 239 deletions src/canthrow.c

This file was deleted.

221 changes: 221 additions & 0 deletions src/canthrow.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2015 by Digital Mars
// 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

module ddmd.canthrow;

import ddmd.apply, ddmd.arraytypes, ddmd.attrib, ddmd.declaration, ddmd.dstruct, ddmd.dsymbol, ddmd.dtemplate, ddmd.expression, ddmd.func, ddmd.globals, ddmd.init, ddmd.mtype, ddmd.root.rootobject, ddmd.tokens, ddmd.visitor;

/********************************************
* Returns true if the expression may throw exceptions.
* If 'mustNotThrow' is true, generate an error if it throws
*/
extern (C++) bool canThrow(Expression e, FuncDeclaration func, bool mustNotThrow)
{
//printf("Expression::canThrow(%d) %s\n", mustNotThrow, toChars());
// stop walking if we determine this expression can throw
extern (C++) final class CanThrow : StoppableVisitor
{
alias visit = super.visit;
FuncDeclaration func;
bool mustNotThrow;

public:
extern (D) this(FuncDeclaration func, bool mustNotThrow)
{
this.func = func;
this.mustNotThrow = mustNotThrow;
}

void visit(Expression)
{
}

void visit(DeclarationExp de)
{
stop = Dsymbol_canThrow(de.declaration, func, mustNotThrow);
}

void visit(CallExp ce)
{
if (global.errors && !ce.e1.type)
return; // error recovery
/* If calling a function or delegate that is typed as nothrow,
* then this expression cannot throw.
* Note that pure functions can throw.
*/
Type t = ce.e1.type.toBasetype();
if (ce.f && ce.f == func)
{
}
else if (t.ty == Tfunction && (cast(TypeFunction)t).isnothrow)
{
}
else if (t.ty == Tdelegate && (cast(TypeFunction)(cast(TypeDelegate)t).next).isnothrow)
{
}
else
{
if (mustNotThrow)
{
const(char)* s;
if (ce.f)
s = ce.f.toPrettyChars();
else if (ce.e1.op == TOKstar)
{
// print 'fp' if ce->e1 is (*fp)
s = (cast(PtrExp)ce.e1).e1.toChars();
}
else
s = ce.e1.toChars();
ce.error("'%s' is not nothrow", s);
}
stop = true;
}
}

void visit(NewExp ne)
{
if (ne.member)
{
// See if constructor call can throw
Type t = ne.member.type.toBasetype();
if (t.ty == Tfunction && !(cast(TypeFunction)t).isnothrow)
{
if (mustNotThrow)
ne.error("constructor %s is not nothrow", ne.member.toChars());
stop = true;
}
}
// regard storage allocation failures as not recoverable
}

void visit(AssignExp ae)
{
// blit-init cannot throw
if (ae.op == TOKblit)
return;
/* Element-wise assignment could invoke postblits.
*/
Type t;
if (ae.type.toBasetype().ty == Tsarray)
{
if (!ae.e2.isLvalue())
return;
t = ae.type;
}
else if (ae.e1.op == TOKslice)
t = (cast(SliceExp)ae.e1).e1.type;
else
return;
Type tv = t.baseElemOf();
if (tv.ty != Tstruct)
return;
StructDeclaration sd = (cast(TypeStruct)tv).sym;
if (!sd.postblit || sd.postblit.type.ty != Tfunction)
return;
if ((cast(TypeFunction)sd.postblit.type).isnothrow)
{
}
else
{
if (mustNotThrow)
ae.error("'%s' is not nothrow", sd.postblit.toPrettyChars());
stop = true;
}
}

void visit(NewAnonClassExp)
{
assert(0); // should have been lowered by semantic()
}
}

scope CanThrow ct = new CanThrow(func, mustNotThrow);
return walkPostorder(e, ct);
}

/**************************************
* Does symbol, when initialized, throw?
* Mirrors logic in Dsymbol_toElem().
*/
extern (C++) bool Dsymbol_canThrow(Dsymbol s, FuncDeclaration func, bool mustNotThrow)
{
AttribDeclaration ad;
VarDeclaration vd;
TemplateMixin tm;
TupleDeclaration td;
//printf("Dsymbol_toElem() %s\n", s->toChars());
ad = s.isAttribDeclaration();
if (ad)
{
Dsymbols* decl = ad.include(null, null);
if (decl && decl.dim)
{
for (size_t i = 0; i < decl.dim; i++)
{
s = (*decl)[i];
if (Dsymbol_canThrow(s, func, mustNotThrow))
return true;
}
}
}
else if ((vd = s.isVarDeclaration()) !is null)
{
s = s.toAlias();
if (s != vd)
return Dsymbol_canThrow(s, func, mustNotThrow);
if (vd.storage_class & STCmanifest)
{
}
else if (vd.isStatic() || vd.storage_class & (STCextern | STCtls | STCgshared))
{
}
else
{
if (vd._init)
{
ExpInitializer ie = vd._init.isExpInitializer();
if (ie && canThrow(ie.exp, func, mustNotThrow))
return true;
}
if (vd.edtor && !vd.noscope)
return canThrow(vd.edtor, func, mustNotThrow);
}
}
else if ((tm = s.isTemplateMixin()) !is null)
{
//printf("%s\n", tm->toChars());
if (tm.members)
{
for (size_t i = 0; i < tm.members.dim; i++)
{
Dsymbol sm = (*tm.members)[i];
if (Dsymbol_canThrow(sm, func, mustNotThrow))
return true;
}
}
}
else if ((td = s.isTupleDeclaration()) !is null)
{
for (size_t i = 0; i < td.objects.dim; i++)
{
RootObject o = (*td.objects)[i];
if (o.dyncast() == DYNCAST_EXPRESSION)
{
Expression eo = cast(Expression)o;
if (eo.op == TOKdsymbol)
{
DsymbolExp se = cast(DsymbolExp)eo;
if (Dsymbol_canThrow(se.s, func, mustNotThrow))
return true;
}
}
}
}
return false;
}
3,746 changes: 0 additions & 3,746 deletions src/cast.c

This file was deleted.

1,855 changes: 0 additions & 1,855 deletions src/class.c

This file was deleted.

1,131 changes: 0 additions & 1,131 deletions src/clone.c

This file was deleted.

1,016 changes: 1,016 additions & 0 deletions src/clone.d

Large diffs are not rendered by default.

388 changes: 0 additions & 388 deletions src/cond.c

This file was deleted.

433 changes: 433 additions & 0 deletions src/cond.d

Large diffs are not rendered by default.

1,999 changes: 0 additions & 1,999 deletions src/constfold.c

This file was deleted.

2,021 changes: 2,021 additions & 0 deletions src/constfold.d

Large diffs are not rendered by default.

1,921 changes: 0 additions & 1,921 deletions src/cppmangle.c

This file was deleted.

1,889 changes: 1,889 additions & 0 deletions src/cppmangle.d

Large diffs are not rendered by default.

2,383 changes: 0 additions & 2,383 deletions src/ctfeexpr.c

This file was deleted.

2,395 changes: 2,395 additions & 0 deletions src/ctfeexpr.d

Large diffs are not rendered by default.

3,445 changes: 3,445 additions & 0 deletions src/dcast.d

Large diffs are not rendered by default.

1,692 changes: 1,692 additions & 0 deletions src/dclass.d

Large diffs are not rendered by default.

2,478 changes: 0 additions & 2,478 deletions src/declaration.c

This file was deleted.

2,771 changes: 2,771 additions & 0 deletions src/declaration.d

Large diffs are not rendered by default.

185 changes: 0 additions & 185 deletions src/delegatize.c

This file was deleted.

160 changes: 160 additions & 0 deletions src/delegatize.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2015 by Digital Mars
// 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

module ddmd.delegatize;

import ddmd.apply, ddmd.declaration, ddmd.dscope, ddmd.expression, ddmd.func, ddmd.globals, ddmd.mtype, ddmd.statement, ddmd.tokens, ddmd.visitor;

extern (C++) Expression toDelegate(Expression e, Type t, Scope* sc)
{
//printf("Expression::toDelegate(t = %s) %s\n", t->toChars(), e->toChars());
Loc loc = e.loc;
auto tf = new TypeFunction(null, t, 0, LINKd);
if (t.hasWild())
tf.mod = MODwild;
auto fld = new FuncLiteralDeclaration(loc, loc, tf, TOKdelegate, null);
sc = sc.push();
sc.parent = fld; // set current function to be the delegate
lambdaSetParent(e, sc);
bool r = lambdaCheckForNestedRef(e, sc);
sc = sc.pop();
if (r)
return new ErrorExp();
Statement s;
if (t.ty == Tvoid)
s = new ExpStatement(loc, e);
else
s = new ReturnStatement(loc, e);
fld.fbody = s;
e = new FuncExp(loc, fld);
e = e.semantic(sc);
return e;
}

/******************************************
* Patch the parent of declarations to be the new function literal.
*/
extern (C++) void lambdaSetParent(Expression e, Scope* sc)
{
extern (C++) final class LambdaSetParent : StoppableVisitor
{
alias visit = super.visit;
Scope* sc;

public:
extern (D) this(Scope* sc)
{
this.sc = sc;
}

void visit(Expression)
{
}

void visit(DeclarationExp e)
{
e.declaration.parent = sc.parent;
}

void visit(IndexExp e)
{
if (e.lengthVar)
{
//printf("lengthVar\n");
e.lengthVar.parent = sc.parent;
}
}

void visit(SliceExp e)
{
if (e.lengthVar)
{
//printf("lengthVar\n");
e.lengthVar.parent = sc.parent;
}
}
}

scope LambdaSetParent lsp = new LambdaSetParent(sc);
walkPostorder(e, lsp);
}

/*******************************************
* Look for references to variables in a scope enclosing the new function literal.
* Returns true if error occurs.
*/
extern (C++) bool lambdaCheckForNestedRef(Expression e, Scope* sc)
{
extern (C++) final class LambdaCheckForNestedRef : StoppableVisitor
{
alias visit = super.visit;
public:
Scope* sc;
bool result;

extern (D) this(Scope* sc)
{
this.sc = sc;
this.result = false;
}

void visit(Expression)
{
}

void visit(SymOffExp e)
{
VarDeclaration v = e.var.isVarDeclaration();
if (v)
result = v.checkNestedReference(sc, Loc());
}

void visit(VarExp e)
{
VarDeclaration v = e.var.isVarDeclaration();
if (v)
result = v.checkNestedReference(sc, Loc());
}

void visit(ThisExp e)
{
VarDeclaration v = e.var.isVarDeclaration();
if (v)
result = v.checkNestedReference(sc, Loc());
}

void visit(DeclarationExp e)
{
VarDeclaration v = e.declaration.isVarDeclaration();
if (v)
{
result = v.checkNestedReference(sc, Loc());
if (result)
return;
/* Some expressions cause the frontend to create a temporary.
* For example, structs with cpctors replace the original
* expression e with:
* __cpcttmp = __cpcttmp.cpctor(e);
*
* In this instance, we need to ensure that the original
* expression e does not have any nested references by
* checking the declaration initializer too.
*/
if (v._init && v._init.isExpInitializer())
{
Expression ie = v._init.toExpression();
result = lambdaCheckForNestedRef(ie, sc);
}
}
}
}

scope LambdaCheckForNestedRef v = new LambdaCheckForNestedRef(sc);
walkPostorder(e, v);
return v.result;
}
707 changes: 707 additions & 0 deletions src/denum.d

Large diffs are not rendered by default.

432 changes: 432 additions & 0 deletions src/dimport.d

Large diffs are not rendered by default.

332 changes: 332 additions & 0 deletions src/dinifile.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,332 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2015 by Digital Mars
// 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

module ddmd.dinifile;

import core.stdc.ctype, core.stdc.stdlib, core.stdc.string, core.sys.posix.stdlib, core.sys.windows.windows;
import ddmd.globals, ddmd.root.file, ddmd.root.filename, ddmd.root.outbuffer, ddmd.root.port, ddmd.root.stringtable;

version (Windows) extern (C) int putenv(const char*);
private enum LOG = false;

/*****************************
* Find the config file
* Input:
* argv0 program name (argv[0])
* inifile .ini file name
* Returns:
* file path of the config file or NULL
* Note: this is a memory leak
*/
extern (C++) const(char)* findConfFile(const(char)* argv0, const(char)* inifile)
{
static if (LOG)
{
printf("findinifile(argv0 = '%s', inifile = '%s')\n", argv0, inifile);
}
if (FileName.absolute(inifile))
return inifile;
if (FileName.exists(inifile))
return inifile;
/* Look for inifile in the following sequence of places:
* o current directory
* o home directory
* o exe directory (windows)
* o directory off of argv0
* o SYSCONFDIR (default=/etc/) (non-windows)
*/
const(char)* filename = FileName.combine(getenv("HOME"), inifile);
if (FileName.exists(filename))
return filename;
version (Windows)
{
// This fix by Tim Matthews
char[MAX_PATH + 1] resolved_name;
if (GetModuleFileNameA(null, resolved_name.ptr, MAX_PATH + 1) && FileName.exists(resolved_name.ptr))
{
filename = FileName.replaceName(resolved_name.ptr, inifile);
if (FileName.exists(filename))
return filename;
}
}
filename = FileName.replaceName(argv0, inifile);
if (FileName.exists(filename))
return filename;
static if (__linux__ || __APPLE__ || __FreeBSD__ || __OpenBSD__ || __sun)
{
// Search PATH for argv0
const(char)* p = getenv("PATH");
static if (LOG)
{
printf("\tPATH='%s'\n", p);
}
Strings* paths = FileName.splitPath(p);
const(char)* abspath = FileName.searchPath(paths, argv0, false);
if (abspath)
{
const(char)* absname = FileName.replaceName(abspath, inifile);
if (FileName.exists(absname))
return absname;
}
// Resolve symbolic links
filename = FileName.canonicalName(abspath ? abspath : argv0);
if (filename)
{
filename = FileName.replaceName(filename, inifile);
if (FileName.exists(filename))
return filename;
}
// Search /etc/ for inifile
enum SYSCONFDIR = "/etc/dmd.conf";
assert(SYSCONFDIR !is null && strlen(SYSCONFDIR));
filename = FileName.combine(SYSCONFDIR, inifile);
}
// __linux__ || __APPLE__ || __FreeBSD__ || __OpenBSD__ || __sun
return filename;
}

/**********************************
* Read from environment, looking for cached value first.
*/
extern (C++) const(char)* readFromEnv(StringTable* environment, const(char)* name)
{
size_t len = strlen(name);
StringValue* sv = environment.lookup(name, len);
if (sv)
return cast(const(char)*)sv.ptrvalue; // get cached value
return getenv(name);
}

/*********************************
* Write to our copy of the environment, not the real environment
*/
extern (C++) static void writeToEnv(StringTable* environment, char* nameEqValue)
{
char* p = strchr(nameEqValue, '=');
assert(p);
StringValue* sv = environment.update(nameEqValue, p - nameEqValue);
sv.ptrvalue = cast(void*)(p + 1);
}

/************************************
* Update real enviroment with our copy.
*/
extern (C++) static int envput(StringValue* sv)
{
const(char)* name = sv.toDchars();
size_t namelen = strlen(name);
const(char)* value = cast(const(char)*)sv.ptrvalue;
size_t valuelen = strlen(value);
char* s = cast(char*)malloc(namelen + 1 + valuelen + 1);
assert(s);
memcpy(s, name, namelen);
s[namelen] = '=';
memcpy(s + namelen + 1, value, valuelen);
s[namelen + 1 + valuelen] = 0;
//printf("envput('%s')\n", s);
putenv(s);
return 0; // do all of them
}

extern (C++) void updateRealEnvironment(StringTable* environment)
{
environment.apply(&envput);
}

/*****************************
* Read and analyze .ini file.
* Write the entries into environment as
* well as any entries in one of the specified section(s).
*
* Params:
* environment = our own cache of the program environment
* path = what @P will expand to
* buffer[len] = contents of configuration file
* sections[] = section namesdimension of array of section names
*/
extern (C++) void parseConfFile(StringTable* environment, const(char)* path, size_t length, ubyte* buffer, Strings* sections)
{
// Parse into lines
bool envsection = true; // default is to read
OutBuffer buf;
bool eof = false;
for (size_t i = 0; i < length && !eof; i++)
{
Lstart:
size_t linestart = i;
for (; i < length; i++)
{
switch (buffer[i])
{
case '\r':
break;
case '\n':
// Skip if it was preceded by '\r'
if (i && buffer[i - 1] == '\r')
{
i++;
goto Lstart;
}
break;
case 0:
case 0x1A:
eof = true;
break;
default:
continue;
}
break;
}
buf.reset();
// First, expand the macros.
// Macros are bracketed by % characters.
for (size_t k = 0; k < i - linestart; k++)
{
// The line is buffer[linestart..i]
char* line = cast(char*)&buffer[linestart];
if (line[k] == '%')
{
for (size_t j = k + 1; j < i - linestart; j++)
{
if (line[j] != '%')
continue;
if (j - k == 3 && Port.memicmp(&line[k + 1], "@P", 2) == 0)
{
// %@P% is special meaning the path to the .ini file
const(char)* p = path;
if (!*p)
p = ".";
buf.writestring(p);
}
else
{
size_t len2 = j - k;
char* p = cast(char*)malloc(len2);
len2--;
memcpy(p, &line[k + 1], len2);
p[len2] = 0;
Port.strupr(p);
const(char)* penv = readFromEnv(environment, p);
if (penv)
buf.writestring(penv);
free(p);
}
k = j;
goto L1;
}
}
buf.writeByte(line[k]);
L1:
}
// Remove trailing spaces
while (buf.offset && isspace(buf.data[buf.offset - 1]))
buf.offset--;
char* p = buf.peekString();
// The expanded line is in p.
// Now parse it for meaning.
p = skipspace(p);
switch (*p)
{
case ';':
// comment
case 0:
// blank
break;
case '[':
// look for [Environment]
p = skipspace(p + 1);
char* pn;
for (pn = p; isalnum(cast(char)*pn); pn++)
{
}
if (*skipspace(pn) != ']')
{
// malformed [sectionname], so just say we're not in a section
envsection = false;
break;
}
/* Seach sectionnamev[] for p..pn and set envsection to true if it's there
*/
for (size_t j = 0; 1; ++j)
{
if (j == sections.dim)
{
// Didn't find it
envsection = false;
break;
}
const(char)* sectionname = (*sections)[j];
size_t len = strlen(sectionname);
if (pn - p == len && Port.memicmp(p, sectionname, len) == 0)
{
envsection = true;
break;
}
}
break;
default:
if (envsection)
{
char* pn = p;
// Convert name to upper case;
// remove spaces bracketing =
for (p = pn; *p; p++)
{
if (islower(cast(char)*p))
*p &= ~0x20;
else if (isspace(cast(char)*p))
{
memmove(p, p + 1, strlen(p));
p--;
}
else if (p[0] == '?' && p[1] == '=')
{
*p = '\0';
if (readFromEnv(environment, pn))
{
pn = null;
break;
}
// remove the '?' and resume parsing starting from
// '=' again so the regular variable format is
// parsed
memmove(p, p + 1, strlen(p + 1) + 1);
p--;
}
else if (*p == '=')
{
p++;
while (isspace(cast(char)*p))
memmove(p, p + 1, strlen(p));
break;
}
}
if (pn)
{
writeToEnv(environment, strdup(pn));
static if (LOG)
{
printf("\tputenv('%s')\n", pn);
//printf("getenv(\"TEST\") = '%s'\n",getenv("TEST"));
}
}
}
break;
}
}
}

/********************
* Skip spaces.
*/
extern (C++) char* skipspace(char* p)
{
while (isspace(cast(char)*p))
p++;
return p;
}
6,586 changes: 6,586 additions & 0 deletions src/dinterpret.d

Large diffs are not rendered by default.

408 changes: 408 additions & 0 deletions src/dmacro.d

Large diffs are not rendered by default.

842 changes: 842 additions & 0 deletions src/dmangle.d

Large diffs are not rendered by default.

1,309 changes: 1,309 additions & 0 deletions src/dmodule.d

Large diffs are not rendered by default.

2,804 changes: 0 additions & 2,804 deletions src/doc.c

This file was deleted.

2,465 changes: 2,465 additions & 0 deletions src/doc.d

Large diffs are not rendered by default.

601 changes: 601 additions & 0 deletions src/dscope.d

Large diffs are not rendered by default.

858 changes: 858 additions & 0 deletions src/dstruct.d

Large diffs are not rendered by default.

1,694 changes: 0 additions & 1,694 deletions src/dsymbol.c

This file was deleted.

1,977 changes: 1,977 additions & 0 deletions src/dsymbol.d

Large diffs are not rendered by default.

8,048 changes: 8,048 additions & 0 deletions src/dtemplate.d

Large diffs are not rendered by default.

19 changes: 19 additions & 0 deletions src/dunittest.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2015 by Digital Mars
// 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

module ddmd.dunittest;

extern (C++) void unittests()
{
version (unittest)
{
unittest_speller();
unittest_importHint();
unittest_aa();
}
}
203 changes: 203 additions & 0 deletions src/dversion.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2015 by Digital Mars
// 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

module ddmd.dversion;

import ddmd.arraytypes, ddmd.cond, ddmd.dmodule, ddmd.dmodule, ddmd.dscope, ddmd.dsymbol, ddmd.globals, ddmd.hdrgen, ddmd.identifier, ddmd.root.outbuffer, ddmd.visitor;

extern (C++) final class DebugSymbol : Dsymbol
{
public:
uint level;

/* ================================================== */
/* DebugSymbol's happen for statements like:
* debug = identifier;
* debug = integer;
*/
extern (D) this(Loc loc, Identifier ident)
{
super(ident);
this.loc = loc;
}

extern (D) this(Loc loc, uint level)
{
super();
this.level = level;
this.loc = loc;
}

Dsymbol syntaxCopy(Dsymbol s)
{
assert(!s);
auto ds = new DebugSymbol(loc, ident);
ds.level = level;
return ds;
}

char* toChars()
{
if (ident)
return ident.toChars();
else
{
OutBuffer buf;
buf.printf("%d", level);
return buf.extractString();
}
}

void addMember(Scope* sc, ScopeDsymbol sds)
{
//printf("DebugSymbol::addMember('%s') %s\n", sds->toChars(), toChars());
Module m = sds.isModule();
// Do not add the member to the symbol table,
// just make sure subsequent debug declarations work.
if (ident)
{
if (!m)
{
error("declaration must be at module level");
errors = true;
}
else
{
if (findCondition(m.debugidsNot, ident))
{
error("defined after use");
errors = true;
}
if (!m.debugids)
m.debugids = new Strings();
m.debugids.push(ident.toChars());
}
}
else
{
if (!m)
{
error("level declaration must be at module level");
errors = true;
}
else
m.debuglevel = level;
}
}

void semantic(Scope* sc)
{
//printf("DebugSymbol::semantic() %s\n", toChars());
}

const(char)* kind()
{
return "debug";
}

void accept(Visitor v)
{
v.visit(this);
}
}

extern (C++) final class VersionSymbol : Dsymbol
{
public:
uint level;

/* ================================================== */
/* VersionSymbol's happen for statements like:
* version = identifier;
* version = integer;
*/
extern (D) this(Loc loc, Identifier ident)
{
super(ident);
this.loc = loc;
}

extern (D) this(Loc loc, uint level)
{
super();
this.level = level;
this.loc = loc;
}

Dsymbol syntaxCopy(Dsymbol s)
{
assert(!s);
auto ds = new VersionSymbol(loc, ident);
ds.level = level;
return ds;
}

char* toChars()
{
if (ident)
return ident.toChars();
else
{
OutBuffer buf;
buf.printf("%d", level);
return buf.extractString();
}
}

void addMember(Scope* sc, ScopeDsymbol sds)
{
//printf("VersionSymbol::addMember('%s') %s\n", sds->toChars(), toChars());
Module m = sds.isModule();
// Do not add the member to the symbol table,
// just make sure subsequent debug declarations work.
if (ident)
{
VersionCondition.checkPredefined(loc, ident.toChars());
if (!m)
{
error("declaration must be at module level");
errors = true;
}
else
{
if (findCondition(m.versionidsNot, ident))
{
error("defined after use");
errors = true;
}
if (!m.versionids)
m.versionids = new Strings();
m.versionids.push(ident.toChars());
}
}
else
{
if (!m)
{
error("level declaration must be at module level");
errors = true;
}
else
m.versionlevel = level;
}
}

void semantic(Scope* sc)
{
}

const(char)* kind()
{
return "version";
}

void accept(Visitor v)
{
v.visit(this);
}
}
2,393 changes: 0 additions & 2,393 deletions src/entity.c

This file was deleted.

720 changes: 0 additions & 720 deletions src/enum.c

This file was deleted.

281 changes: 0 additions & 281 deletions src/errors.c

This file was deleted.

287 changes: 287 additions & 0 deletions src/errors.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,287 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2015 by Digital Mars
// 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

module ddmd.errors;

import core.stdc.stdarg, core.stdc.stdio, core.stdc.stdlib, core.stdc.string, core.sys.posix.unistd, core.sys.windows.windows;
import ddmd.globals, ddmd.root.outbuffer, ddmd.root.rmem;

version (Windows) extern (C) int isatty(int);
version (Windows) alias _isatty = isatty;
version (Windows) int _fileno(FILE* f)
{
return f._file;
}

enum COLOR : int
{
COLOR_BLACK = 0,
COLOR_RED = 1,
COLOR_GREEN = 2,
COLOR_BLUE = 4,
COLOR_YELLOW = COLOR_RED | COLOR_GREEN,
COLOR_MAGENTA = COLOR_RED | COLOR_BLUE,
COLOR_CYAN = COLOR_GREEN | COLOR_BLUE,
COLOR_WHITE = COLOR_RED | COLOR_GREEN | COLOR_BLUE,
}

alias COLOR_BLACK = COLOR.COLOR_BLACK;
alias COLOR_RED = COLOR.COLOR_RED;
alias COLOR_GREEN = COLOR.COLOR_GREEN;
alias COLOR_BLUE = COLOR.COLOR_BLUE;
alias COLOR_YELLOW = COLOR.COLOR_YELLOW;
alias COLOR_MAGENTA = COLOR.COLOR_MAGENTA;
alias COLOR_CYAN = COLOR.COLOR_CYAN;
alias COLOR_WHITE = COLOR.COLOR_WHITE;

version (Windows)
{
extern (C++) static WORD consoleAttributes(HANDLE h)
{
static __gshared CONSOLE_SCREEN_BUFFER_INFO sbi;
static __gshared bool sbi_inited = false;
if (!sbi_inited)
sbi_inited = GetConsoleScreenBufferInfo(h, &sbi) != FALSE;
return sbi.wAttributes;
}

enum : int
{
FOREGROUND_WHITE = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE,
}
}

extern (C++) bool isConsoleColorSupported()
{
version (Windows)
{
return _isatty(_fileno(stderr)) != 0;
}
else static if (__linux__ || __APPLE__ || __FreeBSD__ || __OpenBSD__ || __sun)
{
const(char)* term = getenv("TERM");
return isatty(STDERR_FILENO) && term && term[0] && 0 != strcmp(term, "dumb");
}
else
{
return false;
}
}

extern (C++) void setConsoleColorBright(bool bright)
{
version (Windows)
{
HANDLE h = GetStdHandle(STD_ERROR_HANDLE);
WORD attr = consoleAttributes(h);
SetConsoleTextAttribute(h, attr | (bright ? FOREGROUND_INTENSITY : 0));
}
else
{
fprintf(stderr, "\033[%dm", bright ? 1 : 0);
}
}

extern (C++) void setConsoleColor(COLOR color, bool bright)
{
version (Windows)
{
HANDLE h = GetStdHandle(STD_ERROR_HANDLE);
WORD attr = consoleAttributes(h);
attr = (attr & ~(FOREGROUND_WHITE | FOREGROUND_INTENSITY)) | ((color & COLOR_RED) ? FOREGROUND_RED : 0) | ((color & COLOR_GREEN) ? FOREGROUND_GREEN : 0) | ((color & COLOR_BLUE) ? FOREGROUND_BLUE : 0) | (bright ? FOREGROUND_INTENSITY : 0);
SetConsoleTextAttribute(h, attr);
}
else
{
fprintf(stderr, "\033[%d;%dm", bright ? 1 : 0, 30 + cast(int)color);
}
}

extern (C++) void resetConsoleColor()
{
version (Windows)
{
HANDLE h = GetStdHandle(STD_ERROR_HANDLE);
SetConsoleTextAttribute(h, consoleAttributes(h));
}
else
{
fprintf(stderr, "\033[m");
}
}

/**************************************
* Print error message
*/
extern (C++) void error(Loc loc, const(char)* format, ...)
{
va_list ap;
va_start(ap, format);
verror(loc, format, ap);
va_end(ap);
}

extern (C++) void error(const(char)* filename, uint linnum, uint charnum, const(char)* format, ...)
{
Loc loc;
loc.filename = cast(char*)filename;
loc.linnum = linnum;
loc.charnum = charnum;
va_list ap;
va_start(ap, format);
verror(loc, format, ap);
va_end(ap);
}

extern (C++) void errorSupplemental(Loc loc, const(char)* format, ...)
{
va_list ap;
va_start(ap, format);
verrorSupplemental(loc, format, ap);
va_end(ap);
}

extern (C++) void warning(Loc loc, const(char)* format, ...)
{
va_list ap;
va_start(ap, format);
vwarning(loc, format, ap);
va_end(ap);
}

extern (C++) void warningSupplemental(Loc loc, const(char)* format, ...)
{
va_list ap;
va_start(ap, format);
vwarningSupplemental(loc, format, ap);
va_end(ap);
}

extern (C++) void deprecation(Loc loc, const(char)* format, ...)
{
va_list ap;
va_start(ap, format);
vdeprecation(loc, format, ap);
va_end(ap);
}

extern (C++) void deprecationSupplemental(Loc loc, const(char)* format, ...)
{
va_list ap;
va_start(ap, format);
vdeprecation(loc, format, ap);
va_end(ap);
}

// Just print, doesn't care about gagging
extern (C++) void verrorPrint(Loc loc, COLOR headerColor, const(char)* header, const(char)* format, va_list ap, const(char)* p1 = null, const(char)* p2 = null)
{
char* p = loc.toChars();
if (global.params.color)
setConsoleColorBright(true);
if (*p)
fprintf(stderr, "%s: ", p);
mem.xfree(p);
if (global.params.color)
setConsoleColor(headerColor, true);
fputs(header, stderr);
if (global.params.color)
resetConsoleColor();
if (p1)
fprintf(stderr, "%s ", p1);
if (p2)
fprintf(stderr, "%s ", p2);
OutBuffer tmp;
tmp.vprintf(format, ap);
fprintf(stderr, "%s\n", tmp.peekString());
fflush(stderr);
}

// header is "Error: " by default (see errors.h)
extern (C++) void verror(Loc loc, const(char)* format, va_list ap, const(char)* p1 = null, const(char)* p2 = null, const(char)* header = "Error: ")
{
global.errors++;
if (!global.gag)
{
verrorPrint(loc, COLOR_RED, header, format, ap, p1, p2);
if (global.errorLimit && global.errors >= global.errorLimit)
fatal(); // moderate blizzard of cascading messages
}
else
{
//fprintf(stderr, "(gag:%d) ", global.gag);
//verrorPrint(loc, COLOR_RED, header, format, ap, p1, p2);
global.gaggedErrors++;
}
}

// Doesn't increase error count, doesn't print "Error:".
extern (C++) void verrorSupplemental(Loc loc, const(char)* format, va_list ap)
{
if (!global.gag)
verrorPrint(loc, COLOR_RED, " ", format, ap);
}

extern (C++) void vwarning(Loc loc, const(char)* format, va_list ap)
{
if (global.params.warnings && !global.gag)
{
verrorPrint(loc, COLOR_YELLOW, "Warning: ", format, ap);
//halt();
if (global.params.warnings == 1)
global.warnings++; // warnings don't count if gagged
}
}

extern (C++) void vwarningSupplemental(Loc loc, const(char)* format, va_list ap)
{
if (global.params.warnings && !global.gag)
verrorPrint(loc, COLOR_YELLOW, " ", format, ap);
}

extern (C++) void vdeprecation(Loc loc, const(char)* format, va_list ap, const(char)* p1 = null, const(char)* p2 = null)
{
static __gshared const(char)* header = "Deprecation: ";
if (global.params.useDeprecated == 0)
verror(loc, format, ap, p1, p2, header);
else if (global.params.useDeprecated == 2 && !global.gag)
verrorPrint(loc, COLOR_BLUE, header, format, ap, p1, p2);
}

extern (C++) void vdeprecationSupplemental(Loc loc, const(char)* format, va_list ap)
{
if (global.params.useDeprecated == 0)
verrorSupplemental(loc, format, ap);
else if (global.params.useDeprecated == 2 && !global.gag)
verrorPrint(loc, COLOR_BLUE, " ", format, ap);
}

/***************************************
* Call this after printing out fatal error messages to clean up and exit
* the compiler.
*/
extern (C++) void fatal()
{
version (none)
{
halt();
}
exit(EXIT_FAILURE);
}

/**************************************
* Try to stop forgetting to remove the breakpoints from
* release builds.
*/
extern (C++) void halt()
{
debug
{
*cast(char*)0 = 0;
}
}
Loading