439 changes: 0 additions & 439 deletions src/escape.c

This file was deleted.

428 changes: 428 additions & 0 deletions src/escape.d

Large diffs are not rendered by default.

14,251 changes: 0 additions & 14,251 deletions src/expression.c

This file was deleted.

14,450 changes: 14,450 additions & 0 deletions src/expression.d

Large diffs are not rendered by default.

5,441 changes: 0 additions & 5,441 deletions src/func.c

This file was deleted.

5,362 changes: 5,362 additions & 0 deletions src/func.d

Large diffs are not rendered by default.

134 changes: 0 additions & 134 deletions src/globals.c

This file was deleted.

431 changes: 431 additions & 0 deletions src/globals.d

Large diffs are not rendered by default.

3,280 changes: 0 additions & 3,280 deletions src/hdrgen.c

This file was deleted.

3,168 changes: 3,168 additions & 0 deletions src/hdrgen.d

Large diffs are not rendered by default.

137 changes: 0 additions & 137 deletions src/identifier.c

This file was deleted.

141 changes: 141 additions & 0 deletions src/identifier.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
// 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.identifier;

import core.stdc.stdio, core.stdc.string;
import ddmd.globals, ddmd.id, ddmd.root.outbuffer, ddmd.root.rootobject, ddmd.root.stringtable, ddmd.tokens;

extern (C++) final class Identifier : RootObject
{
public:
int value;
const(char)* string;
size_t len;

extern (D) this(const(char)* string, int value)
{
//printf("Identifier('%s', %d)\n", string, value);
this.string = string;
this.value = value;
this.len = strlen(string);
}

static Identifier create(const(char)* string, int value)
{
return new Identifier(string, value);
}

bool equals(RootObject o)
{
return this == o || strncmp(string, o.toChars(), len + 1) == 0;
}

int compare(RootObject o)
{
return strncmp(string, o.toChars(), len + 1);
}

void print()
{
fprintf(stderr, "%s", string);
}

char* toChars()
{
return cast(char*)string;
}

const(char)* toHChars2()
{
const(char)* p = null;
if (this == Id.ctor)
p = "this";
else if (this == Id.dtor)
p = "~this";
else if (this == Id.unitTest)
p = "unittest";
else if (this == Id.dollar)
p = "$";
else if (this == Id.withSym)
p = "with";
else if (this == Id.result)
p = "result";
else if (this == Id.returnLabel)
p = "return";
else
{
p = toChars();
if (*p == '_')
{
if (strncmp(p, "_staticCtor", 11) == 0)
p = "static this";
else if (strncmp(p, "_staticDtor", 11) == 0)
p = "static ~this";
else if (strncmp(p, "__invariant", 11) == 0)
p = "invariant";
}
}
return p;
}

int dyncast()
{
return DYNCAST_IDENTIFIER;
}

extern (C++) static __gshared StringTable stringtable;

static Identifier generateId(const(char)* prefix)
{
static __gshared size_t i;
return generateId(prefix, ++i);
}

static Identifier generateId(const(char)* prefix, size_t i)
{
OutBuffer buf;
buf.writestring(prefix);
buf.printf("%llu", cast(ulong)i);
char* id = buf.peekString();
return idPool(id);
}

/********************************************
* Create an identifier in the string table.
*/
static Identifier idPool(const(char)* s)
{
return idPool(s, strlen(s));
}

static Identifier idPool(const(char)* s, size_t len)
{
StringValue* sv = stringtable.update(s, len);
Identifier id = cast(Identifier)sv.ptrvalue;
if (!id)
{
id = new Identifier(sv.toDchars(), TOKidentifier);
sv.ptrvalue = cast(char*)id;
}
return id;
}

static Identifier lookup(const(char)* s, size_t len)
{
StringValue* sv = stringtable.lookup(s, len);
if (!sv)
return null;
return cast(Identifier)sv.ptrvalue;
}

static void initTable()
{
stringtable._init(28000);
}
}
75 changes: 0 additions & 75 deletions src/imphint.c

This file was deleted.

65 changes: 65 additions & 0 deletions src/imphint.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// 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.imphint;

import core.stdc.string;

