- Updated to DMD frontend 1.041.

- Removed dmd/inifile.c , it's not under a free license, replaced with libconfig based config file.
This commit is contained in:
Tomas Lindquist Olsen
2009-03-12 20:37:27 +01:00
parent ff354d59b2
commit 8b751cce0e
57 changed files with 1319 additions and 2477 deletions

View File

@@ -9,6 +9,19 @@ if(NOT PERL)
message(FATAL_ERROR "perl not found")
endif(NOT PERL)
include(FindPkgConfig)
if(NOT PKG_CONFIG_FOUND)
message(FATAL_ERROR "pkg-config not found")
else(NOT PKG_CONFIG_FOUND)
pkg_search_module(LIBCONFIGPP libconfig++)
if(NOT LIBCONFIGPP_FOUND)
message(FATAL_ERROR "libconfig++ not found")
endif(NOT LIBCONFIGPP_FOUND)
set(LIBCONFIG_CXXFLAGS ${LIBCONFIGPP_CFLAGS} CACHE STRING "libconfig++ compiler flags")
set(LIBCONFIG_LDFLAGS ${LIBCONFIGPP_LDFLAGS} CACHE STRING "libconfig++ linker flags")
endif(NOT PKG_CONFIG_FOUND)
find_program(LLVM_CONFIG llvm-config ${LLVM_INSTDIR}/bin DOC "path to llvm-config tool")
# get llvm's install dir. a little hackish, we could do something like llvm-config --prefix, but this does as well
string(REPLACE "/bin/llvm-config" "" LLVM_DIR ${LLVM_CONFIG})
@@ -39,7 +52,7 @@ execute_process(
OUTPUT_STRIP_TRAILING_WHITESPACE
)
execute_process(
COMMAND ${PERL_EXECUTABLE} ${LLVM_CONFIG} --libfiles bitwriter linker ipo instrumentation backend
COMMAND ${PERL_EXECUTABLE} ${LLVM_CONFIG} --libfiles bitwriter linker ipo instrumentation backend arm
OUTPUT_VARIABLE LLVM_LIBS
OUTPUT_STRIP_TRAILING_WHITESPACE
)
@@ -161,9 +174,11 @@ if(CMAKE_MINOR_VERSION LESS 6)
set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib CACHE PATH "output dir for built libraries")
add_definitions(-DDEFAULT_TARGET_TRIPLE=\\"${DEFAULT_TARGET}\\")
add_definitions(-DDEFAULT_ALT_TARGET_TRIPLE=\\"${DEFAULT_ALT_TARGET}\\")
add_definitions(-DLDC_INSTALL_PREFIX=\\"${CMAKE_INSTALL_PREFIX}\\")
else(CMAKE_MINOR_VERSION LESS 6)
add_definitions(-DDEFAULT_TARGET_TRIPLE="${DEFAULT_TARGET}")
add_definitions(-DDEFAULT_ALT_TARGET_TRIPLE="${DEFAULT_ALT_TARGET}")
add_definitions(-DLDC_INSTALL_PREFIX="${CMAKE_INSTALL_PREFIX}")
endif(CMAKE_MINOR_VERSION LESS 6)
add_executable(${LDC_EXE} ${LDC_SOURCE_FILES})
@@ -190,11 +205,11 @@ set_target_properties(
${LDC_EXE} PROPERTIES
OUTPUT_NAME ${LDC_EXE_NAME}
RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin
COMPILE_FLAGS "${LLVM_CXXFLAGS} -Wno-deprecated -Wno-write-strings"
COMPILE_FLAGS "${LLVM_CXXFLAGS} ${LIBCONFIG_CXXFLAGS} -Wno-deprecated -Wno-write-strings"
)
# LDFLAGS should actually be in target property LINK_FLAGS, but this works, and gets around linking problems
target_link_libraries(${LDC_EXE} "${LLVM_LDFLAGS} ${LLVM_LIBS}")
target_link_libraries(${LDC_EXE} "${LLVM_LDFLAGS} ${LLVM_LIBS} ${LIBCONFIG_LDFLAGS}")
if(WIN32)
target_link_libraries(${LDC_EXE} psapi)
set(CONF_INST_DIR bin)

File diff suppressed because it is too large Load Diff

View File

@@ -13,7 +13,7 @@
#include <assert.h>
#include "root.h"
#include "mem.h"
#include "rmem.h"
#include "enum.h"
#include "aggregate.h"

View File

@@ -41,7 +41,7 @@
#include "port.h"
#include "root.h"
#include "dchar.h"
#include "mem.h"
#include "rmem.h"
/********************************* Array ****************************/

View File

@@ -11,11 +11,7 @@
#include <string.h>
#include <assert.h>
#if _WIN32 || IN_GCC || IN_LLVM
#include "mem.h"
#else
#include "../root/mem.h"
#endif
#include "rmem.h"
#include "stringtable.h"

View File

