[svn r175] merged dmd 1.029

This commit is contained in:
Christian Kamm
2008-05-01 15:15:28 +02:00
parent 4cd137f9d4
commit 7ae4bc6477
27 changed files with 38673 additions and 38027 deletions

View File

@@ -1,259 +1,282 @@
// Compiler implementation of the D programming language // Compiler implementation of the D programming language
// Copyright (c) 1999-2006 by Digital Mars // Copyright (c) 1999-2008 by Digital Mars
// All Rights Reserved // All Rights Reserved
// written by Walter Bright // written by Walter Bright
// http://www.digitalmars.com // http://www.digitalmars.com
// License for redistribution is by either the Artistic License // License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt. // in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details. // See the included readme.txt for details.
#ifndef DMD_AGGREGATE_H #ifndef DMD_AGGREGATE_H
#define DMD_AGGREGATE_H #define DMD_AGGREGATE_H
#ifdef __DMC__ #ifdef __DMC__
#pragma once #pragma once
#endif /* __DMC__ */ #endif /* __DMC__ */
#include "root.h" #include "root.h"
#include "dsymbol.h" #include "dsymbol.h"
#include <vector> #include <vector>
#include <set> #include <set>
#include <map> #include <map>
struct Identifier; struct Identifier;
struct Type; struct Type;
struct TypeFunction; struct TypeFunction;
struct Expression; struct Expression;
struct FuncDeclaration; struct FuncDeclaration;
struct CtorDeclaration; struct CtorDeclaration;
struct DtorDeclaration; struct DtorDeclaration;
struct InvariantDeclaration; struct InvariantDeclaration;
struct NewDeclaration; struct NewDeclaration;
struct DeleteDeclaration; struct DeleteDeclaration;
struct InterfaceDeclaration; struct InterfaceDeclaration;
struct ClassInfoDeclaration; struct ClassInfoDeclaration;
struct VarDeclaration; struct VarDeclaration;
struct dt_t; struct dt_t;
namespace llvm namespace llvm
{ {
class Type; class Type;
class Value; class Value;
class Constant; class Constant;
class ConstantStruct; class ConstantStruct;
class GlobalVariable; class GlobalVariable;
} }
struct DUnion; struct DUnion;
struct AggregateDeclaration : ScopeDsymbol struct AggregateDeclaration : ScopeDsymbol
{ {
Type *type; Type *type;
unsigned storage_class; unsigned storage_class;
enum PROT protection; enum PROT protection;
Type *handle; // 'this' type Type *handle; // 'this' type
unsigned structsize; // size of struct unsigned structsize; // size of struct
unsigned alignsize; // size of struct for alignment purposes unsigned alignsize; // size of struct for alignment purposes
unsigned structalign; // struct member alignment in effect unsigned structalign; // struct member alignment in effect
int hasUnions; // set if aggregate has overlapping fields int hasUnions; // set if aggregate has overlapping fields
Array fields; // VarDeclaration fields Array fields; // VarDeclaration fields
unsigned sizeok; // set when structsize contains valid data unsigned sizeok; // set when structsize contains valid data
// 0: no size // 0: no size
// 1: size is correct // 1: size is correct
// 2: cannot determine size; fwd referenced // 2: cannot determine size; fwd referenced
int isdeprecated; // !=0 if deprecated int isdeprecated; // !=0 if deprecated
Scope *scope; // !=NULL means context to use Scope *scope; // !=NULL means context to use
FuncDeclarations dtors; // Array of destructors
// Special member functions FuncDeclaration *dtor; // aggregate destructor
InvariantDeclaration *inv; // invariant
NewDeclaration *aggNew; // allocator // Special member functions
DeleteDeclaration *aggDelete; // deallocator InvariantDeclaration *inv; // invariant
NewDeclaration *aggNew; // allocator
#ifdef IN_GCC DeleteDeclaration *aggDelete; // deallocator
Array methods; // flat list of all methods for debug information
#endif #ifdef IN_GCC
Array methods; // flat list of all methods for debug information
AggregateDeclaration(Loc loc, Identifier *id); #endif
void semantic2(Scope *sc);
void semantic3(Scope *sc); AggregateDeclaration(Loc loc, Identifier *id);
void inlineScan(); void semantic2(Scope *sc);
unsigned size(Loc loc); void semantic3(Scope *sc);
static void alignmember(unsigned salign, unsigned size, unsigned *poffset); void inlineScan();
Type *getType(); unsigned size(Loc loc);
void addField(Scope *sc, VarDeclaration *v); static void alignmember(unsigned salign, unsigned size, unsigned *poffset);
int isDeprecated(); // is aggregate deprecated? Type *getType();
void addField(Scope *sc, VarDeclaration *v);
void emitComment(Scope *sc); int isDeprecated(); // is aggregate deprecated?
void toDocBuffer(OutBuffer *buf); FuncDeclaration *buildDtor(Scope *sc);
// For access checking void emitComment(Scope *sc);
virtual PROT getAccess(Dsymbol *smember); // determine access to smember void toDocBuffer(OutBuffer *buf);
int isFriendOf(AggregateDeclaration *cd);
int hasPrivateAccess(Dsymbol *smember); // does smember have private access to members of this class? // For access checking
void accessCheck(Loc loc, Scope *sc, Dsymbol *smember); virtual PROT getAccess(Dsymbol *smember); // determine access to smember
int isFriendOf(AggregateDeclaration *cd);
enum PROT prot(); int hasPrivateAccess(Dsymbol *smember); // does smember have private access to members of this class?
void accessCheck(Loc loc, Scope *sc, Dsymbol *smember);
// Back end
Symbol *stag; // tag symbol for debug data enum PROT prot();
Symbol *sinit;
Symbol *toInitializer(); // Back end
Symbol *stag; // tag symbol for debug data
AggregateDeclaration *isAggregateDeclaration() { return this; } Symbol *sinit;
}; Symbol *toInitializer();
struct AnonymousAggregateDeclaration : AggregateDeclaration AggregateDeclaration *isAggregateDeclaration() { return this; }
{ };
AnonymousAggregateDeclaration()
: AggregateDeclaration(0, NULL) struct AnonymousAggregateDeclaration : AggregateDeclaration
{ {
} AnonymousAggregateDeclaration()
: AggregateDeclaration(0, NULL)
AnonymousAggregateDeclaration *isAnonymousAggregateDeclaration() { return this; } {
}; }
struct StructDeclaration : AggregateDeclaration AnonymousAggregateDeclaration *isAnonymousAggregateDeclaration() { return this; }
{ };
int zeroInit; // !=0 if initialize with 0 fill
struct StructDeclaration : AggregateDeclaration
StructDeclaration(Loc loc, Identifier *id); {
Dsymbol *syntaxCopy(Dsymbol *s); int zeroInit; // !=0 if initialize with 0 fill
void semantic(Scope *sc);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs); StructDeclaration(Loc loc, Identifier *id);
char *mangle(); Dsymbol *syntaxCopy(Dsymbol *s);
char *kind(); void semantic(Scope *sc);
void toDocBuffer(OutBuffer *buf); void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
char *mangle();
PROT getAccess(Dsymbol *smember); // determine access to smember char *kind();
Expression *cloneMembers();
void toObjFile(); // compile to .obj file void toDocBuffer(OutBuffer *buf);
void toDt(dt_t **pdt);
void toDebug(); // to symbolic debug info PROT getAccess(Dsymbol *smember); // determine access to smember
StructDeclaration *isStructDeclaration() { return this; } void toObjFile(); // compile to .obj file
}; void toDt(dt_t **pdt);
void toDebug(); // to symbolic debug info
struct UnionDeclaration : StructDeclaration
{ StructDeclaration *isStructDeclaration() { return this; }
UnionDeclaration(Loc loc, Identifier *id); };
Dsymbol *syntaxCopy(Dsymbol *s);
char *kind(); struct UnionDeclaration : StructDeclaration
{
UnionDeclaration *isUnionDeclaration() { return this; } UnionDeclaration(Loc loc, Identifier *id);
}; Dsymbol *syntaxCopy(Dsymbol *s);
char *kind();
struct BaseClass
{ UnionDeclaration *isUnionDeclaration() { return this; }
Type *type; // (before semantic processing) };
enum PROT protection; // protection for the base interface
struct BaseClass
ClassDeclaration *base; {
int offset; // 'this' pointer offset Type *type; // (before semantic processing)
Array vtbl; // for interfaces: Array of FuncDeclaration's enum PROT protection; // protection for the base interface
// making up the vtbl[]
ClassDeclaration *base;
int baseInterfaces_dim; int offset; // 'this' pointer offset
BaseClass *baseInterfaces; // if BaseClass is an interface, these Array vtbl; // for interfaces: Array of FuncDeclaration's
// are a copy of the InterfaceDeclaration::interfaces // making up the vtbl[]
BaseClass(); int baseInterfaces_dim;
BaseClass(Type *type, enum PROT protection); BaseClass *baseInterfaces; // if BaseClass is an interface, these
// are a copy of the InterfaceDeclaration::interfaces
int fillVtbl(ClassDeclaration *cd, Array *vtbl, int newinstance);
void copyBaseInterfaces(BaseClasses *); BaseClass();
}; BaseClass(Type *type, enum PROT protection);
#define CLASSINFO_SIZE (0x3C+12) // value of ClassInfo.size int fillVtbl(ClassDeclaration *cd, Array *vtbl, int newinstance);
void copyBaseInterfaces(BaseClasses *);
struct ClassDeclaration : AggregateDeclaration };
{
static ClassDeclaration *object; #if V2
static ClassDeclaration *classinfo; #define CLASSINFO_SIZE (0x3C+16) // value of ClassInfo.size
#else
ClassDeclaration *baseClass; // NULL only if this is Object #define CLASSINFO_SIZE (0x3C+12) // value of ClassInfo.size
CtorDeclaration *ctor; #endif
CtorDeclaration *defaultCtor; // default constructor
FuncDeclarations dtors; // Array of destructors struct ClassDeclaration : AggregateDeclaration
FuncDeclaration *staticCtor; {
FuncDeclaration *staticDtor; static ClassDeclaration *object;
Array vtbl; // Array of FuncDeclaration's making up the vtbl[] static ClassDeclaration *classinfo;
Array vtblFinal; // More FuncDeclaration's that aren't in vtbl[]
ClassDeclaration *baseClass; // NULL only if this is Object
BaseClasses baseclasses; // Array of BaseClass's; first is super, CtorDeclaration *ctor;
// rest are Interface's CtorDeclaration *defaultCtor; // default constructor
FuncDeclaration *staticCtor;
int interfaces_dim; FuncDeclaration *staticDtor;
BaseClass **interfaces; // interfaces[interfaces_dim] for this class Array vtbl; // Array of FuncDeclaration's making up the vtbl[]
// (does not include baseClass) Array vtblFinal; // More FuncDeclaration's that aren't in vtbl[]
BaseClasses *vtblInterfaces; // array of base interfaces that have BaseClasses baseclasses; // Array of BaseClass's; first is super,
// their own vtbl[] // rest are Interface's
ClassInfoDeclaration *vclassinfo; // the ClassInfo object for this ClassDeclaration int interfaces_dim;
int com; // !=0 if this is a COM class BaseClass **interfaces; // interfaces[interfaces_dim] for this class
int isauto; // !=0 if this is an auto class // (does not include baseClass)
int isabstract; // !=0 if abstract class
BaseClasses *vtblInterfaces; // array of base interfaces that have
int isnested; // !=0 if is nested // their own vtbl[]
VarDeclaration *vthis; // 'this' parameter if this class is nested
ClassInfoDeclaration *vclassinfo; // the ClassInfo object for this ClassDeclaration
ClassDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses); int com; // !=0 if this is a COM class (meaning
Dsymbol *syntaxCopy(Dsymbol *s); // it derives from IUnknown)
void semantic(Scope *sc); int isauto; // !=0 if this is an auto class
void toCBuffer(OutBuffer *buf, HdrGenState *hgs); int isabstract; // !=0 if abstract class
int isBaseOf2(ClassDeclaration *cd);
int isnested; // !=0 if is nested
#define OFFSET_RUNTIME 0x76543210 VarDeclaration *vthis; // 'this' parameter if this class is nested
virtual int isBaseOf(ClassDeclaration *cd, int *poffset);
int inuse; // to prevent recursive attempts
Dsymbol *search(Loc, Identifier *ident, int flags);
FuncDeclaration *findFunc(Identifier *ident, TypeFunction *tf); ClassDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses);
void interfaceSemantic(Scope *sc); Dsymbol *syntaxCopy(Dsymbol *s);
int isNested(); void semantic(Scope *sc);
int isCOMclass(); void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
virtual int isCOMinterface(); int isBaseOf2(ClassDeclaration *cd);
int isAbstract();
virtual int vtblOffset(); #define OFFSET_RUNTIME 0x76543210
char *kind(); virtual int isBaseOf(ClassDeclaration *cd, int *poffset);
char *mangle();
void toDocBuffer(OutBuffer *buf); Dsymbol *search(Loc, Identifier *ident, int flags);
#if V2
PROT getAccess(Dsymbol *smember); // determine access to smember int isFuncHidden(FuncDeclaration *fd);
#endif
void addLocalClass(ClassDeclarations *); FuncDeclaration *findFunc(Identifier *ident, TypeFunction *tf);
void interfaceSemantic(Scope *sc);
// Back end int isNested();
void toObjFile(); // compile to .obj file int isCOMclass();
void toDebug(); virtual int isCOMinterface();
unsigned baseVtblOffset(BaseClass *bc); #if V2
Symbol *toSymbol(); virtual int isCPPinterface();
Symbol *toVtblSymbol(); #endif
void toDt(dt_t **pdt); int isAbstract();
void toDt2(dt_t **pdt, ClassDeclaration *cd); virtual int vtblOffset();
char *kind();
Symbol *vtblsym; char *mangle();
void toDocBuffer(OutBuffer *buf);
void offsetToIndex(Type* t, unsigned os, std::vector<unsigned>& result);
PROT getAccess(Dsymbol *smember); // determine access to smember
ClassDeclaration *isClassDeclaration() { return (ClassDeclaration *)this; }
}; void addLocalClass(ClassDeclarations *);
struct InterfaceDeclaration : ClassDeclaration // Back end
{ void toObjFile(); // compile to .obj file
InterfaceDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses); void toDebug();
Dsymbol *syntaxCopy(Dsymbol *s); unsigned baseVtblOffset(BaseClass *bc);
void semantic(Scope *sc); Symbol *toSymbol();
int isBaseOf(ClassDeclaration *cd, int *poffset); Symbol *toVtblSymbol();
int isBaseOf(BaseClass *bc, int *poffset); void toDt(dt_t **pdt);
char *kind(); void toDt2(dt_t **pdt, ClassDeclaration *cd);
int vtblOffset();
virtual int isCOMinterface(); Symbol *vtblsym;
void toObjFile(); // compile to .obj file // llvm
Symbol *toSymbol(); void offsetToIndex(Type* t, unsigned os, std::vector<unsigned>& result);
InterfaceDeclaration *isInterfaceDeclaration() { return this; } ClassDeclaration *isClassDeclaration() { return (ClassDeclaration *)this; }
}; };
#endif /* DMD_AGGREGATE_H */ struct InterfaceDeclaration : ClassDeclaration
{
#if V2
int cpp; // !=0 if this is a C++ interface
#endif
InterfaceDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses);
Dsymbol *syntaxCopy(Dsymbol *s);
void semantic(Scope *sc);
int isBaseOf(ClassDeclaration *cd, int *poffset);
int isBaseOf(BaseClass *bc, int *poffset);
char *kind();
int vtblOffset();
#if V2
int isCPPinterface();
#endif
virtual int isCOMinterface();
void toObjFile(); // compile to .obj file
Symbol *toSymbol();
InterfaceDeclaration *isInterfaceDeclaration() { return this; }
};
#endif /* DMD_AGGREGATE_H */

File diff suppressed because it is too large Load Diff

2909
dmd/cast.c

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

175
dmd/clone.c Normal file
View File