/******************************************
* Looks for undefined identifier s to see
* if it might be undefined because an import
* was not specified.
* Not meant to be a comprehensive list of names in each module,
* just the most common ones.
*/
extern (C++) const(char)* importHint(const(char)* s)
{
static __gshared const(char)** modules = ["core.stdc.stdio", "std.stdio", "std.math", "core.vararg", null];
static __gshared const(char)** names =
[
"printf",
null,
"writeln",
null,
"sin",
"cos",
"sqrt",
"fabs",
null,
"__va_argsave_t",
null
];
int m = 0;
for (int n = 0; modules[m]; n++)
{
const(char)* p = names[n];
if (p is null)
{
m++;
continue;
}
assert(modules[m]);
if (strcmp(s, p) == 0)
return modules[m];
}
return null; // didn't find it
}

version (unittest)
{
extern (C++) void unittest_importHint()
{
const(char)* p;
p = importHint("printf");
assert(p);
p = importHint("fabs");
assert(p);
p = importHint("xxxxx");
assert(!p);
}
}
457 changes: 0 additions & 457 deletions src/import.c

This file was deleted.

380 changes: 0 additions & 380 deletions src/inifile.c

This file was deleted.

1,001 changes: 0 additions & 1,001 deletions src/init.c

This file was deleted.

1,045 changes: 1,045 additions & 0 deletions src/init.d

Large diffs are not rendered by default.

2,101 changes: 0 additions & 2,101 deletions src/inline.c

This file was deleted.

1,962 changes: 1,962 additions & 0 deletions src/inline.d

Large diffs are not rendered by default.

6,925 changes: 0 additions & 6,925 deletions src/interpret.c

This file was deleted.

1,107 changes: 0 additions & 1,107 deletions src/intrange.c

This file was deleted.

890 changes: 0 additions & 890 deletions src/json.c

This file was deleted.

770 changes: 770 additions & 0 deletions src/json.d

Large diffs are not rendered by default.

2,484 changes: 0 additions & 2,484 deletions src/lexer.c

This file was deleted.

2,493 changes: 2,493 additions & 0 deletions src/lexer.d

Large diffs are not rendered by default.

48 changes: 48 additions & 0 deletions src/lib.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// 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.lib;

import ddmd.globals;

extern (C++) Library LibOMF_factory();
extern (C++) Library LibElf_factory();
extern (C++) Library LibMSCoff_factory();
extern (C++) Library LibMach_factory();

extern (C++) class Library
{
public:
final static Library factory()
{
static if (TARGET_WINDOS)
{
return global.params.is64bit ? LibMSCoff_factory() : LibOMF_factory();
}
else static if (TARGET_LINUX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS)
{
return LibElf_factory();
}
else static if (TARGET_OSX)
{
return LibMach_factory();
}
else
{
assert(0); // unsupported system
}
}

abstract void setFilename(const(char)* dir, const(char)* filename);

abstract void addObject(const(char)* module_name, void* buf, size_t buflen);

abstract void addLibrary(void* buf, size_t buflen);

abstract void write();
}
911 changes: 0 additions & 911 deletions src/link.c

This file was deleted.

838 changes: 838 additions & 0 deletions src/link.d

Large diffs are not rendered by default.

468 changes: 0 additions & 468 deletions src/macro.c

This file was deleted.

909 changes: 0 additions & 909 deletions src/mangle.c

This file was deleted.

1,904 changes: 0 additions & 1,904 deletions src/mars.c

This file was deleted.

1,689 changes: 1,689 additions & 0 deletions src/mars.d

Large diffs are not rendered by default.

1,328 changes: 0 additions & 1,328 deletions src/module.c

This file was deleted.

9,207 changes: 0 additions & 9,207 deletions src/mtype.c

This file was deleted.

9,523 changes: 9,523 additions & 0 deletions src/mtype.d

Large diffs are not rendered by default.

214 changes: 0 additions & 214 deletions src/nogc.c

This file was deleted.

182 changes: 182 additions & 0 deletions src/nogc.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
// 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.nogc;