@@ -12,11 +12,7 @@
#include <stdlib.h>
#include <assert.h>
#if _WIN32 || IN_GCC || IN_LLVM
#include "mem.h"
#elif POSIX
#include "../root/mem.h"
#endif
#include "rmem.h"
#include "init.h"
#include "declaration.h"
@@ -151,6 +147,14 @@ void AttribDeclaration::emitComment(Scope *sc)
{
//printf("AttribDeclaration::emitComment(sc = %p)\n", sc);
/* A general problem with this, illustrated by BUGZILLA 2516,
* is that attributes are not transmitted through to the underlying
* member declarations for template bodies, because semantic analysis
* is not done for template declaration bodies
* (only template instantiations).
* Hence, Ddoc omits attributes from template members.
*/
Array *d = include(NULL, NULL);
if (d)
@@ -326,11 +330,17 @@ void StorageClassDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{ STCstatic, TOKstatic },
{ STCextern, TOKextern },
{ STCconst, TOKconst },
// { STCinvariant, TOKimmutable },
// { STCshared, TOKshared },
{ STCfinal, TOKfinal },
{ STCabstract, TOKabstract },
{ STCsynchronized, TOKsynchronized },
{ STCdeprecated, TOKdeprecated },
{ STCoverride, TOKoverride },
// { STCnothrow, TOKnothrow },
// { STCpure, TOKpure },
// { STCref, TOKref },
// { STCtls, TOKtls },
};
int written = 0;
@@ -612,7 +622,7 @@ void AnonDeclaration::semantic(Scope *sc)
sc = sc->push();
sc->anonAgg = &aad;
sc->stc &= ~(STCauto | STCscope | STCstatic);
sc->stc &= ~(STCauto | STCscope | STCstatic | STCtls);
sc->inunion = isunion;
sc->offset = 0;
sc->flags = 0;
@@ -753,6 +763,7 @@ PragmaDeclaration::PragmaDeclaration(Loc loc, Identifier *ident, Expressions *ar
Dsymbol *PragmaDeclaration::syntaxCopy(Dsymbol *s)
{
//printf("PragmaDeclaration::syntaxCopy(%s)\n", toChars());
PragmaDeclaration *pd;
assert(!s);
@@ -1393,7 +1404,7 @@ Dsymbol *CompileDeclaration::syntaxCopy(Dsymbol *s)
int CompileDeclaration::addMember(Scope *sc, ScopeDsymbol *sd, int memnum)
{
//printf("CompileDeclaration::addMember(sc = %p)\n", sc);
//printf("CompileDeclaration::addMember(sc = %p, memnum = %d)\n", sc, memnum);
this->sd = sd;
if (memnum == 0)
{ /* No members yet, so parse the mixin now

View File

@@ -10,11 +10,7 @@
#include <stdio.h>
#include <assert.h>
#if _WIN32 || IN_GCC || IN_LLVM
#include "mem.h"
#else
#include "../root/mem.h"
#endif
#include "rmem.h"
#include "expression.h"
#include "mtype.h"

View File

@@ -13,7 +13,7 @@
#include <assert.h>
#include "root.h"
#include "mem.h"
#include "rmem.h"
#include "enum.h"
#include "init.h"
@@ -857,7 +857,9 @@ FuncDeclaration *ClassDeclaration::findFunc(Identifier *ident, TypeFunction *tf)
{
for (size_t i = 0; i < vtbl->dim; i++)
{
FuncDeclaration *fd = (FuncDeclaration *)vtbl->data[i];
FuncDeclaration *fd = ((Dsymbol*)vtbl->data[i])->isFuncDeclaration();
if (!fd)
continue; // the first entry might be a ClassInfo
//printf("\t[%d] = %s\n", i, fd->toChars());
if (ident == fd->ident &&

View File

@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2006 by Digital Mars
// Copyright (c) 1999-2008 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -31,7 +31,7 @@ int findCondition(Array *ids, Identifier *ident)
{
for (int i = 0; i < ids->dim; i++)
{
char *id = (char *)ids->data[i];
const char *id = (const char *)ids->data[i];
if (strcmp(id, ident->toChars()) == 0)
return TRUE;
@@ -75,7 +75,7 @@ void DebugCondition::addGlobalIdent(const char *ident)
{
if (!global.params.debugids)
global.params.debugids = new Array();
global.params.debugids->push((void*)ident);
global.params.debugids->push((void *)ident);
}
@@ -127,13 +127,17 @@ void VersionCondition::checkPredefined(Loc loc, const char *ident)
{
static const char* reserved[] =
{
"DigitalMars", "LLVM", "LDC", "LLVM64",
"X86", "X86_64", "PPC", "PPC64",
"DigitalMars", "X86", "X86_64",
"Windows", "Win32", "Win64",
"linux", "darwin", "Posix",
"linux", "Posix", "OSX", "FreeBSD",
"LittleEndian", "BigEndian",
"all",
"none",
// LDC
"LLVM", "LDC", "LLVM64",
"PPC", "PPC64",
"darwin",
};
for (unsigned i = 0; i < sizeof(reserved) / sizeof(reserved[0]); i++)
@@ -161,7 +165,7 @@ void VersionCondition::addPredefinedGlobalIdent(const char *ident)
{
if (!global.params.versionids)
global.params.versionids = new Array();
global.params.versionids->push((void*)ident);
global.params.versionids->push((void *)ident);
}

View File

@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2006 by Digital Mars
// Copyright (c) 1999-2008 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com

View File

@@ -17,7 +17,7 @@
#include <complex.h>
#endif
#include "mem.h"
#include "rmem.h"
#include "root.h"
#include "mtype.h"
@@ -1172,7 +1172,7 @@ Expression *Index(Type *type, Expression *e1, Expression *e2)
uinteger_t i = e2->toInteger();
if (i >= es1->len)
e1->error("string index %llu is out of bounds [0 .. %"PRIuSIZE"]", i, es1->len);
e1->error("string index %ju is out of bounds [0 .. %zu]", i, es1->len);
else
{ unsigned value = es1->charAt(i);
e = new IntegerExp(loc, value, type);
@@ -1184,8 +1184,7 @@ Expression *Index(Type *type, Expression *e1, Expression *e2)
uinteger_t i = e2->toInteger();
if (i >= length)
{
e2->error("array index %llu is out of bounds %s[0 .. %llu]", i, e1->toChars(), length);
{ e2->error("array index %ju is out of bounds %s[0 .. %ju]", i, e1->toChars(), length);
}
else if (e1->op == TOKarrayliteral && !e1->checkSideEffect(2))
{ ArrayLiteralExp *ale = (ArrayLiteralExp *)e1;
@@ -1200,8 +1199,7 @@ Expression *Index(Type *type, Expression *e1, Expression *e2)
if (e1->op == TOKarrayliteral && !e1->checkSideEffect(2))
{ ArrayLiteralExp *ale = (ArrayLiteralExp *)e1;
if (i >= ale->elements->dim)
{
e2->error("array index %llu is out of bounds %s[0 .. %u]", i, e1->toChars(), ale->elements->dim);
{ e2->error("array index %ju is out of bounds %s[0 .. %u]", i, e1->toChars(), ale->elements->dim);
}
else
{ e = (Expression *)ale->elements->data[i];
@@ -1251,7 +1249,7 @@ Expression *Slice(Type *type, Expression *e1, Expression *lwr, Expression *upr)
uinteger_t iupr = upr->toInteger();
if (iupr > es1->len || ilwr > iupr)
e1->error("string slice [%llu .. %llu] is out of bounds", ilwr, iupr);
e1->error("string slice [%ju .. %ju] is out of bounds", ilwr, iupr);
else
{ integer_t value;
void *s;
@@ -1278,7 +1276,7 @@ Expression *Slice(Type *type, Expression *e1, Expression *lwr, Expression *upr)
uinteger_t iupr = upr->toInteger();
if (iupr > es1->elements->dim || ilwr > iupr)
e1->error("array slice [%llu .. %llu] is out of bounds", ilwr, iupr);
e1->error("array slice [%ju .. %ju] is out of bounds", ilwr, iupr);
else
{
Expressions *elements = new Expressions();

View File

@@ -14,7 +14,7 @@
#include <assert.h>
#include "dchar.h"
#include "mem.h"
#include "rmem.h"
#if M_UNICODE

View File

@@ -750,7 +750,7 @@ void VarDeclaration::semantic(Scope *sc)
{ Argument *arg = Argument::getNth(tt->arguments, i);
OutBuffer buf;
buf.printf("_%s_field_%"PRIuSIZE, ident->toChars(), i);
buf.printf("_%s_field_%zu", ident->toChars(), i);
buf.writeByte(0);
char *name = (char *)buf.extractData();
Identifier *id = new Identifier(name, TOKidentifier);

View File

@@ -16,17 +16,7 @@
#include <ctype.h>
#include <assert.h>
#if IN_GCC || IN_LLVM
#include "mem.h"
#else
#if _WIN32
#include "..\root\mem.h"
#elif POSIX
#include "../root/mem.h"
#else
#error "fix this"
#endif
#endif
#include "rmem.h"
#include "root.h"

View File

@@ -12,7 +12,7 @@
#include <string.h>
#include <assert.h>
#include "mem.h"
#include "rmem.h"
#include "mars.h"
#include "dsymbol.h"

View File

@@ -1,5 +1,5 @@
// Copyright (c) 1999-2006 by Digital Mars
// Copyright (c) 1999-2009 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -19,7 +19,7 @@
struct NameId
{
char *name;
const char *name;
unsigned short value;
};

View File

@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2008 by Digital Mars
// Copyright (c) 1999-2009 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -11,12 +11,12 @@
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
#include <assert.h>
#if _MSC_VER
#include <complex>
#else
#endif
#include <math.h>
#if _WIN32 && __DMC__
extern "C" char * __cdecl __locale_decpoint;
@@ -43,13 +43,7 @@ int isnan(double);
#define integer_t dmd_integer_t
#endif
#if IN_GCC || IN_LLVM
#include "mem.h"
#elif _WIN32
#include "..\root\mem.h"
#elif POSIX
#include "../root/mem.h"
#endif
#include "rmem.h"
//#include "port.h"
#include "mtype.h"
@@ -560,7 +554,7 @@ void functionArguments(Loc loc, Scope *sc, TypeFunction *tf, Expressions *argume
size_t nparams = Argument::dim(tf->parameters);
if (nargs > nparams && tf->varargs == 0)
error(loc, "expected %"PRIuSIZE" arguments, not %"PRIuSIZE, nparams, nargs);
error(loc, "expected %zu arguments, not %zu", nparams, nargs);
n = (nargs > nparams) ? nargs : nparams; // n = max(nargs, nparams)
@@ -585,7 +579,7 @@ void functionArguments(Loc loc, Scope *sc, TypeFunction *tf, Expressions *argume
{
if (tf->varargs == 2 && i + 1 == nparams)
goto L2;
error(loc, "expected %"PRIuSIZE" arguments, not %"PRIuSIZE, nparams, nargs);
error(loc, "expected %zu arguments, not %zu", nparams, nargs);
break;
}
arg = p->defaultArg;
@@ -607,7 +601,7 @@ void functionArguments(Loc loc, Scope *sc, TypeFunction *tf, Expressions *argume
if (arg->implicitConvTo(p->type))
{
if (nargs != nparams)
error(loc, "expected %"PRIuSIZE" arguments, not %"PRIuSIZE, nparams, nargs);
error(loc, "expected %zu arguments, not %zu", nparams, nargs);
goto L1;
}
L2:
@@ -965,6 +959,18 @@ void Expression::error(const char *format, ...)
va_end( ap );
}
void Expression::warning(const char *format, ...)
{
if (global.params.warnings && !global.gag)
{
fprintf(stdmsg, "warning - ");
va_list ap;
va_start(ap, format);
::warning(loc, format, ap);
va_end( ap );
}
}
void Expression::rvalue()
{
if (type && type->toBasetype()->ty == Tvoid)
@@ -1319,7 +1325,8 @@ char *IntegerExp::toChars()
return Expression::toChars();
#else
static char buffer[sizeof(value) * 3 + 1];
sprintf(buffer, "%lld", value);
sprintf(buffer, "%jd", value);
return buffer;
#endif
}
@@ -1501,11 +1508,11 @@ void IntegerExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
break;
case Tint64:
buf->printf("%lldL", v);
buf->printf("%jdL", v);
break;
case Tuns64:
buf->printf("%lluLU", v);
buf->printf("%juLU", v);
break;
case Tbit:
@@ -1534,17 +1541,17 @@ void IntegerExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
}
}
else if (v & 0x8000000000000000LL)
buf->printf("0x%llx", v);
buf->printf("0x%jx", v);
else
buf->printf("%lld", v);
buf->printf("%jd", v);
}
void IntegerExp::toMangleBuffer(OutBuffer *buf)
{
if ((sinteger_t)value < 0)
buf->printf("N%lld", -value);
buf->printf("N%jd", -value);
else
buf->printf("%lld", value);
buf->printf("%jd", value);
}
/******************************** RealExp **************************/
@@ -1617,8 +1624,12 @@ complex_t RealExp::toComplex()
int RealEquals(real_t x1, real_t x2)
{
#if __APPLE__
return (__inline_isnan(x1) && __inline_isnan(x2)) ||
#else
return // special case nans
(isnan(x1) && isnan(x2)) ||
#endif
// and zero, in order to distinguish +0 from -0
(x1 == 0 && x2 == 0 && 1./x1 == 1./x2) ||
// otherwise just compare
@@ -1723,7 +1734,11 @@ void realToMangleBuffer(OutBuffer *buf, real_t value)
* 0X1.9P+2 => 19P2
*/
#if __APPLE__
if (__inline_isnan(value))
#else
if (isnan(value))
#endif
buf->writestring("NAN"); // no -NAN bugs
else
{
@@ -3859,9 +3874,7 @@ Expression *SymOffExp::semantic(Scope *sc)
type = var->type->pointerTo();
VarDeclaration *v = var->isVarDeclaration();
if (v)
{
v->checkNestedReference(sc, loc);
}
v->checkNestedReference(sc, loc);
return this;
}
@@ -7229,13 +7242,16 @@ Expression *SliceExp::semantic(Scope *sc)
}
else
{
error("string slice [%llu .. %llu] is out of bounds", i1, i2);
error("string slice [%ju .. %ju] is out of bounds", i1, i2);
e = e1;
}
return e;
}
type = t->nextOf()->arrayOf();
if (t->ty == Tarray)
type = e1->type;
else
type = t->nextOf()->arrayOf();
return e;
Lerror:
@@ -7610,9 +7626,9 @@ Expression *IndexExp::semantic(Scope *sc)
}
else
{
error("array index [%llu] is outside array bounds [0 .. %"PRIuSIZE"]",
index, length);
e = e1;
error("array index [%ju] is outside array bounds [0 .. %zu]",
index, length);
e = e1;
}
break;
}

View File

@@ -78,6 +78,7 @@ void argsToCBuffer(OutBuffer *buf, Expressions *arguments, HdrGenState *hgs);
void expandTuples(Expressions *exps);
FuncDeclaration *hasThis(Scope *sc);
Expression *fromConstInitializer(int result, Expression *e);
int arrayExpressionCanThrow(Expressions *exps);
struct Expression : Object
{
@@ -97,6 +98,7 @@ struct Expression : Object
char *toChars();
virtual void dump(int indent);
void error(const char *format, ...);
void warning(const char *format, ...);
virtual void rvalue();
static Expression *combine(Expression *e1, Expression *e2);

View File

@@ -337,8 +337,8 @@ void FuncDeclaration::semantic(Scope *sc)
error("cannot override final function %s", fdv->toPrettyChars());
#if DMDV2
if (!isOverride() && global.params.warnings)
warning("%s: overrides base class function %s, but is not marked with 'override'", locToChars() fdv->toPrettyChars());
if (!isOverride())
warning(loc, "overrides base class function %s, but is not marked with 'override'", fdv->toPrettyChars());
#endif
if (fdv->toParent() == parent)
@@ -1083,9 +1083,7 @@ void FuncDeclaration::semantic3(Scope *sc)
if (offend)
{ Expression *e;
if (global.params.warnings)
{ warning("%s: no return at end of function", locToChars());
}
warning(loc, "no return at end of function");
if (global.params.useAssert &&
!global.params.useInline)
@@ -1095,7 +1093,7 @@ void FuncDeclaration::semantic3(Scope *sc)
e = new AssertExp(
endloc,
new IntegerExp(0),
new StringExp(loc, "missing return expression")
new StringExp(loc, (char *)"missing return expression")
);
}
else
@@ -2165,7 +2163,7 @@ FuncLiteralDeclaration::FuncLiteralDeclaration(Loc loc, Loc endloc, Type *type,
enum TOK tok, ForeachStatement *fes)
: FuncDeclaration(loc, endloc, NULL, STCundefined, type)
{
char *id;
const char *id;
if (fes)
id = "__foreachbody";
@@ -2310,7 +2308,7 @@ const char *CtorDeclaration::kind()
char *CtorDeclaration::toChars()
{
return "this";
return (char *)"this";
}
int CtorDeclaration::isVirtual()
@@ -2652,7 +2650,7 @@ void InvariantDeclaration::semantic(Scope *sc)
ad = parent->isAggregateDeclaration();
if (!ad)
{
error("invariants only are for struct/union/class definitions");
error("invariants are only for struct/union/class definitions");
return;
}
else if (ad->inv && ad->inv != this)

View File

@@ -24,17 +24,7 @@
#include <complex.h>
#endif
#if IN_GCC || IN_LLVM
#include "mem.h"
#else
#if _WIN32
#include "..\root\mem.h"
#elif POSIX
#include "../root/mem.h"
#else
#error "fix this"
#endif
#endif
#include "rmem.h"
#include "id.h"
#include "init.h"

View File

@@ -93,7 +93,7 @@ Identifier *Identifier::generateId(const char *prefix, size_t i)
{ OutBuffer buf;
buf.writestring(prefix);
buf.printf("%"PRIuSIZE, i);
buf.printf("%zu", i);
char *id = buf.toChars();
buf.data = NULL;

View File

@@ -1,302 +0,0 @@
// Copyright (c) 1999-2006 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#if (defined (__SVR4) && defined (__sun))
#include <alloca.h>
#endif
#include "root.h"
#include "mem.h"
#ifdef __MINGW32__
#include <malloc.h>
#endif
#define LOG 0
char *skipspace(const char *p);
#if __GNUC__
char *strupr(char *s)
{
char *t = s;
while (*s)
{
*s = toupper(*s);
s++;
}
return t;
}
#endif /* unix */
/*****************************
* Read and analyze .ini file.
* Input:
* argv0 program name (argv[0])
* inifile .ini file name
*/
void inifile(char *argv0, const char *inifile)
{
char *path; // need path for @P macro
const char *filename;
OutBuffer buf;
int i;
int k;
int envsection = 0;
#if LOG
printf("inifile(argv0 = '%s', inifile = '%s')\n", argv0, inifile);
#endif
if (FileName::absolute(inifile))
{
filename = inifile;
}
else
{
/* Look for inifile in the following sequence of places:
* o current directory
* o home directory
* o directory off of argv0
* o /etc/
*/
if (FileName::exists(inifile))
{
filename = inifile;
}
else
{
filename = FileName::combine(getenv("HOME"), inifile);
if (!FileName::exists(filename))
{
filename = FileName::replaceName(argv0, (char*)inifile);
if (!FileName::exists(filename))
{
#if POSIX
#if 0
#if __GLIBC__ // This fix by Thomas Kuehne
/* argv0 might be a symbolic link,
* so try again looking past it to the real path
*/
char* real_argv0 = realpath(argv0, NULL);
if (real_argv0)
{
filename = FileName::replaceName(real_argv0, inifile);
free(real_argv0);
if (FileName::exists(filename))
goto Ldone;
}
#else
#error use of glibc non-standard extension realpath(char*, NULL)
#endif
#endif
// old way; problem is that argv0 might not be on the PATH at all
// and some other instance might be found
// Search PATH for argv0
const char *p = getenv("PATH");
Array *paths = FileName::splitPath(p);
filename = FileName::searchPath(paths, argv0, 0);
if (!filename)
goto Letc; // argv0 not found on path
filename = FileName::replaceName((char*)filename, (char*)inifile);
if (FileName::exists(filename))
goto Ldone;
#endif
// Search /etc/ for inifile
Letc:
filename = FileName::combine("/etc/", inifile);
Ldone:
;
}
}
}
}
path = FileName::path(filename);
#if LOG
printf("\tpath = '%s', filename = '%s'\n", path, filename);
#endif
File file((char*)filename);
if (file.read())
return; // error reading file
// Parse into lines
int eof = 0;
for (i = 0; i < file.len && !eof; i++)
{
int linestart = i;
for (; i < file.len; i++)
{
switch (file.buffer[i])
{
case '\r':
break;
case '\n':
// Skip if it was preceded by '\r'
if (i && file.buffer[i - 1] == '\r')
goto Lskip;
break;
case 0:
case 0x1A:
eof = 1;
break;
default:
continue;
}
break;
}
// The line is file.buffer[linestart..i]
char *line;
int len;
char *p;
char *pn;
line = (char *)&file.buffer[linestart];
len = i - linestart;
buf.reset();
// First, expand the macros.
// Macros are bracketed by % characters.
for (k = 0; k < len; k++)
{
if (line[k] == '%')
{
int j;
for (j = k + 1; j < len; j++)
{
if (line[j] == '%')
{
if (j - k == 3 && memicmp(&line[k + 1], "@P", 2) == 0)
{
// %@P% is special meaning the path to the .ini file
p = path;
if (!*p)
p = ".";
}
else
{ int len = j - k;
char tmp[10]; // big enough most of the time
if (len <= sizeof(tmp))
p = tmp;
else
p = (char *)alloca(len);
len--;
memcpy(p, &line[k + 1], len);
p[len] = 0;
strupr(p);
p = getenv(p);
if (!p)
p = "";
}
buf.writestring(p);
k = j;
goto L1;
}
}
}
buf.writeByte(line[k]);
L1:
;
}
// Remove trailing spaces
while (buf.offset && isspace(buf.data[buf.offset - 1]))
buf.offset--;
p = buf.toChars();
// The expanded line is in p.
// Now parse it for meaning.
p = skipspace(p);
switch (*p)
{
case ';': // comment
case 0: // blank
break;
case '[': // look for [Environment]
p = skipspace(p + 1);
for (pn = p; isalnum(*pn); pn++)
;
if (pn - p == 11 &&
memicmp(p, "Environment", 11) == 0 &&
*skipspace(pn) == ']'
)
envsection = 1;
else
envsection = 0;
break;
default:
if (envsection)
{
pn = p;
// Convert name to upper case;
// remove spaces bracketing =
for (p = pn; *p; p++)
{ if (islower(*p))
*p &= ~0x20;
else if (isspace(*p))
memmove(p, p + 1, strlen(p));
else if (*p == '=')
{
p++;
while (isspace(*p))
memmove(p, p + 1, strlen(p));
break;
}
}
putenv(strdup(pn));
#if LOG
printf("\tputenv('%s')\n", pn);
//printf("getenv(\"TEST\") = '%s'\n",getenv("TEST"));
#endif
}
break;
}
Lskip:
;
}
}
/********************
* Skip spaces.
*/
char *skipspace(const char *p)
{
while (isspace(*p))
p++;
return (char *)p;
}

View File

@@ -12,7 +12,7 @@
#include <stdlib.h>
#include <assert.h>
#include "mem.h"
#include "rmem.h"
#include "statement.h"
#include "expression.h"
@@ -80,8 +80,8 @@ Expression *FuncDeclaration::interpret(InterState *istate, Expressions *argument
if (semanticRun == 0 && scope)
{
semantic3(scope);
if (global.errors) // if errors compiling this function
return NULL;
if (global.errors) // if errors compiling this function
return NULL;
}
if (semanticRun < 2)
return NULL;

View File

@@ -20,28 +20,21 @@
#include <wchar.h>
#include <stdlib.h>
#include <assert.h>
#include <sys/time.h>
#include <math.h>
#if _MSC_VER
#include <time.h>
#else
#include <sys/time.h>
#endif
#ifdef IN_GCC
#include <time.h>
#include "mem.h"
#else
#if __GNUC__
#elif __GNUC__
#include <time.h>
#endif
#if IN_LLVM
#include "mem.h"
#elif _WIN32
#include "..\root\mem.h"
#else
#include "../root/mem.h"
#endif
#endif
#include "rmem.h"
#include "stringtable.h"
@@ -56,6 +49,10 @@
extern "C" char * __cdecl __locale_decpoint;
#endif
#if _MSC_VER // workaround VC++ bug, labels and types should be in separate namespaces
#define Lstring Lstr
#endif
extern int HtmlNamedEntity(unsigned char *p, int length);
#define LS 0x2028 // UTF line separator
@@ -140,11 +137,11 @@ const char *Token::toChars()
break;
case TOKint64v:
sprintf(buffer,"%lldL",(long long)int64value);
sprintf(buffer,"%jdL",int64value);
break;
case TOKuns64v:
sprintf(buffer,"%lluUL",(unsigned long long)uns64value);
sprintf(buffer,"%juUL",uns64value);
break;
#if IN_GCC

View File

@@ -11,7 +11,7 @@
#include <stdlib.h>
#include "dchar.h"
#include "mem.h"
#include "rmem.h"
#include "lstring.h"
Lstring Lstring::zero = LSTRING_EMPTY();

View File

@@ -16,19 +16,9 @@
#include <ctype.h>
#include <assert.h>
#if IN_GCC || IN_LLVM
#include "mem.h"
#else
#if _WIN32
#include "..\root\mem.h"
#elif POSIX
#include "../root/mem.h"
#else
#error "fix this"
#endif
#endif
#include "rmem.h"
#include "root.h"
#include "macro.h"
#define isidstart(c) (isalpha(c) || (c) == '_')

202
dmd/man.c
View File

@@ -1,100 +1,102 @@
// Compiler implementation of the D programming language
// Copyright (c) 2008-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 <string.h>
#include <stdlib.h>
#include <assert.h>
#if _WIN32
#include <windows.h>
#pragma comment(lib,"shell32.lib")
void browse(const char *url)
{
ShellExecute(NULL, "open", url, NULL, NULL, SW_SHOWNORMAL);
}
#endif
#if linux
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
void browse(const char *url)
{
pid_t childpid;
const char *args[3];
char *browser = getenv("BROWSER");
if (browser)
browser = strdup(browser);
else
browser = "firefox";
args[0] = browser;
args[1] = url;
args[2] = NULL;
childpid = fork();
if (childpid == 0)
{
execvp(args[0], (char**)args);
perror(args[0]); // failed to execute
return;
}
}
#endif
#if __APPLE__
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
void browse(const char *url)
{
pid_t childpid;
const char *args[5];
char *browser = getenv("BROWSER");
if (browser)
{ browser = strdup(browser);
args[0] = browser;
args[1] = url;
args[2] = NULL;
}
else
{
//browser = "/Applications/Safari.app/Contents/MacOS/Safari";
args[0] = "open";
args[1] = "-a";
args[2] = "/Applications/Safari.app";
args[3] = url;
args[4] = NULL;
}
childpid = fork();
if (childpid == 0)
{
execvp(args[0], (char**)args);
perror(args[0]); // failed to execute
return;
}
}
#endif
// Compiler implementation of the D programming language
// Copyright (c) 2008-2009 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 <string.h>
#include <stdlib.h>
#include <assert.h>
#if _WIN32
#include <windows.h>
#pragma comment(lib,"shell32.lib")
void browse(const char *url)
{
ShellExecute(NULL, "open", url, NULL, NULL, SW_SHOWNORMAL);
}
#endif
#if linux
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
void browse(const char *url)
{
pid_t childpid;
const char *args[3];
char *browser = getenv("BROWSER");
if (browser)
browser = strdup(browser);
else
browser = "x-www-browser";
args[0] = browser;
args[1] = url;
args[2] = NULL;
childpid = fork();
if (childpid == 0)
{
execvp(args[0], (char**)args);
perror(args[0]); // failed to execute
return;
}
}
#endif
#if __APPLE__
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
void browse(const char *url)
{
pid_t childpid;
const char *args[5];
char *browser = getenv("BROWSER");
if (browser)
{ browser = strdup(browser);
args[0] = browser;
args[1] = url;
args[2] = NULL;
}
else
{
//browser = "/Applications/Safari.app/Contents/MacOS/Safari";
args[0] = "open";
args[1] = "-a";
args[2] = "/Applications/Safari.app";
args[3] = url;
args[4] = NULL;
}
childpid = fork();
if (childpid == 0)
{
execvp(args[0], (char**)args);
perror(args[0]); // failed to execute
return;
}
}
#endif
#if __FreeBSD__
#endif

View File

@@ -24,6 +24,10 @@
#include "id.h"
#include "module.h"
#if TARGET_LINUX || TARGET_OSX
char *cpp_mangle(Dsymbol *s);
#endif
char *mangle(Declaration *sthis)
{
OutBuffer buf;
@@ -110,9 +114,16 @@ char *Declaration::mangle()
case LINKc:
case LINKwindows:
case LINKpascal:
case LINKcpp:
return ident->toChars();
case LINKcpp:
#if V2 && (TARGET_LINUX || TARGET_OSX)
return cpp_mangle(this);
#else
// Windows C++ mangling is done by C++ back end
return ident->toChars();
#endif
case LINKdefault:
error("forward declaration");
return ident->toChars();
@@ -142,7 +153,7 @@ char *FuncDeclaration::mangle()
#endif
{
if (isMain())
return "_Dmain";
return (char *)"_Dmain";
if (isWinMain() || isDllMain())
return ident->toChars();
@@ -216,7 +227,7 @@ char *TemplateInstance::mangle()
p += 2;
buf.writestring(p);
}
buf.printf("%"PRIuSIZE"%s", strlen(id), id);
buf.printf("%zu%s", strlen(id), id);
id = buf.toChars();
buf.data = NULL;
//printf("TemplateInstance::mangle() %s = %s\n", toChars(), id);
@@ -243,7 +254,7 @@ char *TemplateMixin::mangle()
p += 2;
buf.writestring(p);
}
buf.printf("%"PRIuSIZE"%s", strlen(id), id);
buf.printf("%zu%s", strlen(id), id);
id = buf.toChars();
buf.data = NULL;
//printf("TemplateMixin::mangle() %s = %s\n", toChars(), id);
@@ -269,7 +280,7 @@ char *Dsymbol::mangle()
p += 2;
buf.writestring(p);
}
buf.printf("%"PRIuSIZE"%s", strlen(id), id);
buf.printf("%zu%s", strlen(id), id);
id = buf.toChars();
buf.data = NULL;
//printf("Dsymbol::mangle() %s = %s\n", toChars(), id);

View File

@@ -25,7 +25,7 @@
#include <windows.h>
#endif
#include "mem.h"
#include "rmem.h"
#include "root.h"
#include "mars.h"
@@ -105,6 +105,20 @@ void error(Loc loc, const char *format, ...)
va_end( ap );
}
void warning(Loc loc, const char *format, ...)
{
if (global.params.warnings && !global.gag)
{
fprintf(stdmsg, "warning - ");
va_list ap;
va_start(ap, format);
char* p = loc.toChars();
fprintf(stdmsg, "Warning: %s:", p?p:"");
vfprintf(stdmsg, format, ap);
va_end( ap );
}
}
void verror(Loc loc, const char *format, va_list ap)
{
if (!global.gag)

View File

@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2007 by Digital Mars
// Copyright (c) 1999-2009 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -13,7 +13,49 @@
#ifdef __DMC__
#pragma once
#endif /* __DMC__ */
#endif
/*
It is very important to use version control macros correctly - the
idea is that host and target are independent. If these are done
correctly, cross compilers can be built.
The host compiler and host operating system are also different,
and are predefined by the host compiler. The ones used in
dmd are:
Macros defined by the compiler, not the code:
Compiler:
__DMC__ Digital Mars compiler
_MSC_VER Microsoft compiler
__GNUC__ Gnu compiler
Host operating system:
_WIN32 Microsoft NT, Windows 95, Windows 98, Win32s,
Windows 2000, Win XP, Vista
_WIN64 Windows for AMD64
linux Linux
__APPLE__ Mac OSX
For the target systems, there are the target operating system and
the target object file format:
Target operating system:
TARGET_WINDOS Covers 32 bit windows and 64 bit windows
TARGET_LINUX Covers 32 and 64 bit linux
TARGET_OSX Covers 32 and 64 bit Mac OSX
It is expected that the compiler for each platform will be able
to generate 32 and 64 bit code from the same compiler binary.
Target object module format:
OMFOBJ Intel Object Module Format, used on Windows
ELFOBJ Elf Object Module Format, used on linux
MACHOBJ Mach-O Object Module Format, used on Mac OSX
There are currently no macros for byte endianness order.
*/
#include <stdint.h>
#include <stdarg.h>
@@ -35,6 +77,29 @@
#define DMDV2 0 // Version 2.0 features
#define BREAKABI 1 // 0 if not ready to break the ABI just yet
#define STRUCTTHISREF V2 // if 'this' for struct is a reference, not a pointer
/* Other targets are TARGET_LINUX and TARGET_OSX, which are
* set on the command line via the compiler makefile.
*/
#if _WIN32
#define TARGET_WINDOS 1 // Windows dmd generates Windows targets
#define OMFOBJ 1
#endif
#if TARGET_LINUX
#ifndef ELFOBJ
#define ELFOBJ 1
#endif
#endif
#if TARGET_OSX
#ifndef MACHOBJ
#define MACHOBJ 1
#endif
#endif
struct Array;
@@ -90,6 +155,7 @@ struct Param
bool useInline; // inline expand functions
bool warnings; // enable warnings
char Dversion; // D version number
char safe; // enforce safe memory model
char *argv0; // program name
Array *imppath; // array of char*'s of where to look for import modules
@@ -117,7 +183,7 @@ struct Param
Array *defaultlibnames; // default libraries for non-debug builds
Array *debuglibnames; // default libraries for debug builds
char *xmlname; // filename for XML output
const char *xmlname; // filename for XML output
// Hidden debug switches
bool debuga;
@@ -156,24 +222,25 @@ struct Param
struct Global
{
char *mars_ext;
char *sym_ext;
char *obj_ext;
const char *mars_ext;
const char *sym_ext;
const char *obj_ext;
#if _WIN32
char *obj_ext_alt;
#endif
char *ll_ext;
char *bc_ext;
char *s_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;
const char *lib_ext;
const char *doc_ext; // for Ddoc generated files
const char *ddoc_ext; // for Ddoc macro include files
const char *hdr_ext; // for D 'header' import files
const char *copyright;
const 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;
const char *version;
char *ldc_version;
char *llvm_version;
@@ -251,19 +318,6 @@ typedef long double real_t;
#include "d-gcc-complex_t.h"
#endif
// taken from GDC
// for handling printf incompatibilities
#if __MSVCRT__
#define PRIuSIZE "Iu"
#define PRIxSIZE "Ix"
#elif __MINGW32__
#define PRIuSIZE "u"
#define PRIxSIZE "x"
#else
#define PRIuSIZE "zu"
#define PRIxSIZE "zx"
#endif
struct Module;
//typedef unsigned Loc; // file location
@@ -333,6 +387,7 @@ enum MATCH
MATCHexact // exact match
};
void warning(Loc loc, const char *format, ...);
void error(Loc loc, const char *format, ...);
void verror(Loc loc, const char *format, va_list);
void fatal();

View File

@@ -7,7 +7,7 @@
#include <cstring>
#include <cassert>
#include "mem.h"
#include "rmem.h"
#if USE_BOEHM_GC
// I needed to perfix the dir after upgrading to gc 7.0

View File

@@ -24,7 +24,7 @@
#include "gdc_alloca.h"
#endif
#include "mem.h"
#include "rmem.h"
#include "mars.h"
#include "module.h"
@@ -88,6 +88,7 @@ Module::Module(char *filename, Identifier *ident, int doDocComment, int doHdrGen
#ifdef IN_GCC
strictlyneedmoduleinfo = 0;
#endif
selfimports = 0;
insearch = 0;
searchCacheIdent = NULL;
searchCacheSymbol = NULL;
@@ -145,9 +146,9 @@ Module::Module(char *filename, Identifier *ident, int doDocComment, int doHdrGen
this->doHdrGen = doHdrGen;
}
File* Module::buildFilePath(char* forcename, char* path, char* ext)
File* Module::buildFilePath(const char* forcename, const char* path, const char* ext)
{
char *argobj;
const char *argobj;
if (forcename)
argobj = forcename;
else
@@ -160,9 +161,9 @@ File* Module::buildFilePath(char* forcename, char* path, char* ext)
if (fqnNames)
{
if(md)
argobj = FileName::replaceName(argobj, md->toChars());
argobj = FileName::replaceName((char*)argobj, md->toChars());
else
argobj = FileName::replaceName(argobj, toChars());
argobj = FileName::replaceName((char*)argobj, toChars());
// add ext, otherwise forceExt will make nested.module into nested.bc
size_t len = strlen(argobj);
@@ -926,7 +927,6 @@ int Module::imports(Module *m)
{
mi->insearch = 1;
int r = mi->imports(m);
mi->insearch = 0;
if (r)
return r;
}
@@ -934,6 +934,33 @@ int Module::imports(Module *m)
return FALSE;
}
/*************************************
* Return !=0 if module imports itself.
*/
int Module::selfImports()
{
//printf("Module::selfImports() %s\n", toChars());
if (!selfimports)
{
for (int i = 0; i < amodules.dim; i++)
{ Module *mi = (Module *)amodules.data[i];
//printf("\t[%d] %s\n", i, mi->toChars());
mi->insearch = 0;
}
selfimports = imports(this) + 1;
for (int i = 0; i < amodules.dim; i++)
{ Module *mi = (Module *)amodules.data[i];
//printf("\t[%d] %s\n", i, mi->toChars());
mi->insearch = 0;
}
}
return selfimports - 1;
}
/* =========================== ModuleDeclaration ===================== */
ModuleDeclaration::ModuleDeclaration(Array *packages, Identifier *id)

View File

@@ -80,6 +80,9 @@ struct Module : Package
int strictlyneedmoduleinfo;
#endif
int selfimports; // 0: don't know, 1: does not, 2: does
int selfImports(); // returns !=0 if module imports itself
int insearch;
Identifier *searchCacheIdent;
Dsymbol *searchCacheSymbol; // cached value of search
@@ -173,7 +176,7 @@ struct Module : Package
// LDC
llvm::Module* genLLVMModule(int multiobj);
void buildTargetFiles();
File* buildFilePath(char* forcename, char* path, char* ext);
File* buildFilePath(const char* forcename, const char* path, const char* ext);
Module *isModule() { return this; }
bool llvmForceLogging;

View File

@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2008 by Digital Mars
// Copyright (c) 1999-2009 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -49,7 +49,7 @@ static double zero = 0;
static double zero = 0;
#endif
#include "mem.h"
#include "rmem.h"
#include "dsymbol.h"
#include "mtype.h"
@@ -213,6 +213,7 @@ void Type::init()
mangleChar[Ttypeof] = '@';
mangleChar[Ttuple] = 'B';
mangleChar[Tslice] = '@';
mangleChar[Treturn] = '@';
for (i = 0; i < TMAX; i++)
{ if (!mangleChar[i])
@@ -709,6 +710,18 @@ void Type::error(Loc loc, const char *format, ...)
va_end( ap );
}
void Type::warning(Loc loc, const char *format, ...)
{
if (global.params.warnings && !global.gag)
{
fprintf(stdmsg, "warning - ");
va_list ap;
va_start(ap, format);
::verror(loc, format, ap);
va_end( ap );
}
}
Identifier *Type::getTypeInfoIdent(int internal)
{
// _init_10TypeInfo_%s
@@ -721,7 +734,7 @@ Identifier *Type::getTypeInfoIdent(int internal)
if (internal)
{ buf.writeByte(mangleChar[ty]);
if (ty == Tarray)
buf.writeByte(mangleChar[next->ty]);
buf.writeByte(mangleChar[((TypeArray *)this)->next->ty]);
}
else
toDecoBuffer(&buf);
@@ -746,9 +759,8 @@ TypeBasic *Type::isTypeBasic()
void Type::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps)
{
Type *t;
t = semantic(loc, sc);
//printf("Type::resolve() %s, %d\n", toChars(), ty);
Type *t = semantic(loc, sc);
*pt = t;
*pe = NULL;
*ps = NULL;
@@ -1873,7 +1885,7 @@ Type *TypeSArray::semantic(Loc loc, Scope *sc)
dim = semanticLength(sc, tbn, dim);
dim = dim->optimize(WANTvalue | WANTinterpret);
if (sc->parameterSpecialization && dim->op == TOKvar &&
if (sc && sc->parameterSpecialization && dim->op == TOKvar &&
((VarExp *)dim)->var->storage_class & STCtemplateparameter)
{
/* It could be a template parameter N which has no value yet:
@@ -1909,7 +1921,7 @@ Type *TypeSArray::semantic(Loc loc, Scope *sc)
if (n && n2 / n != d2)
{
Loverflow:
error(loc, "index %lld overflow for static array", d1);
error(loc, "index %jd overflow for static array", d1);
dim = new IntegerExp(0, 1, tsize_t);
}
}
@@ -1923,7 +1935,7 @@ Type *TypeSArray::semantic(Loc loc, Scope *sc)
uinteger_t d = dim->toUInteger();
if (d >= tt->arguments->dim)
{ error(loc, "tuple index %llu exceeds %u", d, tt->arguments->dim);
{ error(loc, "tuple index %ju exceeds %u", d, tt->arguments->dim);
return Type::terror;
}
Argument *arg = (Argument *)tt->arguments->data[(size_t)d];
@@ -1944,7 +1956,7 @@ void TypeSArray::toDecoBuffer(OutBuffer *buf)
{
buf->writeByte(mangleChar[ty]);
if (dim)
buf->printf("%llu", dim->toInteger());
buf->printf("%ju", dim->toInteger());
if (next)
next->toDecoBuffer(buf);
}
@@ -2636,8 +2648,7 @@ Expression *TypeReference::defaultInit(Loc loc)
#if LOGDEFAULTINIT
printf("TypeReference::defaultInit() '%s'\n", toChars());
#endif
Expression *e;
e = new NullExp(loc);
Expression *e = new NullExp(loc);
e->type = this;
return e;
}
@@ -3719,6 +3730,7 @@ TypeTypeof::TypeTypeof(Loc loc, Expression *exp)
Type *TypeTypeof::syntaxCopy()
{
//printf("TypeTypeof::syntaxCopy() %s\n", toChars());
TypeTypeof *t;
t = new TypeTypeof(loc, exp->syntaxCopy());
@@ -3954,7 +3966,16 @@ Expression *TypeEnum::dotExp(Scope *sc, Expression *e, Identifier *ident)
s = sym->symtab->lookup(ident);
if (!s)
{
return getProperty(e->loc, ident);
if (ident == Id::max ||
ident == Id::min ||
ident == Id::init ||
ident == Id::stringof ||
!sym->memtype
)
{
return getProperty(e->loc, ident);
}
return sym->memtype->dotExp(sc, e, ident);
}
m = s->isEnumMember();
em = m->value->copy();
@@ -5038,6 +5059,7 @@ TypeTuple::TypeTuple(Arguments *arguments)
{
//printf("TypeTuple(this = %p)\n", this);
this->arguments = arguments;
//printf("TypeTuple() %s\n", toChars());
#ifdef DEBUG
if (arguments)
{
@@ -5083,6 +5105,7 @@ Type *TypeTuple::syntaxCopy()
Type *TypeTuple::semantic(Loc loc, Scope *sc)
{
//printf("TypeTuple::semantic(this = %p)\n", this);
//printf("TypeTuple::semantic() %s\n", toChars());
if (!deco)
deco = merge()->deco;
@@ -5206,7 +5229,7 @@ Type *TypeSlice::semantic(Loc loc, Scope *sc)
uinteger_t i2 = upr->toUInteger();
if (!(i1 <= i2 && i2 <= tt->arguments->dim))
{ error(loc, "slice [%llu..%llu] is out of range of [0..%u]", i1, i2, tt->arguments->dim);
{ error(loc, "slice [%ju..%ju] is out of range of [0..%u]", i1, i2, tt->arguments->dim);
return Type::terror;
}
@@ -5251,7 +5274,7 @@ void TypeSlice::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol
sc = sc->pop();
if (!(i1 <= i2 && i2 <= td->objects->dim))
{ error(loc, "slice [%llu..%llu] is out of range of [0..%u]", i1, i2, td->objects->dim);
{ error(loc, "slice [%ju..%ju] is out of range of [0..%u]", i1, i2, td->objects->dim);
goto Ldefault;
}

View File

@@ -37,10 +37,12 @@ struct TypedefDeclaration;
struct TypeInfoDeclaration;
struct Dsymbol;
struct TemplateInstance;
struct CppMangleState;
enum LINK;
struct TypeBasic;
struct HdrGenState;
struct Argument;
// Back end
#if IN_GCC
@@ -99,7 +101,7 @@ enum TY
Ttypeof,
Ttuple,
Tslice,
Treturn,
TMAX
};
@@ -108,13 +110,16 @@ enum TY
extern int Tsize_t;
extern int Tptrdiff_t;
struct Type : Object
{
TY ty;
unsigned char mod; // modifiers (MODconst, MODinvariant)
unsigned char mod; // modifiers MODxxxx
/* pick this order of numbers so switch statements work better
*/
#define MODconst 1 // type is const
#define MODinvariant 2 // type is invariant
Type *next;
#define MODinvariant 4 // type is invariant
#define MODshared 2 // type is shared
char *deco;
Type *pto; // merged pointer to this type
Type *rto; // reference to this type
@@ -242,9 +247,11 @@ struct Type : Object
virtual Type *reliesOnTident();
virtual Expression *toExpression();
virtual int hasPointers();
Type *next;
Type *nextOf() { return next; }
static void error(Loc loc, const char *format, ...);
static void warning(Loc loc, const char *format, ...);
// For backend
virtual unsigned totym();

View File

@@ -18,13 +18,7 @@
#define integer_t dmd_integer_t
#endif
#if IN_GCC || IN_LLVM
#include "mem.h"
#elif POSIX
#include "../root/mem.h"
#elif _WIN32
#include "..\root\mem.h"
#endif
#include "rmem.h"
//#include "port.h"
#include "mtype.h"
@@ -276,7 +270,7 @@ Expression *BinExp::op_overload(Scope *sc)
templateResolve(&m, td, sc, loc, NULL, &args2);
}
}
lastf = m.lastf;
if (s_r)
@@ -576,7 +570,7 @@ void inferApplyArgTypes(enum TOK op, Arguments *arguments, Expression *aggr)
if (s)
{
fd = s->isFuncDeclaration();
if (fd)
if (fd)
inferApplyArgTypesX(fd, arguments);
}
break;

View File

@@ -234,7 +234,7 @@ Expression *AddrExp::optimize(int result)
TypeSArray *ts = (TypeSArray *)ve->type;
integer_t dim = ts->dim->toInteger();
if (index < 0 || index >= dim)
error("array index %lld is out of bounds [0..%lld]", index, dim);
error("array index %jd is out of bounds [0..%jd]", index, dim);
e = new SymOffExp(loc, ve->var, index * ts->next->size());
e->type = type;
return e;
@@ -421,8 +421,7 @@ Expression *BinExp::optimize(int result)
integer_t i2 = e2->toInteger();
d_uns64 sz = e1->type->size() * 8;
if (i2 < 0 || i2 > sz)
{
error("shift assign by %lld is outside the range 0..%"PRIuSIZE, i2, sz);
{ error("shift assign by %jd is outside the range 0..%zu", i2, sz);
e2 = new IntegerExp(0);
}
}
@@ -517,8 +516,7 @@ Expression *shift_optimize(int result, BinExp *e, Expression *(*shift)(Type *, E
integer_t i2 = e->e2->toInteger();
d_uns64 sz = e->e1->type->size() * 8;
if (i2 < 0 || i2 > sz)
{
error("shift by %lld is outside the range 0..%"PRIuSIZE, i2, sz);
{ e->error("shift by %jd is outside the range 0..%zu", i2, sz);
e->e2 = new IntegerExp(0);
}
if (e->e1->isConst() == 1)

View File

@@ -13,7 +13,7 @@
#include <stdio.h>
#include <assert.h>
#include "mem.h"
#include "rmem.h"
#include "lexer.h"
#include "parse.h"
#include "init.h"

16
dmd/rmem.h Normal file
View File

@@ -0,0 +1,16 @@
#ifndef __RMEM_H__
#define __RMEM_H__
// jam memory stuff here
#include "mem.h"
#if (defined (__SVR4) && defined (__sun))
#include <alloca.h>
#endif
#ifdef __MINGW32__
#include <malloc.h>
#endif
#endif // __RMEM_H__

View File

@@ -1,5 +1,5 @@
// Copyright (c) 1999-2006 by Digital Mars
// Copyright (c) 1999-2009 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// www.digitalmars.com
@@ -40,7 +40,7 @@
#include "port.h"
#include "root.h"
#include "dchar.h"
#include "mem.h"
#include "rmem.h"
#include "mars.h"
#if 0 //__SC__ //def DEBUG
@@ -376,6 +376,9 @@ Array *FileName::splitPath(const char *path)
instring ^= 1; // toggle inside/outside of string
continue;
#if MACINTOSH
case ',':
#endif
#if _WIN32
case ';':
#endif
@@ -1344,7 +1347,7 @@ void File::stat()
void File::checkoffset(size_t offset, size_t nbytes)
{
if (offset > len || offset + nbytes > len)
error("Corrupt file '%s': offset x%"PRIxSIZE" off end of file",toChars(),offset);
error("Corrupt file '%s': offset x%zx off end of file",toChars(),offset);
}
char *File::toChars()
@@ -1385,14 +1388,10 @@ void OutBuffer::mark()
void OutBuffer::reserve(unsigned nbytes)
{
//printf("OutBuffer::reserve: size = %d, offset = %d, nbytes = %d\n", size, offset, nbytes);
//printf("OutBuffer::reserve: size = %d, offset = %d, nbytes = %d\n", size, offset, nbytes);
if (size - offset < nbytes)
{
#if defined (__x86_64__)
size = (offset + nbytes) * 2+2;
#else
size = (offset + nbytes) * 2;
#endif
data = (unsigned char *)mem.realloc(data, size);
}
}

View File

@@ -37,6 +37,7 @@ void warning(const char *format, ...);
#define TYPEDEFS
#if _MSC_VER
#include <float.h> // for _isnan
typedef __int64 longlong;
typedef unsigned __int64 ulonglong;
#else

View File

@@ -257,10 +257,7 @@ Dsymbol *Scope::search(Loc loc, Identifier *ident, Dsymbol **pscopesym)
sc->enclosing &&
sc->enclosing->search(loc, ident, NULL))
{
// WTF ?
if (global.params.warnings)
fprintf(stdmsg, "warning - ");
error(s->loc, "array 'length' hides other 'length' name in outer scope");
warning(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());

View File

@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2008 by Digital Mars
// Copyright (c) 1999-2009 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -12,7 +12,7 @@
#include <stdlib.h>
#include <assert.h>
#include "mem.h"
#include "rmem.h"
#include "statement.h"
#include "expression.h"
@@ -96,6 +96,18 @@ void Statement::error(const char *format, ...)
va_end( ap );
}
void Statement::warning(const char *format, ...)
{
if (global.params.warnings && !global.gag)
{
fprintf(stdmsg, "warning - ");
va_list ap;
va_start(ap, format);
::verror(loc, format, ap);
va_end( ap );
}
}
int Statement::hasBreak()
{
//printf("Statement::hasBreak()\n");
@@ -539,10 +551,7 @@ int CompoundStatement::blockExit()
//printf("%s\n", s->toChars());
if (!(result & BEfallthru) && !s->comeFrom())
{
if (global.params.warnings)
{ fprintf(stdmsg, "warning - ");
s->error("statement is not reachable");
}
s->warning("statement is not reachable");
}
result &= ~BEfallthru;
@@ -1029,9 +1038,11 @@ Statement *ForStatement::semantic(Scope *sc)
sc = sc->push(sym);
if (init)
init = init->semantic(sc);
#if 0
if (!condition)
// Use a default value
condition = new IntegerExp(loc, 1, Type::tboolean);
#endif
sc->noctor++;
if (condition)
{
@@ -1096,9 +1107,9 @@ int ForStatement::blockExit()
result &= ~BEfallthru; // the body must do the exiting
if (body)
{ int r = body->blockExit();
if (r & BEbreak)
if (r & (BEbreak | BEgoto))
result |= BEfallthru;
result |= r & ~(BEbreak | BEcontinue);
result |= r & ~(BEfallthru | BEbreak | BEcontinue);
}
if (increment && increment->canThrow())
result |= BEthrow;
@@ -1669,7 +1680,7 @@ Statement *ForeachStatement::semantic(Scope *sc)
default: assert(0);
}
const char *r = (op == TOKforeach_reverse) ? "R" : "";
int j = sprintf(fdname, "_aApply%s%.*s%" PRIuSIZE, r, 2, fntab[flag], dim);
int j = sprintf(fdname, "_aApply%s%.*s%zu", r, 2, fntab[flag], dim);
assert(j < sizeof(fdname));
//LDC: Build arguments.
Arguments* args = new Arguments;
@@ -2323,9 +2334,7 @@ Statement *SwitchStatement::semantic(Scope *sc)
if (!sc->sw->sdefault)
{ hasNoDefault = 1;
if (global.params.warnings)
{ warning("%s: switch statement has no default", loc.toChars());
}
warning("switch statement has no default");
// Generate runtime error if the default is hit
Statements *a = new Statements();
@@ -3930,5 +3939,3 @@ LabelDsymbol *LabelDsymbol::isLabel() // is this a LabelDsymbol()?
{
return this;
}

View File

@@ -79,7 +79,7 @@ struct block;
#endif
struct code;
/* How a statement exits
/* How a statement exits; this is returned by blockExit()
*/
enum BE
{
@@ -134,6 +134,7 @@ struct Statement : Object
char *toChars();
void error(const char *format, ...);
void warning(const char *format, ...);
virtual void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
virtual TryCatchStatement *isTryCatchStatement() { return NULL; }
virtual GotoStatement *isGotoStatement() { return NULL; }

View File

@@ -13,7 +13,7 @@
#include <stdlib.h>
#include "root.h"
#include "mem.h"
#include "rmem.h"
#include "dchar.h"
#include "lstring.h"
#include "stringtable.h"

View File

@@ -1,485 +1,510 @@
// 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.
#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 "statement.h"
/********************************* AggregateDeclaration ****************************/
AggregateDeclaration::AggregateDeclaration(Loc loc, Identifier *id)
: ScopeDsymbol(id)
{
this->loc = loc;
storage_class = 0;
protection = PROTpublic;
type = NULL;
handle = NULL;
structsize = 0; // size of struct
alignsize = 0; // size of struct for alignment purposes
structalign = 0; // struct member alignment in effect
hasUnions = 0;
sizeok = 0; // size not determined yet
isdeprecated = 0;
inv = NULL;
aggNew = NULL;
aggDelete = NULL;
stag = NULL;
sinit = NULL;
scope = NULL;
}
enum PROT AggregateDeclaration::prot()
{
return protection;
}
void AggregateDeclaration::semantic2(Scope *sc)
{
//printf("AggregateDeclaration::semantic2(%s)\n", toChars());
if (scope)
{ error("has forward references");
return;
}
if (members)
{
sc = sc->push(this);
for (size_t i = 0; i < members->dim; i++)
{
Dsymbol *s = (Dsymbol *)members->data[i];
s->semantic2(sc);
}
sc->pop();
}
}
void AggregateDeclaration::semantic3(Scope *sc)
{ int i;
//printf("AggregateDeclaration::semantic3(%s)\n", toChars());
if (members)
{
sc = sc->push(this);
for (i = 0; i < members->dim; i++)
{
Dsymbol *s = (Dsymbol *)members->data[i];
s->semantic3(sc);
}
sc->pop();
}
}
void AggregateDeclaration::inlineScan()
{ int i;
//printf("AggregateDeclaration::inlineScan(%s)\n", toChars());
if (members)
{
for (i = 0; i < members->dim; i++)
{
Dsymbol *s = (Dsymbol *)members->data[i];
//printf("inline scan aggregate symbol '%s'\n", s->toChars());
s->inlineScan();
}
}
}
unsigned AggregateDeclaration::size(Loc loc)
{
//printf("AggregateDeclaration::size() = %d\n", structsize);
if (!members)
error(loc, "unknown size");
if (sizeok != 1)
{ error(loc, "no size yet for forward reference");
//*(char*)0=0;
}
return structsize;
}
Type *AggregateDeclaration::getType()
{
return type;
}
int AggregateDeclaration::isDeprecated()
{
return isdeprecated;
}
/****************************
* Do byte or word alignment as necessary.
* Align sizes of 0, as we may not know array sizes yet.
*/
void AggregateDeclaration::alignmember(unsigned salign, unsigned size, unsigned *poffset)
{
//printf("salign = %d, size = %d, offset = %d\n",salign,size,*poffset);
if (salign > 1)
{ int sa;
switch (size)
{ case 1:
break;
case 2:
case_2:
*poffset = (*poffset + 1) & ~1; // align to word
break;
case 3:
case 4:
if (salign == 2)
goto case_2;
*poffset = (*poffset + 3) & ~3; // align to dword
break;
default:
*poffset = (*poffset + size - 1) & ~(size - 1);
break;
}
}
//printf("result = %d\n",*poffset);
}
void AggregateDeclaration::addField(Scope *sc, VarDeclaration *v)
{
unsigned memsize; // size of member
unsigned memalignsize; // size of member for alignment purposes
unsigned xalign; // alignment boundaries
//printf("AggregateDeclaration::addField('%s') %s\n", v->toChars(), toChars());
// Check for forward referenced types which will fail the size() call
Type *t = v->type->toBasetype();
if (t->ty == Tstruct /*&& isStructDeclaration()*/)
{ TypeStruct *ts = (TypeStruct *)t;
if (ts->sym->sizeok != 1)
{
sizeok = 2; // cannot finish; flag as forward referenced
return;
}
}
if (t->ty == Tident)
{
sizeok = 2; // cannot finish; flag as forward referenced
return;
}
memsize = v->type->size(loc);
memalignsize = v->type->alignsize();
xalign = v->type->memalign(sc->structalign);
alignmember(xalign, memalignsize, &sc->offset);
v->offset = sc->offset;
sc->offset += memsize;
if (sc->offset > structsize)
structsize = sc->offset;
if (sc->structalign < memalignsize)
memalignsize = sc->structalign;
if (alignsize < memalignsize)
alignsize = memalignsize;
//printf("\talignsize = %d\n", alignsize);
v->storage_class |= STCfield;
//printf(" addField '%s' to '%s' at offset %d, size = %d\n", v->toChars(), toChars(), v->offset, memsize);
fields.push(v);
}
/********************************* StructDeclaration ****************************/
StructDeclaration::StructDeclaration(Loc loc, Identifier *id)
: AggregateDeclaration(loc, id)
{
zeroInit = 0; // assume false until we do semantic processing
// For forward references
type = new TypeStruct(this);
}
Dsymbol *StructDeclaration::syntaxCopy(Dsymbol *s)
{
StructDeclaration *sd;
if (s)
sd = (StructDeclaration *)s;
else
sd = new StructDeclaration(loc, ident);
ScopeDsymbol::syntaxCopy(sd);
return sd;
}
void StructDeclaration::semantic(Scope *sc)
{ int i;
Scope *sc2;
//printf("+StructDeclaration::semantic(this=%p, '%s')\n", this, toChars());
//static int count; if (++count == 20) *(char*)0=0;
assert(type);
if (!members) // if forward reference
return;
if (symtab)
{ if (!scope)
return; // semantic() already completed
}
else
symtab = new DsymbolTable();
Scope *scx = NULL;
if (scope)
{ sc = scope;
scx = scope; // save so we don't make redundant copies
scope = NULL;
}
parent = sc->parent;
handle = type->pointerTo();
structalign = sc->structalign;
protection = sc->protection;
if (sc->stc & STCdeprecated)
isdeprecated = 1;
assert(!isAnonymous());
if (sc->stc & STCabstract)
error("structs, unions cannot be abstract");
if (sizeok == 0) // if not already done the addMember step
{
for (i = 0; i < members->dim; i++)
{
Dsymbol *s = (Dsymbol *)members->data[i];
//printf("adding member '%s' to '%s'\n", s->toChars(), this->toChars());
s->addMember(sc, this, 1);
}
}
sizeok = 0;
sc2 = sc->push(this);
sc2->stc = 0;
sc2->parent = this;
if (isUnionDeclaration())
sc2->inunion = 1;
sc2->protection = PROTpublic;
sc2->explicitProtection = 0;
int members_dim = members->dim;
for (i = 0; i < members_dim; i++)
{
Dsymbol *s = (Dsymbol *)members->data[i];
s->semantic(sc2);
if (isUnionDeclaration())
sc2->offset = 0;
#if 0
if (sizeok == 2)
{ //printf("forward reference\n");
break;
}
#endif
}
/* The TypeInfo_Struct is expecting an opEquals and opCmp with
* a parameter that is a pointer to the struct. But if there
* isn't one, but is an opEquals or opCmp with a value, write
* another that is a shell around the value:
* int opCmp(struct *p) { return opCmp(*p); }
*/
TypeFunction *tfeqptr;
{
Arguments *arguments = new Arguments;
Argument *arg = new Argument(STCin, handle, Id::p, NULL);
arguments->push(arg);
tfeqptr = new TypeFunction(arguments, Type::tint32, 0, LINKd);
tfeqptr = (TypeFunction *)tfeqptr->semantic(0, sc);
}
TypeFunction *tfeq;
{
Arguments *arguments = new Arguments;
Argument *arg = new Argument(STCin, type, NULL, NULL);
arguments->push(arg);
tfeq = new TypeFunction(arguments, Type::tint32, 0, LINKd);
tfeq = (TypeFunction *)tfeq->semantic(0, sc);
}
Identifier *id = Id::eq;
for (int i = 0; i < 2; i++)
{
Dsymbol *s = search_function(this, id);
FuncDeclaration *fdx = s ? s->isFuncDeclaration() : NULL;
if (fdx)
{ FuncDeclaration *fd = fdx->overloadExactMatch(tfeqptr);
if (!fd)
{ fd = fdx->overloadExactMatch(tfeq);
if (fd)
{ // Create the thunk, fdptr
FuncDeclaration *fdptr = new FuncDeclaration(loc, loc, fdx->ident, STCundefined, tfeqptr);
Expression *e = new IdentifierExp(loc, Id::p);
e = new PtrExp(loc, e);
Expressions *args = new Expressions();
args->push(e);
e = new IdentifierExp(loc, id);
e = new CallExp(loc, e, args);
fdptr->fbody = new ReturnStatement(loc, e);
ScopeDsymbol *s = fdx->parent->isScopeDsymbol();
assert(s);
s->members->push(fdptr);
fdptr->addMember(sc, s, 1);
fdptr->semantic(sc2);
}
}
}
id = Id::cmp;
}
sc2->pop();
if (sizeok == 2)
{ // semantic() failed because of forward references.
// Unwind what we did, and defer it for later
fields.setDim(0);
structsize = 0;
alignsize = 0;
structalign = 0;
scope = scx ? scx : new Scope(*sc);
scope->setNoFree();
scope->module->addDeferredSemantic(this);
//printf("\tdeferring %s\n", toChars());
return;
}
// 0 sized struct's are set to 1 byte
if (structsize == 0)
{
structsize = 1;
alignsize = 1;
}
// Round struct size up to next alignsize boundary.
// This will ensure that arrays of structs will get their internals
// aligned properly.
structsize = (structsize + alignsize - 1) & ~(alignsize - 1);
sizeok = 1;
Module::dprogress++;
//printf("-StructDeclaration::semantic(this=%p, '%s')\n", this, toChars());
// Determine if struct is all zeros or not
zeroInit = 1;
for (i = 0; i < fields.dim; i++)
{
Dsymbol *s = (Dsymbol *)fields.data[i];
VarDeclaration *vd = s->isVarDeclaration();
if (vd && !vd->isDataseg())
{
if (vd->init)
{
// Should examine init to see if it is really all 0's
zeroInit = 0;
break;
}
else
{
if (!vd->type->isZeroInit())
{
zeroInit = 0;
break;
}
}
}
}
/* Look for special member functions.
*/
inv = (InvariantDeclaration *)search(0, Id::classInvariant, 0);
aggNew = (NewDeclaration *)search(0, Id::classNew, 0);
aggDelete = (DeleteDeclaration *)search(0, Id::classDelete, 0);
if (sc->func)
{
semantic2(sc);
semantic3(sc);
}
}
void StructDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{ int i;
buf->printf("%s ", kind());
if (!isAnonymous())
buf->writestring(toChars());
if (!members)
{
buf->writeByte(';');
buf->writenl();
return;
}
buf->writenl();
buf->writeByte('{');
buf->writenl();
for (i = 0; i < members->dim; i++)
{
Dsymbol *s = (Dsymbol *)members->data[i];
buf->writestring(" ");
s->toCBuffer(buf, hgs);
}
buf->writeByte('}');
buf->writenl();
}
const char *StructDeclaration::kind()
{
return "struct";
}
/********************************* UnionDeclaration ****************************/
UnionDeclaration::UnionDeclaration(Loc loc, Identifier *id)
: StructDeclaration(loc, id)
{
}
Dsymbol *UnionDeclaration::syntaxCopy(Dsymbol *s)
{
UnionDeclaration *ud;
if (s)
ud = (UnionDeclaration *)s;
else
ud = new UnionDeclaration(loc, ident);
StructDeclaration::syntaxCopy(ud);
return ud;
}
const char *UnionDeclaration::kind()
{
return "union";
}
// Compiler implementation of the D programming language
// Copyright (c) 1999-2009 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 "statement.h"
/********************************* AggregateDeclaration ****************************/
AggregateDeclaration::AggregateDeclaration(Loc loc, Identifier *id)
: ScopeDsymbol(id)
{
this->loc = loc;
storage_class = 0;
protection = PROTpublic;
type = NULL;
handle = NULL;
structsize = 0; // size of struct
alignsize = 0; // size of struct for alignment purposes
structalign = 0; // struct member alignment in effect
hasUnions = 0;
sizeok = 0; // size not determined yet
isdeprecated = 0;
inv = NULL;
aggNew = NULL;
aggDelete = NULL;
stag = NULL;
sinit = NULL;
scope = NULL;
#if V2
dtor = NULL;
ctor = NULL;
defaultCtor = NULL;
#endif
}
enum PROT AggregateDeclaration::prot()
{
return protection;
}
void AggregateDeclaration::semantic2(Scope *sc)
{
//printf("AggregateDeclaration::semantic2(%s)\n", toChars());
if (scope)
{ error("has forward references");
return;
}
if (members)
{
sc = sc->push(this);
for (size_t i = 0; i < members->dim; i++)
{
Dsymbol *s = (Dsymbol *)members->data[i];
s->semantic2(sc);
}
sc->pop();
}
}
void AggregateDeclaration::semantic3(Scope *sc)
{ int i;
//printf("AggregateDeclaration::semantic3(%s)\n", toChars());
if (members)
{
sc = sc->push(this);
for (i = 0; i < members->dim; i++)
{
Dsymbol *s = (Dsymbol *)members->data[i];
s->semantic3(sc);
}
sc->pop();
}
}
void AggregateDeclaration::inlineScan()
{ int i;
//printf("AggregateDeclaration::inlineScan(%s)\n", toChars());
if (members)
{
for (i = 0; i < members->dim; i++)
{
Dsymbol *s = (Dsymbol *)members->data[i];
//printf("inline scan aggregate symbol '%s'\n", s->toChars());
s->inlineScan();
}
}
}
unsigned AggregateDeclaration::size(Loc loc)
{
//printf("AggregateDeclaration::size() = %d\n", structsize);
if (!members)
error(loc, "unknown size");
if (sizeok != 1)
{ error(loc, "no size yet for forward reference");
//*(char*)0=0;
}
return structsize;
}
Type *AggregateDeclaration::getType()
{
return type;
}
int AggregateDeclaration::isDeprecated()
{
return isdeprecated;
}
/****************************
* Do byte or word alignment as necessary.
* Align sizes of 0, as we may not know array sizes yet.
*/
void AggregateDeclaration::alignmember(
unsigned salign, // struct alignment that is in effect
unsigned size, // alignment requirement of field
unsigned *poffset)
{
//printf("salign = %d, size = %d, offset = %d\n",salign,size,offset);
if (salign > 1)
{
assert(size != 3);
int sa = size;
if (sa == 0 || salign < sa)
sa = salign;
*poffset = (*poffset + sa - 1) & ~(sa - 1);
}
//printf("result = %d\n",offset);
}
void AggregateDeclaration::addField(Scope *sc, VarDeclaration *v)
{
unsigned memsize; // size of member
unsigned memalignsize; // size of member for alignment purposes
unsigned xalign; // alignment boundaries
//printf("AggregateDeclaration::addField('%s') %s\n", v->toChars(), toChars());
// Check for forward referenced types which will fail the size() call
Type *t = v->type->toBasetype();
if (t->ty == Tstruct /*&& isStructDeclaration()*/)
{ TypeStruct *ts = (TypeStruct *)t;
#if V2
if (ts->sym == this)
{
error("cannot have field %s with same struct type", v->toChars());
}
#endif
if (ts->sym->sizeok != 1)
{
sizeok = 2; // cannot finish; flag as forward referenced
return;
}
}
if (t->ty == Tident)
{
sizeok = 2; // cannot finish; flag as forward referenced
return;
}
memsize = v->type->size(loc);
memalignsize = v->type->alignsize();
xalign = v->type->memalign(sc->structalign);
alignmember(xalign, memalignsize, &sc->offset);
v->offset = sc->offset;
sc->offset += memsize;
if (sc->offset > structsize)
structsize = sc->offset;
if (sc->structalign < memalignsize)
memalignsize = sc->structalign;
if (alignsize < memalignsize)
alignsize = memalignsize;
//printf("\talignsize = %d\n", alignsize);
v->storage_class |= STCfield;
//printf(" addField '%s' to '%s' at offset %d, size = %d\n", v->toChars(), toChars(), v->offset, memsize);
fields.push(v);
}
/********************************* StructDeclaration ****************************/
StructDeclaration::StructDeclaration(Loc loc, Identifier *id)
: AggregateDeclaration(loc, id)
{
zeroInit = 0; // assume false until we do semantic processing
#if V2
hasIdentityAssign = 0;
cpctor = NULL;
postblit = NULL;
#endif
// For forward references
type = new TypeStruct(this);
}
Dsymbol *StructDeclaration::syntaxCopy(Dsymbol *s)
{
StructDeclaration *sd;
if (s)
sd = (StructDeclaration *)s;
else
sd = new StructDeclaration(loc, ident);
ScopeDsymbol::syntaxCopy(sd);
return sd;
}
void StructDeclaration::semantic(Scope *sc)
{ int i;
Scope *sc2;
//printf("+StructDeclaration::semantic(this=%p, '%s')\n", this, toChars());
//static int count; if (++count == 20) *(char*)0=0;
assert(type);
if (!members) // if forward reference
return;
if (symtab)
{ if (!scope)
return; // semantic() already completed
}
else
symtab = new DsymbolTable();
Scope *scx = NULL;
if (scope)
{ sc = scope;
scx = scope; // save so we don't make redundant copies
scope = NULL;
}
parent = sc->parent;
#if STRUCTTHISREF
handle = type;
#else
handle = type->pointerTo();
#endif
structalign = sc->structalign;
protection = sc->protection;
if (sc->stc & STCdeprecated)
isdeprecated = 1;
assert(!isAnonymous());
if (sc->stc & STCabstract)
error("structs, unions cannot be abstract");
#if V2
if (storage_class & STCinvariant)
type = type->invariantOf();
else if (storage_class & STCconst)
type = type->constOf();
#endif
if (sizeok == 0) // if not already done the addMember step
{
for (i = 0; i < members->dim; i++)
{
Dsymbol *s = (Dsymbol *)members->data[i];
//printf("adding member '%s' to '%s'\n", s->toChars(), this->toChars());
s->addMember(sc, this, 1);
}
}
sizeok = 0;
sc2 = sc->push(this);
sc2->stc = 0;
sc2->parent = this;
if (isUnionDeclaration())
sc2->inunion = 1;
sc2->protection = PROTpublic;
sc2->explicitProtection = 0;
int members_dim = members->dim;
for (i = 0; i < members_dim; i++)
{
Dsymbol *s = (Dsymbol *)members->data[i];
s->semantic(sc2);
if (isUnionDeclaration())
sc2->offset = 0;
#if 0
if (sizeok == 2)
{ //printf("forward reference\n");
break;
}
#endif
}
/* The TypeInfo_Struct is expecting an opEquals and opCmp with
* a parameter that is a pointer to the struct. But if there
* isn't one, but is an opEquals or opCmp with a value, write
* another that is a shell around the value:
* int opCmp(struct *p) { return opCmp(*p); }
*/
TypeFunction *tfeqptr;
{
Arguments *arguments = new Arguments;
Argument *arg = new Argument(STCin, handle, Id::p, NULL);
arguments->push(arg);
tfeqptr = new TypeFunction(arguments, Type::tint32, 0, LINKd);
tfeqptr = (TypeFunction *)tfeqptr->semantic(0, sc);
}
TypeFunction *tfeq;
{
Arguments *arguments = new Arguments;
Argument *arg = new Argument(STCin, type, NULL, NULL);
arguments->push(arg);
tfeq = new TypeFunction(arguments, Type::tint32, 0, LINKd);
tfeq = (TypeFunction *)tfeq->semantic(0, sc);
}
Identifier *id = Id::eq;
for (int i = 0; i < 2; i++)
{
Dsymbol *s = search_function(this, id);
FuncDeclaration *fdx = s ? s->isFuncDeclaration() : NULL;
if (fdx)
{ FuncDeclaration *fd = fdx->overloadExactMatch(tfeqptr);
if (!fd)
{ fd = fdx->overloadExactMatch(tfeq);
if (fd)
{ // Create the thunk, fdptr
FuncDeclaration *fdptr = new FuncDeclaration(loc, loc, fdx->ident, STCundefined, tfeqptr);
Expression *e = new IdentifierExp(loc, Id::p);
e = new PtrExp(loc, e);
Expressions *args = new Expressions();
args->push(e);
e = new IdentifierExp(loc, id);
e = new CallExp(loc, e, args);
fdptr->fbody = new ReturnStatement(loc, e);
ScopeDsymbol *s = fdx->parent->isScopeDsymbol();
assert(s);
s->members->push(fdptr);
fdptr->addMember(sc, s, 1);
fdptr->semantic(sc2);
}
}
}
id = Id::cmp;
}
#if V2
dtor = buildDtor(sc2);
postblit = buildPostBlit(sc2);
cpctor = buildCpCtor(sc2);
buildOpAssign(sc2);
#endif
sc2->pop();
if (sizeok == 2)
{ // semantic() failed because of forward references.
// Unwind what we did, and defer it for later
fields.setDim(0);
structsize = 0;
alignsize = 0;
structalign = 0;
scope = scx ? scx : new Scope(*sc);
scope->setNoFree();
scope->module->addDeferredSemantic(this);
//printf("\tdeferring %s\n", toChars());
return;
}
// 0 sized struct's are set to 1 byte
if (structsize == 0)
{
structsize = 1;
alignsize = 1;
}
// Round struct size up to next alignsize boundary.
// This will ensure that arrays of structs will get their internals
// aligned properly.
structsize = (structsize + alignsize - 1) & ~(alignsize - 1);
sizeok = 1;
Module::dprogress++;
//printf("-StructDeclaration::semantic(this=%p, '%s')\n", this, toChars());
// Determine if struct is all zeros or not
zeroInit = 1;
for (i = 0; i < fields.dim; i++)
{
Dsymbol *s = (Dsymbol *)fields.data[i];
VarDeclaration *vd = s->isVarDeclaration();
if (vd && !vd->isDataseg())
{
if (vd->init)
{
// Should examine init to see if it is really all 0's
zeroInit = 0;
break;
}
else
{
if (!vd->type->isZeroInit())
{
zeroInit = 0;
break;
}
}
}
}
/* Look for special member functions.
*/
#if V2
ctor = (CtorDeclaration *)search(0, Id::ctor, 0);
#endif
inv = (InvariantDeclaration *)search(0, Id::classInvariant, 0);
aggNew = (NewDeclaration *)search(0, Id::classNew, 0);
aggDelete = (DeleteDeclaration *)search(0, Id::classDelete, 0);
if (sc->func)
{
semantic2(sc);
semantic3(sc);
}
}
void StructDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{ int i;
buf->printf("%s ", kind());
if (!isAnonymous())
buf->writestring(toChars());
if (!members)
{
buf->writeByte(';');
buf->writenl();
return;
}
buf->writenl();
buf->writeByte('{');
buf->writenl();
for (i = 0; i < members->dim; i++)
{
Dsymbol *s = (Dsymbol *)members->data[i];
buf->writestring(" ");
s->toCBuffer(buf, hgs);
}
buf->writeByte('}');
buf->writenl();
}
const char *StructDeclaration::kind()
{
return "struct";
}
/********************************* UnionDeclaration ****************************/
UnionDeclaration::UnionDeclaration(Loc loc, Identifier *id)
: StructDeclaration(loc, id)
{
}
Dsymbol *UnionDeclaration::syntaxCopy(Dsymbol *s)
{
UnionDeclaration *ud;
if (s)
ud = (UnionDeclaration *)s;
else
ud = new UnionDeclaration(loc, ident);
StructDeclaration::syntaxCopy(ud);
return ud;
}
const char *UnionDeclaration::kind()
{
return "union";
}

View File

@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2008 by Digital Mars
// Copyright (c) 1999-2009 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -21,7 +21,7 @@ long __cdecl __ehfilter(LPEXCEPTION_POINTERS ep);
#endif
#include "root.h"
#include "mem.h"
#include "rmem.h"
#include "stringtable.h"
#include "mars.h"
#include "identifier.h"
@@ -186,6 +186,16 @@ int match(Object *o1, Object *o2, TemplateDeclaration *tempdecl, Scope *sc)
{
goto Lnomatch;
}
#if V2
VarDeclaration *v1 = s1->isVarDeclaration();
VarDeclaration *v2 = s2->isVarDeclaration();
if (v1 && v2 && v1->storage_class & v2->storage_class & STCmanifest)
{ ExpInitializer *ei1 = v1->init->isExpInitializer();
ExpInitializer *ei2 = v2->init->isExpInitializer();
if (ei1 && ei2 && !ei1->exp->equals(ei2->exp))
goto Lnomatch;
}
#endif
}
else if (v1)
{
@@ -253,6 +263,20 @@ void ObjectToCBuffer(OutBuffer *buf, HdrGenState *hgs, Object *oarg)
}
}
#if V2
Object *objectSyntaxCopy(Object *o)
{
if (!o)
return NULL;
Type *t = isType(o);
if (t)
return t->syntaxCopy();
Expression *e = isExpression(o);
if (e)
return e->syntaxCopy();
return o;
}
#endif
/* ======================== TemplateDeclaration ============================= */
@@ -279,6 +303,9 @@ TemplateDeclaration::TemplateDeclaration(Loc loc, Identifier *id, TemplateParame
this->loc = loc;
this->parameters = parameters;
this->origParameters = parameters;
#if V2
this->constraint = constraint;
#endif
this->members = decldefs;
this->overnext = NULL;
this->overroot = NULL;
@@ -303,6 +330,11 @@ Dsymbol *TemplateDeclaration::syntaxCopy(Dsymbol *)
p->data[i] = (void *)tp->syntaxCopy();
}
}
#if V2
Expression *e = NULL;
if (constraint)
e = constraint->syntaxCopy();
#endif
d = Dsymbol::arraySyntaxCopy(members);
td = new TemplateDeclaration(loc, ident, p, d);
@@ -352,6 +384,7 @@ void TemplateDeclaration::semantic(Scope *sc)
paramsym->parent = sc->parent;
Scope *paramscope = sc->push(paramsym);
paramscope->parameterSpecialization = 1;
paramscope->stc = 0;
if (global.params.doDocComments)
{
@@ -512,6 +545,7 @@ MATCH TemplateDeclaration::matchWithInstance(TemplateInstance *ti,
ScopeDsymbol *paramsym = new ScopeDsymbol();
paramsym->parent = scope->parent;
Scope *paramscope = scope->push(paramsym);
paramscope->stc = 0;
// Attempt type deduction
m = MATCHexact;
@@ -763,7 +797,8 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Loc loc, Objects *targsi,
memcpy(dedargs->data, targsi->data, nargsi * sizeof(*dedargs->data));
for (i = 0; i < nargsi; i++)
{ TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
{ assert(i < parameters->dim);
TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
MATCH m;
Declaration *sparam;
@@ -800,6 +835,7 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Loc loc, Objects *targsi,
Tuple *t = new Tuple();
//printf("t = %p\n", t);
dedargs->data[parameters->dim - 1] = (void *)t;
declareParameter(paramscope, tp, t);
goto L2;
}
else if (nfargs < nfparams - 1)
@@ -835,6 +871,7 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Loc loc, Objects *targsi,
{ Expression *farg = (Expression *)fargs->data[fptupindex + i];
t->objects.data[i] = (void *)farg->type;
}
declareParameter(paramscope, tp, t);
goto L2;
}
fptupindex = -1;
@@ -1020,7 +1057,7 @@ Lmatch:
*/
Declaration *sparam;
dedargs->data[i] = (void *)oded;
MATCH m2 = tp->matchArg(paramscope, dedargs, i, parameters, &dedtypes, &sparam);
MATCH m2 = tp->matchArg(paramscope, dedargs, i, parameters, &dedtypes, &sparam, 0);
//printf("m2 = %d\n", m2);
if (!m2)
goto Lnomatch;
@@ -1077,7 +1114,7 @@ Lnomatch:
}
/**************************************************
* Declare template parameter tp with value o.
* Declare template parameter tp with value o, and install it in the scope sc.
*/
void TemplateDeclaration::declareParameter(Scope *sc, TemplateParameter *tp, Object *o)
@@ -1260,8 +1297,8 @@ FuncDeclaration *TemplateDeclaration::deduceFunctionTemplate(Scope *sc, Loc loc,
}
if (td_ambig)
{
error(loc, "%s matches more than one function template declaration, %s and %s",
toChars(), td_best->toChars(), td_ambig->toChars());
error(loc, "matches more than one function template declaration:\n %s\nand:\n %s",
td_best->toChars(), td_ambig->toChars());
}
/* The best match is td_best with arguments tdargs.
@@ -1794,11 +1831,20 @@ MATCH TypeInstance::deduceType(Scope *sc,
Expression *e1 = isExpression(o1);
Expression *e2 = isExpression(o2);
Dsymbol *s1 = isDsymbol(o1);
Dsymbol *s2 = isDsymbol(o2);
Tuple *v1 = isTuple(o1);
Tuple *v2 = isTuple(o2);
#if 0
if (t1) printf("t1 = %s\n", t1->toChars());
if (t2) printf("t2 = %s\n", t2->toChars());
if (e1) printf("e1 = %s\n", e1->toChars());
if (e2) printf("e2 = %s\n", e2->toChars());
if (s1) printf("s1 = %s\n", s1->toChars());
if (s2) printf("s2 = %s\n", s2->toChars());
if (v1) printf("v1 = %s\n", v1->toChars());
if (v2) printf("v2 = %s\n", v2->toChars());
#endif
if (t1 && t2)
@@ -1845,7 +1891,33 @@ MATCH TypeInstance::deduceType(Scope *sc,
dedtypes->data[j] = e1;
}
}
// BUG: Need to handle alias and tuple parameters
else if (s1 && t2 && t2->ty == Tident)
{
j = templateParameterLookup(t2, parameters);
if (j == -1)
goto Lnomatch;
TemplateParameter *tp = (TemplateParameter *)parameters->data[j];
// BUG: use tp->matchArg() instead of the following
TemplateAliasParameter *ta = tp->isTemplateAliasParameter();
if (!ta)
goto Lnomatch;
Dsymbol *s = (Dsymbol *)dedtypes->data[j];
if (s)
{
if (!s1->equals(s))
goto Lnomatch;
}
else
{
dedtypes->data[j] = s1;
}
}
else if (s1 && s2)
{
if (!s1->equals(s2))
goto Lnomatch;
}
// BUG: Need to handle tuple parameters
else
goto Lnomatch;
}
@@ -2113,7 +2185,7 @@ Lnomatch:
MATCH TemplateTypeParameter::matchArg(Scope *sc, Objects *tiargs,
int i, TemplateParameters *parameters, Objects *dedtypes,
Declaration **psparam)
Declaration **psparam, int flags)
{
//printf("TemplateTypeParameter::matchArg()\n");
Type *t;
@@ -2357,7 +2429,7 @@ Lnomatch:
MATCH TemplateAliasParameter::matchArg(Scope *sc,
Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes,
Declaration **psparam)
Declaration **psparam, int flags)
{
Dsymbol *sa;
Object *oarg;
@@ -2569,7 +2641,7 @@ Lnomatch:
MATCH TemplateValueParameter::matchArg(Scope *sc,
Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes,
Declaration **psparam)
Declaration **psparam, int flags)
{
//printf("TemplateValueParameter::matchArg()\n");
@@ -2766,7 +2838,7 @@ Lnomatch:
MATCH TemplateTupleParameter::matchArg(Scope *sc,
Objects *tiargs, int i, TemplateParameters *parameters,
Objects *dedtypes,
Declaration **psparam)
Declaration **psparam, int flags)
{
//printf("TemplateTupleParameter::matchArg()\n");
@@ -3026,7 +3098,7 @@ void TemplateInstance::semantic(Scope *sc)
}
}
isNested(tiargs);
hasNestedArgs(tiargs);
/* See if there is an existing TemplateInstantiation that already
* implements the typeargs. If so, just refer to that one instead.
@@ -3101,12 +3173,16 @@ void TemplateInstance::semantic(Scope *sc)
//if (scx && scx->scopesym) printf("3: scx is %s %s\n", scx->scopesym->kind(), scx->scopesym->toChars());
if (scx && scx->scopesym &&
scx->scopesym->members && !scx->scopesym->isTemplateMixin() &&
/* The following test should really be if scx->module recursively
* imports itself. Because if it does, see bugzilla 2500.
scx->scopesym->members && !scx->scopesym->isTemplateMixin()
#if 1 // removed because it bloated compile times
/* The problem is if A imports B, and B imports A, and both A
* and B instantiate the same template, does the compilation of A
* or the compilation of B do the actual instantiation?
*
* see bugzilla 2500.
*/
//scx->module == tempdecl->getModule()
!scx->module->imports(scx->module)
&& !scx->module->selfImports()
#endif
)
{
//printf("\t1: adding to %s %s\n", scx->scopesym->kind(), scx->scopesym->toChars());
@@ -3151,7 +3227,10 @@ void TemplateInstance::semantic(Scope *sc)
scope = scope->push(argsym);
// Declare each template parameter as an alias for the argument type
declareParameters(scope);
Scope *paramscope = scope->push();
paramscope->stc = 0;
declareParameters(paramscope);
paramscope->pop();
// Add members of template instance to template instance symbol table
// parent = scope->scopesym;
@@ -3620,9 +3699,9 @@ TemplateDeclaration *TemplateInstance::findBestMatch(Scope *sc)
* generation of the TemplateDeclaration.
*/
int TemplateInstance::isNested(Objects *args)
int TemplateInstance::hasNestedArgs(Objects *args)
{ int nested = 0;
//printf("TemplateInstance::isNested('%s')\n", tempdecl->ident->toChars());
//printf("TemplateInstance::hasNestedArgs('%s')\n", tempdecl->ident->toChars());
/* A nested instance happens when an argument references a local
* symbol that is on the stack.
@@ -3691,7 +3770,7 @@ int TemplateInstance::isNested(Objects *args)
}
else if (va)
{
nested |= isNested(&va->objects);
nested |= hasNestedArgs(&va->objects);
}
}
return nested;
@@ -3710,7 +3789,7 @@ Identifier *TemplateInstance::genIdent()
//printf("TemplateInstance::genIdent('%s')\n", tempdecl->ident->toChars());
id = tempdecl->ident->toChars();
buf.printf("__T%"PRIuSIZE"%s", strlen(id), id);
buf.printf("__T%zu%s", strlen(id), id);
args = tiargs;
for (int i = 0; i < args->dim; i++)
{ Object *o = (Object *)args->data[i];
@@ -3777,7 +3856,7 @@ Identifier *TemplateInstance::genIdent()
else
{
char *p = sa->mangle();
buf.printf("%"PRIuSIZE"%s", strlen(p), p);
buf.printf("%zu%s", strlen(p), p);
}
}
else if (va)

View File

@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2008 by Digital Mars
// Copyright (c) 1999-2009 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -137,7 +137,7 @@ struct TemplateParameter
/* Match actual argument against parameter.
*/
virtual MATCH matchArg(Scope *sc, Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam) = 0;
virtual MATCH matchArg(Scope *sc, Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam, int flags = 0) = 0;
/* Create dummy argument based on parameter.
*/
@@ -163,7 +163,7 @@ struct TemplateTypeParameter : TemplateParameter
Object *specialization();
Object *defaultArg(Loc loc, Scope *sc);
int overloadMatch(TemplateParameter *);
MATCH matchArg(Scope *sc, Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam);
MATCH matchArg(Scope *sc, Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam, int flags);
void *dummyArg();
};
@@ -207,7 +207,7 @@ struct TemplateValueParameter : TemplateParameter
Object *specialization();
Object *defaultArg(Loc loc, Scope *sc);
int overloadMatch(TemplateParameter *);
MATCH matchArg(Scope *sc, Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam);
MATCH matchArg(Scope *sc, Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam, int flags);
void *dummyArg();
};
@@ -235,7 +235,7 @@ struct TemplateAliasParameter : TemplateParameter
Object *specialization();
Object *defaultArg(Loc loc, Scope *sc);
int overloadMatch(TemplateParameter *);
MATCH matchArg(Scope *sc, Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam);
MATCH matchArg(Scope *sc, Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam, int flags);
void *dummyArg();
};
@@ -256,7 +256,7 @@ struct TemplateTupleParameter : TemplateParameter
Object *specialization();
Object *defaultArg(Loc loc, Scope *sc);
int overloadMatch(TemplateParameter *);
MATCH matchArg(Scope *sc, Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam);
MATCH matchArg(Scope *sc, Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam, int flags);
void *dummyArg();
};
@@ -318,7 +318,7 @@ struct TemplateInstance : ScopeDsymbol
TemplateDeclaration *findTemplateDeclaration(Scope *sc);
TemplateDeclaration *findBestMatch(Scope *sc);
void declareParameters(Scope *sc);
int isNested(Objects *tiargs);
int hasNestedArgs(Objects *tiargs);
Identifier *genIdent();
TemplateInstance *isTemplateInstance() { return this; }

View File

@@ -1,45 +0,0 @@
// 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_TOTAL_H
#define DMD_TOTAL_H
#ifdef __DMC__
#pragma once
#endif /* __DMC__ */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <wchar.h>
#include "root.h"
#include "stringtable.h"
#include "arraytypes.h"
#include "mars.h"
#include "lexer.h"
#include "parse.h"
#include "identifier.h"
#include "enum.h"
#include "aggregate.h"
#include "mtype.h"
#include "expression.h"
#include "declaration.h"
#include "statement.h"
#include "scope.h"
#include "import.h"
#include "module.h"
#include "id.h"
#include "cond.h"
#include "version.h"
#endif /* DMD_TOTAL_H */

View File

@@ -469,7 +469,7 @@ static void remap_outargs(std::string& insnt, size_t nargs, size_t idx)
needle = prefix + digits[i] + suffix;
size_t pos = insnt.find(needle);
if(std::string::npos != pos)
sprintf(buf, "%" PRIuSIZE, idx++);
sprintf(buf, "%lu", idx++);
while(std::string::npos != (pos = insnt.find(needle)))
insnt.replace(pos, needle.size(), buf);
}
@@ -494,7 +494,7 @@ static void remap_inargs(std::string& insnt, size_t nargs, size_t idx)
needle = prefix + digits[i] + suffix;
size_t pos = insnt.find(needle);
if(std::string::npos != pos)
sprintf(buf, "%" PRIuSIZE, idx++);
sprintf(buf, "%lu", idx++);
while(std::string::npos != (pos = insnt.find(needle)))
insnt.replace(pos, needle.size(), buf);
}

View File

@@ -1,7 +1,7 @@
#include "gen/cl_helpers.h"
#include "root.h"
#include "mem.h"
#include "rmem.h"
#include <cctype> // isupper, tolower
#include <algorithm>

112
gen/configfile.cpp Normal file
View File

@@ -0,0 +1,112 @@
#include <iostream>
#include <string>
#include <cassert>
#include "llvm/System/Path.h"
#include "libconfig.h++"
#include "gen/configfile.h"
#include "mars.h"
namespace sys = llvm::sys;
ConfigFile::ConfigFile()
{
cfg = new libconfig::Config;
}
ConfigFile::~ConfigFile()
{
delete cfg;
}
bool ConfigFile::read(const char* argv0, void* mainAddr, const char* filename)
{
// try to find the config file
// 1) try the current working dir
sys::Path p = sys::Path::GetCurrentDirectory();
p.appendComponent(filename);
if (!p.exists())
{
// 2) try the user home dir
p = sys::Path::GetUserHomeDirectory();
p.appendComponent(filename);
if (!p.exists())
{
// 3) try the install-prefix/etc
p = sys::Path(LDC_INSTALL_PREFIX);
p.appendComponent(filename);
if (!p.exists())
{
// 4) try next to the executable
p = sys::Path::GetMainExecutable(argv0, mainAddr);
p.eraseComponent();
p.appendComponent(filename);
if (!p.exists())
{
// 5) fail load cfg, users still have the DFLAGS environment var
std::cerr << "Error failed to locate the configuration file: " << filename << std::endl;
return false;
}
}
}
}
try
{
// read the cfg
cfg->readFile(p.c_str());
// make sure there's a default group
if (!cfg->exists("default"))
{
std::cerr << "no default settings in configuration file" << std::endl;
return false;
}
libconfig::Setting& root = cfg->lookup("default");
if (!root.isGroup())
{
std::cerr << "default is not a group" << std::endl;
return false;
}
// handle switches
if (root.exists("switches"))
{
libconfig::Setting& arr = cfg->lookup("default.switches");
int len = arr.getLength();
for (int i=0; i<len; i++)
{
const char* v = arr[i];
switches.push_back(v);
}
}
}
catch(libconfig::FileIOException& fioe)
{
std::cerr << "Error reading configuration file: " << filename << std::endl;
return false;
}
catch(libconfig::ParseException& pe)
{
std::cerr << "Error parsing configuration file: " << filename
<< "(" << pe.getLine() << "): " << pe.getError() << std::endl;
return false;
}
catch(...)
{
std::cerr << "Unknown exception caught!" << std::endl;
return false;
}
return true;
}

32
gen/configfile.h Normal file
View File

@@ -0,0 +1,32 @@
#ifndef LDC_CONF_CONFIGFILE_H
#define LDC_CONF_CONFIGFILE_H
#include <vector>
namespace libconfig
{
class Config;
}
class ConfigFile
{
public:
typedef std::vector<const char*> s_vector;
typedef s_vector::iterator s_iterator;
public:
ConfigFile();
~ConfigFile();
bool read(const char* argv0, void* mainAddr, const char* filename);
s_iterator switches_begin() { return switches.begin(); }
s_iterator switches_end() { return switches.end(); }
private:
libconfig::Config* cfg;
s_vector switches;
};
#endif // LDC_CONF_CONFIGFILE_H

View File

@@ -21,7 +21,7 @@
#include <windows.h>
#endif
#include "mem.h"
#include "rmem.h"
#include "root.h"
#include "mars.h"
@@ -39,6 +39,8 @@
#include "gen/cl_helpers.h"
using namespace opts;
#include "gen/configfile.h"
extern void getenv_setargv(const char *envvar, int *pargc, char** *pargv);
extern void backend_init();
extern void backend_term();
@@ -144,15 +146,7 @@ int main(int argc, char** argv)
VersionCondition::addPredefinedGlobalIdent("D_Version2");
#endif
// read the inifile
#if DMDV2
inifile(global.params.argv0, "ldc2.conf");
#else
inifile(global.params.argv0, "ldc.conf");
#endif
// merge DFLAGS into argc/argv
// merge DFLAGS environment variable into argc/argv
getenv_setargv("DFLAGS", &argc, &argv);
#if 0
for (int i = 0; i < argc; i++)
@@ -161,9 +155,38 @@ int main(int argc, char** argv)
}
#endif
// build complete fixed up list of command line arguments
std::vector<const char*> final_args;
final_args.reserve(argc);
// insert argc + DFLAGS
final_args.insert(final_args.end(), &argv[0], &argv[argc]);
// read the configuration file
ConfigFile cfg_file;
// just ignore errors for now, they are still printed
#if DMDV2
#define CFG_FILENAME "ldc2.conf"
#else
#define CFG_FILENAME "ldc.conf"
#endif
cfg_file.read(global.params.argv0, (void*)main, CFG_FILENAME);
#undef CFG_FILENAME
// insert config file additions to the argument list
final_args.insert(final_args.end(), cfg_file.switches_begin(), cfg_file.switches_end());
#if 0
for (size_t i = 0; i < final_args.size(); ++i)
{
printf("final_args[%zu] = %s\n", i, final_args[i]);
}
#endif
// Handle fixed-up arguments!
cl::SetVersionPrinter(&printVersion);
cl::ParseCommandLineOptions(argc, argv, "LLVM-based D Compiler\n");
cl::ParseCommandLineOptions(final_args.size(), (char**)&final_args[0], "LLVM-based D Compiler\n", true);
global.params.optimize = (global.params.optimizeLevel >= 0);

View File

@@ -9,7 +9,6 @@
#include "llvm/Support/CFG.h"
#include "mars.h"
#include "total.h"
#include "init.h"
#include "mtype.h"
#include "hdrgen.h"

View File

@@ -13,13 +13,14 @@
#include "gen/llvm.h"
#include "attrib.h"
#include "total.h"
#include "init.h"
#include "mtype.h"
#include "template.h"
#include "hdrgen.h"
#include "port.h"
#include "mem.h"
#include "rmem.h"
#include "id.h"
#include "enum.h"
#include "gen/irstate.h"
#include "gen/logger.h"

View File

@@ -1,2 +1,17 @@
[Environment]
DFLAGS=-I@RUNTIME_DIR@ -I@RUNTIME_DIR@/lib/common -L-L%@P%/../lib -d-version=Tango -defaultlib=@RUNTIME_AIO@ -debuglib=@RUNTIME_AIO@
// This configuration file uses libconfig.
// See http://www.hyperrealm.com/libconfig/ for syntax details.
// The default group is required
default:
{
// 'switches' holds array of string that are appends to the command line
// arguments before they are parsed.
// {#} is replaced with the path to the directory holding the executable
switches = [
"-I@RUNTIME_DIR@",
"-I@RUNTIME_DIR@/lib/common",
"-L-L@PROJECT_BINARY_DIR@/../lib",
"-d-version=Tango",
"-defaultlib=@RUNTIME_AIO@"
];
};