mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-02-26 16:43:13 +01:00
[svn r175] merged dmd 1.029
This commit is contained in:
541
dmd/aggregate.h
541
dmd/aggregate.h
@@ -1,259 +1,282 @@
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 1999-2006 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.
|
||||
|
||||
#ifndef DMD_AGGREGATE_H
|
||||
#define DMD_AGGREGATE_H
|
||||
|
||||
#ifdef __DMC__
|
||||
#pragma once
|
||||
#endif /* __DMC__ */
|
||||
|
||||
#include "root.h"
|
||||
#include "dsymbol.h"
|
||||
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <map>
|
||||
|
||||
struct Identifier;
|
||||
struct Type;
|
||||
struct TypeFunction;
|
||||
struct Expression;
|
||||
struct FuncDeclaration;
|
||||
struct CtorDeclaration;
|
||||
struct DtorDeclaration;
|
||||
struct InvariantDeclaration;
|
||||
struct NewDeclaration;
|
||||
struct DeleteDeclaration;
|
||||
struct InterfaceDeclaration;
|
||||
struct ClassInfoDeclaration;
|
||||
struct VarDeclaration;
|
||||
struct dt_t;
|
||||
|
||||
namespace llvm
|
||||
{
|
||||
class Type;
|
||||
class Value;
|
||||
class Constant;
|
||||
class ConstantStruct;
|
||||
class GlobalVariable;
|
||||
}
|
||||
struct DUnion;
|
||||
|
||||
struct AggregateDeclaration : ScopeDsymbol
|
||||
{
|
||||
Type *type;
|
||||
unsigned storage_class;
|
||||
enum PROT protection;
|
||||
Type *handle; // 'this' type
|
||||
unsigned structsize; // size of struct
|
||||
unsigned alignsize; // size of struct for alignment purposes
|
||||
unsigned structalign; // struct member alignment in effect
|
||||
int hasUnions; // set if aggregate has overlapping fields
|
||||
Array fields; // VarDeclaration fields
|
||||
unsigned sizeok; // set when structsize contains valid data
|
||||
// 0: no size
|
||||
// 1: size is correct
|
||||
// 2: cannot determine size; fwd referenced
|
||||
int isdeprecated; // !=0 if deprecated
|
||||
Scope *scope; // !=NULL means context to use
|
||||
|
||||
// Special member functions
|
||||
InvariantDeclaration *inv; // invariant
|
||||
NewDeclaration *aggNew; // allocator
|
||||
DeleteDeclaration *aggDelete; // deallocator
|
||||
|
||||
#ifdef IN_GCC
|
||||
Array methods; // flat list of all methods for debug information
|
||||
#endif
|
||||
|
||||
AggregateDeclaration(Loc loc, Identifier *id);
|
||||
void semantic2(Scope *sc);
|
||||
void semantic3(Scope *sc);
|
||||
void inlineScan();
|
||||
unsigned size(Loc loc);
|
||||
static void alignmember(unsigned salign, unsigned size, unsigned *poffset);
|
||||
Type *getType();
|
||||
void addField(Scope *sc, VarDeclaration *v);
|
||||
int isDeprecated(); // is aggregate deprecated?
|
||||
|
||||
void emitComment(Scope *sc);
|
||||
void toDocBuffer(OutBuffer *buf);
|
||||
|
||||
// For access checking
|
||||
virtual PROT getAccess(Dsymbol *smember); // determine access to smember
|
||||
int isFriendOf(AggregateDeclaration *cd);
|
||||
int hasPrivateAccess(Dsymbol *smember); // does smember have private access to members of this class?
|
||||
void accessCheck(Loc loc, Scope *sc, Dsymbol *smember);
|
||||
|
||||
enum PROT prot();
|
||||
|
||||
// Back end
|
||||
Symbol *stag; // tag symbol for debug data
|
||||
Symbol *sinit;
|
||||
Symbol *toInitializer();
|
||||
|
||||
AggregateDeclaration *isAggregateDeclaration() { return this; }
|
||||
};
|
||||
|
||||
struct AnonymousAggregateDeclaration : AggregateDeclaration
|
||||
{
|
||||
AnonymousAggregateDeclaration()
|
||||
: AggregateDeclaration(0, NULL)
|
||||
{
|
||||
}
|
||||
|
||||
AnonymousAggregateDeclaration *isAnonymousAggregateDeclaration() { return this; }
|
||||
};
|
||||
|
||||
struct StructDeclaration : AggregateDeclaration
|
||||
{
|
||||
int zeroInit; // !=0 if initialize with 0 fill
|
||||
|
||||
StructDeclaration(Loc loc, Identifier *id);
|
||||
Dsymbol *syntaxCopy(Dsymbol *s);
|
||||
void semantic(Scope *sc);
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
char *mangle();
|
||||
char *kind();
|
||||
void toDocBuffer(OutBuffer *buf);
|
||||
|
||||
PROT getAccess(Dsymbol *smember); // determine access to smember
|
||||
|
||||
void toObjFile(); // compile to .obj file
|
||||
void toDt(dt_t **pdt);
|
||||
void toDebug(); // to symbolic debug info
|
||||
|
||||
StructDeclaration *isStructDeclaration() { return this; }
|
||||
};
|
||||
|
||||
struct UnionDeclaration : StructDeclaration
|
||||
{
|
||||
UnionDeclaration(Loc loc, Identifier *id);
|
||||
Dsymbol *syntaxCopy(Dsymbol *s);
|
||||
char *kind();
|
||||
|
||||
UnionDeclaration *isUnionDeclaration() { return this; }
|
||||
};
|
||||
|
||||
struct BaseClass
|
||||
{
|
||||
Type *type; // (before semantic processing)
|
||||
enum PROT protection; // protection for the base interface
|
||||
|
||||
ClassDeclaration *base;
|
||||
int offset; // 'this' pointer offset
|
||||
Array vtbl; // for interfaces: Array of FuncDeclaration's
|
||||
// making up the vtbl[]
|
||||
|
||||
int baseInterfaces_dim;
|
||||
BaseClass *baseInterfaces; // if BaseClass is an interface, these
|
||||
// are a copy of the InterfaceDeclaration::interfaces
|
||||
|
||||
BaseClass();
|
||||
BaseClass(Type *type, enum PROT protection);
|
||||
|
||||
int fillVtbl(ClassDeclaration *cd, Array *vtbl, int newinstance);
|
||||
void copyBaseInterfaces(BaseClasses *);
|
||||
};
|
||||
|
||||
#define CLASSINFO_SIZE (0x3C+12) // value of ClassInfo.size
|
||||
|
||||
struct ClassDeclaration : AggregateDeclaration
|
||||
{
|
||||
static ClassDeclaration *object;
|
||||
static ClassDeclaration *classinfo;
|
||||
|
||||
ClassDeclaration *baseClass; // NULL only if this is Object
|
||||
CtorDeclaration *ctor;
|
||||
CtorDeclaration *defaultCtor; // default constructor
|
||||
FuncDeclarations dtors; // Array of destructors
|
||||
FuncDeclaration *staticCtor;
|
||||
FuncDeclaration *staticDtor;
|
||||
Array vtbl; // Array of FuncDeclaration's making up the vtbl[]
|
||||
Array vtblFinal; // More FuncDeclaration's that aren't in vtbl[]
|
||||
|
||||
BaseClasses baseclasses; // Array of BaseClass's; first is super,
|
||||
// rest are Interface's
|
||||
|
||||
int interfaces_dim;
|
||||
BaseClass **interfaces; // interfaces[interfaces_dim] for this class
|
||||
// (does not include baseClass)
|
||||
|
||||
BaseClasses *vtblInterfaces; // array of base interfaces that have
|
||||
// their own vtbl[]
|
||||
|
||||
ClassInfoDeclaration *vclassinfo; // the ClassInfo object for this ClassDeclaration
|
||||
int com; // !=0 if this is a COM class
|
||||
int isauto; // !=0 if this is an auto class
|
||||
int isabstract; // !=0 if abstract class
|
||||
|
||||
int isnested; // !=0 if is nested
|
||||
VarDeclaration *vthis; // 'this' parameter if this class is nested
|
||||
|
||||
ClassDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses);
|
||||
Dsymbol *syntaxCopy(Dsymbol *s);
|
||||
void semantic(Scope *sc);
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
int isBaseOf2(ClassDeclaration *cd);
|
||||
|
||||
#define OFFSET_RUNTIME 0x76543210
|
||||
virtual int isBaseOf(ClassDeclaration *cd, int *poffset);
|
||||
|
||||
Dsymbol *search(Loc, Identifier *ident, int flags);
|
||||
FuncDeclaration *findFunc(Identifier *ident, TypeFunction *tf);
|
||||
void interfaceSemantic(Scope *sc);
|
||||
int isNested();
|
||||
int isCOMclass();
|
||||
virtual int isCOMinterface();
|
||||
int isAbstract();
|
||||
virtual int vtblOffset();
|
||||
char *kind();
|
||||
char *mangle();
|
||||
void toDocBuffer(OutBuffer *buf);
|
||||
|
||||
PROT getAccess(Dsymbol *smember); // determine access to smember
|
||||
|
||||
void addLocalClass(ClassDeclarations *);
|
||||
|
||||
// Back end
|
||||
void toObjFile(); // compile to .obj file
|
||||
void toDebug();
|
||||
unsigned baseVtblOffset(BaseClass *bc);
|
||||
Symbol *toSymbol();
|
||||
Symbol *toVtblSymbol();
|
||||
void toDt(dt_t **pdt);
|
||||
void toDt2(dt_t **pdt, ClassDeclaration *cd);
|
||||
|
||||
Symbol *vtblsym;
|
||||
|
||||
void offsetToIndex(Type* t, unsigned os, std::vector<unsigned>& result);
|
||||
|
||||
ClassDeclaration *isClassDeclaration() { return (ClassDeclaration *)this; }
|
||||
};
|
||||
|
||||
struct InterfaceDeclaration : ClassDeclaration
|
||||
{
|
||||
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();
|
||||
virtual int isCOMinterface();
|
||||
|
||||
void toObjFile(); // compile to .obj file
|
||||
Symbol *toSymbol();
|
||||
|
||||
InterfaceDeclaration *isInterfaceDeclaration() { return this; }
|
||||
};
|
||||
|
||||
#endif /* DMD_AGGREGATE_H */
|
||||
|
||||
// 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.
|
||||
|
||||
#ifndef DMD_AGGREGATE_H
|
||||
#define DMD_AGGREGATE_H
|
||||
|
||||
#ifdef __DMC__
|
||||
#pragma once
|
||||
#endif /* __DMC__ */
|
||||
|
||||
#include "root.h"
|
||||
#include "dsymbol.h"
|
||||
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <map>
|
||||
|
||||
struct Identifier;
|
||||
struct Type;
|
||||
struct TypeFunction;
|
||||
struct Expression;
|
||||
struct FuncDeclaration;
|
||||
struct CtorDeclaration;
|
||||
struct DtorDeclaration;
|
||||
struct InvariantDeclaration;
|
||||
struct NewDeclaration;
|
||||
struct DeleteDeclaration;
|
||||
struct InterfaceDeclaration;
|
||||
struct ClassInfoDeclaration;
|
||||
struct VarDeclaration;
|
||||
struct dt_t;
|
||||
|
||||
namespace llvm
|
||||
{
|
||||
class Type;
|
||||
class Value;
|
||||
class Constant;
|
||||
class ConstantStruct;
|
||||
class GlobalVariable;
|
||||
}
|
||||
struct DUnion;
|
||||
|
||||
struct AggregateDeclaration : ScopeDsymbol
|
||||
{
|
||||
Type *type;
|
||||
unsigned storage_class;
|
||||
enum PROT protection;
|
||||
Type *handle; // 'this' type
|
||||
unsigned structsize; // size of struct
|
||||
unsigned alignsize; // size of struct for alignment purposes
|
||||
unsigned structalign; // struct member alignment in effect
|
||||
int hasUnions; // set if aggregate has overlapping fields
|
||||
Array fields; // VarDeclaration fields
|
||||
unsigned sizeok; // set when structsize contains valid data
|
||||
// 0: no size
|
||||
// 1: size is correct
|
||||
// 2: cannot determine size; fwd referenced
|
||||
int isdeprecated; // !=0 if deprecated
|
||||
Scope *scope; // !=NULL means context to use
|
||||
FuncDeclarations dtors; // Array of destructors
|
||||
FuncDeclaration *dtor; // aggregate destructor
|
||||
|
||||
// Special member functions
|
||||
InvariantDeclaration *inv; // invariant
|
||||
NewDeclaration *aggNew; // allocator
|
||||
DeleteDeclaration *aggDelete; // deallocator
|
||||
|
||||
#ifdef IN_GCC
|
||||
Array methods; // flat list of all methods for debug information
|
||||
#endif
|
||||
|
||||
AggregateDeclaration(Loc loc, Identifier *id);
|
||||
void semantic2(Scope *sc);
|
||||
void semantic3(Scope *sc);
|
||||
void inlineScan();
|
||||
unsigned size(Loc loc);
|
||||
static void alignmember(unsigned salign, unsigned size, unsigned *poffset);
|
||||
Type *getType();
|
||||
void addField(Scope *sc, VarDeclaration *v);
|
||||
int isDeprecated(); // is aggregate deprecated?
|
||||
FuncDeclaration *buildDtor(Scope *sc);
|
||||
|
||||
void emitComment(Scope *sc);
|
||||
void toDocBuffer(OutBuffer *buf);
|
||||
|
||||
// For access checking
|
||||
virtual PROT getAccess(Dsymbol *smember); // determine access to smember
|
||||
int isFriendOf(AggregateDeclaration *cd);
|
||||
int hasPrivateAccess(Dsymbol *smember); // does smember have private access to members of this class?
|
||||
void accessCheck(Loc loc, Scope *sc, Dsymbol *smember);
|
||||
|
||||
enum PROT prot();
|
||||
|
||||
// Back end
|
||||
Symbol *stag; // tag symbol for debug data
|
||||
Symbol *sinit;
|
||||
Symbol *toInitializer();
|
||||
|
||||
AggregateDeclaration *isAggregateDeclaration() { return this; }
|
||||
};
|
||||
|
||||
struct AnonymousAggregateDeclaration : AggregateDeclaration
|
||||
{
|
||||
AnonymousAggregateDeclaration()
|
||||
: AggregateDeclaration(0, NULL)
|
||||
{
|
||||
}
|
||||
|
||||
AnonymousAggregateDeclaration *isAnonymousAggregateDeclaration() { return this; }
|
||||
};
|
||||
|
||||
struct StructDeclaration : AggregateDeclaration
|
||||
{
|
||||
int zeroInit; // !=0 if initialize with 0 fill
|
||||
|
||||
StructDeclaration(Loc loc, Identifier *id);
|
||||
Dsymbol *syntaxCopy(Dsymbol *s);
|
||||
void semantic(Scope *sc);
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
char *mangle();
|
||||
char *kind();
|
||||
Expression *cloneMembers();
|
||||
void toDocBuffer(OutBuffer *buf);
|
||||
|
||||
PROT getAccess(Dsymbol *smember); // determine access to smember
|
||||
|
||||
void toObjFile(); // compile to .obj file
|
||||
void toDt(dt_t **pdt);
|
||||
void toDebug(); // to symbolic debug info
|
||||
|
||||
StructDeclaration *isStructDeclaration() { return this; }
|
||||
};
|
||||
|
||||
struct UnionDeclaration : StructDeclaration
|
||||
{
|
||||
UnionDeclaration(Loc loc, Identifier *id);
|
||||
Dsymbol *syntaxCopy(Dsymbol *s);
|
||||
char *kind();
|
||||
|
||||
UnionDeclaration *isUnionDeclaration() { return this; }
|
||||
};
|
||||
|
||||
struct BaseClass
|
||||
{
|
||||
Type *type; // (before semantic processing)
|
||||
enum PROT protection; // protection for the base interface
|
||||
|
||||
ClassDeclaration *base;
|
||||
int offset; // 'this' pointer offset
|
||||
Array vtbl; // for interfaces: Array of FuncDeclaration's
|
||||
// making up the vtbl[]
|
||||
|
||||
int baseInterfaces_dim;
|
||||
BaseClass *baseInterfaces; // if BaseClass is an interface, these
|
||||
// are a copy of the InterfaceDeclaration::interfaces
|
||||
|
||||
BaseClass();
|
||||
BaseClass(Type *type, enum PROT protection);
|
||||
|
||||
int fillVtbl(ClassDeclaration *cd, Array *vtbl, int newinstance);
|
||||
void copyBaseInterfaces(BaseClasses *);
|
||||
};
|
||||
|
||||
#if V2
|
||||
#define CLASSINFO_SIZE (0x3C+16) // value of ClassInfo.size
|
||||
#else
|
||||
#define CLASSINFO_SIZE (0x3C+12) // value of ClassInfo.size
|
||||
#endif
|
||||
|
||||
struct ClassDeclaration : AggregateDeclaration
|
||||
{
|
||||
static ClassDeclaration *object;
|
||||
static ClassDeclaration *classinfo;
|
||||
|
||||
ClassDeclaration *baseClass; // NULL only if this is Object
|
||||
CtorDeclaration *ctor;
|
||||
CtorDeclaration *defaultCtor; // default constructor
|
||||
FuncDeclaration *staticCtor;
|
||||
FuncDeclaration *staticDtor;
|
||||
Array vtbl; // Array of FuncDeclaration's making up the vtbl[]
|
||||
Array vtblFinal; // More FuncDeclaration's that aren't in vtbl[]
|
||||
|
||||
BaseClasses baseclasses; // Array of BaseClass's; first is super,
|
||||
// rest are Interface's
|
||||
|
||||
int interfaces_dim;
|
||||
BaseClass **interfaces; // interfaces[interfaces_dim] for this class
|
||||
// (does not include baseClass)
|
||||
|
||||
BaseClasses *vtblInterfaces; // array of base interfaces that have
|
||||
// their own vtbl[]
|
||||
|
||||
ClassInfoDeclaration *vclassinfo; // the ClassInfo object for this ClassDeclaration
|
||||
int com; // !=0 if this is a COM class (meaning
|
||||
// it derives from IUnknown)
|
||||
int isauto; // !=0 if this is an auto class
|
||||
int isabstract; // !=0 if abstract class
|
||||
|
||||
int isnested; // !=0 if is nested
|
||||
VarDeclaration *vthis; // 'this' parameter if this class is nested
|
||||
|
||||
int inuse; // to prevent recursive attempts
|
||||
|
||||
ClassDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses);
|
||||
Dsymbol *syntaxCopy(Dsymbol *s);
|
||||
void semantic(Scope *sc);
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
int isBaseOf2(ClassDeclaration *cd);
|
||||
|
||||
#define OFFSET_RUNTIME 0x76543210
|
||||
virtual int isBaseOf(ClassDeclaration *cd, int *poffset);
|
||||
|
||||
Dsymbol *search(Loc, Identifier *ident, int flags);
|
||||
#if V2
|
||||
int isFuncHidden(FuncDeclaration *fd);
|
||||
#endif
|
||||
FuncDeclaration *findFunc(Identifier *ident, TypeFunction *tf);
|
||||
void interfaceSemantic(Scope *sc);
|
||||
int isNested();
|
||||
int isCOMclass();
|
||||
virtual int isCOMinterface();
|
||||
#if V2
|
||||
virtual int isCPPinterface();
|
||||
#endif
|
||||
int isAbstract();
|
||||
virtual int vtblOffset();
|
||||
char *kind();
|
||||
char *mangle();
|
||||
void toDocBuffer(OutBuffer *buf);
|
||||
|
||||
PROT getAccess(Dsymbol *smember); // determine access to smember
|
||||
|
||||
void addLocalClass(ClassDeclarations *);
|
||||
|
||||
// Back end
|
||||
void toObjFile(); // compile to .obj file
|
||||
void toDebug();
|
||||
unsigned baseVtblOffset(BaseClass *bc);
|
||||
Symbol *toSymbol();
|
||||
Symbol *toVtblSymbol();
|
||||
void toDt(dt_t **pdt);
|
||||
void toDt2(dt_t **pdt, ClassDeclaration *cd);
|
||||
|
||||
Symbol *vtblsym;
|
||||
|
||||
// llvm
|
||||
void offsetToIndex(Type* t, unsigned os, std::vector<unsigned>& result);
|
||||
|
||||
ClassDeclaration *isClassDeclaration() { return (ClassDeclaration *)this; }
|
||||
};
|
||||
|
||||
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 */
|
||||
|
||||
2611
dmd/attrib.c
2611
dmd/attrib.c
File diff suppressed because it is too large
Load Diff
2909
dmd/cast.c
2909
dmd/cast.c
File diff suppressed because it is too large
Load Diff
2698
dmd/class.c
2698
dmd/class.c
File diff suppressed because it is too large
Load Diff
175
dmd/clone.c
Normal file
175
dmd/clone.c
Normal 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
2626
dmd/declaration.c
2626
dmd/declaration.c
File diff suppressed because it is too large
Load Diff
1528
dmd/declaration.h
1528
dmd/declaration.h
File diff suppressed because it is too large
Load Diff
2014
dmd/dsymbol.c
2014
dmd/dsymbol.c
File diff suppressed because it is too large
Load Diff
597
dmd/dsymbol.h
597
dmd/dsymbol.h
@@ -1,298 +1,299 @@
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 1999-2007 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.
|
||||
|
||||
#ifndef DMD_DSYMBOL_H
|
||||
#define DMD_DSYMBOL_H
|
||||
|
||||
#ifdef __DMC__
|
||||
#pragma once
|
||||
#endif /* __DMC__ */
|
||||
|
||||
#include "root.h"
|
||||
#include "stringtable.h"
|
||||
|
||||
#include "mars.h"
|
||||
#include "arraytypes.h"
|
||||
|
||||
struct Identifier;
|
||||
struct Scope;
|
||||
struct DsymbolTable;
|
||||
struct Declaration;
|
||||
struct TupleDeclaration;
|
||||
struct TypedefDeclaration;
|
||||
struct AliasDeclaration;
|
||||
struct AggregateDeclaration;
|
||||
struct EnumDeclaration;
|
||||
struct ClassDeclaration;
|
||||
struct InterfaceDeclaration;
|
||||
struct StructDeclaration;
|
||||
struct UnionDeclaration;
|
||||
struct FuncDeclaration;
|
||||
struct FuncAliasDeclaration;
|
||||
struct FuncLiteralDeclaration;
|
||||
struct CtorDeclaration;
|
||||
struct DtorDeclaration;
|
||||
struct StaticCtorDeclaration;
|
||||
struct StaticDtorDeclaration;
|
||||
struct InvariantDeclaration;
|
||||
struct UnitTestDeclaration;
|
||||
struct NewDeclaration;
|
||||
struct VarDeclaration;
|
||||
struct AttribDeclaration;
|
||||
struct Symbol;
|
||||
struct Package;
|
||||
struct Module;
|
||||
struct Import;
|
||||
struct Type;
|
||||
struct TypeTuple;
|
||||
struct WithStatement;
|
||||
struct LabelDsymbol;
|
||||
struct ScopeDsymbol;
|
||||
struct TemplateDeclaration;
|
||||
struct TemplateInstance;
|
||||
struct TemplateMixin;
|
||||
struct EnumMember;
|
||||
struct ScopeDsymbol;
|
||||
struct WithScopeSymbol;
|
||||
struct ArrayScopeSymbol;
|
||||
struct SymbolDeclaration;
|
||||
struct Expression;
|
||||
struct DeleteDeclaration;
|
||||
struct HdrGenState;
|
||||
struct TypeInfoDeclaration;
|
||||
struct ClassInfoDeclaration;
|
||||
|
||||
#if IN_GCC
|
||||
union tree_node;
|
||||
typedef union tree_node TYPE;
|
||||
#else
|
||||
struct TYPE;
|
||||
#endif
|
||||
|
||||
#if IN_LLVM
|
||||
namespace llvm
|
||||
{
|
||||
class Value;
|
||||
}
|
||||
#endif
|
||||
|
||||
enum PROT
|
||||
{
|
||||
PROTundefined,
|
||||
PROTnone, // no access
|
||||
PROTprivate,
|
||||
PROTpackage,
|
||||
PROTprotected,
|
||||
PROTpublic,
|
||||
PROTexport,
|
||||
};
|
||||
|
||||
struct Dsymbol : Object
|
||||
{
|
||||
Identifier *ident;
|
||||
Identifier *c_ident;
|
||||
Dsymbol *parent;
|
||||
Symbol *csym; // symbol for code generator
|
||||
Symbol *isym; // import version of csym
|
||||
unsigned char *comment; // documentation comment for this Dsymbol
|
||||
Loc loc; // where defined
|
||||
|
||||
Dsymbol();
|
||||
Dsymbol(Identifier *);
|
||||
char *toChars();
|
||||
char *toPrettyChars();
|
||||
char *locToChars();
|
||||
int equals(Object *o);
|
||||
int isAnonymous();
|
||||
void error(Loc loc, const char *format, ...);
|
||||
void error(const char *format, ...);
|
||||
void checkDeprecated(Loc loc, Scope *sc);
|
||||
Module *getModule();
|
||||
Dsymbol *pastMixin();
|
||||
Dsymbol *toParent();
|
||||
Dsymbol *toParent2();
|
||||
|
||||
int dyncast() { return DYNCAST_DSYMBOL; } // kludge for template.isSymbol()
|
||||
|
||||
static Array *arraySyntaxCopy(Array *a);
|
||||
|
||||
virtual char *kind();
|
||||
virtual Dsymbol *toAlias(); // resolve real symbol
|
||||
virtual int addMember(Scope *sc, ScopeDsymbol *s, int memnum);
|
||||
virtual void semantic(Scope *sc);
|
||||
virtual void semantic2(Scope *sc);
|
||||
virtual void semantic3(Scope *sc);
|
||||
virtual void inlineScan();
|
||||
virtual Dsymbol *search(Loc loc, Identifier *ident, int flags);
|
||||
Dsymbol *searchX(Loc loc, Scope *sc, Identifier *id);
|
||||
virtual int overloadInsert(Dsymbol *s);
|
||||
#ifdef _DH
|
||||
char *toHChars();
|
||||
virtual void toHBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
#endif
|
||||
virtual void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
virtual void toDocBuffer(OutBuffer *buf);
|
||||
virtual unsigned size(Loc loc);
|
||||
virtual int isforwardRef();
|
||||
virtual void defineRef(Dsymbol *s);
|
||||
virtual AggregateDeclaration *isThis(); // is a 'this' required to access the member
|
||||
virtual ClassDeclaration *isClassMember(); // are we a member of a class?
|
||||
virtual int isExport(); // is Dsymbol exported?
|
||||
virtual int isImportedSymbol(); // is Dsymbol imported?
|
||||
virtual int isDeprecated(); // is Dsymbol deprecated?
|
||||
virtual LabelDsymbol *isLabel(); // is this a LabelDsymbol?
|
||||
virtual AggregateDeclaration *isMember(); // is this symbol a member of an AggregateDeclaration?
|
||||
virtual Type *getType(); // is this a type?
|
||||
virtual char *mangle();
|
||||
virtual int needThis(); // need a 'this' pointer?
|
||||
virtual enum PROT prot();
|
||||
virtual Dsymbol *syntaxCopy(Dsymbol *s); // copy only syntax trees
|
||||
virtual int oneMember(Dsymbol **ps);
|
||||
static int oneMembers(Array *members, Dsymbol **ps);
|
||||
virtual int hasPointers();
|
||||
virtual void addLocalClass(ClassDeclarations *) { }
|
||||
virtual void checkCtorConstInit() { }
|
||||
|
||||
virtual void addComment(unsigned char *comment);
|
||||
virtual void emitComment(Scope *sc);
|
||||
void emitDitto(Scope *sc);
|
||||
|
||||
// Backend
|
||||
|
||||
virtual Symbol *toSymbol(); // to backend symbol
|
||||
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 *toSymbolX(const char *prefix, int sclass, TYPE *t, const char *suffix); // helper
|
||||
|
||||
// Eliminate need for dynamic_cast
|
||||
virtual Package *isPackage() { return NULL; }
|
||||
virtual Module *isModule() { return NULL; }
|
||||
virtual EnumMember *isEnumMember() { return NULL; }
|
||||
virtual TemplateDeclaration *isTemplateDeclaration() { return NULL; }
|
||||
virtual TemplateInstance *isTemplateInstance() { return NULL; }
|
||||
virtual TemplateMixin *isTemplateMixin() { return NULL; }
|
||||
virtual Declaration *isDeclaration() { return NULL; }
|
||||
virtual TupleDeclaration *isTupleDeclaration() { return NULL; }
|
||||
virtual TypedefDeclaration *isTypedefDeclaration() { return NULL; }
|
||||
virtual AliasDeclaration *isAliasDeclaration() { return NULL; }
|
||||
virtual AggregateDeclaration *isAggregateDeclaration() { return NULL; }
|
||||
virtual FuncDeclaration *isFuncDeclaration() { return NULL; }
|
||||
virtual FuncAliasDeclaration *isFuncAliasDeclaration() { return NULL; }
|
||||
virtual FuncLiteralDeclaration *isFuncLiteralDeclaration() { return NULL; }
|
||||
virtual CtorDeclaration *isCtorDeclaration() { return NULL; }
|
||||
virtual DtorDeclaration *isDtorDeclaration() { return NULL; }
|
||||
virtual StaticCtorDeclaration *isStaticCtorDeclaration() { return NULL; }
|
||||
virtual StaticDtorDeclaration *isStaticDtorDeclaration() { return NULL; }
|
||||
virtual InvariantDeclaration *isInvariantDeclaration() { return NULL; }
|
||||
virtual UnitTestDeclaration *isUnitTestDeclaration() { return NULL; }
|
||||
virtual NewDeclaration *isNewDeclaration() { return NULL; }
|
||||
virtual VarDeclaration *isVarDeclaration() { return NULL; }
|
||||
virtual ClassDeclaration *isClassDeclaration() { return NULL; }
|
||||
virtual StructDeclaration *isStructDeclaration() { return NULL; }
|
||||
virtual UnionDeclaration *isUnionDeclaration() { return NULL; }
|
||||
virtual InterfaceDeclaration *isInterfaceDeclaration() { return NULL; }
|
||||
virtual ScopeDsymbol *isScopeDsymbol() { return NULL; }
|
||||
virtual WithScopeSymbol *isWithScopeSymbol() { return NULL; }
|
||||
virtual ArrayScopeSymbol *isArrayScopeSymbol() { return NULL; }
|
||||
virtual Import *isImport() { return NULL; }
|
||||
virtual EnumDeclaration *isEnumDeclaration() { return NULL; }
|
||||
#ifdef _DH
|
||||
virtual DeleteDeclaration *isDeleteDeclaration() { return NULL; }
|
||||
#endif
|
||||
virtual SymbolDeclaration *isSymbolDeclaration() { return NULL; }
|
||||
virtual AttribDeclaration *isAttribDeclaration() { return NULL; }
|
||||
virtual TypeInfoDeclaration* isTypeInfoDeclaration() { return NULL; }
|
||||
virtual ClassInfoDeclaration* isClassInfoDeclaration() { return NULL; }
|
||||
|
||||
// llvm stuff
|
||||
int llvmInternal;
|
||||
char* llvmInternal1;
|
||||
char* llvmInternal2;
|
||||
};
|
||||
|
||||
// Dsymbol that generates a scope
|
||||
|
||||
struct ScopeDsymbol : Dsymbol
|
||||
{
|
||||
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
|
||||
|
||||
ScopeDsymbol();
|
||||
ScopeDsymbol(Identifier *id);
|
||||
Dsymbol *syntaxCopy(Dsymbol *s);
|
||||
Dsymbol *search(Loc loc, Identifier *ident, int flags);
|
||||
void importScope(ScopeDsymbol *s, enum PROT protection);
|
||||
int isforwardRef();
|
||||
void defineRef(Dsymbol *s);
|
||||
static void multiplyDefined(Loc loc, Dsymbol *s1, Dsymbol *s2);
|
||||
Dsymbol *nameCollision(Dsymbol *s);
|
||||
char *kind();
|
||||
|
||||
void emitMemberComments(Scope *sc);
|
||||
|
||||
ScopeDsymbol *isScopeDsymbol() { return this; }
|
||||
};
|
||||
|
||||
// With statement scope
|
||||
|
||||
struct WithScopeSymbol : ScopeDsymbol
|
||||
{
|
||||
WithStatement *withstate;
|
||||
|
||||
WithScopeSymbol(WithStatement *withstate);
|
||||
Dsymbol *search(Loc loc, Identifier *ident, int flags);
|
||||
|
||||
WithScopeSymbol *isWithScopeSymbol() { return this; }
|
||||
};
|
||||
|
||||
// Array Index/Slice scope
|
||||
|
||||
struct ArrayScopeSymbol : ScopeDsymbol
|
||||
{
|
||||
Expression *exp; // IndexExp or SliceExp
|
||||
TypeTuple *type; // for tuple[length]
|
||||
TupleDeclaration *td; // for tuples of objects
|
||||
|
||||
ArrayScopeSymbol(Expression *e);
|
||||
ArrayScopeSymbol(TypeTuple *t);
|
||||
ArrayScopeSymbol(TupleDeclaration *td);
|
||||
Dsymbol *search(Loc loc, Identifier *ident, int flags);
|
||||
|
||||
ArrayScopeSymbol *isArrayScopeSymbol() { return this; }
|
||||
};
|
||||
|
||||
// Table of Dsymbol's
|
||||
|
||||
struct DsymbolTable : Object
|
||||
{
|
||||
StringTable *tab;
|
||||
|
||||
DsymbolTable();
|
||||
~DsymbolTable();
|
||||
|
||||
// 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);
|
||||
|
||||
// Look for Dsymbol in table. If there, return it. If not, insert s and return that.
|
||||
Dsymbol *update(Dsymbol *s);
|
||||
Dsymbol *insert(Identifier *ident, Dsymbol *s); // when ident and s are not the same
|
||||
};
|
||||
|
||||
#endif /* DMD_DSYMBOL_H */
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 1999-2007 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.
|
||||
|
||||
#ifndef DMD_DSYMBOL_H
|
||||
#define DMD_DSYMBOL_H
|
||||
|
||||
#ifdef __DMC__
|
||||
#pragma once
|
||||
#endif /* __DMC__ */
|
||||
|
||||
#include "root.h"
|
||||
#include "stringtable.h"
|
||||
|
||||
#include "mars.h"
|
||||
#include "arraytypes.h"
|
||||
|
||||
struct Identifier;
|
||||
struct Scope;
|
||||
struct DsymbolTable;
|
||||
struct Declaration;
|
||||
struct TupleDeclaration;
|
||||
struct TypedefDeclaration;
|
||||
struct AliasDeclaration;
|
||||
struct AggregateDeclaration;
|
||||
struct EnumDeclaration;
|
||||
struct ClassDeclaration;
|
||||
struct InterfaceDeclaration;
|
||||
struct StructDeclaration;
|
||||
struct UnionDeclaration;
|
||||
struct FuncDeclaration;
|
||||
struct FuncAliasDeclaration;
|
||||
struct FuncLiteralDeclaration;
|
||||
struct CtorDeclaration;
|
||||
struct DtorDeclaration;
|
||||
struct StaticCtorDeclaration;
|
||||
struct StaticDtorDeclaration;
|
||||
struct InvariantDeclaration;
|
||||
struct UnitTestDeclaration;
|
||||
struct NewDeclaration;
|
||||
struct VarDeclaration;
|
||||
struct AttribDeclaration;
|
||||
struct Symbol;
|
||||
struct Package;
|
||||
struct Module;
|
||||
struct Import;
|
||||
struct Type;
|
||||
struct TypeTuple;
|
||||
struct WithStatement;
|
||||
struct LabelDsymbol;
|
||||
struct ScopeDsymbol;
|
||||
struct TemplateDeclaration;
|
||||
struct TemplateInstance;
|
||||
struct TemplateMixin;
|
||||
struct EnumMember;
|
||||
struct ScopeDsymbol;
|
||||
struct WithScopeSymbol;
|
||||
struct ArrayScopeSymbol;
|
||||
struct SymbolDeclaration;
|
||||
struct Expression;
|
||||
struct DeleteDeclaration;
|
||||
struct HdrGenState;
|
||||
struct TypeInfoDeclaration;
|
||||
struct ClassInfoDeclaration;
|
||||
|
||||
#if IN_GCC
|
||||
union tree_node;
|
||||
typedef union tree_node TYPE;
|
||||
#else
|
||||
struct TYPE;
|
||||
#endif
|
||||
|
||||
#if IN_LLVM
|
||||
namespace llvm
|
||||
{
|
||||
class Value;
|
||||
}
|
||||
#endif
|
||||
|
||||
enum PROT
|
||||
{
|
||||
PROTundefined,
|
||||
PROTnone, // no access
|
||||
PROTprivate,
|
||||
PROTpackage,
|
||||
PROTprotected,
|
||||
PROTpublic,
|
||||
PROTexport,
|
||||
};
|
||||
|
||||
|
||||
struct Dsymbol : Object
|
||||
{
|
||||
Identifier *ident;
|
||||
Identifier *c_ident;
|
||||
Dsymbol *parent;
|
||||
Symbol *csym; // symbol for code generator
|
||||
Symbol *isym; // import version of csym
|
||||
unsigned char *comment; // documentation comment for this Dsymbol
|
||||
Loc loc; // where defined
|
||||
|
||||
Dsymbol();
|
||||
Dsymbol(Identifier *);
|
||||
char *toChars();
|
||||
char *toPrettyChars();
|
||||
char *locToChars();
|
||||
int equals(Object *o);
|
||||
int isAnonymous();
|
||||
void error(Loc loc, const char *format, ...);
|
||||
void error(const char *format, ...);
|
||||
void checkDeprecated(Loc loc, Scope *sc);
|
||||
Module *getModule();
|
||||
Dsymbol *pastMixin();
|
||||
Dsymbol *toParent();
|
||||
Dsymbol *toParent2();
|
||||
|
||||
int dyncast() { return DYNCAST_DSYMBOL; } // kludge for template.isSymbol()
|
||||
|
||||
static Array *arraySyntaxCopy(Array *a);
|
||||
|
||||
virtual char *kind();
|
||||
virtual Dsymbol *toAlias(); // resolve real symbol
|
||||
virtual int addMember(Scope *sc, ScopeDsymbol *s, int memnum);
|
||||
virtual void semantic(Scope *sc);
|
||||
virtual void semantic2(Scope *sc);
|
||||
virtual void semantic3(Scope *sc);
|
||||
virtual void inlineScan();
|
||||
virtual Dsymbol *search(Loc loc, Identifier *ident, int flags);
|
||||
Dsymbol *searchX(Loc loc, Scope *sc, Identifier *id);
|
||||
virtual int overloadInsert(Dsymbol *s);
|
||||
#ifdef _DH
|
||||
char *toHChars();
|
||||
virtual void toHBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
#endif
|
||||
virtual void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
virtual void toDocBuffer(OutBuffer *buf);
|
||||
virtual unsigned size(Loc loc);
|
||||
virtual int isforwardRef();
|
||||
virtual void defineRef(Dsymbol *s);
|
||||
virtual AggregateDeclaration *isThis(); // is a 'this' required to access the member
|
||||
virtual ClassDeclaration *isClassMember(); // are we a member of a class?
|
||||
virtual int isExport(); // is Dsymbol exported?
|
||||
virtual int isImportedSymbol(); // is Dsymbol imported?
|
||||
virtual int isDeprecated(); // is Dsymbol deprecated?
|
||||
virtual LabelDsymbol *isLabel(); // is this a LabelDsymbol?
|
||||
virtual AggregateDeclaration *isMember(); // is this symbol a member of an AggregateDeclaration?
|
||||
virtual Type *getType(); // is this a type?
|
||||
virtual char *mangle();
|
||||
virtual int needThis(); // need a 'this' pointer?
|
||||
virtual enum PROT prot();
|
||||
virtual Dsymbol *syntaxCopy(Dsymbol *s); // copy only syntax trees
|
||||
virtual int oneMember(Dsymbol **ps);
|
||||
static int oneMembers(Array *members, Dsymbol **ps);
|
||||
virtual int hasPointers();
|
||||
virtual void addLocalClass(ClassDeclarations *) { }
|
||||
virtual void checkCtorConstInit() { }
|
||||
|
||||
virtual void addComment(unsigned char *comment);
|
||||
virtual void emitComment(Scope *sc);
|
||||
void emitDitto(Scope *sc);
|
||||
|
||||
// Backend
|
||||
|
||||
virtual Symbol *toSymbol(); // to backend symbol
|
||||
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 *toSymbolX(const char *prefix, int sclass, TYPE *t, const char *suffix); // helper
|
||||
|
||||
// Eliminate need for dynamic_cast
|
||||
virtual Package *isPackage() { return NULL; }
|
||||
virtual Module *isModule() { return NULL; }
|
||||
virtual EnumMember *isEnumMember() { return NULL; }
|
||||
virtual TemplateDeclaration *isTemplateDeclaration() { return NULL; }
|
||||
virtual TemplateInstance *isTemplateInstance() { return NULL; }
|
||||
virtual TemplateMixin *isTemplateMixin() { return NULL; }
|
||||
virtual Declaration *isDeclaration() { return NULL; }
|
||||
virtual TupleDeclaration *isTupleDeclaration() { return NULL; }
|
||||
virtual TypedefDeclaration *isTypedefDeclaration() { return NULL; }
|
||||
virtual AliasDeclaration *isAliasDeclaration() { return NULL; }
|
||||
virtual AggregateDeclaration *isAggregateDeclaration() { return NULL; }
|
||||
virtual FuncDeclaration *isFuncDeclaration() { return NULL; }
|
||||
virtual FuncAliasDeclaration *isFuncAliasDeclaration() { return NULL; }
|
||||
virtual FuncLiteralDeclaration *isFuncLiteralDeclaration() { return NULL; }
|
||||
virtual CtorDeclaration *isCtorDeclaration() { return NULL; }
|
||||
virtual DtorDeclaration *isDtorDeclaration() { return NULL; }
|
||||
virtual StaticCtorDeclaration *isStaticCtorDeclaration() { return NULL; }
|
||||
virtual StaticDtorDeclaration *isStaticDtorDeclaration() { return NULL; }
|
||||
virtual InvariantDeclaration *isInvariantDeclaration() { return NULL; }
|
||||
virtual UnitTestDeclaration *isUnitTestDeclaration() { return NULL; }
|
||||
virtual NewDeclaration *isNewDeclaration() { return NULL; }
|
||||
virtual VarDeclaration *isVarDeclaration() { return NULL; }
|
||||
virtual ClassDeclaration *isClassDeclaration() { return NULL; }
|
||||
virtual StructDeclaration *isStructDeclaration() { return NULL; }
|
||||
virtual UnionDeclaration *isUnionDeclaration() { return NULL; }
|
||||
virtual InterfaceDeclaration *isInterfaceDeclaration() { return NULL; }
|
||||
virtual ScopeDsymbol *isScopeDsymbol() { return NULL; }
|
||||
virtual WithScopeSymbol *isWithScopeSymbol() { return NULL; }
|
||||
virtual ArrayScopeSymbol *isArrayScopeSymbol() { return NULL; }
|
||||
virtual Import *isImport() { return NULL; }
|
||||
virtual EnumDeclaration *isEnumDeclaration() { return NULL; }
|
||||
#ifdef _DH
|
||||
virtual DeleteDeclaration *isDeleteDeclaration() { return NULL; }
|
||||
#endif
|
||||
virtual SymbolDeclaration *isSymbolDeclaration() { return NULL; }
|
||||
virtual AttribDeclaration *isAttribDeclaration() { return NULL; }
|
||||
virtual TypeInfoDeclaration* isTypeInfoDeclaration() { return NULL; }
|
||||
virtual ClassInfoDeclaration* isClassInfoDeclaration() { return NULL; }
|
||||
|
||||
// llvm stuff
|
||||
int llvmInternal;
|
||||
char* llvmInternal1;
|
||||
char* llvmInternal2;
|
||||
};
|
||||
|
||||
// Dsymbol that generates a scope
|
||||
|
||||
struct ScopeDsymbol : Dsymbol
|
||||
{
|
||||
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
|
||||
|
||||
ScopeDsymbol();
|
||||
ScopeDsymbol(Identifier *id);
|
||||
Dsymbol *syntaxCopy(Dsymbol *s);
|
||||
Dsymbol *search(Loc loc, Identifier *ident, int flags);
|
||||
void importScope(ScopeDsymbol *s, enum PROT protection);
|
||||
int isforwardRef();
|
||||
void defineRef(Dsymbol *s);
|
||||
static void multiplyDefined(Loc loc, Dsymbol *s1, Dsymbol *s2);
|
||||
Dsymbol *nameCollision(Dsymbol *s);
|
||||
char *kind();
|
||||
|
||||
void emitMemberComments(Scope *sc);
|
||||
|
||||
ScopeDsymbol *isScopeDsymbol() { return this; }
|
||||
};
|
||||
|
||||
// With statement scope
|
||||
|
||||
struct WithScopeSymbol : ScopeDsymbol
|
||||
{
|
||||
WithStatement *withstate;
|
||||
|
||||
WithScopeSymbol(WithStatement *withstate);
|
||||
Dsymbol *search(Loc loc, Identifier *ident, int flags);
|
||||
|
||||
WithScopeSymbol *isWithScopeSymbol() { return this; }
|
||||
};
|
||||
|
||||
// Array Index/Slice scope
|
||||
|
||||
struct ArrayScopeSymbol : ScopeDsymbol
|
||||
{
|
||||
Expression *exp; // IndexExp or SliceExp
|
||||
TypeTuple *type; // for tuple[length]
|
||||
TupleDeclaration *td; // for tuples of objects
|
||||
|
||||
ArrayScopeSymbol(Expression *e);
|
||||
ArrayScopeSymbol(TypeTuple *t);
|
||||
ArrayScopeSymbol(TupleDeclaration *td);
|
||||
Dsymbol *search(Loc loc, Identifier *ident, int flags);
|
||||
|
||||
ArrayScopeSymbol *isArrayScopeSymbol() { return this; }
|
||||
};
|
||||
|
||||
// Table of Dsymbol's
|
||||
|
||||
struct DsymbolTable : Object
|
||||
{
|
||||
StringTable *tab;
|
||||
|
||||
DsymbolTable();
|
||||
~DsymbolTable();
|
||||
|
||||
// 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);
|
||||
|
||||
// Look for Dsymbol in table. If there, return it. If not, insert s and return that.
|
||||
Dsymbol *update(Dsymbol *s);
|
||||
Dsymbol *insert(Identifier *ident, Dsymbol *s); // when ident and s are not the same
|
||||
};
|
||||
|
||||
#endif /* DMD_DSYMBOL_H */
|
||||
|
||||
17352
dmd/expression.c
17352
dmd/expression.c
File diff suppressed because it is too large
Load Diff
2886
dmd/expression.h
2886
dmd/expression.h
File diff suppressed because it is too large
Load Diff
5510
dmd/func.c
5510
dmd/func.c
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 1999-2007 by Digital Mars
|
||||
// Copyright (c) 1999-2008 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright
|
||||
// http://www.digitalmars.com
|
||||
@@ -109,7 +109,7 @@ Expression *FuncDeclaration::interpret(InterState *istate, Expressions *argument
|
||||
istatex.caller = istate;
|
||||
istatex.fd = this;
|
||||
|
||||
Expressions vsave;
|
||||
Expressions vsave; // place to save previous parameter values
|
||||
size_t dim = 0;
|
||||
if (arguments)
|
||||
{
|
||||
@@ -117,9 +117,40 @@ Expression *FuncDeclaration::interpret(InterState *istate, Expressions *argument
|
||||
assert(!dim || parameters->dim == 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++)
|
||||
{ Expression *earg = (Expression *)arguments->data[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];
|
||||
vsave.data[i] = v->value;
|
||||
#if LOG
|
||||
@@ -161,17 +192,6 @@ Expression *FuncDeclaration::interpret(InterState *istate, Expressions *argument
|
||||
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;
|
||||
v->value = earg;
|
||||
}
|
||||
#if LOG
|
||||
@@ -584,6 +604,8 @@ Expression *ForStatement::interpret(InterState *istate)
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (!condition)
|
||||
goto Lhead;
|
||||
e = condition->interpret(istate);
|
||||
if (e == EXP_CANT_INTERPRET)
|
||||
break;
|
||||
@@ -592,7 +614,9 @@ Expression *ForStatement::interpret(InterState *istate)
|
||||
break;
|
||||
}
|
||||
if (e->isBool(TRUE))
|
||||
{ e = body ? body->interpret(istate) : NULL;
|
||||
{
|
||||
Lhead:
|
||||
e = body ? body->interpret(istate) : NULL;
|
||||
if (e == EXP_CANT_INTERPRET)
|
||||
break;
|
||||
if (e == EXP_BREAK_INTERPRET)
|
||||
@@ -602,9 +626,12 @@ Expression *ForStatement::interpret(InterState *istate)
|
||||
if (e && e != EXP_CONTINUE_INTERPRET)
|
||||
break;
|
||||
Lcontinue:
|
||||
e = increment->interpret(istate);
|
||||
if (e == EXP_CANT_INTERPRET)
|
||||
break;
|
||||
if (increment)
|
||||
{
|
||||
e = increment->interpret(istate);
|
||||
if (e == EXP_CANT_INTERPRET)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (e->isBool(FALSE))
|
||||
{ e = NULL;
|
||||
|
||||
6083
dmd/lexer.c
6083
dmd/lexer.c
File diff suppressed because it is too large
Load Diff
12
dmd/lexer.h
12
dmd/lexer.h
@@ -1,6 +1,6 @@
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 1999-2007 by Digital Mars
|
||||
// Copyright (c) 1999-2008 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright
|
||||
// http://www.digitalmars.com
|
||||
@@ -92,11 +92,11 @@ enum TOK
|
||||
TOKand, TOKor, TOKxor,
|
||||
TOKandass, TOKorass, TOKxorass,
|
||||
TOKassign, TOKnot, TOKtilde,
|
||||
TOKplusplus, TOKminusminus, TOKconstruct,
|
||||
TOKplusplus, TOKminusminus, TOKconstruct, TOKblit,
|
||||
TOKdot, TOKarrow, TOKcomma,
|
||||
TOKquestion, TOKandand, TOKoror,
|
||||
|
||||
// 103
|
||||
// 104
|
||||
// Numeric literals
|
||||
TOKint32v, TOKuns32v,
|
||||
TOKint64v, TOKuns64v,
|
||||
@@ -131,7 +131,7 @@ enum TOK
|
||||
TOKalign, TOKextern, TOKprivate, TOKprotected, TOKpublic, TOKexport,
|
||||
TOKstatic, /*TOKvirtual,*/ TOKfinal, TOKconst, TOKabstract, TOKvolatile,
|
||||
TOKdebug, TOKdeprecated, TOKin, TOKout, TOKinout, TOKlazy,
|
||||
TOKauto, TOKpackage,
|
||||
TOKauto, TOKpackage, TOKmanifest,
|
||||
|
||||
// Statements
|
||||
TOKif, TOKelse, TOKwhile, TOKfor, TOKdo, TOKswitch,
|
||||
@@ -152,6 +152,8 @@ enum TOK
|
||||
TOKmacro,
|
||||
#if V2
|
||||
TOKtraits,
|
||||
TOKoverloadset,
|
||||
TOKpure,
|
||||
#endif
|
||||
|
||||
TOKMAX
|
||||
@@ -261,6 +263,8 @@ struct Lexer
|
||||
|
||||
static void initKeywords();
|
||||
static Identifier *idPool(const char *s);
|
||||
static Identifier *uniqueId(const char *s);
|
||||
static Identifier *uniqueId(const char *s, int num);
|
||||
|
||||
TOK nextToken();
|
||||
void scan(Token *t);
|
||||
|
||||
1026
dmd/link.c
1026
dmd/link.c
File diff suppressed because it is too large
Load Diff
2434
dmd/mars.c
2434
dmd/mars.c
File diff suppressed because it is too large
Load Diff
615
dmd/mars.h
615
dmd/mars.h
@@ -1,307 +1,308 @@
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 1999-2007 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.
|
||||
|
||||
#ifndef DMD_MARS_H
|
||||
#define DMD_MARS_H
|
||||
|
||||
#ifdef __DMC__
|
||||
#pragma once
|
||||
#endif /* __DMC__ */
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
#include <cstdarg>
|
||||
|
||||
#ifdef __DMC__
|
||||
#ifdef DEBUG
|
||||
#undef assert
|
||||
#define assert(e) (static_cast<void>((e) || (printf("assert %s(%d) %s\n", __FILE__, __LINE__, #e), halt())))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef IN_GCC
|
||||
/* Changes for the GDC compiler by David Friedman */
|
||||
#endif
|
||||
|
||||
#define V2 0 // Version 2.0 features
|
||||
#define BREAKABI 1 // 0 if not ready to break the ABI just yet
|
||||
|
||||
struct Array;
|
||||
|
||||
// Put command line switches in here
|
||||
struct Param
|
||||
{
|
||||
char obj; // write object file
|
||||
char link; // perform link
|
||||
char trace; // insert profiling hooks
|
||||
char quiet; // suppress non-error messages
|
||||
char verbose; // verbose compile
|
||||
char symdebug; // insert debug symbolic information
|
||||
char optimize; // run optimizer
|
||||
char optimizeLevel; // optimization level
|
||||
char cpu; // target CPU
|
||||
char is64bit; // generate 64 bit code
|
||||
char isLE; // generate little endian code
|
||||
char isLinux; // generate code for linux
|
||||
char isWindows; // generate code for Windows
|
||||
char scheduler; // which scheduler to use
|
||||
char useDeprecated; // allow use of deprecated features
|
||||
char useAssert; // generate runtime code for assert()'s
|
||||
char useInvariants; // generate class invariant checks
|
||||
char useIn; // generate precondition checks
|
||||
char useOut; // generate postcondition checks
|
||||
char useArrayBounds; // generate array bounds checks
|
||||
char useSwitchError; // check for switches without a default
|
||||
char useUnitTests; // generate unittest code
|
||||
char useInline; // inline expand functions
|
||||
char release; // build release version
|
||||
char preservePaths; // !=0 means don't strip path from source file
|
||||
char warnings; // enable warnings
|
||||
char pic; // generate position-independent-code for shared libs
|
||||
char cov; // generate code coverage data
|
||||
char nofloat; // code should not pull in floating point support
|
||||
char noruntime; // code is not allowed to make implicit calls to the runtime
|
||||
char novalidate;// no bitcode validation
|
||||
char Dversion; // D version number
|
||||
|
||||
char *argv0; // program name
|
||||
Array *imppath; // array of char*'s of where to look for import modules
|
||||
Array *fileImppath; // array of char*'s of where to look for file import modules
|
||||
char *runtimeImppath; // char* of where to look for the core runtime
|
||||
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 *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 *hdrname; // write 'header' file to docname
|
||||
|
||||
unsigned debuglevel; // debug level
|
||||
Array *debugids; // debug identifiers
|
||||
|
||||
unsigned versionlevel; // version level
|
||||
Array *versionids; // version identifiers
|
||||
|
||||
bool dump_source;
|
||||
|
||||
char *defaultlibname; // default library for non-debug builds
|
||||
char *debuglibname; // default library for debug builds
|
||||
|
||||
char *xmlname; // filename for XML output
|
||||
|
||||
// Hidden debug switches
|
||||
char debuga;
|
||||
char debugb;
|
||||
char debugc;
|
||||
char debugf;
|
||||
char debugr;
|
||||
char debugw;
|
||||
char debugx;
|
||||
char debugy;
|
||||
|
||||
char run; // run resulting executable
|
||||
size_t runargs_length;
|
||||
char** runargs; // arguments for executable
|
||||
|
||||
// Linker stuff
|
||||
Array *objfiles;
|
||||
Array *linkswitches;
|
||||
Array *libfiles;
|
||||
char *deffile;
|
||||
char *resfile;
|
||||
char *exefile;
|
||||
|
||||
// LLVM stuff
|
||||
char *llvmArch;
|
||||
char forceBE;
|
||||
char *tt_arch;
|
||||
char *tt_os;
|
||||
char *data_layout;
|
||||
char disassemble;
|
||||
char llvmInline;
|
||||
char llvmAnnotate;
|
||||
char *runtimePath;
|
||||
};
|
||||
|
||||
struct Global
|
||||
{
|
||||
char *mars_ext;
|
||||
char *sym_ext;
|
||||
char *obj_ext;
|
||||
char *ll_ext;
|
||||
char *bc_ext;
|
||||
char *nativeobj_ext;
|
||||
char *doc_ext; // for Ddoc generated files
|
||||
char *ddoc_ext; // for Ddoc macro include files
|
||||
char *hdr_ext; // for D 'header' import files
|
||||
char *copyright;
|
||||
char *written;
|
||||
Array *path; // Array of char*'s which form the import lookup path
|
||||
Array *filePath; // Array of char*'s which form the file import lookup path
|
||||
int structalign;
|
||||
char *version;
|
||||
char *llvmdc_version;
|
||||
|
||||
Param params;
|
||||
unsigned errors; // number of errors reported so far
|
||||
unsigned gag; // !=0 means gag reporting of errors
|
||||
|
||||
Global();
|
||||
};
|
||||
|
||||
extern Global global;
|
||||
|
||||
#if __GNUC__
|
||||
//#define memicmp strncasecmp
|
||||
//#define stricmp strcasecmp
|
||||
#endif
|
||||
|
||||
#ifdef __DMC__
|
||||
typedef _Complex long double complex_t;
|
||||
#else
|
||||
#ifndef IN_GCC
|
||||
#include "complex_t.h"
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
//#include "complex.h"//This causes problems with include the c++ <complex> and not the C "complex.h"
|
||||
#define integer_t dmd_integer_t
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// 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;
|
||||
typedef uint64_t uinteger_t;
|
||||
|
||||
typedef int8_t d_int8;
|
||||
typedef uint8_t d_uns8;
|
||||
typedef int16_t d_int16;
|
||||
typedef uint16_t d_uns16;
|
||||
typedef int32_t d_int32;
|
||||
typedef uint32_t d_uns32;
|
||||
typedef int64_t d_int64;
|
||||
typedef uint64_t d_uns64;
|
||||
|
||||
typedef float d_float32;
|
||||
typedef double d_float64;
|
||||
typedef long double d_float80;
|
||||
|
||||
typedef d_uns8 d_char;
|
||||
typedef d_uns16 d_wchar;
|
||||
typedef d_uns32 d_dchar;
|
||||
|
||||
#ifdef IN_GCC
|
||||
#include "d-gcc-real.h"
|
||||
#else
|
||||
typedef long double real_t;
|
||||
#endif
|
||||
|
||||
// Modify OutBuffer::writewchar to write the correct size of wchar
|
||||
#if _WIN32
|
||||
#define writewchar writeword
|
||||
#else
|
||||
// This needs a configuration test...
|
||||
#define writewchar write4
|
||||
#endif
|
||||
|
||||
#ifdef IN_GCC
|
||||
#include "d-gcc-complex_t.h"
|
||||
#endif
|
||||
|
||||
struct Module;
|
||||
|
||||
//typedef unsigned Loc; // file location
|
||||
struct Loc
|
||||
{
|
||||
char *filename;
|
||||
unsigned linnum;
|
||||
|
||||
Loc()
|
||||
{
|
||||
linnum = 0;
|
||||
filename = NULL;
|
||||
}
|
||||
|
||||
Loc(int x)
|
||||
{
|
||||
linnum = x;
|
||||
filename = NULL;
|
||||
}
|
||||
|
||||
Loc(Module *mod, unsigned linnum);
|
||||
|
||||
char *toChars() const;
|
||||
};
|
||||
|
||||
#ifndef GCC_SAFE_DMD
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#define INTERFACE_OFFSET 0 // if 1, put classinfo as first entry
|
||||
// in interface vtbl[]'s
|
||||
#define INTERFACE_VIRTUAL 0 // 1 means if an interface appears
|
||||
// in the inheritance graph multiple
|
||||
// times, only one is used
|
||||
|
||||
enum LINK
|
||||
{
|
||||
LINKdefault,
|
||||
LINKd,
|
||||
LINKc,
|
||||
LINKcpp,
|
||||
LINKwindows,
|
||||
LINKpascal,
|
||||
};
|
||||
|
||||
enum DYNCAST
|
||||
{
|
||||
DYNCAST_OBJECT,
|
||||
DYNCAST_EXPRESSION,
|
||||
DYNCAST_DSYMBOL,
|
||||
DYNCAST_TYPE,
|
||||
DYNCAST_IDENTIFIER,
|
||||
DYNCAST_TUPLE,
|
||||
};
|
||||
|
||||
enum MATCH
|
||||
{
|
||||
MATCHnomatch, // no match
|
||||
MATCHconvert, // match with conversions
|
||||
#if V2
|
||||
MATCHconst, // match with conversion to const
|
||||
#endif
|
||||
MATCHexact // exact match
|
||||
};
|
||||
|
||||
void error(Loc loc, const char *format, ...);
|
||||
void verror(Loc loc, const char *format, va_list);
|
||||
void fatal();
|
||||
void err_nomem();
|
||||
int runLINK();
|
||||
void deleteExeFile();
|
||||
int runProgram();
|
||||
void inifile(char *argv0, char *inifile);
|
||||
void halt();
|
||||
|
||||
/*** Where to send error messages ***/
|
||||
#if IN_GCC
|
||||
#define stdmsg stderr
|
||||
#else
|
||||
#define stdmsg stdout
|
||||
#endif
|
||||
|
||||
#endif /* DMD_MARS_H */
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 1999-2007 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.
|
||||
|
||||
#ifndef DMD_MARS_H
|
||||
#define DMD_MARS_H
|
||||
|
||||
#ifdef __DMC__
|
||||
#pragma once
|
||||
#endif /* __DMC__ */
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
#include <cstdarg>
|
||||
|
||||
#ifdef __DMC__
|
||||
#ifdef DEBUG
|
||||
#undef assert
|
||||
#define assert(e) (static_cast<void>((e) || (printf("assert %s(%d) %s\n", __FILE__, __LINE__, #e), halt())))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef IN_GCC
|
||||
/* Changes for the GDC compiler by David Friedman */
|
||||
#endif
|
||||
|
||||
#define V2 0 // Version 2.0 features
|
||||
#define BREAKABI 1 // 0 if not ready to break the ABI just yet
|
||||
|
||||
struct Array;
|
||||
|
||||
// Put command line switches in here
|
||||
struct Param
|
||||
{
|
||||
char obj; // write object file
|
||||
char link; // perform link
|
||||
char trace; // insert profiling hooks
|
||||
char quiet; // suppress non-error messages
|
||||
char verbose; // verbose compile
|
||||
char symdebug; // insert debug symbolic information
|
||||
char optimize; // run optimizer
|
||||
char optimizeLevel; // optimization level
|
||||
char cpu; // target CPU
|
||||
char is64bit; // generate 64 bit code
|
||||
char isLE; // generate little endian code
|
||||
char isLinux; // generate code for linux
|
||||
char isWindows; // generate code for Windows
|
||||
char scheduler; // which scheduler to use
|
||||
char useDeprecated; // allow use of deprecated features
|
||||
char useAssert; // generate runtime code for assert()'s
|
||||
char useInvariants; // generate class invariant checks
|
||||
char useIn; // generate precondition checks
|
||||
char useOut; // generate postcondition checks
|
||||
char useArrayBounds; // generate array bounds checks
|
||||
char useSwitchError; // check for switches without a default
|
||||
char useUnitTests; // generate unittest code
|
||||
char useInline; // inline expand functions
|
||||
char release; // build release version
|
||||
char preservePaths; // !=0 means don't strip path from source file
|
||||
char warnings; // enable warnings
|
||||
char pic; // generate position-independent-code for shared libs
|
||||
char cov; // generate code coverage data
|
||||
char nofloat; // code should not pull in floating point support
|
||||
char noruntime; // code is not allowed to make implicit calls to the runtime
|
||||
char novalidate;// no bitcode validation
|
||||
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
|
||||
Array *fileImppath; // array of char*'s of where to look for file import modules
|
||||
char *runtimeImppath; // char* of where to look for the core runtime
|
||||
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 *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 *hdrname; // write 'header' file to docname
|
||||
|
||||
unsigned debuglevel; // debug level
|
||||
Array *debugids; // debug identifiers
|
||||
|
||||
unsigned versionlevel; // version level
|
||||
Array *versionids; // version identifiers
|
||||
|
||||
bool dump_source;
|
||||
|
||||
char *defaultlibname; // default library for non-debug builds
|
||||
char *debuglibname; // default library for debug builds
|
||||
|
||||
char *xmlname; // filename for XML output
|
||||
|
||||
// Hidden debug switches
|
||||
char debuga;
|
||||
char debugb;
|
||||
char debugc;
|
||||
char debugf;
|
||||
char debugr;
|
||||
char debugw;
|
||||
char debugx;
|
||||
char debugy;
|
||||
|
||||
char run; // run resulting executable
|
||||
size_t runargs_length;
|
||||
char** runargs; // arguments for executable
|
||||
|
||||
// Linker stuff
|
||||
Array *objfiles;
|
||||
Array *linkswitches;
|
||||
Array *libfiles;
|
||||
char *deffile;
|
||||
char *resfile;
|
||||
char *exefile;
|
||||
|
||||
// LLVM stuff
|
||||
char *llvmArch;
|
||||
char forceBE;
|
||||
char *tt_arch;
|
||||
char *tt_os;
|
||||
char *data_layout;
|
||||
char disassemble;
|
||||
char llvmInline;
|
||||
char llvmAnnotate;
|
||||
char *runtimePath;
|
||||
};
|
||||
|
||||
struct Global
|
||||
{
|
||||
char *mars_ext;
|
||||
char *sym_ext;
|
||||
char *obj_ext;
|
||||
char *ll_ext;
|
||||
char *bc_ext;
|
||||
char *nativeobj_ext;
|
||||
char *doc_ext; // for Ddoc generated files
|
||||
char *ddoc_ext; // for Ddoc macro include files
|
||||
char *hdr_ext; // for D 'header' import files
|
||||
char *copyright;
|
||||
char *written;
|
||||
Array *path; // Array of char*'s which form the import lookup path
|
||||
Array *filePath; // Array of char*'s which form the file import lookup path
|
||||
int structalign;
|
||||
char *version;
|
||||
char *llvmdc_version;
|
||||
|
||||
Param params;
|
||||
unsigned errors; // number of errors reported so far
|
||||
unsigned gag; // !=0 means gag reporting of errors
|
||||
|
||||
Global();
|
||||
};
|
||||
|
||||
extern Global global;
|
||||
|
||||
#if __GNUC__
|
||||
//#define memicmp strncasecmp
|
||||
//#define stricmp strcasecmp
|
||||
#endif
|
||||
|
||||
#ifdef __DMC__
|
||||
typedef _Complex long double complex_t;
|
||||
#else
|
||||
#ifndef IN_GCC
|
||||
#include "complex_t.h"
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
//#include "complex.h"//This causes problems with include the c++ <complex> and not the C "complex.h"
|
||||
#define integer_t dmd_integer_t
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// 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;
|
||||
typedef uint64_t uinteger_t;
|
||||
|
||||
typedef int8_t d_int8;
|
||||
typedef uint8_t d_uns8;
|
||||
typedef int16_t d_int16;
|
||||
typedef uint16_t d_uns16;
|
||||
typedef int32_t d_int32;
|
||||
typedef uint32_t d_uns32;
|
||||
typedef int64_t d_int64;
|
||||
typedef uint64_t d_uns64;
|
||||
|
||||
typedef float d_float32;
|
||||
typedef double d_float64;
|
||||
typedef long double d_float80;
|
||||
|
||||
typedef d_uns8 d_char;
|
||||
typedef d_uns16 d_wchar;
|
||||
typedef d_uns32 d_dchar;
|
||||
|
||||
#ifdef IN_GCC
|
||||
#include "d-gcc-real.h"
|
||||
#else
|
||||
typedef long double real_t;
|
||||
#endif
|
||||
|
||||
// Modify OutBuffer::writewchar to write the correct size of wchar
|
||||
#if _WIN32
|
||||
#define writewchar writeword
|
||||
#else
|
||||
// This needs a configuration test...
|
||||
#define writewchar write4
|
||||
#endif
|
||||
|
||||
#ifdef IN_GCC
|
||||
#include "d-gcc-complex_t.h"
|
||||
#endif
|
||||
|
||||
struct Module;
|
||||
|
||||
//typedef unsigned Loc; // file location
|
||||
struct Loc
|
||||
{
|
||||
char *filename;
|
||||
unsigned linnum;
|
||||
|
||||
Loc()
|
||||
{
|
||||
linnum = 0;
|
||||
filename = NULL;
|
||||
}
|
||||
|
||||
Loc(int x)
|
||||
{
|
||||
linnum = x;
|
||||
filename = NULL;
|
||||
}
|
||||
|
||||
Loc(Module *mod, unsigned linnum);
|
||||
|
||||
char *toChars() const;
|
||||
};
|
||||
|
||||
#ifndef GCC_SAFE_DMD
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#define INTERFACE_OFFSET 0 // if 1, put classinfo as first entry
|
||||
// in interface vtbl[]'s
|
||||
#define INTERFACE_VIRTUAL 0 // 1 means if an interface appears
|
||||
// in the inheritance graph multiple
|
||||
// times, only one is used
|
||||
|
||||
enum LINK
|
||||
{
|
||||
LINKdefault,
|
||||
LINKd,
|
||||
LINKc,
|
||||
LINKcpp,
|
||||
LINKwindows,
|
||||
LINKpascal,
|
||||
};
|
||||
|
||||
enum DYNCAST
|
||||
{
|
||||
DYNCAST_OBJECT,
|
||||
DYNCAST_EXPRESSION,
|
||||
DYNCAST_DSYMBOL,
|
||||
DYNCAST_TYPE,
|
||||
DYNCAST_IDENTIFIER,
|
||||
DYNCAST_TUPLE,
|
||||
};
|
||||
|
||||
enum MATCH
|
||||
{
|
||||
MATCHnomatch, // no match
|
||||
MATCHconvert, // match with conversions
|
||||
#if V2
|
||||
MATCHconst, // match with conversion to const
|
||||
#endif
|
||||
MATCHexact // exact match
|
||||
};
|
||||
|
||||
void error(Loc loc, const char *format, ...);
|
||||
void verror(Loc loc, const char *format, va_list);
|
||||
void fatal();
|
||||
void err_nomem();
|
||||
int runLINK();
|
||||
void deleteExeFile();
|
||||
int runProgram();
|
||||
void inifile(char *argv0, char *inifile);
|
||||
void halt();
|
||||
|
||||
/*** Where to send error messages ***/
|
||||
#if IN_GCC
|
||||
#define stdmsg stderr
|
||||
#else
|
||||
#define stdmsg stdout
|
||||
#endif
|
||||
|
||||
#endif /* DMD_MARS_H */
|
||||
|
||||
10627
dmd/mtype.c
10627
dmd/mtype.c
File diff suppressed because it is too large
Load Diff
1379
dmd/mtype.h
1379
dmd/mtype.h
File diff suppressed because it is too large
Load Diff
@@ -637,6 +637,14 @@ Condition *Parser::parseVersionCondition()
|
||||
id = token.ident;
|
||||
else if (token.value == TOKint32v)
|
||||
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
|
||||
error("identifier or integer expected, not %s", token.toChars());
|
||||
nextToken();
|
||||
|
||||
720
dmd/scope.c
720
dmd/scope.c
@@ -1,359 +1,361 @@
|
||||
|
||||
// Copyright (c) 1999-2005 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 "mars.h"
|
||||
#include "init.h"
|
||||
#include "identifier.h"
|
||||
#include "attrib.h"
|
||||
#include "dsymbol.h"
|
||||
#include "scope.h"
|
||||
#include "declaration.h"
|
||||
#include "aggregate.h"
|
||||
#include "module.h"
|
||||
#include "id.h"
|
||||
|
||||
Scope *Scope::freelist = NULL;
|
||||
|
||||
void *Scope::operator new(size_t size)
|
||||
{
|
||||
if (freelist)
|
||||
{
|
||||
Scope *s = freelist;
|
||||
freelist = s->enclosing;
|
||||
//printf("freelist %p\n", s);
|
||||
assert(s->flags & SCOPEfree);
|
||||
s->flags &= ~SCOPEfree;
|
||||
return s;
|
||||
}
|
||||
|
||||
void *p = ::operator new(size);
|
||||
//printf("new %p\n", p);
|
||||
return p;
|
||||
}
|
||||
|
||||
Scope::Scope()
|
||||
{ // Create root scope
|
||||
|
||||
//printf("Scope::Scope() %p\n", this);
|
||||
this->module = NULL;
|
||||
this->scopesym = NULL;
|
||||
this->sd = NULL;
|
||||
this->enclosing = NULL;
|
||||
this->parent = NULL;
|
||||
this->sw = NULL;
|
||||
this->tf = NULL;
|
||||
this->tfOfTry = NULL;
|
||||
this->sbreak = NULL;
|
||||
this->scontinue = NULL;
|
||||
this->fes = NULL;
|
||||
this->structalign = global.structalign;
|
||||
this->func = NULL;
|
||||
this->slabel = NULL;
|
||||
this->linkage = LINKd;
|
||||
this->protection = PROTpublic;
|
||||
this->explicitProtection = 0;
|
||||
this->stc = 0;
|
||||
this->offset = 0;
|
||||
this->inunion = 0;
|
||||
this->incontract = 0;
|
||||
this->nofree = 0;
|
||||
this->noctor = 0;
|
||||
this->intypeof = 0;
|
||||
this->parameterSpecialization = 0;
|
||||
this->callSuper = 0;
|
||||
this->flags = 0;
|
||||
this->anonAgg = NULL;
|
||||
this->lastdc = NULL;
|
||||
this->lastoffset = 0;
|
||||
this->docbuf = NULL;
|
||||
}
|
||||
|
||||
Scope::Scope(Scope *enclosing)
|
||||
{
|
||||
//printf("Scope::Scope(enclosing = %p) %p\n", enclosing, this);
|
||||
assert(!(enclosing->flags & SCOPEfree));
|
||||
this->module = enclosing->module;
|
||||
this->func = enclosing->func;
|
||||
this->parent = enclosing->parent;
|
||||
this->scopesym = NULL;
|
||||
this->sd = NULL;
|
||||
this->sw = enclosing->sw;
|
||||
this->tf = enclosing->tf;
|
||||
this->tfOfTry = enclosing->tfOfTry;
|
||||
this->sbreak = enclosing->sbreak;
|
||||
this->scontinue = enclosing->scontinue;
|
||||
this->fes = enclosing->fes;
|
||||
this->structalign = enclosing->structalign;
|
||||
this->enclosing = enclosing;
|
||||
#ifdef DEBUG
|
||||
if (enclosing->enclosing)
|
||||
assert(!(enclosing->enclosing->flags & SCOPEfree));
|
||||
if (this == enclosing->enclosing)
|
||||
{
|
||||
printf("this = %p, enclosing = %p, enclosing->enclosing = %p\n", this, enclosing, enclosing->enclosing);
|
||||
}
|
||||
assert(this != enclosing->enclosing);
|
||||
#endif
|
||||
this->slabel = NULL;
|
||||
this->linkage = enclosing->linkage;
|
||||
this->protection = enclosing->protection;
|
||||
this->explicitProtection = enclosing->explicitProtection;
|
||||
this->stc = enclosing->stc;
|
||||
this->offset = 0;
|
||||
this->inunion = enclosing->inunion;
|
||||
this->incontract = enclosing->incontract;
|
||||
this->nofree = 0;
|
||||
this->noctor = enclosing->noctor;
|
||||
this->intypeof = enclosing->intypeof;
|
||||
this->parameterSpecialization = enclosing->parameterSpecialization;
|
||||
this->callSuper = enclosing->callSuper;
|
||||
this->flags = 0;
|
||||
this->anonAgg = NULL;
|
||||
this->lastdc = NULL;
|
||||
this->lastoffset = 0;
|
||||
this->docbuf = enclosing->docbuf;
|
||||
assert(this != enclosing);
|
||||
}
|
||||
|
||||
Scope *Scope::createGlobal(Module *module)
|
||||
{
|
||||
Scope *sc;
|
||||
|
||||
sc = new Scope();
|
||||
sc->module = module;
|
||||
sc->scopesym = new ScopeDsymbol();
|
||||
sc->scopesym->symtab = new DsymbolTable();
|
||||
|
||||
// Add top level package as member of this global scope
|
||||
Dsymbol *m = module;
|
||||
while (m->parent)
|
||||
m = m->parent;
|
||||
m->addMember(NULL, sc->scopesym, 1);
|
||||
m->parent = NULL; // got changed by addMember()
|
||||
|
||||
// Create the module scope underneath the global scope
|
||||
sc = sc->push(module);
|
||||
sc->parent = module;
|
||||
return sc;
|
||||
}
|
||||
|
||||
Scope *Scope::push()
|
||||
{
|
||||
//printf("Scope::push()\n");
|
||||
Scope *s = new Scope(this);
|
||||
assert(this != s);
|
||||
return s;
|
||||
}
|
||||
|
||||
Scope *Scope::push(ScopeDsymbol *ss)
|
||||
{
|
||||
//printf("Scope::push(%s)\n", ss->toChars());
|
||||
Scope *s = push();
|
||||
s->scopesym = ss;
|
||||
return s;
|
||||
}
|
||||
|
||||
Scope *Scope::pop()
|
||||
{
|
||||
//printf("Scope::pop() %p nofree = %d\n", this, nofree);
|
||||
Scope *enc = enclosing;
|
||||
|
||||
if (enclosing)
|
||||
enclosing->callSuper |= callSuper;
|
||||
|
||||
if (!nofree)
|
||||
{ enclosing = freelist;
|
||||
freelist = this;
|
||||
flags |= SCOPEfree;
|
||||
}
|
||||
|
||||
return enc;
|
||||
}
|
||||
|
||||
void Scope::mergeCallSuper(Loc loc, unsigned cs)
|
||||
{
|
||||
// This does a primitive flow analysis to support the restrictions
|
||||
// regarding when and how constructors can appear.
|
||||
// It merges the results of two paths.
|
||||
// The two paths are callSuper and cs; the result is merged into callSuper.
|
||||
|
||||
if (cs != callSuper)
|
||||
{ int a;
|
||||
int b;
|
||||
|
||||
callSuper |= cs & (CSXany_ctor | CSXlabel);
|
||||
if (cs & CSXreturn)
|
||||
{
|
||||
}
|
||||
else if (callSuper & CSXreturn)
|
||||
{
|
||||
callSuper = cs | (callSuper & (CSXany_ctor | CSXlabel));
|
||||
}
|
||||
else
|
||||
{
|
||||
a = (cs & (CSXthis_ctor | CSXsuper_ctor)) != 0;
|
||||
b = (callSuper & (CSXthis_ctor | CSXsuper_ctor)) != 0;
|
||||
if (a != b)
|
||||
error(loc, "one path skips constructor");
|
||||
callSuper |= cs;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Dsymbol *Scope::search(Loc loc, Identifier *ident, Dsymbol **pscopesym)
|
||||
{ Dsymbol *s;
|
||||
Scope *sc;
|
||||
|
||||
//printf("Scope::search(%p, '%s')\n", this, ident->toChars());
|
||||
if (ident == Id::empty)
|
||||
{
|
||||
// Look for module scope
|
||||
for (sc = this; sc; sc = sc->enclosing)
|
||||
{
|
||||
assert(sc != sc->enclosing);
|
||||
if (sc->scopesym)
|
||||
{
|
||||
s = sc->scopesym->isModule();
|
||||
if (s)
|
||||
{
|
||||
//printf("\tfound %s.%s\n", s->parent ? s->parent->toChars() : "", s->toChars());
|
||||
if (pscopesym)
|
||||
*pscopesym = sc->scopesym;
|
||||
return s;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (sc = this; sc; sc = sc->enclosing)
|
||||
{
|
||||
assert(sc != sc->enclosing);
|
||||
if (sc->scopesym)
|
||||
{
|
||||
//printf("\tlooking in scopesym '%s', kind = '%s'\n", sc->scopesym->toChars(), sc->scopesym->kind());
|
||||
s = sc->scopesym->search(loc, ident, 0);
|
||||
if (s)
|
||||
{
|
||||
if ((global.params.warnings ||
|
||||
global.params.Dversion > 1) &&
|
||||
ident == Id::length &&
|
||||
sc->scopesym->isArrayScopeSymbol() &&
|
||||
sc->enclosing &&
|
||||
sc->enclosing->search(loc, ident, NULL))
|
||||
{
|
||||
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;
|
||||
return s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Dsymbol *Scope::insert(Dsymbol *s)
|
||||
{ Scope *sc;
|
||||
|
||||
for (sc = this; sc; sc = sc->enclosing)
|
||||
{
|
||||
//printf("\tsc = %p\n", sc);
|
||||
if (sc->scopesym)
|
||||
{
|
||||
//printf("\t\tsc->scopesym = %p\n", sc->scopesym);
|
||||
if (!sc->scopesym->symtab)
|
||||
sc->scopesym->symtab = new DsymbolTable();
|
||||
return sc->scopesym->symtab->insert(s);
|
||||
}
|
||||
}
|
||||
assert(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/********************************************
|
||||
* Search enclosing scopes for ClassDeclaration.
|
||||
*/
|
||||
|
||||
ClassDeclaration *Scope::getClassScope()
|
||||
{ Scope *sc;
|
||||
|
||||
for (sc = this; sc; sc = sc->enclosing)
|
||||
{
|
||||
ClassDeclaration *cd;
|
||||
|
||||
if (sc->scopesym)
|
||||
{
|
||||
cd = sc->scopesym->isClassDeclaration();
|
||||
if (cd)
|
||||
return cd;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/********************************************
|
||||
* Search enclosing scopes for ClassDeclaration.
|
||||
*/
|
||||
|
||||
AggregateDeclaration *Scope::getStructClassScope()
|
||||
{ Scope *sc;
|
||||
|
||||
for (sc = this; sc; sc = sc->enclosing)
|
||||
{
|
||||
AggregateDeclaration *ad;
|
||||
|
||||
if (sc->scopesym)
|
||||
{
|
||||
ad = sc->scopesym->isClassDeclaration();
|
||||
if (ad)
|
||||
return ad;
|
||||
else
|
||||
{ ad = sc->scopesym->isStructDeclaration();
|
||||
if (ad)
|
||||
return ad;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*******************************************
|
||||
* 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;
|
||||
|
||||
//printf("Scope::setNoFree(this = %p)\n", this);
|
||||
for (sc = this; sc; sc = sc->enclosing)
|
||||
{
|
||||
//printf("\tsc = %p\n", sc);
|
||||
sc->nofree = 1;
|
||||
|
||||
assert(!(flags & SCOPEfree));
|
||||
//assert(sc != sc->enclosing);
|
||||
//assert(!sc->enclosing || sc != sc->enclosing->enclosing);
|
||||
//if (++i == 10)
|
||||
//assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
// Copyright (c) 1999-2005 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 "mars.h"
|
||||
#include "init.h"
|
||||
#include "identifier.h"
|
||||
#include "attrib.h"
|
||||
#include "dsymbol.h"
|
||||
#include "scope.h"
|
||||
#include "declaration.h"
|
||||
#include "aggregate.h"
|
||||
#include "module.h"
|
||||
#include "id.h"
|
||||
|
||||
Scope *Scope::freelist = NULL;
|
||||
|
||||
void *Scope::operator new(size_t size)
|
||||
{
|
||||
if (freelist)
|
||||
{
|
||||
Scope *s = freelist;
|
||||
freelist = s->enclosing;
|
||||
//printf("freelist %p\n", s);
|
||||
assert(s->flags & SCOPEfree);
|
||||
s->flags &= ~SCOPEfree;
|
||||
return s;
|
||||
}
|
||||
|
||||
void *p = ::operator new(size);
|
||||
//printf("new %p\n", p);
|
||||
return p;
|
||||
}
|
||||
|
||||
Scope::Scope()
|
||||
{ // Create root scope
|
||||
|
||||
//printf("Scope::Scope() %p\n", this);
|
||||
this->module = NULL;
|
||||
this->scopesym = NULL;
|
||||
this->sd = NULL;
|
||||
this->enclosing = NULL;
|
||||
this->parent = NULL;
|
||||
this->sw = NULL;
|
||||
this->tf = NULL;
|
||||
this->tfOfTry = NULL;
|
||||
this->sbreak = NULL;
|
||||
this->scontinue = NULL;
|
||||
this->fes = NULL;
|
||||
this->structalign = global.structalign;
|
||||
this->func = NULL;
|
||||
this->slabel = NULL;
|
||||
this->linkage = LINKd;
|
||||
this->protection = PROTpublic;
|
||||
this->explicitProtection = 0;
|
||||
this->stc = 0;
|
||||
this->offset = 0;
|
||||
this->inunion = 0;
|
||||
this->incontract = 0;
|
||||
this->nofree = 0;
|
||||
this->noctor = 0;
|
||||
this->noaccesscheck = 0;
|
||||
this->intypeof = 0;
|
||||
this->parameterSpecialization = 0;
|
||||
this->callSuper = 0;
|
||||
this->flags = 0;
|
||||
this->anonAgg = NULL;
|
||||
this->lastdc = NULL;
|
||||
this->lastoffset = 0;
|
||||
this->docbuf = NULL;
|
||||
}
|
||||
|
||||
Scope::Scope(Scope *enclosing)
|
||||
{
|
||||
//printf("Scope::Scope(enclosing = %p) %p\n", enclosing, this);
|
||||
assert(!(enclosing->flags & SCOPEfree));
|
||||
this->module = enclosing->module;
|
||||
this->func = enclosing->func;
|
||||
this->parent = enclosing->parent;
|
||||
this->scopesym = NULL;
|
||||
this->sd = NULL;
|
||||
this->sw = enclosing->sw;
|
||||
this->tf = enclosing->tf;
|
||||
this->tfOfTry = enclosing->tfOfTry;
|
||||
this->sbreak = enclosing->sbreak;
|
||||
this->scontinue = enclosing->scontinue;
|
||||
this->fes = enclosing->fes;
|
||||
this->structalign = enclosing->structalign;
|
||||
this->enclosing = enclosing;
|
||||
#ifdef DEBUG
|
||||
if (enclosing->enclosing)
|
||||
assert(!(enclosing->enclosing->flags & SCOPEfree));
|
||||
if (this == enclosing->enclosing)
|
||||
{
|
||||
printf("this = %p, enclosing = %p, enclosing->enclosing = %p\n", this, enclosing, enclosing->enclosing);
|
||||
}
|
||||
assert(this != enclosing->enclosing);
|
||||
#endif
|
||||
this->slabel = NULL;
|
||||
this->linkage = enclosing->linkage;
|
||||
this->protection = enclosing->protection;
|
||||
this->explicitProtection = enclosing->explicitProtection;
|
||||
this->stc = enclosing->stc;
|
||||
this->offset = 0;
|
||||
this->inunion = enclosing->inunion;
|
||||
this->incontract = enclosing->incontract;
|
||||
this->nofree = 0;
|
||||
this->noctor = enclosing->noctor;
|
||||
this->noaccesscheck = enclosing->noaccesscheck;
|
||||
this->intypeof = enclosing->intypeof;
|
||||
this->parameterSpecialization = enclosing->parameterSpecialization;
|
||||
this->callSuper = enclosing->callSuper;
|
||||
this->flags = 0;
|
||||
this->anonAgg = NULL;
|
||||
this->lastdc = NULL;
|
||||
this->lastoffset = 0;
|
||||
this->docbuf = enclosing->docbuf;
|
||||
assert(this != enclosing);
|
||||
}
|
||||
|
||||
Scope *Scope::createGlobal(Module *module)
|
||||
{
|
||||
Scope *sc;
|
||||
|
||||
sc = new Scope();
|
||||
sc->module = module;
|
||||
sc->scopesym = new ScopeDsymbol();
|
||||
sc->scopesym->symtab = new DsymbolTable();
|
||||
|
||||
// Add top level package as member of this global scope
|
||||
Dsymbol *m = module;
|
||||
while (m->parent)
|
||||
m = m->parent;
|
||||
m->addMember(NULL, sc->scopesym, 1);
|
||||
m->parent = NULL; // got changed by addMember()
|
||||
|
||||
// Create the module scope underneath the global scope
|
||||
sc = sc->push(module);
|
||||
sc->parent = module;
|
||||
return sc;
|
||||
}
|
||||
|
||||
Scope *Scope::push()
|
||||
{
|
||||
//printf("Scope::push()\n");
|
||||
Scope *s = new Scope(this);
|
||||
assert(this != s);
|
||||
return s;
|
||||
}
|
||||
|
||||
Scope *Scope::push(ScopeDsymbol *ss)
|
||||
{
|
||||
//printf("Scope::push(%s)\n", ss->toChars());
|
||||
Scope *s = push();
|
||||
s->scopesym = ss;
|
||||
return s;
|
||||
}
|
||||
|
||||
Scope *Scope::pop()
|
||||
{
|
||||
//printf("Scope::pop() %p nofree = %d\n", this, nofree);
|
||||
Scope *enc = enclosing;
|
||||
|
||||
if (enclosing)
|
||||
enclosing->callSuper |= callSuper;
|
||||
|
||||
if (!nofree)
|
||||
{ enclosing = freelist;
|
||||
freelist = this;
|
||||
flags |= SCOPEfree;
|
||||
}
|
||||
|
||||
return enc;
|
||||
}
|
||||
|
||||
void Scope::mergeCallSuper(Loc loc, unsigned cs)
|
||||
{
|
||||
// This does a primitive flow analysis to support the restrictions
|
||||
// regarding when and how constructors can appear.
|
||||
// It merges the results of two paths.
|
||||
// The two paths are callSuper and cs; the result is merged into callSuper.
|
||||
|
||||
if (cs != callSuper)
|
||||
{ int a;
|
||||
int b;
|
||||
|
||||
callSuper |= cs & (CSXany_ctor | CSXlabel);
|
||||
if (cs & CSXreturn)
|
||||
{
|
||||
}
|
||||
else if (callSuper & CSXreturn)
|
||||
{
|
||||
callSuper = cs | (callSuper & (CSXany_ctor | CSXlabel));
|
||||
}
|
||||
else
|
||||
{
|
||||
a = (cs & (CSXthis_ctor | CSXsuper_ctor)) != 0;
|
||||
b = (callSuper & (CSXthis_ctor | CSXsuper_ctor)) != 0;
|
||||
if (a != b)
|
||||
error(loc, "one path skips constructor");
|
||||
callSuper |= cs;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Dsymbol *Scope::search(Loc loc, Identifier *ident, Dsymbol **pscopesym)
|
||||
{ Dsymbol *s;
|
||||
Scope *sc;
|
||||
|
||||
//printf("Scope::search(%p, '%s')\n", this, ident->toChars());
|
||||
if (ident == Id::empty)
|
||||
{
|
||||
// Look for module scope
|
||||
for (sc = this; sc; sc = sc->enclosing)
|
||||
{
|
||||
assert(sc != sc->enclosing);
|
||||
if (sc->scopesym)
|
||||
{
|
||||
s = sc->scopesym->isModule();
|
||||
if (s)
|
||||
{
|
||||
//printf("\tfound %s.%s\n", s->parent ? s->parent->toChars() : "", s->toChars());
|
||||
if (pscopesym)
|
||||
*pscopesym = sc->scopesym;
|
||||
return s;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (sc = this; sc; sc = sc->enclosing)
|
||||
{
|
||||
assert(sc != sc->enclosing);
|
||||
if (sc->scopesym)
|
||||
{
|
||||
//printf("\tlooking in scopesym '%s', kind = '%s'\n", sc->scopesym->toChars(), sc->scopesym->kind());
|
||||
s = sc->scopesym->search(loc, ident, 0);
|
||||
if (s)
|
||||
{
|
||||
if ((global.params.warnings ||
|
||||
global.params.Dversion > 1) &&
|
||||
ident == Id::length &&
|
||||
sc->scopesym->isArrayScopeSymbol() &&
|
||||
sc->enclosing &&
|
||||
sc->enclosing->search(loc, ident, NULL))
|
||||
{
|
||||
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;
|
||||
return s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Dsymbol *Scope::insert(Dsymbol *s)
|
||||
{ Scope *sc;
|
||||
|
||||
for (sc = this; sc; sc = sc->enclosing)
|
||||
{
|
||||
//printf("\tsc = %p\n", sc);
|
||||
if (sc->scopesym)
|
||||
{
|
||||
//printf("\t\tsc->scopesym = %p\n", sc->scopesym);
|
||||
if (!sc->scopesym->symtab)
|
||||
sc->scopesym->symtab = new DsymbolTable();
|
||||
return sc->scopesym->symtab->insert(s);
|
||||
}
|
||||
}
|
||||
assert(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/********************************************
|
||||
* Search enclosing scopes for ClassDeclaration.
|
||||
*/
|
||||
|
||||
ClassDeclaration *Scope::getClassScope()
|
||||
{ Scope *sc;
|
||||
|
||||
for (sc = this; sc; sc = sc->enclosing)
|
||||
{
|
||||
ClassDeclaration *cd;
|
||||
|
||||
if (sc->scopesym)
|
||||
{
|
||||
cd = sc->scopesym->isClassDeclaration();
|
||||
if (cd)
|
||||
return cd;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/********************************************
|
||||
* Search enclosing scopes for ClassDeclaration.
|
||||
*/
|
||||
|
||||
AggregateDeclaration *Scope::getStructClassScope()
|
||||
{ Scope *sc;
|
||||
|
||||
for (sc = this; sc; sc = sc->enclosing)
|
||||
{
|
||||
AggregateDeclaration *ad;
|
||||
|
||||
if (sc->scopesym)
|
||||
{
|
||||
ad = sc->scopesym->isClassDeclaration();
|
||||
if (ad)
|
||||
return ad;
|
||||
else
|
||||
{ ad = sc->scopesym->isStructDeclaration();
|
||||
if (ad)
|
||||
return ad;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*******************************************
|
||||
* 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;
|
||||
|
||||
//printf("Scope::setNoFree(this = %p)\n", this);
|
||||
for (sc = this; sc; sc = sc->enclosing)
|
||||
{
|
||||
//printf("\tsc = %p\n", sc);
|
||||
sc->nofree = 1;
|
||||
|
||||
assert(!(flags & SCOPEfree));
|
||||
//assert(sc != sc->enclosing);
|
||||
//assert(!sc->enclosing || sc != sc->enclosing->enclosing);
|
||||
//if (++i == 10)
|
||||
//assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
221
dmd/scope.h
221
dmd/scope.h
@@ -1,110 +1,111 @@
|
||||
|
||||
// Copyright (c) 1999-2005 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.
|
||||
|
||||
#ifndef DMD_SCOPE_H
|
||||
#define DMD_SCOPE_H
|
||||
|
||||
#ifdef __DMC__
|
||||
#pragma once
|
||||
#endif /* __DMC__ */
|
||||
|
||||
struct Dsymbol;
|
||||
struct ScopeDsymbol;
|
||||
struct Array;
|
||||
struct Identifier;
|
||||
struct Module;
|
||||
struct Statement;
|
||||
struct SwitchStatement;
|
||||
struct TryFinallyStatement;
|
||||
struct LabelStatement;
|
||||
struct ForeachStatement;
|
||||
struct ClassDeclaration;
|
||||
struct AggregateDeclaration;
|
||||
struct AnonymousAggregateDeclaration;
|
||||
struct FuncDeclaration;
|
||||
struct DocComment;
|
||||
enum LINK;
|
||||
enum PROT;
|
||||
|
||||
struct Scope
|
||||
{
|
||||
Scope *enclosing; // enclosing Scope
|
||||
|
||||
Module *module; // Root module
|
||||
ScopeDsymbol *scopesym; // current symbol
|
||||
ScopeDsymbol *sd; // if in static if, and declaring new symbols,
|
||||
// sd gets the addMember()
|
||||
FuncDeclaration *func; // function we are in
|
||||
Dsymbol *parent; // parent to use
|
||||
LabelStatement *slabel; // enclosing labelled statement
|
||||
SwitchStatement *sw; // enclosing switch statement
|
||||
TryFinallyStatement *tf; // enclosing try finally statement; set inside its finally block
|
||||
TryFinallyStatement *tfOfTry; // enclosing try finally statement; set inside its try block
|
||||
Statement *sbreak; // enclosing statement that supports "break"
|
||||
Statement *scontinue; // enclosing statement that supports "continue"
|
||||
ForeachStatement *fes; // if nested function for ForeachStatement, this is it
|
||||
unsigned offset; // next offset to use in aggregate
|
||||
int inunion; // we're processing members of a union
|
||||
int incontract; // we're inside contract code
|
||||
int nofree; // set if shouldn't free it
|
||||
int noctor; // set if constructor calls aren't allowed
|
||||
int intypeof; // in typeof(exp)
|
||||
int parameterSpecialization; // if in template parameter specialization
|
||||
|
||||
unsigned callSuper; // primitive flow analysis for constructors
|
||||
#define CSXthis_ctor 1 // called this()
|
||||
#define CSXsuper_ctor 2 // called super()
|
||||
#define CSXthis 4 // referenced this
|
||||
#define CSXsuper 8 // referenced super
|
||||
#define CSXlabel 0x10 // seen a label
|
||||
#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
|
||||
|
||||
enum PROT protection; // protection for class members
|
||||
int explicitProtection; // set if in an explicit protection attribute
|
||||
|
||||
unsigned stc; // storage class
|
||||
|
||||
unsigned flags;
|
||||
#define SCOPEctor 1 // constructor type
|
||||
#define SCOPEstaticif 2 // inside static if
|
||||
#define SCOPEfree 4 // is on free list
|
||||
|
||||
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
|
||||
OutBuffer *docbuf; // buffer for documentation output
|
||||
|
||||
static Scope *freelist;
|
||||
static void *operator new(size_t sz);
|
||||
static Scope *createGlobal(Module *module);
|
||||
|
||||
Scope();
|
||||
Scope(Module *module);
|
||||
Scope(Scope *enclosing);
|
||||
|
||||
Scope *push();
|
||||
Scope *push(ScopeDsymbol *ss);
|
||||
Scope *pop();
|
||||
|
||||
void mergeCallSuper(Loc loc, unsigned cs);
|
||||
|
||||
Dsymbol *search(Loc loc, Identifier *ident, Dsymbol **pscopesym);
|
||||
Dsymbol *insert(Dsymbol *s);
|
||||
|
||||
ClassDeclaration *getClassScope();
|
||||
AggregateDeclaration *getStructClassScope();
|
||||
void setNoFree();
|
||||
};
|
||||
|
||||
#endif /* DMD_SCOPE_H */
|
||||
|
||||
// Copyright (c) 1999-2005 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.
|
||||
|
||||
#ifndef DMD_SCOPE_H
|
||||
#define DMD_SCOPE_H
|
||||
|
||||
#ifdef __DMC__
|
||||
#pragma once
|
||||
#endif /* __DMC__ */
|
||||
|
||||
struct Dsymbol;
|
||||
struct ScopeDsymbol;
|
||||
struct Array;
|
||||
struct Identifier;
|
||||
struct Module;
|
||||
struct Statement;
|
||||
struct SwitchStatement;
|
||||
struct TryFinallyStatement;
|
||||
struct LabelStatement;
|
||||
struct ForeachStatement;
|
||||
struct ClassDeclaration;
|
||||
struct AggregateDeclaration;
|
||||
struct AnonymousAggregateDeclaration;
|
||||
struct FuncDeclaration;
|
||||
struct DocComment;
|
||||
enum LINK;
|
||||
enum PROT;
|
||||
|
||||
struct Scope
|
||||
{
|
||||
Scope *enclosing; // enclosing Scope
|
||||
|
||||
Module *module; // Root module
|
||||
ScopeDsymbol *scopesym; // current symbol
|
||||
ScopeDsymbol *sd; // if in static if, and declaring new symbols,
|
||||
// sd gets the addMember()
|
||||
FuncDeclaration *func; // function we are in
|
||||
Dsymbol *parent; // parent to use
|
||||
LabelStatement *slabel; // enclosing labelled statement
|
||||
SwitchStatement *sw; // enclosing switch statement
|
||||
TryFinallyStatement *tf; // enclosing try finally statement; set inside its finally block
|
||||
TryFinallyStatement *tfOfTry; // enclosing try finally statement; set inside its try block
|
||||
Statement *sbreak; // enclosing statement that supports "break"
|
||||
Statement *scontinue; // enclosing statement that supports "continue"
|
||||
ForeachStatement *fes; // if nested function for ForeachStatement, this is it
|
||||
unsigned offset; // next offset to use in aggregate
|
||||
int inunion; // we're processing members of a union
|
||||
int incontract; // we're inside contract code
|
||||
int nofree; // set if shouldn't free it
|
||||
int noctor; // set if constructor calls aren't allowed
|
||||
int intypeof; // in typeof(exp)
|
||||
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()
|
||||
#define CSXsuper_ctor 2 // called super()
|
||||
#define CSXthis 4 // referenced this
|
||||
#define CSXsuper 8 // referenced super
|
||||
#define CSXlabel 0x10 // seen a label
|
||||
#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
|
||||
|
||||
enum PROT protection; // protection for class members
|
||||
int explicitProtection; // set if in an explicit protection attribute
|
||||
|
||||
unsigned stc; // storage class
|
||||
|
||||
unsigned flags;
|
||||
#define SCOPEctor 1 // constructor type
|
||||
#define SCOPEstaticif 2 // inside static if
|
||||
#define SCOPEfree 4 // is on free list
|
||||
|
||||
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
|
||||
OutBuffer *docbuf; // buffer for documentation output
|
||||
|
||||
static Scope *freelist;
|
||||
static void *operator new(size_t sz);
|
||||
static Scope *createGlobal(Module *module);
|
||||
|
||||
Scope();
|
||||
Scope(Module *module);
|
||||
Scope(Scope *enclosing);
|
||||
|
||||
Scope *push();
|
||||
Scope *push(ScopeDsymbol *ss);
|
||||
Scope *pop();
|
||||
|
||||
void mergeCallSuper(Loc loc, unsigned cs);
|
||||
|
||||
Dsymbol *search(Loc loc, Identifier *ident, Dsymbol **pscopesym);
|
||||
Dsymbol *insert(Dsymbol *s);
|
||||
|
||||
ClassDeclaration *getClassScope();
|
||||
AggregateDeclaration *getStructClassScope();
|
||||
void setNoFree();
|
||||
};
|
||||
|
||||
#endif /* DMD_SCOPE_H */
|
||||
|
||||
7216
dmd/statement.c
7216
dmd/statement.c
File diff suppressed because it is too large
Load Diff
264
dmd/template.c
264
dmd/template.c
@@ -130,6 +130,7 @@ int match(Object *o1, Object *o2, TemplateDeclaration *tempdecl, Scope *sc)
|
||||
Dsymbol *s2 = isDsymbol(o2);
|
||||
Tuple *v1 = isTuple(o1);
|
||||
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
|
||||
* 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))
|
||||
goto L1;
|
||||
goto Lnomatch;
|
||||
}
|
||||
else if (e1)
|
||||
{
|
||||
@@ -168,33 +169,39 @@ int match(Object *o1, Object *o2, TemplateDeclaration *tempdecl, Scope *sc)
|
||||
printf("match %d\n", e1->equals(e2));
|
||||
e1->print();
|
||||
e2->print();
|
||||
e1->type->print();
|
||||
e2->type->print();
|
||||
}
|
||||
#endif
|
||||
if (!e2 || !e1->equals(e2))
|
||||
goto L1;
|
||||
if (!e2)
|
||||
goto Lnomatch;
|
||||
if (!e1->equals(e2))
|
||||
goto Lnomatch;
|
||||
}
|
||||
else if (s1)
|
||||
{
|
||||
//printf("%p %s, %p %s\n", s1, s1->toChars(), s2, s2->toChars());
|
||||
if (!s2 || !s1->equals(s2) || s1->parent != s2->parent)
|
||||
goto L1;
|
||||
{
|
||||
goto Lnomatch;
|
||||
}
|
||||
}
|
||||
else if (v1)
|
||||
{
|
||||
if (!v2)
|
||||
goto L1;
|
||||
goto Lnomatch;
|
||||
if (v1->objects.dim != v2->objects.dim)
|
||||
goto L1;
|
||||
goto Lnomatch;
|
||||
for (size_t i = 0; i < v1->objects.dim; i++)
|
||||
{
|
||||
if (!match((Object *)v1->objects.data[i],
|
||||
(Object *)v2->objects.data[i],
|
||||
tempdecl, sc))
|
||||
goto L1;
|
||||
goto Lnomatch;
|
||||
}
|
||||
}
|
||||
return 1; // match
|
||||
L1:
|
||||
Lnomatch:
|
||||
return 0; // nomatch;
|
||||
}
|
||||
|
||||
@@ -268,6 +275,7 @@ TemplateDeclaration::TemplateDeclaration(Loc loc, Identifier *id, TemplateParame
|
||||
#endif
|
||||
this->loc = loc;
|
||||
this->parameters = parameters;
|
||||
this->origParameters = parameters;
|
||||
this->members = decldefs;
|
||||
this->overnext = NULL;
|
||||
this->overroot = NULL;
|
||||
@@ -336,6 +344,17 @@ void TemplateDeclaration::semantic(Scope *sc)
|
||||
Scope *paramscope = sc->push(paramsym);
|
||||
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++)
|
||||
{
|
||||
TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
|
||||
@@ -348,6 +367,8 @@ void TemplateDeclaration::semantic(Scope *sc)
|
||||
TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
|
||||
|
||||
tp->semantic(paramscope);
|
||||
if (i + 1 != parameters->dim && tp->isTemplateTupleParameter())
|
||||
error("template tuple parameter must be last one");
|
||||
}
|
||||
|
||||
paramscope->pop();
|
||||
@@ -437,6 +458,7 @@ int TemplateDeclaration::overloadInsert(Dsymbol *s)
|
||||
* those deduced types in dedtypes[].
|
||||
* Input:
|
||||
* flag 1: don't do semantic() because of dummy types
|
||||
* 2: don't change types in matchArg()
|
||||
* Output:
|
||||
* dedtypes deduced arguments
|
||||
* Return match level.
|
||||
@@ -447,8 +469,9 @@ MATCH TemplateDeclaration::matchWithInstance(TemplateInstance *ti,
|
||||
{ MATCH m;
|
||||
int dedtypes_dim = dedtypes->dim;
|
||||
|
||||
#if LOG
|
||||
printf("+TemplateDeclaration::matchWithInstance(this = %s, ti = %s, flag = %d)\n", toChars(), ti->toChars(), flag);
|
||||
#define LOGM 0
|
||||
#if LOGM
|
||||
printf("\n+TemplateDeclaration::matchWithInstance(this = %s, ti = %s, flag = %d)\n", toChars(), ti->toChars(), flag);
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
@@ -466,7 +489,7 @@ MATCH TemplateDeclaration::matchWithInstance(TemplateInstance *ti,
|
||||
// If more arguments than parameters, no match
|
||||
if (ti->tiargs->dim > parameters_dim && !variadic)
|
||||
{
|
||||
#if LOG
|
||||
#if LOGM
|
||||
printf(" no match: more arguments than parameters\n");
|
||||
#endif
|
||||
return MATCHnomatch;
|
||||
@@ -489,7 +512,7 @@ MATCH TemplateDeclaration::matchWithInstance(TemplateInstance *ti,
|
||||
Declaration *sparam;
|
||||
|
||||
//printf("\targument [%d]\n", i);
|
||||
#if 0
|
||||
#if LOGM
|
||||
//printf("\targument [%d] is %s\n", i, oarg ? oarg->toChars() : "null");
|
||||
TemplateTypeParameter *ttp = tp->isTemplateTypeParameter();
|
||||
if (ttp)
|
||||
@@ -528,7 +551,7 @@ MATCH TemplateDeclaration::matchWithInstance(TemplateInstance *ti,
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
#if LOGM
|
||||
// Print out the results
|
||||
printf("--------------------------\n");
|
||||
printf("template %s\n", toChars());
|
||||
@@ -553,20 +576,20 @@ MATCH TemplateDeclaration::matchWithInstance(TemplateInstance *ti,
|
||||
goto Lnomatch;
|
||||
#endif
|
||||
|
||||
#if LOG
|
||||
#if LOGM
|
||||
printf(" match = %d\n", m);
|
||||
#endif
|
||||
goto Lret;
|
||||
|
||||
Lnomatch:
|
||||
#if LOG
|
||||
#if LOGM
|
||||
printf(" no match\n");
|
||||
#endif
|
||||
m = MATCHnomatch;
|
||||
|
||||
Lret:
|
||||
paramscope->pop();
|
||||
#if LOG
|
||||
#if LOGM
|
||||
printf("-TemplateDeclaration::matchWithInstance(this = %p, ti = %p) = %d\n", this, ti, m);
|
||||
#endif
|
||||
return m;
|
||||
@@ -645,6 +668,8 @@ int TemplateDeclaration::leastAsSpecialized(TemplateDeclaration *td2)
|
||||
* fargs arguments to function
|
||||
* Output:
|
||||
* dedargs Expression/Type deduced template arguments
|
||||
* Returns:
|
||||
* match level
|
||||
*/
|
||||
|
||||
MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Objects *targsi, Expressions *fargs,
|
||||
@@ -652,12 +677,13 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Objects *targsi, Expressi
|
||||
{
|
||||
size_t i;
|
||||
size_t nfparams;
|
||||
size_t nfparams2;
|
||||
size_t nfargs;
|
||||
size_t nargsi;
|
||||
size_t nargsi; // array size of targsi
|
||||
int fptupindex = -1;
|
||||
int tuple_dim = 0;
|
||||
MATCH match = MATCHexact;
|
||||
FuncDeclaration *fd = onemember->toAlias()->isFuncDeclaration();
|
||||
TypeFunction *fdtype;
|
||||
TypeFunction *fdtype; // type of fd
|
||||
TemplateTupleParameter *tp;
|
||||
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;
|
||||
Scope *paramscope = scope->push(paramsym);
|
||||
|
||||
tp = isVariadic();
|
||||
|
||||
nargsi = 0;
|
||||
if (targsi)
|
||||
{ // Set initial template arguments
|
||||
|
||||
nargsi = targsi->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));
|
||||
|
||||
@@ -698,6 +730,7 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Objects *targsi, Expressi
|
||||
Declaration *sparam;
|
||||
|
||||
m = tp->matchArg(paramscope, dedargs, i, parameters, &dedtypes, &sparam);
|
||||
//printf("\tdeduceType m = %d\n", m);
|
||||
if (m == MATCHnomatch)
|
||||
goto Lnomatch;
|
||||
if (m < match)
|
||||
@@ -713,7 +746,6 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Objects *targsi, Expressi
|
||||
fdtype = (TypeFunction *)fd->type;
|
||||
|
||||
nfparams = Argument::dim(fdtype->parameters); // number of function parameters
|
||||
nfparams2 = nfparams;
|
||||
nfargs = fargs->dim; // number of function arguments
|
||||
|
||||
/* 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); }
|
||||
*/
|
||||
tp = isVariadic();
|
||||
if (tp)
|
||||
if (tp) // if variadic
|
||||
{
|
||||
if (nfparams == 0) // if no function parameters
|
||||
{
|
||||
@@ -736,33 +768,38 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Objects *targsi, Expressi
|
||||
goto L1;
|
||||
else
|
||||
{
|
||||
/* See if 'A' of the template parameter matches 'A'
|
||||
* of the type of the last function parameter.
|
||||
/* Figure out which of the function parameters matches
|
||||
* 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];
|
||||
if (fparam->type->ty != Tident)
|
||||
goto L1;
|
||||
TypeIdentifier *tid = (TypeIdentifier *)fparam->type;
|
||||
if (!tp->ident->equals(tid->ident) || tid->idents.dim)
|
||||
goto L1;
|
||||
for (fptupindex = 0; fptupindex < nfparams; fptupindex++)
|
||||
{
|
||||
Argument *fparam = (Argument *)fdtype->parameters->data[fptupindex];
|
||||
if (fparam->type->ty != Tident)
|
||||
continue;
|
||||
TypeIdentifier *tid = (TypeIdentifier *)fparam->type;
|
||||
if (!tp->ident->equals(tid->ident) || tid->idents.dim)
|
||||
continue;
|
||||
|
||||
if (fdtype->varargs) // variadic function doesn't
|
||||
goto Lnomatch; // go with variadic template
|
||||
if (fdtype->varargs) // variadic function doesn't
|
||||
goto Lnomatch; // go with variadic template
|
||||
|
||||
/* The types of the function arguments [nfparams - 1 .. nfargs]
|
||||
* now form the tuple argument.
|
||||
*/
|
||||
Tuple *t = new Tuple();
|
||||
dedargs->data[parameters->dim - 1] = (void *)t;
|
||||
/* The types of the function arguments
|
||||
* now form the tuple argument.
|
||||
*/
|
||||
Tuple *t = new Tuple();
|
||||
dedargs->data[parameters->dim - 1] = (void *)t;
|
||||
|
||||
int tuple_dim = nfargs - (nfparams - 1);
|
||||
t->objects.setDim(tuple_dim);
|
||||
for (i = 0; i < tuple_dim; i++)
|
||||
{ Expression *farg = (Expression *)fargs->data[nfparams - 1 + i];
|
||||
t->objects.data[i] = (void *)farg->type;
|
||||
tuple_dim = nfargs - (nfparams - 1);
|
||||
t->objects.setDim(tuple_dim);
|
||||
for (i = 0; i < tuple_dim; i++)
|
||||
{ Expression *farg = (Expression *)fargs->data[fptupindex + i];
|
||||
t->objects.data[i] = (void *)farg->type;
|
||||
}
|
||||
goto L2;
|
||||
}
|
||||
nfparams2--; // don't consider the last parameter for type deduction
|
||||
goto L2;
|
||||
fptupindex = -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -778,11 +815,19 @@ L1:
|
||||
|
||||
L2:
|
||||
// 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);
|
||||
Expression *farg;
|
||||
MATCH m;
|
||||
|
||||
if (i >= nfargs) // if not enough arguments
|
||||
{
|
||||
@@ -794,12 +839,13 @@ L2:
|
||||
}
|
||||
}
|
||||
else
|
||||
{ farg = (Expression *)fargs->data[i];
|
||||
{ Expression *farg = (Expression *)fargs->data[i];
|
||||
#if 0
|
||||
printf("\tfarg->type = %s\n", farg->type->toChars());
|
||||
printf("\tfparam->type = %s\n", fparam->type->toChars());
|
||||
#endif
|
||||
|
||||
MATCH m;
|
||||
m = farg->type->deduceType(scope, fparam->type, parameters, &dedtypes);
|
||||
//printf("\tdeduceType m = %d\n", m);
|
||||
|
||||
@@ -852,30 +898,40 @@ Lmatch:
|
||||
for (i = nargsi; i < dedargs->dim; 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 *o = (Object *)dedtypes.data[i];
|
||||
//printf("1dedargs[%d] = %p, dedtypes[%d] = %p\n", i, oarg, i, o);
|
||||
Object *oded = (Object *)dedtypes.data[i];
|
||||
//printf("1dedargs[%d] = %p, dedtypes[%d] = %p\n", i, oarg, i, oded);
|
||||
if (!oarg)
|
||||
{
|
||||
if (o)
|
||||
if (oded)
|
||||
{
|
||||
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
|
||||
{ o = tp->defaultArg(paramscope);
|
||||
if (!o)
|
||||
{ oded = tp->defaultArg(paramscope);
|
||||
if (!oded)
|
||||
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);
|
||||
dedargs->data[i] = (void *)o;
|
||||
declareParameter(paramscope, tp, oded);
|
||||
dedargs->data[i] = (void *)oded;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -887,7 +943,7 @@ Lmatch:
|
||||
#endif
|
||||
|
||||
paramscope->pop();
|
||||
//printf("\tmatch\n");
|
||||
//printf("\tmatch %d\n", match);
|
||||
return match;
|
||||
|
||||
Lnomatch:
|
||||
@@ -1044,9 +1100,9 @@ FuncDeclaration *TemplateDeclaration::deduceFunctionTemplate(Scope *sc, Loc loc,
|
||||
int c2 = td_best->leastAsSpecialized(td);
|
||||
//printf("c1 = %d, c2 = %d\n", c1, c2);
|
||||
|
||||
if (c1 && !c2)
|
||||
if (c1 > c2)
|
||||
goto Ltd;
|
||||
else if (!c1 && c2)
|
||||
else if (c1 < c2)
|
||||
goto Ltd_best;
|
||||
else
|
||||
goto Lambig;
|
||||
@@ -1116,6 +1172,8 @@ void TemplateDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||
for (int i = 0; i < parameters->dim; i++)
|
||||
{
|
||||
TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
|
||||
if (hgs->ddoc)
|
||||
tp = (TemplateParameter *)origParameters->data[i];
|
||||
if (i)
|
||||
buf->writeByte(',');
|
||||
tp->toCBuffer(buf, hgs);
|
||||
@@ -1516,7 +1574,19 @@ MATCH TypeInstance::deduceType(Scope *sc,
|
||||
*/
|
||||
int i = templateIdentifierLookup(tp->tempinst->name, parameters);
|
||||
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;
|
||||
}
|
||||
TemplateParameter *tpx = (TemplateParameter *)parameters->data[i];
|
||||
// This logic duplicates tpx->matchArg()
|
||||
TemplateAliasParameter *ta = tpx->isTemplateAliasParameter();
|
||||
@@ -1540,12 +1610,14 @@ MATCH TypeInstance::deduceType(Scope *sc,
|
||||
else if (tempinst->tempdecl != tp->tempinst->tempdecl)
|
||||
goto Lnomatch;
|
||||
|
||||
L2:
|
||||
if (tempinst->tiargs->dim != tp->tempinst->tiargs->dim)
|
||||
goto Lnomatch;
|
||||
|
||||
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 *o2 = (Object *)tp->tempinst->tiargs->data[i];
|
||||
|
||||
@@ -1570,18 +1642,29 @@ MATCH TypeInstance::deduceType(Scope *sc,
|
||||
else if (e1 && 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;
|
||||
}
|
||||
}
|
||||
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;
|
||||
TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
|
||||
TemplateParameter *tp = (TemplateParameter *)parameters->data[j];
|
||||
// BUG: use tp->matchArg() instead of the following
|
||||
TemplateValueParameter *tv = tp->isTemplateValueParameter();
|
||||
if (!tv)
|
||||
goto Lnomatch;
|
||||
Expression *e = (Expression *)dedtypes->data[i];
|
||||
Expression *e = (Expression *)dedtypes->data[j];
|
||||
if (e)
|
||||
{
|
||||
if (!e1->equals(e))
|
||||
@@ -1592,7 +1675,7 @@ MATCH TypeInstance::deduceType(Scope *sc,
|
||||
MATCH m = (MATCH)e1->implicitConvTo(vt);
|
||||
if (!m)
|
||||
goto Lnomatch;
|
||||
dedtypes->data[i] = e1;
|
||||
dedtypes->data[j] = e1;
|
||||
}
|
||||
}
|
||||
// BUG: Need to handle alias and tuple parameters
|
||||
@@ -2351,6 +2434,7 @@ Lmatch:
|
||||
return m;
|
||||
|
||||
Lnomatch:
|
||||
//printf("\tno match\n");
|
||||
*psparam = NULL;
|
||||
return MATCHnomatch;
|
||||
}
|
||||
@@ -2780,7 +2864,7 @@ void TemplateInstance::semantic(Scope *sc)
|
||||
if (m->semanticdone >= 3)
|
||||
dosemantic3 = 1;
|
||||
}
|
||||
for (i = 0; 1; i++)
|
||||
for (int i = 0; 1; i++)
|
||||
{
|
||||
if (i == a->dim)
|
||||
{
|
||||
@@ -2953,7 +3037,7 @@ void TemplateInstance::semanticTiargs(Loc loc, Scope *sc, Objects *tiargs)
|
||||
Expression *ea = isExpression(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)
|
||||
{
|
||||
//printf("type %s\n", ta->toChars());
|
||||
@@ -3196,9 +3280,9 @@ TemplateDeclaration *TemplateInstance::findBestMatch(Scope *sc)
|
||||
int c2 = td_best->leastAsSpecialized(td);
|
||||
//printf("c1 = %d, c2 = %d\n", c1, c2);
|
||||
|
||||
if (c1 && !c2)
|
||||
if (c1 > c2)
|
||||
goto Ltd;
|
||||
else if (!c1 && c2)
|
||||
else if (c1 < c2)
|
||||
goto Ltd_best;
|
||||
else
|
||||
goto Lambig;
|
||||
@@ -3305,10 +3389,30 @@ int TemplateInstance::isNested(Objects *args)
|
||||
{
|
||||
// if module level template
|
||||
if (tempdecl->toParent()->isModule())
|
||||
{
|
||||
if (isnested && isnested != d->toParent())
|
||||
error("inconsistent nesting levels %s and %s", isnested->toChars(), d->toParent()->toChars());
|
||||
isnested = d->toParent();
|
||||
{ Dsymbol *dparent = d->toParent();
|
||||
if (!isnested)
|
||||
isnested = dparent;
|
||||
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;
|
||||
}
|
||||
else
|
||||
|
||||
653
dmd/template.h
653
dmd/template.h
@@ -1,325 +1,328 @@
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 1999-2006 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.
|
||||
|
||||
#ifndef DMD_TEMPLATE_H
|
||||
#define DMD_TEMPLATE_H
|
||||
|
||||
#ifdef __DMC__
|
||||
#pragma once
|
||||
#endif /* __DMC__ */
|
||||
|
||||
#include "root.h"
|
||||
#include "arraytypes.h"
|
||||
#include "dsymbol.h"
|
||||
#include "mtype.h"
|
||||
|
||||
|
||||
struct OutBuffer;
|
||||
struct Identifier;
|
||||
struct TemplateInstance;
|
||||
struct TemplateParameter;
|
||||
struct TemplateTypeParameter;
|
||||
struct TemplateValueParameter;
|
||||
struct TemplateAliasParameter;
|
||||
struct TemplateTupleParameter;
|
||||
struct Type;
|
||||
struct TypeTypeof;
|
||||
struct Scope;
|
||||
struct Expression;
|
||||
struct AliasDeclaration;
|
||||
struct FuncDeclaration;
|
||||
struct HdrGenState;
|
||||
enum MATCH;
|
||||
|
||||
struct Tuple : Object
|
||||
{
|
||||
Objects objects;
|
||||
|
||||
int dyncast() { return DYNCAST_TUPLE; } // kludge for template.isType()
|
||||
};
|
||||
|
||||
|
||||
struct TemplateDeclaration : ScopeDsymbol
|
||||
{
|
||||
TemplateParameters *parameters; // array of TemplateParameter's
|
||||
Array instances; // array of TemplateInstance's
|
||||
|
||||
TemplateDeclaration *overnext; // next overloaded TemplateDeclaration
|
||||
TemplateDeclaration *overroot; // first in overnext list
|
||||
|
||||
Scope *scope;
|
||||
Dsymbol *onemember; // if !=NULL then one member of this template
|
||||
|
||||
TemplateDeclaration(Loc loc, Identifier *id, TemplateParameters *parameters, Array *decldefs);
|
||||
Dsymbol *syntaxCopy(Dsymbol *);
|
||||
void semantic(Scope *sc);
|
||||
int overloadInsert(Dsymbol *s);
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
char *kind();
|
||||
char *toChars();
|
||||
|
||||
void emitComment(Scope *sc);
|
||||
// void toDocBuffer(OutBuffer *buf);
|
||||
|
||||
MATCH matchWithInstance(TemplateInstance *ti, Objects *atypes, int flag);
|
||||
int leastAsSpecialized(TemplateDeclaration *td2);
|
||||
|
||||
MATCH deduceFunctionTemplateMatch(Objects *targsi, Expressions *fargs, Objects *dedargs);
|
||||
FuncDeclaration *deduceFunctionTemplate(Scope *sc, Loc loc, Objects *targsi, Expressions *fargs);
|
||||
void declareParameter(Scope *sc, TemplateParameter *tp, Object *o);
|
||||
|
||||
TemplateDeclaration *isTemplateDeclaration() { return this; }
|
||||
|
||||
TemplateTupleParameter *isVariadic();
|
||||
int isOverloadable();
|
||||
};
|
||||
|
||||
struct TemplateParameter
|
||||
{
|
||||
/* For type-parameter:
|
||||
* template Foo(ident) // specType is set to NULL
|
||||
* template Foo(ident : specType)
|
||||
* For value-parameter:
|
||||
* template Foo(valType ident) // specValue is set to NULL
|
||||
* template Foo(valType ident : specValue)
|
||||
* For alias-parameter:
|
||||
* template Foo(alias ident)
|
||||
*/
|
||||
|
||||
Loc loc;
|
||||
Identifier *ident;
|
||||
|
||||
Declaration *sparam;
|
||||
|
||||
TemplateParameter(Loc loc, Identifier *ident);
|
||||
|
||||
virtual TemplateTypeParameter *isTemplateTypeParameter();
|
||||
virtual TemplateValueParameter *isTemplateValueParameter();
|
||||
virtual TemplateAliasParameter *isTemplateAliasParameter();
|
||||
virtual TemplateTupleParameter *isTemplateTupleParameter();
|
||||
|
||||
virtual TemplateParameter *syntaxCopy() = 0;
|
||||
virtual void declareParameter(Scope *sc) = 0;
|
||||
virtual void semantic(Scope *) = 0;
|
||||
virtual void print(Object *oarg, Object *oded) = 0;
|
||||
virtual void toCBuffer(OutBuffer *buf, HdrGenState *hgs) = 0;
|
||||
virtual Object *specialization() = 0;
|
||||
virtual Object *defaultArg(Scope *sc) = 0;
|
||||
|
||||
/* If TemplateParameter's match as far as overloading goes.
|
||||
*/
|
||||
virtual int overloadMatch(TemplateParameter *) = 0;
|
||||
|
||||
/* Match actual argument against parameter.
|
||||
*/
|
||||
virtual MATCH matchArg(Scope *sc, Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam) = 0;
|
||||
|
||||
/* Create dummy argument based on parameter.
|
||||
*/
|
||||
virtual void *dummyArg() = 0;
|
||||
};
|
||||
|
||||
struct TemplateTypeParameter : TemplateParameter
|
||||
{
|
||||
/* Syntax:
|
||||
* ident : specType = defaultType
|
||||
*/
|
||||
Type *specType; // type parameter: if !=NULL, this is the type specialization
|
||||
Type *defaultType;
|
||||
|
||||
TemplateTypeParameter(Loc loc, Identifier *ident, Type *specType, Type *defaultType);
|
||||
|
||||
TemplateTypeParameter *isTemplateTypeParameter();
|
||||
TemplateParameter *syntaxCopy();
|
||||
void declareParameter(Scope *sc);
|
||||
void semantic(Scope *);
|
||||
void print(Object *oarg, Object *oded);
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
Object *specialization();
|
||||
Object *defaultArg(Scope *sc);
|
||||
int overloadMatch(TemplateParameter *);
|
||||
MATCH matchArg(Scope *sc, Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam);
|
||||
void *dummyArg();
|
||||
};
|
||||
|
||||
struct TemplateValueParameter : TemplateParameter
|
||||
{
|
||||
/* Syntax:
|
||||
* valType ident : specValue = defaultValue
|
||||
*/
|
||||
|
||||
Type *valType;
|
||||
Expression *specValue;
|
||||
Expression *defaultValue;
|
||||
|
||||
static Expression *edummy;
|
||||
|
||||
TemplateValueParameter(Loc loc, Identifier *ident, Type *valType, Expression *specValue, Expression *defaultValue);
|
||||
|
||||
TemplateValueParameter *isTemplateValueParameter();
|
||||
TemplateParameter *syntaxCopy();
|
||||
void declareParameter(Scope *sc);
|
||||
void semantic(Scope *);
|
||||
void print(Object *oarg, Object *oded);
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
Object *specialization();
|
||||
Object *defaultArg(Scope *sc);
|
||||
int overloadMatch(TemplateParameter *);
|
||||
MATCH matchArg(Scope *sc, Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam);
|
||||
void *dummyArg();
|
||||
};
|
||||
|
||||
struct TemplateAliasParameter : TemplateParameter
|
||||
{
|
||||
/* Syntax:
|
||||
* ident : specAlias = defaultAlias
|
||||
*/
|
||||
|
||||
Type *specAliasT;
|
||||
Dsymbol *specAlias;
|
||||
|
||||
Type *defaultAlias;
|
||||
|
||||
static Dsymbol *sdummy;
|
||||
|
||||
TemplateAliasParameter(Loc loc, Identifier *ident, Type *specAliasT, Type *defaultAlias);
|
||||
|
||||
TemplateAliasParameter *isTemplateAliasParameter();
|
||||
TemplateParameter *syntaxCopy();
|
||||
void declareParameter(Scope *sc);
|
||||
void semantic(Scope *);
|
||||
void print(Object *oarg, Object *oded);
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
Object *specialization();
|
||||
Object *defaultArg(Scope *sc);
|
||||
int overloadMatch(TemplateParameter *);
|
||||
MATCH matchArg(Scope *sc, Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam);
|
||||
void *dummyArg();
|
||||
};
|
||||
|
||||
struct TemplateTupleParameter : TemplateParameter
|
||||
{
|
||||
/* Syntax:
|
||||
* ident ...
|
||||
*/
|
||||
|
||||
TemplateTupleParameter(Loc loc, Identifier *ident);
|
||||
|
||||
TemplateTupleParameter *isTemplateTupleParameter();
|
||||
TemplateParameter *syntaxCopy();
|
||||
void declareParameter(Scope *sc);
|
||||
void semantic(Scope *);
|
||||
void print(Object *oarg, Object *oded);
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
Object *specialization();
|
||||
Object *defaultArg(Scope *sc);
|
||||
int overloadMatch(TemplateParameter *);
|
||||
MATCH matchArg(Scope *sc, Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam);
|
||||
void *dummyArg();
|
||||
};
|
||||
|
||||
struct TemplateInstance : ScopeDsymbol
|
||||
{
|
||||
/* Given:
|
||||
* foo!(args) =>
|
||||
* name = foo
|
||||
* tiargs = args
|
||||
*/
|
||||
Identifier *name;
|
||||
//Array idents;
|
||||
Objects *tiargs; // Array of Types/Expressions of template
|
||||
// instance arguments [int*, char, 10*10]
|
||||
|
||||
Objects tdtypes; // Array of Types/Expressions corresponding
|
||||
// to TemplateDeclaration.parameters
|
||||
// [int, char, 100]
|
||||
|
||||
TemplateDeclaration *tempdecl; // referenced by foo.bar.abc
|
||||
TemplateInstance *inst; // refer to existing instance
|
||||
ScopeDsymbol *argsym; // argument symbol table
|
||||
AliasDeclaration *aliasdecl; // !=NULL if instance is an alias for its
|
||||
// sole member
|
||||
WithScopeSymbol *withsym; // if a member of a with statement
|
||||
int semanticdone; // has semantic() been done?
|
||||
int nest; // for recursion detection
|
||||
int havetempdecl; // 1 if used second constructor
|
||||
Dsymbol *isnested; // if referencing local symbols, this is the context
|
||||
int errors; // 1 if compiled with errors
|
||||
#ifdef IN_GCC
|
||||
/* On some targets, it is necessary to know whether a symbol
|
||||
will be emitted in the output or not before the symbol
|
||||
is used. This can be different from getModule(). */
|
||||
Module * objFileModule;
|
||||
#endif
|
||||
|
||||
TemplateInstance(Loc loc, Identifier *temp_id);
|
||||
TemplateInstance(Loc loc, TemplateDeclaration *tempdecl, Objects *tiargs);
|
||||
static Objects *arraySyntaxCopy(Objects *objs);
|
||||
Dsymbol *syntaxCopy(Dsymbol *);
|
||||
void semantic(Scope *sc);
|
||||
void semantic2(Scope *sc);
|
||||
void semantic3(Scope *sc);
|
||||
void inlineScan();
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
Dsymbol *toAlias(); // resolve real symbol
|
||||
char *kind();
|
||||
int oneMember(Dsymbol **ps);
|
||||
char *toChars();
|
||||
char *mangle();
|
||||
|
||||
void toObjFile(); // compile to .obj file
|
||||
|
||||
// Internal
|
||||
static void semanticTiargs(Loc loc, Scope *sc, Objects *tiargs);
|
||||
void semanticTiargs(Scope *sc);
|
||||
TemplateDeclaration *findTemplateDeclaration(Scope *sc);
|
||||
TemplateDeclaration *findBestMatch(Scope *sc);
|
||||
void declareParameters(Scope *sc);
|
||||
int isNested(Objects *tiargs);
|
||||
Identifier *genIdent();
|
||||
|
||||
TemplateInstance *isTemplateInstance() { return this; }
|
||||
AliasDeclaration *isAliasDeclaration();
|
||||
};
|
||||
|
||||
struct TemplateMixin : TemplateInstance
|
||||
{
|
||||
Array *idents;
|
||||
Type *tqual;
|
||||
|
||||
Scope *scope; // for forward referencing
|
||||
|
||||
TemplateMixin(Loc loc, Identifier *ident, Type *tqual, Array *idents, Objects *tiargs);
|
||||
Dsymbol *syntaxCopy(Dsymbol *s);
|
||||
void semantic(Scope *sc);
|
||||
void semantic2(Scope *sc);
|
||||
void semantic3(Scope *sc);
|
||||
void inlineScan();
|
||||
char *kind();
|
||||
int oneMember(Dsymbol **ps);
|
||||
int hasPointers();
|
||||
char *toChars();
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
|
||||
void toObjFile(); // compile to .obj file
|
||||
|
||||
TemplateMixin *isTemplateMixin() { return this; }
|
||||
};
|
||||
|
||||
Expression *isExpression(Object *o);
|
||||
Dsymbol *isDsymbol(Object *o);
|
||||
Type *isType(Object *o);
|
||||
Tuple *isTuple(Object *o);
|
||||
Type *getType(Object *o);
|
||||
Dsymbol *getDsymbol(Object *o);
|
||||
|
||||
void ObjectToCBuffer(OutBuffer *buf, HdrGenState *hgs, Object *oarg);
|
||||
|
||||
#endif /* DMD_TEMPLATE_H */
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 1999-2006 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.
|
||||
|
||||
#ifndef DMD_TEMPLATE_H
|
||||
#define DMD_TEMPLATE_H
|
||||
|
||||
#ifdef __DMC__
|
||||
#pragma once
|
||||
#endif /* __DMC__ */
|
||||
|
||||
#include "root.h"
|
||||
#include "arraytypes.h"
|
||||
#include "dsymbol.h"
|
||||
#include "mtype.h"
|
||||
|
||||
|
||||
struct OutBuffer;
|
||||
struct Identifier;
|
||||
struct TemplateInstance;
|
||||
struct TemplateParameter;
|
||||
struct TemplateTypeParameter;
|
||||
struct TemplateValueParameter;
|
||||
struct TemplateAliasParameter;
|
||||
struct TemplateTupleParameter;
|
||||
struct Type;
|
||||
struct TypeTypeof;
|
||||
struct Scope;
|
||||
struct Expression;
|
||||
struct AliasDeclaration;
|
||||
struct FuncDeclaration;
|
||||
struct HdrGenState;
|
||||
enum MATCH;
|
||||
|
||||
struct Tuple : Object
|
||||
{
|
||||
Objects objects;
|
||||
|
||||
int dyncast() { return DYNCAST_TUPLE; } // kludge for template.isType()
|
||||
};
|
||||
|
||||
|
||||
struct TemplateDeclaration : ScopeDsymbol
|
||||
{
|
||||
TemplateParameters *parameters; // array of TemplateParameter's
|
||||
|
||||
TemplateParameters *origParameters; // originals for Ddoc
|
||||
|
||||
Array instances; // array of TemplateInstance's
|
||||
|
||||
TemplateDeclaration *overnext; // next overloaded TemplateDeclaration
|
||||
TemplateDeclaration *overroot; // first in overnext list
|
||||
|
||||
Scope *scope;
|
||||
Dsymbol *onemember; // if !=NULL then one member of this template
|
||||
|
||||
TemplateDeclaration(Loc loc, Identifier *id, TemplateParameters *parameters, Array *decldefs);
|
||||
Dsymbol *syntaxCopy(Dsymbol *);
|
||||
void semantic(Scope *sc);
|
||||
int overloadInsert(Dsymbol *s);
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
char *kind();
|
||||
char *toChars();
|
||||
|
||||
void emitComment(Scope *sc);
|
||||
// void toDocBuffer(OutBuffer *buf);
|
||||
|
||||
MATCH matchWithInstance(TemplateInstance *ti, Objects *atypes, int flag);
|
||||
int leastAsSpecialized(TemplateDeclaration *td2);
|
||||
|
||||
MATCH deduceFunctionTemplateMatch(Objects *targsi, Expressions *fargs, Objects *dedargs);
|
||||
FuncDeclaration *deduceFunctionTemplate(Scope *sc, Loc loc, Objects *targsi, Expressions *fargs);
|
||||
void declareParameter(Scope *sc, TemplateParameter *tp, Object *o);
|
||||
|
||||
TemplateDeclaration *isTemplateDeclaration() { return this; }
|
||||
|
||||
TemplateTupleParameter *isVariadic();
|
||||
int isOverloadable();
|
||||
};
|
||||
|
||||
struct TemplateParameter
|
||||
{
|
||||
/* For type-parameter:
|
||||
* template Foo(ident) // specType is set to NULL
|
||||
* template Foo(ident : specType)
|
||||
* For value-parameter:
|
||||
* template Foo(valType ident) // specValue is set to NULL
|
||||
* template Foo(valType ident : specValue)
|
||||
* For alias-parameter:
|
||||
* template Foo(alias ident)
|
||||
*/
|
||||
|
||||
Loc loc;
|
||||
Identifier *ident;
|
||||
|
||||
Declaration *sparam;
|
||||
|
||||
TemplateParameter(Loc loc, Identifier *ident);
|
||||
|
||||
virtual TemplateTypeParameter *isTemplateTypeParameter();
|
||||
virtual TemplateValueParameter *isTemplateValueParameter();
|
||||
virtual TemplateAliasParameter *isTemplateAliasParameter();
|
||||
virtual TemplateTupleParameter *isTemplateTupleParameter();
|
||||
|
||||
virtual TemplateParameter *syntaxCopy() = 0;
|
||||
virtual void declareParameter(Scope *sc) = 0;
|
||||
virtual void semantic(Scope *) = 0;
|
||||
virtual void print(Object *oarg, Object *oded) = 0;
|
||||
virtual void toCBuffer(OutBuffer *buf, HdrGenState *hgs) = 0;
|
||||
virtual Object *specialization() = 0;
|
||||
virtual Object *defaultArg(Scope *sc) = 0;
|
||||
|
||||
/* If TemplateParameter's match as far as overloading goes.
|
||||
*/
|
||||
virtual int overloadMatch(TemplateParameter *) = 0;
|
||||
|
||||
/* Match actual argument against parameter.
|
||||
*/
|
||||
virtual MATCH matchArg(Scope *sc, Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam) = 0;
|
||||
|
||||
/* Create dummy argument based on parameter.
|
||||
*/
|
||||
virtual void *dummyArg() = 0;
|
||||
};
|
||||
|
||||
struct TemplateTypeParameter : TemplateParameter
|
||||
{
|
||||
/* Syntax:
|
||||
* ident : specType = defaultType
|
||||
*/
|
||||
Type *specType; // type parameter: if !=NULL, this is the type specialization
|
||||
Type *defaultType;
|
||||
|
||||
TemplateTypeParameter(Loc loc, Identifier *ident, Type *specType, Type *defaultType);
|
||||
|
||||
TemplateTypeParameter *isTemplateTypeParameter();
|
||||
TemplateParameter *syntaxCopy();
|
||||
void declareParameter(Scope *sc);
|
||||
void semantic(Scope *);
|
||||
void print(Object *oarg, Object *oded);
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
Object *specialization();
|
||||
Object *defaultArg(Scope *sc);
|
||||
int overloadMatch(TemplateParameter *);
|
||||
MATCH matchArg(Scope *sc, Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam);
|
||||
void *dummyArg();
|
||||
};
|
||||
|
||||
struct TemplateValueParameter : TemplateParameter
|
||||
{
|
||||
/* Syntax:
|
||||
* valType ident : specValue = defaultValue
|
||||
*/
|
||||
|
||||
Type *valType;
|
||||
Expression *specValue;
|
||||
Expression *defaultValue;
|
||||
|
||||
static Expression *edummy;
|
||||
|
||||
TemplateValueParameter(Loc loc, Identifier *ident, Type *valType, Expression *specValue, Expression *defaultValue);
|
||||
|
||||
TemplateValueParameter *isTemplateValueParameter();
|
||||
TemplateParameter *syntaxCopy();
|
||||
void declareParameter(Scope *sc);
|
||||
void semantic(Scope *);
|
||||
void print(Object *oarg, Object *oded);
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
Object *specialization();
|
||||
Object *defaultArg(Scope *sc);
|
||||
int overloadMatch(TemplateParameter *);
|
||||
MATCH matchArg(Scope *sc, Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam);
|
||||
void *dummyArg();
|
||||
};
|
||||
|
||||
struct TemplateAliasParameter : TemplateParameter
|
||||
{
|
||||
/* Syntax:
|
||||
* ident : specAlias = defaultAlias
|
||||
*/
|
||||
|
||||
Type *specAliasT;
|
||||
Dsymbol *specAlias;
|
||||
|
||||
Type *defaultAlias;
|
||||
|
||||
static Dsymbol *sdummy;
|
||||
|
||||
TemplateAliasParameter(Loc loc, Identifier *ident, Type *specAliasT, Type *defaultAlias);
|
||||
|
||||
TemplateAliasParameter *isTemplateAliasParameter();
|
||||
TemplateParameter *syntaxCopy();
|
||||
void declareParameter(Scope *sc);
|
||||
void semantic(Scope *);
|
||||
void print(Object *oarg, Object *oded);
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
Object *specialization();
|
||||
Object *defaultArg(Scope *sc);
|
||||
int overloadMatch(TemplateParameter *);
|
||||
MATCH matchArg(Scope *sc, Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam);
|
||||
void *dummyArg();
|
||||
};
|
||||
|
||||
struct TemplateTupleParameter : TemplateParameter
|
||||
{
|
||||
/* Syntax:
|
||||
* ident ...
|
||||
*/
|
||||
|
||||
TemplateTupleParameter(Loc loc, Identifier *ident);
|
||||
|
||||
TemplateTupleParameter *isTemplateTupleParameter();
|
||||
TemplateParameter *syntaxCopy();
|
||||
void declareParameter(Scope *sc);
|
||||
void semantic(Scope *);
|
||||
void print(Object *oarg, Object *oded);
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
Object *specialization();
|
||||
Object *defaultArg(Scope *sc);
|
||||
int overloadMatch(TemplateParameter *);
|
||||
MATCH matchArg(Scope *sc, Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam);
|
||||
void *dummyArg();
|
||||
};
|
||||
|
||||
struct TemplateInstance : ScopeDsymbol
|
||||
{
|
||||
/* Given:
|
||||
* foo!(args) =>
|
||||
* name = foo
|
||||
* tiargs = args
|
||||
*/
|
||||
Identifier *name;
|
||||
//Array idents;
|
||||
Objects *tiargs; // Array of Types/Expressions of template
|
||||
// instance arguments [int*, char, 10*10]
|
||||
|
||||
Objects tdtypes; // Array of Types/Expressions corresponding
|
||||
// to TemplateDeclaration.parameters
|
||||
// [int, char, 100]
|
||||
|
||||
TemplateDeclaration *tempdecl; // referenced by foo.bar.abc
|
||||
TemplateInstance *inst; // refer to existing instance
|
||||
ScopeDsymbol *argsym; // argument symbol table
|
||||
AliasDeclaration *aliasdecl; // !=NULL if instance is an alias for its
|
||||
// sole member
|
||||
WithScopeSymbol *withsym; // if a member of a with statement
|
||||
int semanticdone; // has semantic() been done?
|
||||
int nest; // for recursion detection
|
||||
int havetempdecl; // 1 if used second constructor
|
||||
Dsymbol *isnested; // if referencing local symbols, this is the context
|
||||
int errors; // 1 if compiled with errors
|
||||
#ifdef IN_GCC
|
||||
/* On some targets, it is necessary to know whether a symbol
|
||||
will be emitted in the output or not before the symbol
|
||||
is used. This can be different from getModule(). */
|
||||
Module * objFileModule;
|
||||
#endif
|
||||
|
||||
TemplateInstance(Loc loc, Identifier *temp_id);
|
||||
TemplateInstance(Loc loc, TemplateDeclaration *tempdecl, Objects *tiargs);
|
||||
static Objects *arraySyntaxCopy(Objects *objs);
|
||||
Dsymbol *syntaxCopy(Dsymbol *);
|
||||
void semantic(Scope *sc);
|
||||
void semantic2(Scope *sc);
|
||||
void semantic3(Scope *sc);
|
||||
void inlineScan();
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
Dsymbol *toAlias(); // resolve real symbol
|
||||
char *kind();
|
||||
int oneMember(Dsymbol **ps);
|
||||
char *toChars();
|
||||
char *mangle();
|
||||
|
||||
void toObjFile(); // compile to .obj file
|
||||
|
||||
// Internal
|
||||
static void semanticTiargs(Loc loc, Scope *sc, Objects *tiargs);
|
||||
void semanticTiargs(Scope *sc);
|
||||
TemplateDeclaration *findTemplateDeclaration(Scope *sc);
|
||||
TemplateDeclaration *findBestMatch(Scope *sc);
|
||||
void declareParameters(Scope *sc);
|
||||
int isNested(Objects *tiargs);
|
||||
Identifier *genIdent();
|
||||
|
||||
TemplateInstance *isTemplateInstance() { return this; }
|
||||
AliasDeclaration *isAliasDeclaration();
|
||||
};
|
||||
|
||||
struct TemplateMixin : TemplateInstance
|
||||
{
|
||||
Array *idents;
|
||||
Type *tqual;
|
||||
|
||||
Scope *scope; // for forward referencing
|
||||
|
||||
TemplateMixin(Loc loc, Identifier *ident, Type *tqual, Array *idents, Objects *tiargs);
|
||||
Dsymbol *syntaxCopy(Dsymbol *s);
|
||||
void semantic(Scope *sc);
|
||||
void semantic2(Scope *sc);
|
||||
void semantic3(Scope *sc);
|
||||
void inlineScan();
|
||||
char *kind();
|
||||
int oneMember(Dsymbol **ps);
|
||||
int hasPointers();
|
||||
char *toChars();
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
|
||||
void toObjFile(); // compile to .obj file
|
||||
|
||||
TemplateMixin *isTemplateMixin() { return this; }
|
||||
};
|
||||
|
||||
Expression *isExpression(Object *o);
|
||||
Dsymbol *isDsymbol(Object *o);
|
||||
Type *isType(Object *o);
|
||||
Tuple *isTuple(Object *o);
|
||||
Type *getType(Object *o);
|
||||
Dsymbol *getDsymbol(Object *o);
|
||||
|
||||
void ObjectToCBuffer(OutBuffer *buf, HdrGenState *hgs, Object *oarg);
|
||||
|
||||
#endif /* DMD_TEMPLATE_H */
|
||||
|
||||
Reference in New Issue
Block a user