import ddmd.apply, ddmd.declaration, ddmd.dscope, ddmd.expression, ddmd.func, ddmd.globals, ddmd.id, ddmd.identifier, ddmd.init, ddmd.mtype, ddmd.sapply, ddmd.statement, ddmd.tokens, ddmd.visitor;

/**************************************
* Look for GC-allocations
*/
extern (C++) final class NOGCVisitor : StoppableVisitor
{
alias visit = super.visit;
public:
FuncDeclaration f;
bool err;

extern (D) this(FuncDeclaration f)
{
this.f = f;
this.err = false;
}

void doCond(Expression exp)
{
if (exp)
walkPostorder(exp, this);
}

void visit(Expression e)
{
}

void visit(DeclarationExp e)
{
// Note that, walkPostorder does not support DeclarationExp today.
VarDeclaration v = e.declaration.isVarDeclaration();
if (v && !(v.storage_class & STCmanifest) && !v.isDataseg() && v._init)
{
if (ExpInitializer ei = v._init.isExpInitializer())
{
doCond(ei.exp);
}
}
}

void visit(CallExp e)
{
}

void visit(ArrayLiteralExp e)
{
if (e.type.ty != Tarray || !e.elements || !e.elements.dim)
return;
if (f.setGC())
{
e.error("array literal in @nogc function %s may cause GC allocation", f.toChars());
err = true;
return;
}
f.printGCUsage(e.loc, "array literal may cause GC allocation");
}

void visit(AssocArrayLiteralExp e)
{
if (!e.keys.dim)
return;
if (f.setGC())
{
e.error("associative array literal in @nogc function %s may cause GC allocation", f.toChars());
err = true;
return;
}
f.printGCUsage(e.loc, "associative array literal may cause GC allocation");
}

void visit(NewExp e)
{
if (e.member && !e.member.isNogc() && f.setGC())
{
// @nogc-ness is already checked in NewExp::semantic
return;
}
if (e.onstack)
return;
if (e.allocator)
return;
if (f.setGC())
{
e.error("cannot use 'new' in @nogc function %s", f.toChars());
err = true;
return;
}
f.printGCUsage(e.loc, "'new' causes GC allocation");
}

void visit(DeleteExp e)
{
if (e.e1.op == TOKvar)
{
VarDeclaration v = (cast(VarExp)e.e1).var.isVarDeclaration();
if (v && v.onstack)
return; // delete for scope allocated class object
}
if (f.setGC())
{
e.error("cannot use 'delete' in @nogc function %s", f.toChars());
err = true;
return;
}
f.printGCUsage(e.loc, "'delete' requires GC");
}

void visit(IndexExp e)
{
Type t1b = e.e1.type.toBasetype();
if (t1b.ty == Taarray)
{
if (f.setGC())
{
e.error("indexing an associative array in @nogc function %s may cause GC allocation", f.toChars());
err = true;
return;
}
f.printGCUsage(e.loc, "indexing an associative array may cause GC allocation");
}
}

void visit(AssignExp e)
{
if (e.e1.op == TOKarraylength)
{
if (f.setGC())
{
e.error("setting 'length' in @nogc function %s may cause GC allocation", f.toChars());
err = true;
return;
}
f.printGCUsage(e.loc, "setting 'length' may cause GC allocation");
}
}

void visit(CatAssignExp e)
{
if (f.setGC())
{
e.error("cannot use operator ~= in @nogc function %s", f.toChars());
err = true;
return;
}
f.printGCUsage(e.loc, "operator ~= may cause GC allocation");
}

void visit(CatExp e)
{
if (f.setGC())
{
e.error("cannot use operator ~ in @nogc function %s", f.toChars());
err = true;
return;
}
f.printGCUsage(e.loc, "operator ~ may cause GC allocation");
}
}

extern (C++) Expression checkGC(Scope* sc, Expression e)
{
FuncDeclaration f = sc.func;
if (e && e.op != TOKerror && f && sc.intypeof != 1 && !(sc.flags & SCOPEctfe) && (f.type.ty == Tfunction && (cast(TypeFunction)f.type).isnogc || (f.flags & FUNCFLAGnogcInprocess) || global.params.vgc))
{
scope NOGCVisitor gcv = new NOGCVisitor(f);
walkPostorder(e, gcv);
if (gcv.err)
return new ErrorExp();
}
return e;
}
214 changes: 0 additions & 214 deletions src/nspace.c

