mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-01-11 18:33:14 +01:00
- 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:
@@ -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)
|
||||
|
||||
1257
dmd/Doxyfile
1257
dmd/Doxyfile
File diff suppressed because it is too large
Load Diff
@@ -13,7 +13,7 @@
|
||||
#include <assert.h>
|
||||
|
||||
#include "root.h"
|
||||
#include "mem.h"
|
||||
#include "rmem.h"
|
||||
|
||||
#include "enum.h"
|
||||
#include "aggregate.h"
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
#include "port.h"
|
||||
#include "root.h"
|
||||
#include "dchar.h"
|
||||
#include "mem.h"
|
||||
#include "rmem.h"
|
||||
|
||||
|
||||
/********************************* Array ****************************/
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
25
dmd/attrib.c
25
dmd/attrib.c
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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 &&
|
||||
|
||||
18
dmd/cond.c
18
dmd/cond.c
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#include <assert.h>
|
||||
|
||||
#include "dchar.h"
|
||||
#include "mem.h"
|
||||
#include "rmem.h"
|
||||
|
||||
#if M_UNICODE
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
12
dmd/doc.c
12
dmd/doc.c
@@ -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"
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "mem.h"
|
||||
#include "rmem.h"
|
||||
|
||||
#include "mars.h"
|
||||
#include "dsymbol.h"
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
16
dmd/func.c
16
dmd/func.c
@@ -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)
|
||||
|
||||
12
dmd/hdrgen.c
12
dmd/hdrgen.c
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
|
||||
302
dmd/inifile.c
302
dmd/inifile.c
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
31
dmd/lexer.c
31
dmd/lexer.c
@@ -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
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "dchar.h"
|
||||
#include "mem.h"
|
||||
#include "rmem.h"
|
||||
#include "lstring.h"
|
||||
|
||||
Lstring Lstring::zero = LSTRING_EMPTY();
|
||||
|
||||
14
dmd/macro.c
14
dmd/macro.c
@@ -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
202
dmd/man.c
@@ -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
|
||||
|
||||
21
dmd/mangle.c
21
dmd/mangle.c
@@ -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);
|
||||
|
||||
16
dmd/mars.c
16
dmd/mars.c
@@ -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)
|
||||
|
||||
105
dmd/mars.h
105
dmd/mars.h
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
39
dmd/module.c
39
dmd/module.c
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
53
dmd/mtype.c
53
dmd/mtype.c
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
15
dmd/mtype.h
15
dmd/mtype.h
@@ -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();
|
||||
|
||||
12
dmd/opover.c
12
dmd/opover.c
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
16
dmd/rmem.h
Normal 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__
|
||||
15
dmd/root.c
15
dmd/root.c
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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"
|
||||
|
||||
995
dmd/struct.c
995
dmd/struct.c
@@ -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";
|
||||
}
|
||||
|
||||
|
||||
|
||||
127
dmd/template.c
127
dmd/template.c
@@ -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)
|
||||
|
||||
@@ -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; }
|
||||
|
||||
45
dmd/total.h
45
dmd/total.h
@@ -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 */
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
112
gen/configfile.cpp
Normal 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
32
gen/configfile.h
Normal 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
|
||||
45
gen/main.cpp
45
gen/main.cpp
@@ -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);
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include "llvm/Support/CFG.h"
|
||||
|
||||
#include "mars.h"
|
||||
#include "total.h"
|
||||
#include "init.h"
|
||||
#include "mtype.h"
|
||||
#include "hdrgen.h"
|
||||
|
||||
@@ -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"
|
||||
|
||||
19
ldc.conf.in
19
ldc.conf.in
@@ -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@"
|
||||
];
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user