@@ -0,0 +1,175 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2008 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#include <stdio.h>
#include <assert.h>
#include "root.h"
#include "aggregate.h"
#include "scope.h"
#include "mtype.h"
#include "declaration.h"
#include "module.h"
#include "id.h"
#include "expression.h"
#include "statement.h"
/*********************************
* Generate expression that calls opClone()
* for each member of the struct
* (can be NULL for members that don't need one)
*/
#if V2
Expression *StructDeclaration::cloneMembers()
{
Expression *e = NULL;
for (size_t i = 0; i < fields.dim; i++)
{
Dsymbol *s = (Dsymbol *)fields.data[i];
VarDeclaration *v = s->isVarDeclaration();
assert(v && v->storage_class & STCfield);
Type *tv = v->type->toBasetype();
size_t dim = 1;
while (tv->ty == Tsarray)
{ TypeSArray *ta = (TypeSArray *)tv;
dim *= ((TypeSArray *)tv)->dim->toInteger();
tv = tv->nextOf()->toBasetype();
}
if (tv->ty == Tstruct)
{ TypeStruct *ts = (TypeStruct *)tv;
StructDeclaration *sd = ts->sym;
if (sd->opclone)
{ Expression *ex;
// this.v
ex = new ThisExp(0);
ex = new DotVarExp(0, ex, v, 0);
if (dim == 1)
{ // this.v.opClone()
ex = new DotVarExp(0, ex, sd->opclone, 0);
ex = new CallExp(0, ex);
}
else
{
// _callOpClones(&this.v, opclone, dim)
Expressions *args = new Expressions();
args->push(new AddrExp(0, ex));
args->push(new SymOffExp(0, sd->opclone, 0));
args->push(new IntegerExp(dim));
FuncDeclaration *ec = FuncDeclaration::genCfunc(Type::tvoid, "_callOpClones");
ex = new CallExp(0, new VarExp(0, ec), args);
}
e = Expression::combine(e, ex);
}
}
}
return e;
}
#endif
/*****************************************
* Create inclusive destructor for struct by aggregating
* all the destructors in dtors[] with the destructors for
* all the members.
*/
FuncDeclaration *AggregateDeclaration::buildDtor(Scope *sc)
{
//printf("StructDeclaration::buildDtor() %s\n", toChars());
Expression *e = NULL;
#if V2
for (size_t i = 0; i < fields.dim; i++)
{
Dsymbol *s = (Dsymbol *)fields.data[i];
VarDeclaration *v = s->isVarDeclaration();
assert(v && v->storage_class & STCfield);
Type *tv = v->type->toBasetype();
size_t dim = 1;
while (tv->ty == Tsarray)
{ TypeSArray *ta = (TypeSArray *)tv;
dim *= ((TypeSArray *)tv)->dim->toInteger();
tv = tv->nextOf()->toBasetype();
}
if (tv->ty == Tstruct)
{ TypeStruct *ts = (TypeStruct *)tv;
StructDeclaration *sd = ts->sym;
if (sd->dtor)
{ Expression *ex;
// this.v
ex = new ThisExp(0);
ex = new DotVarExp(0, ex, v, 0);
if (dim == 1)
{ // this.v.dtor()
ex = new DotVarExp(0, ex, sd->dtor, 0);
ex = new CallExp(0, ex);
}
else
{
// Typeinfo.destroy(cast(void*)&this.v);
Expression *ea = new AddrExp(0, ex);
ea = new CastExp(0, ea, Type::tvoid->pointerTo());
Expressions *args = new Expressions();
args->push(ea);
Expression *et = v->type->getTypeInfo(sc);
et = new DotIdExp(0, et, Id::destroy);
ex = new CallExp(0, et, args);
}
e = Expression::combine(ex, e); // combine in reverse order
}
}
}
/* Build our own "destructor" which executes e
*/
if (e)
{ //printf("Building __fieldDtor()\n");
DtorDeclaration *dd = new DtorDeclaration(0, 0, Lexer::idPool("__fieldDtor"));
dd->fbody = new ExpStatement(0, e);
dtors.shift(dd);
members->push(dd);
dd->semantic(sc);
}
#endif
switch (dtors.dim)
{
case 0:
return NULL;
case 1:
return (FuncDeclaration *)dtors.data[0];
default:
e = NULL;
for (size_t i = 0; i < dtors.dim; i++)
{ FuncDeclaration *fd = (FuncDeclaration *)dtors.data[i];
Expression *ex = new ThisExp(0);
ex = new DotVarExp(0, ex, fd);
ex = new CallExp(0, ex);
e = Expression::combine(ex, e);
}
DtorDeclaration *dd = new DtorDeclaration(0, 0, Lexer::idPool("__aggrDtor"));
dd->fbody = new ExpStatement(0, e);
members->push(dd);
dd->semantic(sc);
return dd;
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

3934
dmd/doc.c

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,298 +1,299 @@
// Compiler implementation of the D programming language // Compiler implementation of the D programming language
// Copyright (c) 1999-2007 by Digital Mars // Copyright (c) 1999-2007 by Digital Mars
// All Rights Reserved // All Rights Reserved
// written by Walter Bright // written by Walter Bright
// http://www.digitalmars.com // http://www.digitalmars.com
// License for redistribution is by either the Artistic License // License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt. // in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details. // See the included readme.txt for details.
#ifndef DMD_DSYMBOL_H #ifndef DMD_DSYMBOL_H
#define DMD_DSYMBOL_H #define DMD_DSYMBOL_H
#ifdef __DMC__ #ifdef __DMC__
#pragma once #pragma once
#endif /* __DMC__ */ #endif /* __DMC__ */
#include "root.h" #include "root.h"
#include "stringtable.h" #include "stringtable.h"
#include "mars.h" #include "mars.h"
#include "arraytypes.h" #include "arraytypes.h"
struct Identifier; struct Identifier;
struct Scope; struct Scope;
struct DsymbolTable; struct DsymbolTable;
struct Declaration; struct Declaration;
struct TupleDeclaration; struct TupleDeclaration;
struct TypedefDeclaration; struct TypedefDeclaration;
struct AliasDeclaration; struct AliasDeclaration;
struct AggregateDeclaration; struct AggregateDeclaration;
struct EnumDeclaration; struct EnumDeclaration;
struct ClassDeclaration; struct ClassDeclaration;
struct InterfaceDeclaration; struct InterfaceDeclaration;
struct StructDeclaration; struct StructDeclaration;
struct UnionDeclaration; struct UnionDeclaration;
struct FuncDeclaration; struct FuncDeclaration;
struct FuncAliasDeclaration; struct FuncAliasDeclaration;
struct FuncLiteralDeclaration; struct FuncLiteralDeclaration;
struct CtorDeclaration; struct CtorDeclaration;
struct DtorDeclaration; struct DtorDeclaration;
struct StaticCtorDeclaration; struct StaticCtorDeclaration;
struct StaticDtorDeclaration; struct StaticDtorDeclaration;
struct InvariantDeclaration; struct InvariantDeclaration;
struct UnitTestDeclaration; struct UnitTestDeclaration;
struct NewDeclaration; struct NewDeclaration;
struct VarDeclaration; struct VarDeclaration;
struct AttribDeclaration; struct AttribDeclaration;
struct Symbol; struct Symbol;
struct Package; struct Package;
struct Module; struct Module;
struct Import; struct Import;
struct Type; struct Type;
struct TypeTuple; struct TypeTuple;
struct WithStatement; struct WithStatement;
struct LabelDsymbol; struct LabelDsymbol;
struct ScopeDsymbol; struct ScopeDsymbol;
struct TemplateDeclaration; struct TemplateDeclaration;
struct TemplateInstance; struct TemplateInstance;
struct TemplateMixin; struct TemplateMixin;
struct EnumMember; struct EnumMember;
struct ScopeDsymbol; struct ScopeDsymbol;
struct WithScopeSymbol; struct WithScopeSymbol;
struct ArrayScopeSymbol; struct ArrayScopeSymbol;
struct SymbolDeclaration; struct SymbolDeclaration;
struct Expression; struct Expression;
struct DeleteDeclaration; struct DeleteDeclaration;
struct HdrGenState; struct HdrGenState;
struct TypeInfoDeclaration; struct TypeInfoDeclaration;
struct ClassInfoDeclaration; struct ClassInfoDeclaration;
#if IN_GCC #if IN_GCC
union tree_node; union tree_node;
typedef union tree_node TYPE; typedef union tree_node TYPE;
#else #else
struct TYPE; struct TYPE;
#endif #endif
#if IN_LLVM #if IN_LLVM
namespace llvm namespace llvm
{ {
class Value; class Value;
} }
#endif #endif
enum PROT enum PROT
{ {
PROTundefined, PROTundefined,
PROTnone, // no access PROTnone, // no access
PROTprivate, PROTprivate,
PROTpackage, PROTpackage,
PROTprotected, PROTprotected,
PROTpublic, PROTpublic,
PROTexport, PROTexport,
}; };
struct Dsymbol : Object
{ struct Dsymbol : Object
Identifier *ident; {
Identifier *c_ident; Identifier *ident;
Dsymbol *parent; Identifier *c_ident;
Symbol *csym; // symbol for code generator Dsymbol *parent;
Symbol *isym; // import version of csym Symbol *csym; // symbol for code generator
unsigned char *comment; // documentation comment for this Dsymbol Symbol *isym; // import version of csym
Loc loc; // where defined unsigned char *comment; // documentation comment for this Dsymbol
Loc loc; // where defined
Dsymbol();
Dsymbol(Identifier *); Dsymbol();
char *toChars(); Dsymbol(Identifier *);
char *toPrettyChars(); char *toChars();
char *locToChars(); char *toPrettyChars();
int equals(Object *o); char *locToChars();
int isAnonymous(); int equals(Object *o);
void error(Loc loc, const char *format, ...); int isAnonymous();
void error(const char *format, ...); void error(Loc loc, const char *format, ...);
void checkDeprecated(Loc loc, Scope *sc); void error(const char *format, ...);
Module *getModule(); void checkDeprecated(Loc loc, Scope *sc);
Dsymbol *pastMixin(); Module *getModule();
Dsymbol *toParent(); Dsymbol *pastMixin();
Dsymbol *toParent2(); Dsymbol *toParent();
Dsymbol *toParent2();
int dyncast() { return DYNCAST_DSYMBOL; } // kludge for template.isSymbol()
int dyncast() { return DYNCAST_DSYMBOL; } // kludge for template.isSymbol()
static Array *arraySyntaxCopy(Array *a);
static Array *arraySyntaxCopy(Array *a);
virtual char *kind();
virtual Dsymbol *toAlias(); // resolve real symbol virtual char *kind();
virtual int addMember(Scope *sc, ScopeDsymbol *s, int memnum); virtual Dsymbol *toAlias(); // resolve real symbol
virtual void semantic(Scope *sc); virtual int addMember(Scope *sc, ScopeDsymbol *s, int memnum);
virtual void semantic2(Scope *sc); virtual void semantic(Scope *sc);
virtual void semantic3(Scope *sc); virtual void semantic2(Scope *sc);
virtual void inlineScan(); virtual void semantic3(Scope *sc);
virtual Dsymbol *search(Loc loc, Identifier *ident, int flags); virtual void inlineScan();
Dsymbol *searchX(Loc loc, Scope *sc, Identifier *id); virtual Dsymbol *search(Loc loc, Identifier *ident, int flags);
virtual int overloadInsert(Dsymbol *s); Dsymbol *searchX(Loc loc, Scope *sc, Identifier *id);
#ifdef _DH virtual int overloadInsert(Dsymbol *s);
char *toHChars(); #ifdef _DH
virtual void toHBuffer(OutBuffer *buf, HdrGenState *hgs); char *toHChars();
#endif virtual void toHBuffer(OutBuffer *buf, HdrGenState *hgs);
virtual void toCBuffer(OutBuffer *buf, HdrGenState *hgs); #endif
virtual void toDocBuffer(OutBuffer *buf); virtual void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
virtual unsigned size(Loc loc); virtual void toDocBuffer(OutBuffer *buf);
virtual int isforwardRef(); virtual unsigned size(Loc loc);
virtual void defineRef(Dsymbol *s); virtual int isforwardRef();
virtual AggregateDeclaration *isThis(); // is a 'this' required to access the member virtual void defineRef(Dsymbol *s);
virtual ClassDeclaration *isClassMember(); // are we a member of a class? virtual AggregateDeclaration *isThis(); // is a 'this' required to access the member
virtual int isExport(); // is Dsymbol exported? virtual ClassDeclaration *isClassMember(); // are we a member of a class?
virtual int isImportedSymbol(); // is Dsymbol imported? virtual int isExport(); // is Dsymbol exported?
virtual int isDeprecated(); // is Dsymbol deprecated? virtual int isImportedSymbol(); // is Dsymbol imported?
virtual LabelDsymbol *isLabel(); // is this a LabelDsymbol? virtual int isDeprecated(); // is Dsymbol deprecated?
virtual AggregateDeclaration *isMember(); // is this symbol a member of an AggregateDeclaration? virtual LabelDsymbol *isLabel(); // is this a LabelDsymbol?
virtual Type *getType(); // is this a type? virtual AggregateDeclaration *isMember(); // is this symbol a member of an AggregateDeclaration?
virtual char *mangle(); virtual Type *getType(); // is this a type?
virtual int needThis(); // need a 'this' pointer? virtual char *mangle();
virtual enum PROT prot(); virtual int needThis(); // need a 'this' pointer?
virtual Dsymbol *syntaxCopy(Dsymbol *s); // copy only syntax trees virtual enum PROT prot();
virtual int oneMember(Dsymbol **ps); virtual Dsymbol *syntaxCopy(Dsymbol *s); // copy only syntax trees
static int oneMembers(Array *members, Dsymbol **ps); virtual int oneMember(Dsymbol **ps);
virtual int hasPointers(); static int oneMembers(Array *members, Dsymbol **ps);
virtual void addLocalClass(ClassDeclarations *) { } virtual int hasPointers();
virtual void checkCtorConstInit() { } virtual void addLocalClass(ClassDeclarations *) { }
virtual void checkCtorConstInit() { }
virtual void addComment(unsigned char *comment);
virtual void emitComment(Scope *sc); virtual void addComment(unsigned char *comment);
void emitDitto(Scope *sc); virtual void emitComment(Scope *sc);
void emitDitto(Scope *sc);
// Backend
// Backend
virtual Symbol *toSymbol(); // to backend symbol
virtual void toObjFile(); // compile to .obj file virtual Symbol *toSymbol(); // to backend symbol
virtual int cvMember(unsigned char *p); // emit cv debug info for member virtual void toObjFile(); // compile to .obj file
virtual int cvMember(unsigned char *p); // emit cv debug info for member
Symbol *toImport(); // to backend import symbol
static Symbol *toImport(Symbol *s); // to backend import symbol Symbol *toImport(); // to backend import symbol
static Symbol *toImport(Symbol *s); // to backend import symbol
Symbol *toSymbolX(const char *prefix, int sclass, TYPE *t, const char *suffix); // helper
Symbol *toSymbolX(const char *prefix, int sclass, TYPE *t, const char *suffix); // helper
// Eliminate need for dynamic_cast
virtual Package *isPackage() { return NULL; } // Eliminate need for dynamic_cast
virtual Module *isModule() { return NULL; } virtual Package *isPackage() { return NULL; }
virtual EnumMember *isEnumMember() { return NULL; } virtual Module *isModule() { return NULL; }
virtual TemplateDeclaration *isTemplateDeclaration() { return NULL; } virtual EnumMember *isEnumMember() { return NULL; }
virtual TemplateInstance *isTemplateInstance() { return NULL; } virtual TemplateDeclaration *isTemplateDeclaration() { return NULL; }
virtual TemplateMixin *isTemplateMixin() { return NULL; } virtual TemplateInstance *isTemplateInstance() { return NULL; }
virtual Declaration *isDeclaration() { return NULL; } virtual TemplateMixin *isTemplateMixin() { return NULL; }
virtual TupleDeclaration *isTupleDeclaration() { return NULL; } virtual Declaration *isDeclaration() { return NULL; }
virtual TypedefDeclaration *isTypedefDeclaration() { return NULL; } virtual TupleDeclaration *isTupleDeclaration() { return NULL; }
virtual AliasDeclaration *isAliasDeclaration() { return NULL; } virtual TypedefDeclaration *isTypedefDeclaration() { return NULL; }
virtual AggregateDeclaration *isAggregateDeclaration() { return NULL; } virtual AliasDeclaration *isAliasDeclaration() { return NULL; }
virtual FuncDeclaration *isFuncDeclaration() { return NULL; } virtual AggregateDeclaration *isAggregateDeclaration() { return NULL; }
virtual FuncAliasDeclaration *isFuncAliasDeclaration() { return NULL; } virtual FuncDeclaration *isFuncDeclaration() { return NULL; }
virtual FuncLiteralDeclaration *isFuncLiteralDeclaration() { return NULL; } virtual FuncAliasDeclaration *isFuncAliasDeclaration() { return NULL; }
virtual CtorDeclaration *isCtorDeclaration() { return NULL; } virtual FuncLiteralDeclaration *isFuncLiteralDeclaration() { return NULL; }
virtual DtorDeclaration *isDtorDeclaration() { return NULL; } virtual CtorDeclaration *isCtorDeclaration() { return NULL; }
virtual StaticCtorDeclaration *isStaticCtorDeclaration() { return NULL; } virtual DtorDeclaration *isDtorDeclaration() { return NULL; }
virtual StaticDtorDeclaration *isStaticDtorDeclaration() { return NULL; } virtual StaticCtorDeclaration *isStaticCtorDeclaration() { return NULL; }
virtual InvariantDeclaration *isInvariantDeclaration() { return NULL; } virtual StaticDtorDeclaration *isStaticDtorDeclaration() { return NULL; }
virtual UnitTestDeclaration *isUnitTestDeclaration() { return NULL; } virtual InvariantDeclaration *isInvariantDeclaration() { return NULL; }
virtual NewDeclaration *isNewDeclaration() { return NULL; } virtual UnitTestDeclaration *isUnitTestDeclaration() { return NULL; }
virtual VarDeclaration *isVarDeclaration() { return NULL; } virtual NewDeclaration *isNewDeclaration() { return NULL; }
virtual ClassDeclaration *isClassDeclaration() { return NULL; } virtual VarDeclaration *isVarDeclaration() { return NULL; }
virtual StructDeclaration *isStructDeclaration() { return NULL; } virtual ClassDeclaration *isClassDeclaration() { return NULL; }
virtual UnionDeclaration *isUnionDeclaration() { return NULL; } virtual StructDeclaration *isStructDeclaration() { return NULL; }
virtual InterfaceDeclaration *isInterfaceDeclaration() { return NULL; } virtual UnionDeclaration *isUnionDeclaration() { return NULL; }
virtual ScopeDsymbol *isScopeDsymbol() { return NULL; } virtual InterfaceDeclaration *isInterfaceDeclaration() { return NULL; }
virtual WithScopeSymbol *isWithScopeSymbol() { return NULL; } virtual ScopeDsymbol *isScopeDsymbol() { return NULL; }
virtual ArrayScopeSymbol *isArrayScopeSymbol() { return NULL; } virtual WithScopeSymbol *isWithScopeSymbol() { return NULL; }
virtual Import *isImport() { return NULL; } virtual ArrayScopeSymbol *isArrayScopeSymbol() { return NULL; }
virtual EnumDeclaration *isEnumDeclaration() { return NULL; } virtual Import *isImport() { return NULL; }
#ifdef _DH virtual EnumDeclaration *isEnumDeclaration() { return NULL; }
virtual DeleteDeclaration *isDeleteDeclaration() { return NULL; } #ifdef _DH
#endif virtual DeleteDeclaration *isDeleteDeclaration() { return NULL; }
virtual SymbolDeclaration *isSymbolDeclaration() { return NULL; } #endif
virtual AttribDeclaration *isAttribDeclaration() { return NULL; } virtual SymbolDeclaration *isSymbolDeclaration() { return NULL; }
virtual TypeInfoDeclaration* isTypeInfoDeclaration() { return NULL; } virtual AttribDeclaration *isAttribDeclaration() { return NULL; }
virtual ClassInfoDeclaration* isClassInfoDeclaration() { return NULL; } virtual TypeInfoDeclaration* isTypeInfoDeclaration() { return NULL; }
virtual ClassInfoDeclaration* isClassInfoDeclaration() { return NULL; }
// llvm stuff
int llvmInternal; // llvm stuff
char* llvmInternal1; int llvmInternal;
char* llvmInternal2; char* llvmInternal1;
}; char* llvmInternal2;
};
// Dsymbol that generates a scope
// Dsymbol that generates a scope
struct ScopeDsymbol : Dsymbol
{ struct ScopeDsymbol : Dsymbol
Array *members; // all Dsymbol's in this scope {
DsymbolTable *symtab; // members[] sorted into table Array *members; // all Dsymbol's in this scope
DsymbolTable *symtab; // members[] sorted into table
Array *imports; // imported ScopeDsymbol's
unsigned char *prots; // PROT for each import Array *imports; // imported ScopeDsymbol's
unsigned char *prots; // PROT for each import
ScopeDsymbol();
ScopeDsymbol(Identifier *id); ScopeDsymbol();
Dsymbol *syntaxCopy(Dsymbol *s); ScopeDsymbol(Identifier *id);
Dsymbol *search(Loc loc, Identifier *ident, int flags); Dsymbol *syntaxCopy(Dsymbol *s);
void importScope(ScopeDsymbol *s, enum PROT protection); Dsymbol *search(Loc loc, Identifier *ident, int flags);
int isforwardRef(); void importScope(ScopeDsymbol *s, enum PROT protection);
void defineRef(Dsymbol *s); int isforwardRef();
static void multiplyDefined(Loc loc, Dsymbol *s1, Dsymbol *s2); void defineRef(Dsymbol *s);
Dsymbol *nameCollision(Dsymbol *s); static void multiplyDefined(Loc loc, Dsymbol *s1, Dsymbol *s2);
char *kind(); Dsymbol *nameCollision(Dsymbol *s);
char *kind();
void emitMemberComments(Scope *sc);
void emitMemberComments(Scope *sc);
ScopeDsymbol *isScopeDsymbol() { return this; }
}; ScopeDsymbol *isScopeDsymbol() { return this; }
};
// With statement scope
// With statement scope
struct WithScopeSymbol : ScopeDsymbol
{ struct WithScopeSymbol : ScopeDsymbol
WithStatement *withstate; {
WithStatement *withstate;
WithScopeSymbol(WithStatement *withstate);
Dsymbol *search(Loc loc, Identifier *ident, int flags); WithScopeSymbol(WithStatement *withstate);
Dsymbol *search(Loc loc, Identifier *ident, int flags);
WithScopeSymbol *isWithScopeSymbol() { return this; }
}; WithScopeSymbol *isWithScopeSymbol() { return this; }
};
// Array Index/Slice scope
// Array Index/Slice scope
struct ArrayScopeSymbol : ScopeDsymbol
{ struct ArrayScopeSymbol : ScopeDsymbol
Expression *exp; // IndexExp or SliceExp {
TypeTuple *type; // for tuple[length] Expression *exp; // IndexExp or SliceExp
TupleDeclaration *td; // for tuples of objects TypeTuple *type; // for tuple[length]
TupleDeclaration *td; // for tuples of objects
ArrayScopeSymbol(Expression *e);
ArrayScopeSymbol(TypeTuple *t); ArrayScopeSymbol(Expression *e);
ArrayScopeSymbol(TupleDeclaration *td); ArrayScopeSymbol(TypeTuple *t);
Dsymbol *search(Loc loc, Identifier *ident, int flags); ArrayScopeSymbol(TupleDeclaration *td);
Dsymbol *search(Loc loc, Identifier *ident, int flags);
ArrayScopeSymbol *isArrayScopeSymbol() { return this; }
}; ArrayScopeSymbol *isArrayScopeSymbol() { return this; }
};
// Table of Dsymbol's
// Table of Dsymbol's
struct DsymbolTable : Object
{ struct DsymbolTable : Object
StringTable *tab; {
StringTable *tab;
DsymbolTable();
~DsymbolTable(); DsymbolTable();
~DsymbolTable();
// Look up Identifier. Return Dsymbol if found, NULL if not.
Dsymbol *lookup(Identifier *ident); // Look up Identifier. Return Dsymbol if found, NULL if not.
Dsymbol *lookup(Identifier *ident);
// Insert Dsymbol in table. Return NULL if already there.
Dsymbol *insert(Dsymbol *s); // Insert Dsymbol in table. Return NULL if already there.
Dsymbol *insert(Dsymbol *s);
// Look for Dsymbol in table. If there, return it. If not, insert s and return that.
Dsymbol *update(Dsymbol *s); // Look for Dsymbol in table. If there, return it. If not, insert s and return that.
Dsymbol *insert(Identifier *ident, Dsymbol *s); // when ident and s are not the same Dsymbol *update(Dsymbol *s);
}; Dsymbol *insert(Identifier *ident, Dsymbol *s); // when ident and s are not the same
};
#endif /* DMD_DSYMBOL_H */
#endif /* DMD_DSYMBOL_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