This file was deleted.

226 changes: 226 additions & 0 deletions src/nspace.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,226 @@
// 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.nspace;

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

private enum LOG = false;

/* A namespace corresponding to a C++ namespace.
* Implies extern(C++).
*/
extern (C++) final class Nspace : ScopeDsymbol
{
public:
/* This implements namespaces.
*/
extern (D) this(Loc loc, Identifier ident, Dsymbols* members)
{
super(ident);
//printf("Nspace::Nspace(ident = %s)\n", ident->toChars());
this.loc = loc;
this.members = members;
}

Dsymbol syntaxCopy(Dsymbol s)
{
auto ns = new Nspace(loc, ident, null);
return ScopeDsymbol.syntaxCopy(ns);
}

void semantic(Scope* sc)
{
if (semanticRun >= PASSsemantic)
return;
semanticRun = PASSsemantic;
static if (LOG)
{
printf("+Nspace::semantic('%s')\n", toChars());
}
if (_scope)
{
sc = _scope;
_scope = null;
}
parent = sc.parent;
if (members)
{
if (!symtab)
symtab = new DsymbolTable();
// The namespace becomes 'imported' into the enclosing scope
for (Scope* sce = sc; 1; sce = sce.enclosing)
{
ScopeDsymbol sds = cast(ScopeDsymbol)sce.scopesym;
if (sds)
{
sds.importScope(this, Prot(PROTpublic));
break;
}
}
assert(sc);
sc = sc.push(this);
sc.linkage = LINKcpp; // note that namespaces imply C++ linkage
sc.parent = this;
for (size_t i = 0; i < members.dim; i++)
{
Dsymbol s = (*members)[i];
//printf("add %s to scope %s\n", s->toChars(), toChars());
s.addMember(sc, this);
}
for (size_t i = 0; i < members.dim; i++)
{
Dsymbol s = (*members)[i];
s.setScope(sc);
}
for (size_t i = 0; i < members.dim; i++)
{
Dsymbol s = (*members)[i];
s.importAll(sc);
}
for (size_t i = 0; i < members.dim; i++)
{
Dsymbol s = (*members)[i];
static if (LOG)
{
printf("\tmember '%s', kind = '%s'\n", s.toChars(), s.kind());
}
s.semantic(sc);
}
sc.pop();
}
static if (LOG)
{
printf("-Nspace::semantic('%s')\n", toChars());
}
}

void semantic2(Scope* sc)
{
if (semanticRun >= PASSsemantic2)
return;
semanticRun = PASSsemantic2;
static if (LOG)
{
printf("+Nspace::semantic2('%s')\n", toChars());
}
if (members)
{
assert(sc);
sc = sc.push(this);
sc.linkage = LINKcpp;
for (size_t i = 0; i < members.dim; i++)
{
Dsymbol s = (*members)[i];
static if (LOG)
{
printf("\tmember '%s', kind = '%s'\n", s.toChars(), s.kind());
}
s.semantic2(sc);
}
sc.pop();
}
static if (LOG)
{
printf("-Nspace::semantic2('%s')\n", toChars());
}
}

void semantic3(Scope* sc)
{
if (semanticRun >= PASSsemantic3)
return;
semanticRun = PASSsemantic3;
static if (LOG)
{
printf("Nspace::semantic3('%s')\n", toChars());
}
if (members)
{
sc = sc.push(this);
sc.linkage = LINKcpp;
for (size_t i = 0; i < members.dim; i++)
{
Dsymbol s = (*members)[i];
s.semantic3(sc);
}
sc.pop();
}
}

bool oneMember(Dsymbol* ps, Identifier ident)
{
return Dsymbol.oneMember(ps, ident);
}

int apply(Dsymbol_apply_ft_t fp, void* param)
{
if (members)
{
for (size_t i = 0; i < members.dim; i++)
{
Dsymbol s = (*members)[i];
if (s)
{
if (s.apply(fp, param))
return 1;
}
}
}
return 0;
}

bool hasPointers()
{
//printf("Nspace::hasPointers() %s\n", toChars());
if (members)
{
for (size_t i = 0; i < members.dim; i++)
{
Dsymbol s = (*members)[i];
//printf(" s = %s %s\n", s->kind(), s->toChars());
if (s.hasPointers())
{
return true;
}
}
}
return false;
}

void setFieldOffset(AggregateDeclaration ad, uint* poffset, bool isunion)
{
//printf("Nspace::setFieldOffset() %s\n", toChars());
if (_scope) // if fwd reference
semantic(null); // try to resolve it
if (members)
{
for (size_t i = 0; i < members.dim; i++)
{
Dsymbol s = (*members)[i];
//printf("\t%s\n", s->toChars());
s.setFieldOffset(ad, poffset, isunion);
}
}
}

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

Nspace isNspace()
{
return this;
}

void accept(Visitor v)
{
v.visit(this);
}
}
241 changes: 0 additions & 241 deletions src/objc.c

This file was deleted.

213 changes: 213 additions & 0 deletions src/objc.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
// 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.objc;

import ddmd.arraytypes, ddmd.cond, ddmd.dclass, ddmd.dmangle, ddmd.dmodule, ddmd.dscope, ddmd.dstruct, ddmd.expression, ddmd.func, ddmd.globals, ddmd.id, ddmd.identifier, ddmd.mtype, ddmd.root.outbuffer, ddmd.root.stringtable;

extern(C++) void objc_initSymbols();

struct ObjcSelector
{
// MARK: Selector
extern (C++) static __gshared StringTable stringtable;
extern (C++) static __gshared StringTable vTableDispatchSelectors;
extern (C++) static __gshared int incnum = 0;
const(char)* stringvalue;
size_t stringlen;
size_t paramCount;

extern (C++) static void _init()
{
stringtable._init();
}

extern (D) this(const(char)* sv, size_t len, size_t pcount)
{
stringvalue = sv;
stringlen = len;
paramCount = pcount;
}

extern (C++) static ObjcSelector* lookup(const(char)* s)
{
size_t len = 0;
size_t pcount = 0;
const(char)* i = s;
while (*i != 0)
{
++len;
if (*i == ':')
++pcount;
++i;
}
return lookup(s, len, pcount);
}

extern (C++) static ObjcSelector* lookup(const(char)* s, size_t len, size_t pcount)
{
StringValue* sv = stringtable.update(s, len);
ObjcSelector* sel = cast(ObjcSelector*)sv.ptrvalue;
if (!sel)
{
sel = new ObjcSelector(sv.toDchars(), len, pcount);
sv.ptrvalue = cast(char*)sel;
}
return sel;
}

extern (C++) static ObjcSelector* create(FuncDeclaration fdecl)
{
OutBuffer buf;
size_t pcount = 0;
TypeFunction ftype = cast(TypeFunction)fdecl.type;
// Special case: property setter
if (ftype.isproperty && ftype.parameters && ftype.parameters.dim == 1)
{
// rewrite "identifier" as "setIdentifier"
char firstChar = fdecl.ident.string[0];
if (firstChar >= 'a' && firstChar <= 'z')
firstChar = cast(char)(firstChar - 'a' + 'A');
buf.writestring("set");
buf.writeByte(firstChar);
buf.write(fdecl.ident.string + 1, fdecl.ident.len - 1);
buf.writeByte(':');
goto Lcomplete;
}
// write identifier in selector
buf.write(fdecl.ident.string, fdecl.ident.len);
// add mangled type and colon for each parameter
if (ftype.parameters && ftype.parameters.dim)
{
buf.writeByte('_');
Parameters* arguments = ftype.parameters;
size_t dim = Parameter.dim(arguments);
for (size_t i = 0; i < dim; i++)
{
Parameter arg = Parameter.getNth(arguments, i);
mangleToBuffer(arg.type, &buf);
buf.writeByte(':');
}
pcount = dim;
}
Lcomplete:
buf.writeByte('\0');
return lookup(cast(const(char)*)buf.data, buf.size, pcount);
}
}