5510
dmd/func.c

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language // Compiler implementation of the D programming language
// Copyright (c) 1999-2007 by Digital Mars // Copyright (c) 1999-2008 by Digital Mars
// All Rights Reserved // All Rights Reserved
// written by Walter Bright // written by Walter Bright
// http://www.digitalmars.com // http://www.digitalmars.com
@@ -109,7 +109,7 @@ Expression *FuncDeclaration::interpret(InterState *istate, Expressions *argument
istatex.caller = istate; istatex.caller = istate;
istatex.fd = this; istatex.fd = this;
Expressions vsave; Expressions vsave; // place to save previous parameter values
size_t dim = 0; size_t dim = 0;
if (arguments) if (arguments)
{ {
@@ -117,9 +117,40 @@ Expression *FuncDeclaration::interpret(InterState *istate, Expressions *argument
assert(!dim || parameters->dim == dim); assert(!dim || parameters->dim == dim);
vsave.setDim(dim); vsave.setDim(dim);
/* Evaluate all the arguments to the function,
* store the results in eargs[]
*/
Expressions eargs;
eargs.setDim(dim);
for (size_t i = 0; i < dim; i++) for (size_t i = 0; i < dim; i++)
{ Expression *earg = (Expression *)arguments->data[i]; { Expression *earg = (Expression *)arguments->data[i];
Argument *arg = Argument::getNth(tf->parameters, i); Argument *arg = Argument::getNth(tf->parameters, i);
if (arg->storageClass & (STCout | STCref))
{
}
else
{ /* Value parameters
*/
Type *ta = arg->type->toBasetype();
if (ta->ty == Tsarray && earg->op == TOKaddress)
{
/* Static arrays are passed by a simple pointer.
* Skip past this to get at the actual arg.
*/
earg = ((AddrExp *)earg)->e1;
}
earg = earg->interpret(istate ? istate : &istatex);
if (earg == EXP_CANT_INTERPRET)
return NULL;
}
eargs.data[i] = earg;
}
for (size_t i = 0; i < dim; i++)
{ Expression *earg = (Expression *)eargs.data[i];
Argument *arg = Argument::getNth(tf->parameters, i);
VarDeclaration *v = (VarDeclaration *)parameters->data[i]; VarDeclaration *v = (VarDeclaration *)parameters->data[i];
vsave.data[i] = v->value; vsave.data[i] = v->value;
#if LOG #if LOG
@@ -161,17 +192,6 @@ Expression *FuncDeclaration::interpret(InterState *istate, Expressions *argument
else else
{ /* Value parameters { /* Value parameters
*/ */
Type *ta = arg->type->toBasetype();
if (ta->ty == Tsarray && earg->op == TOKaddress)
{
/* Static arrays are passed by a simple pointer.
* Skip past this to get at the actual arg.
*/
earg = ((AddrExp *)earg)->e1;
}
earg = earg->interpret(istate ? istate : &istatex);
if (earg == EXP_CANT_INTERPRET)
return NULL;
v->value = earg; v->value = earg;
} }
#if LOG #if LOG
@@ -584,6 +604,8 @@ Expression *ForStatement::interpret(InterState *istate)
while (1) while (1)
{ {
if (!condition)
goto Lhead;
e = condition->interpret(istate); e = condition->interpret(istate);
if (e == EXP_CANT_INTERPRET) if (e == EXP_CANT_INTERPRET)
break; break;
@@ -592,7 +614,9 @@ Expression *ForStatement::interpret(InterState *istate)
break; break;
} }
if (e->isBool(TRUE)) if (e->isBool(TRUE))
{ e = body ? body->interpret(istate) : NULL; {
Lhead:
e = body ? body->interpret(istate) : NULL;
if (e == EXP_CANT_INTERPRET) if (e == EXP_CANT_INTERPRET)
break; break;
if (e == EXP_BREAK_INTERPRET) if (e == EXP_BREAK_INTERPRET)
@@ -602,9 +626,12 @@ Expression *ForStatement::interpret(InterState *istate)
if (e && e != EXP_CONTINUE_INTERPRET) if (e && e != EXP_CONTINUE_INTERPRET)
break; break;
Lcontinue: Lcontinue:
e = increment->interpret(istate); if (increment)
if (e == EXP_CANT_INTERPRET) {
break; e = increment->interpret(istate);
if (e == EXP_CANT_INTERPRET)
break;
}
} }
else if (e->isBool(FALSE)) else if (e->isBool(FALSE))
{ e = NULL; { e = NULL;

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language // Compiler implementation of the D programming language
// Copyright (c) 1999-2007 by Digital Mars // Copyright (c) 1999-2008 by Digital Mars
// All Rights Reserved // All Rights Reserved
// written by Walter Bright // written by Walter Bright
// http://www.digitalmars.com // http://www.digitalmars.com
@@ -92,11 +92,11 @@ enum TOK
TOKand, TOKor, TOKxor, TOKand, TOKor, TOKxor,
TOKandass, TOKorass, TOKxorass, TOKandass, TOKorass, TOKxorass,
TOKassign, TOKnot, TOKtilde, TOKassign, TOKnot, TOKtilde,
TOKplusplus, TOKminusminus, TOKconstruct, TOKplusplus, TOKminusminus, TOKconstruct, TOKblit,
TOKdot, TOKarrow, TOKcomma, TOKdot, TOKarrow, TOKcomma,
TOKquestion, TOKandand, TOKoror, TOKquestion, TOKandand, TOKoror,
// 103 // 104
// Numeric literals // Numeric literals
TOKint32v, TOKuns32v, TOKint32v, TOKuns32v,
TOKint64v, TOKuns64v, TOKint64v, TOKuns64v,
@@ -131,7 +131,7 @@ enum TOK
TOKalign, TOKextern, TOKprivate, TOKprotected, TOKpublic, TOKexport, TOKalign, TOKextern, TOKprivate, TOKprotected, TOKpublic, TOKexport,
TOKstatic, /*TOKvirtual,*/ TOKfinal, TOKconst, TOKabstract, TOKvolatile, TOKstatic, /*TOKvirtual,*/ TOKfinal, TOKconst, TOKabstract, TOKvolatile,
TOKdebug, TOKdeprecated, TOKin, TOKout, TOKinout, TOKlazy, TOKdebug, TOKdeprecated, TOKin, TOKout, TOKinout, TOKlazy,
TOKauto, TOKpackage, TOKauto, TOKpackage, TOKmanifest,
// Statements // Statements
TOKif, TOKelse, TOKwhile, TOKfor, TOKdo, TOKswitch, TOKif, TOKelse, TOKwhile, TOKfor, TOKdo, TOKswitch,
@@ -152,6 +152,8 @@ enum TOK
TOKmacro, TOKmacro,
#if V2 #if V2
TOKtraits, TOKtraits,
TOKoverloadset,
TOKpure,
#endif #endif
TOKMAX TOKMAX
@@ -261,6 +263,8 @@ struct Lexer
static void initKeywords(); static void initKeywords();
static Identifier *idPool(const char *s); static Identifier *idPool(const char *s);
static Identifier *uniqueId(const char *s);
static Identifier *uniqueId(const char *s, int num);
TOK nextToken(); TOK nextToken();
void scan(Token *t); void scan(Token *t);

1026
dmd/link.c

File diff suppressed because it is too large Load Diff

2434
dmd/mars.c

File diff suppressed because it is too large Load Diff

View File

@@ -1,307 +1,308 @@
// Compiler implementation of the D programming language // Compiler implementation of the D programming language
// Copyright (c) 1999-2007 by Digital Mars // Copyright (c) 1999-2007 by Digital Mars
// All Rights Reserved // All Rights Reserved
// written by Walter Bright // written by Walter Bright
// http://www.digitalmars.com // http://www.digitalmars.com
// License for redistribution is by either the Artistic License // License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt. // in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details. // See the included readme.txt for details.
#ifndef DMD_MARS_H #ifndef DMD_MARS_H
#define DMD_MARS_H #define DMD_MARS_H
#ifdef __DMC__ #ifdef __DMC__
#pragma once #pragma once
#endif /* __DMC__ */ #endif /* __DMC__ */
#include <stdint.h> #include <stdint.h>
#include <string> #include <string>
#include <cstdarg> #include <cstdarg>
#ifdef __DMC__ #ifdef __DMC__
#ifdef DEBUG #ifdef DEBUG
#undef assert #undef assert
#define assert(e) (static_cast<void>((e) || (printf("assert %s(%d) %s\n", __FILE__, __LINE__, #e), halt()))) #define assert(e) (static_cast<void>((e) || (printf("assert %s(%d) %s\n", __FILE__, __LINE__, #e), halt())))
#endif #endif
#endif #endif
#ifdef IN_GCC #ifdef IN_GCC
/* Changes for the GDC compiler by David Friedman */ /* Changes for the GDC compiler by David Friedman */
#endif #endif
#define V2 0 // Version 2.0 features #define V2 0 // Version 2.0 features
#define BREAKABI 1 // 0 if not ready to break the ABI just yet #define BREAKABI 1 // 0 if not ready to break the ABI just yet
struct Array; struct Array;
// Put command line switches in here // Put command line switches in here
struct Param struct Param
{ {
char obj; // write object file char obj; // write object file
char link; // perform link char link; // perform link
char trace; // insert profiling hooks char trace; // insert profiling hooks
char quiet; // suppress non-error messages char quiet; // suppress non-error messages
char verbose; // verbose compile char verbose; // verbose compile
char symdebug; // insert debug symbolic information char symdebug; // insert debug symbolic information
char optimize; // run optimizer char optimize; // run optimizer
char optimizeLevel; // optimization level char optimizeLevel; // optimization level
char cpu; // target CPU char cpu; // target CPU
char is64bit; // generate 64 bit code char is64bit; // generate 64 bit code
char isLE; // generate little endian code char isLE; // generate little endian code
char isLinux; // generate code for linux char isLinux; // generate code for linux
char isWindows; // generate code for Windows char isWindows; // generate code for Windows
char scheduler; // which scheduler to use char scheduler; // which scheduler to use
char useDeprecated; // allow use of deprecated features char useDeprecated; // allow use of deprecated features
char useAssert; // generate runtime code for assert()'s char useAssert; // generate runtime code for assert()'s
char useInvariants; // generate class invariant checks char useInvariants; // generate class invariant checks
char useIn; // generate precondition checks char useIn; // generate precondition checks
char useOut; // generate postcondition checks char useOut; // generate postcondition checks
char useArrayBounds; // generate array bounds checks char useArrayBounds; // generate array bounds checks
char useSwitchError; // check for switches without a default char useSwitchError; // check for switches without a default
char useUnitTests; // generate unittest code char useUnitTests; // generate unittest code
char useInline; // inline expand functions char useInline; // inline expand functions
char release; // build release version char release; // build release version
char preservePaths; // !=0 means don't strip path from source file char preservePaths; // !=0 means don't strip path from source file
char warnings; // enable warnings char warnings; // enable warnings
char pic; // generate position-independent-code for shared libs char pic; // generate position-independent-code for shared libs
char cov; // generate code coverage data char cov; // generate code coverage data
char nofloat; // code should not pull in floating point support char nofloat; // code should not pull in floating point support
char noruntime; // code is not allowed to make implicit calls to the runtime char noruntime; // code is not allowed to make implicit calls to the runtime
char novalidate;// no bitcode validation char novalidate;// no bitcode validation
char Dversion; // D version number char Dversion; // D version number
char ignoreUnsupportedPragmas; // rather than error on them
char *argv0; // program name
Array *imppath; // array of char*'s of where to look for import modules char *argv0; // program name
Array *fileImppath; // array of char*'s of where to look for file import modules Array *imppath; // array of char*'s of where to look for import modules
char *runtimeImppath; // char* of where to look for the core runtime Array *fileImppath; // array of char*'s of where to look for file import modules
char *objdir; // .obj file output directory char *runtimeImppath; // char* of where to look for the core runtime
char *objname; // .obj file output name char *objdir; // .obj file output directory
char *objname; // .obj file output name
char doDocComments; // process embedded documentation comments
char *docdir; // write documentation file to docdir directory char doDocComments; // process embedded documentation comments
char *docname; // write documentation file to docname char *docdir; // write documentation file to docdir directory
Array *ddocfiles; // macro include files for Ddoc char *docname; // write documentation file to docname
Array *ddocfiles; // macro include files for Ddoc
char doHdrGeneration; // process embedded documentation comments
char *hdrdir; // write 'header' file to docdir directory char doHdrGeneration; // process embedded documentation comments
char *hdrname; // write 'header' file to docname char *hdrdir; // write 'header' file to docdir directory
char *hdrname; // write 'header' file to docname
unsigned debuglevel; // debug level
Array *debugids; // debug identifiers unsigned debuglevel; // debug level
Array *debugids; // debug identifiers
unsigned versionlevel; // version level
Array *versionids; // version identifiers unsigned versionlevel; // version level
Array *versionids; // version identifiers
bool dump_source;
bool dump_source;
char *defaultlibname; // default library for non-debug builds
char *debuglibname; // default library for debug builds char *defaultlibname; // default library for non-debug builds
char *debuglibname; // default library for debug builds
char *xmlname; // filename for XML output
char *xmlname; // filename for XML output
// Hidden debug switches
char debuga; // Hidden debug switches
char debugb; char debuga;
char debugc; char debugb;
char debugf; char debugc;
char debugr; char debugf;
char debugw; char debugr;
char debugx; char debugw;
char debugy; char debugx;
char debugy;
char run; // run resulting executable
size_t runargs_length; char run; // run resulting executable
char** runargs; // arguments for executable size_t runargs_length;
char** runargs; // arguments for executable
// Linker stuff
Array *objfiles; // Linker stuff
Array *linkswitches; Array *objfiles;
Array *libfiles; Array *linkswitches;
char *deffile; Array *libfiles;
char *resfile; char *deffile;
char *exefile; char *resfile;
char *exefile;
// LLVM stuff
char *llvmArch; // LLVM stuff
char forceBE; char *llvmArch;
char *tt_arch; char forceBE;
char *tt_os; char *tt_arch;
char *data_layout; char *tt_os;
char disassemble; char *data_layout;
char llvmInline; char disassemble;
char llvmAnnotate; char llvmInline;
char *runtimePath; char llvmAnnotate;
}; char *runtimePath;
};
struct Global
{ struct Global
char *mars_ext; {
char *sym_ext; char *mars_ext;
char *obj_ext; char *sym_ext;
char *ll_ext; char *obj_ext;
char *bc_ext; char *ll_ext;
char *nativeobj_ext; char *bc_ext;
char *doc_ext; // for Ddoc generated files char *nativeobj_ext;
char *ddoc_ext; // for Ddoc macro include files char *doc_ext; // for Ddoc generated files
char *hdr_ext; // for D 'header' import files char *ddoc_ext; // for Ddoc macro include files
char *copyright; char *hdr_ext; // for D 'header' import files
char *written; char *copyright;
Array *path; // Array of char*'s which form the import lookup path char *written;
Array *filePath; // Array of char*'s which form the file import lookup path Array *path; // Array of char*'s which form the import lookup path
int structalign; Array *filePath; // Array of char*'s which form the file import lookup path
char *version; int structalign;
char *llvmdc_version; char *version;
char *llvmdc_version;
Param params;
unsigned errors; // number of errors reported so far Param params;
unsigned gag; // !=0 means gag reporting of errors unsigned errors; // number of errors reported so far
unsigned gag; // !=0 means gag reporting of errors
Global();
}; Global();
};
extern Global global;
extern Global global;
#if __GNUC__
//#define memicmp strncasecmp #if __GNUC__
//#define stricmp strcasecmp //#define memicmp strncasecmp
#endif //#define stricmp strcasecmp
#endif
#ifdef __DMC__
typedef _Complex long double complex_t; #ifdef __DMC__
#else typedef _Complex long double complex_t;
#ifndef IN_GCC #else
#include "complex_t.h" #ifndef IN_GCC
#endif #include "complex_t.h"
#ifdef __APPLE__ #endif
//#include "complex.h"//This causes problems with include the c++ <complex> and not the C "complex.h" #ifdef __APPLE__
#define integer_t dmd_integer_t //#include "complex.h"//This causes problems with include the c++ <complex> and not the C "complex.h"
#endif #define integer_t dmd_integer_t
#endif #endif
#endif
// Be careful not to care about sign when using integer_t
typedef uint64_t integer_t; // Be careful not to care about sign when using integer_t
typedef uint64_t integer_t;
// Signed and unsigned variants
typedef int64_t sinteger_t; // Signed and unsigned variants
typedef uint64_t uinteger_t; typedef int64_t sinteger_t;
typedef uint64_t uinteger_t;
typedef int8_t d_int8;
typedef uint8_t d_uns8; typedef int8_t d_int8;
typedef int16_t d_int16; typedef uint8_t d_uns8;
typedef uint16_t d_uns16; typedef int16_t d_int16;
typedef int32_t d_int32; typedef uint16_t d_uns16;
typedef uint32_t d_uns32; typedef int32_t d_int32;
typedef int64_t d_int64; typedef uint32_t d_uns32;
typedef uint64_t d_uns64; typedef int64_t d_int64;
typedef uint64_t d_uns64;
typedef float d_float32;
typedef double d_float64; typedef float d_float32;
typedef long double d_float80; typedef double d_float64;
typedef long double d_float80;
typedef d_uns8 d_char;
typedef d_uns16 d_wchar; typedef d_uns8 d_char;
typedef d_uns32 d_dchar; typedef d_uns16 d_wchar;
typedef d_uns32 d_dchar;
#ifdef IN_GCC
#include "d-gcc-real.h" #ifdef IN_GCC
#else #include "d-gcc-real.h"
typedef long double real_t; #else
#endif typedef long double real_t;
#endif
// Modify OutBuffer::writewchar to write the correct size of wchar
#if _WIN32 // Modify OutBuffer::writewchar to write the correct size of wchar
#define writewchar writeword #if _WIN32
#else #define writewchar writeword
// This needs a configuration test... #else
#define writewchar write4 // This needs a configuration test...
#endif #define writewchar write4
#endif
#ifdef IN_GCC
#include "d-gcc-complex_t.h" #ifdef IN_GCC
#endif #include "d-gcc-complex_t.h"
#endif
struct Module;
struct Module;
//typedef unsigned Loc; // file location
struct Loc //typedef unsigned Loc; // file location
{ struct Loc
char *filename; {
unsigned linnum; char *filename;
unsigned linnum;
Loc()
{ Loc()
linnum = 0; {
filename = NULL; linnum = 0;
} filename = NULL;
}
Loc(int x)
{ Loc(int x)
linnum = x; {
filename = NULL; linnum = x;
} filename = NULL;
}
Loc(Module *mod, unsigned linnum);
Loc(Module *mod, unsigned linnum);
char *toChars() const;
}; char *toChars() const;
};
#ifndef GCC_SAFE_DMD
#define TRUE 1 #ifndef GCC_SAFE_DMD
#define FALSE 0 #define TRUE 1
#endif #define FALSE 0
#endif
#define INTERFACE_OFFSET 0 // if 1, put classinfo as first entry
// in interface vtbl[]'s #define INTERFACE_OFFSET 0 // if 1, put classinfo as first entry
#define INTERFACE_VIRTUAL 0 // 1 means if an interface appears // in interface vtbl[]'s
// in the inheritance graph multiple #define INTERFACE_VIRTUAL 0 // 1 means if an interface appears
// times, only one is used // in the inheritance graph multiple
// times, only one is used
enum LINK
{ enum LINK
LINKdefault, {
LINKd, LINKdefault,
LINKc, LINKd,
LINKcpp, LINKc,
LINKwindows, LINKcpp,
LINKpascal, LINKwindows,
}; LINKpascal,
};
enum DYNCAST
{ enum DYNCAST
DYNCAST_OBJECT, {
DYNCAST_EXPRESSION, DYNCAST_OBJECT,
DYNCAST_DSYMBOL, DYNCAST_EXPRESSION,
DYNCAST_TYPE, DYNCAST_DSYMBOL,
DYNCAST_IDENTIFIER, DYNCAST_TYPE,
DYNCAST_TUPLE, DYNCAST_IDENTIFIER,
}; DYNCAST_TUPLE,
};
enum MATCH
{ enum MATCH
MATCHnomatch, // no match {
MATCHconvert, // match with conversions MATCHnomatch, // no match
#if V2 MATCHconvert, // match with conversions
MATCHconst, // match with conversion to const #if V2
#endif MATCHconst, // match with conversion to const
MATCHexact // exact match #endif
}; MATCHexact // exact match
};
void error(Loc loc, const char *format, ...);
void verror(Loc loc, const char *format, va_list); void error(Loc loc, const char *format, ...);
void fatal(); void verror(Loc loc, const char *format, va_list);
void err_nomem(); void fatal();
int runLINK(); void err_nomem();
void deleteExeFile(); int runLINK();
int runProgram(); void deleteExeFile();
void inifile(char *argv0, char *inifile); int runProgram();
void halt(); void inifile(char *argv0, char *inifile);
void halt();
/*** Where to send error messages ***/
#if IN_GCC /*** Where to send error messages ***/
#define stdmsg stderr #if IN_GCC
#else #define stdmsg stderr
#define stdmsg stdout #else
#endif #define stdmsg stdout
#endif
#endif /* DMD_MARS_H */
#endif /* DMD_MARS_H */

10627
dmd/mtype.c

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -637,6 +637,14 @@ Condition *Parser::parseVersionCondition()
id = token.ident; id = token.ident;
else if (token.value == TOKint32v) else if (token.value == TOKint32v)
level = (unsigned)token.uns64value; level = (unsigned)token.uns64value;
#if V2
/* Allow:
* version (unittest)
* even though unittest is a keyword
*/
else if (token.value == TOKunittest)
id = Lexer::idPool(Token::toChars(TOKunittest));
#endif
else else
error("identifier or integer expected, not %s", token.toChars()); error("identifier or integer expected, not %s", token.toChars());
nextToken(); nextToken();

View File

@@ -1,359 +1,361 @@
// Copyright (c) 1999-2005 by Digital Mars // Copyright (c) 1999-2005 by Digital Mars
// All Rights Reserved // All Rights Reserved
// written by Walter Bright // written by Walter Bright
// http://www.digitalmars.com // http://www.digitalmars.com
// License for redistribution is by either the Artistic License // License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt. // in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details. // See the included readme.txt for details.
#include <stdio.h> #include <stdio.h>
#include <assert.h> #include <assert.h>
#include "root.h" #include "root.h"
#include "mars.h" #include "mars.h"
#include "init.h" #include "init.h"
#include "identifier.h" #include "identifier.h"
#include "attrib.h" #include "attrib.h"
#include "dsymbol.h" #include "dsymbol.h"
#include "scope.h" #include "scope.h"
#include "declaration.h" #include "declaration.h"
#include "aggregate.h" #include "aggregate.h"
#include "module.h" #include "module.h"
#include "id.h" #include "id.h"
Scope *Scope::freelist = NULL; Scope *Scope::freelist = NULL;
void *Scope::operator new(size_t size) void *Scope::operator new(size_t size)
{ {
if (freelist) if (freelist)
{ {
Scope *s = freelist; Scope *s = freelist;
freelist = s->enclosing; freelist = s->enclosing;
//printf("freelist %p\n", s); //printf("freelist %p\n", s);
assert(s->flags & SCOPEfree); assert(s->flags & SCOPEfree);
s->flags &= ~SCOPEfree; s->flags &= ~SCOPEfree;
return s; return s;
} }
void *p = ::operator new(size); void *p = ::operator new(size);
//printf("new %p\n", p); //printf("new %p\n", p);
return p; return p;
} }
Scope::Scope() Scope::Scope()
{ // Create root scope { // Create root scope
//printf("Scope::Scope() %p\n", this); //printf("Scope::Scope() %p\n", this);
this->module = NULL; this->module = NULL;
this->scopesym = NULL; this->scopesym = NULL;
this->sd = NULL; this->sd = NULL;
this->enclosing = NULL; this->enclosing = NULL;
this->parent = NULL; this->parent = NULL;
this->sw = NULL; this->sw = NULL;
this->tf = NULL; this->tf = NULL;
this->tfOfTry = NULL; this->tfOfTry = NULL;
this->sbreak = NULL; this->sbreak = NULL;
this->scontinue = NULL; this->scontinue = NULL;
this->fes = NULL; this->fes = NULL;
this->structalign = global.structalign; this->structalign = global.structalign;
this->func = NULL; this->func = NULL;
this->slabel = NULL; this->slabel = NULL;
this->linkage = LINKd; this->linkage = LINKd;
this->protection = PROTpublic; this->protection = PROTpublic;
this->explicitProtection = 0; this->explicitProtection = 0;
this->stc = 0; this->stc = 0;
this->offset = 0; this->offset = 0;
this->inunion = 0; this->inunion = 0;
this->incontract = 0; this->incontract = 0;
this->nofree = 0; this->nofree = 0;
this->noctor = 0; this->noctor = 0;
this->intypeof = 0; this->noaccesscheck = 0;
this->parameterSpecialization = 0; this->intypeof = 0;
this->callSuper = 0; this->parameterSpecialization = 0;
this->flags = 0; this->callSuper = 0;
this->anonAgg = NULL; this->flags = 0;
this->lastdc = NULL; this->anonAgg = NULL;
this->lastoffset = 0; this->lastdc = NULL;
this->docbuf = NULL; this->lastoffset = 0;
} this->docbuf = NULL;
}
Scope::Scope(Scope *enclosing)
{ Scope::Scope(Scope *enclosing)
//printf("Scope::Scope(enclosing = %p) %p\n", enclosing, this); {
assert(!(enclosing->flags & SCOPEfree)); //printf("Scope::Scope(enclosing = %p) %p\n", enclosing, this);
this->module = enclosing->module; assert(!(enclosing->flags & SCOPEfree));
this->func = enclosing->func; this->module = enclosing->module;
this->parent = enclosing->parent; this->func = enclosing->func;
this->scopesym = NULL; this->parent = enclosing->parent;
this->sd = NULL; this->scopesym = NULL;
this->sw = enclosing->sw; this->sd = NULL;
this->tf = enclosing->tf; this->sw = enclosing->sw;
this->tfOfTry = enclosing->tfOfTry; this->tf = enclosing->tf;
this->sbreak = enclosing->sbreak; this->tfOfTry = enclosing->tfOfTry;
this->scontinue = enclosing->scontinue; this->sbreak = enclosing->sbreak;
this->fes = enclosing->fes; this->scontinue = enclosing->scontinue;
this->structalign = enclosing->structalign; this->fes = enclosing->fes;
this->enclosing = enclosing; this->structalign = enclosing->structalign;
#ifdef DEBUG this->enclosing = enclosing;
if (enclosing->enclosing) #ifdef DEBUG
assert(!(enclosing->enclosing->flags & SCOPEfree)); if (enclosing->enclosing)
if (this == enclosing->enclosing) assert(!(enclosing->enclosing->flags & SCOPEfree));
{ if (this == enclosing->enclosing)
printf("this = %p, enclosing = %p, enclosing->enclosing = %p\n", this, enclosing, enclosing->enclosing); {
} printf("this = %p, enclosing = %p, enclosing->enclosing = %p\n", this, enclosing, enclosing->enclosing);
assert(this != enclosing->enclosing); }
#endif assert(this != enclosing->enclosing);
this->slabel = NULL; #endif
this->linkage = enclosing->linkage; this->slabel = NULL;
this->protection = enclosing->protection; this->linkage = enclosing->linkage;
this->explicitProtection = enclosing->explicitProtection; this->protection = enclosing->protection;
this->stc = enclosing->stc; this->explicitProtection = enclosing->explicitProtection;
this->offset = 0; this->stc = enclosing->stc;
this->inunion = enclosing->inunion; this->offset = 0;
this->incontract = enclosing->incontract; this->inunion = enclosing->inunion;
this->nofree = 0; this->incontract = enclosing->incontract;
this->noctor = enclosing->noctor; this->nofree = 0;
this->intypeof = enclosing->intypeof; this->noctor = enclosing->noctor;
this->parameterSpecialization = enclosing->parameterSpecialization; this->noaccesscheck = enclosing->noaccesscheck;
this->callSuper = enclosing->callSuper; this->intypeof = enclosing->intypeof;
this->flags = 0; this->parameterSpecialization = enclosing->parameterSpecialization;
this->anonAgg = NULL; this->callSuper = enclosing->callSuper;
this->lastdc = NULL; this->flags = 0;
this->lastoffset = 0; this->anonAgg = NULL;
this->docbuf = enclosing->docbuf; this->lastdc = NULL;
assert(this != enclosing); this->lastoffset = 0;
} this->docbuf = enclosing->docbuf;
assert(this != enclosing);
Scope *Scope::createGlobal(Module *module) }
{
Scope *sc; Scope *Scope::createGlobal(Module *module)
{
sc = new Scope(); Scope *sc;
sc->module = module;
sc->scopesym = new ScopeDsymbol(); sc = new Scope();
sc->scopesym->symtab = new DsymbolTable(); sc->module = module;
sc->scopesym = new ScopeDsymbol();
// Add top level package as member of this global scope sc->scopesym->symtab = new DsymbolTable();
Dsymbol *m = module;
while (m->parent) // Add top level package as member of this global scope
m = m->parent; Dsymbol *m = module;
m->addMember(NULL, sc->scopesym, 1); while (m->parent)
m->parent = NULL; // got changed by addMember() m = m->parent;
m->addMember(NULL, sc->scopesym, 1);
// Create the module scope underneath the global scope m->parent = NULL; // got changed by addMember()
sc = sc->push(module);
sc->parent = module; // Create the module scope underneath the global scope
return sc; sc = sc->push(module);
} sc->parent = module;
return sc;
Scope *Scope::push() }
{
//printf("Scope::push()\n"); Scope *Scope::push()
Scope *s = new Scope(this); {
assert(this != s); //printf("Scope::push()\n");
return s; Scope *s = new Scope(this);
} assert(this != s);
return s;
Scope *Scope::push(ScopeDsymbol *ss) }
{
//printf("Scope::push(%s)\n", ss->toChars()); Scope *Scope::push(ScopeDsymbol *ss)
Scope *s = push(); {
s->scopesym = ss; //printf("Scope::push(%s)\n", ss->toChars());
return s; Scope *s = push();
} s->scopesym = ss;
return s;
Scope *Scope::pop() }
{
//printf("Scope::pop() %p nofree = %d\n", this, nofree); Scope *Scope::pop()
Scope *enc = enclosing; {
//printf("Scope::pop() %p nofree = %d\n", this, nofree);
if (enclosing) Scope *enc = enclosing;
enclosing->callSuper |= callSuper;
if (enclosing)
if (!nofree) enclosing->callSuper |= callSuper;
{ enclosing = freelist;
freelist = this; if (!nofree)
flags |= SCOPEfree; { enclosing = freelist;
} freelist = this;
flags |= SCOPEfree;
return enc; }
}
return enc;
void Scope::mergeCallSuper(Loc loc, unsigned cs) }
{
// This does a primitive flow analysis to support the restrictions void Scope::mergeCallSuper(Loc loc, unsigned cs)
// regarding when and how constructors can appear. {
// It merges the results of two paths. // This does a primitive flow analysis to support the restrictions
// The two paths are callSuper and cs; the result is merged into callSuper. // regarding when and how constructors can appear.
// It merges the results of two paths.
if (cs != callSuper) // The two paths are callSuper and cs; the result is merged into callSuper.
{ int a;
int b; if (cs != callSuper)
{ int a;
callSuper |= cs & (CSXany_ctor | CSXlabel); int b;
if (cs & CSXreturn)
{ callSuper |= cs & (CSXany_ctor | CSXlabel);
} if (cs & CSXreturn)
else if (callSuper & CSXreturn) {
{ }
callSuper = cs | (callSuper & (CSXany_ctor | CSXlabel)); else if (callSuper & CSXreturn)
} {
else callSuper = cs | (callSuper & (CSXany_ctor | CSXlabel));
{ }
a = (cs & (CSXthis_ctor | CSXsuper_ctor)) != 0; else
b = (callSuper & (CSXthis_ctor | CSXsuper_ctor)) != 0; {
if (a != b) a = (cs & (CSXthis_ctor | CSXsuper_ctor)) != 0;
error(loc, "one path skips constructor"); b = (callSuper & (CSXthis_ctor | CSXsuper_ctor)) != 0;
callSuper |= cs; if (a != b)
} error(loc, "one path skips constructor");
} callSuper |= cs;
} }
}
Dsymbol *Scope::search(Loc loc, Identifier *ident, Dsymbol **pscopesym) }
{ Dsymbol *s;
Scope *sc; Dsymbol *Scope::search(Loc loc, Identifier *ident, Dsymbol **pscopesym)
{ Dsymbol *s;
//printf("Scope::search(%p, '%s')\n", this, ident->toChars()); Scope *sc;
if (ident == Id::empty)
{ //printf("Scope::search(%p, '%s')\n", this, ident->toChars());
// Look for module scope if (ident == Id::empty)
for (sc = this; sc; sc = sc->enclosing) {
{ // Look for module scope
assert(sc != sc->enclosing); for (sc = this; sc; sc = sc->enclosing)
if (sc->scopesym) {
{ assert(sc != sc->enclosing);
s = sc->scopesym->isModule(); if (sc->scopesym)
if (s) {
{ s = sc->scopesym->isModule();
//printf("\tfound %s.%s\n", s->parent ? s->parent->toChars() : "", s->toChars()); if (s)
if (pscopesym) {
*pscopesym = sc->scopesym; //printf("\tfound %s.%s\n", s->parent ? s->parent->toChars() : "", s->toChars());
return s; if (pscopesym)
} *pscopesym = sc->scopesym;
} return s;
} }
return NULL; }
} }
return NULL;
for (sc = this; sc; sc = sc->enclosing) }
{
assert(sc != sc->enclosing); for (sc = this; sc; sc = sc->enclosing)
if (sc->scopesym) {
{ assert(sc != sc->enclosing);
//printf("\tlooking in scopesym '%s', kind = '%s'\n", sc->scopesym->toChars(), sc->scopesym->kind()); if (sc->scopesym)
s = sc->scopesym->search(loc, ident, 0); {
if (s) //printf("\tlooking in scopesym '%s', kind = '%s'\n", sc->scopesym->toChars(), sc->scopesym->kind());
{ s = sc->scopesym->search(loc, ident, 0);
if ((global.params.warnings || if (s)
global.params.Dversion > 1) && {
ident == Id::length && if ((global.params.warnings ||
sc->scopesym->isArrayScopeSymbol() && global.params.Dversion > 1) &&
sc->enclosing && ident == Id::length &&
sc->enclosing->search(loc, ident, NULL)) sc->scopesym->isArrayScopeSymbol() &&
{ sc->enclosing &&
if (global.params.warnings) sc->enclosing->search(loc, ident, NULL))
fprintf(stdmsg, "warning - "); {
error(s->loc, "array 'length' hides other 'length' name in outer scope"); if (global.params.warnings)
} fprintf(stdmsg, "warning - ");
error(s->loc, "array 'length' hides other 'length' name in outer scope");
//printf("\tfound %s.%s, kind = '%s'\n", s->parent ? s->parent->toChars() : "", s->toChars(), s->kind()); }
if (pscopesym)
*pscopesym = sc->scopesym; //printf("\tfound %s.%s, kind = '%s'\n", s->parent ? s->parent->toChars() : "", s->toChars(), s->kind());
return s; if (pscopesym)
} *pscopesym = sc->scopesym;
} return s;
} }
}
return NULL; }
}
return NULL;
Dsymbol *Scope::insert(Dsymbol *s) }
{ Scope *sc;
Dsymbol *Scope::insert(Dsymbol *s)
for (sc = this; sc; sc = sc->enclosing) { Scope *sc;
{
//printf("\tsc = %p\n", sc); for (sc = this; sc; sc = sc->enclosing)
if (sc->scopesym) {
{ //printf("\tsc = %p\n", sc);
//printf("\t\tsc->scopesym = %p\n", sc->scopesym); if (sc->scopesym)
if (!sc->scopesym->symtab) {
sc->scopesym->symtab = new DsymbolTable(); //printf("\t\tsc->scopesym = %p\n", sc->scopesym);
return sc->scopesym->symtab->insert(s); if (!sc->scopesym->symtab)
} sc->scopesym->symtab = new DsymbolTable();
} return sc->scopesym->symtab->insert(s);
assert(0); }
return NULL; }
} assert(0);
return NULL;
/******************************************** }
* Search enclosing scopes for ClassDeclaration.
*/ /********************************************
* Search enclosing scopes for ClassDeclaration.
ClassDeclaration *Scope::getClassScope() */
{ Scope *sc;
ClassDeclaration *Scope::getClassScope()
for (sc = this; sc; sc = sc->enclosing) { Scope *sc;
{
ClassDeclaration *cd; for (sc = this; sc; sc = sc->enclosing)
{
if (sc->scopesym) ClassDeclaration *cd;
{
cd = sc->scopesym->isClassDeclaration(); if (sc->scopesym)
if (cd) {
return cd; cd = sc->scopesym->isClassDeclaration();
} if (cd)
} return cd;
return NULL; }
} }
return NULL;
/******************************************** }
* Search enclosing scopes for ClassDeclaration.
*/ /********************************************
* Search enclosing scopes for ClassDeclaration.
AggregateDeclaration *Scope::getStructClassScope() */
{ Scope *sc;
AggregateDeclaration *Scope::getStructClassScope()
for (sc = this; sc; sc = sc->enclosing) { Scope *sc;
{
AggregateDeclaration *ad; for (sc = this; sc; sc = sc->enclosing)
{
if (sc->scopesym) AggregateDeclaration *ad;
{
ad = sc->scopesym->isClassDeclaration(); if (sc->scopesym)
if (ad) {
return ad; ad = sc->scopesym->isClassDeclaration();
else if (ad)
{ ad = sc->scopesym->isStructDeclaration(); return ad;
if (ad) else
return ad; { ad = sc->scopesym->isStructDeclaration();
} if (ad)
} return ad;
} }
return NULL; }
} }
return NULL;
/******************************************* }
* For TemplateDeclarations, we need to remember the Scope
* where it was declared. So mark the Scope as not /*******************************************
* to be free'd. * For TemplateDeclarations, we need to remember the Scope
*/ * where it was declared. So mark the Scope as not
* to be free'd.
void Scope::setNoFree() */
{ Scope *sc;
//int i = 0; void Scope::setNoFree()
{ Scope *sc;
//printf("Scope::setNoFree(this = %p)\n", this); //int i = 0;
for (sc = this; sc; sc = sc->enclosing)
{ //printf("Scope::setNoFree(this = %p)\n", this);
//printf("\tsc = %p\n", sc); for (sc = this; sc; sc = sc->enclosing)
sc->nofree = 1; {
//printf("\tsc = %p\n", sc);
assert(!(flags & SCOPEfree)); sc->nofree = 1;
//assert(sc != sc->enclosing);
//assert(!sc->enclosing || sc != sc->enclosing->enclosing); assert(!(flags & SCOPEfree));
//if (++i == 10) //assert(sc != sc->enclosing);
//assert(0); //assert(!sc->enclosing || sc != sc->enclosing->enclosing);
} //if (++i == 10)
} //assert(0);
}
}

View File

@@ -1,110 +1,111 @@
// Copyright (c) 1999-2005 by Digital Mars // Copyright (c) 1999-2005 by Digital Mars
// All Rights Reserved // All Rights Reserved
// written by Walter Bright // written by Walter Bright
// http://www.digitalmars.com // http://www.digitalmars.com
// License for redistribution is by either the Artistic License // License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt. // in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details. // See the included readme.txt for details.
#ifndef DMD_SCOPE_H #ifndef DMD_SCOPE_H
#define DMD_SCOPE_H #define DMD_SCOPE_H
#ifdef __DMC__ #ifdef __DMC__
#pragma once #pragma once
#endif /* __DMC__ */ #endif /* __DMC__ */
struct Dsymbol; struct Dsymbol;
struct ScopeDsymbol; struct ScopeDsymbol;
struct Array; struct Array;
struct Identifier; struct Identifier;
struct Module; struct Module;
struct Statement; struct Statement;
struct SwitchStatement; struct SwitchStatement;
struct TryFinallyStatement; struct TryFinallyStatement;
struct LabelStatement; struct LabelStatement;
struct ForeachStatement; struct ForeachStatement;
struct ClassDeclaration; struct ClassDeclaration;
struct AggregateDeclaration; struct AggregateDeclaration;
struct AnonymousAggregateDeclaration; struct AnonymousAggregateDeclaration;
struct FuncDeclaration; struct FuncDeclaration;
struct DocComment; struct DocComment;
enum LINK; enum LINK;
enum PROT; enum PROT;
struct Scope struct Scope
{ {
Scope *enclosing; // enclosing Scope Scope *enclosing; // enclosing Scope
Module *module; // Root module Module *module; // Root module
ScopeDsymbol *scopesym; // current symbol ScopeDsymbol *scopesym; // current symbol
ScopeDsymbol *sd; // if in static if, and declaring new symbols, ScopeDsymbol *sd; // if in static if, and declaring new symbols,
// sd gets the addMember() // sd gets the addMember()
FuncDeclaration *func; // function we are in FuncDeclaration *func; // function we are in
Dsymbol *parent; // parent to use Dsymbol *parent; // parent to use
LabelStatement *slabel; // enclosing labelled statement LabelStatement *slabel; // enclosing labelled statement
SwitchStatement *sw; // enclosing switch statement SwitchStatement *sw; // enclosing switch statement
TryFinallyStatement *tf; // enclosing try finally statement; set inside its finally block TryFinallyStatement *tf; // enclosing try finally statement; set inside its finally block
TryFinallyStatement *tfOfTry; // enclosing try finally statement; set inside its try block TryFinallyStatement *tfOfTry; // enclosing try finally statement; set inside its try block
Statement *sbreak; // enclosing statement that supports "break" Statement *sbreak; // enclosing statement that supports "break"
Statement *scontinue; // enclosing statement that supports "continue" Statement *scontinue; // enclosing statement that supports "continue"
ForeachStatement *fes; // if nested function for ForeachStatement, this is it ForeachStatement *fes; // if nested function for ForeachStatement, this is it
unsigned offset; // next offset to use in aggregate unsigned offset; // next offset to use in aggregate
int inunion; // we're processing members of a union int inunion; // we're processing members of a union
int incontract; // we're inside contract code int incontract; // we're inside contract code
int nofree; // set if shouldn't free it int nofree; // set if shouldn't free it
int noctor; // set if constructor calls aren't allowed int noctor; // set if constructor calls aren't allowed
int intypeof; // in typeof(exp) int intypeof; // in typeof(exp)
int parameterSpecialization; // if in template parameter specialization int parameterSpecialization; // if in template parameter specialization
int noaccesscheck; // don't do access checks
unsigned callSuper; // primitive flow analysis for constructors
#define CSXthis_ctor 1 // called this() unsigned callSuper; // primitive flow analysis for constructors
#define CSXsuper_ctor 2 // called super() #define CSXthis_ctor 1 // called this()
#define CSXthis 4 // referenced this #define CSXsuper_ctor 2 // called super()
#define CSXsuper 8 // referenced super #define CSXthis 4 // referenced this
#define CSXlabel 0x10 // seen a label #define CSXsuper 8 // referenced super
#define CSXreturn 0x20 // seen a return statement #define CSXlabel 0x10 // seen a label
#define CSXany_ctor 0x40 // either this() or super() was called #define CSXreturn 0x20 // seen a return statement
#define CSXany_ctor 0x40 // either this() or super() was called
unsigned structalign; // alignment for struct members
enum LINK linkage; // linkage for external functions unsigned structalign; // alignment for struct members
enum LINK linkage; // linkage for external functions
enum PROT protection; // protection for class members
int explicitProtection; // set if in an explicit protection attribute enum PROT protection; // protection for class members
int explicitProtection; // set if in an explicit protection attribute
unsigned stc; // storage class
unsigned stc; // storage class
unsigned flags;
#define SCOPEctor 1 // constructor type unsigned flags;
#define SCOPEstaticif 2 // inside static if #define SCOPEctor 1 // constructor type
#define SCOPEfree 4 // is on free list #define SCOPEstaticif 2 // inside static if
#define SCOPEfree 4 // is on free list
AnonymousAggregateDeclaration *anonAgg; // for temporary analysis
AnonymousAggregateDeclaration *anonAgg; // for temporary analysis
DocComment *lastdc; // documentation comment for last symbol at this scope
unsigned lastoffset; // offset in docbuf of where to insert next dec DocComment *lastdc; // documentation comment for last symbol at this scope
OutBuffer *docbuf; // buffer for documentation output unsigned lastoffset; // offset in docbuf of where to insert next dec
OutBuffer *docbuf; // buffer for documentation output
static Scope *freelist;
static void *operator new(size_t sz); static Scope *freelist;
static Scope *createGlobal(Module *module); static void *operator new(size_t sz);
static Scope *createGlobal(Module *module);
Scope();
Scope(Module *module); Scope();
Scope(Scope *enclosing); Scope(Module *module);
Scope(Scope *enclosing);
Scope *push();
Scope *push(ScopeDsymbol *ss); Scope *push();
Scope *pop(); Scope *push(ScopeDsymbol *ss);
Scope *pop();
void mergeCallSuper(Loc loc, unsigned cs);
void mergeCallSuper(Loc loc, unsigned cs);
Dsymbol *search(Loc loc, Identifier *ident, Dsymbol **pscopesym);
Dsymbol *insert(Dsymbol *s); Dsymbol *search(Loc loc, Identifier *ident, Dsymbol **pscopesym);
Dsymbol *insert(Dsymbol *s);
ClassDeclaration *getClassScope();
AggregateDeclaration *getStructClassScope(); ClassDeclaration *getClassScope();
void setNoFree(); AggregateDeclaration *getStructClassScope();
}; void setNoFree();
};
#endif /* DMD_SCOPE_H */
#endif /* DMD_SCOPE_H */

File diff suppressed because it is too large Load Diff

View File

@@ -130,6 +130,7 @@ int match(Object *o1, Object *o2, TemplateDeclaration *tempdecl, Scope *sc)
Dsymbol *s2 = isDsymbol(o2); Dsymbol *s2 = isDsymbol(o2);
Tuple *v1 = isTuple(o1); Tuple *v1 = isTuple(o1);
Tuple *v2 = isTuple(o2); Tuple *v2 = isTuple(o2);
//printf("\t match t1 %p t2 %p, e1 %p e2 %p, s1 %p s2 %p, v1 %p v2 %p\n", t1,t2,e1,e2,s1,s2,v1,v2);
/* A proper implementation of the various equals() overrides /* A proper implementation of the various equals() overrides
* should make it possible to just do o1->equals(o2), but * should make it possible to just do o1->equals(o2), but
@@ -158,7 +159,7 @@ int match(Object *o1, Object *o2, TemplateDeclaration *tempdecl, Scope *sc)
} }
if (!t2 || !t1->equals(t2)) if (!t2 || !t1->equals(t2))
goto L1; goto Lnomatch;
} }
else if (e1) else if (e1)
{ {
@@ -168,33 +169,39 @@ int match(Object *o1, Object *o2, TemplateDeclaration *tempdecl, Scope *sc)
printf("match %d\n", e1->equals(e2)); printf("match %d\n", e1->equals(e2));
e1->print(); e1->print();
e2->print(); e2->print();
e1->type->print();
e2->type->print();
} }
#endif #endif
if (!e2 || !e1->equals(e2)) if (!e2)
goto L1; goto Lnomatch;
if (!e1->equals(e2))
goto Lnomatch;
} }
else if (s1) else if (s1)
{ {
//printf("%p %s, %p %s\n", s1, s1->toChars(), s2, s2->toChars()); //printf("%p %s, %p %s\n", s1, s1->toChars(), s2, s2->toChars());
if (!s2 || !s1->equals(s2) || s1->parent != s2->parent) if (!s2 || !s1->equals(s2) || s1->parent != s2->parent)
goto L1; {
goto Lnomatch;
}
} }
else if (v1) else if (v1)
{ {
if (!v2) if (!v2)
goto L1; goto Lnomatch;
if (v1->objects.dim != v2->objects.dim) if (v1->objects.dim != v2->objects.dim)
goto L1; goto Lnomatch;
for (size_t i = 0; i < v1->objects.dim; i++) for (size_t i = 0; i < v1->objects.dim; i++)
{ {
if (!match((Object *)v1->objects.data[i], if (!match((Object *)v1->objects.data[i],
(Object *)v2->objects.data[i], (Object *)v2->objects.data[i],
tempdecl, sc)) tempdecl, sc))
goto L1; goto Lnomatch;
} }
} }
return 1; // match return 1; // match
L1: Lnomatch:
return 0; // nomatch; return 0; // nomatch;
} }
@@ -268,6 +275,7 @@ TemplateDeclaration::TemplateDeclaration(Loc loc, Identifier *id, TemplateParame
#endif #endif
this->loc = loc; this->loc = loc;
this->parameters = parameters; this->parameters = parameters;
this->origParameters = parameters;
this->members = decldefs; this->members = decldefs;
this->overnext = NULL; this->overnext = NULL;
this->overroot = NULL; this->overroot = NULL;
@@ -336,6 +344,17 @@ void TemplateDeclaration::semantic(Scope *sc)
Scope *paramscope = sc->push(paramsym); Scope *paramscope = sc->push(paramsym);
paramscope->parameterSpecialization = 1; paramscope->parameterSpecialization = 1;
if (global.params.doDocComments)
{
origParameters = new TemplateParameters();
origParameters->setDim(parameters->dim);
for (int i = 0; i < parameters->dim; i++)
{
TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
origParameters->data[i] = (void *)tp->syntaxCopy();
}
}
for (int i = 0; i < parameters->dim; i++) for (int i = 0; i < parameters->dim; i++)
{ {
TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
@@ -348,6 +367,8 @@ void TemplateDeclaration::semantic(Scope *sc)
TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
tp->semantic(paramscope); tp->semantic(paramscope);
if (i + 1 != parameters->dim && tp->isTemplateTupleParameter())
error("template tuple parameter must be last one");
} }
paramscope->pop(); paramscope->pop();
@@ -437,6 +458,7 @@ int TemplateDeclaration::overloadInsert(Dsymbol *s)
* those deduced types in dedtypes[]. * those deduced types in dedtypes[].
* Input: * Input:
* flag 1: don't do semantic() because of dummy types * flag 1: don't do semantic() because of dummy types
* 2: don't change types in matchArg()
* Output: * Output:
* dedtypes deduced arguments * dedtypes deduced arguments
* Return match level. * Return match level.
@@ -447,8 +469,9 @@ MATCH TemplateDeclaration::matchWithInstance(TemplateInstance *ti,
{ MATCH m; { MATCH m;
int dedtypes_dim = dedtypes->dim; int dedtypes_dim = dedtypes->dim;
#if LOG #define LOGM 0
printf("+TemplateDeclaration::matchWithInstance(this = %s, ti = %s, flag = %d)\n", toChars(), ti->toChars(), flag); #if LOGM
printf("\n+TemplateDeclaration::matchWithInstance(this = %s, ti = %s, flag = %d)\n", toChars(), ti->toChars(), flag);
#endif #endif
#if 0 #if 0
@@ -466,7 +489,7 @@ MATCH TemplateDeclaration::matchWithInstance(TemplateInstance *ti,
// If more arguments than parameters, no match // If more arguments than parameters, no match
if (ti->tiargs->dim > parameters_dim && !variadic) if (ti->tiargs->dim > parameters_dim && !variadic)
{ {
#if LOG #if LOGM
printf(" no match: more arguments than parameters\n"); printf(" no match: more arguments than parameters\n");
#endif #endif
return MATCHnomatch; return MATCHnomatch;
@@ -489,7 +512,7 @@ MATCH TemplateDeclaration::matchWithInstance(TemplateInstance *ti,
Declaration *sparam; Declaration *sparam;
//printf("\targument [%d]\n", i); //printf("\targument [%d]\n", i);
#if 0 #if LOGM
//printf("\targument [%d] is %s\n", i, oarg ? oarg->toChars() : "null"); //printf("\targument [%d] is %s\n", i, oarg ? oarg->toChars() : "null");
TemplateTypeParameter *ttp = tp->isTemplateTypeParameter(); TemplateTypeParameter *ttp = tp->isTemplateTypeParameter();
if (ttp) if (ttp)
@@ -528,7 +551,7 @@ MATCH TemplateDeclaration::matchWithInstance(TemplateInstance *ti,
} }
} }
#if 0 #if LOGM
// Print out the results // Print out the results
printf("--------------------------\n"); printf("--------------------------\n");
printf("template %s\n", toChars()); printf("template %s\n", toChars());
@@ -553,20 +576,20 @@ MATCH TemplateDeclaration::matchWithInstance(TemplateInstance *ti,
goto Lnomatch; goto Lnomatch;
#endif #endif
#if LOG #if LOGM
printf(" match = %d\n", m); printf(" match = %d\n", m);
#endif #endif
goto Lret; goto Lret;
Lnomatch: Lnomatch:
#if LOG #if LOGM
printf(" no match\n"); printf(" no match\n");
#endif #endif
m = MATCHnomatch; m = MATCHnomatch;
Lret: Lret:
paramscope->pop(); paramscope->pop();
#if LOG #if LOGM
printf("-TemplateDeclaration::matchWithInstance(this = %p, ti = %p) = %d\n", this, ti, m); printf("-TemplateDeclaration::matchWithInstance(this = %p, ti = %p) = %d\n", this, ti, m);
#endif #endif
return m; return m;
@@ -645,6 +668,8 @@ int TemplateDeclaration::leastAsSpecialized(TemplateDeclaration *td2)
* fargs arguments to function * fargs arguments to function
* Output: * Output:
* dedargs Expression/Type deduced template arguments * dedargs Expression/Type deduced template arguments
* Returns:
* match level
*/ */
MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Objects *targsi, Expressions *fargs, MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Objects *targsi, Expressions *fargs,
@@ -652,12 +677,13 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Objects *targsi, Expressi
{ {
size_t i; size_t i;
size_t nfparams; size_t nfparams;
size_t nfparams2;
size_t nfargs; size_t nfargs;
size_t nargsi; size_t nargsi; // array size of targsi
int fptupindex = -1;
int tuple_dim = 0;
MATCH match = MATCHexact; MATCH match = MATCHexact;
FuncDeclaration *fd = onemember->toAlias()->isFuncDeclaration(); FuncDeclaration *fd = onemember->toAlias()->isFuncDeclaration();
TypeFunction *fdtype; TypeFunction *fdtype; // type of fd
TemplateTupleParameter *tp; TemplateTupleParameter *tp;
Objects dedtypes; // for T:T*, the dedargs is the T*, dedtypes is the T Objects dedtypes; // for T:T*, the dedargs is the T*, dedtypes is the T
@@ -682,13 +708,19 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Objects *targsi, Expressi
paramsym->parent = scope->parent; paramsym->parent = scope->parent;
Scope *paramscope = scope->push(paramsym); Scope *paramscope = scope->push(paramsym);
tp = isVariadic();
nargsi = 0; nargsi = 0;
if (targsi) if (targsi)
{ // Set initial template arguments { // Set initial template arguments
nargsi = targsi->dim; nargsi = targsi->dim;
if (nargsi > parameters->dim) if (nargsi > parameters->dim)
goto Lnomatch; { if (!tp)
goto Lnomatch;
dedargs->setDim(nargsi);
dedargs->zero();
}
memcpy(dedargs->data, targsi->data, nargsi * sizeof(*dedargs->data)); memcpy(dedargs->data, targsi->data, nargsi * sizeof(*dedargs->data));
@@ -698,6 +730,7 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Objects *targsi, Expressi
Declaration *sparam; Declaration *sparam;
m = tp->matchArg(paramscope, dedargs, i, parameters, &dedtypes, &sparam); m = tp->matchArg(paramscope, dedargs, i, parameters, &dedtypes, &sparam);
//printf("\tdeduceType m = %d\n", m);
if (m == MATCHnomatch) if (m == MATCHnomatch)
goto Lnomatch; goto Lnomatch;
if (m < match) if (m < match)
@@ -713,7 +746,6 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Objects *targsi, Expressi
fdtype = (TypeFunction *)fd->type; fdtype = (TypeFunction *)fd->type;
nfparams = Argument::dim(fdtype->parameters); // number of function parameters nfparams = Argument::dim(fdtype->parameters); // number of function parameters
nfparams2 = nfparams;
nfargs = fargs->dim; // number of function arguments nfargs = fargs->dim; // number of function arguments
/* Check for match of function arguments with variadic template /* Check for match of function arguments with variadic template
@@ -723,7 +755,7 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Objects *targsi, Expressi
* void main() { Foo(1,2,3); } * void main() { Foo(1,2,3); }
*/ */
tp = isVariadic(); tp = isVariadic();
if (tp) if (tp) // if variadic
{ {
if (nfparams == 0) // if no function parameters if (nfparams == 0) // if no function parameters
{ {
@@ -736,33 +768,38 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Objects *targsi, Expressi
goto L1; goto L1;
else else
{ {
/* See if 'A' of the template parameter matches 'A' /* Figure out which of the function parameters matches
* of the type of the last function parameter. * the tuple template parameter. Do this by matching
* type identifiers.
* Set the index of this function parameter to fptupindex.
*/ */
Argument *fparam = (Argument *)fdtype->parameters->data[nfparams - 1]; for (fptupindex = 0; fptupindex < nfparams; fptupindex++)
if (fparam->type->ty != Tident) {
goto L1; Argument *fparam = (Argument *)fdtype->parameters->data[fptupindex];
TypeIdentifier *tid = (TypeIdentifier *)fparam->type; if (fparam->type->ty != Tident)
if (!tp->ident->equals(tid->ident) || tid->idents.dim) continue;
goto L1; TypeIdentifier *tid = (TypeIdentifier *)fparam->type;
if (!tp->ident->equals(tid->ident) || tid->idents.dim)
continue;
if (fdtype->varargs) // variadic function doesn't if (fdtype->varargs) // variadic function doesn't
goto Lnomatch; // go with variadic template goto Lnomatch; // go with variadic template
/* The types of the function arguments [nfparams - 1 .. nfargs] /* The types of the function arguments
* now form the tuple argument. * now form the tuple argument.
*/ */
Tuple *t = new Tuple(); Tuple *t = new Tuple();
dedargs->data[parameters->dim - 1] = (void *)t; dedargs->data[parameters->dim - 1] = (void *)t;
int tuple_dim = nfargs - (nfparams - 1); tuple_dim = nfargs - (nfparams - 1);
t->objects.setDim(tuple_dim); t->objects.setDim(tuple_dim);
for (i = 0; i < tuple_dim; i++) for (i = 0; i < tuple_dim; i++)
{ Expression *farg = (Expression *)fargs->data[nfparams - 1 + i]; { Expression *farg = (Expression *)fargs->data[fptupindex + i];
t->objects.data[i] = (void *)farg->type; t->objects.data[i] = (void *)farg->type;
}
goto L2;
} }
nfparams2--; // don't consider the last parameter for type deduction fptupindex = -1;
goto L2;
} }
} }
@@ -778,11 +815,19 @@ L1:
L2: L2:
// Loop through the function parameters // Loop through the function parameters
for (i = 0; i < nfparams2; i++) for (i = 0; i < nfparams; i++)
{ {
/* Skip over function parameters which wound up
* as part of a template tuple parameter.
*/
if (i == fptupindex)
{ if (fptupindex == nfparams - 1)
break;
i += tuple_dim - 1;
continue;
}
Argument *fparam = Argument::getNth(fdtype->parameters, i); Argument *fparam = Argument::getNth(fdtype->parameters, i);
Expression *farg;
MATCH m;
if (i >= nfargs) // if not enough arguments if (i >= nfargs) // if not enough arguments
{ {
@@ -794,12 +839,13 @@ L2:
} }
} }
else else
{ farg = (Expression *)fargs->data[i]; { Expression *farg = (Expression *)fargs->data[i];
#if 0 #if 0
printf("\tfarg->type = %s\n", farg->type->toChars()); printf("\tfarg->type = %s\n", farg->type->toChars());
printf("\tfparam->type = %s\n", fparam->type->toChars()); printf("\tfparam->type = %s\n", fparam->type->toChars());
#endif #endif
MATCH m;
m = farg->type->deduceType(scope, fparam->type, parameters, &dedtypes); m = farg->type->deduceType(scope, fparam->type, parameters, &dedtypes);
//printf("\tdeduceType m = %d\n", m); //printf("\tdeduceType m = %d\n", m);
@@ -852,30 +898,40 @@ Lmatch:
for (i = nargsi; i < dedargs->dim; i++) for (i = nargsi; i < dedargs->dim; i++)
{ {
TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
//printf("tp[%d] = %s\n", i, tp->ident->toChars());
/* For T:T*, the dedargs is the T*, dedtypes is the T
* But for function templates, we really need them to match
*/
Object *oarg = (Object *)dedargs->data[i]; Object *oarg = (Object *)dedargs->data[i];
Object *o = (Object *)dedtypes.data[i]; Object *oded = (Object *)dedtypes.data[i];
//printf("1dedargs[%d] = %p, dedtypes[%d] = %p\n", i, oarg, i, o); //printf("1dedargs[%d] = %p, dedtypes[%d] = %p\n", i, oarg, i, oded);
if (!oarg) if (!oarg)
{ {
if (o) if (oded)
{ {
if (tp->specialization()) if (tp->specialization())
error("specialization not allowed for deduced parameter %s", tp->ident->toChars()); { /* The specialization can work as long as afterwards
* the oded == oarg
*/
Declaration *sparam;
dedargs->data[i] = (void *)oded;
MATCH m2 = tp->matchArg(paramscope, dedargs, i, parameters, &dedtypes, &sparam);
//printf("m2 = %d\n", m2);
if (!m2)
goto Lnomatch;
if (m2 < match)
match = m2; // pick worst match
if (dedtypes.data[i] != oded)
error("specialization not allowed for deduced parameter %s", tp->ident->toChars());
}
} }
else else
{ o = tp->defaultArg(paramscope); { oded = tp->defaultArg(paramscope);
if (!o) if (!oded)
goto Lnomatch; goto Lnomatch;
#if 0
Match m;
Declaration *sparam;
m = tp->matchArg(paramscope, dedargs, i, parameters, &sparam);
if (!m)
goto Lnomatch;
#endif
} }
declareParameter(paramscope, tp, o); declareParameter(paramscope, tp, oded);
dedargs->data[i] = (void *)o; dedargs->data[i] = (void *)oded;
} }
} }
@@ -887,7 +943,7 @@ Lmatch:
#endif #endif
paramscope->pop(); paramscope->pop();
//printf("\tmatch\n"); //printf("\tmatch %d\n", match);
return match; return match;
Lnomatch: Lnomatch:
@@ -1044,9 +1100,9 @@ FuncDeclaration *TemplateDeclaration::deduceFunctionTemplate(Scope *sc, Loc loc,
int c2 = td_best->leastAsSpecialized(td); int c2 = td_best->leastAsSpecialized(td);
//printf("c1 = %d, c2 = %d\n", c1, c2); //printf("c1 = %d, c2 = %d\n", c1, c2);
if (c1 && !c2) if (c1 > c2)
goto Ltd; goto Ltd;
else if (!c1 && c2) else if (c1 < c2)
goto Ltd_best; goto Ltd_best;
else else
goto Lambig; goto Lambig;
@@ -1116,6 +1172,8 @@ void TemplateDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
for (int i = 0; i < parameters->dim; i++) for (int i = 0; i < parameters->dim; i++)
{ {
TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
if (hgs->ddoc)
tp = (TemplateParameter *)origParameters->data[i];
if (i) if (i)
buf->writeByte(','); buf->writeByte(',');
tp->toCBuffer(buf, hgs); tp->toCBuffer(buf, hgs);
@@ -1516,7 +1574,19 @@ MATCH TypeInstance::deduceType(Scope *sc,
*/ */
int i = templateIdentifierLookup(tp->tempinst->name, parameters); int i = templateIdentifierLookup(tp->tempinst->name, parameters);
if (i == -1) if (i == -1)
{ /* Didn't find it as a parameter identifier. Try looking
* it up and seeing if is an alias. See Bugzilla 1454
*/
Dsymbol *s = tempinst->tempdecl->scope->search(0, tp->tempinst->name, NULL);
if (s)
{
s = s->toAlias();
TemplateDeclaration *td = s->isTemplateDeclaration();
if (td && td == tempinst->tempdecl)
goto L2;
}
goto Lnomatch; goto Lnomatch;
}
TemplateParameter *tpx = (TemplateParameter *)parameters->data[i]; TemplateParameter *tpx = (TemplateParameter *)parameters->data[i];
// This logic duplicates tpx->matchArg() // This logic duplicates tpx->matchArg()
TemplateAliasParameter *ta = tpx->isTemplateAliasParameter(); TemplateAliasParameter *ta = tpx->isTemplateAliasParameter();
@@ -1540,12 +1610,14 @@ MATCH TypeInstance::deduceType(Scope *sc,
else if (tempinst->tempdecl != tp->tempinst->tempdecl) else if (tempinst->tempdecl != tp->tempinst->tempdecl)
goto Lnomatch; goto Lnomatch;
L2:
if (tempinst->tiargs->dim != tp->tempinst->tiargs->dim) if (tempinst->tiargs->dim != tp->tempinst->tiargs->dim)
goto Lnomatch; goto Lnomatch;
for (int i = 0; i < tempinst->tiargs->dim; i++) for (int i = 0; i < tempinst->tiargs->dim; i++)
{ {
//printf("test: [%d]\n", i); //printf("\ttest: tempinst->tiargs[%d]\n", i);
int j;
Object *o1 = (Object *)tempinst->tiargs->data[i]; Object *o1 = (Object *)tempinst->tiargs->data[i];
Object *o2 = (Object *)tp->tempinst->tiargs->data[i]; Object *o2 = (Object *)tp->tempinst->tiargs->data[i];
@@ -1570,18 +1642,29 @@ MATCH TypeInstance::deduceType(Scope *sc,
else if (e1 && e2) else if (e1 && e2)
{ {
if (!e1->equals(e2)) if (!e1->equals(e2))
{ if (e2->op == TOKvar)
{
/*
* (T:Number!(e2), int e2)
*/
j = templateIdentifierLookup(((VarExp *)e2)->var->ident, parameters);
goto L1;
}
goto Lnomatch; goto Lnomatch;
}
} }
else if (e1 && t2 && t2->ty == Tident) else if (e1 && t2 && t2->ty == Tident)
{ int i = templateParameterLookup(t2, parameters); {
if (i == -1) j = templateParameterLookup(t2, parameters);
L1:
if (j == -1)
goto Lnomatch; goto Lnomatch;
TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; TemplateParameter *tp = (TemplateParameter *)parameters->data[j];
// BUG: use tp->matchArg() instead of the following // BUG: use tp->matchArg() instead of the following
TemplateValueParameter *tv = tp->isTemplateValueParameter(); TemplateValueParameter *tv = tp->isTemplateValueParameter();
if (!tv) if (!tv)
goto Lnomatch; goto Lnomatch;
Expression *e = (Expression *)dedtypes->data[i]; Expression *e = (Expression *)dedtypes->data[j];
if (e) if (e)
{ {
if (!e1->equals(e)) if (!e1->equals(e))
@@ -1592,7 +1675,7 @@ MATCH TypeInstance::deduceType(Scope *sc,
MATCH m = (MATCH)e1->implicitConvTo(vt); MATCH m = (MATCH)e1->implicitConvTo(vt);
if (!m) if (!m)
goto Lnomatch; goto Lnomatch;
dedtypes->data[i] = e1; dedtypes->data[j] = e1;
} }
} }
// BUG: Need to handle alias and tuple parameters // BUG: Need to handle alias and tuple parameters
@@ -2351,6 +2434,7 @@ Lmatch:
return m; return m;
Lnomatch: Lnomatch:
//printf("\tno match\n");
*psparam = NULL; *psparam = NULL;
return MATCHnomatch; return MATCHnomatch;
} }
@@ -2780,7 +2864,7 @@ void TemplateInstance::semantic(Scope *sc)
if (m->semanticdone >= 3) if (m->semanticdone >= 3)
dosemantic3 = 1; dosemantic3 = 1;
} }
for (i = 0; 1; i++) for (int i = 0; 1; i++)
{ {
if (i == a->dim) if (i == a->dim)
{ {
@@ -2953,7 +3037,7 @@ void TemplateInstance::semanticTiargs(Loc loc, Scope *sc, Objects *tiargs)
Expression *ea = isExpression(o); Expression *ea = isExpression(o);
Dsymbol *sa = isDsymbol(o); Dsymbol *sa = isDsymbol(o);
//printf("1: tiargs->data[%d] = %p, %p, %p\n", j, o, isDsymbol(o), isTuple(o)); //printf("1: tiargs->data[%d] = %p, %p, %p, ea=%p, ta=%p\n", j, o, isDsymbol(o), isTuple(o), ea, ta);
if (ta) if (ta)
{ {
//printf("type %s\n", ta->toChars()); //printf("type %s\n", ta->toChars());
@@ -3196,9 +3280,9 @@ TemplateDeclaration *TemplateInstance::findBestMatch(Scope *sc)
int c2 = td_best->leastAsSpecialized(td); int c2 = td_best->leastAsSpecialized(td);
//printf("c1 = %d, c2 = %d\n", c1, c2); //printf("c1 = %d, c2 = %d\n", c1, c2);
if (c1 && !c2) if (c1 > c2)
goto Ltd; goto Ltd;
else if (!c1 && c2) else if (c1 < c2)
goto Ltd_best; goto Ltd_best;
else else
goto Lambig; goto Lambig;
@@ -3305,10 +3389,30 @@ int TemplateInstance::isNested(Objects *args)
{ {
// if module level template // if module level template
if (tempdecl->toParent()->isModule()) if (tempdecl->toParent()->isModule())
{ { Dsymbol *dparent = d->toParent();
if (isnested && isnested != d->toParent()) if (!isnested)
error("inconsistent nesting levels %s and %s", isnested->toChars(), d->toParent()->toChars()); isnested = dparent;
isnested = d->toParent(); else if (isnested != dparent)
{
/* Select the more deeply nested of the two.
* Error if one is not nested inside the other.
*/
for (Dsymbol *p = isnested; p; p = p->parent)
{
if (p == dparent)
goto L1; // isnested is most nested
}
for (Dsymbol *p = dparent; 1; p = p->parent)
{
if (p == isnested)
{ isnested = dparent;
goto L1; // dparent is most nested
}
}
error("is nested in both %s and %s", isnested->toChars(), dparent->toChars());
}
L1:
//printf("\tnested inside %s\n", isnested->toChars());
nested |= 1; nested |= 1;
} }
else else

View File

@@ -1,325 +1,328 @@
// Compiler implementation of the D programming language // Compiler implementation of the D programming language
// Copyright (c) 1999-2006 by Digital Mars // Copyright (c) 1999-2006 by Digital Mars
// All Rights Reserved // All Rights Reserved
// written by Walter Bright // written by Walter Bright
// http://www.digitalmars.com // http://www.digitalmars.com
// License for redistribution is by either the Artistic License // License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt. // in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details. // See the included readme.txt for details.
#ifndef DMD_TEMPLATE_H #ifndef DMD_TEMPLATE_H
#define DMD_TEMPLATE_H #define DMD_TEMPLATE_H
#ifdef __DMC__ #ifdef __DMC__
#pragma once #pragma once
#endif /* __DMC__ */ #endif /* __DMC__ */
#include "root.h" #include "root.h"
#include "arraytypes.h" #include "arraytypes.h"
#include "dsymbol.h" #include "dsymbol.h"
#include "mtype.h" #include "mtype.h"
struct OutBuffer; struct OutBuffer;
struct Identifier; struct Identifier;
struct TemplateInstance; struct TemplateInstance;
struct TemplateParameter; struct TemplateParameter;
struct TemplateTypeParameter; struct TemplateTypeParameter;
struct TemplateValueParameter; struct TemplateValueParameter;
struct TemplateAliasParameter; struct TemplateAliasParameter;
struct TemplateTupleParameter; struct TemplateTupleParameter;
struct Type; struct Type;
struct TypeTypeof; struct TypeTypeof;
struct Scope; struct Scope;
struct Expression; struct Expression;
struct AliasDeclaration; struct AliasDeclaration;
struct FuncDeclaration; struct FuncDeclaration;
struct HdrGenState; struct HdrGenState;
enum MATCH; enum MATCH;
struct Tuple : Object struct Tuple : Object
{ {
Objects objects; Objects objects;
int dyncast() { return DYNCAST_TUPLE; } // kludge for template.isType() int dyncast() { return DYNCAST_TUPLE; } // kludge for template.isType()
}; };
struct TemplateDeclaration : ScopeDsymbol struct TemplateDeclaration : ScopeDsymbol
{ {
TemplateParameters *parameters; // array of TemplateParameter's TemplateParameters *parameters; // array of TemplateParameter's
Array instances; // array of TemplateInstance's
TemplateParameters *origParameters; // originals for Ddoc
TemplateDeclaration *overnext; // next overloaded TemplateDeclaration
TemplateDeclaration *overroot; // first in overnext list Array instances; // array of TemplateInstance's
Scope *scope; TemplateDeclaration *overnext; // next overloaded TemplateDeclaration
Dsymbol *onemember; // if !=NULL then one member of this template TemplateDeclaration *overroot; // first in overnext list
TemplateDeclaration(Loc loc, Identifier *id, TemplateParameters *parameters, Array *decldefs); Scope *scope;
Dsymbol *syntaxCopy(Dsymbol *); Dsymbol *onemember; // if !=NULL then one member of this template
void semantic(Scope *sc);
int overloadInsert(Dsymbol *s); TemplateDeclaration(Loc loc, Identifier *id, TemplateParameters *parameters, Array *decldefs);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs); Dsymbol *syntaxCopy(Dsymbol *);
char *kind(); void semantic(Scope *sc);
char *toChars(); int overloadInsert(Dsymbol *s);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
void emitComment(Scope *sc); char *kind();
// void toDocBuffer(OutBuffer *buf); char *toChars();
MATCH matchWithInstance(TemplateInstance *ti, Objects *atypes, int flag); void emitComment(Scope *sc);
int leastAsSpecialized(TemplateDeclaration *td2); // void toDocBuffer(OutBuffer *buf);
MATCH deduceFunctionTemplateMatch(Objects *targsi, Expressions *fargs, Objects *dedargs); MATCH matchWithInstance(TemplateInstance *ti, Objects *atypes, int flag);
FuncDeclaration *deduceFunctionTemplate(Scope *sc, Loc loc, Objects *targsi, Expressions *fargs); int leastAsSpecialized(TemplateDeclaration *td2);
void declareParameter(Scope *sc, TemplateParameter *tp, Object *o);
MATCH deduceFunctionTemplateMatch(Objects *targsi, Expressions *fargs, Objects *dedargs);
TemplateDeclaration *isTemplateDeclaration() { return this; } FuncDeclaration *deduceFunctionTemplate(Scope *sc, Loc loc, Objects *targsi, Expressions *fargs);
void declareParameter(Scope *sc, TemplateParameter *tp, Object *o);
TemplateTupleParameter *isVariadic();
int isOverloadable(); TemplateDeclaration *isTemplateDeclaration() { return this; }
};
TemplateTupleParameter *isVariadic();
struct TemplateParameter int isOverloadable();
{ };
/* For type-parameter:
* template Foo(ident) // specType is set to NULL struct TemplateParameter
* template Foo(ident : specType) {
* For value-parameter: /* For type-parameter:
* template Foo(valType ident) // specValue is set to NULL * template Foo(ident) // specType is set to NULL
* template Foo(valType ident : specValue) * template Foo(ident : specType)
* For alias-parameter: * For value-parameter:
* template Foo(alias ident) * template Foo(valType ident) // specValue is set to NULL
*/ * template Foo(valType ident : specValue)
* For alias-parameter:
Loc loc; * template Foo(alias ident)
Identifier *ident; */
Declaration *sparam; Loc loc;
Identifier *ident;
TemplateParameter(Loc loc, Identifier *ident);
Declaration *sparam;
virtual TemplateTypeParameter *isTemplateTypeParameter();
virtual TemplateValueParameter *isTemplateValueParameter(); TemplateParameter(Loc loc, Identifier *ident);
virtual TemplateAliasParameter *isTemplateAliasParameter();
virtual TemplateTupleParameter *isTemplateTupleParameter(); virtual TemplateTypeParameter *isTemplateTypeParameter();
virtual TemplateValueParameter *isTemplateValueParameter();
virtual TemplateParameter *syntaxCopy() = 0; virtual TemplateAliasParameter *isTemplateAliasParameter();
virtual void declareParameter(Scope *sc) = 0; virtual TemplateTupleParameter *isTemplateTupleParameter();
virtual void semantic(Scope *) = 0;
virtual void print(Object *oarg, Object *oded) = 0; virtual TemplateParameter *syntaxCopy() = 0;
virtual void toCBuffer(OutBuffer *buf, HdrGenState *hgs) = 0; virtual void declareParameter(Scope *sc) = 0;
virtual Object *specialization() = 0; virtual void semantic(Scope *) = 0;
virtual Object *defaultArg(Scope *sc) = 0; virtual void print(Object *oarg, Object *oded) = 0;
virtual void toCBuffer(OutBuffer *buf, HdrGenState *hgs) = 0;
/* If TemplateParameter's match as far as overloading goes. virtual Object *specialization() = 0;
*/ virtual Object *defaultArg(Scope *sc) = 0;
virtual int overloadMatch(TemplateParameter *) = 0;
/* If TemplateParameter's match as far as overloading goes.
/* Match actual argument against parameter. */
*/ virtual int overloadMatch(TemplateParameter *) = 0;
virtual MATCH matchArg(Scope *sc, Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam) = 0;
/* Match actual argument against parameter.
/* Create dummy argument based on parameter. */
*/ virtual MATCH matchArg(Scope *sc, Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam) = 0;
virtual void *dummyArg() = 0;
}; /* Create dummy argument based on parameter.
*/
struct TemplateTypeParameter : TemplateParameter virtual void *dummyArg() = 0;
{ };
/* Syntax:
* ident : specType = defaultType struct TemplateTypeParameter : TemplateParameter
*/ {
Type *specType; // type parameter: if !=NULL, this is the type specialization /* Syntax:
Type *defaultType; * ident : specType = defaultType
*/
TemplateTypeParameter(Loc loc, Identifier *ident, Type *specType, Type *defaultType); Type *specType; // type parameter: if !=NULL, this is the type specialization
Type *defaultType;
TemplateTypeParameter *isTemplateTypeParameter();
TemplateParameter *syntaxCopy(); TemplateTypeParameter(Loc loc, Identifier *ident, Type *specType, Type *defaultType);
void declareParameter(Scope *sc);
void semantic(Scope *); TemplateTypeParameter *isTemplateTypeParameter();
void print(Object *oarg, Object *oded); TemplateParameter *syntaxCopy();
void toCBuffer(OutBuffer *buf, HdrGenState *hgs); void declareParameter(Scope *sc);
Object *specialization(); void semantic(Scope *);
Object *defaultArg(Scope *sc); void print(Object *oarg, Object *oded);
int overloadMatch(TemplateParameter *); void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
MATCH matchArg(Scope *sc, Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam); Object *specialization();
void *dummyArg(); Object *defaultArg(Scope *sc);
}; int overloadMatch(TemplateParameter *);
MATCH matchArg(Scope *sc, Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam);
struct TemplateValueParameter : TemplateParameter void *dummyArg();
{ };
/* Syntax:
* valType ident : specValue = defaultValue struct TemplateValueParameter : TemplateParameter
*/ {
/* Syntax:
Type *valType; * valType ident : specValue = defaultValue
Expression *specValue; */
Expression *defaultValue;
Type *valType;
static Expression *edummy; Expression *specValue;
Expression *defaultValue;
TemplateValueParameter(Loc loc, Identifier *ident, Type *valType, Expression *specValue, Expression *defaultValue);
static Expression *edummy;
TemplateValueParameter *isTemplateValueParameter();
TemplateParameter *syntaxCopy(); TemplateValueParameter(Loc loc, Identifier *ident, Type *valType, Expression *specValue, Expression *defaultValue);
void declareParameter(Scope *sc);
void semantic(Scope *); TemplateValueParameter *isTemplateValueParameter();
void print(Object *oarg, Object *oded); TemplateParameter *syntaxCopy();
void toCBuffer(OutBuffer *buf, HdrGenState *hgs); void declareParameter(Scope *sc);
Object *specialization(); void semantic(Scope *);
Object *defaultArg(Scope *sc); void print(Object *oarg, Object *oded);
int overloadMatch(TemplateParameter *); void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
MATCH matchArg(Scope *sc, Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam); Object *specialization();
void *dummyArg(); Object *defaultArg(Scope *sc);
}; int overloadMatch(TemplateParameter *);
MATCH matchArg(Scope *sc, Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam);
struct TemplateAliasParameter : TemplateParameter void *dummyArg();
{ };
/* Syntax:
* ident : specAlias = defaultAlias struct TemplateAliasParameter : TemplateParameter
*/ {
/* Syntax:
Type *specAliasT; * ident : specAlias = defaultAlias
Dsymbol *specAlias; */
Type *defaultAlias; Type *specAliasT;
Dsymbol *specAlias;
static Dsymbol *sdummy;
Type *defaultAlias;
TemplateAliasParameter(Loc loc, Identifier *ident, Type *specAliasT, Type *defaultAlias);
static Dsymbol *sdummy;
TemplateAliasParameter *isTemplateAliasParameter();
TemplateParameter *syntaxCopy(); TemplateAliasParameter(Loc loc, Identifier *ident, Type *specAliasT, Type *defaultAlias);
void declareParameter(Scope *sc);
void semantic(Scope *); TemplateAliasParameter *isTemplateAliasParameter();
void print(Object *oarg, Object *oded); TemplateParameter *syntaxCopy();
void toCBuffer(OutBuffer *buf, HdrGenState *hgs); void declareParameter(Scope *sc);
Object *specialization(); void semantic(Scope *);
Object *defaultArg(Scope *sc); void print(Object *oarg, Object *oded);
int overloadMatch(TemplateParameter *); void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
MATCH matchArg(Scope *sc, Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam); Object *specialization();
void *dummyArg(); Object *defaultArg(Scope *sc);
}; int overloadMatch(TemplateParameter *);
MATCH matchArg(Scope *sc, Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam);
struct TemplateTupleParameter : TemplateParameter void *dummyArg();
{ };
/* Syntax:
* ident ... struct TemplateTupleParameter : TemplateParameter
*/ {
/* Syntax:
TemplateTupleParameter(Loc loc, Identifier *ident); * ident ...
*/
TemplateTupleParameter *isTemplateTupleParameter();
TemplateParameter *syntaxCopy(); TemplateTupleParameter(Loc loc, Identifier *ident);
void declareParameter(Scope *sc);
void semantic(Scope *); TemplateTupleParameter *isTemplateTupleParameter();
void print(Object *oarg, Object *oded); TemplateParameter *syntaxCopy();
void toCBuffer(OutBuffer *buf, HdrGenState *hgs); void declareParameter(Scope *sc);
Object *specialization(); void semantic(Scope *);
Object *defaultArg(Scope *sc); void print(Object *oarg, Object *oded);
int overloadMatch(TemplateParameter *); void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
MATCH matchArg(Scope *sc, Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam); Object *specialization();
void *dummyArg(); Object *defaultArg(Scope *sc);
}; int overloadMatch(TemplateParameter *);
MATCH matchArg(Scope *sc, Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam);
struct TemplateInstance : ScopeDsymbol void *dummyArg();
{ };
/* Given:
* foo!(args) => struct TemplateInstance : ScopeDsymbol
* name = foo {
* tiargs = args /* Given:
*/ * foo!(args) =>
Identifier *name; * name = foo
//Array idents; * tiargs = args
Objects *tiargs; // Array of Types/Expressions of template */
// instance arguments [int*, char, 10*10] Identifier *name;
//Array idents;
Objects tdtypes; // Array of Types/Expressions corresponding Objects *tiargs; // Array of Types/Expressions of template
// to TemplateDeclaration.parameters // instance arguments [int*, char, 10*10]
// [int, char, 100]
Objects tdtypes; // Array of Types/Expressions corresponding
TemplateDeclaration *tempdecl; // referenced by foo.bar.abc // to TemplateDeclaration.parameters
TemplateInstance *inst; // refer to existing instance // [int, char, 100]
ScopeDsymbol *argsym; // argument symbol table
AliasDeclaration *aliasdecl; // !=NULL if instance is an alias for its TemplateDeclaration *tempdecl; // referenced by foo.bar.abc
// sole member TemplateInstance *inst; // refer to existing instance
WithScopeSymbol *withsym; // if a member of a with statement ScopeDsymbol *argsym; // argument symbol table
int semanticdone; // has semantic() been done? AliasDeclaration *aliasdecl; // !=NULL if instance is an alias for its
int nest; // for recursion detection // sole member
int havetempdecl; // 1 if used second constructor WithScopeSymbol *withsym; // if a member of a with statement
Dsymbol *isnested; // if referencing local symbols, this is the context int semanticdone; // has semantic() been done?
int errors; // 1 if compiled with errors int nest; // for recursion detection
#ifdef IN_GCC int havetempdecl; // 1 if used second constructor
/* On some targets, it is necessary to know whether a symbol Dsymbol *isnested; // if referencing local symbols, this is the context
will be emitted in the output or not before the symbol int errors; // 1 if compiled with errors
is used. This can be different from getModule(). */ #ifdef IN_GCC
Module * objFileModule; /* On some targets, it is necessary to know whether a symbol
#endif will be emitted in the output or not before the symbol
is used. This can be different from getModule(). */
TemplateInstance(Loc loc, Identifier *temp_id); Module * objFileModule;
TemplateInstance(Loc loc, TemplateDeclaration *tempdecl, Objects *tiargs); #endif
static Objects *arraySyntaxCopy(Objects *objs);
Dsymbol *syntaxCopy(Dsymbol *); TemplateInstance(Loc loc, Identifier *temp_id);
void semantic(Scope *sc); TemplateInstance(Loc loc, TemplateDeclaration *tempdecl, Objects *tiargs);
void semantic2(Scope *sc); static Objects *arraySyntaxCopy(Objects *objs);
void semantic3(Scope *sc); Dsymbol *syntaxCopy(Dsymbol *);
void inlineScan(); void semantic(Scope *sc);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs); void semantic2(Scope *sc);
Dsymbol *toAlias(); // resolve real symbol void semantic3(Scope *sc);
char *kind(); void inlineScan();
int oneMember(Dsymbol **ps); void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
char *toChars(); Dsymbol *toAlias(); // resolve real symbol
char *mangle(); char *kind();
int oneMember(Dsymbol **ps);
void toObjFile(); // compile to .obj file char *toChars();
char *mangle();
// Internal
static void semanticTiargs(Loc loc, Scope *sc, Objects *tiargs); void toObjFile(); // compile to .obj file
void semanticTiargs(Scope *sc);
TemplateDeclaration *findTemplateDeclaration(Scope *sc); // Internal
TemplateDeclaration *findBestMatch(Scope *sc); static void semanticTiargs(Loc loc, Scope *sc, Objects *tiargs);
void declareParameters(Scope *sc); void semanticTiargs(Scope *sc);
int isNested(Objects *tiargs); TemplateDeclaration *findTemplateDeclaration(Scope *sc);
Identifier *genIdent(); TemplateDeclaration *findBestMatch(Scope *sc);
void declareParameters(Scope *sc);
TemplateInstance *isTemplateInstance() { return this; } int isNested(Objects *tiargs);
AliasDeclaration *isAliasDeclaration(); Identifier *genIdent();
};
TemplateInstance *isTemplateInstance() { return this; }
struct TemplateMixin : TemplateInstance AliasDeclaration *isAliasDeclaration();
{ };
Array *idents;
Type *tqual; struct TemplateMixin : TemplateInstance
{
Scope *scope; // for forward referencing Array *idents;
Type *tqual;
TemplateMixin(Loc loc, Identifier *ident, Type *tqual, Array *idents, Objects *tiargs);
Dsymbol *syntaxCopy(Dsymbol *s); Scope *scope; // for forward referencing
void semantic(Scope *sc);
void semantic2(Scope *sc); TemplateMixin(Loc loc, Identifier *ident, Type *tqual, Array *idents, Objects *tiargs);
void semantic3(Scope *sc); Dsymbol *syntaxCopy(Dsymbol *s);
void inlineScan(); void semantic(Scope *sc);
char *kind(); void semantic2(Scope *sc);
int oneMember(Dsymbol **ps); void semantic3(Scope *sc);
int hasPointers(); void inlineScan();
char *toChars(); char *kind();
void toCBuffer(OutBuffer *buf, HdrGenState *hgs); int oneMember(Dsymbol **ps);
int hasPointers();
void toObjFile(); // compile to .obj file char *toChars();
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
TemplateMixin *isTemplateMixin() { return this; }
}; void toObjFile(); // compile to .obj file
Expression *isExpression(Object *o); TemplateMixin *isTemplateMixin() { return this; }
Dsymbol *isDsymbol(Object *o); };
Type *isType(Object *o);
Tuple *isTuple(Object *o); Expression *isExpression(Object *o);
Type *getType(Object *o); Dsymbol *isDsymbol(Object *o);
Dsymbol *getDsymbol(Object *o); Type *isType(Object *o);
Tuple *isTuple(Object *o);
void ObjectToCBuffer(OutBuffer *buf, HdrGenState *hgs, Object *oarg); Type *getType(Object *o);
Dsymbol *getDsymbol(Object *o);
#endif /* DMD_TEMPLATE_H */
void ObjectToCBuffer(OutBuffer *buf, HdrGenState *hgs, Object *oarg);
#endif /* DMD_TEMPLATE_H */