struct Objc_ClassDeclaration
{
// true if this is an Objective-C class/interface
bool objc;

// MARK: Objc_ClassDeclaration
extern (C++) bool isInterface()
{
return objc;
}
}

struct Objc_FuncDeclaration
{
FuncDeclaration fdecl;
// Objective-C method selector (member function only)
ObjcSelector* selector;

extern (D) this(FuncDeclaration fdecl)
{
this.fdecl = fdecl;
selector = null;
}
}

// MARK: semantic
extern (C++) void objc_ClassDeclaration_semantic_PASSinit_LINKobjc(ClassDeclaration cd)
{
cd.objc.objc = true;
}

extern (C++) void objc_InterfaceDeclaration_semantic_objcExtern(InterfaceDeclaration id, Scope* sc)
{
if (sc.linkage == LINKobjc)
id.objc.objc = true;
}

// MARK: semantic
extern (C++) void objc_FuncDeclaration_semantic_setSelector(FuncDeclaration fd, Scope* sc)
{
if (!fd.userAttribDecl)
return;
Expressions* udas = fd.userAttribDecl.getAttributes();
arrayExpressionSemantic(udas, sc, true);
for (size_t i = 0; i < udas.dim; i++)
{
Expression uda = (*udas)[i];
assert(uda.type);
if (uda.type.ty != Ttuple)
continue;
Expressions* exps = (cast(TupleExp)uda).exps;
for (size_t j = 0; j < exps.dim; j++)
{
Expression e = (*exps)[j];
assert(e.type);
if (e.type.ty != Tstruct)
continue;
StructLiteralExp literal = cast(StructLiteralExp)e;
assert(literal.sd);
if (!objc_isUdaSelector(literal.sd))
continue;
if (fd.objc.selector)
{
fd.error("can only have one Objective-C selector per method");
return;
}
assert(literal.elements.dim == 1);
StringExp se = (*literal.elements)[0].toStringExp();
assert(se);
fd.objc.selector = ObjcSelector.lookup(cast(const(char)*)se.toUTF8(sc).string);
}
}
}

extern (C++) bool objc_isUdaSelector(StructDeclaration sd)
{
if (sd.ident != Id.udaSelector || !sd.parent)
return false;
Module _module = sd.parent.isModule();
return _module && _module.isCoreModule(Id.attribute);
}

extern (C++) void objc_FuncDeclaration_semantic_validateSelector(FuncDeclaration fd)
{
if (!fd.objc.selector)
return;
TypeFunction tf = cast(TypeFunction)fd.type;
if (fd.objc.selector.paramCount != tf.parameters.dim)
fd.error("number of colons in Objective-C selector must match number of parameters");
if (fd.parent && fd.parent.isTemplateInstance())
fd.error("template cannot have an Objective-C selector attached");
}

extern (C++) void objc_FuncDeclaration_semantic_checkLinkage(FuncDeclaration fd)
{
if (fd.linkage != LINKobjc && fd.objc.selector)
fd.error("must have Objective-C linkage to attach a selector");
}

// MARK: init
extern (C++) void objc_tryMain_dObjc()
{
VersionCondition.addPredefinedGlobalIdent("D_ObjectiveC");
}

extern (C++) void objc_tryMain_init()
{
objc_initSymbols();
ObjcSelector._init();
}
118 changes: 0 additions & 118 deletions src/objc_stubs.c

This file was deleted.

1,825 changes: 0 additions & 1,825 deletions src/opover.c

This file was deleted.

1,929 changes: 1,929 additions & 0 deletions src/opover.d

Large diffs are not rendered by default.

1,263 changes: 0 additions & 1,263 deletions src/optimize.c

This file was deleted.

1,155 changes: 1,155 additions & 0 deletions src/optimize.d

Large diffs are not rendered by default.

8,007 changes: 0 additions & 8,007 deletions src/parse.c

This file was deleted.

7,770 changes: 7,770 additions & 0 deletions src/parse.d

Large diffs are not rendered by default.

193 changes: 0 additions & 193 deletions src/root/aav.c

This file was deleted.

171 changes: 171 additions & 0 deletions src/root/aav.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
// 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.root.aav;

import core.stdc.stdlib, core.stdc.string;
import ddmd.root.rmem;

extern (C++) size_t hash(size_t a)
{
a ^= (a >> 20) ^ (a >> 12);
return a ^ (a >> 7) ^ (a >> 4);
}

alias Key = void*;
alias Value = void*;

struct aaA
{
aaA* next;
Key key;
Value value;
}

struct AA
{
aaA** b;
size_t b_length;
size_t nodes; // total number of aaA nodes
aaA*[4] binit; // initial value of b[]
aaA aafirst; // a lot of these AA's have only one entry
}

/****************************************************
* Determine number of entries in associative array.
*/
extern (C++) size_t dmd_aaLen(AA* aa)
{
return aa ? aa.nodes : 0;
}

/*************************************************
* Get pointer to value in associative array indexed by key.
* Add entry for key if it is not already there, returning a pointer to a null Value.
* Create the associative array if it does not already exist.
*/
extern (C++) Value* dmd_aaGet(AA** paa, Key key)
{
//printf("paa = %p\n", paa);
if (!*paa)
{
AA* a = cast(AA*)mem.xmalloc(AA.sizeof);
a.b = cast(aaA**)a.binit;
a.b_length = 4;
a.nodes = 0;
a.binit[0] = null;
a.binit[1] = null;
a.binit[2] = null;
a.binit[3] = null;
*paa = a;
assert((*paa).b_length == 4);
}
//printf("paa = %p, *paa = %p\n", paa, *paa);
assert((*paa).b_length);
size_t i = hash(cast(size_t)key) & ((*paa).b_length - 1);
aaA** pe = &(*paa).b[i];
aaA* e;
while ((e = *pe) !is null)
{
if (key == e.key)
return &e.value;
pe = &e.next;
}
// Not found, create new elem
//printf("create new one\n");
size_t nodes = ++(*paa).nodes;
e = (nodes != 1) ? cast(aaA*)mem.xmalloc(aaA.sizeof) : &(*paa).aafirst;
//e = new aaA();
e.next = null;
e.key = key;
e.value = null;
*pe = e;
//printf("length = %d, nodes = %d\n", (*paa)->b_length, nodes);
if (nodes > (*paa).b_length * 2)
{
//printf("rehash\n");
dmd_aaRehash(paa);
}
return &e.value;
}

/*************************************************
* Get value in associative array indexed by key.
* Returns NULL if it is not already there.
*/
extern (C++) Value dmd_aaGetRvalue(AA* aa, Key key)
{
//printf("_aaGetRvalue(key = %p)\n", key);
if (aa)
{
size_t i;
size_t len = aa.b_length;
i = hash(cast(size_t)key) & (len - 1);
aaA* e = aa.b[i];
while (e)
{
if (key == e.key)
return e.value;
e = e.next;
}
}
return null; // not found
}

/********************************************
* Rehash an array.
*/
extern (C++) void dmd_aaRehash(AA** paa)
{
//printf("Rehash\n");
if (*paa)
{
AA* aa = *paa;
if (aa)
{
size_t len = aa.b_length;
if (len == 4)
len = 32;
else
len *= 4;
aaA** newb = cast(aaA**)mem.xmalloc(aaA.sizeof * len);
memset(newb, 0, len * (aaA*).sizeof);
for (size_t k = 0; k < aa.b_length; k++)
{
aaA* e = aa.b[k];
while (e)
{
aaA* enext = e.next;
size_t j = hash(cast(size_t)e.key) & (len - 1);
e.next = newb[j];
newb[j] = e;
e = enext;
}
}
if (aa.b != cast(aaA**)aa.binit)
mem.xfree(aa.b);
aa.b = newb;
aa.b_length = len;
}
}
}

version (unittest)
{
extern (C++) void unittest_aa()
{
AA* aa = null;
Value v = dmd_aaGetRvalue(aa, null);
assert(!v);
Value* pv = dmd_aaGet(&aa, null);
assert(pv);
*pv = cast(void*)3;
v = dmd_aaGetRvalue(aa, null);
assert(v == cast(void*)3);
}
}
Loading