Squashed 'dmd2/' changes from 10017d5..3443f38

3443f38 Fix issue 7493  Initialization of void[][N]
0b371da foreach can run semantic again
7216e2a fix Issue 7735 - Functions with variadic void[][]... arguments corrupt passed data
4fb2b2a Merge pull request #850 from 9rnsr/fix7773
9c59931 Merge pull request #851 from donc/ctfe7785pointerToVar
407f7e4 Merge pull request #852 from donc/segfault7639
9370f83 Fix issue 7380 Crash trying to use address of variable in struct constructor at module level
240866b Fix issue 7639 Undefined enum AA key crashes compiler
19b7096 Fix issue 7785 [CTFE] ICE when slicing pointer to variable
d9b11f6 fix Issue 7773 - UCFS syntax on built-in attributes too?
296d812 Merge pull request #846 from donc/ctfe7781segfault
65aca2d Merge pull request #848 from donc/regression7751
5576737 Merge pull request #849 from donc/bug7794
0310838 Merge pull request #828 from 9rnsr/fix7751
4027e4f Fix issue 7794 Sea of errors when calling regex() after compile error
59cc12d Fix issue 7781 [CTFE] Segmentation fault on 'mixin({return;}());'
3430947 fix seg fault in fail91.d
948274e Merge pull request #824 from donc/regression7745
22ac4b1 Merge pull request #826 from 9rnsr/fix6659
1c15841 Merge pull request #823 from redstar/mscclean
5f54752 Merge pull request #827 from 9rnsr/fix7694
399e4a3 Merge pull request #844 from donc/regression7782
516f49b Fix issue 7789 [CTFE] null pointer exception on setting array length
d74b354 Fix issue 7782 Regression: ICE with wrong import syntax
0269194 Fix issue 7751 [ICE] (Regression 2.059head) From auto and forward reference
42ad236 Merge pull request #830 from 9rnsr/fix_ufcs
67bf025 Merge pull request #832 from 9rnsr/fix7608
d13f107 Merge pull request #829 from 9rnsr/fix7754
e25cbe2 Merge pull request #834 from 9rnsr/fix2367
7fac235 merge D2 pull #842
c836773 Merge pull request #836 from 9rnsr/fix7757
a2754c5 Merge pull request #839 from 9rnsr/fix7768
4948836 fix Issue 7694 - Internal error: e2ir.c 1251 when calling member function inside struct via alias param
9f23335 Merge pull request #838 from 9rnsr/fix7621
92eba60 Merge pull request #840 from 9rnsr/fix7769
8fae3c2 fix issue 7742 - 'More initializers than fields' error with correct number of fields
6c2d706 to enum
35e4f08 fix Issue 7769 - relax inout rule doesn't work for template function
96a0105 fix Issue 7768 - More readable template error messages
8012d58 Merge pull request #831 from 9rnsr/fix7743
9c0cbdd fix Issue 7621 - Immutable type equivalence problem
f67f313 Merge pull request #833 from 9rnsr/fix7731
29754dd Merge pull request #837 from braddr/cleanup-backend2
374109a restore original binary() function and re-fix the new version
78c04aa fix Issue 7757 - Inout function with lazy inout parameter doesn't compile
50c34e9 fix Issue 7754 - static this() in template is stripped during header gen
11acdff Fix auto tester breaking.
f0b7157 fix Issue 7755 - regression(2.059head): ICE in glue.c
cfceb77 fix Issue 7751 - [ICE] From auto and forward reference
7a86807 fix Issue 2367 - Overloading error with string literals
6039c40 fix Issue 7731 - Assertion failure: 't' on line 7911 in file 'mtype.c'
aea3a39 fix Issue 7608 - __traits(allMembers) is broken
f46f07a fix Issue 7743 - Parsing problem with nothrow delegate
fa9d29f Revert "Revert "Refactor for UFCS property getter/setter resolution.""
d9698d8 Revert "Revert "fix Issue 7722 - Refuse normal functions to be used as properties""
0fbc772 Revert "Revert "Allow property function has two arguments""
07a3b09 fix Issue 6659 - Destructor in range foreach called after initialization
e499d4d Fix issue 7745 Regression(2.059beta) Methods defined in external object files when a pointer to it is taken
79a74e1 Fixes an unknown pragma warning.
2b12052 Fix issue 176 [module] message "module and package have the same name"
90e89a4 Merge pull request #814 from 9rnsr/fix7713
3ab0e79 Merge pull request #818 from donc/assoc7732
b3360e9 Fix issue 7732 [CTFE] wrong code for a struct called AssociativeArray
05f0b08 Merge pull request #779 from 9rnsr/fix7534
867e567 Revert "Allow property function has two arguments"
9171aeb Revert "fix Issue 7722 - Refuse normal functions to be used as properties"
989ced7 Revert "Refactor for UFCS property getter/setter resolution."
e9b5292 Refactor for UFCS property getter/setter resolution.
761d000 fix Issue 7722 - Refuse normal functions to be used as properties
9f5956b Allow property function has two arguments
1a11862 Revert "Allow property function has two arguments"
32f57e5 Revert "fix Issue 7722 - Refuse normal functions to be used as properties"
6489bb4 Revert "Refactor for UFCS property getter/setter resolution."
214296f Merge pull request #817 from 9rnsr/fix_ufcs
c3c7f2a Merge pull request #816 from donc/voidctfe6438
185d031 Refactor for UFCS property getter/setter resolution.
08bf89d fix Issue 7722 - Refuse normal functions to be used as properties
f0e3433 Allow property function has two arguments
1b67ac9 Direct check by Type::reliesOnTident
a3cd7d9 fix Issue 7713 - lambda inference doesn't work on template function argument
1762112 Fix issue 6438 - [CTFE] wrong error "value used before set" when slicing =void array
ace1eca fix complex constant folding
76f9b22 Consider return type covariance.
f700dbc fix Issue 7534 - Allow attribute-overloading of an overridden method
cba8f5c Merge pull request #763 from 9rnsr/fix7578
392d93f Merge pull request #815 from dawgfoto/fixSegFault
e48aba2 merge part of pull #769
d72a17e revert dd5a543
24d860b error(Loc loc,) doesn't abort program
4c79117 Use correct opcodes for moving cfloat from st->xmm and xmm->st
af875ff Merge pull request #785 from braddr/cleanup-backend2
9d3021a remove debugging printfs
b3df5ee Merge pull request #807 from dawgfoto/fix7698
f005537 Merge pull request #802 from dawgfoto/fixVC
65a145d Merge pull request #803 from donc/ctfeunion6681yebblies
1cf39ca Merge pull request #812 from 9rnsr/fix_ufcs
d846c3c Merge pull request #808 from 9rnsr/fix7702
fd0a492 fix Issue 7670 - UFCS problem with @property and structs
1ad35b2 Fix for UFCS with property syntax, and add exhaustive test
96f15a1 Resolve broken build after merging
4712aab fix regression
4e05482 Merge pull request #805 from donc/regression7681
245a107 dt_ functions aren't x86 specific
b35f43a another missing loc in an error() call
001addb minor cleanups
2fb1e46 make util_assert take a const string
907da39 cleanup whitespace in binary(), add binary() that takes the length of the string to search for
59d0425 Merge pull request #804 from braddr/nearsighted
d725eed Merge pull request #806 from donc/ctfe7633equalmsg
12a5c26 Merge pull request #811 from donc/bug7699
4279d5e revert the revert
c895c3b revert pull #809
865fb20 fix Issue 5733 - Calling opDispatch As Template Results in Compiler Infinite Loop
96e16d3 fix Issue 7702 - opDispatch goes into infinite loop
5e343c0 Remove special case for DotIdExp and opDispatch semantic, it isn't need anymore
1a9d607 Fix issue 7699 - Cannot get frame pointer to in contract when compiling with -inline
d1476eb Merge pull request #809 from 9rnsr/fix_funclit
afc7c60 allow out-of-order semantic analysis of fields
17da3a0 fix Issue 7705 - lambda syntax doesn't allow some valid signatures
e29d06d fix issue 7698
911d053 Fix issue 7633 - Missing CTFE error message
3802dde Fix issue 7681 Regression(2.059head):ICE:opCatAssign(delegate) to undefined identifier
8da4121 near-ectomy
cd6dc83 fix Library::error()s format string to take a const char*
f3f03c6 switch to apply()
faf873a fix Issue 3510 - Cannot forward reference a templated type from within a template mixin
23aa2be fix Issue 3509 - Cannot forward reference a template mixin's members in a compile-time context
e81309b Add missing 'loc' to error message.
b6898e3 Fix issue 6681 - struct constructor call is converted to struct literal that breaks union initialization
b79afba long double => longdouble
e48c319 Merge pull request #742 from yebblies/issue5879
d74485a Merge pull request #787 from eco/ddoc-srcfilename
3038cb9 Merge pull request #795 from dawgfoto/fixComment
89a039a Merge pull request #801 from dawgfoto/fix4507
c17c2d8 fix issue 4507
dd86c72 Merge pull request #796 from dawgfoto/fixVC
a516588 Merge pull request #797 from 9rnsr/fix7682
1b9839a Merge pull request #799 from 9rnsr/fix6982
4596774 Merge pull request #800 from 9rnsr/fix_type_deduction
b68d546 forgot about @system
bfe1083 add attributes to toHash
8f819d6 Stop special case in mutableOf/makeMutable with inout type.
319b1a3 Fix the lacks of type merging in Type::mutableOf() and uhSharedOf()
cfe7450 fix Issue 7671 - Broken inout deduction of shared(inout(T[n])) from immutable(int[3])
aca5c37 Stop too eager call of TypeAArray::getImpl() When implicitConvTo(non aa Tstruct => Taarray)
50b2a97 fix Issue 6982 - immutability isn't respected on associative array assignment
a5daa5e fix Issue 7684 - IFTI and shared overload doesn't work
e43fbac fix Issue 7682 - shared array type and "cast() is not an lvalue" error
8191801 cpp_prettyident only needed for C++
4487f75 fix ldval
525647c tparam is the specialization
f893925 fix issue 7592 https://github.com/yebblies/dmd/commit/d847c1c2dd3c254324924530beab38b49510bf13
108b25d Merge pull request #780 from 9rnsr/fix7641
105a51f Merge pull request #784 from 9rnsr/fix7110
8b5b67f Merge pull request #792 from donc/bug7667
f72f237 fix Issue 3682 - Regression(2.038) is expression fails to match types
436b711 Fix issue 7667. ICE(interpret.c): 'ctfeStack.stackPointer() == 0'
9005276 Merge pull request #679 from yebblies/issue783
350a3ce Merge pull request #582 from 9rnsr/fix3382_ufcs
5f020c3 Merge pull request #788 from braddr/cleanup-backend3
6aa91cf Merge pull request #790 from p0nce/master
351d595 remove tls bracketing
a137d72 Fix bug #6391
6ce219c remove some of the bracketing
aec4c13 fix Issue 7578 - ICE on indexing result of vararg opDispatch
95e3dc1 Fix unintended infinite loop in Phobos build
b66196a fix Issue 3382 - [tdpl] Implement uniform function call syntax
ee2fe6c Fix 977 is with counting end-of-lines towards msot advanced lexer peeking
7790b16 fix Issue 7650 - Bad lambda inference in associative array literal
c03484e fix Issue 7649 - Bad lambda inference in default function argument
f293a10 fix Issue 7499 - [ICE] ('cast.c line 1495) with lambda array
9f0622c Expression::inferType() and remove FuncExp::setType()
cfc67b7 refactor lambda inference process
6d49586 more de-TX86'ing in relation to a bunch of OP codes
2efbf6a TX86-ectomy in evalu8.c
953f6d7 rip TX86 conditionals out of el.c
d5663c7 fix Issue 7595 - Data being overwritten.
449c165 Add predefined Ddoc macro SRCFILENAME
5c5da66 fix uninitialized field
29cde54 Merge pull request #783 from 9rnsr/fix7038
06d65ab fix Issue 7038 - Type mismatch with const struct
b77e2c9 fix Issue 7110 - opSlice() & opIndex functions works unstable as template arguments
a65f02f Merge pull request #781 from braddr/fix
08d6cd5 Merge pull request #782 from braddr/fixiasm
2492332 fix latent bug with Lexer::peek and recently introduced bug in Lexer::scan
ec1888e initialize popndTmp rather than rely on carefulness when usNumops == 0 and emitting a vector instruction, popndTmp is left uninitialized and is later dereferenced.
1d4a742 Merge pull request #766 from 9rnsr/fix7563
e1cd535 refactor
90f8dcf fix Issue 7641 - std.typecons.Proxy incorrectly allows implicit conversion to class
83a93cf Merge pull request #778 from dawgfoto/MoreSpellCorrection
7f0bcde 2nd go at fix issue 5590
567d7df fix Issue 5590 - Regression(2.036) ICE(e2ir.c): when using .values on enum which is associative array
48ea951 fix Issue 4820 - Regression(1.058, 2.044) in DStress caused by changeset 452
e8f9f3b more spell correction
afd9a45 fix Issue 7618 - delegate/function pointer call bypass parameter storage class
dabcdfb Merge pull request #773 from 9rnsr/fix7583
9846bb2 Merge pull request #774 from donc/ctfe7568
8c20445 Merge pull request #775 from donc/_error6785
d41e58e Avoiding shallow copy is more better.
cccef09 Revert "fix Issue 7585 - functions in templates inferred as delegate"
fc8dfc0 6785 Wrong error message from pragma(msg) of failed instantiation
61ec04d 7568 pragma(msg) segfaults with an aggregate including a class.
4d86d39 Merge pull request #767 from 9rnsr/fix7585
207d351 fix Issue 7583 - [CTFE] ICE with tuple and alias this
53bafa2 fix Issue 7411 - Deduce base type from vector types in templates
5ab1bd9 fix Issue 7518 - std.array.empty doesn't work for shared arrays
a1030d3 fix Issue 7554 - Immutable function pointer arguments too
5e96900 Merge pull request #771 from donc/bug7589
2287ebc fix Issue 7547 - -deps output lists object as a top level module
e611781 7589 __traits(compiles) does not work with a template that fails to compile
0113cde fix Issue 7585 - functions in templates inferred as delegate
4b978d5 fix Issue 7563 - Class members with default template arguments have no type
4d68981 fix Issue 7500 - [ICE] (template.c line 5287) with immutable lambda function
1a39c3c missed a line
6dd89ca Merge pull request #765 from 9rnsr/fix7525
8d6dcac fix Issue 7502 - 2.056 regression: Assigning .init takes forever to compile for large structs
042096e fix Issue 7525 - Broken return type inference for delegate returns
c5affa5 fix Issue 7582 - Untyped nested delegate literals don't compile
121677c fix Issue 7580 - Identity assignment of Nullable crashes dmd
adc0502 Small refactoring to resolve alias this.
1f52383 Merge pull request #671 from yebblies/issue4958
2a12345 fix build breakage
8755819 fix build
ba86204 fix vcbuild
464c664 fix linux build
31197c8 tweaked command line moved some inline asm to C-function to not interfere with optimizations build with VS2011
4dcdc9c increase stack size for win64 build
77262aa add missing include to root
56afe3f batch to build through win32.mak
5a0fd30 build through win32.mak
a5b5190 long_double -> longdouble remove C99 printf add Win64 support
9640110 vcbuild
b619171 Merge pull request #761 from donc/ctfe7473structref
7756328 Merge pull request #725 from kennytm/bug7399-import-too-fatal
bbac9e4 Merge pull request #759 from yebblies/issue1149
d1ff23b 7473 [CTFE] Non-ref argument behaves as if it's a ref argument
ab5cb18 Fix OPmsw codegen - integer only is too restrictive.
a00833b Merge pull request #743 from yebblies/issue3354
b006e11 Merge pull request #757 from 9rnsr/fix7562
3bccbb0 fix Issue 7562 - DMD crashes by using TemplateThisParameter
a7dc50e Merge pull request #749 from yebblies/issue1149
a873c5f Merge pull request #758 from 9rnsr/fix5525
5d639ec fix Issue 5525 - Eponymous templates should allow for overloaded eponymous members
f50852c Merge pull request #729 from donc/gag4269
de02523 fix Issue 3927 - array.length++; is an error, but ++array.length compiles
1dc5bfd Merge pull request #680 from yebblies/issue3812
cf887ba move errors to Dsymbol
fc4acf5 Merge pull request #755 from donc/seaOfErrors7557
be2f3a9 7557b soldier on through dottemplate expressions
8cec825 7557 Sea of errors after template failure
37ec6d6 A small fixup to call Type::defaultInitLiteral
7b5e2cb Revert "Revert "Merge pull request #41 from 9rnsr/rvalue-struct-literal""
3d8f09a Merge branch 'master' of github.com:D-Programming-Language/dmd
7dfb4cc Merge pull request #752 from braddr/cleanup-backend2
1b28f51 Merge branch 'master' of github.com:D-Programming-Language/dmd
31ad73c Merge pull request #746 from yebblies/issue5554
25f770d Change lexer to support # as a token, preserving #line's original behavior
dd8d20a Revert "Merge pull request #41 from 9rnsr/rvalue-struct-literal"
ee2fdf9 Merge pull request #41 from 9rnsr/rvalue-struct-literal
f94fdbf Merge pull request #750 from yebblies/issue3630
61f5fcf Improve codegen for OPmsw
05a3fa4 Merge pull request #744 from Safety0ff/avx-fix
0231d6a Merge pull request #748 from 9rnsr/fix7552
9a97979 Merge pull request #751 from donc/ctfe7536
e091e6e 7536 ctfeAdrOnStack triggered
c9edaf4 fix Issue 7552 - Cannot get and combine a part of overloaded functions
1edeba9 Fix Issue 3630 - bad error location in "has no effect in expression" error
7d0fb72 Fix Issue 5554 - [qtd] Covariance detection failure
4f36aca fix Issue 7550 - Missing AVX instruction VPMULDQ
0b82dfe Fix Issue 5879 - Not all frontend errors use stderr
963a41a Merge pull request #695 from yebblies/refactor_expression
3f06690 Fix Issue 3354 - asm fld x, ST(6); accepted
713f69f Merge pull request #677 from yebblies/issue4241
cf22ce3 Merge pull request #711 from yebblies/issue3559
56ca73c Merge pull request #700 from kennytm/bug7452_lazy_safe
c4dc723 Merge pull request #736 from ibuclaw/in_gcc
121c9b9 Merge pull request #737 from yebblies/issue7544
cedcb3c Merge pull request #740 from yebblies/issue7545
fb3e8f2 Merge pull request #741 from dawgfoto/DMCWarning
5d26c1e Merge pull request #735 from 9rnsr/fix7105
734a921 dmc warning
1e1cfbc Fix Issue 7545 - ICE(cast.c) Merge integral types through alias this
6b135be Fix Issue 7544 - ICE(interpret.c) Catching an exception with a null catch block
c5336f9 Update already existing gdc-specific code, harmonise headers.
44b8d59 Merge pull request #703 from kennytm/bug435_template_ctor
6b368e1 Merge pull request #707 from yebblies/issue3822
8439e07 Merge pull request #717 from yebblies/issue6611
2b4502e fix Issue 7105 - relax inout rules
ac4463a wildsubparam isn't need anymore, because it works properly.
f77879a Issue 6611 - better error message for array post increment/decrement
7393395 Merge pull request #716 from yebblies/issue6685
77568f0 Merge pull request #719 from yebblies/issue4536
9accb04 tired of tdata()
5fbd5a2 Merge pull request #732 from dawgfoto/fix5412
41a901a Revert "hide private/package module level symbols"
23d5e14 Merge pull request #733 from dawgfoto/HideModuleMembers
e2f8a23 hide private/package module level symbols
ae75287 detect collisions with renamed imports
75a2442 fix Dsymbol::search_correct
50e122a Merge pull request #723 from kennytm/bug7504_null_array
c5b7601 Revert "fix 7494 - selective imports in function scope"
aa6f4d9 Revert "fix Protection"
5be660e Revert "fix Imports"
040371b Revert "detect collisions with renamed imports"
0159818 Revert "find private symbols during spell correction"
0c95c45 find private symbols during spell correction
ca22fb2 detect collisions with renamed imports
0dca0af fix Imports
37d4fda fix Protection
16a2e7e fix 7494 - selective imports in function scope
c16f5b2 Merge pull request #667 from 9rnsr/fix7406
f776617 explanatory comments belong in the code, not bugzilla
bfa2060 Merge pull request #704 from donc/_error6699
f46705c fix fail222 regression
28d9635 Merge pull request #708 from donc/soldieron7481
2c2a7af Merge pull request #715 from 9rnsr/fix6738
98cfa64 Merge pull request #722 from 9rnsr/fix7353
b040567 revert pull 724
0e84f63 revert part of pull 724
400f702 Merge pull request #724 from yebblies/issue3632
d82cc74 Merge pull request #720 from yebblies/issue3279
2da3bed Merge pull request #718 from yebblies/fixdebugmsg
f6627ec 7527 [CTFE] Segfault when slicing a pointer at compile time
c8f09bf 4269a Regression(2.031): invalid type accepted if evaluated while errors are gagged
d10fba0 implement const/purity/nothrow/@safe inheritance
ad689fb Fix bug 7399: Broken import statement in trySemantic() causes silent compiler error
eb0c643 Add global.speculativeGag
c18220a Refactor isSpeculativeFunction into Dsymbol
f5c56d8 Issue 3632 - modify float is float to do a bitwise compare
af1cab4 Issue 7353 - NRVO not properly working with inferred return type
03ee438 Fix bug 7504: Cannot assign an object of type 'typeof(null)' to an array
dfb941c Remove debug printing in code that generates errors.
62118e3 Issue 4536 - Typetuples (T...) should have an .init member
989da7b Issue 3279 - Confusing error message when comparing types
36e8045 Issue 6685 - Allow using "with" with rvalues
60cbc6f fix issue 6738 revisited
4e20e7d Issue 3822 - Invalid optimization of alloca called with constant size
b37bf8c Fixes bug 435: Constructors should be templatized
ad8157d Issue 3559 - DMD 1.048+ fails to take function pointer from overloaded member functions
838cd06 7481 Compiler should 'soldier on' after template errors
673063e Simplify fix for 6699
1a0b199 6699a __error when instantiating function template
b6d072d 6699b __error in alias expression
df16ffa 6699c __error in synchronized error message
338f804 7462 Error message with _error_ in overridden function
0f60bd3 7463 Duplicated error message with bad template value parameter
f43e93a 6699E: _error inside error msg for bad base class
5109a5a Fixes bug 7452.
04d888f Refactor XxxAssignExp semantic
73973d6 Issue 3812 - Missing line number for implicit cast of variadic function to array
f0bbf18 Issue 3927 - array.length++; is an error, but ++array.length compiles
24576c2 Issue 783 - Cannot use an array w/ const or variable index as new[] size argument.
7e4cd4b Issue 4241 - duplicate union initialization error doesn't give a file location
9987127 Issue 4958 - Floating point enums should check for total loss of precision
60287fd Issue 7406 - tuple foreach doesn't work with mixed tuples
633d88e Issue 5889 - Struct literal/construction should be rvalue
5d5f78a Now function overloading with ref and non-ref parameter is legal for struct type

git-subtree-dir: dmd2
git-subtree-split: 3443f38fc4c17807a0f36005a05d598cfc7301db
This commit is contained in:
Alexey Prokhin
2012-04-05 11:45:25 +04:00
parent caad8cde58
commit f2237662df
123 changed files with 7585 additions and 2745 deletions
+15 -8
View File
@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2011 by Digital Mars
// Copyright (c) 1999-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -34,6 +34,12 @@ struct TypeInfoClassDeclaration;
struct VarDeclaration;
struct dt_t;
enum Sizeok
{
SIZEOKnone, // size of aggregate is not computed yet
SIZEOKdone, // size of aggregate is set correctly
SIZEOKfwd, // error in computing size of aggregate
};
struct AggregateDeclaration : ScopeDsymbol
{
@@ -46,10 +52,7 @@ struct AggregateDeclaration : ScopeDsymbol
unsigned structalign; // struct member alignment in effect
int hasUnions; // set if aggregate has overlapping fields
VarDeclarations fields; // VarDeclaration fields
unsigned sizeok; // set when structsize contains valid data
// 0: no size
// 1: size is correct
// 2: cannot determine size; fwd referenced
enum Sizeok sizeok; // set when structsize contains valid data
Dsymbol *deferred; // any deferred semantic2() or semantic3() symbol
bool isdeprecated; // !=0 if deprecated
@@ -74,7 +77,8 @@ struct AggregateDeclaration : ScopeDsymbol
FuncDeclaration *dtor; // aggregate destructor
#ifdef IN_GCC
Array methods; // flat list of all methods for debug information
Expressions *attributes; // GCC decl/type attributes
FuncDeclarations methods; // flat list of all methods for debug information
#endif
AggregateDeclaration(Loc loc, Identifier *id);
@@ -83,8 +87,10 @@ struct AggregateDeclaration : ScopeDsymbol
void inlineScan();
unsigned size(Loc loc);
static void alignmember(unsigned salign, unsigned size, unsigned *poffset);
static unsigned placeField(unsigned *nextoffset,
unsigned memsize, unsigned memalignsize, unsigned memalign,
unsigned *paggsize, unsigned *paggalignsize, bool isunion);
Type *getType();
void addField(Scope *sc, VarDeclaration *v);
int firstFieldInUnion(int indx); // first field in union that includes indx
int numFieldsInUnion(int firstIndex); // #fields in union starting at index
int isDeprecated(); // is aggregate deprecated?
@@ -143,7 +149,7 @@ struct StructDeclaration : AggregateDeclaration
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
char *mangle();
const char *kind();
void finalizeSize();
void finalizeSize(Scope *sc);
#if DMDV1
Expression *cloneMembers();
#endif
@@ -203,6 +209,7 @@ struct BaseClass
#define CLASSINFO_SIZE (0x3C+12+4) // value of ClassInfo.size
#else
#define CLASSINFO_SIZE (0x3C+12+4) // value of ClassInfo.size
#define CLASSINFO_SIZE_64 (0x98) // value of ClassInfo.size
#endif
struct ClassDeclaration : AggregateDeclaration
+23
View File
@@ -17,9 +17,32 @@
#include "scope.h"
#include "aggregate.h"
#include "dsymbol.h"
#include "mtype.h"
#if DMDV2
Expression *resolveAliasThis(Scope *sc, Expression *e)
{
Type *t = e->type->toBasetype();
AggregateDeclaration *ad;
if (t->ty == Tclass)
{ ad = ((TypeClass *)t)->sym;
goto L1;
}
else if (t->ty == Tstruct)
{ ad = ((TypeStruct *)t)->sym;
L1:
if (ad && ad->aliasthis)
{
e = new DotIdExp(e->loc, e, ad->aliasthis->ident);
e = e->semantic(sc);
e = resolveProperties(sc, e);
}
}
return e;
}
AliasThis::AliasThis(Loc loc, Identifier *ident)
: Dsymbol(NULL) // it's anonymous (no identifier)
+144 -164
View File
@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2011 by Digital Mars
// Copyright (c) 1999-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -47,6 +47,24 @@ Dsymbols *AttribDeclaration::include(Scope *sc, ScopeDsymbol *sd)
return decl;
}
int AttribDeclaration::apply(Dsymbol_apply_ft_t fp, void *param)
{
Dsymbols *d = include(NULL, NULL);
if (d)
{
for (size_t i = 0; i < d->dim; i++)
{ Dsymbol *s = (*d)[i];
if (s)
{
if (s->apply(fp, param))
return 1;
}
}
}
return 0;
}
int AttribDeclaration::addMember(Scope *sc, ScopeDsymbol *sd, int memnum)
{
int m = 0;
@@ -54,8 +72,8 @@ int AttribDeclaration::addMember(Scope *sc, ScopeDsymbol *sd, int memnum)
if (d)
{
for (unsigned i = 0; i < d->dim; i++)
{ Dsymbol *s = d->tdata()[i];
for (size_t i = 0; i < d->dim; i++)
{ Dsymbol *s = (*d)[i];
//printf("\taddMember %s to %s\n", s->toChars(), sd->toChars());
m |= s->addMember(sc, sd, m | memnum);
}
@@ -85,8 +103,8 @@ void AttribDeclaration::setScopeNewSc(Scope *sc,
newsc->explicitProtection = explicitProtection;
newsc->structalign = structalign;
}
for (unsigned i = 0; i < decl->dim; i++)
{ Dsymbol *s = decl->tdata()[i];
for (size_t i = 0; i < decl->dim; i++)
{ Dsymbol *s = (*decl)[i];
s->setScope(newsc); // yes, the only difference from semanticNewSc()
}
@@ -120,8 +138,8 @@ void AttribDeclaration::semanticNewSc(Scope *sc,
newsc->explicitProtection = explicitProtection;
newsc->structalign = structalign;
}
for (unsigned i = 0; i < decl->dim; i++)
{ Dsymbol *s = decl->tdata()[i];
for (size_t i = 0; i < decl->dim; i++)
{ Dsymbol *s = (*decl)[i];
s->semantic(newsc);
}
@@ -142,7 +160,7 @@ void AttribDeclaration::semantic(Scope *sc)
{
for (size_t i = 0; i < d->dim; i++)
{
Dsymbol *s = d->tdata()[i];
Dsymbol *s = (*d)[i];
s->semantic(sc);
}
@@ -156,7 +174,7 @@ void AttribDeclaration::semantic2(Scope *sc)
if (d)
{
for (size_t i = 0; i < d->dim; i++)
{ Dsymbol *s = d->tdata()[i];
{ Dsymbol *s = (*d)[i];
s->semantic2(sc);
}
}
@@ -169,7 +187,7 @@ void AttribDeclaration::semantic3(Scope *sc)
if (d)
{
for (size_t i = 0; i < d->dim; i++)
{ Dsymbol *s = d->tdata()[i];
{ Dsymbol *s = (*d)[i];
s->semantic3(sc);
}
}
@@ -181,8 +199,8 @@ void AttribDeclaration::inlineScan()
if (d)
{
for (unsigned i = 0; i < d->dim; i++)
{ Dsymbol *s = d->tdata()[i];
for (size_t i = 0; i < d->dim; i++)
{ Dsymbol *s = (*d)[i];
//printf("AttribDeclaration::inlineScan %s\n", s->toChars());
s->inlineScan();
}
@@ -198,8 +216,8 @@ void AttribDeclaration::addComment(unsigned char *comment)
if (d)
{
for (unsigned i = 0; i < d->dim; i++)
{ Dsymbol *s = d->tdata()[i];
for (size_t i = 0; i < d->dim; i++)
{ Dsymbol *s = (*d)[i];
//printf("AttribDeclaration::addComment %s\n", s->toChars());
s->addComment(comment);
}
@@ -223,8 +241,8 @@ void AttribDeclaration::emitComment(Scope *sc)
if (d)
{
for (unsigned i = 0; i < d->dim; i++)
{ Dsymbol *s = d->tdata()[i];
for (size_t i = 0; i < d->dim; i++)
{ Dsymbol *s = (*d)[i];
//printf("AttribDeclaration::emitComment %s\n", s->toChars());
s->emitComment(sc);
}
@@ -237,30 +255,24 @@ void AttribDeclaration::toObjFile(int multiobj)
if (d)
{
for (unsigned i = 0; i < d->dim; i++)
{ Dsymbol *s = d->tdata()[i];
for (size_t i = 0; i < d->dim; i++)
{ Dsymbol *s = (*d)[i];
s->toObjFile(multiobj);
}
}
}
int AttribDeclaration::cvMember(unsigned char *p)
void AttribDeclaration::setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion)
{
int nwritten = 0;
int n;
Dsymbols *d = include(NULL, NULL);
if (d)
{
for (unsigned i = 0; i < d->dim; i++)
{ Dsymbol *s = d->tdata()[i];
n = s->cvMember(p);
if (p)
p += n;
nwritten += n;
for (size_t i = 0; i < d->dim; i++)
{ Dsymbol *s = (*d)[i];
s->setFieldOffset(ad, poffset, isunion);
}
}
return nwritten;
}
int AttribDeclaration::hasPointers()
@@ -271,7 +283,7 @@ int AttribDeclaration::hasPointers()
{
for (size_t i = 0; i < d->dim; i++)
{
Dsymbol *s = d->tdata()[i];
Dsymbol *s = (*d)[i];
if (s->hasPointers())
return 1;
}
@@ -313,8 +325,8 @@ void AttribDeclaration::checkCtorConstInit()
if (d)
{
for (unsigned i = 0; i < d->dim; i++)
{ Dsymbol *s = d->tdata()[i];
for (size_t i = 0; i < d->dim; i++)
{ Dsymbol *s = (*d)[i];
s->checkCtorConstInit();
}
}
@@ -329,8 +341,8 @@ void AttribDeclaration::addLocalClass(ClassDeclarations *aclasses)
if (d)
{
for (unsigned i = 0; i < d->dim; i++)
{ Dsymbol *s = d->tdata()[i];
for (size_t i = 0; i < d->dim; i++)
{ Dsymbol *s = (*d)[i];
s->addLocalClass(aclasses);
}
}
@@ -344,15 +356,15 @@ void AttribDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
if (decl->dim == 0)
buf->writestring("{}");
else if (decl->dim == 1)
(decl->tdata()[0])->toCBuffer(buf, hgs);
((*decl)[0])->toCBuffer(buf, hgs);
else
{
buf->writenl();
buf->writeByte('{');
buf->writenl();
for (unsigned i = 0; i < decl->dim; i++)
for (size_t i = 0; i < decl->dim; i++)
{
Dsymbol *s = decl->tdata()[i];
Dsymbol *s = (*decl)[i];
buf->writestring(" ");
s->toCBuffer(buf, hgs);
@@ -571,9 +583,9 @@ void LinkDeclaration::semantic3(Scope *sc)
{ enum LINK linkage_save = sc->linkage;
sc->linkage = linkage;
for (unsigned i = 0; i < decl->dim; i++)
for (size_t i = 0; i < decl->dim; i++)
{
Dsymbol *s = decl->tdata()[i];
Dsymbol *s = (*decl)[i];
s->semantic3(sc);
}
@@ -740,6 +752,7 @@ AnonDeclaration::AnonDeclaration(Loc loc, int isunion, Dsymbols *decl)
: AttribDeclaration(decl)
{
this->loc = loc;
this->alignment = 0;
this->isunion = isunion;
this->sem = 0;
}
@@ -757,21 +770,6 @@ void AnonDeclaration::semantic(Scope *sc)
{
//printf("\tAnonDeclaration::semantic %s %p\n", isunion ? "union" : "struct", this);
if (sem == 1)
{ //printf("already completed\n");
scope = NULL;
return; // semantic() already completed
}
Scope *scx = NULL;
if (scope)
{ sc = scope;
scx = scope;
scope = NULL;
}
unsigned dprogress_save = Module::dprogress;
assert(sc->parent);
Dsymbol *parent = sc->parent->pastMixin();
@@ -783,106 +781,85 @@ void AnonDeclaration::semantic(Scope *sc)
return;
}
alignment = sc->structalign;
if (decl)
{
AnonymousAggregateDeclaration aad;
int adisunion;
if (sc->anonAgg)
{ ad = sc->anonAgg;
adisunion = sc->inunion;
}
else
adisunion = ad->isUnionDeclaration() != NULL;
// printf("\tsc->anonAgg = %p\n", sc->anonAgg);
// printf("\tad = %p\n", ad);
// printf("\taad = %p\n", &aad);
sc = sc->push();
sc->anonAgg = &aad;
sc->stc &= ~(STCauto | STCscope | STCstatic | STCtls | STCgshared);
sc->inunion = isunion;
sc->offset = 0;
sc->flags = 0;
aad.structalign = sc->structalign;
aad.parent = ad;
for (unsigned i = 0; i < decl->dim; i++)
for (size_t i = 0; i < decl->dim; i++)
{
Dsymbol *s = decl->tdata()[i];
Dsymbol *s = (*decl)[i];
s->semantic(sc);
if (isunion)
sc->offset = 0;
if (aad.sizeok == 2)
{
break;
}
}
sc = sc->pop();
}
}
// If failed due to forward references, unwind and try again later
if (aad.sizeok == 2)
void AnonDeclaration::setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion)
{
//printf("\tAnonDeclaration::setFieldOffset %s %p\n", isunion ? "union" : "struct", this);
if (decl)
{
/* This works by treating an AnonDeclaration as an aggregate 'member',
* so in order to place that member we need to compute the member's
* size and alignment.
*/
size_t fieldstart = ad->fields.dim;
/* Hackishly hijack ad's structsize and alignsize fields
* for use in our fake anon aggregate member.
*/
unsigned savestructsize = ad->structsize;
unsigned savealignsize = ad->alignsize;
ad->structsize = 0;
ad->alignsize = 0;
unsigned offset = 0;
for (size_t i = 0; i < decl->dim; i++)
{
ad->sizeok = 2;
//printf("\tsetting ad->sizeok %p to 2\n", ad);
if (!sc->anonAgg)
{
scope = scx ? scx : new Scope(*sc);
scope->setNoFree();
scope->module->addDeferredSemantic(this);
}
Module::dprogress = dprogress_save;
//printf("\tforward reference %p\n", this);
return;
Dsymbol *s = (*decl)[i];
s->setFieldOffset(ad, &offset, this->isunion);
if (this->isunion)
offset = 0;
}
if (sem == 0)
{ Module::dprogress++;
sem = 1;
//printf("\tcompleted %p\n", this);
}
else
;//printf("\talready completed %p\n", this);
unsigned anonstructsize = ad->structsize;
unsigned anonalignsize = ad->alignsize;
ad->structsize = savestructsize;
ad->alignsize = savealignsize;
// 0 sized structs are set to 1 byte
if (aad.structsize == 0)
if (anonstructsize == 0)
{
aad.structsize = 1;
aad.alignsize = 1;
anonstructsize = 1;
anonalignsize = 1;
}
// Align size of anonymous aggregate
//printf("aad.structalign = %d, aad.alignsize = %d, sc->offset = %d\n", aad.structalign, aad.alignsize, sc->offset);
ad->alignmember(aad.structalign, aad.alignsize, &sc->offset);
//ad->structsize = sc->offset;
//printf("sc->offset = %d\n", sc->offset);
/* Given the anon 'member's size and alignment,
* go ahead and place it.
*/
unsigned anonoffset = AggregateDeclaration::placeField(
poffset,
anonstructsize, anonalignsize, alignment,
&ad->structsize, &ad->alignsize,
isunion);
// Add members of aad to ad
//printf("\tadding members of aad to '%s'\n", ad->toChars());
for (unsigned i = 0; i < aad.fields.dim; i++)
// Add to the anon fields the base offset of this anonymous aggregate
//printf("anon fields, anonoffset = %d\n", anonoffset);
for (size_t i = fieldstart; i < ad->fields.dim; i++)
{
VarDeclaration *v = aad.fields.tdata()[i];
v->offset += sc->offset;
ad->fields.push(v);
VarDeclaration *v = ad->fields[i];
//printf("\t[%d] %s %d\n", i, v->toChars(), v->offset);
v->offset += anonoffset;
}
// Add size of aad to ad
if (adisunion)
{
if (aad.structsize > ad->structsize)
ad->structsize = aad.structsize;
sc->offset = 0;
}
else
{
ad->structsize = sc->offset + aad.structsize;
sc->offset = ad->structsize;
}
if (ad->alignsize < aad.alignsize)
ad->alignsize = aad.alignsize;
}
}
@@ -893,9 +870,9 @@ void AnonDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
buf->writestring("\n{\n");
if (decl)
{
for (unsigned i = 0; i < decl->dim; i++)
for (size_t i = 0; i < decl->dim; i++)
{
Dsymbol *s = decl->tdata()[i];
Dsymbol *s = (*decl)[i];
//buf->writestring(" ");
s->toCBuffer(buf, hgs);
@@ -941,10 +918,10 @@ void PragmaDeclaration::setScope(Scope *sc)
}
else
{
Expression *e = args->tdata()[0];
Expression *e = (*args)[0];
e = e->semantic(sc);
e = e->optimize(WANTvalue | WANTinterpret);
args->tdata()[0] = e;
(*args)[0] = e;
StringExp* se = e->toString();
if (!se)
{
@@ -974,10 +951,15 @@ void PragmaDeclaration::semantic(Scope *sc)
{
for (size_t i = 0; i < args->dim; i++)
{
Expression *e = args->tdata()[i];
Expression *e = (*args)[i];
e = e->semantic(sc);
e = e->optimize(WANTvalue | WANTinterpret);
if (e->op != TOKerror)
e = e->optimize(WANTvalue | WANTinterpret);
if (e->op == TOKerror)
{ errorSupplemental(loc, "while evaluating pragma(msg, %s)", (*args)[i]->toChars());
return;
}
StringExp *se = e->toString();
if (se)
{
@@ -996,11 +978,11 @@ void PragmaDeclaration::semantic(Scope *sc)
error("string expected for library name");
else
{
Expression *e = args->tdata()[0];
Expression *e = (*args)[0];
e = e->semantic(sc);
e = e->optimize(WANTvalue | WANTinterpret);
args->tdata()[0] = e;
(*args)[0] = e;
if (e->op == TOKerror)
goto Lnodecl;
StringExp *se = e->toString();
@@ -1028,7 +1010,7 @@ void PragmaDeclaration::semantic(Scope *sc)
Declaration *d = NULL;
StringExp *s = NULL;
e = args->tdata()[0];
e = (*args)[0];
e = e->semantic(sc);
if (e->op == TOKvar)
{
@@ -1039,14 +1021,14 @@ void PragmaDeclaration::semantic(Scope *sc)
if (!d)
error("first argument of GNU_asm must be a function or variable declaration");
e = args->tdata()[1];
e = (*args)[1];
e = e->semantic(sc);
e = e->optimize(WANTvalue | WANTinterpret);
e = e->toString();
if (e && ((StringExp *)e)->sz == 1)
s = ((StringExp *)e);
else
error("second argument of GNU_asm must be a char string");
error("second argument of GNU_asm must be a character string");
if (d && s)
d->c_ident = Lexer::idPool((char*) s->string);
@@ -1061,10 +1043,10 @@ void PragmaDeclaration::semantic(Scope *sc)
error("function name expected for start address");
else
{
Expression *e = args->tdata()[0];
Expression *e = (*args)[0];
e = e->semantic(sc);
e = e->optimize(WANTvalue | WANTinterpret);
args->tdata()[0] = e;
(*args)[0] = e;
Dsymbol *sa = getDsymbol(e);
if (!sa || !sa->isFuncDeclaration())
error("function name expected for start address, not '%s'", e->toChars());
@@ -1088,7 +1070,7 @@ void PragmaDeclaration::semantic(Scope *sc)
{
for (size_t i = 0; i < args->dim; i++)
{
Expression *e = args->tdata()[i];
Expression *e = (*args)[i];
e = e->semantic(sc);
e = e->optimize(WANTvalue | WANTinterpret);
if (i == 0)
@@ -1110,9 +1092,9 @@ void PragmaDeclaration::semantic(Scope *sc)
Ldecl:
if (decl)
{
for (unsigned i = 0; i < decl->dim; i++)
for (size_t i = 0; i < decl->dim; i++)
{
Dsymbol *s = decl->tdata()[i];
Dsymbol *s = (*decl)[i];
s->semantic(sc);
}
@@ -1144,7 +1126,7 @@ void PragmaDeclaration::toObjFile(int multiobj)
{
assert(args && args->dim == 1);
Expression *e = args->tdata()[0];
Expression *e = (*args)[0];
assert(e->op == TOKstring);
@@ -1172,7 +1154,7 @@ void PragmaDeclaration::toObjFile(int multiobj)
else if (ident == Id::startaddress)
{
assert(args && args->dim == 1);
Expression *e = args->tdata()[0];
Expression *e = (*args)[0];
Dsymbol *sa = getDsymbol(e);
FuncDeclaration *f = sa->isFuncDeclaration();
assert(f);
@@ -1243,8 +1225,8 @@ void ConditionalDeclaration::emitComment(Scope *sc)
* a template, then include(NULL, NULL) will fail.
*/
Dsymbols *d = decl ? decl : elsedecl;
for (unsigned i = 0; i < d->dim; i++)
{ Dsymbol *s = d->tdata()[i];
for (size_t i = 0; i < d->dim; i++)
{ Dsymbol *s = (*d)[i];
s->emitComment(sc);
}
}
@@ -1266,9 +1248,9 @@ void ConditionalDeclaration::setScope(Scope *sc)
//printf("\tConditionalDeclaration::setScope '%s', d = %p\n",toChars(), d);
if (d)
{
for (unsigned i = 0; i < d->dim; i++)
for (size_t i = 0; i < d->dim; i++)
{
Dsymbol *s = d->tdata()[i];
Dsymbol *s = (*d)[i];
s->setScope(sc);
}
@@ -1282,9 +1264,9 @@ void ConditionalDeclaration::importAll(Scope *sc)
//printf("\tConditionalDeclaration::importAll '%s', d = %p\n",toChars(), d);
if (d)
{
for (unsigned i = 0; i < d->dim; i++)
for (size_t i = 0; i < d->dim; i++)
{
Dsymbol *s = d->tdata()[i];
Dsymbol *s = (*d)[i];
s->importAll(sc);
}
@@ -1307,10 +1289,8 @@ void ConditionalDeclaration::addComment(unsigned char *comment)
{
if (d)
{
for (unsigned i = 0; i < d->dim; i++)
{ Dsymbol *s;
s = d->tdata()[i];
for (size_t i = 0; i < d->dim; i++)
{ Dsymbol *s = (*d)[i];
//printf("ConditionalDeclaration::addComment %s\n", s->toChars());
s->addComment(comment);
}
@@ -1330,9 +1310,9 @@ void ConditionalDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
buf->writenl();
if (decl)
{
for (unsigned i = 0; i < decl->dim; i++)
for (size_t i = 0; i < decl->dim; i++)
{
Dsymbol *s = decl->tdata()[i];
Dsymbol *s = (*decl)[i];
buf->writestring(" ");
s->toCBuffer(buf, hgs);
@@ -1346,9 +1326,9 @@ void ConditionalDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
buf->writenl();
buf->writeByte('{');
buf->writenl();
for (unsigned i = 0; i < elsedecl->dim; i++)
for (size_t i = 0; i < elsedecl->dim; i++)
{
Dsymbol *s = elsedecl->tdata()[i];
Dsymbol *s = (*elsedecl)[i];
buf->writestring(" ");
s->toCBuffer(buf, hgs);
@@ -1432,9 +1412,9 @@ void StaticIfDeclaration::semantic(Scope *sc)
addisdone = 1;
}
for (unsigned i = 0; i < d->dim; i++)
for (size_t i = 0; i < d->dim; i++)
{
Dsymbol *s = d->tdata()[i];
Dsymbol *s = (*d)[i];
s->semantic(sc);
}
+6 -3
View File
@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2011 by Digital Mars
// Copyright (c) 1999-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -33,6 +33,7 @@ struct AttribDeclaration : Dsymbol
AttribDeclaration(Dsymbols *decl);
virtual Dsymbols *include(Scope *sc, ScopeDsymbol *s);
int apply(Dsymbol_apply_ft_t fp, void *param);
int addMember(Scope *sc, ScopeDsymbol *s, int memnum);
void setScopeNewSc(Scope *sc,
StorageClass newstc, enum LINK linkage, enum PROT protection, int explictProtection,
@@ -48,6 +49,7 @@ struct AttribDeclaration : Dsymbol
void emitComment(Scope *sc);
const char *kind();
int oneMember(Dsymbol **ps, Identifier *ident);
void setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion);
int hasPointers();
bool hasStaticCtorOrDtor();
void checkCtorConstInit();
@@ -57,7 +59,6 @@ struct AttribDeclaration : Dsymbol
AttribDeclaration *isAttribDeclaration() { return this; }
void toObjFile(int multiobj); // compile to .obj file
int cvMember(unsigned char *p);
};
struct StorageClassDeclaration: AttribDeclaration
@@ -114,12 +115,14 @@ struct AlignDeclaration : AttribDeclaration
struct AnonDeclaration : AttribDeclaration
{
int isunion;
bool isunion;
unsigned alignment;
int sem; // 1 if successful semantic()
AnonDeclaration(Loc loc, int isunion, Dsymbols *decl);
Dsymbol *syntaxCopy(Dsymbol *s);
void semantic(Scope *sc);
void setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
const char *kind();
};
+15 -15
View File
@@ -9,8 +9,8 @@
Complex_ld Complex_ld::div(Complex_ld &x, Complex_ld &y)
{
Complex_ld q;
long double r;
long double den;
longdouble r;
longdouble den;
if (fabs(y.re) < fabs(y.im))
{
@@ -38,9 +38,9 @@ Complex_ld Complex_ld::mul(Complex_ld &x, Complex_ld &y)
return p;
}
long double Complex_ld::abs(Complex_ld &z)
longdouble Complex_ld::abs(Complex_ld &z)
{
long double x,y,ans,temp;
longdouble x,y,ans,temp;
x = fabs(z.re);
y = fabs(z.im);
@@ -64,7 +64,7 @@ long double Complex_ld::abs(Complex_ld &z)
Complex_ld Complex_ld::sqrtc(Complex_ld &z)
{
Complex_ld c;
long double x,y,w,r;
longdouble x,y,w,r;
if (z.re == 0 && z.im == 0)
{
@@ -104,8 +104,8 @@ Complex_ld Complex_ld::sqrtc(Complex_ld &z)
Complex_d Complex_d::div(Complex_d &x, Complex_d &y)
{
Complex_d q;
long double r;
long double den;
longdouble r;
longdouble den;
if (fabs(y.re) < fabs(y.im))
{
@@ -133,9 +133,9 @@ Complex_d Complex_d::mul(Complex_d &x, Complex_d &y)
return p;
}
long double Complex_d::abs(Complex_d &z)
longdouble Complex_d::abs(Complex_d &z)
{
long double x,y,ans,temp;
longdouble x,y,ans,temp;
x = fabs(z.re);
y = fabs(z.im);
@@ -159,7 +159,7 @@ long double Complex_d::abs(Complex_d &z)
Complex_d Complex_d::sqrtc(Complex_d &z)
{
Complex_d c;
long double x,y,w,r;
longdouble x,y,w,r;
if (z.re == 0 && z.im == 0)
{
@@ -199,8 +199,8 @@ Complex_d Complex_d::sqrtc(Complex_d &z)
Complex_f Complex_f::div(Complex_f &x, Complex_f &y)
{
Complex_f q;
long double r;
long double den;
longdouble r;
longdouble den;
if (fabs(y.re) < fabs(y.im))
{
@@ -228,9 +228,9 @@ Complex_f Complex_f::mul(Complex_f &x, Complex_f &y)
return p;
}
long double Complex_f::abs(Complex_f &z)
longdouble Complex_f::abs(Complex_f &z)
{
long double x,y,ans,temp;
longdouble x,y,ans,temp;
x = fabs(z.re);
y = fabs(z.im);
@@ -254,7 +254,7 @@ long double Complex_f::abs(Complex_f &z)
Complex_f Complex_f::sqrtc(Complex_f &z)
{
Complex_f c;
long double x,y,w,r;
longdouble x,y,w,r;
if (z.re == 0 && z.im == 0)
{
+10 -4
View File
@@ -3,6 +3,12 @@
#ifndef BCOMPLEX_H
#define BCOMPLEX_H 1
#if _MSC_VER
#include "longdouble.h"
#else
typedef long double longdouble;
#endif
// Avoid interfering with system <complex.h> and other
// such; roll our own for reliable bootstrapping
@@ -11,7 +17,7 @@ struct Complex_f
static Complex_f div(Complex_f &x, Complex_f &y);
static Complex_f mul(Complex_f &x, Complex_f &y);
static long double abs(Complex_f &z);
static longdouble abs(Complex_f &z);
static Complex_f sqrtc(Complex_f &z);
};
@@ -20,16 +26,16 @@ struct Complex_d
static Complex_d div(Complex_d &x, Complex_d &y);
static Complex_d mul(Complex_d &x, Complex_d &y);
static long double abs(Complex_d &z);
static longdouble abs(Complex_d &z);
static Complex_d sqrtc(Complex_d &z);
};
struct Complex_ld
{ long double re, im;
{ longdouble re, im;
static Complex_ld div(Complex_ld &x, Complex_ld &y);
static Complex_ld mul(Complex_ld &x, Complex_ld &y);
static long double abs(Complex_ld &z);
static longdouble abs(Complex_ld &z);
static Complex_ld sqrtc(Complex_ld &z);
};
+7 -3
View File
@@ -1,5 +1,5 @@
// Copyright (C) 1985-1998 by Symantec
// Copyright (C) 2000-2009 by Digital Mars
// Copyright (C) 2000-2012 by Digital Mars
// All Rights Reserved
// http://www.digitalmars.com
// Written by Walter Bright
@@ -1330,9 +1330,13 @@ struct Aliassym : Symbol { };
#endif
/* Format the identifier for presentation to the user */
char *cpp_prettyident (Symbol *s);
#if SCPP
char *cpp_prettyident (Symbol *s);
inline char *prettyident(Symbol *s) { return CPP ? cpp_prettyident(s) : s->Sident; }
#else
inline char *prettyident(Symbol *s) { return s->Sident; }
#endif
inline char *prettyident(Symbol *s) { return CPP ? cpp_prettyident(s) : s->Sident; }
/**********************************
* Function parameters:
+11 -6
View File
@@ -240,7 +240,7 @@ One and only one of these macros must be set by the makefile:
#if __GNUC__
#define LONGLONG 1
#elif __SC__ < 0x700 || _MSC_VER
#elif __SC__ > 0 && __SC__ < 0x700
#define LONGLONG 0
#else
#define LONGLONG 1 // add in code to support 64 bit integral types
@@ -252,6 +252,12 @@ One and only one of these macros must be set by the makefile:
#define LDOUBLE (config.exe == EX_NT) // support true long doubles
#endif
#if _MSC_VER
#include "longdouble.h"
#else
typedef long double longdouble;
#endif
// Precompiled header variations
#define MEMORYHX (_WINDLL && _WIN32) // HX and SYM files are cached in memory
#define MMFIO (_WIN32 || linux || __APPLE__ || __FreeBSD__ || __OpenBSD__ || __sun&&__SVR4) // if memory mapped files
@@ -444,7 +450,7 @@ typedef unsigned long long targ_ullong;
#endif
typedef float targ_float;
typedef double targ_double;
typedef long double targ_ldouble;
typedef longdouble targ_ldouble;
// Extract most significant register from constant
#define MSREG(p) ((REGSIZE == 2) ? (p) >> 16 : ((sizeof(targ_llong) == 8) ? (p) >> 32 : 0))
@@ -459,6 +465,7 @@ typedef unsigned targ_uns;
#define WCHARSIZE 2 // 2 for WIN32, 4 for linux/OSX/FreeBSD/OpenBSD/Solaris
#define LONGSIZE 4
#define LLONGSIZE 8
#define CENTSIZE 16
#define FLOATSIZE 4
#define DOUBLESIZE 8
#if TARGET_OSX
@@ -482,7 +489,8 @@ typedef unsigned targ_uns;
#define FPTRSIZE tysize[TYfptr]
#define REGMASK 0xFFFF
#if TARGET_LINUX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS || TARGET_OSX
// targ_llong is also used to store host pointers, so it should have at least their size
#if TARGET_LINUX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS || TARGET_OSX || _WIN64
typedef targ_llong targ_ptrdiff_t; /* ptrdiff_t for target machine */
typedef targ_ullong targ_size_t; /* size_t for the target machine */
#else
@@ -585,9 +593,6 @@ typedef int bool;
#define __far
#define __cs
#define __ss
#define near
#define _near
#define __near
#endif
// gcc defines this for us, dmc doesn't, so look for it's __I86__
-2
View File
@@ -28,8 +28,6 @@
#define __stdcall __attribute__ ((__stdcall__))
#define __pascal
#define __near
#define _near
#define __far
#define _far
#define __ss
+12 -15
View File
@@ -663,21 +663,18 @@ __body
{0.0,1.0,PI,LOG2T,LOG2E,LOG2,LN2};
static double dval[7] =
{0.0,1.0,PI,LOG2T,LOG2E,LOG2,LN2};
static long double ldval[7] =
#if __APPLE__ || __FreeBSD__ || __OpenBSD__ || __sun&&__SVR4
#define M_PIl 0x1.921fb54442d1846ap+1L // 3.14159 fldpi
static longdouble ldval[7] =
#if __DMC__ // from math.h
{0.0,1.0,M_PI_L,M_LOG2T_L,M_LOG2E_L,M_LOG2_L,M_LN2_L};
#elif _MSC_VER // struct longdouble constants
{ld_zero, ld_one, ld_pi, ld_log2t, ld_log2e, ld_log2, ld_ln2};
#else // C99 hexadecimal floats (GCC, CLANG, ...)
#define M_PI_L 0x1.921fb54442d1846ap+1L // 3.14159 fldpi
#define M_LOG2T_L 0x1.a934f0979a3715fcp+1L // 3.32193 fldl2t
#define M_LOG2El 0x1.71547652b82fe178p+0L // 1.4427 fldl2e
#define M_LOG2E_L 0x1.71547652b82fe178p+0L // 1.4427 fldl2e
#define M_LOG2_L 0x1.34413509f79fef32p-2L // 0.30103 fldlg2
#define M_LN2l 0x1.62e42fefa39ef358p-1L // 0.693147 fldln2
{0.0,1.0,M_PIl,M_LOG2T_L,M_LOG2El,M_LOG2_L,M_LN2l};
#elif __GNUC__
// BUG: should get proper 80 bit values for these
#define M_LOG2T_L LOG2T
#define M_LOG2_L LOG2
{0.0,1.0,M_PIl,M_LOG2T_L,M_LOG2El,M_LOG2_L,M_LN2l};
#else
{0.0,1.0,M_PI_L,M_LOG2T_L,M_LOG2E_L,M_LOG2_L,M_LN2_L};
#define M_LN2_L 0x1.62e42fefa39ef358p-1L // 0.693147 fldln2
{0.0,1.0,M_PI_L,M_LOG2T_L,M_LOG2E_L,M_LOG2_L,M_LN2_L};
#endif
static char opcode[7 + 1] =
/* FLDZ,FLD1,FLDPI,FLDL2T,FLDL2E,FLDLG2,FLDLN2,0 */
@@ -689,7 +686,7 @@ __body
int sz;
int zero;
void *p;
static char zeros[sizeof(long double)];
static char zeros[sizeof(longdouble)];
if (im == 0)
{
@@ -2302,7 +2299,7 @@ code *opass87(elem *e,regm_t *pretregs)
retregs = mST0;
cr = codelem(e->E2,&retregs,FALSE); // evaluate rvalue
note87(e->E2,0,0);
cl = getlvalue(&cs,e->E1,0);
cl = getlvalue(&cs,e->E1,e->Eoper==OPmodass?mAX:0);
cl = cat(cl,makesure87(e->E2,0,0,0));
cs.Iflags |= ADDFWAIT() ? CFwait : 0;
if (I32)
+1 -1
View File
@@ -17,7 +17,7 @@
#include <stdlib.h>
#include <time.h>
#if __sun&&__SVR4
#if __sun&&__SVR4 || _MSC_VER
#include <alloca.h>
#endif
+1 -16
View File
@@ -302,7 +302,6 @@ STATIC void ecom(elem **pe)
if (tyfloating(tym))
return;
break;
#if TX86
case OPstrcpy:
case OPstrcat:
case OPmemcpy:
@@ -312,9 +311,7 @@ STATIC void ecom(elem **pe)
ecom(&e->E1);
touchfunc(0);
return;
#endif
default: /* other operators */
#if TX86
#ifdef DEBUG
if (!EBIN(e)) WROP(e->Eoper);
#endif
@@ -334,16 +331,6 @@ STATIC void ecom(elem **pe)
ecom(&e->E1);
ecom(&e->E2);
break;
#else
#ifdef DEBUG
if (!EOP(e)) WROP(e->Eoper);
#endif
assert(EOP(e));
ecom(&e->E1);
if (EBIN(e))
ecom(&e->E2); /* eval left first */
break;
#endif
case OPstring:
case OPaddr:
case OPbit:
@@ -620,12 +607,10 @@ STATIC void touchfunc(int flag)
}
break;
case OPind:
#if TX86
case OPstrlen:
case OPstrcmp:
case OPmemcmp:
case OPbt:
#endif
goto L1;
#if TARGET_SEGMENTED
case OPvp_fp:
@@ -653,7 +638,7 @@ STATIC void touchstar()
for (i = touchstari; i < hcstop; i++)
{ e = hcstab[i].Helem;
if (e && (e->Eoper == OPind || e->Eoper == OPbt) /*&& !(e->Ety & mTYconst)*/)
if (e && (e->Eoper == OPind || e->Eoper == OPbt) )
hcstab[i].Helem = NULL;
}
touchstari = hcstop;
+1 -1
View File
@@ -519,7 +519,7 @@ void cv_init()
* Return number of bytes required to store a numeric leaf.
*/
inline unsigned cv4_numericbytes(targ_size_t value)
unsigned cv4_numericbytes(targ_size_t value)
{ unsigned u;
if (value < 0x8000)
+1 -1
View File
@@ -58,7 +58,7 @@ extern Cgcv cgcv;
debtyp_t * debtyp_alloc(unsigned length);
int cv_stringbytes(const char *name);
inline unsigned cv4_numericbytes(targ_size_t value);
unsigned cv4_numericbytes(targ_size_t value);
void cv4_storenumeric(unsigned char *p,targ_size_t value);
idx_t cv_debtyp ( debtyp_t *d );
int cv_namestring ( unsigned char *p , const char *name );
+72 -13
View File
@@ -581,12 +581,6 @@ STATIC elem * elstrcpy(elem *e)
#endif
case OPstring:
/* Replace strcpy(e1,"string") with memcpy(e1,"string",sizeof("string")) */
#if 0
// As memcpy
e->Eoper = OPmemcpy;
elem *en = el_long(TYsize_t, strlen(e->E2->EV.ss.Vstring) + 1);
e->E2 = el_bin(OPparam,TYvoid,e->E2,en);
#else
// As streq
e->Eoper = OPstreq;
type *t = type_allocn(TYarray, tschar);
@@ -599,7 +593,6 @@ STATIC elem * elstrcpy(elem *e)
e = el_bin(OPcomma,e->Ety,e,el_copytree(e->E1->E1));
if (el_sideeffect(e->E2))
fixside(&e->E1->E1->E1,&e->E2);
#endif
e = optelem(e,TRUE);
break;
}
@@ -741,7 +734,6 @@ STATIC elem * elmemxxx(elem *e)
el_free(ex);
return optelem(e, TRUE);
}
#if 1
// Convert OPmemcpy to OPstreq
e->Eoper = OPstreq;
type *t = type_allocn(TYarray, tschar);
@@ -761,7 +753,6 @@ STATIC elem * elmemxxx(elem *e)
if (el_sideeffect(e->E2))
fixside(&e->E1->E1->E1,&e->E2);
return optelem(e,TRUE);
#endif
}
break;
@@ -2520,7 +2511,6 @@ CEXTERN elem * elstruct(elem *e)
if (e->ET)
switch ((int) type_size(e->ET))
{
#if TX86
case CHARSIZE: tym = TYchar; goto L1;
case SHORTSIZE: tym = TYshort; goto L1;
case LONGSIZE: tym = TYlong; goto L1;
@@ -2547,7 +2537,6 @@ CEXTERN elem * elstruct(elem *e)
break;
}
break;
#endif
case 0:
if (e->Eoper == OPstreq)
{ e->Eoper = OPcomma;
@@ -3853,6 +3842,78 @@ STATIC elem * elshr(elem *e)
return e;
}
/***********************************
* Handle OPmsw.
*/
elem *elmsw(elem *e)
{
#if TX86
tym_t ty = e->Ety;
elem *e1 = e->E1;
if (OPTIMIZER &&
tysize(e1->Ety) == LLONGSIZE &&
tysize(ty) == LONGSIZE)
{
// Replace (int)(msw (long)x) with (int)*(&x+4)
if (e1->Eoper == OPvar)
{
e1->EV.sp.Voffset += LONGSIZE; // address high dword in longlong
if (I64)
// Cannot independently address high word of register
e1->EV.sp.Vsym->Sflags &= ~GTregcand;
e1->Ety = ty;
e = optelem(e1,TRUE);
}
// Replace (int)(msw (long)*x) with (int)*(&*x+4)
else if (e1->Eoper == OPind)
{
e1 = el_una(OPind,ty,
el_bin(OPadd,e1->E1->Ety,
el_una(OPaddr,e1->E1->Ety,e1),
el_int(TYint,LONGSIZE)));
e = optelem(e1,TRUE);
}
else
{
e = evalu8(e);
}
}
else if (OPTIMIZER && I64 &&
tysize(e1->Ety) == CENTSIZE &&
tysize(ty) == LLONGSIZE)
{
// Replace (long)(msw (cent)x) with (long)*(&x+8)
if (e1->Eoper == OPvar)
{
e1->EV.sp.Voffset += LLONGSIZE; // address high dword in longlong
e1->Ety = ty;
e = optelem(e1,TRUE);
}
// Replace (long)(msw (cent)*x) with (long)*(&*x+8)
else if (e1->Eoper == OPind)
{
e1 = el_una(OPind,ty,
el_bin(OPadd,e1->E1->Ety,
el_una(OPaddr,e1->E1->Ety,e1),
el_int(TYint,LLONGSIZE)));
e = optelem(e1,TRUE);
}
else
{
e = evalu8(e);
}
}
else
{
e = evalu8(e);
}
#endif
return e;
}
/***********************************
* Handle OPpair, OPrpair.
*/
@@ -4147,7 +4208,6 @@ beg:
goto retnull;
leftgoal = rightgoal;
break;
#if TX86
case OPmemcmp:
if (!goal)
{ // So OPmemcmp is removed cleanly
@@ -4156,7 +4216,6 @@ beg:
}
leftgoal = rightgoal;
break;
#endif
}
e1 = e->E1;
+6 -6
View File
@@ -1129,7 +1129,7 @@ void obj_user(const char *p)
STATIC void obj_defaultlib()
{
char library[4]; // default library
static const char model[MEMMODELS] = "SMCLV";
static const char model[MEMMODELS+1] = "SMCLV";
#if MARS
memcpy(library,"SM?",4);
@@ -1264,7 +1264,7 @@ void obj_theadr(const char *modname)
void obj_compiler()
{
static const char compiler[] = "\0\xDBDigital Mars C/C++"
static const char compiler[] = "\0\xDB" "Digital Mars C/C++"
VERSION
; // compiled by ...
@@ -1292,7 +1292,7 @@ STATIC void objheader(char *csegname)
int texti = 8; // index of _TEXT
static char comment[] = {0,0x9D,'0','?','O'}; // memory model
static char model[MEMMODELS] = "smclv";
static char model[MEMMODELS+1] = "smclv";
static char exten[] = {0,0xA1,1,'C','V'}; // extended format
static char pmdeb[] = {0x80,0xA1,1,'H','L','L',0}; // IBM PM debug format
@@ -1606,7 +1606,7 @@ void obj_funcptr(Symbol *s)
{
// We need to always put out the segments in triples, so that the
// linker will put them in the correct order.
static char lnames[4][5+4+5] =
static char lnames[4][5+4+5+1] =
{ "\03XIB\02XI\03XIE", // near constructor
"\03XCB\02XC\03XCE", // near destructor
"\04XIFB\03XIF\04XIFE", // far constructor
@@ -2137,7 +2137,7 @@ size_t obj_mangle(Symbol *s,char *dest)
// Use as max length the max length lib.exe can handle
// Use 5 as length of _ + @nnn
#define LIBIDMAX ((512 - 0x25 - 3 - 4) - 5)
// #define LIBIDMAX ((512 - 0x25 - 3 - 4) - 5)
#define LIBIDMAX 128
if (len > LIBIDMAX)
//if (len > IDMAX)
@@ -2954,7 +2954,7 @@ unsigned obj_bytes(int seg,targ_size_t offset,unsigned nbytes, void *p)
while (nbytes)
{ obj_byte(seg,offset,*(char *)p);
offset++;
((char *)p)++;
p = ((char *)p) + 1;
nbytes--;
lr = SegData[seg]->ledata;
if (lr->i + nbytes <= LEDATAMAX)
+29
View File
@@ -92,6 +92,32 @@ code *orthxmm(elem *e, regm_t *pretregs)
unsigned op = xmmoperator(e1->Ety, e->Eoper);
unsigned rreg = findreg(rretregs);
// float + ifloat is not actually addition
if ((e->Eoper == OPadd || e->Eoper == OPmin) &&
((tyreal(e1->Ety) && tyimaginary(e2->Ety)) ||
(tyreal(e2->Ety) && tyimaginary(e1->Ety))))
{
retregs |= rretregs;
c = cat(c, cr);
if (e->Eoper == OPmin)
{
unsigned nretregs = XMMREGS & ~retregs;
unsigned sreg; // hold sign bit
unsigned sz = tysize[tybasic(e1->Ety)];
c = cat(c,allocreg(&nretregs,&sreg,e2->Ety));
targ_size_t signbit = 0x80000000;
if (sz == 8)
signbit = 0x8000000000000000LL;
c = cat(c, movxmmconst(sreg, sz, signbit, 0));
c = cat(c, getregs(nretregs));
unsigned xop = (sz == 8) ? XORPD : XORPS; // XORPD/S rreg,sreg
c = cat(c, gen2(CNIL,xop,modregxrmx(3,rreg-XMM0,sreg-XMM0)));
}
if (retregs != *pretregs)
c = cat(c, fixresult(e,retregs,pretregs));
return c;
}
code *cg;
if (OTrel(e->Eoper))
{
@@ -482,8 +508,10 @@ unsigned xmmload(tym_t tym)
switch (tybasic(tym))
{
case TYfloat:
case TYcfloat:
case TYifloat: op = LODSS; break; // MOVSS
case TYdouble:
case TYcdouble:
case TYidouble: op = LODSD; break; // MOVSD
case TYfloat4: op = LODAPS; break; // MOVAPS
@@ -520,6 +548,7 @@ unsigned xmmstore(tym_t tym)
case TYullong:
case TYuint:
case TYlong:
case TYcdouble:
case TYcfloat: op = STOSD; break; // MOVSD
case TYfloat4: op = STOAPS; break; // MOVAPS
+1 -1
View File
@@ -17,7 +17,7 @@
#include <stdlib.h>
#include <time.h>
#if __sun&&__SVR4
#if __sun&&__SVR4 || _MSC_VER
#include <alloca.h>
#endif
+6 -6
View File
@@ -631,7 +631,7 @@ void outblkexitcode(block *bl, code*& c, int& anyspill, const char* sflsave, sym
code_orrex(cs, REX_W);
}
}
cs = genc(cs,0xE8,0,0,0,FLblock,(long)list_block(bf->Bsucc));
cs = genc(cs,0xE8,0,0,0,FLblock,(targ_size_t)list_block(bf->Bsucc));
if (nalign)
{ cs = genc2(cs,0x81,modregrm(3,0,SP),nalign); // ADD ESP,nalign
if (I64)
@@ -694,7 +694,7 @@ void outblkexitcode(block *bl, code*& c, int& anyspill, const char* sflsave, sym
code_orrex(c, REX_W);
}
// CALL bl->Bsucc
c = genc(c,0xE8,0,0,0,FLblock,(long)list_block(bl->Bsucc));
c = genc(c,0xE8,0,0,0,FLblock,(targ_size_t)list_block(bl->Bsucc));
if (nalign)
{ c = genc2(c,0x81,modregrm(3,0,SP),nalign); // ADD ESP,nalign
if (I64)
@@ -711,7 +711,7 @@ void outblkexitcode(block *bl, code*& c, int& anyspill, const char* sflsave, sym
// corresponding BC_ret
//assert(list_block(list_next(bl->Bsucc))->BC == BC_ret);
// PUSH &succ
c = genc(c,0x68,0,0,0,FLblock,(long)list_block(list_next(bl->Bsucc)));
c = genc(c,0x68,0,0,0,FLblock,(targ_size_t)list_block(list_next(bl->Bsucc)));
nextb = list_block(bl->Bsucc);
goto L2;
}
@@ -811,7 +811,7 @@ void outblkexitcode(block *bl, code*& c, int& anyspill, const char* sflsave, sym
c = cat(c,nteh_gensindex(-1));
gensaverestore(retregs,&cs,&cr);
cs = genc(cs,0xE8,0,0,0,FLblock,(long)list_block(bf->Bsucc));
cs = genc(cs,0xE8,0,0,0,FLblock,(targ_size_t)list_block(bf->Bsucc));
bl->Bcode = cat3(c,cs,cr);
}
else
@@ -836,7 +836,7 @@ void outblkexitcode(block *bl, code*& c, int& anyspill, const char* sflsave, sym
}
}
// CALL bf->Bsucc
cs = genc(cs,0xE8,0,0,0,FLblock,(long)list_block(bf->Bsucc));
cs = genc(cs,0xE8,0,0,0,FLblock,(targ_size_t)list_block(bf->Bsucc));
if (nalign)
{ cs = genc2(cs,0x81,modregrm(3,0,SP),nalign); // ADD ESP,nalign
if (I64)
@@ -5179,7 +5179,7 @@ static char *pgen;
#define GEN(c) (*pgen++ = (c))
#define GENP(n,p) (memcpy(pgen,(p),(n)), pgen += (n))
#if ELFOBJ || MACHOBJ
#if ELFOBJ || MACHOBJ || _MSC_VER
#define FLUSH() if (pgen-bytes) cod3_flush()
#else
#define FLUSH() ((pgen - bytes) && cod3_flush())
+11 -8
View File
@@ -32,14 +32,17 @@ struct Declaration;
#define SI 6
#define DI 7
#define R8 8
#define R9 9
#define R10 10
#define R11 11
#define R12 12
#define R13 13
#define R14 14
#define R15 15
enum // #defining R12-R15 interfere with setjmps' _JUMP_BUFFER members
{
R8 = 8,
R9 = 9,
R10 = 10,
R11 = 11,
R12 = 12,
R13 = 13,
R14 = 14,
R15 = 15,
};
#define XMM0 16
#define XMM1 17
+1 -1
View File
@@ -624,7 +624,7 @@ char *template_mangle(symbol *s,param_t *arglist)
}
p = (char *)&d;
// ni = tysize[TYdouble];
ni = sizeof(long double); // just until new unmangler is in
ni = sizeof(longdouble); // just until new unmangler is in
L1:
a[1] = 0;
n = cpp_catname(n,a);
+10 -1
View File
@@ -1,5 +1,5 @@
// Copyright (C) 1985-1998 by Symantec
// Copyright (C) 2000-2009 by Digital Mars
// Copyright (C) 2000-2012 by Digital Mars
// All Rights Reserved
// http://www.digitalmars.com
// Written by Walter Bright
@@ -201,8 +201,17 @@ void WReqn(elem *e)
dbg_printf("%g ",e->EV.Vdouble);
break;
case TYldouble:
#if _MSC_VER
{
char buffer[3 + 3 * sizeof(targ_ldouble) + 1];
ld_sprint(buffer, 'g', e->EV.Vldouble);
dbg_printf("%s ",buffer);
break;
}
#else
dbg_printf("%Lg ",e->EV.Vldouble);
break;
#endif
case TYcent:
case TYucent:
dbg_printf("%lld+%lld ", e->EV.Vcent.msw, e->EV.Vcent.lsw);
-4
View File
@@ -60,10 +60,8 @@ struct dt_t
#define DTpbytes _DU._DN.DTpbytes_
unsigned DTnbytes_; // # of bytes
#define DTnbytes _DU._DN.DTnbytes_
#if TX86
int DTseg_; // segment it went into
#define DTseg _DU._DN.DTseg_
#endif
targ_size_t DTabytes_; // offset of abytes for DTabytes
#define DTabytes _DU._DN.DTabytes_
}_DN;
@@ -90,11 +88,9 @@ enum
DT_ibytes, // 8
};
#if TX86
dt_t *dt_calloc(char dtx);
void dt_free(dt_t *);
void dt_term(void);
#endif
dt_t **dtnbytes(dt_t **,targ_size_t,const char *);
dt_t **dtabytes(dt_t **pdtend,tym_t ty, targ_size_t offset, targ_size_t size, const char *ptr);
+6 -3
View File
@@ -1621,9 +1621,12 @@ unsigned dwarf_typidx(type *t)
tym_t ty;
ty = tybasic(t->Tty);
idx = typidx_tab[ty];
if (idx)
return idx;
if (!(t->Tnext && (ty == TYucent || ty == TYcent)))
{ // use cached basic type if it's not TYdarray or TYdelegate
idx = typidx_tab[ty];
if (idx)
return idx;
}
unsigned char ate;
ate = tyuns(t->Tty) ? DW_ATE_unsigned : DW_ATE_signed;
+17 -66
View File
@@ -93,7 +93,6 @@ void el_reset()
memset(stable,0,sizeof(stable));
}
#if TX86
/************************
* Terminate el package.
*/
@@ -101,9 +100,7 @@ void el_reset()
void el_term()
{
#if TERMCODE
int i;
for (i = 0; i < arraysize(stable); i++)
for (int i = 0; i < arraysize(stable); i++)
mem_free(stable[i].p);
#ifdef DEBUG
@@ -122,7 +119,6 @@ void el_term()
assert(elcount == 0);
#endif
}
#endif
/***********************
* Allocate an element.
@@ -873,12 +869,7 @@ void el_toconst(elem *e)
{
elem_debug(e);
assert(PARSER);
#if TX86
if (e->Eoper == OPvar && e->EV.sp.Vsym->Sflags & SFLvalue)
#else
if (e->Eoper == OPvar && e->EV.sp.Vsym->Sflags & SFLvalue &&
tybasic(e->ET->Tty) != TYstruct)
#endif
{ elem *es = e->EV.sp.Vsym->Svalue;
type_debug(e->ET);
@@ -1053,7 +1044,6 @@ int el_sideeffect(elem *e)
el_sideeffect(e->E2)));
}
#if TX86
/******************************
* Input:
* ea lvalue (might be an OPbit)
@@ -1100,7 +1090,6 @@ int el_depends(elem *ea,elem *eb)
Lnodep:
return 0;
}
#endif
/***************************************
* Allocate localgot symbol.
@@ -1570,12 +1559,12 @@ elem * el_var(symbol *s)
e->Eoper = OPvar;
e->EV.sp.Vsym = s;
if (SCPP && PARSER)
#if TX86 && TARGET_WINDOS
{ type *t = s->Stype;
type_debug(t);
e->ET = t;
t->Tcount++;
#if TARGET_WINDOS
switch (t->Tty & (mTYimport | mTYthread))
{ case mTYimport:
obj_import(e);
@@ -1613,18 +1602,11 @@ elem * el_var(symbol *s)
break;
case mTYthread | mTYimport:
assert(SCPP);
#if SCPP
tx86err(EM_thread_and_dllimport,s->Sident); // can't be both thread and import
#endif
break;
}
}
#else
{ type_debug(s->Stype);
e->ET = s->Stype;
e->ET->Tcount++;
}
#endif
}
else
e->Ety = s->ty();
return e;
@@ -2037,8 +2019,13 @@ void shrinkLongDoubleConstantIfPossible(elem *e)
* Use 'volatile' to prevent optimizer from folding away the conversions,
* and thereby missing the truncation in the conversion to double.
*/
#if _MSC_VER
volatile_longdouble v = e->EV.Vldouble;
#else
volatile long double v = e->EV.Vldouble;
#endif
volatile double vDouble;
*(&vDouble) = v;
if (v == vDouble) // This will fail if compiler does NaN incorrectly!
{
@@ -2217,10 +2204,8 @@ elem *el_ctor(elem *ector,elem *e,symbol *sdtor)
}
if (!sdtor || ector->Eoper == OPcall ||
(ector->Eoper == OPrelconst && !(sytab[ector->EV.sp.Vsym->Sclass] & SCSS))
#if TX86
// Not ambient memory model
|| (tyfarfunc(sdtor->ty()) ? !LARGECODE : LARGECODE)
#endif
)
{
el_free(ector);
@@ -2327,11 +2312,7 @@ L1:
if ((tym = typemask(n1)) != (tym2 = typemask(n2)))
{
#if TX86
if ((tym & ~mTYbasic) != (tym2 & ~mTYbasic))
#else
if ((tym & ~mTYbasic & ~mTYMAN) != (tym2 & ~mTYbasic & ~mTYMAN))
#endif
{
if (!(gmatch2 & 2))
goto nomatch;
@@ -2441,7 +2422,6 @@ L1:
else
goto case_long;
#if TX86
#if JHANDLE
case TYjhandle:
#endif
@@ -2459,7 +2439,6 @@ L1:
{ assert(NPTRSIZE == LLONGSIZE);
goto case_llong;
}
#endif
case TYbool:
case TYchar:
@@ -2717,7 +2696,7 @@ L1:
Ushort:
result = e->EV.Vushort;
break;
#if SCPP && TX86
#if SCPP
case TYenum:
assert(PARSER);
ty = e->ET->Tnext->Tty;
@@ -2869,7 +2848,6 @@ targ_ldouble el_toldouble(elem *e)
elem_debug(e);
assert(cnst(e));
#if TX86
switch (tybasic(typemask(e)))
{
case TYfloat:
@@ -2889,28 +2867,6 @@ targ_ldouble el_toldouble(elem *e)
result = 0;
break;
}
#else
switch (tysize[tybasic(typemask(e))])
{
case FLOATSIZE: // TYfloat
result = e->EV.Vfloat;
break;
case DOUBLESIZE: // TYdouble
result = e->EV.Vdouble;
break;
#if DOUBLESIZE != LNGDBLSIZE
case LNGDBLSIZE: // TYldouble
#ifdef LNGHDBLSIZE
case LNGHDBLSIZE:
#endif
result = e->EV.Vldouble;
break;
#endif
default:
result = 0;
break;
}
#endif
return result;
}
@@ -3096,10 +3052,8 @@ void elem_print(elem *e)
case TYint:
case TYuint:
case TYvoid: /* in case (void)(1) */
#if TX86
if (tysize[TYint] == LONGSIZE)
goto L1;
#endif
case TYshort:
case TYwchar_t:
case TYushort:
@@ -3141,9 +3095,16 @@ void elem_print(elem *e)
dbg_printf("%g ",(double)e->EV.Vdouble);
break;
case TYldouble:
{
#if _MSC_VER
char buffer[3 + 3 * sizeof(targ_ldouble) + 1];
ld_sprint(buffer, 'g', e->EV.Vldouble);
dbg_printf("%s ", buffer);
#else
dbg_printf("%Lg ", e->EV.Vldouble);
#endif
break;
}
case TYifloat:
dbg_printf("%gfi ", (double)e->EV.Vfloat);
break;
@@ -3252,11 +3213,7 @@ void el_hydrate(elem **pe)
//if (tybasic(e->ET->Tty) == TYmemptr)
//el_hydrate(&e->EV.sm.ethis);
case OPvar:
#if TX86
symbol_hydrate(&e->EV.sp.Vsym);
#else
ph_hydrate(&e->EV.sp.Vsym);
#endif
symbol_debug(e->EV.sp.Vsym);
break;
}
@@ -3288,10 +3245,8 @@ void el_dehydrate(elem **pe)
return;
#endif
type_dehydrate(&e->ET);
#if TX86
if (configv.addlinenumbers)
srcpos_dehydrate(&e->Esrcpos);
#endif
if (EOP(e))
{ el_dehydrate(&e->E1);
if (EBIN(e))
@@ -3312,11 +3267,7 @@ void el_dehydrate(elem **pe)
//if (tybasic(e->ET->Tty) == TYmemptr)
//el_dehydrate(&e->EV.sm.ethis);
case OPvar:
#if TX86
symbol_dehydrate(&e->EV.sp.Vsym);
#else
ph_dehydrate(&e->EV.sp.Vsym);
#endif
break;
}
}
+8 -68
View File
@@ -78,7 +78,7 @@ static int resolve_sizeof;
*/
#if __DMC__
long double _modulo(long double x, long double y)
longdouble _modulo(longdouble x, longdouble y)
{ short sw;
__asm
@@ -384,7 +384,6 @@ elem *poptelem(elem *e)
L3:
e = selecte1(e,e->ET);
e->Eoper = OPrelconst;
#if 1
// If this is an address of a function template,
// try to expand the template if it's got an explicit
// parameter list.
@@ -402,56 +401,16 @@ elem *poptelem(elem *e)
type_settype(&e->ET, newpointer(s->Stype));
}
}
#endif
}
break;
case OPind:
e->E1 = e1 = poptelem(e->E1);
#if TX86
if (e1->Eoper == OPrelconst)
{ /* convert *(&var) to var */
e = selecte1(e,e->ET);
e->Eoper = OPvar;
}
#else
if (e1->Eoper == OPrelconst)
{
unsigned to_sz = tysize(tym_conv(e->ET));
unsigned frm_sz = tysize(tym_conv(e1->ET));
if (tyfunc(tybasic(e->ET->Tty)))
to_sz = LONGSIZE;
else if (tybasic(e->ET->Tty) == TYstruct || tybasic(e->ET->Tty) == TYarray)
{
to_sz = LONGSIZE;
e1->ET = e->ET;
}
if(to_sz == frm_sz)
{ /* convert *(&var) to var */
doit:
e = selecte1(e,e->ET);
e->Eoper = OPvar;
}
else /* handle the most common cases for now */
{ unsigned offset = e1->Eoffset;
switch(to_sz)
{
case SHORTSIZE:
if (frm_sz == LONGSIZE && (offset%LONGSIZE) == SHORTSIZE)
goto doit;
break;
case CHARSIZE:
if (frm_sz == LONGSIZE &&
offset%(LONGSIZE-CHARSIZE) == CHARSIZE)
goto doit;
if (frm_sz == SHORTSIZE && offset&1)
goto doit;
break;
}
}
}
#endif
break;
#if TARGET_SEGMENTED
case OPnp_fp:
@@ -640,13 +599,13 @@ elem * evalu8(elem *e)
d1 = el_toldouble(e1);
tym = tybasic(typemask(e1)); /* type of op is type of left child */
#if TX86 && SCPP
#if TARGET_SEGMENTED && SCPP
// Huge pointers are always evaluated at runtime
if (tym == TYhptr && (l1 != 0 || l2 != 0))
return e;
#endif
esave = *e;
#if !__OpenBSD__
#if TX86 && !__OpenBSD__
_clear87();
#endif
}
@@ -844,7 +803,7 @@ elem * evalu8(elem *e)
break;
default:
#if TX86
#if TARGET_SEGMENTED
if (intsize == 2)
{ if (tyfv(tym))
e->EV.Vlong = (l1 & 0xFFFF0000) |
@@ -1039,7 +998,7 @@ elem * evalu8(elem *e)
break;
default:
#if TX86
#if TARGET_SEGMENTED
if (intsize == 2 &&
tyfv(tym) && tysize[tym2] == 2)
e->EV.Vllong = (l1 & 0xFFFF0000) |
@@ -1589,7 +1548,6 @@ elem * evalu8(elem *e)
break;
case OPneg:
#if TX86
// Avoid converting NANS to NAN
memcpy(&e->EV.Vcldouble,&e1->EV.Vcldouble,sizeof(e->EV.Vcldouble));
switch (tym)
@@ -1622,25 +1580,8 @@ elem * evalu8(elem *e)
e->EV.Vllong = -l1;
break;
}
#else
switch (tym)
{ case TYdouble:
e->EV.Vdouble = -e1->EV.Vdouble;
break;
case TYfloat:
e->EV.Vfloat = -e1->EV.Vfloat;
break;
case TYldouble:
e->EV.Vldouble = -d1;
break;
default:
e->EV.Vllong = -l1;
break;
}
#endif
break;
case OPabs:
#if 1
switch (tym)
{
case TYdouble:
@@ -1674,7 +1615,6 @@ elem * evalu8(elem *e)
break;
}
break;
#endif
case OPsqrt:
case OPrndtol:
case OPsin:
@@ -1745,7 +1685,7 @@ elem * evalu8(elem *e)
case TYcfloat:
if (isnan(e1->EV.Vcfloat.re) || isnan(e1->EV.Vcfloat.im) ||
isnan(e2->EV.Vcfloat.re) || isnan(e2->EV.Vcfloat.im))
i ^= 1;
;
else
i ^= (int)((e1->EV.Vcfloat.re == e2->EV.Vcfloat.re) &&
(e1->EV.Vcfloat.im == e2->EV.Vcfloat.im));
@@ -1753,7 +1693,7 @@ elem * evalu8(elem *e)
case TYcdouble:
if (isnan(e1->EV.Vcdouble.re) || isnan(e1->EV.Vcdouble.im) ||
isnan(e2->EV.Vcdouble.re) || isnan(e2->EV.Vcdouble.im))
i ^= 1;
;
else
i ^= (int)((e1->EV.Vcdouble.re == e2->EV.Vcdouble.re) &&
(e1->EV.Vcdouble.im == e2->EV.Vcdouble.im));
@@ -1761,7 +1701,7 @@ elem * evalu8(elem *e)
case TYcldouble:
if (isnan(e1->EV.Vcldouble.re) || isnan(e1->EV.Vcldouble.im) ||
isnan(e2->EV.Vcldouble.re) || isnan(e2->EV.Vcldouble.im))
i ^= 1;
;
else
i ^= (int)((e1->EV.Vcldouble.re == e2->EV.Vcldouble.re) &&
(e1->EV.Vcldouble.im == e2->EV.Vcldouble.im));
-6
View File
@@ -805,12 +805,10 @@ void main()
)
break;
#endif
#if TX86
case OPstrlen:
case OPstrcmp:
case OPmemcmp:
case OPbt: // OPbt is like OPind
#endif
vec_setbit(i,defkill);
vec_setbit(i,starkill);
break;
@@ -1339,11 +1337,9 @@ STATIC void accumlv(vec_t GEN,vec_t KILL,elem *n)
case OPcall:
case OPcallns:
#if TX86
case OPstrcpy:
case OPmemcpy:
case OPmemset:
#endif
#ifdef DEBUG
assert(OTrtol(op));
#endif
@@ -1351,14 +1347,12 @@ STATIC void accumlv(vec_t GEN,vec_t KILL,elem *n)
accumlv(GEN,KILL,n->E1);
goto L1;
#if TX86
case OPstrcat:
#ifdef DEBUG
assert(!OTrtol(op));
#endif
accumlv(GEN,KILL,n->E1);
accumlv(GEN,KILL,n->E2);
#endif
L1:
vec_orass(GEN,ambigsym);
vec_subass(GEN,KILL);
+8 -4
View File
@@ -115,11 +115,14 @@ elem *exp2_copytotemp(elem *e);
/* util.c */
#if __clang__
void util_exit(int) __attribute__((analyzer_noreturn));
void util_assert(char *, int) __attribute__((analyzer_noreturn));
void util_exit(int) __attribute__((noreturn));
void util_assert(const char *, int) __attribute__((noreturn));
#elif _MSC_VER
__declspec(noreturn) void util_exit(int);
__declspec(noreturn) void util_assert(const char *, int);
#else
void util_exit(int);
void util_assert(char *, int);
void util_assert(const char *, int);
#if __DMC__
#pragma ZTC noreturn(util_exit)
#pragma ZTC noreturn(util_assert)
@@ -512,7 +515,8 @@ Symbol *symboldata(targ_size_t offset,tym_t ty);
int dom(block *A , block *B);
unsigned revop(unsigned op);
unsigned invrel(unsigned op);
int binary(const char *p, const char __near * __near *tab, int high);
int binary(const char *p, const char ** tab, int high);
int binary(const char *p, size_t len, const char ** tab, int high);
/* go.c */
void go_term(void);
+1 -11
View File
@@ -16,7 +16,7 @@
#include <stdlib.h>
#include <time.h>
#if __sun&&__SVR4
#if __sun&&__SVR4 || _MSC_VER
#include <alloca.h>
#endif
@@ -269,9 +269,7 @@ Loop:
local_remove(LFambigdef | LFambigref);
}
break;
#if TX86
case OPstrlen:
#endif
case OPind:
local_exp(e->E1,1);
local_ambigref();
@@ -316,7 +314,6 @@ Loop:
local_remove(LFfloat | LFambigref | LFambigdef);
break;
#if TX86
case OPmemset:
local_exp(e->E2,1);
if (e->E1->Eoper == OPvar)
@@ -334,7 +331,6 @@ Loop:
local_exp(e->E1,1);
local_ambigdef();
break;
#endif
case OPvar:
s = e->EV.sp.Vsym;
@@ -590,23 +586,19 @@ STATIC int local_getflags(elem *e,symbol *s)
case OPcallns:
case OPnewarray:
case OPmultinewarray:
#if TX86
case OPstrcat:
case OPstrcpy:
case OPmemcpy:
case OPbtc:
case OPbtr:
case OPbts:
#endif
case OPstrctor:
flags |= LFambigref | LFambigdef;
break;
#if TX86
case OPmemset:
flags |= LFambigdef;
break;
#endif
case OPvar:
if (e->EV.sp.Vsym == s)
@@ -618,12 +610,10 @@ STATIC int local_getflags(elem *e,symbol *s)
case OPind:
case OParray:
case OPfield:
#if TX86
case OPstrlen:
case OPstrcmp:
case OPmemcmp:
case OPbt:
#endif
flags |= LFambigref;
break;
+3 -7
View File
@@ -958,7 +958,6 @@ STATIC void markinvar(elem *n,vec_t rd)
markinvar(n->E1,rd);
break;
#if TX86
case OPstrcpy:
case OPstrcat:
case OPmemcpy:
@@ -974,7 +973,6 @@ STATIC void markinvar(elem *n,vec_t rd)
markinvar(n->E2,rd);
updaterd(n,rd,NULL);
break;
#endif
case OPucall:
markinvar(n->E1,rd);
/* FALL-THROUGH */
@@ -987,20 +985,20 @@ STATIC void markinvar(elem *n,vec_t rd)
case OPstrpar:
case OPstrctor:
case OPvector:
#if TX86
case OPvoid:
case OPstrlen:
#if TX86
case OPinp:
#endif
markinvar(n->E1,rd);
break;
case OPcond:
case OPparam:
#if TX86
case OPoutp:
case OPstrcmp:
case OPmemcmp:
case OPbt: // OPbt is like OPind, assume not LI
#if TX86
case OPoutp:
#endif
markinvar(n->E1,rd);
markinvar(n->E2,rd);
@@ -1057,12 +1055,10 @@ STATIC void markinvar(elem *n,vec_t rd)
case OPsin:
case OPcos:
case OPrint:
#if TX86
case OPsetjmp:
case OPbsf:
case OPbsr:
case OPbswap:
#endif
#if TARGET_SEGMENTED
case OPvp_fp: /* BUG for MacHandles */
case OPnp_f16p: case OPf16p_np: case OPoffset: case OPnp_fp:
+4 -4
View File
@@ -101,15 +101,15 @@ Html::Html(const char *sourcename, unsigned char *base, unsigned length)
void Html::error(const char *format, ...)
{
printf("%s(%d) : HTML Error: ", sourcename, linnum);
fprintf(stderr, "%s(%d) : HTML Error: ", sourcename, linnum);
va_list ap;
va_start(ap, format);
vprintf(format, ap);
vfprintf(stderr, format, ap);
va_end(ap);
printf("\n");
fflush(stdout);
fprintf(stderr, "\n");
fflush(stderr);
//#if MARS
// global.errors++;
-13
View File
@@ -1600,9 +1600,7 @@ void obj_ehtables(Symbol *sfunc,targ_size_t size,Symbol *ehsym)
int align = I64 ? 3 : 2; // align to NPTRSIZE
// The size is sizeof(struct FuncTable) in deh2.d
mach_getsegment("__deh_beg", "__DATA", align, S_COALESCED, 3 * NPTRSIZE);
int seg = mach_getsegment("__deh_eh", "__DATA", align, S_REGULAR);
mach_getsegment("__deh_end", "__DATA", align, S_COALESCED, NPTRSIZE);
Outbuffer *buf = SegData[seg]->SDbuf;
if (I64)
@@ -1692,11 +1690,7 @@ int obj_comdat(Symbol *s)
else if ((s->ty() & mTYLINK) == mTYthread)
{
s->Sfl = FLtlsdata;
align = I64 ? 4 : 2; // align to 16 bytes for floating point
mach_getsegment("__tls_beg", "__DATA", align, S_COALESCED, 4);
mach_getsegment("__tls_data", "__DATA", align, S_REGULAR, 4);
s->Sseg = mach_getsegment("__tlscoal_nt", "__DATA", 4, S_COALESCED);
mach_getsegment("__tls_end", "__DATA", align, S_COALESCED, 4);
elf_data_start(s, 1 << align, s->Sseg);
}
else
@@ -1887,10 +1881,7 @@ seg_data *obj_tlsseg()
if (seg_tlsseg == UNKNOWN)
{
int align = I64 ? 4 : 2; // align to 16 bytes for floating point
mach_getsegment("__tls_beg", "__DATA", align, S_COALESCED, 4);
seg_tlsseg = mach_getsegment("__tls_data", "__DATA", align, S_REGULAR);
mach_getsegment("__tlscoal_nt", "__DATA", 4, S_COALESCED, 4);
mach_getsegment("__tls_end", "__DATA", align, S_COALESCED, 4);
}
return SegData[seg_tlsseg];
}
@@ -2703,8 +2694,6 @@ void obj_moduleinfo(Symbol *scc)
{
int align = I64 ? 4 : 2;
mach_getsegment("__minfo_beg", "__DATA", align, S_COALESCED, 4);
int seg = mach_getsegment("__minfodata", "__DATA", align, S_REGULAR);
//printf("obj_moduleinfo(%s) seg = %d:x%x\n", scc->Sident, seg, Offset(seg));
@@ -2722,8 +2711,6 @@ void obj_moduleinfo(Symbol *scc)
if (I64)
flags |= CFoffset64;
SegData[seg]->SDoffset += reftoident(seg, Offset(seg), scc, 0, flags);
mach_getsegment("__minfo_end", "__DATA", align, S_COALESCED, 4);
}
#endif
+4 -11
View File
@@ -80,8 +80,7 @@ static unsigned char PADDING[64] = {
(a) += (b); \
}
void MD5Init (mdContext)
MD5_CTX *mdContext;
void MD5Init (MD5_CTX *mdContext)
{
mdContext->i[0] = mdContext->i[1] = (UINT4)0;
@@ -93,10 +92,7 @@ MD5_CTX *mdContext;
mdContext->buf[3] = (UINT4)0x10325476;
}
void MD5Update (mdContext, inBuf, inLen)
MD5_CTX *mdContext;
unsigned char *inBuf;
unsigned int inLen;
void MD5Update (MD5_CTX *mdContext, unsigned char *inBuf, unsigned int inLen)
{
UINT4 in[16];
int mdi;
@@ -128,8 +124,7 @@ unsigned int inLen;
}
}
void MD5Final (mdContext)
MD5_CTX *mdContext;
void MD5Final (MD5_CTX *mdContext)
{
UINT4 in[16];
int mdi;
@@ -169,9 +164,7 @@ MD5_CTX *mdContext;
/* Basic MD5 step. Transform buf based on in.
*/
static void Transform (buf, in)
UINT4 *buf;
UINT4 *in;
static void Transform (UINT4 *buf, UINT4 *in)
{
UINT4 a = buf[0], b = buf[1], c = buf[2], d = buf[3];
+7 -1
View File
@@ -132,7 +132,7 @@ struct OPTABLE
{
unsigned char tokn;
unsigned char oper;
char __near *string;
char *string;
char *pretty;
}
#endif
@@ -199,6 +199,7 @@ struct OPTABLE
/****************************************
* Convert from identifier to operator
*/
#if SCPP
#if __GNUC__ // NOT DONE - FIX
char * unmangle_pt(const char **s)
@@ -264,6 +265,7 @@ char *cpp_unmangleident(const char *p)
//printf("-cpp_unmangleident() = '%s'\n", p);
return (char *)p;
}
#endif
/****************************************
* Find index in oparray[] for operator.
@@ -271,6 +273,8 @@ char *cpp_unmangleident(const char *p)
* index or -1 if not found
*/
#if SCPP
int cpp_opidx(int op)
{ int i;
@@ -280,6 +284,8 @@ int cpp_opidx(int op)
return -1;
}
#endif
/***************************************
* Find identifier string associated with operator.
* Returns:
+2 -4
View File
@@ -45,9 +45,9 @@ enum OPER
OPaddr, /* &E */
OPneg, /* unary - */
OPuadd, /* unary + */
#if TX86
OPvoid, // where casting to void is not a no-op
OPabs, /* absolute value */
#if TX86
OPsqrt, /* square root */
OPrndtol, // round to short, long, long long (inline 8087 only)
OPsin, // sine
@@ -56,6 +56,7 @@ enum OPER
OPscale, // ldexp
OPyl2x, // y * log2(x)
OPyl2xp1, // y * log2(x + 1)
#endif
OPstrlen, /* strlen() */
OPstrcpy, /* strcpy() */
OPstrcat, /* strcat() */
@@ -64,11 +65,9 @@ enum OPER
OPmemcmp,
OPmemset,
OPsetjmp, // setjmp()
#endif
OPremquo, // / and % in one operation
#if TX86
OPbsf, // bit scan forward
OPbsr, // bit scan reverse
OPbt, // bit test
@@ -78,7 +77,6 @@ enum OPER
OPbswap, // swap bytes
OProl, // rotate left
OPror, // rotate right
#endif
OPstreq, /* structure assignment */
+2 -3
View File
@@ -75,7 +75,6 @@ int _assign[] =
{OPstreq,OPeq,OPaddass,OPminass,OPmulass,OPdivass,OPmodass,
OPshrass,OPashrass,OPshlass,OPandass,OPxorass,OPorass,OPpostinc,OPpostdec,
OPnegass,
/* OPbtc,OPbtr,OPbts,*/
};
int _wid[] =
{OPadd,OPmin,OPand,OPor,OPxor,OPcom,OPneg,OPmul,OPaddass,OPnegass,
@@ -142,7 +141,7 @@ int _ae[] = {OPvar,OPconst,OPrelconst,OPneg,
#if TARGET_SEGMENTED
OPvp_fp,OPcvp_fp,OPnp_fp,OPnp_f16p,OPf16p_np,OPoffset,
#endif
/*OPcomma,OPbit,OPoror,OPandand,OPcond,OPcolon,OPcolon2*/};
};
int _exp[] = {OPvar,OPconst,OPrelconst,OPneg,OPabs,OPsqrt,OPrndtol,OPrint,
OPsin,OPcos,OPscale,OPyl2x,OPyl2xp1,
OPstrlen,OPstrcmp,OPind,OPaddr,
@@ -583,7 +582,7 @@ void dotab()
case OPu64_128: X("u64_128", evalu8, cdshtlng);
case OPs64_128: X("s64_128", evalu8, cdshtlng);
case OP128_64: X("128_64", el64_32, cdlngsht);
case OPmsw: X("msw", evalu8, cdmsw);
case OPmsw: X("msw", elmsw, cdmsw);
case OPd_s64: X("d_s64", evalu8, cdcnvt);
case OPs64_d: X("s64_d", evalu8, cdcnvt);
+12 -3
View File
@@ -40,13 +40,17 @@
#include <windows.h>
#endif
#if __DMC__ || __GNUC__
#if __DMC__ || __GNUC__ || _MSC_VER
static char __file__[] = __FILE__; /* for tassert.h */
#include "tassert.h"
#else
#include <assert.h>
#endif
#if _MSC_VER
#include <alloca.h>
#endif
#if _WINDLL
extern void dll_printf(const char *format,...);
#define dbg_printf dll_printf
@@ -61,6 +65,9 @@ int file_createdirs(char *name);
* This function does not return.
*/
#if _MSC_VER
__declspec(noreturn)
#endif
void os_error(int line)
{
#if _WIN32
@@ -75,7 +82,9 @@ void os_error(int line)
#endif
#define os_error() os_error(__LINE__)
#if __DMC__
#pragma noreturn(os_error)
#endif
#if _WIN32
/*********************************
@@ -672,13 +681,13 @@ int os_file_exists(const char *name)
* Get file size of open file. Return -1L on error.
*/
#if _WIN32
#if _WIN32 && !_MSC_VER
extern "C" void * __cdecl _osfhnd[];
#endif
long os_file_size(int fd)
{
#if _WIN32
#if _WIN32 && !_MSC_VER
return GetFileSize(_osfhnd[fd],NULL);
#else
struct stat buf;
+6
View File
@@ -4039,6 +4039,11 @@ PTRNTAB2 aptb2PMULDQ[] = /* PMULDQ */ {
{ ASM_END }
};
PTRNTAB3 aptb3VPMULDQ[] = /* VPMULDQ */ {
{ VEX_NDS_128_WIG(PMULDQ), _r, _xmm, _xmm, _xmm_m128 },
{ ASM_END }
};
PTRNTAB2 aptb2PMULLD[] = /* PMULLD */ {
{ PMULLD, _r, _xmm, _xmm_m128 },
{ ASM_END }
@@ -5573,6 +5578,7 @@ PTRNTAB3 aptb3VFMSUB231SS[] = /* VFMSUB231SS */ {
X("vpmovzxdq", 2, (P) aptb2VPMOVZXDQ ) \
X("vpmovzxwd", 2, (P) aptb2VPMOVZXWD ) \
X("vpmovzxwq", 2, (P) aptb2VPMOVZXWQ ) \
X("vpmuldq", 3, (P) aptb3VPMULDQ ) \
X("vpmulhrsw", 3, (P) aptb3VPMULHRSW ) \
X("vpmulhuw", 3, (P) aptb3VPMULHUW ) \
X("vpmulhw", 3, (P) aptb3VPMULHW ) \
+31 -29
View File
@@ -16,7 +16,7 @@
#include <float.h>
#include <string.h>
#include <math.h>
#if _WIN32
#if _WIN32 && __DMC__
#include <fenv.h>
#include <fltpnt.h>
#endif
@@ -24,7 +24,9 @@
#include <errno.h>
#endif
#if _WIN32
#include "longdouble.h"
#if _WIN32 && __DMC__
// from \sc\src\include\setlocal.h
extern char * __cdecl __locale_decpoint;
void __pascal __set_errno (int an_errno);
@@ -37,22 +39,22 @@ void __pascal __set_errno (int an_errno);
* and also makes it clearer what constants we're trying to use.
*/
static long double negtab[] =
static longdouble negtab[] =
{1e-4096L,1e-2048L,1e-1024L,1e-512L,
1e-256L,1e-128L,1e-64L,1e-32L,1e-16L,1e-8L,1e-4L,1e-2L,1e-1L,1.0L};
static long double postab[] =
static longdouble postab[] =
{1e+4096L,1e+2048L,1e+1024L,1e+512L,
1e+256L,1e+128L,1e+64L,1e+32L,1e+16L,1e+8L,1e+4L,1e+2L,1e+1L};
#elif defined(__GNUC__) && __FreeBSD__ && __i386__
#elif (defined(__GNUC__) && __FreeBSD__ && __i386__) || _MSC_VER
// GCC on FreeBSD/i386 incorrectly rounds long double constants to double precision. Workaround:
// Note that the [sizeof(long double)] takes care of whatever the 0 padding is for the
// Note that the [sizeof(longdouble)] takes care of whatever the 0 padding is for the
// target platform
static unsigned char _negtab_bytes[][sizeof(long double)] =
static unsigned char _negtab_bytes[][sizeof(longdouble)] =
{ { 0xDE,0x9F,0xCE,0xD2,0xC8,0x04,0xDD,0xA6,0xD8,0x0A,0xBF,0xBF },
{ 0xE4,0x2D,0x36,0x34,0x4F,0x53,0xAE,0xCE,0x6B,0x25,0xBF,0xBF },
{ 0xBE,0xC0,0x57,0xDA,0xA5,0x82,0xA6,0xA2,0xB5,0x32,0xBF,0xBF },
@@ -68,7 +70,7 @@ static unsigned char _negtab_bytes[][sizeof(long double)] =
{ 0xCD,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xFB,0x3F,0xBF,0xBF },
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xFF,0x3F,0xBF,0xBF } };
static unsigned char _postab_bytes[][sizeof(long double)] =
static unsigned char _postab_bytes[][sizeof(longdouble)] =
{ { 0x9B,0x97,0x20,0x8A,0x02,0x52,0x60,0xC4,0x25,0x75,0x18,0x28 },
{ 0xE5,0x5D,0x3D,0xC5,0x5D,0x3B,0x8B,0x9E,0x92,0x5A,0x18,0x28 },
{ 0x17,0x0C,0x75,0x81,0x86,0x75,0x76,0xC9,0x48,0x4D,0x18,0x28 },
@@ -84,8 +86,8 @@ static unsigned char _postab_bytes[][sizeof(long double)] =
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xA0,0x02,0x40,0x18,0x28 },
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xFF,0x3F,0x18,0x28 } };
static long double *negtab = (long double *) _negtab_bytes;
static long double *postab = (long double *) _postab_bytes;
static longdouble *negtab = (longdouble *) _negtab_bytes;
static longdouble *postab = (longdouble *) _postab_bytes;
#else
@@ -93,7 +95,7 @@ static long double *postab = (long double *) _postab_bytes;
// The digits here past 17 are just for amusement value, they
// only contribute to the 'sticky' bit.
static long double negtab[] =
static longdouble negtab[] =
{
1 / 0x62.30290145104bcd64a60a9fc025254932bb0fd922271133eeae7be4a2f9151ffff868e970c234d8f51c5563f48bd2b496d868b27518ae42404964046f87cc1d213d5d0b54f74eb9281bb6c6e435fcb457200c03a5bca35f7792959da22e8d623b3e7b21e2b6100fab123cd8a1a75409f23956d4b941c759f83557de068edd2d00bcdd9d4a52ec8721ac7867f9e974996fb03d7ecd2fdc6349af06940d48741a6c2ed4684e5ab8d9c7bd7991dc03b4f63b8afd6b25ff66e42caeee333b7000a51987ec7038aec29e6ee8cac982a4ba47440496fcbe00d313d584e857fd214495bbdf373f41fd86fe49b70a5c7d2b17e0b2544f10cd4d8bfa89d0d73df29d0176cca7c234f4e6d2767113fd01c8c1a08a138c4ef80456c02d9a0ff4f1d4e3e51cb9255858325ed8d2399faddd9e9985a2df904ff6bf5c4f2ef0650ebc692c5508c2cbd6667097aced8e437b3d7fe03b2b6341a4c954108b89bc108f19ade5b533458e0dd75a53400d03119534074e89541bae9641fdd6266a3fdcbf778900fc509ba674343dd6769f3b72b882e7282566fbc6cc3f8d6b0dd9bc96119b31a96ddeff35e836b5d298f9994b8c90918e7b9a73491260806f233b7c94ab6feba2ebd6c1d9960e2d73a130d84c4a74fde9ce4724ed5bf546a03f40a8fb126ab1c32da38338eb3acc1a67778cfbe8b12acf1b23504dcd6cd995aca6a8b492ed8aa19adb95484971870239f4cea6e9cfda20c33857b32c450c3fecb534b71bd1a45b060904788f6e50fe78d6823613c8509ee3352c90ca19cfe90afb779eea37c8ab8db59a0a80627ce41d3cc425971d582dfe6d97ee63302b8e13e25feeaf19e63d326a7eb6d1c7bf2608c4cf1cc939c1307641d9b2c39497a8fcd8e0cd9e8d7c3172826ac9df13cb3d04e8d2fca26a9ff7d8b57e27ecf57bbb9373f46fee7aab86deb3f078787e2ab608b89572dac789bf627ede440b3f251f2b2322ab312bb95893d4b850be10e02d2408206e7bb8272181327ec8fa2e8a37a2d4390caea134c53c0adf9462ea75ecf9b5d0ed4d542dc19e1faf7a872e74f984d83e2dd8d92580152f18390a2b295138753d1fa8fd5d59c89f1b095edc162e2690f3cd8f62ff42923bbd87d1cde840b464a0e137d5e9a4eb8f8cde35c88baf63b71292baf1deeca19beb77fb8af6176ca776743074fa7021b97a1e0a68173c20ee69e79dadf7eb83cadbdfea5242a8329761ffe062053ccb5b92ac50b9c175a697b2b5341743c994a4503b9af26b398c6fed037d19eef4090ee8ae0725b1655fec303297cd0c2bd9cc1110c4e9968738b909454eb2a0dcfe388f15b8c898d3967a1b6dc3a5b4811a4f04f3618ac0280f4d3295a842bcfd82373a3f8ec72af2acd5071a8309cb2130504dd97d9556a1ebcad7947e0d0e30c7ae41eb659fb878f061814f6cea9c441c2d473bfe167b1a1c304e7613b22454ab9c41ff0b0905bc13176168dde6d488052f8cf8169c84cb4bf982870097012c23481161959127142e0e80cab3e6d7af6a25743dbeabcd0f237f1a016b67b2c2dfae78e341be10d6bfdf759b8ba1e81d1f4cce7c4823da7e1e7c34c0591cc245155e93b86ae5be806c0ed3f0da6146e599574efb29b172506be82913b1bb5154e05154ef084117f89a1e908efe7ae7d4724e8d2a67c001p+13600L,
1 / 0x9.e8b3b5dc53d5de4a74d28ce329ace526a3197bbebe3034f77154ce2bcba19648b21c11eb962b1b61b93cf2ee5ca6f7e928e61d08e2d694222771e50f30278c9836230af908b40a753b7d77cd8c6be7151aab4efac5dcd83e49d6907855eeb028af623f6f7024d2c36fa9ce9d04a487fa1fb992be221ef1bd0ad5f775677ce0de08402ad3fa140eac7d56c7c9dee0bedd8a6c038f9245b2e87c348ad803ecca8f0070f8dbb57a6a445f278b3d5cf42915e818415c7f3ef82df84658ccf45cfad379433f3389a4408f43c513ef5a83fb8886fbf56d9d4bd5f860792e55ecee70beb1810d76ce39de9ec24bcf99d01953761abd9d7389c0a244de3c195355d84eeebeee6f46eadb56c6815b785ce6b7b125ac8edb0708fd8f6cae5f5715f7915b33eb417bf03c19d7917c7ba1fc6b9681428c85744695f0e866d7efc9ac375d77c1a42f40660460944545ff87a7dc62d752f7a66a57b1ab730f203c1aa9f44484d80e2e5fc5a04779c56b8a9e110c7bcbea4ca7982da4663cfe491d0dbd21feab49869733554c36685e5510c4a656654419bd438e48ff35d6c7d6ab91bac974fb1264b4f111821fa2bca416afe609c313b41e449952fbed5a151440967abbb3a8281ed6a8f16f9210c17f94e3892ee98074ff01e3cb64f32dbb6643a7a8289c8c6c54de34c101349713b44938209ce1f3861ce0fb7fedcc235552eb57a7842d71c7fd8f66912e4ad2f869c29279498719342c12866ed6f1c850dabc98342c9e51b78db2ea50d142fd8277732ed56d55a5e5a191368b8abbb6067584ee87e354ec2e472149e28dcfb27d4d3fe30968651333e001p+6800L,
@@ -110,7 +112,7 @@ static long double negtab[] =
1 / 0xa.p+0L,
};
static long double postab[] =
static longdouble postab[] =
{
0x62.30290145104bcd64a60a9fc025254932bb0fd922271133eeae7be4a2f9151ffff868e970c234d8f51c5563f48bd2b496d868b27518ae42404964046f87cc1d213d5d0b54f74eb9281bb6c6e435fcb457200c03a5bca35f7792959da22e8d623b3e7b21e2b6100fab123cd8a1a75409f23956d4b941c759f83557de068edd2d00bcdd9d4a52ec8721ac7867f9e974996fb03d7ecd2fdc6349af06940d48741a6c2ed4684e5ab8d9c7bd7991dc03b4f63b8afd6b25ff66e42caeee333b7000a51987ec7038aec29e6ee8cac982a4ba47440496fcbe00d313d584e857fd214495bbdf373f41fd86fe49b70a5c7d2b17e0b2544f10cd4d8bfa89d0d73df29d0176cca7c234f4e6d2767113fd01c8c1a08a138c4ef80456c02d9a0ff4f1d4e3e51cb9255858325ed8d2399faddd9e9985a2df904ff6bf5c4f2ef0650ebc692c5508c2cbd6667097aced8e437b3d7fe03b2b6341a4c954108b89bc108f19ade5b533458e0dd75a53400d03119534074e89541bae9641fdd6266a3fdcbf778900fc509ba674343dd6769f3b72b882e7282566fbc6cc3f8d6b0dd9bc96119b31a96ddeff35e836b5d298f9994b8c90918e7b9a73491260806f233b7c94ab6feba2ebd6c1d9960e2d73a130d84c4a74fde9ce4724ed5bf546a03f40a8fb126ab1c32da38338eb3acc1a67778cfbe8b12acf1b23504dcd6cd995aca6a8b492ed8aa19adb95484971870239f4cea6e9cfda20c33857b32c450c3fecb534b71bd1a45b060904788f6e50fe78d6823613c8509ee3352c90ca19cfe90afb779eea37c8ab8db59a0a80627ce41d3cc425971d582dfe6d97ee63302b8e13e25feeaf19e63d326a7eb6d1c7bf2608c4cf1cc939c1307641d9b2c39497a8fcd8e0cd9e8d7c3172826ac9df13cb3d04e8d2fca26a9ff7d8b57e27ecf57bbb9373f46fee7aab86deb3f078787e2ab608b89572dac789bf627ede440b3f251f2b2322ab312bb95893d4b850be10e02d2408206e7bb8272181327ec8fa2e8a37a2d4390caea134c53c0adf9462ea75ecf9b5d0ed4d542dc19e1faf7a872e74f984d83e2dd8d92580152f18390a2b295138753d1fa8fd5d59c89f1b095edc162e2690f3cd8f62ff42923bbd87d1cde840b464a0e137d5e9a4eb8f8cde35c88baf63b71292baf1deeca19beb77fb8af6176ca776743074fa7021b97a1e0a68173c20ee69e79dadf7eb83cadbdfea5242a8329761ffe062053ccb5b92ac50b9c175a697b2b5341743c994a4503b9af26b398c6fed037d19eef4090ee8ae0725b1655fec303297cd0c2bd9cc1110c4e9968738b909454eb2a0dcfe388f15b8c898d3967a1b6dc3a5b4811a4f04f3618ac0280f4d3295a842bcfd82373a3f8ec72af2acd5071a8309cb2130504dd97d9556a1ebcad7947e0d0e30c7ae41eb659fb878f061814f6cea9c441c2d473bfe167b1a1c304e7613b22454ab9c41ff0b0905bc13176168dde6d488052f8cf8169c84cb4bf982870097012c23481161959127142e0e80cab3e6d7af6a25743dbeabcd0f237f1a016b67b2c2dfae78e341be10d6bfdf759b8ba1e81d1f4cce7c4823da7e1e7c34c0591cc245155e93b86ae5be806c0ed3f0da6146e599574efb29b172506be82913b1bb5154e05154ef084117f89a1e908efe7ae7d4724e8d2a67c001p+13600L,
0x9.e8b3b5dc53d5de4a74d28ce329ace526a3197bbebe3034f77154ce2bcba19648b21c11eb962b1b61b93cf2ee5ca6f7e928e61d08e2d694222771e50f30278c9836230af908b40a753b7d77cd8c6be7151aab4efac5dcd83e49d6907855eeb028af623f6f7024d2c36fa9ce9d04a487fa1fb992be221ef1bd0ad5f775677ce0de08402ad3fa140eac7d56c7c9dee0bedd8a6c038f9245b2e87c348ad803ecca8f0070f8dbb57a6a445f278b3d5cf42915e818415c7f3ef82df84658ccf45cfad379433f3389a4408f43c513ef5a83fb8886fbf56d9d4bd5f860792e55ecee70beb1810d76ce39de9ec24bcf99d01953761abd9d7389c0a244de3c195355d84eeebeee6f46eadb56c6815b785ce6b7b125ac8edb0708fd8f6cae5f5715f7915b33eb417bf03c19d7917c7ba1fc6b9681428c85744695f0e866d7efc9ac375d77c1a42f40660460944545ff87a7dc62d752f7a66a57b1ab730f203c1aa9f44484d80e2e5fc5a04779c56b8a9e110c7bcbea4ca7982da4663cfe491d0dbd21feab49869733554c36685e5510c4a656654419bd438e48ff35d6c7d6ab91bac974fb1264b4f111821fa2bca416afe609c313b41e449952fbed5a151440967abbb3a8281ed6a8f16f9210c17f94e3892ee98074ff01e3cb64f32dbb6643a7a8289c8c6c54de34c101349713b44938209ce1f3861ce0fb7fedcc235552eb57a7842d71c7fd8f66912e4ad2f869c29279498719342c12866ed6f1c850dabc98342c9e51b78db2ea50d142fd8277732ed56d55a5e5a191368b8abbb6067584ee87e354ec2e472149e28dcfb27d4d3fe30968651333e001p+6800L,
@@ -134,9 +136,9 @@ static long double postab[] =
* Terminates on first unrecognized character.
*/
long double strtold(const char *p,char **endp)
longdouble strtold(const char *p,char **endp)
{
long double ldval;
longdouble ldval;
int exp;
long long msdec,lsdec;
unsigned long msscale;
@@ -149,7 +151,7 @@ long double strtold(const char *p,char **endp)
unsigned int old_cw;
unsigned int old_status;
#if _WIN32
#if _WIN32 && __DMC__
fenv_t flagp;
fegetenv(&flagp); /* Store all exceptions, and current status word */
if (_8087)
@@ -264,7 +266,7 @@ long double strtold(const char *p,char **endp)
exp -= dot;
i = *++p;
}
#ifdef _WIN32
#if _WIN32 && __DMC__
if (i == *__locale_decpoint && !dot)
#else
if (i == '.' && !dot)
@@ -395,7 +397,7 @@ long double strtold(const char *p,char **endp)
exp -= dot;
i = *++p;
}
#if _WIN32
#if _WIN32 && __DMC__
if (i == *__locale_decpoint && !dot)
#else
if (i == '.' && !dot)
@@ -435,7 +437,7 @@ long double strtold(const char *p,char **endp)
goto Lerr; // return 0.0
}
#if _WIN32
#if _WIN32 && __DMC__
__asm
{
fild qword ptr msdec
@@ -460,7 +462,7 @@ long double strtold(const char *p,char **endp)
u = 0;
pow = 4096;
#if _WIN32
#if _WIN32 && __DMC__
//printf("msdec = x%x, lsdec = x%x, msscale = x%x\n",msdec,lsdec,msscale);
//printf("dval = %g, x%llx, exp = %d\n",dval,dval,exp);
__asm fld tbyte ptr ldval
@@ -470,7 +472,7 @@ long double strtold(const char *p,char **endp)
{
while (exp >= pow)
{
#if _WIN32
#if _WIN32 && __DMC__
__asm
{
mov EAX,u
@@ -486,13 +488,13 @@ long double strtold(const char *p,char **endp)
pow >>= 1;
u++;
}
#if _WIN32
#if _WIN32 && __DMC__
__asm fstp tbyte ptr ldval
#endif
while (exp < 0)
{ while (exp <= -pow)
{
#if _WIN32
#if _WIN32 && __DMC__
__asm
{
mov EAX,u
@@ -506,7 +508,7 @@ long double strtold(const char *p,char **endp)
ldval *= negtab[u];
#endif
if (ldval == 0)
#if _WIN32
#if _WIN32 && __DMC__
__set_errno (ERANGE);
#else
errno = ERANGE;
@@ -528,7 +530,7 @@ long double strtold(const char *p,char **endp)
}
L6: // if overflow occurred
if (ldval == HUGE_VAL)
#if _WIN32
#if _WIN32 && __DMC__
__set_errno (ERANGE); // range error
#else
errno = ERANGE;
@@ -540,7 +542,7 @@ long double strtold(const char *p,char **endp)
*endp = (char *) p;
}
L3:
#if _WIN32
#if _WIN32 && __DMC__
fesetenv(&flagp); // reset floating point environment
if (_8087)
{
@@ -563,7 +565,7 @@ long double strtold(const char *p,char **endp)
#else
long double strtold(const char *p,char **endp)
longdouble strtold(const char *p,char **endp)
{
return strtod(p, endp);
}
@@ -578,7 +580,7 @@ long double strtold(const char *p,char **endp)
#include <float.h>
#include <errno.h>
extern "C" long double strtold(const char *p,char **endp);
extern "C" longdouble strtold(const char *p,char **endp);
struct longdouble
{
@@ -587,7 +589,7 @@ struct longdouble
void main()
{
long double ld;
longdouble ld;
struct longdouble x;
int i;
@@ -674,7 +676,7 @@ void main()
int i;
int j;
static long double tab[] =
static longdouble tab[] =
{
0x62.30290145104bcd64a60a9fc025254932bb0fd922271133eeae7be4a2f9151ffff868e970c234d8f51c5563f48bd2b496d868b27518ae42404964046f87cc1d213d5d0b54f74eb9281bb6c6e435fcb457200c03a5bca35f7792959da22e8d623b3e7b21e2b6100fab123cd8a1a75409f23956d4b941c759f83557de068edd2d00bcdd9d4a52ec8721ac7867f9e974996fb03d7ecd2fdc6349af06940d48741a6c2ed4684e5ab8d9c7bd7991dc03b4f63b8afd6b25ff66e42caeee333b7000a51987ec7038aec29e6ee8cac982a4ba47440496fcbe00d313d584e857fd214495bbdf373f41fd86fe49b70a5c7d2b17e0b2544f10cd4d8bfa89d0d73df29d0176cca7c234f4e6d2767113fd01c8c1a08a138c4ef80456c02d9a0ff4f1d4e3e51cb9255858325ed8d2399faddd9e9985a2df904ff6bf5c4f2ef0650ebc692c5508c2cbd6667097aced8e437b3d7fe03b2b6341a4c954108b89bc108f19ade5b533458e0dd75a53400d03119534074e89541bae9641fdd6266a3fdcbf778900fc509ba674343dd6769f3b72b882e7282566fbc6cc3f8d6b0dd9bc96119b31a96ddeff35e836b5d298f9994b8c90918e7b9a73491260806f233b7c94ab6feba2ebd6c1d9960e2d73a130d84c4a74fde9ce4724ed5bf546a03f40a8fb126ab1c32da38338eb3acc1a67778cfbe8b12acf1b23504dcd6cd995aca6a8b492ed8aa19adb95484971870239f4cea6e9cfda20c33857b32c450c3fecb534b71bd1a45b060904788f6e50fe78d6823613c8509ee3352c90ca19cfe90afb779eea37c8ab8db59a0a80627ce41d3cc425971d582dfe6d97ee63302b8e13e25feeaf19e63d326a7eb6d1c7bf2608c4cf1cc939c1307641d9b2c39497a8fcd8e0cd9e8d7c3172826ac9df13cb3d04e8d2fca26a9ff7d8b57e27ecf57bbb9373f46fee7aab86deb3f078787e2ab608b89572dac789bf627ede440b3f251f2b2322ab312bb95893d4b850be10e02d2408206e7bb8272181327ec8fa2e8a37a2d4390caea134c53c0adf9462ea75ecf9b5d0ed4d542dc19e1faf7a872e74f984d83e2dd8d92580152f18390a2b295138753d1fa8fd5d59c89f1b095edc162e2690f3cd8f62ff42923bbd87d1cde840b464a0e137d5e9a4eb8f8cde35c88baf63b71292baf1deeca19beb77fb8af6176ca776743074fa7021b97a1e0a68173c20ee69e79dadf7eb83cadbdfea5242a8329761ffe062053ccb5b92ac50b9c175a697b2b5341743c994a4503b9af26b398c6fed037d19eef4090ee8ae0725b1655fec303297cd0c2bd9cc1110c4e9968738b909454eb2a0dcfe388f15b8c898d3967a1b6dc3a5b4811a4f04f3618ac0280f4d3295a842bcfd82373a3f8ec72af2acd5071a8309cb2130504dd97d9556a1ebcad7947e0d0e30c7ae41eb659fb878f061814f6cea9c441c2d473bfe167b1a1c304e7613b22454ab9c41ff0b0905bc13176168dde6d488052f8cf8169c84cb4bf982870097012c23481161959127142e0e80cab3e6d7af6a25743dbeabcd0f237f1a016b67b2c2dfae78e341be10d6bfdf759b8ba1e81d1f4cce7c4823da7e1e7c34c0591cc245155e93b86ae5be806c0ed3f0da6146e599574efb29b172506be82913b1bb5154e05154ef084117f89a1e908efe7ae7d4724e8d2a67c001p+13600L,
0x9.e8b3b5dc53d5de4a74d28ce329ace526a3197bbebe3034f77154ce2bcba19648b21c11eb962b1b61b93cf2ee5ca6f7e928e61d08e2d694222771e50f30278c9836230af908b40a753b7d77cd8c6be7151aab4efac5dcd83e49d6907855eeb028af623f6f7024d2c36fa9ce9d04a487fa1fb992be221ef1bd0ad5f775677ce0de08402ad3fa140eac7d56c7c9dee0bedd8a6c038f9245b2e87c348ad803ecca8f0070f8dbb57a6a445f278b3d5cf42915e818415c7f3ef82df84658ccf45cfad379433f3389a4408f43c513ef5a83fb8886fbf56d9d4bd5f860792e55ecee70beb1810d76ce39de9ec24bcf99d01953761abd9d7389c0a244de3c195355d84eeebeee6f46eadb56c6815b785ce6b7b125ac8edb0708fd8f6cae5f5715f7915b33eb417bf03c19d7917c7ba1fc6b9681428c85744695f0e866d7efc9ac375d77c1a42f40660460944545ff87a7dc62d752f7a66a57b1ab730f203c1aa9f44484d80e2e5fc5a04779c56b8a9e110c7bcbea4ca7982da4663cfe491d0dbd21feab49869733554c36685e5510c4a656654419bd438e48ff35d6c7d6ab91bac974fb1264b4f111821fa2bca416afe609c313b41e449952fbed5a151440967abbb3a8281ed6a8f16f9210c17f94e3892ee98074ff01e3cb64f32dbb6643a7a8289c8c6c54de34c101349713b44938209ce1f3861ce0fb7fedcc235552eb57a7842d71c7fd8f66912e4ad2f869c29279498719342c12866ed6f1c850dabc98342c9e51b78db2ea50d142fd8277732ed56d55a5e5a191368b8abbb6067584ee87e354ec2e472149e28dcfb27d4d3fe30968651333e001p+6800L,
+2 -2
View File
@@ -23,7 +23,7 @@
#if __clang__
void util_assert ( char * , int ) __attribute__((analyzer_noreturn));
void util_assert(const char * , int) __attribute__((noreturn));
static void local_assert(int line)
{
@@ -36,7 +36,7 @@ static void local_assert(int line)
#if _MSC_VER
__declspec(noreturn)
#endif
void util_assert ( char * , int );
void util_assert(const char *, int);
static void local_assert(int line)
{
+6 -6
View File
@@ -346,11 +346,11 @@ inline enum_TK stoken() { return toklist ? stokenx() : rtoken(1); }
void token_init(void);
void removext(void);
void __near comment(void);
void __near cppcomment(void);
void comment(void);
void cppcomment(void);
char *combinestrings(targ_size_t *plen);
char *combinestrings(targ_size_t *plen, tym_t *pty);
void __near inident(void);
void inident(void);
void inidentX(char *p);
unsigned comphash(const char *p);
int insertSpace(unsigned char xclast, unsigned char xcnext);
@@ -368,9 +368,9 @@ void token_term(void);
/* from pragma.c */
//enum_TK ptoken(void);
void pragma_process();
int __near pragma_search(char *id);
macro_t * __near macfind(void);
void __near listident(void);
int pragma_search(char *id);
macro_t * macfind(void);
void listident(void);
void pragma_term(void);
macro_t *defmac(const char *name , const char *text);
int pragma_defined(void);
+5 -8
View File
@@ -188,8 +188,8 @@ L1:
if (t->Tflags & TFsizeunknown)
goto err1;
sz = t->Ttag->Sstruct->Salignsize;
if (sz > t->Ttag->Sstruct->Sstructalign)
sz = t->Ttag->Sstruct->Sstructalign;
if (sz > t->Ttag->Sstruct->Sstructalign + 1)
sz = t->Ttag->Sstruct->Sstructalign + 1;
break;
case TYldouble:
@@ -239,7 +239,7 @@ type *type_alloc(tym_t ty)
{ type *t;
static type tzero;
#if TARGET_SEGMENTED
#if !MARS
assert(tybasic(ty) != TYtemplate);
#endif
if (type_list)
@@ -336,7 +336,7 @@ type *type_allocn(tym_t ty,type *tn)
* Allocate a TYmemptr type.
*/
#if !MARS
#if SCPP
type *type_allocmemptr(Classsym *stag,type *tn)
{ type *t;
@@ -415,7 +415,7 @@ type_count_free()
* Initialize type package.
*/
STATIC type * __near type_allocbasic(tym_t ty)
STATIC type * type_allocbasic(tym_t ty)
{ type *t;
t = type_alloc(ty);
@@ -1139,9 +1139,6 @@ param_t *param_calloc()
static param_t pzero;
param_t *p;
#if !TX86
debug_assert(PARSER);
#endif
if (param_list)
{
p = param_list;
+2
View File
@@ -187,7 +187,9 @@ targ_size_t type_paramsize(type *t);
type *type_alloc(tym_t);
type *type_alloc_template(symbol *s);
type *type_allocn(tym_t,type *tn);
#if SCPP
type *type_allocmemptr(Classsym *stag,type *tn);
#endif
type *type_fake(tym_t);
type *type_setty(type **,long);
type *type_settype(type **pt, type *t);
+10 -9
View File
@@ -12,15 +12,6 @@
#include <assert.h>
#include <math.h>
#if __FreeBSD__
extern "C"
{
long double sinl(long double);
long double cosl(long double);
long double tanl(long double);
long double sqrtl(long double);
}
#endif
#include "mars.h"
#include "declaration.h"
@@ -33,6 +24,16 @@ extern "C"
#include "id.h"
#include "module.h"
#if __FreeBSD__
extern "C"
{
longdouble sinl(longdouble);
longdouble cosl(longdouble);
longdouble tanl(longdouble);
longdouble sqrtl(longdouble);
}
#endif
#if DMDV2
/**********************************
+231 -48
View File
@@ -17,6 +17,7 @@
#include "utf.h"
#include "declaration.h"
#include "aggregate.h"
#include "template.h"
#include "scope.h"
//#define DUMP .dump(__PRETTY_FUNCTION__, this)
@@ -107,6 +108,9 @@ fflush(stdout);
else if (t->reliesOnTident())
error("forward reference to type %s", t->reliesOnTident()->toChars());
//printf("type %p ty %d deco %p\n", type, type->ty, type->deco);
//type = type->semantic(loc, sc);
//printf("type %s t %s\n", type->deco, t->deco);
error("cannot implicitly convert expression (%s) of type %s to %s",
toChars(), type->toChars(), t->toChars());
}
@@ -131,6 +135,12 @@ Expression *ErrorExp::implicitCastTo(Scope *sc, Type *t)
return this;
}
Expression *FuncExp::implicitCastTo(Scope *sc, Type *t)
{
//printf("FuncExp::implicitCastTo type = %p %s, t = %s\n", type, type ? type->toChars() : NULL, t->toChars());
return inferType(t);
}
/*******************************************
* Return !=0 if we can implicitly convert this to type t.
* Don't do the actual cast.
@@ -352,16 +362,16 @@ MATCH IntegerExp::implicitConvTo(Type *t)
case Tfloat80:
{
volatile long double f;
volatile_longdouble f;
if (type->isunsigned())
{
f = (long double)value;
if (f != value)
f = ldouble(value);
if (f != value) // isn't this a noop, because the compiler prefers ld
goto Lno;
}
else
{
f = (long double)(long long)value;
f = ldouble((long long)value);
if (f != (long long)value)
goto Lno;
}
@@ -490,14 +500,17 @@ MATCH StringExp::implicitConvTo(Type *t)
return MATCHnomatch;
m = MATCHconst;
}
switch (tn->ty)
if (!committed)
{
case Tchar:
case Twchar:
case Tdchar:
if (!committed)
return m;
break;
switch (tn->ty)
{
case Tchar:
return (postfix != 'w' && postfix != 'd' ? m : MATCHconvert);
case Twchar:
return (postfix == 'w' ? m : MATCHconvert);
case Tdchar:
return (postfix == 'd' ? m : MATCHconvert);
}
}
break;
}
@@ -719,12 +732,24 @@ MATCH DelegateExp::implicitConvTo(Type *t)
MATCH FuncExp::implicitConvTo(Type *t)
{
//printf("FuncExp::implicitCastTo type = %p %s, t = %s\n", type, type ? type->toChars() : NULL, t->toChars());
if (type && type != Type::tvoid && tok == TOKreserved && type->ty == Tpointer
&& (t->ty == Tpointer || t->ty == Tdelegate))
{ // Allow implicit function to delegate conversion
if (type->nextOf()->covariant(t->nextOf()) == 1)
return t->ty == Tpointer ? MATCHconst : MATCHconvert;
//printf("FuncExp::implicitConvTo type = %p %s, t = %s\n", type, type ? type->toChars() : NULL, t->toChars());
Expression *e = inferType(t, 1);
if (e)
{
if (e != this)
return e->implicitConvTo(t);
/* MATCHconst: Conversion from implicit to explicit function pointer
* MATCHconvert: Conversion from impliict funciton pointer to delegate
*/
if (tok == TOKreserved && type->ty == Tpointer &&
(t->ty == Tpointer || t->ty == Tdelegate))
{
if (type == t)
return MATCHexact;
if (type->nextOf()->covariant(t->nextOf()) == 1)
return t->ty == Tpointer ? MATCHconst : MATCHconvert;
}
}
return Expression::implicitConvTo(t);
}
@@ -845,7 +870,7 @@ Expression *Expression::castTo(Scope *sc, Type *t)
{ /* Forward the cast to our alias this member, rewrite to:
* cast(to)e1.aliasthis
*/
Expression *e1 = new DotIdExp(loc, this, ts->sym->aliasthis->ident);
Expression *e1 = resolveAliasThis(sc, this);
Expression *e2 = new CastExp(loc, e1, tb);
e2 = e2->semantic(sc);
return e2;
@@ -866,7 +891,7 @@ Expression *Expression::castTo(Scope *sc, Type *t)
/* Forward the cast to our alias this member, rewrite to:
* cast(to)e1.aliasthis
*/
Expression *e1 = new DotIdExp(loc, this, ts->sym->aliasthis->ident);
Expression *e1 = resolveAliasThis(sc, this);
Expression *e2 = new CastExp(loc, e1, tb);
e2 = e2->semantic(sc);
return e2;
@@ -1450,7 +1475,7 @@ Expression *DelegateExp::castTo(Scope *sc, Type *t)
Expression *e = this;
Type *tb = t->toBasetype();
Type *typeb = type->toBasetype();
if (tb != typeb)
if (tb != typeb || hasOverloads)
{
// Look for delegates to functions where the functions are overloaded.
FuncDeclaration *f;
@@ -1491,15 +1516,11 @@ Expression *DelegateExp::castTo(Scope *sc, Type *t)
Expression *FuncExp::castTo(Scope *sc, Type *t)
{
//printf("FuncExp::castTo type = %s, t = %s\n", type->toChars(), t->toChars());
if (tok == TOKreserved)
{ assert(type && type != Type::tvoid);
if (type->ty == Tpointer && t->ty == Tdelegate)
{
Expression *e = copy();
e->type = new TypeDelegate(fd->type);
e->type = e->type->semantic(loc, sc);
return e;
}
Expression *e = inferType(t, 1);
if (e)
{ if (e != this)
e = e->castTo(sc, t);
return e;
}
return Expression::castTo(sc, t);
}
@@ -1537,6 +1558,180 @@ Expression *CommaExp::castTo(Scope *sc, Type *t)
return e;
}
/* ==================== inferType ====================== */
/****************************************
* Set type inference target
* flag 1: don't put an error when inference fails
*/
Expression *Expression::inferType(Type *t, int flag, TemplateParameters *tparams)
{
return this;
}
Expression *ArrayLiteralExp::inferType(Type *t, int flag, TemplateParameters *tparams)
{
if (t)
{
t = t->toBasetype();
if (t->ty == Tarray || t->ty == Tsarray)
{
Type *tn = t->nextOf();
for (size_t i = 0; i < elements->dim; i++)
{ Expression *e = (*elements)[i];
if (e)
{ e = e->inferType(tn, flag, tparams);
(*elements)[i] = e;
}
}
}
}
return this;
}
Expression *AssocArrayLiteralExp::inferType(Type *t, int flag, TemplateParameters *tparams)
{
if (t)
{
t = t->toBasetype();
if (t->ty == Taarray)
{ TypeAArray *taa = (TypeAArray *)t;
Type *ti = taa->index;
Type *tv = taa->nextOf();
for (size_t i = 0; i < keys->dim; i++)
{ Expression *e = (*keys)[i];
if (e)
{ e = e->inferType(ti, flag, tparams);
(*keys)[i] = e;
}
}
for (size_t i = 0; i < values->dim; i++)
{ Expression *e = (*values)[i];
if (e)
{ e = e->inferType(tv, flag, tparams);
(*values)[i] = e;
}
}
}
}
return this;
}
Expression *FuncExp::inferType(Type *to, int flag, TemplateParameters *tparams)
{
if (!to)
return this;
//printf("FuncExp::interType('%s'), to=%s\n", type?type->toChars():"null", to->toChars());
if (!type) // semantic is not yet done
{
if (to->ty == Tdelegate ||
to->ty == Tpointer && to->nextOf()->ty == Tfunction)
{ treq = to;
}
return this;
}
Expression *e = NULL;
Type *t = to;
if (t->ty == Tdelegate)
{ if (tok == TOKfunction)
goto L1;
t = t->nextOf();
}
else if (t->ty == Tpointer && t->nextOf()->ty == Tfunction)
{ if (tok == TOKdelegate)
goto L1;
t = t->nextOf();
}
if (td)
{ /// Parameter types inference from
assert(td->scope);
if (t->ty == Tfunction)
{
TypeFunction *tfv = (TypeFunction *)t;
TypeFunction *tfl = (TypeFunction *)fd->type;
size_t dim = Parameter::dim(tfl->parameters);
if (Parameter::dim(tfv->parameters) == dim &&
tfv->varargs == tfl->varargs)
{
Objects *tiargs = new Objects();
tiargs->reserve(td->parameters->dim);
for (size_t i = 0; i < td->parameters->dim; i++)
{
TemplateParameter *tp = (*td->parameters)[i];
for (size_t u = 0; u < dim; u++)
{ Parameter *p = Parameter::getNth(tfl->parameters, u);
if (p->type->ty == Tident &&
((TypeIdentifier *)p->type)->ident == tp->ident)
{ p = Parameter::getNth(tfv->parameters, u);
Type *tprm = p->type;
if (tprm->reliesOnTident(tparams))
goto L1;
tprm = tprm->semantic(loc, td->scope);
tiargs->push(tprm);
u = dim; // break inner loop
}
}
}
TemplateInstance *ti = new TemplateInstance(loc, td, tiargs);
e = (new ScopeExp(loc, ti))->semantic(td->scope);
if (e->op == TOKfunction)
{ FuncExp *fe = (FuncExp *)e;
assert(fe->td == NULL);
e = fe->inferType(to, flag);
}
}
}
}
else if (type)
{
assert(type != Type::tvoid); // semantic is already done
// Allow conversion from implicit function pointer to delegate
if (tok == TOKreserved && type->ty == Tpointer &&
to->ty == Tdelegate)
{
Type *typen = type->nextOf();
assert(typen->deco);
//if (typen->covariant(to->nextOf()) == 1)
{
FuncExp *fe = (FuncExp *)copy();
fe->tok = TOKdelegate;
fe->type = (new TypeDelegate(typen))->merge();
e = fe;
//e = fe->Expression::implicitCastTo(sc, to);
}
}
else
e = this;
}
L1:
if (!flag && !e)
{ error("cannot infer function literal type from %s", to->toChars());
e = new ErrorExp();
}
return e;
}
Expression *CondExp::inferType(Type *t, int flag, TemplateParameters *tparams)
{
if (t)
{
t = t->toBasetype();
e1 = e1->inferType(t, flag, tparams);
e2 = e2->inferType(t, flag, tparams);
}
return this;
}
/* ==================== ====================== */
/****************************************
@@ -1655,6 +1850,7 @@ int typeMerge(Scope *sc, Expression *e, Type **pt, Expression **pe1, Expression
#endif
assert(t2);
Lagain:
Type *t1b = t1->toBasetype();
Type *t2b = t2->toBasetype();
@@ -1694,7 +1890,6 @@ int typeMerge(Scope *sc, Expression *e, Type **pt, Expression **pe1, Expression
t1 = t1b;
t2 = t2b;
Lagain:
if (t1 == t2)
{
}
@@ -1940,17 +2135,13 @@ Lcc:
}
else if (t1->ty == Tstruct && ((TypeStruct *)t1)->sym->aliasthis)
{
e1 = new DotIdExp(e1->loc, e1, ((TypeStruct *)t1)->sym->aliasthis->ident);
e1 = e1->semantic(sc);
e1 = resolveProperties(sc, e1);
e1 = resolveAliasThis(sc, e1);
t1 = e1->type;
continue;
}
else if (t2->ty == Tstruct && ((TypeStruct *)t2)->sym->aliasthis)
{
e2 = new DotIdExp(e2->loc, e2, ((TypeStruct *)t2)->sym->aliasthis->ident);
e2 = e2->semantic(sc);
e2 = resolveProperties(sc, e2);
e2 = resolveAliasThis(sc, e2);
t2 = e2->type;
continue;
}
@@ -1985,16 +2176,12 @@ Lcc:
Expression *e2b = NULL;
if (ts2->sym->aliasthis)
{
e2b = new DotIdExp(e2->loc, e2, ts2->sym->aliasthis->ident);
e2b = e2b->semantic(sc);
e2b = resolveProperties(sc, e2b);
e2b = resolveAliasThis(sc, e2);
i1 = e2b->implicitConvTo(t1);
}
if (ts1->sym->aliasthis)
{
e1b = new DotIdExp(e1->loc, e1, ts1->sym->aliasthis->ident);
e1b = e1b->semantic(sc);
e1b = resolveProperties(sc, e1b);
e1b = resolveAliasThis(sc, e1);
i2 = e1b->implicitConvTo(t2);
}
if (i1 && i2)
@@ -2021,18 +2208,14 @@ Lcc:
{
if (t1->ty == Tstruct && ((TypeStruct *)t1)->sym->aliasthis)
{
e1 = new DotIdExp(e1->loc, e1, ((TypeStruct *)t1)->sym->aliasthis->ident);
e1 = e1->semantic(sc);
e1 = resolveProperties(sc, e1);
e1 = resolveAliasThis(sc, e1);
t1 = e1->type;
t = t1;
goto Lagain;
}
if (t2->ty == Tstruct && ((TypeStruct *)t2)->sym->aliasthis)
{
e2 = new DotIdExp(e2->loc, e2, ((TypeStruct *)t2)->sym->aliasthis->ident);
e2 = e2->semantic(sc);
e2 = resolveProperties(sc, e2);
e2 = resolveAliasThis(sc, e2);
t2 = e2->type;
t = t2;
goto Lagain;
+57 -34
View File
@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2011 by Digital Mars
// Copyright (c) 1999-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -273,7 +273,7 @@ void ClassDeclaration::semantic(Scope *sc)
return;
}
if (symtab)
{ if (sizeok == 1 || !scope)
{ if (sizeok == SIZEOKdone || !scope)
{ //printf("\tsemantic for '%s' is already completed\n", toChars());
return; // semantic() already completed
}
@@ -333,7 +333,8 @@ void ClassDeclaration::semantic(Scope *sc)
//b->type = b->type->semantic(loc, sc);
tb = b->type->toBasetype();
if (tb->ty != Tclass)
{ error("base type must be class or interface, not %s", b->type->toChars());
{ if (b->type != Type::terror)
error("base type must be class or interface, not %s", b->type->toChars());
baseclasses->remove(0);
}
else
@@ -364,12 +365,12 @@ void ClassDeclaration::semantic(Scope *sc)
goto L7;
}
}
if (!tc->sym->symtab || tc->sym->sizeok == 0)
if (!tc->sym->symtab || tc->sym->sizeok == SIZEOKnone)
{ // Try to resolve forward reference
if (/*sc->mustsemantic &&*/ tc->sym->scope)
tc->sym->semantic(NULL);
}
if (!tc->sym->symtab || tc->sym->scope || tc->sym->sizeok == 0)
if (!tc->sym->symtab || tc->sym->scope || tc->sym->sizeok == SIZEOKnone)
{
//printf("%s: forward reference of base class %s\n", toChars(), tc->sym->toChars());
//error("forward reference of base class %s", baseClass->toChars());
@@ -406,8 +407,8 @@ void ClassDeclaration::semantic(Scope *sc)
else
tc = NULL;
if (!tc || !tc->sym->isInterfaceDeclaration())
{
error("base type must be interface, not %s", b->type->toChars());
{ if (b->type != Type::terror)
error("base type must be interface, not %s", b->type->toChars());
baseclasses->remove(i);
continue;
}
@@ -512,13 +513,13 @@ void ClassDeclaration::semantic(Scope *sc)
protection = sc->protection;
storage_class |= sc->stc;
if (sizeok == 0)
if (sizeok == SIZEOKnone)
{
interfaceSemantic(sc);
for (size_t i = 0; i < members->dim; i++)
{
Dsymbol *s = members->tdata()[i];
Dsymbol *s = (*members)[i];
s->addMember(sc, this, 1);
}
@@ -589,13 +590,6 @@ void ClassDeclaration::semantic(Scope *sc)
if (storage_class & STCabstract)
isabstract = 1;
if (storage_class & STCimmutable)
type = type->addMod(MODimmutable);
if (storage_class & STCconst)
type = type->addMod(MODconst);
if (storage_class & STCshared)
type = type->addMod(MODshared);
sc = sc->push(this);
//sc->stc &= ~(STCfinal | STCauto | STCscope | STCstatic | STCabstract | STCdeprecated | STC_TYPECTOR | STCtls | STCgshared);
//sc->stc |= storage_class & STC_TYPECTOR;
@@ -631,17 +625,20 @@ void ClassDeclaration::semantic(Scope *sc)
structsize = sc->offset;
Scope scsave = *sc;
size_t members_dim = members->dim;
sizeok = 0;
sizeok = SIZEOKnone;
/* Set scope so if there are forward references, we still might be able to
* resolve individual members like enums.
*/
for (size_t i = 0; i < members_dim; i++)
{ Dsymbol *s = members->tdata()[i];
{ Dsymbol *s = (*members)[i];
/* There are problems doing this in the general case because
* Scope keeps track of things like 'offset'
*/
if (s->isEnumDeclaration() || (s->isAggregateDeclaration() && s->ident))
if (s->isEnumDeclaration() ||
(s->isAggregateDeclaration() && s->ident) ||
s->isTemplateMixin() ||
s->isAliasDeclaration())
{
//printf("setScope %s %s\n", s->kind(), s->toChars());
s->setScope(sc);
@@ -649,19 +646,35 @@ void ClassDeclaration::semantic(Scope *sc)
}
for (size_t i = 0; i < members_dim; i++)
{ Dsymbol *s = members->tdata()[i];
{ Dsymbol *s = (*members)[i];
s->semantic(sc);
}
// Set the offsets of the fields and determine the size of the class
unsigned offset = structsize;
bool isunion = isUnionDeclaration() != NULL;
for (size_t i = 0; i < members->dim; i++)
{ Dsymbol *s = (*members)[i];
s->setFieldOffset(this, &offset, false);
}
sc->offset = structsize;
if (global.gag && global.gaggedErrors != errors)
{ // The type is no good, yet the error messages were gagged.
type = Type::terror;
}
if (sizeok == 2) // failed due to forward references
if (sizeok == SIZEOKfwd) // failed due to forward references
{ // semantic() failed due to forward references
// Unwind what we did, and defer it for later
for (size_t i = 0; i < fields.dim; i++)
{ Dsymbol *s = fields[i];
VarDeclaration *vd = s->isVarDeclaration();
if (vd)
vd->offset = 0;
}
fields.setDim(0);
structsize = 0;
alignsize = 0;
@@ -681,15 +694,19 @@ void ClassDeclaration::semantic(Scope *sc)
//printf("\tsemantic('%s') successful\n", toChars());
structsize = sc->offset;
//members->print();
/* Look for special member functions.
* They must be in this class, not in a base class.
*/
ctor = (CtorDeclaration *)search(0, Id::ctor, 0);
ctor = search(0, Id::ctor, 0);
#if DMDV1
if (ctor && (ctor->toParent() != this || !ctor->isCtorDeclaration()))
ctor = NULL;
#else
if (ctor && (ctor->toParent() != this || !(ctor->isCtorDeclaration() || ctor->isTemplateDeclaration())))
ctor = NULL; // search() looks through ancestor classes
#endif
// dtor = (DtorDeclaration *)search(Id::dtor, 0);
// if (dtor && dtor->toParent() != this)
@@ -715,7 +732,6 @@ void ClassDeclaration::semantic(Scope *sc)
members->push(ctor);
ctor->addMember(sc, this, 1);
*sc = scsave; // why? What about sc->nofree?
sc->offset = structsize;
ctor->semantic(sc);
this->ctor = ctor;
defaultCtor = ctor;
@@ -731,9 +747,10 @@ void ClassDeclaration::semantic(Scope *sc)
#endif
// Allocate instance of each new interface
sc->offset = structsize;
for (size_t i = 0; i < vtblInterfaces->dim; i++)
{
BaseClass *b = vtblInterfaces->tdata()[i];
BaseClass *b = (*vtblInterfaces)[i];
unsigned thissize = PTRSIZE;
alignmember(structalign, thissize, &sc->offset);
@@ -752,7 +769,7 @@ void ClassDeclaration::semantic(Scope *sc)
alignsize = thissize;
}
structsize = sc->offset;
sizeok = 1;
sizeok = SIZEOKdone;
Module::dprogress++;
dtor = buildDtor(sc);
@@ -898,7 +915,12 @@ Dsymbol *ClassDeclaration::search(Loc loc, Identifier *ident, int flags)
if (scope && !symtab)
{ Scope *sc = scope;
sc->mustsemantic++;
// If speculatively gagged, ungag now.
unsigned oldgag = global.gag;
if (global.isSpeculativeGagging())
global.gag = 0;
semantic(sc);
global.gag = oldgag;
sc->mustsemantic--;
}
@@ -1017,7 +1039,7 @@ FuncDeclaration *ClassDeclaration::findFunc(Identifier *ident, TypeFunction *tf)
{
for (size_t i = 0; i < vtbl->dim; i++)
{
FuncDeclaration *fd = vtbl->tdata()[i]->isFuncDeclaration();
FuncDeclaration *fd = (*vtbl)[i]->isFuncDeclaration();
if (!fd)
continue; // the first entry might be a ClassInfo
@@ -1236,7 +1258,7 @@ void InterfaceDeclaration::semantic(Scope *sc)
// Expand any tuples in baseclasses[]
for (size_t i = 0; i < baseclasses->dim; )
{ BaseClass *b = baseclasses->tdata()[0];
{ BaseClass *b = (*baseclasses)[0];
b->type = b->type->semantic(loc, sc);
Type *tb = b->type->toBasetype();
@@ -1272,8 +1294,8 @@ void InterfaceDeclaration::semantic(Scope *sc)
else
tc = NULL;
if (!tc || !tc->sym->isInterfaceDeclaration())
{
error("base type must be interface, not %s", b->type->toChars());
{ if (b->type != Type::terror)
error("base type must be interface, not %s", b->type->toChars());
baseclasses->remove(i);
continue;
}
@@ -1330,7 +1352,7 @@ void InterfaceDeclaration::semantic(Scope *sc)
{ BaseClass *b = interfaces[i];
// Skip if b has already appeared
for (int k = 0; k < i; k++)
for (size_t k = 0; k < i; k++)
{
if (b == interfaces[k])
goto Lcontinue;
@@ -1338,11 +1360,11 @@ void InterfaceDeclaration::semantic(Scope *sc)
// Copy vtbl[] from base class
if (b->base->vtblOffset())
{ int d = b->base->vtbl.dim;
{ size_t d = b->base->vtbl.dim;
if (d > 1)
{
vtbl.reserve(d - 1);
for (int j = 1; j < d; j++)
for (size_t j = 1; j < d; j++)
vtbl.push(b->base->vtbl.tdata()[j]);
}
}
@@ -1360,7 +1382,7 @@ void InterfaceDeclaration::semantic(Scope *sc)
for (size_t i = 0; i < members->dim; i++)
{
Dsymbol *s = members->tdata()[i];
Dsymbol *s = (*members)[i];
s->addMember(sc, this, 1);
}
@@ -1376,6 +1398,7 @@ void InterfaceDeclaration::semantic(Scope *sc)
sc->explicitProtection = 0;
structalign = sc->structalign;
sc->offset = PTRSIZE * 2;
structsize = sc->offset;
inuse++;
/* Set scope so if there are forward references, we still might be able to
+14
View File
@@ -204,6 +204,11 @@ int StructDeclaration::needOpEquals()
if (hasIdentityEquals)
goto Lneed;
#if 0
if (isUnionDeclaration())
goto Ldontneed;
#endif
/* If any of the fields has an opEquals, then we
* need it too.
*/
@@ -215,6 +220,14 @@ int StructDeclaration::needOpEquals()
if (v->storage_class & STCref)
continue;
Type *tv = v->type->toBasetype();
#if 0
if (tv->isfloating())
goto Lneed;
if (tv->ty == Tarray)
goto Lneed;
if (tv->ty == Tclass)
goto Lneed;
#endif
while (tv->ty == Tsarray)
{ TypeSArray *ta = (TypeSArray *)tv;
tv = tv->nextOf()->toBasetype();
@@ -226,6 +239,7 @@ int StructDeclaration::needOpEquals()
goto Lneed;
}
}
Ldontneed:
if (X) printf("\tdontneed\n");
return 0;
+14 -12
View File
@@ -16,12 +16,14 @@
struct complex_t
{
long double re;
long double im;
longdouble re;
longdouble im;
complex_t() { this->re = 0; this->im = 0; }
complex_t(long double re) { this->re = re; this->im = 0; }
complex_t(long double re, long double im) { this->re = re; this->im = im; }
complex_t(longdouble re) { this->re = re; this->im = 0; }
complex_t(double re) { this->re = re; this->im = 0; }
complex_t(longdouble re, longdouble im) { this->re = re; this->im = im; }
complex_t(double re, double im) { this->re = re; this->im = im; }
complex_t operator + (complex_t y) { complex_t r; r.re = re + y.re; r.im = im + y.im; return r; }
complex_t operator - (complex_t y) { complex_t r; r.re = re - y.re; r.im = im - y.im; return r; }
@@ -30,9 +32,9 @@ struct complex_t
complex_t operator / (complex_t y)
{
long double abs_y_re = y.re < 0 ? -y.re : y.re;
long double abs_y_im = y.im < 0 ? -y.im : y.im;
long double r, den;
longdouble abs_y_re = y.re < 0 ? -y.re : y.re;
longdouble abs_y_im = y.im < 0 ? -y.im : y.im;
longdouble r, den;
if (abs_y_re < abs_y_im)
{
@@ -56,17 +58,17 @@ struct complex_t
int operator != (complex_t y) { return re != y.re || im != y.im; }
};
inline complex_t operator * (long double x, complex_t y) { return complex_t(x) * y; }
inline complex_t operator * (complex_t x, long double y) { return x * complex_t(y); }
inline complex_t operator / (complex_t x, long double y) { return x / complex_t(y); }
inline complex_t operator * (longdouble x, complex_t y) { return complex_t(x) * y; }
inline complex_t operator * (complex_t x, longdouble y) { return x * complex_t(y); }
inline complex_t operator / (complex_t x, longdouble y) { return x / complex_t(y); }
inline long double creall(complex_t x)
inline longdouble creall(complex_t x)
{
return x.re;
}
inline long double cimagl(complex_t x)
inline longdouble cimagl(complex_t x)
{
return x.im;
}
+9 -9
View File
@@ -577,12 +577,12 @@ Expression *Pow(Type *type, Expression *e1, Expression *e2)
if (e1->type->isfloating())
{
r = new RealExp(loc, e1->toReal(), e1->type);
v = new RealExp(loc, 1.0, e1->type);
v = new RealExp(loc, ldouble(1.0), e1->type);
}
else
{
r = new RealExp(loc, e1->toReal(), Type::tfloat64);
v = new RealExp(loc, 1.0, Type::tfloat64);
v = new RealExp(loc, ldouble(1.0), Type::tfloat64);
}
while (n != 0)
@@ -594,7 +594,7 @@ Expression *Pow(Type *type, Expression *e1, Expression *e2)
}
if (neg)
v = Div(v->type, new RealExp(loc, 1.0, v->type), v);
v = Div(v->type, new RealExp(loc, ldouble(1.0), v->type), v);
if (type->isintegral())
e = new IntegerExp(loc, v->toInteger(), type);
@@ -606,7 +606,7 @@ Expression *Pow(Type *type, Expression *e1, Expression *e2)
// x ^^ y for x < 0 and y not an integer is not defined
if (e1->toReal() < 0.0)
{
e = new RealExp(loc, Port::nan, type);
e = new RealExp(loc, ldouble(Port::nan), type);
}
else if (e2->toReal() == 0.5)
{
@@ -1346,7 +1346,7 @@ Expression *Index(Type *type, Expression *e1, Expression *e2)
if (i >= es1->len)
{
e1->error("string index %ju is out of bounds [0 .. %zu]", i, es1->len);
e1->error("string index %llu is out of bounds [0 .. %llu]", i, (ulonglong)es1->len);
e = new ErrorExp();
}
else
@@ -1361,7 +1361,7 @@ Expression *Index(Type *type, Expression *e1, Expression *e2)
if (i >= length)
{
e1->error("array index %ju is out of bounds %s[0 .. %ju]", i, e1->toChars(), length);
e1->error("array index %llu is out of bounds %s[0 .. %llu]", i, e1->toChars(), length);
e = new ErrorExp();
}
else if (e1->op == TOKarrayliteral)
@@ -1380,7 +1380,7 @@ Expression *Index(Type *type, Expression *e1, Expression *e2)
{ ArrayLiteralExp *ale = (ArrayLiteralExp *)e1;
if (i >= ale->elements->dim)
{
e1->error("array index %ju is out of bounds %s[0 .. %u]", i, e1->toChars(), ale->elements->dim);
e1->error("array index %llu is out of bounds %s[0 .. %u]", i, e1->toChars(), ale->elements->dim);
e = new ErrorExp();
}
else
@@ -1436,7 +1436,7 @@ Expression *Slice(Type *type, Expression *e1, Expression *lwr, Expression *upr)
if (iupr > es1->len || ilwr > iupr)
{
e1->error("string slice [%ju .. %ju] is out of bounds", ilwr, iupr);
e1->error("string slice [%llu .. %llu] is out of bounds", ilwr, iupr);
e = new ErrorExp();
}
else
@@ -1466,7 +1466,7 @@ Expression *Slice(Type *type, Expression *e1, Expression *lwr, Expression *upr)
if (iupr > es1->elements->dim || ilwr > iupr)
{
e1->error("array slice [%ju .. %ju] is out of bounds", ilwr, iupr);
e1->error("array slice [%llu .. %llu] is out of bounds", ilwr, iupr);
e = new ErrorExp();
}
else
+1 -1
View File
@@ -277,7 +277,7 @@ void TypeVector::toCppMangle(OutBuffer *buf, CppMangleState *cms)
void TypeSArray::toCppMangle(OutBuffer *buf, CppMangleState *cms)
{
if (!cms->substitute(buf, this))
{ buf->printf("A%ju_", dim ? dim->toInteger() : 0);
{ buf->printf("A%llu_", dim ? dim->toInteger() : 0);
next->toCppMangle(buf, cms);
}
}
+117 -16
View File
@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2011 by Digital Mars
// Copyright (c) 1999-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -490,7 +490,8 @@ void AliasDeclaration::semantic(Scope *sc)
if (s)
goto L2;
error("cannot alias an expression %s", e->toChars());
if (e->op != TOKerror)
error("cannot alias an expression %s", e->toChars());
t = e->type;
}
else if (t)
@@ -502,7 +503,7 @@ void AliasDeclaration::semantic(Scope *sc)
ScopeDsymbol::multiplyDefined(0, this, overnext);
this->inSemantic = 0;
if (errors != global.errors)
if (global.gag && errors != global.errors)
type = savedtype;
return;
@@ -538,7 +539,7 @@ void AliasDeclaration::semantic(Scope *sc)
assert(global.errors);
s = NULL;
}
if (errors != global.errors)
if (global.gag && errors != global.errors)
{
type = savedtype;
overnext = savedovernext;
@@ -669,6 +670,7 @@ VarDeclaration::VarDeclaration(Loc loc, Type *type, Identifier *id, Initializer
#if DMDV1
nestedref = 0;
#endif
alignment = 0;
ctorinit = 0;
aliassym = NULL;
onstack = 0;
@@ -976,7 +978,7 @@ Lnomatch:
{ Parameter *arg = Parameter::getNth(tt->arguments, i);
OutBuffer buf;
buf.printf("_%s_field_%zu", ident->toChars(), i);
buf.printf("_%s_field_%llu", ident->toChars(), (ulonglong)i);
buf.writeByte(0);
const char *name = (const char *)buf.extractData();
Identifier *id = Lexer::idPool(name);
@@ -1051,9 +1053,7 @@ Lnomatch:
}
else
{
AggregateDeclaration *aad = sc->anonAgg;
if (!aad)
aad = parent->isAggregateDeclaration();
AggregateDeclaration *aad = parent->isAggregateDeclaration();
if (aad)
{
#if DMDV2
@@ -1065,15 +1065,16 @@ Lnomatch:
storage_class |= STCstatic;
}
else
#endif
{
aad->addField(sc, this);
storage_class |= STCfield;
alignment = sc->structalign;
#if DMDV2
if (tb->ty == Tstruct && ((TypeStruct *)tb)->sym->noDefaultCtor ||
tb->ty == Tclass && ((TypeClass *)tb)->sym->noDefaultCtor)
aad->noDefaultCtor = TRUE;
}
#else
aad->addField(sc, this);
#endif
}
}
InterfaceDeclaration *id = parent->isInterfaceDeclaration();
@@ -1126,7 +1127,7 @@ Lnomatch:
{
if (func->fes)
func = func->fes->func;
if (!func->type->hasWild())
if (!((TypeFunction *)func->type)->iswild)
{
error("inout variables can only be declared inside inout functions");
}
@@ -1232,9 +1233,6 @@ Lnomatch:
StructInitializer *si = init->isStructInitializer();
ExpInitializer *ei = init->isExpInitializer();
if (ei && ei->exp->op == TOKfunction && !inferred)
((FuncExp *)ei->exp)->setType(type);
if (ei && isScope())
{
// See if initializer is a NewExp that can be allocated on the stack
@@ -1283,6 +1281,8 @@ Lnomatch:
Expression *e1 = new VarExp(loc, this);
Type *t = type->toBasetype();
if (ei && !inferred)
ei->exp = ei->exp->inferType(t);
Linit2:
if (t->ty == Tsarray && !(storage_class & (STCref | STCout)))
@@ -1558,6 +1558,31 @@ Ldtor:
void VarDeclaration::semantic2(Scope *sc)
{
//printf("VarDeclaration::semantic2('%s')\n", toChars());
// Inside unions, default to void initializers
if (!init && sc->inunion && !toParent()->isFuncDeclaration())
{
AggregateDeclaration *aad = parent->isAggregateDeclaration();
if (aad)
{
if (aad->fields[0] == this)
{
int hasinit = 0;
for (size_t i = 1; i < aad->fields.dim; i++)
{
if (aad->fields[i]->init &&
!aad->fields[i]->init->isVoidInitializer())
{
hasinit = 1;
break;
}
}
if (!hasinit)
init = new ExpInitializer(loc, type->defaultInitLiteral(loc));
}
else
init = new VoidInitializer(loc);
}
}
if (init && !toParent()->isFuncDeclaration())
{ inuse++;
#if 0
@@ -1574,6 +1599,82 @@ void VarDeclaration::semantic2(Scope *sc)
sem = Semantic2Done;
}
void VarDeclaration::setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion)
{
//printf("VarDeclaration::setFieldOffset(ad = %s) %s\n", ad->toChars(), toChars());
if (aliassym)
{ // If this variable was really a tuple, set the offsets for the tuple fields
TupleDeclaration *v2 = aliassym->isTupleDeclaration();
assert(v2);
for (size_t i = 0; i < v2->objects->dim; i++)
{ Object *o = (*v2->objects)[i];
assert(o->dyncast() == DYNCAST_EXPRESSION);
Expression *e = (Expression *)o;
assert(e->op == TOKdsymbol);
DsymbolExp *se = (DsymbolExp *)e;
se->s->setFieldOffset(ad, poffset, isunion);
}
return;
}
if (!(storage_class & STCfield))
return;
assert(!(storage_class & (STCstatic | STCextern | STCparameter | STCtls)));
/* Fields that are tuples appear both as part of TupleDeclarations and
* as members. That means ignore them if they are already a field.
*/
if (offset)
return; // already a field
for (size_t i = 0; i < ad->fields.dim; i++)
{
if (ad->fields[i] == this)
return; // already a field
}
// Check for forward referenced types which will fail the size() call
Type *t = type->toBasetype();
if (storage_class & STCref)
{ // References are the size of a pointer
t = Type::tvoidptr;
}
if (t->ty == Tstruct)
{ TypeStruct *ts = (TypeStruct *)t;
#if DMDV2
if (ts->sym == ad)
{
ad->error("cannot have field %s with same struct type", toChars());
}
#endif
if (ts->sym->sizeok != SIZEOKdone && ts->sym->scope)
ts->sym->semantic(NULL);
if (ts->sym->sizeok != SIZEOKdone)
{
ad->sizeok = SIZEOKfwd; // cannot finish; flag as forward referenced
return;
}
}
if (t->ty == Tident)
{
ad->sizeok = SIZEOKfwd; // cannot finish; flag as forward referenced
return;
}
unsigned memsize = t->size(loc); // size of member
unsigned memalignsize = t->alignsize(); // size of member for alignment purposes
unsigned memalign = t->memalign(alignment); // alignment boundaries
offset = AggregateDeclaration::placeField(poffset, memsize, memalignsize, memalign,
&ad->structsize, &ad->alignsize, isunion);
//printf("\t%s: alignsize = %d\n", toChars(), alignsize);
//printf(" addField '%s' to '%s' at offset %d, size = %d\n", toChars(), ad->toChars(), offset, memsize);
ad->fields.push(this);
}
const char *VarDeclaration::kind()
{
return "variable";
+19 -1
View File
@@ -119,6 +119,10 @@ struct Declaration : Dsymbol
enum LINK linkage;
int inuse; // used to detect cycles
#if IN_GCC
Expressions *attributes; // GCC decl/type attributes
#endif
enum Semantic sem;
Declaration(Identifier *id);
@@ -246,6 +250,7 @@ struct VarDeclaration : Declaration
#else
int nestedref; // referenced by a lexically nested function
#endif
unsigned short alignment;
int ctorinit; // it has been initialized in a ctor
int onstack; // 1: it has been allocated on the stack
// 2: on stack, run destructor anyway
@@ -272,6 +277,7 @@ struct VarDeclaration : Declaration
VarDeclaration(Loc loc, Type *t, Identifier *id, Initializer *init);
Dsymbol *syntaxCopy(Dsymbol *);
void semantic(Scope *sc);
void setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion);
void semantic2(Scope *sc);
const char *kind();
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
@@ -523,6 +529,9 @@ enum BUILTIN
BUILTINbsr, // core.bitop.bsr
BUILTINbsf, // core.bitop.bsf
BUILTINbswap, // core.bitop.bswap
#if IN_GCC
BUILTINgcc, // GCC builtin
#endif
};
Expression *eval_builtin(Loc loc, enum BUILTIN builtin, Expressions *arguments);
@@ -596,6 +605,7 @@ struct FuncDeclaration : Declaration
VarDeclarations closureVars; // local variables in this function
// which are referenced by nested
// functions
FuncDeclarations deferred; // toObjFile() these functions after this one
unsigned flags;
#define FUNCFLAGpurityInprocess 1 // working on determining purity
@@ -640,10 +650,12 @@ struct FuncDeclaration : Declaration
int isAbstract();
int isCodeseg();
int isOverloadable();
int hasOverloads();
enum PURE isPure();
enum PURE isPureBypassingInference();
bool setImpure();
int isSafe();
bool isSafeBypassingInference();
int isTrusted();
bool setUnsafe();
virtual int isNested();
@@ -677,6 +689,8 @@ struct FuncDeclaration : Declaration
void buildClosure(IRState *irs);
FuncDeclaration *isFuncDeclaration() { return this; }
virtual FuncDeclaration *toAliasFunc() { return this; }
};
#if DMDV2
@@ -690,12 +704,16 @@ FuncDeclaration *resolveFuncCall(Scope *sc, Loc loc, Dsymbol *s,
struct FuncAliasDeclaration : FuncDeclaration
{
FuncDeclaration *funcalias;
int hasOverloads;
FuncAliasDeclaration(FuncDeclaration *funcalias);
FuncAliasDeclaration(FuncDeclaration *funcalias, int hasOverloads = 1);
FuncAliasDeclaration *isFuncAliasDeclaration() { return this; }
const char *kind();
Symbol *toSymbol();
char *mangle() { return toAliasFunc()->mangle(); }
FuncDeclaration *toAliasFunc();
};
struct FuncLiteralDeclaration : FuncDeclaration
+4 -1
View File
@@ -34,7 +34,10 @@ int lambdaCheckForNestedRef(Expression *e, void *param);
Expression *Expression::toDelegate(Scope *sc, Type *t)
{
//printf("Expression::toDelegate(t = %s) %s\n", t->toChars(), toChars());
TypeFunction *tf = new TypeFunction(NULL, t, 0, LINKd);
Type *tw = t->semantic(loc, sc);
Type *tc = t->substWildTo(MODconst)->semantic(loc, sc);
TypeFunction *tf = new TypeFunction(NULL, tc, 0, LINKd);
(tf = (TypeFunction *)tf->semantic(loc, sc))->next = tw; // hack for bug7757
FuncLiteralDeclaration *fld =
new FuncLiteralDeclaration(loc, loc, tf, TOKdelegate, NULL);
Expression *e;
+2088
View File
File diff suppressed because it is too large Load Diff
+3
View File
@@ -261,6 +261,9 @@ void Module::gendocfile()
Macro::define(&macrotable, (unsigned char *)"YEAR", 4, (unsigned char *)p + 20, 4);
}
char *srcfilename = srcfile->toChars();
Macro::define(&macrotable, (unsigned char *)"SRCFILENAME", 11, (unsigned char *)srcfilename, strlen(srcfilename));
char *docfilename = docfile->toChars();
Macro::define(&macrotable, (unsigned char *)"DOCFILENAME", 11, (unsigned char *)docfilename, strlen(docfilename));
+61 -9
View File
@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2011 by Digital Mars
// Copyright (c) 1999-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -45,6 +45,7 @@ Dsymbol::Dsymbol()
this->loc = 0;
this->comment = NULL;
this->scope = NULL;
this->errors = false;
}
Dsymbol::Dsymbol(Identifier *ident)
@@ -58,6 +59,7 @@ Dsymbol::Dsymbol(Identifier *ident)
this->loc = 0;
this->comment = NULL;
this->scope = NULL;
this->errors = false;
}
int Dsymbol::equals(Object *o)
@@ -130,12 +132,15 @@ int Dsymbol::oneMembers(Dsymbols *members, Dsymbol **ps, Identifier *ident)
if (!(*ps)->ident || !(*ps)->ident->equals(ident))
continue;
}
if (s) // more than one symbol
if (!s)
s = *ps;
else if (s->isOverloadable() && (*ps)->isOverloadable())
; // keep head of overload set
else // more than one symbol
{ *ps = NULL;
//printf("\tfalse 2\n");
return FALSE;
}
s = *ps;
}
}
}
@@ -160,6 +165,10 @@ bool Dsymbol::hasStaticCtorOrDtor()
return FALSE;
}
void Dsymbol::setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion)
{
}
char *Dsymbol::toChars()
{
return ident ? ident->toChars() : (char *)"__anonymous";
@@ -274,6 +283,23 @@ TemplateInstance *Dsymbol::inTemplateInstance()
return NULL;
}
// Check if this function is a member of a template which has only been
// instantiated speculatively, eg from inside is(typeof()).
// Return the speculative template instance it is part of,
// or NULL if not speculative.
TemplateInstance *Dsymbol::isSpeculative()
{
Dsymbol * par = parent;
while (par)
{
TemplateInstance *ti = par->isTemplateInstance();
if (ti && ti->speculative)
return ti;
par = par->toParent();
}
return NULL;
}
int Dsymbol::isAnonymous()
{
return ident ? 0 : 1;
@@ -358,11 +384,21 @@ Dsymbol *Dsymbol::search(Loc loc, Identifier *ident, int flags)
void *symbol_search_fp(void *arg, const char *seed)
{
/* If not in the lexer's string table, it certainly isn't in the symbol table.
* Doing this first is a lot faster.
*/
size_t len = strlen(seed);
if (!len)
return NULL;
StringValue *sv = Lexer::stringtable.lookup(seed, len);
if (!sv)
return NULL;
Identifier *id = (Identifier *)sv->ptrvalue;
assert(id);
Dsymbol *s = (Dsymbol *)arg;
Identifier id(seed, 0);
Module::clearCache();
s = s->search(0, &id, 4|2);
return s;
return s->search(0, id, 4|2);
}
Dsymbol *Dsymbol::search_correct(Identifier *ident)
@@ -400,8 +436,14 @@ Dsymbol *Dsymbol::searchX(Loc loc, Scope *sc, Identifier *id)
id = ti->name;
sm = s->search(loc, id, 0);
if (!sm)
{ error("template identifier %s is not a member of %s %s",
id->toChars(), s->kind(), s->toChars());
{
sm = s->search_correct(id);
if (sm)
error("template identifier '%s' is not a member of '%s %s', did you mean '%s %s'?",
id->toChars(), s->kind(), s->toChars(), sm->kind(), sm->toChars());
else
error("template identifier '%s' is not a member of '%s %s'",
id->toChars(), s->kind(), s->toChars());
return NULL;
}
sm = sm->toAlias();
@@ -490,6 +532,11 @@ int Dsymbol::isOverloadable()
{
return 0;
}
int Dsymbol::hasOverloads()
{
return 0;
}
#endif
LabelDsymbol *Dsymbol::isLabel() // is this a LabelDsymbol()?
@@ -515,6 +562,11 @@ int Dsymbol::needThis()
return FALSE;
}
int Dsymbol::apply(Dsymbol_apply_ft_t fp, void *param)
{
return (*fp)(this, param);
}
int Dsymbol::addMember(Scope *sc, ScopeDsymbol *sd, int memnum)
{
//printf("Dsymbol::addMember('%s')\n", toChars());
@@ -1093,7 +1145,7 @@ int ScopeDsymbol::foreach(Dsymbols *members, ScopeDsymbol::ForeachDg dg, void *c
{ Dsymbol *s = (*members)[i];
if (AttribDeclaration *a = s->isAttribDeclaration())
result = foreach(a->decl, dg, ctx, &n);
result = foreach(a->include(NULL, NULL), dg, ctx, &n);
else if (TemplateMixin *tm = s->isTemplateMixin())
result = foreach(tm->members, dg, ctx, &n);
else if (s->isTemplateInstance())
+8 -1
View File
@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2011 by Digital Mars
// Copyright (c) 1999-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -109,6 +109,8 @@ enum PASS
PASSobj, // toObjFile() run
};
typedef int (*Dsymbol_apply_ft_t)(Dsymbol *, void *);
struct Dsymbol : Object
{
Identifier *ident;
@@ -119,6 +121,7 @@ struct Dsymbol : Object
unsigned char *comment; // documentation comment for this Dsymbol
Loc loc; // where defined
Scope *scope; // !=NULL means context to use for semantic()
bool errors; // this symbol failed to pass semantic()
Dsymbol();
Dsymbol(Identifier *);
@@ -136,6 +139,7 @@ struct Dsymbol : Object
Dsymbol *toParent();
Dsymbol *toParent2();
TemplateInstance *inTemplateInstance();
TemplateInstance *isSpeculative();
int dyncast() { return DYNCAST_DSYMBOL; } // kludge for template.isSymbol()
@@ -144,6 +148,7 @@ struct Dsymbol : Object
virtual const char *toPrettyChars();
virtual const char *kind();
virtual Dsymbol *toAlias(); // resolve real symbol
virtual int apply(Dsymbol_apply_ft_t fp, void *param);
virtual int addMember(Scope *sc, ScopeDsymbol *s, int memnum);
virtual void setScope(Scope *sc);
virtual void importAll(Scope *sc);
@@ -172,6 +177,7 @@ struct Dsymbol : Object
virtual int isDeprecated(); // is Dsymbol deprecated?
#if DMDV2
virtual int isOverloadable();
virtual int hasOverloads();
#endif
virtual LabelDsymbol *isLabel(); // is this a LabelDsymbol?
virtual AggregateDeclaration *isMember(); // is this symbol a member of an AggregateDeclaration?
@@ -182,6 +188,7 @@ struct Dsymbol : Object
virtual Dsymbol *syntaxCopy(Dsymbol *s); // copy only syntax trees
virtual int oneMember(Dsymbol **ps, Identifier *ident);
static int oneMembers(Dsymbols *members, Dsymbol **ps, Identifier *ident = NULL);
virtual void setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion);
virtual int hasPointers();
virtual bool hasStaticCtorOrDtor();
virtual void addLocalClass(ClassDeclarations *) { }
+1 -1
View File
@@ -55,7 +55,7 @@ void Expression::dump(int i)
void IntegerExp::dump(int i)
{
indent(i);
printf("%p %jd type=%s\n", this, (intmax_t)value, type_print(type));
printf("%p %lld type=%s\n", this, (ulonglong)value, type_print(type));
}
void IdentifierExp::dump(int i)
+119 -47
View File
@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2011 by Digital Mars
// Copyright (c) 1999-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -11,7 +11,7 @@
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <complex.h>
//#include <complex.h>
#include "port.h"
@@ -2784,13 +2784,8 @@ elem *AssignExp::toElem(IRState *irs)
esize = el_bin(OPmul, TYsize_t, elen, esize);
elem *epto = array_toPtr(e1->type, ex);
elem *epfr = array_toPtr(e2->type, efrom);
#if 1
// memcpy() is faster, so if we can't beat 'em, join 'em
e = el_params(esize, epfr, epto, NULL);
e = el_bin(OPcall,TYnptr,el_var(rtlsym[RTLSYM_MEMCPY]),e);
#else
e = el_bin(OPmemcpy, TYnptr, epto, el_param(epfr, esize));
#endif
e = el_pair(eto->Ety, el_copytree(elen), e);
e = el_combine(eto, e);
}
@@ -3377,7 +3372,7 @@ elem *CondExp::toElem(IRState *irs)
elem *TypeExp::toElem(IRState *irs)
{
#ifdef DEBUG
#if 0
printf("TypeExp::toElem()\n");
#endif
error("type %s is not an expression", toChars());
@@ -3426,11 +3421,28 @@ elem *DelegateExp::toElem(IRState *irs)
int directcall = 0;
//printf("DelegateExp::toElem() '%s'\n", toChars());
if (func->semanticRun == PASSsemantic3done)
{ // Bug 7745 - only include the function if it belongs to this module
// ie, it is a member of this module, or is a template instance
// (the template declaration could come from any module).
Dsymbol * owner = func->toParent();
while (!owner->isTemplateInstance() && owner->toParent())
owner = owner->toParent();
if (owner->isTemplateInstance() || owner == irs->m )
{
irs->deferToObj->push(func);
}
}
sfunc = func->toSymbol();
if (func->isNested())
{
ep = el_ptr(sfunc);
ethis = getEthis(loc, irs, func);
if (e1->op == TOKnull)
ethis = e1->toElem(irs);
else
ethis = getEthis(loc, irs, func);
}
else
{
@@ -3460,8 +3472,7 @@ elem *DelegateExp::toElem(IRState *irs)
ep = el_una(OPind, TYnptr, ep);
vindex = func->vtblIndex;
if ((int)vindex < 0)
error("Internal compiler error: malformed delegate. See Bugzilla 4860");
assert((int)vindex >= 0);
// Build *(ep + vindex * 4)
ep = el_bin(OPadd,TYnptr,ep,el_long(TYsize_t, vindex * PTRSIZE));
@@ -3534,6 +3545,10 @@ elem *CallExp::toElem(IRState *irs)
}
break;
}
if (dve->e1->op == TOKstructliteral)
{ StructLiteralExp *sle = (StructLiteralExp *)dve->e1;
sle->sinit = NULL; // don't modify initializer
}
ec = dve->e1->toElem(irs);
ectype = dve->e1->type->toBasetype();
}
@@ -3541,7 +3556,10 @@ elem *CallExp::toElem(IRState *irs)
{
fd = ((VarExp *)e1)->var->isFuncDeclaration();
if (fd && fd->ident == Id::alloca &&
#if 0 // This optimization is not valid if alloca can be called
// multiple times within the same function, eg in a loop
// see issue 3822
if (fd && fd->ident == Id::__alloca &&
!fd->fbody && fd->linkage == LINKc &&
arguments && arguments->dim == 1)
{ Expression *arg = arguments->tdata()[0];
@@ -3567,6 +3585,7 @@ elem *CallExp::toElem(IRState *irs)
}
}
}
#endif
ec = e1->toElem(irs);
}
@@ -4336,7 +4355,7 @@ Lagain:
case X(Timaginary80,Tfloat32):
case X(Timaginary80,Tfloat64):
case X(Timaginary80,Tfloat80): goto Lzero;
case X(Timaginary80,Timaginary32): e = el_una(OPf_d, TYidouble, e);
case X(Timaginary80,Timaginary32): e = el_una(OPld_d, TYidouble, e);
fty = Timaginary64;
goto Lagain;
case X(Timaginary80,Timaginary64): eop = OPld_d; goto Leop;
@@ -4428,6 +4447,9 @@ Lagain:
fty = Tcomplex64;
goto Lagain;
case X(Tnull, Tarray):
goto Lzero;
/* ============================= */
default:
@@ -4789,22 +4811,34 @@ elem *ArrayLiteralExp::toElem(IRState *irs)
* exps[].
* Return the initialization expression, and the symbol for the static array in *psym.
*/
elem *ExpressionsToStaticArray(IRState *irs, Loc loc, Expressions *exps, Type *telem, symbol **psym)
elem *ExpressionsToStaticArray(IRState *irs, Loc loc, Expressions *exps, symbol **psym)
{
// Create a static array of type telem[dim]
size_t dim = exps->dim;
Type *tsarray = new TypeSArray(telem, new IntegerExp(loc, dim, Type::tsize_t));
tsarray = tsarray->semantic(loc, NULL);
symbol *stmp = symbol_genauto(tsarray->toCtype());
targ_size_t szelem = telem->size();
Elems elems;
elems.setDim(dim);
::type *te = telem->toCtype(); // stmp[] element type
Type *telem;
Type *tsarray;
symbol *stmp;
targ_size_t szelem;
::type *te; // stmp[] element type
for (size_t i = 0; i < dim; i++)
{ Expression *el = exps->tdata()[i];
{ Expression *el = (*exps)[i];
if (i == 0)
{
telem = el->type;
szelem = telem->size();
te = telem->toCtype();
tsarray = new TypeSArray(telem, new IntegerExp(loc, dim, Type::tsize_t));
tsarray = tsarray->semantic(loc, NULL);
stmp = symbol_genauto(tsarray->toCtype());
*psym = stmp;
}
/* Generate: *(&stmp + i * szelem) = element[i]
*/
@@ -4825,44 +4859,62 @@ elem *ExpressionsToStaticArray(IRState *irs, Loc loc, Expressions *exps, Type *t
eeq->Ejty = eeq->Ety = TYstruct;
eeq->ET = te;
}
elems.tdata()[i] = eeq;
elems[i] = eeq;
}
*psym = stmp;
return el_combines((void **)elems.tdata(), dim);
}
elem *AssocArrayLiteralExp::toElem(IRState *irs)
{
//printf("AssocArrayLiteralExp::toElem() %s\n", toChars());
size_t dim = keys->dim;
elem *e;
// call _d_assocarrayliteralTX(TypeInfo_AssociativeArray ti, void[] keys, void[] values)
// Prefer this to avoid the varargs fiasco in 64 bit code
Type *t = type->toBasetype()->mutableOf();
assert(t->ty == Taarray);
TypeAArray *ta = (TypeAArray *)t;
symbol *skeys;
elem *ekeys = ExpressionsToStaticArray(irs, loc, keys, ta->index, &skeys);
size_t dim = keys->dim;
if (dim)
{
// call _d_assocarrayliteralTX(TypeInfo_AssociativeArray ti, void[] keys, void[] values)
// Prefer this to avoid the varargs fiasco in 64 bit code
symbol *svalues;
elem *evalues = ExpressionsToStaticArray(irs, loc, values, ta->nextOf(), &svalues);
Type *ta;
if (t->ty == Taarray)
ta = t;
else
{ // It's the AssociativeArray type.
// Turn it back into a TypeAArray
ta = new TypeAArray((*values)[0]->type, (*keys)[0]->type);
ta = ta->semantic(loc, NULL);
}
e = el_params(el_pair(TYdarray, el_long(TYsize_t, dim), el_ptr(svalues)),
el_pair(TYdarray, el_long(TYsize_t, dim), el_ptr(skeys )),
ta->getTypeInfo(NULL)->toElem(irs),
NULL);
symbol *skeys = NULL;
elem *ekeys = ExpressionsToStaticArray(irs, loc, keys, &skeys);
// call _d_assocarrayliteralTX(ti, keys, values)
e = el_bin(OPcall,TYnptr,el_var(rtlsym[RTLSYM_ASSOCARRAYLITERALTX]),e);
el_setLoc(e,loc);
symbol *svalues = NULL;
elem *evalues = ExpressionsToStaticArray(irs, loc, values, &svalues);
e = el_combine(evalues, e);
e = el_combine(ekeys, e);
elem *e = el_params(el_pair(TYdarray, el_long(TYsize_t, dim), el_ptr(svalues)),
el_pair(TYdarray, el_long(TYsize_t, dim), el_ptr(skeys )),
ta->getTypeInfo(NULL)->toElem(irs),
NULL);
return e;
// call _d_assocarrayliteralTX(ti, keys, values)
e = el_bin(OPcall,TYnptr,el_var(rtlsym[RTLSYM_ASSOCARRAYLITERALTX]),e);
if (t != ta)
e = addressElem(e, ta);
el_setLoc(e,loc);
e = el_combine(evalues, e);
e = el_combine(ekeys, e);
return e;
}
else
{
elem *e = el_long(TYnptr, 0); // empty associative array is the null pointer
if (t->ty != Taarray)
e = addressElem(e, Type::tvoidptr);
return e;
}
}
@@ -4911,15 +4963,35 @@ elem *fillHole(Symbol *stmp, size_t *poffset, size_t offset2, size_t maxoff)
}
elem *StructLiteralExp::toElem(IRState *irs)
{ elem *e;
size_t dim;
{
//printf("StructLiteralExp::toElem() %s\n", toChars());
if (sinit)
{
elem *e = el_var(sinit);
e->ET = sd->type->toCtype();
el_setLoc(e,loc);
if (sym)
{ elem *ev = el_var(sym);
if (tybasic(ev->Ety) == TYnptr)
ev = el_una(OPind, e->Ety, ev);
ev->ET = e->ET;
e = el_bin(OPstreq,e->Ety,ev,e);
e->ET = ev->ET;
//ev = el_var(sym);
//ev->ET = e->ET;
//e = el_combine(e, ev);
el_setLoc(e,loc);
}
return e;
}
// struct symbol to initialize with the literal
Symbol *stmp = sym ? sym : symbol_genauto(sd->type->toCtype());
e = NULL;
elem *e = NULL;
if (fillHoles)
{
@@ -4944,7 +5016,7 @@ elem *StructLiteralExp::toElem(IRState *irs)
if (elements)
{
dim = elements->dim;
size_t dim = elements->dim;
assert(dim <= sd->fields.dim);
for (size_t i = 0; i < dim; i++)
{ Expression *el = elements->tdata()[i];
+6
View File
@@ -31,6 +31,10 @@
static char __file__[] = __FILE__; /* for tassert.h */
#include "tassert.h"
#if _MSC_VER
#include <alloca.h>
#endif
/* If we do our own EH tables and stack walking scheme
* (Otherwise use NT Structured Exception Handling)
*/
@@ -103,6 +107,8 @@ void except_fillInEHTable(symbol *s)
*/
#if OUREH
#define GUARD_SIZE (I64 ? 3*8 : 5*4) // sizeof(Guard)
#elif _WIN64
#define GUARD_SIZE (I64 ? 3*8 : 3*4) // sizeof(Guard) depends on target
#else
#define GUARD_SIZE (sizeof(Guard))
#endif
+20 -1
View File
@@ -167,6 +167,7 @@ void EnumDeclaration::semantic(Scope *sc)
{
EnumMember *em = (*members)[i]->isEnumMember();
Expression *e;
Expression *emax = NULL;
if (!em)
/* The e->semantic(sce) can insert other symbols, such as
@@ -217,10 +218,18 @@ void EnumDeclaration::semantic(Scope *sc)
}
else
{
// Lazily evaluate enum.max
if (!emax)
{
emax = t->getProperty(0, Id::max);
emax = emax->semantic(sce);
emax = emax->optimize(WANTvalue | WANTinterpret);
}
// Set value to (elast + 1).
// But first check that (elast != t.max)
assert(elast);
e = new EqualExp(TOKequal, em->loc, elast, t->getProperty(0, Id::max));
e = new EqualExp(TOKequal, em->loc, elast, emax);
e = e->semantic(sce);
e = e->optimize(WANTvalue | WANTinterpret);
if (e->toInteger())
@@ -231,6 +240,16 @@ void EnumDeclaration::semantic(Scope *sc)
e = e->semantic(sce);
e = e->castTo(sce, elast->type);
e = e->optimize(WANTvalue | WANTinterpret);
if (t->isfloating())
{
// Check that e != elast (not always true for floats)
Expression *etest = new EqualExp(TOKequal, em->loc, e, elast);
etest = etest->semantic(sce);
etest = etest->optimize(WANTvalue | WANTinterpret);
if (etest->toInteger())
error("enum member %s has inexact value, due to loss of precision", em->toChars());
}
}
elast = e;
em->value = e;
+3
View File
@@ -42,6 +42,9 @@ struct EnumDeclaration : ScopeDsymbol
int isdeprecated;
int isdone; // 0: not done
// 1: semantic() successfully completed
#if IN_GCC
Expressions *attributes; // GCC decl/type attributes
#endif
EnumDeclaration(Loc loc, Identifier *id, Type *memtype);
Dsymbol *syntaxCopy(Dsymbol *s);
+718 -889
View File
File diff suppressed because it is too large Load Diff
+29 -13
View File
@@ -79,7 +79,9 @@ int arrayExpressionCanThrow(Expressions *exps, bool mustNotThrow);
TemplateDeclaration *getFuncTemplateDecl(Dsymbol *s);
void valueNoDtor(Expression *e);
void modifyFieldVar(Loc loc, Scope *sc, VarDeclaration *var, Expression *e1);
#if DMDV2
Expression *resolveAliasThis(Scope *sc, Expression *e);
#endif
/* Interpreter: what form of return value expression is required?
*/
@@ -133,6 +135,7 @@ struct Expression : Object
virtual MATCH implicitConvTo(Type *t);
virtual IntRange getIntRange();
virtual Expression *castTo(Scope *sc, Type *t);
virtual Expression *inferType(Type *t, int flag = 0, TemplateParameters *tparams = NULL);
virtual void checkEscape();
virtual void checkEscapeRef();
virtual Expression *resolveLoc(Loc loc, Scope *sc);
@@ -436,6 +439,7 @@ struct ArrayLiteralExp : Expression
Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue);
MATCH implicitConvTo(Type *t);
Expression *castTo(Scope *sc, Type *t);
Expression *inferType(Type *t, int flag = 0, TemplateParameters *tparams = NULL);
dt_t **toDt(dt_t **pdt);
Expression *doInline(InlineDoState *ids);
@@ -461,6 +465,7 @@ struct AssocArrayLiteralExp : Expression
Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue);
MATCH implicitConvTo(Type *t);
Expression *castTo(Scope *sc, Type *t);
Expression *inferType(Type *t, int flag = 0, TemplateParameters *tparams = NULL);
Expression *doInline(InlineDoState *ids);
Expression *inlineScan(InlineScanState *iss);
@@ -473,6 +478,7 @@ struct StructLiteralExp : Expression
// NULL entries for fields to skip
Type *stype; // final type of result (can be different from sd's type)
Symbol *sinit; // if this is a defaultInitLiteral, this symbol contains the default initializer
Symbol *sym; // back end symbol to initialize with literal
size_t soffset; // offset from start of s
int fillHoles; // fill alignment 'holes' with zero
@@ -491,8 +497,6 @@ struct StructLiteralExp : Expression
Expression *optimize(int result);
Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue);
dt_t **toDt(dt_t **pdt);
int isLvalue();
Expression *toLvalue(Scope *sc, Expression *e);
MATCH implicitConvTo(Type *t);
int inlineCost3(InlineCostState *ics);
@@ -654,18 +658,17 @@ struct FuncExp : Expression
FuncLiteralDeclaration *fd;
TemplateDeclaration *td;
enum TOK tok;
Type *tded;
Scope *scope;
Type *treq;
FuncExp(Loc loc, FuncLiteralDeclaration *fd, TemplateDeclaration *td = NULL);
Expression *syntaxCopy();
Expression *semantic(Scope *sc);
Expression *semantic(Scope *sc, Expressions *arguments);
Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue);
Expression *implicitCastTo(Scope *sc, Type *t);
MATCH implicitConvTo(Type *t);
Expression *castTo(Scope *sc, Type *t);
Expression *inferType(Scope *sc, Type *t);
void setType(Type *t);
Expression *inferType(Type *t, int flag = 0, TemplateParameters *tparams = NULL);
char *toChars();
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
elem *toElem(IRState *irs);
@@ -778,8 +781,7 @@ struct BinExp : Expression
int apply(apply_fp_t fp, void *param);
Expression *semantic(Scope *sc);
Expression *semanticp(Scope *sc);
void checkComplexMulAssign();
void checkComplexAddAssign();
Expression *checkComplexOpAssign(Scope *sc);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
Expression *scaleFactor(Scope *sc);
Expression *typeCombine(Scope *sc);
@@ -787,6 +789,7 @@ struct BinExp : Expression
int isunsigned();
Expression *incompatibleTypes();
void dump(int indent);
Expression *interpretCommon(InterState *istate, CtfeGoal goal,
Expression *(*fp)(Type *, Expression *, Expression *));
Expression *interpretCommon2(InterState *istate, CtfeGoal goal,
@@ -811,8 +814,7 @@ struct BinAssignExp : BinExp
{
}
Expression *commonSemanticAssign(Scope *sc);
Expression *commonSemanticAssignIntegral(Scope *sc);
Expression *semantic(Scope *sc);
Expression *op_overload(Scope *sc);
@@ -898,6 +900,7 @@ struct DotTemplateInstanceExp : UnaExp
Expression *syntaxCopy();
TemplateDeclaration *getTempdecl(Scope *sc);
Expression *semantic(Scope *sc);
Expression *semantic(Scope *sc, int flag);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
void dump(int indent);
};
@@ -1248,7 +1251,7 @@ struct ConstructExp : AssignExp
struct op##AssignExp : BinAssignExp \
{ \
op##AssignExp(Loc loc, Expression *e1, Expression *e2); \
Expression *semantic(Scope *sc); \
S(Expression *semantic(Scope *sc);) \
Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue); \
X(void buildArrayIdent(OutBuffer *buf, Expressions *arguments);) \
X(Expression *buildArrayLoop(Parameters *fparams);) \
@@ -1259,6 +1262,7 @@ struct op##AssignExp : BinAssignExp \
};
#define X(a) a
#define S(a)
ASSIGNEXP(Add)
ASSIGNEXP(Min)
ASSIGNEXP(Mul)
@@ -1267,17 +1271,28 @@ ASSIGNEXP(Mod)
ASSIGNEXP(And)
ASSIGNEXP(Or)
ASSIGNEXP(Xor)
#undef S
#if DMDV2
#define S(a) a
ASSIGNEXP(Pow)
#undef S
#endif
#undef S
#undef X
#define X(a)
#define S(a)
ASSIGNEXP(Shl)
ASSIGNEXP(Shr)
ASSIGNEXP(Ushr)
#undef S
#define S(a) a
ASSIGNEXP(Cat)
#undef S
#undef X
#undef ASSIGNEXP
@@ -1580,7 +1595,7 @@ struct EqualExp : BinExp
elem *toElem(IRState *irs);
};
// === and !===
// is and !is
struct IdentityExp : BinExp
{
@@ -1613,6 +1628,7 @@ struct CondExp : BinExp
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
MATCH implicitConvTo(Type *t);
Expression *castTo(Scope *sc, Type *t);
Expression *inferType(Type *t, int flag = 0, TemplateParameters *tparams = NULL);
Expression *doInline(InlineDoState *ids);
Expression *inlineScan(InlineScanState *iss);
+105 -39
View File
@@ -1,5 +1,5 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2011 by Digital Mars
// Copyright (c) 1999-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -307,13 +307,6 @@ void FuncDeclaration::semantic(Scope *sc)
}
#endif
#ifdef IN_GCC
{
AggregateDeclaration *ad = parent->isAggregateDeclaration();
if (ad)
ad->methods.push(this);
}
#endif
sd = parent->isStructDeclaration();
if (sd)
{
@@ -434,6 +427,9 @@ void FuncDeclaration::semantic(Scope *sc)
//printf("\tnot virtual\n");
goto Ldone;
}
// Suppress further errors if the return type is an error
if (type->nextOf() == Type::terror)
goto Ldone;
/* Find index of existing function in base class's vtbl[] to override
* (the index will be the same as in cd's current vtbl[])
@@ -445,6 +441,7 @@ void FuncDeclaration::semantic(Scope *sc)
switch (vi)
{
case -1:
Lintro:
/* Didn't find one, so
* This is an 'introducing' function which gets a new
* slot in the vtbl[].
@@ -481,7 +478,7 @@ void FuncDeclaration::semantic(Scope *sc)
break;
case -2: // can't determine because of fwd refs
cd->sizeok = 2; // can't finish due to forward reference
cd->sizeok = SIZEOKfwd; // can't finish due to forward reference
Module::dprogress = dprogress_save;
return;
@@ -500,9 +497,12 @@ void FuncDeclaration::semantic(Scope *sc)
FuncDeclaration *fdc = ((Dsymbol *)cd->vtbl.data[vi])->isFuncDeclaration();
if (fdc->toParent() == parent)
{
// fdc overrides fdv exactly, then this introduces new function.
if (fdc->type->mod == fdv->type->mod && this->type->mod != fdv->type->mod)
goto Lintro;
// If both are mixins, then error.
// If either is not, the one that is not overrides the other.
if (this->parent->isClassDeclaration() && fdc->parent->isClassDeclaration())
error("multiple overrides of same function");
@@ -566,7 +566,7 @@ void FuncDeclaration::semantic(Scope *sc)
break;
case -2:
cd->sizeok = 2; // can't finish due to forward reference
cd->sizeok = SIZEOKfwd; // can't finish due to forward reference
Module::dprogress = dprogress_save;
return;
@@ -602,7 +602,7 @@ void FuncDeclaration::semantic(Scope *sc)
{
// any error in isBaseOf() is a forward reference error, so we bail out
global.errors = errors;
cd->sizeok = 2; // can't finish due to forward reference
cd->sizeok = SIZEOKfwd; // can't finish due to forward reference
Module::dprogress = dprogress_save;
return;
}
@@ -613,9 +613,14 @@ void FuncDeclaration::semantic(Scope *sc)
}
if (ti)
{
if (tintro && !tintro->equals(ti))
if (tintro)
{
error("incompatible covariant types %s and %s", tintro->toChars(), ti->toChars());
if (!tintro->nextOf()->equals(ti->nextOf()) &&
!tintro->nextOf()->isBaseOf(ti->nextOf(), NULL) &&
!ti->nextOf()->isBaseOf(tintro->nextOf(), NULL))
{
error("incompatible covariant types %s and %s", tintro->toChars(), ti->toChars());
}
}
tintro = ti;
}
@@ -626,7 +631,11 @@ void FuncDeclaration::semantic(Scope *sc)
if (!doesoverride && isOverride())
{
error("does not override any function");
Dsymbol *s = cd->search_correct(ident);
if (s)
error("does not override any function, did you mean '%s'", s->toPrettyChars());
else
error("does not override any function");
}
L2: ;
@@ -836,7 +845,7 @@ void FuncDeclaration::semantic3(Scope *sc)
//printf("FuncDeclaration::semantic3(%s '%s', sc = %p)\n", kind(), toChars(), sc);
assert(0);
}
//printf("FuncDeclaration::semantic3('%s.%s', sc = %p, loc = %s)\n", parent->toChars(), toChars(), sc, loc.toChars());
//printf("FuncDeclaration::semantic3('%s.%s', %p, sc = %p, loc = %s)\n", parent->toChars(), toChars(), this, sc, loc.toChars());
//fflush(stdout);
//printf("storage class = x%x %x\n", sc->stc, storage_class);
//{ static int x; if (++x == 2) *(char*)0=0; }
@@ -925,6 +934,9 @@ void FuncDeclaration::semantic3(Scope *sc)
}
else
assert(!isNested() || sc->intypeof); // can't be both member and nested
#if IN_GCC
ad->methods.push(this);
#endif
}
vthis = declareThis(sc2, ad);
@@ -936,6 +948,7 @@ void FuncDeclaration::semantic3(Scope *sc)
#else
Type *t;
#ifndef IN_GCC
if (global.params.is64bit)
{ // Declare save area for varargs registers
Type *t = new TypeIdentifier(loc, Id::va_argsave_t);
@@ -953,6 +966,7 @@ void FuncDeclaration::semantic3(Scope *sc)
v_argsave->parent = this;
}
}
#endif
if (f->linkage == LINKd)
{ // Declare _arguments[]
@@ -1241,7 +1255,7 @@ void FuncDeclaration::semantic3(Scope *sc)
}
}
if (inferRetType || f->retStyle() != RETstack)
if (!inferRetType && f->retStyle() != RETstack)
nrvo_can = 0;
fbody = fbody->semantic(sc2);
@@ -1763,11 +1777,13 @@ int FuncDeclaration::equals(Object *o)
Dsymbol *s = isDsymbol(o);
if (s)
{
FuncDeclaration *fd = s->isFuncDeclaration();
if (fd)
FuncDeclaration *fd1 = this->toAliasFunc();
FuncDeclaration *fd2 = s->isFuncDeclaration();
if (fd2)
{
return toParent()->equals(fd->toParent()) &&
ident->equals(fd->ident) && type->equals(fd->type);
fd2 = fd2->toAliasFunc();
return fd1->toParent()->equals(fd2->toParent()) &&
fd1->ident->equals(fd2->ident) && fd1->type->equals(fd2->type);
}
}
return FALSE;
@@ -1983,6 +1999,8 @@ int FuncDeclaration::overrides(FuncDeclaration *fd)
int FuncDeclaration::findVtblIndex(Dsymbols *vtbl, int dim)
{
FuncDeclaration *mismatch = NULL;
StorageClass mismatchstc = 0;
int mismatchvi = -1;
int bestvi = -1;
for (int vi = 0; vi < dim; vi++)
{
@@ -1992,7 +2010,8 @@ int FuncDeclaration::findVtblIndex(Dsymbols *vtbl, int dim)
if (type->equals(fdv->type)) // if exact match
return vi; // no need to look further
int cov = type->covariant(fdv->type);
StorageClass stc = 0;
int cov = type->covariant(fdv->type, &stc);
//printf("\tbaseclass cov = %d\n", cov);
switch (cov)
{
@@ -2004,6 +2023,8 @@ int FuncDeclaration::findVtblIndex(Dsymbols *vtbl, int dim)
break; // keep looking for an exact match
case 2:
mismatchvi = vi;
mismatchstc = stc;
mismatch = fdv; // overrides, but is not covariant
break; // keep looking for an exact match
@@ -2020,8 +2041,15 @@ int FuncDeclaration::findVtblIndex(Dsymbols *vtbl, int dim)
//type->print();
//mismatch->type->print();
//printf("%s %s\n", type->deco, mismatch->type->deco);
error("of type %s overrides but is not covariant with %s of type %s",
type->toChars(), mismatch->toPrettyChars(), mismatch->type->toChars());
//printf("stc = %llx\n", mismatchstc);
if (mismatchstc)
{ // Fix it by modifying the type to add the storage classes
type = type->addStorageClass(mismatchstc);
bestvi = mismatchvi;
}
else
error("of type %s overrides but is not covariant with %s of type %s",
type->toChars(), mismatch->toPrettyChars(), mismatch->type->toChars());
}
return bestvi;
}
@@ -2108,8 +2136,21 @@ int overloadApply(FuncDeclaration *fstart,
if (fa)
{
if (overloadApply(fa->funcalias, fp, param))
return 1;
if (fa->hasOverloads)
{
if (overloadApply(fa->funcalias, fp, param))
return 1;
}
else
{
f = fa->toAliasFunc();
if (!f)
{ d->error("is aliased to a function");
break;
}
if ((*fp)(param, f))
return 1;
}
next = fa->overnext;
}
else
@@ -2457,7 +2498,7 @@ MATCH FuncDeclaration::leastAsSpecialized(FuncDeclaration *g)
e->type = p->type;
}
else
e = p->type->defaultInit();
e = p->type->defaultInitLiteral(0);
args.tdata()[u] = e;
}
@@ -2771,6 +2812,11 @@ int FuncDeclaration::isOverloadable()
return 1; // functions can be overloaded
}
int FuncDeclaration::hasOverloads()
{
return overnext != NULL;
}
enum PURE FuncDeclaration::isPure()
{
//printf("FuncDeclaration::isPure() '%s'\n", toChars());
@@ -2828,6 +2874,14 @@ int FuncDeclaration::isSafe()
return ((TypeFunction *)type)->trust == TRUSTsafe;
}
bool FuncDeclaration::isSafeBypassingInference()
{
if (flags & FUNCFLAGsafetyInprocess)
return false;
else
return isSafe();
}
int FuncDeclaration::isTrusted()
{
assert(type->ty == Tfunction);
@@ -2858,21 +2912,16 @@ bool FuncDeclaration::setUnsafe()
int FuncDeclaration::isNested()
{
//if (!toParent())
//printf("FuncDeclaration::isNested('%s') parent=%p\n", toChars(), parent);
//printf("\ttoParent2() = '%s'\n", toParent2()->toChars());
return ((storage_class & STCstatic) == 0) &&
(toParent2()->isFuncDeclaration() != NULL);
FuncDeclaration *f = toAliasFunc();
//printf("\ttoParent2() = '%s'\n", f->toParent2()->toChars());
return ((f->storage_class & STCstatic) == 0) &&
(f->toParent2()->isFuncDeclaration() != NULL);
}
int FuncDeclaration::needThis()
{
//printf("FuncDeclaration::needThis() '%s'\n", toChars());
int i = isThis() != NULL;
//printf("\t%d\n", i);
if (!i && isFuncAliasDeclaration())
i = ((FuncAliasDeclaration *)this)->funcalias->needThis();
return i;
return toAliasFunc()->isThis() != NULL;
}
int FuncDeclaration::addPreInvariant()
@@ -3114,12 +3163,24 @@ Parameters *FuncDeclaration::getParameters(int *pvarargs)
// Used as a way to import a set of functions from another scope into this one.
FuncAliasDeclaration::FuncAliasDeclaration(FuncDeclaration *funcalias)
FuncAliasDeclaration::FuncAliasDeclaration(FuncDeclaration *funcalias, int hasOverloads)
: FuncDeclaration(funcalias->loc, funcalias->endloc, funcalias->ident,
funcalias->storage_class, funcalias->type)
{
assert(funcalias != this);
this->funcalias = funcalias;
this->hasOverloads = hasOverloads;
if (hasOverloads)
{
if (FuncAliasDeclaration *fad = funcalias->isFuncAliasDeclaration())
this->hasOverloads = fad->hasOverloads;
}
else
{ // for internal use
assert(!funcalias->isFuncAliasDeclaration());
this->hasOverloads = 0;
}
}
const char *FuncAliasDeclaration::kind()
@@ -3127,6 +3188,11 @@ const char *FuncAliasDeclaration::kind()
return "function alias";
}
FuncDeclaration *FuncAliasDeclaration::toAliasFunc()
{
return funcalias->toAliasFunc();
}
/****************************** FuncLiteralDeclaration ************************/
@@ -3574,7 +3640,7 @@ int StaticCtorDeclaration::addPostInvariant()
void StaticCtorDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
if (hgs->hdrgen)
if (hgs->hdrgen && !hgs->tpltMember)
{ buf->writestring("static this();");
buf->writenl();
return;
+29 -4
View File
@@ -674,6 +674,12 @@ void FuncDeclaration::toObjFile(int multiobj)
irs.shidden = shidden;
this->shidden = shidden;
}
else
{ // Register return style cannot make nrvo.
// Auto functions keep the nrvo_can flag up to here,
// so we should eliminate it before entering backend.
nrvo_can = 0;
}
if (vthis)
{
@@ -969,10 +975,32 @@ void FuncDeclaration::toObjFile(int multiobj)
for (size_t i = 0; i < irs.deferToObj->dim; i++)
{
Dsymbol *s = irs.deferToObj->tdata()[i];
Dsymbol *s = (*irs.deferToObj)[i];
FuncDeclaration *fd = s->isFuncDeclaration();
if (fd)
{ FuncDeclaration *fdp = fd->toParent2()->isFuncDeclaration();
if (fdp && fdp->semanticRun < PASSobj)
{ /* Bugzilla 7595
* FuncDeclaration::buildClosure() relies on nested functions
* being toObjFile'd after the outer function. Otherwise, the
* v->offset's for the closure variables are wrong.
* So, defer fd until after fdp is done.
*/
fdp->deferred.push(fd);
continue;
}
}
s->toObjFile(0);
}
for (size_t i = 0; i < deferred.dim; i++)
{
FuncDeclaration *fd = deferred[i];
fd->toObjFile(0);
}
#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS
// A hack to get a pointer to this function put in the .dtors segment
if (ident && memcmp(ident->toChars(), "_STD", 4) == 0)
@@ -1048,9 +1076,6 @@ unsigned Type::totym()
case Tident:
case Ttypeof:
#ifdef DEBUG
printf("ty = %d, '%s'\n", ty, toChars());
#endif
error(0, "forward reference of %s", toChars());
t = TYint;
break;
+23 -24
View File
@@ -459,7 +459,7 @@ typedef struct opnd
opflag_t usFlags;
Dsymbol *s;
targ_llong disp;
long double real;
longdouble real;
Type *ptype;
ASM_JUMPTYPE ajt;
} OPND;
@@ -638,6 +638,11 @@ RETRY:
if (I64 && (pop->ptb.pptb0->usFlags & _i64_bit))
asmerr( EM_invalid_64bit_opcode, asm_opstr(pop)); // illegal opcode in 64bit mode
if ((asmstate.ucItype == ITopt ||
asmstate.ucItype == ITfloat) &&
usNumops != 0)
goto PARAM_ERROR;
ptbRet = pop->ptb;
goto RETURN_IT;
@@ -674,16 +679,23 @@ RETRY:
0)) &&
popnd1->disp == table1->usFlags)
break;
if ((asmstate.ucItype == ITopt ||
asmstate.ucItype == ITfloat) &&
!usNumops &&
!table1->usOp1)
if (asmstate.ucItype == ITopt ||
asmstate.ucItype == ITfloat)
{
if (usNumops > 1)
goto PARAM_ERROR;
break;
switch (usNumops)
{
case 0:
if (!table1->usOp1)
goto Lfound1;
break;
case 1:
break;
default:
goto PARAM_ERROR;
}
}
}
Lfound1:
if (table1->usOpcode == ASM_END)
{
#ifdef DEBUG
@@ -1293,7 +1305,7 @@ STATIC code *asm_emit(Loc loc,
unsigned char *puc;
unsigned usDefaultseg;
code *pc = NULL;
OPND *popndTmp;
OPND *popndTmp = NULL;
ASM_OPERAND_TYPE aoptyTmp;
unsigned uSizemaskTmp;
REG *pregSegment;
@@ -2123,18 +2135,12 @@ code *asm_genloc(Loc loc, code *c)
STATIC void asmerr(int errnum, ...)
{ const char *format;
const char *p = asmstate.loc.toChars();
if (*p)
printf("%s: ", p);
format = asmerrmsgs[errnum];
va_list ap;
va_start(ap, errnum);
vprintf(format, ap);
verror(asmstate.loc, format, ap);
va_end(ap);
printf("\n");
fflush(stdout);
longjmp(asmstate.env,1);
}
@@ -2143,18 +2149,11 @@ STATIC void asmerr(int errnum, ...)
STATIC void asmerr(const char *format, ...)
{
const char *p = asmstate.loc.toChars();
if (*p)
printf("%s: ", p);
va_list ap;
va_start(ap, format);
vprintf(format, ap);
verror(asmstate.loc, format, ap);
va_end(ap);
printf("\n");
fflush(stdout);
longjmp(asmstate.env,1);
}
+1 -1
View File
@@ -94,7 +94,7 @@ Identifier *Identifier::generateId(const char *prefix, size_t i)
{ OutBuffer buf;
buf.writestring(prefix);
buf.printf("%zu", i);
buf.printf("%llu", (ulonglong)i);
char *id = buf.toChars();
buf.data = NULL;
+1 -1
View File
@@ -271,7 +271,7 @@ Msgtable msgtable[] =
{ "getmembers", "getMembers" },
// Special functions
{ "alloca" },
{ "__alloca", "alloca" }, // has to be mapped because alloca is #defined if _MSC_VER
{ "main" },
{ "WinMain" },
{ "DllMain" },
+50 -23
View File
@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2009 by Digital Mars
// Copyright (c) 1999-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -77,13 +77,11 @@ Dsymbol *Import::syntaxCopy(Dsymbol *s)
{
assert(!s);
Import *si;
si = new Import(loc, packages, id, aliasId, isstatic);
Import *si = new Import(loc, packages, id, aliasId, isstatic);
for (size_t i = 0; i < names.dim; i++)
{
si->addAlias(names.tdata()[i], aliases.tdata()[i]);
si->addAlias(names[i], aliases[i]);
}
return si;
@@ -95,7 +93,16 @@ void Import::load(Scope *sc)
// See if existing module
DsymbolTable *dst = Package::resolve(packages, NULL, &pkg);
#if TARGET_NET //dot net needs modules and packages with same name
#else
if (pkg && pkg->isModule())
{
::error(loc, "can only import from a module, not from a member of module %s. Did you mean `import %s : %s`?",
pkg->toChars(), pkg->toPrettyChars(), id->toChars());
mod = pkg->isModule(); // Error recovery - treat as import of that module
return;
}
#endif
Dsymbol *s = dst->lookup(id);
if (s)
{
@@ -105,7 +112,8 @@ void Import::load(Scope *sc)
if (s->isModule())
mod = (Module *)s;
else
error("package and module have the same name");
::error(loc, "can only import from a module, not from package %s.%s",
pkg->toPrettyChars(), id->toChars());
#endif
}
@@ -113,10 +121,13 @@ void Import::load(Scope *sc)
{
// Load module
mod = Module::load(loc, packages, id);
dst->insert(id, mod); // id may be different from mod->ident,
// if so then insert alias
if (!mod->importedFrom)
mod->importedFrom = sc ? sc->module->importedFrom : Module::rootModule;
if (mod)
{
dst->insert(id, mod); // id may be different from mod->ident,
// if so then insert alias
if (!mod->importedFrom)
mod->importedFrom = sc ? sc->module->importedFrom : Module::rootModule;
}
}
if (!pkg)
pkg = mod;
@@ -167,7 +178,8 @@ void Import::semantic(Scope *sc)
// Load if not already done so
if (!mod)
{ load(sc);
mod->importAll(0);
if (mod)
mod->importAll(0);
}
if (mod)
@@ -217,18 +229,26 @@ void Import::semantic(Scope *sc)
sc->protection = PROTpublic;
#endif
for (size_t i = 0; i < aliasdecls.dim; i++)
{ Dsymbol *s = aliasdecls.tdata()[i];
{ Dsymbol *s = aliasdecls[i];
//printf("\tImport alias semantic('%s')\n", s->toChars());
if (!mod->search(loc, names.tdata()[i], 0))
error("%s not found", (names.tdata()[i])->toChars());
s->semantic(sc);
if (mod->search(loc, names[i], 0))
s->semantic(sc);
else
{
s = mod->search_correct(names[i]);
if (s)
mod->error(loc, "import '%s' not found, did you mean '%s %s'?", names[i]->toChars(), s->kind(), s->toChars());
else
mod->error(loc, "import '%s' not found", names[i]->toChars());
}
}
sc = sc->pop();
}
if (global.params.moduleDeps != NULL)
if (global.params.moduleDeps != NULL &&
// object self-imports itself, so skip that (Bugzilla 7547)
!(id == Id::object && sc->module->ident == Id::object))
{
/* The grammar of the file is:
* ImportDeclaration
@@ -259,7 +279,7 @@ void Import::semantic(Scope *sc)
{
for (size_t i = 0; i < packages->dim; i++)
{
Identifier *pid = packages->tdata()[i];
Identifier *pid = (*packages)[i];
ob->printf("%s.", pid->toChars());
}
}
@@ -279,8 +299,8 @@ void Import::semantic(Scope *sc)
else
ob->writebyte(',');
Identifier *name = names.tdata()[i];
Identifier *alias = aliases.tdata()[i];
Identifier *name = names[i];
Identifier *alias = aliases[i];
if (!alias)
{
@@ -367,8 +387,15 @@ Dsymbol *Import::search(Loc loc, Identifier *ident, int flags)
int Import::overloadInsert(Dsymbol *s)
{
// Allow multiple imports of the same name
return s->isImport() != NULL;
/* Allow multiple imports with the same package base, but disallow
* alias collisions (Bugzilla 5412).
*/
assert(ident && ident == s->ident);
Import *imp;
if (!aliasId && (imp = s->isImport()) != NULL && !imp->aliasId)
return TRUE;
else
return FALSE;
}
void Import::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
+63 -66
View File
@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2011 by Digital Mars
// Copyright (c) 1999-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -53,10 +53,10 @@ Initializers *Initializer::arraySyntaxCopy(Initializers *ai)
a = new Initializers();
a->setDim(ai->dim);
for (size_t i = 0; i < a->dim; i++)
{ Initializer *e = ai->tdata()[i];
{ Initializer *e = (*ai)[i];
e = e->syntaxCopy();
a->tdata()[i] = e;
(*a)[i] = e;
}
}
return a;
@@ -125,11 +125,11 @@ Initializer *StructInitializer::syntaxCopy()
ai->value.setDim(value.dim);
for (size_t i = 0; i < field.dim; i++)
{
ai->field.tdata()[i] = field.tdata()[i];
ai->field[i] = field[i];
Initializer *init = value.tdata()[i];
Initializer *init = value[i];
init = init->syntaxCopy();
ai->value.tdata()[i] = init;
ai->value[i] = init;
}
return ai;
}
@@ -161,8 +161,8 @@ Initializer *StructInitializer::semantic(Scope *sc, Type *t, int needInterpret)
if (((StructDeclaration *)ad)->isnested) nfields--;
for (size_t i = 0; i < field.dim; i++)
{
Identifier *id = field.tdata()[i];
Initializer *val = value.tdata()[i];
Identifier *id = field[i];
Initializer *val = value[i];
Dsymbol *s;
VarDeclaration *v;
@@ -177,7 +177,7 @@ Initializer *StructInitializer::semantic(Scope *sc, Type *t, int needInterpret)
}
else
{
s = ad->fields.tdata()[fieldi];
s = ad->fields[fieldi];
}
}
else
@@ -186,7 +186,12 @@ Initializer *StructInitializer::semantic(Scope *sc, Type *t, int needInterpret)
s = ad->search(loc, id, 0);
if (!s)
{
error(loc, "'%s' is not a member of '%s'", id->toChars(), t->toChars());
s = ad->search_correct(id);
if (s)
error(loc, "'%s' is not a member of '%s', did you mean '%s %s'?",
id->toChars(), t->toChars(), s->kind(), s->toChars());
else
error(loc, "'%s' is not a member of '%s'", id->toChars(), t->toChars());
errors = 1;
continue;
}
@@ -202,15 +207,15 @@ Initializer *StructInitializer::semantic(Scope *sc, Type *t, int needInterpret)
errors = 1;
break;
}
if (s == ad->fields.tdata()[fieldi])
if (s == ad->fields[fieldi])
break;
}
}
if (s && (v = s->isVarDeclaration()) != NULL)
{
val = val->semantic(sc, v->type, needInterpret);
value.tdata()[i] = val;
vars.tdata()[i] = v;
value[i] = val;
vars[i] = v;
}
else
{ error(loc, "%s is not a field of %s", id ? id->toChars() : s->toChars(), ad->toChars());
@@ -271,12 +276,12 @@ Expression *StructInitializer::toExpression()
elements->setDim(nfields);
for (size_t i = 0; i < elements->dim; i++)
{
elements->tdata()[i] = NULL;
(*elements)[i] = NULL;
}
unsigned fieldi = 0;
for (size_t i = 0; i < value.dim; i++)
{
Identifier *id = field.tdata()[i];
Identifier *id = field[i];
if (id)
{
Dsymbol * s = ad->search(loc, id, 0);
@@ -295,7 +300,7 @@ Expression *StructInitializer::toExpression()
s->error("is not a per-instance initializable field");
goto Lno;
}
if (s == ad->fields.tdata()[fieldi])
if (s == ad->fields[fieldi])
break;
}
}
@@ -303,18 +308,18 @@ Expression *StructInitializer::toExpression()
{ error(loc, "too many initializers for '%s'", ad->toChars());
goto Lno;
}
Initializer *iz = value.tdata()[i];
Initializer *iz = value[i];
if (!iz)
goto Lno;
Expression *ex = iz->toExpression();
if (!ex)
goto Lno;
if (elements->tdata()[fieldi])
if ((*elements)[fieldi])
{ error(loc, "duplicate initializer for field '%s'",
ad->fields.tdata()[fieldi]->toChars());
ad->fields[fieldi]->toChars());
goto Lno;
}
elements->tdata()[fieldi] = ex;
(*elements)[fieldi] = ex;
++fieldi;
}
// Now, fill in any missing elements with default initializers.
@@ -322,20 +327,20 @@ Expression *StructInitializer::toExpression()
offset = 0;
for (size_t i = 0; i < elements->dim; )
{
VarDeclaration * vd = ad->fields.tdata()[i]->isVarDeclaration();
VarDeclaration * vd = ad->fields[i]->isVarDeclaration();
//printf("test2 [%d] : %s %d %d\n", i, vd->toChars(), (int)offset, (int)vd->offset);
if (vd->offset < offset)
{
// Only the first field of a union can have an initializer
if (elements->tdata()[i])
if ((*elements)[i])
goto Lno;
}
else
{
if (!elements->tdata()[i])
if (!(*elements)[i])
// Default initialize
elements->tdata()[i] = vd->type->defaultInit();
(*elements)[i] = vd->type->defaultInit();
}
offset = vd->offset + vd->type->size();
i++;
@@ -343,15 +348,15 @@ Expression *StructInitializer::toExpression()
int unionSize = ad->numFieldsInUnion(i);
if (unionSize == 1)
{ // Not a union -- default initialize if missing
if (!elements->tdata()[i])
elements->tdata()[i] = vd->type->defaultInit();
if (!(*elements)[i])
(*elements)[i] = vd->type->defaultInit();
}
else
{ // anonymous union -- check for errors
int found = -1; // index of the first field with an initializer
for (int j = i; j < i + unionSize; ++j)
for (size_t j = i; j < i + unionSize; ++j)
{
if (!elements->tdata()[j])
if (!(*elements)[j])
continue;
if (found >= 0)
{
@@ -392,13 +397,13 @@ void StructInitializer::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
if (i > 0)
buf->writebyte(',');
Identifier *id = field.tdata()[i];
Identifier *id = field[i];
if (id)
{
buf->writestring(id->toChars());
buf->writebyte(':');
}
Initializer *iz = value.tdata()[i];
Initializer *iz = value[i];
if (iz)
iz->toCBuffer(buf, hgs);
}
@@ -425,14 +430,14 @@ Initializer *ArrayInitializer::syntaxCopy()
ai->index.setDim(index.dim);
ai->value.setDim(value.dim);
for (size_t i = 0; i < ai->value.dim; i++)
{ Expression *e = index.tdata()[i];
{ Expression *e = index[i];
if (e)
e = e->syntaxCopy();
ai->index.tdata()[i] = e;
ai->index[i] = e;
Initializer *init = value.tdata()[i];
Initializer *init = value[i];
init = init->syntaxCopy();
ai->value.tdata()[i] = init;
ai->value[i] = init;
}
return ai;
}
@@ -471,17 +476,17 @@ Initializer *ArrayInitializer::semantic(Scope *sc, Type *t, int needInterpret)
length = 0;
for (i = 0; i < index.dim; i++)
{
Expression *idx = index.tdata()[i];
Expression *idx = index[i];
if (idx)
{ idx = idx->semantic(sc);
idx = idx->optimize(WANTvalue | WANTinterpret);
index.tdata()[i] = idx;
index[i] = idx;
length = idx->toInteger();
}
Initializer *val = value.tdata()[i];
Initializer *val = value[i];
val = val->semantic(sc, t->nextOf(), needInterpret);
value.tdata()[i] = val;
value[i] = val;
length++;
if (length == 0)
{ error(loc, "array dimension overflow");
@@ -495,7 +500,7 @@ Initializer *ArrayInitializer::semantic(Scope *sc, Type *t, int needInterpret)
dinteger_t edim = ((TypeSArray *)t)->dim->toInteger();
if (dim > edim)
{
error(loc, "array initializer has %u elements, but array length is %jd", dim, edim);
error(loc, "array initializer has %u elements, but array length is %lld", dim, edim);
goto Lerr;
}
}
@@ -549,8 +554,8 @@ Expression *ArrayInitializer::toExpression()
edim = value.dim;
for (size_t i = 0, j = 0; i < value.dim; i++, j++)
{
if (index.tdata()[i])
j = index.tdata()[i]->toInteger();
if (index[i])
j = index[i]->toInteger();
if (j >= edim)
edim = j + 1;
}
@@ -561,10 +566,10 @@ Expression *ArrayInitializer::toExpression()
elements->zero();
for (size_t i = 0, j = 0; i < value.dim; i++, j++)
{
if (index.tdata()[i])
j = (index.tdata()[i])->toInteger();
if (index[i])
j = (index[i])->toInteger();
assert(j < edim);
Initializer *iz = value.tdata()[i];
Initializer *iz = value[i];
if (!iz)
goto Lno;
Expression *ex = iz->toExpression();
@@ -572,7 +577,7 @@ Expression *ArrayInitializer::toExpression()
{
goto Lno;
}
elements->tdata()[j] = ex;
(*elements)[j] = ex;
}
/* Fill in any missing elements with the default initializer
@@ -581,13 +586,13 @@ Expression *ArrayInitializer::toExpression()
Expression *init = NULL;
for (size_t i = 0; i < edim; i++)
{
if (!elements->tdata()[i])
if (!(*elements)[i])
{
if (!type)
goto Lno;
if (!init)
init = ((TypeNext *)t)->next->defaultInit();
elements->tdata()[i] = init;
(*elements)[i] = init;
}
}
@@ -618,18 +623,18 @@ Expression *ArrayInitializer::toAssocArrayLiteral()
for (size_t i = 0; i < value.dim; i++)
{
e = index.tdata()[i];
e = index[i];
if (!e)
goto Lno;
keys->tdata()[i] = e;
(*keys)[i] = e;
Initializer *iz = value.tdata()[i];
Initializer *iz = value[i];
if (!iz)
goto Lno;
e = iz->toExpression();
if (!e)
goto Lno;
values->tdata()[i] = e;
(*values)[i] = e;
}
e = new AssocArrayLiteralExp(loc, keys, values);
return e;
@@ -645,7 +650,7 @@ int ArrayInitializer::isAssociativeArray()
{
for (size_t i = 0; i < value.dim; i++)
{
if (index.tdata()[i])
if (index[i])
return 1;
}
return 0;
@@ -707,13 +712,13 @@ void ArrayInitializer::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
if (i > 0)
buf->writebyte(',');
Expression *ex = index.tdata()[i];
Expression *ex = index[i];
if (ex)
{
ex->toCBuffer(buf, hgs);
buf->writebyte(':');
}
Initializer *iz = value.tdata()[i];
Initializer *iz = value[i];
if (iz)
iz->toCBuffer(buf, hgs);
}
@@ -778,10 +783,8 @@ bool hasNonConstPointers(Expression *e)
bool arrayHasNonConstPointers(Expressions *elems)
{
for (size_t i = 0; i < elems->dim; i++)
{
if (!elems->tdata()[i])
continue;
if (hasNonConstPointers(elems->tdata()[i]))
{ Expression *e = (*elems)[i];
if (e && hasNonConstPointers(e))
return true;
}
return false;
@@ -802,7 +805,7 @@ Initializer *ExpInitializer::semantic(Scope *sc, Type *t, int needInterpret)
return this; // Failed, suppress duplicate error messages
if (exp->op == TOKtype)
error("initializer must be an expression, not '%s'", exp->toChars());
exp->error("initializer must be an expression, not '%s'", exp->toChars());
// Make sure all pointers are constants
if (needInterpret && hasNonConstPointers(exp))
@@ -851,12 +854,6 @@ L1:
Type *ExpInitializer::inferType(Scope *sc)
{
//printf("ExpInitializer::inferType() %s\n", toChars());
if (exp->op == TOKfunction && ((FuncExp *)exp)->td)
{
exp->error("cannot infer type from ambiguous function literal %s", exp->toChars());
return Type::terror;
}
exp = exp->semantic(sc);
exp = resolveProperties(sc, exp);
@@ -870,7 +867,7 @@ Type *ExpInitializer::inferType(Scope *sc)
// Give error for overloaded function addresses
if (exp->op == TOKdelegate)
{ DelegateExp *se = (DelegateExp *)exp;
if (
if (se->hasOverloads &&
se->func->isFuncDeclaration() &&
!se->func->isFuncDeclaration()->isUnique())
exp->error("cannot infer type from overloaded function symbol %s", exp->toChars());
+16
View File
@@ -1486,6 +1486,9 @@ int FuncDeclaration::canInline(int hasthis, int hdrscan, int statementsToo)
if (
!fbody ||
ident == Id::ensure || // ensure() has magic properties the inliner loses
(ident == Id::require && // require() has magic properties too
toParent()->isFuncDeclaration() && // see bug 7699
toParent()->isFuncDeclaration()->needThis()) ||
!hdrscan &&
(
#if 0
@@ -1779,6 +1782,18 @@ Expression *Expression::inlineCopy(Scope *sc)
*/
return copy();
#else
if (op == TOKdelegate)
{ DelegateExp *de = (DelegateExp *)this;
if (de->func->isNested())
{ /* See Bugzilla 4820
* Defer checking until later if we actually need the 'this' pointer
*/
Expression *e = de->copy();
return e;
}
}
InlineCostState ics;
memset(&ics, 0, sizeof(ics));
@@ -1795,3 +1810,4 @@ Expression *Expression::inlineCopy(Scope *sc)
return e;
#endif
}
+299 -90
View File
@@ -27,7 +27,6 @@
#include "attrib.h" // for AttribDeclaration
#include "template.h"
TemplateInstance *isSpeculativeFunction(FuncDeclaration *fd);
#define LOG 0
@@ -45,6 +44,10 @@ private:
together with the VarDeclaration, and the previous
stack address of that variable, so that we can restore it
when we leave the stack frame.
Note that when a function is forward referenced, the interpreter must
run semantic3, and that may start CTFE again with a NULL istate. Thus
the stack might not be empty when CTFE begins.
Ctfe Stack addresses are just 0-based integers, but we save
them as 'void *' because ArrayBase can only do pointers.
*/
@@ -143,7 +146,11 @@ public:
}
void saveGlobalConstant(VarDeclaration *v, Expression *e)
{
assert(v->isDataseg() && !v->isCTFE());
#if DMDV2
assert( v->init && (v->isConst() || v->isImmutable()) && !v->isCTFE());
#else
assert( v->init && v->isConst() && !v->isCTFE());
#endif
v->ctfeAdrOnStack = globalValues.dim;
globalValues.push(e);
}
@@ -208,7 +215,7 @@ VarDeclaration *findParentVar(Expression *e, Expression *thisval);
bool needToCopyLiteral(Expression *expr);
Expression *copyLiteral(Expression *e);
Expression *paintTypeOntoLiteral(Type *type, Expression *lit);
Expression *findKeyInAA(AssocArrayLiteralExp *ae, Expression *e2);
Expression *findKeyInAA(Loc loc, AssocArrayLiteralExp *ae, Expression *e2);
Expression *evaluateIfBuiltin(InterState *istate, Loc loc,
FuncDeclaration *fd, Expressions *arguments, Expression *pthis);
Expression *scrubReturnValue(Loc loc, Expression *e);
@@ -243,6 +250,16 @@ struct ClassReferenceExp : Expression
{
return value->sd->isClassDeclaration();
}
VarDeclaration *getFieldAt(int index)
{
ClassDeclaration *cd = originalClass();
size_t fieldsSoFar = 0;
while (index - fieldsSoFar >= cd->fields.dim)
{ fieldsSoFar += cd->fields.dim;
cd = cd->baseClass;
}
return cd->fields.tdata()[index - fieldsSoFar];
}
// Return index of the field, or -1 if not found
int getFieldIndex(Type *fieldtype, size_t fieldoffset)
{
@@ -283,6 +300,28 @@ struct ClassReferenceExp : Expression
}
};
struct VoidInitExp : Expression
{
VarDeclaration *var;
VoidInitExp(VarDeclaration *var, Type *type)
: Expression(var->loc, TOKvoid, sizeof(VoidInitExp))
{
this->var = var;
this->type = var->type;
}
char *toChars()
{
return (char *)"void";
}
Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue)
{
error("CTFE internal error: trying to read uninitialized variable");
assert(0);
return EXP_CANT_INTERPRET;
}
};
// Return index of the field, or -1 if not found
// Same as getFieldIndex, but checks for a direct match with the VarDeclaration
int findFieldIndexByName(StructDeclaration *sd, VarDeclaration *v)
@@ -456,7 +495,8 @@ void showCtfeExpr(Expression *e, int level = 0)
* arguments function arguments
* thisarg 'this', if a needThis() function, NULL if not.
*
* Return result expression if successful, EXP_CANT_INTERPRET if not.
* Return result expression if successful, EXP_CANT_INTERPRET if not,
* or EXP_VOID_INTERPRET if function returned void.
*/
Expression *FuncDeclaration::interpret(InterState *istate, Expressions *arguments, Expression *thisarg)
@@ -475,7 +515,7 @@ Expression *FuncDeclaration::interpret(InterState *istate, Expressions *argument
*/
int olderrors = global.errors;
int oldgag = global.gag;
TemplateInstance *spec = isSpeculativeFunction(this);
TemplateInstance *spec = isSpeculative();
if (global.gag && !spec)
global.gag = 0;
semantic3(scope);
@@ -576,6 +616,15 @@ Expression *FuncDeclaration::interpret(InterState *istate, Expressions *argument
--evaluatingArgs;
if (earg == EXP_CANT_INTERPRET)
return earg;
/* Struct literals are passed by value, but we don't need to
* copy them if they are passed as const
*/
if (earg->op == TOKstructliteral
#if DMDV2
&& !(arg->storageClass & (STCconst | STCimmutable))
#endif
)
earg = copyLiteral(earg);
}
if (earg->op == TOKthrownexception)
{
@@ -675,6 +724,11 @@ Expression *FuncDeclaration::interpret(InterState *istate, Expressions *argument
// If fell off the end of a void function, return void
if (!e && type->toBasetype()->nextOf()->ty == Tvoid)
return EXP_VOID_INTERPRET;
// If result is void, return void
if (e == EXP_VOID_INTERPRET)
return e;
// If it generated an exception, return it
if (exceptionOrCantInterpret(e))
{
@@ -683,6 +737,9 @@ Expression *FuncDeclaration::interpret(InterState *istate, Expressions *argument
((ThrownExceptionExp *)e)->generateUncaughtError();
return EXP_CANT_INTERPRET;
}
// If we're about to leave CTFE, make sure we don't crash the
// compiler by returning a CTFE-internal expression.
if (!istate && !evaluatingArgs)
{
e = scrubReturnValue(loc, e);
@@ -896,13 +953,16 @@ uinteger_t resolveArrayLength(Expression *e)
}
// As Equal, but resolves slices before comparing
Expression *ctfeEqual(enum TOK op, Type *type, Expression *e1, Expression *e2)
Expression *ctfeEqual(Loc loc, enum TOK op, Type *type, Expression *e1, Expression *e2)
{
if (e1->op == TOKslice)
e1 = resolveSlice(e1);
if (e2->op == TOKslice)
e2 = resolveSlice(e2);
return Equal(op, type, e1, e2);
Expression *e = Equal(op, type, e1, e2);
if (e == EXP_CANT_INTERPRET)
error(loc, "cannot evaluate %s==%s at compile time", e1->toChars(), e2->toChars());
return e;
}
Expression *ctfeCat(Type *type, Expression *e1, Expression *e2)
@@ -973,7 +1033,7 @@ Expression *ctfeCat(Type *type, Expression *e1, Expression *e2)
return Cat(type, e1, e2);
}
void scrubArray(Loc loc, Expressions *elems);
bool scrubArray(Loc loc, Expressions *elems, bool structlit = false);
/* All results destined for use outside of CTFE need to have their CTFE-specific
* features removed.
@@ -986,6 +1046,11 @@ Expression *scrubReturnValue(Loc loc, Expression *e)
error(loc, "%s class literals cannot be returned from CTFE", ((ClassReferenceExp*)e)->originalClass()->toChars());
return EXP_CANT_INTERPRET;
}
if (e->op == TOKvoid)
{
error(loc, "uninitialized variable '%s' cannot be returned from CTFE", ((VoidInitExp *)e)->var->toChars());
e = new ErrorExp();
}
if (e->op == TOKslice)
{
e = resolveSlice(e);
@@ -994,7 +1059,8 @@ Expression *scrubReturnValue(Loc loc, Expression *e)
{
StructLiteralExp *se = (StructLiteralExp *)e;
se->ownedByCtfe = false;
scrubArray(loc, se->elements);
if (!scrubArray(loc, se->elements, true))
return EXP_CANT_INTERPRET;
}
if (e->op == TOKstring)
{
@@ -1003,29 +1069,38 @@ Expression *scrubReturnValue(Loc loc, Expression *e)
if (e->op == TOKarrayliteral)
{
((ArrayLiteralExp *)e)->ownedByCtfe = false;
scrubArray(loc, ((ArrayLiteralExp *)e)->elements);
if (!scrubArray(loc, ((ArrayLiteralExp *)e)->elements))
return EXP_CANT_INTERPRET;
}
if (e->op == TOKassocarrayliteral)
{
AssocArrayLiteralExp *aae = (AssocArrayLiteralExp *)e;
aae->ownedByCtfe = false;
scrubArray(loc, aae->keys);
scrubArray(loc, aae->values);
if (!scrubArray(loc, aae->keys))
return EXP_CANT_INTERPRET;
if (!scrubArray(loc, aae->values))
return EXP_CANT_INTERPRET;
}
return e;
}
// Scrub all members of an array
void scrubArray(Loc loc, Expressions *elems)
// Scrub all members of an array. Return false if error
bool scrubArray(Loc loc, Expressions *elems, bool structlit)
{
for (size_t i = 0; i < elems->dim; i++)
{
Expression *m = elems->tdata()[i];
if (!m)
continue;
m = scrubReturnValue(loc, m);
if (m && m->op == TOKvoid && structlit)
m = NULL;
if (m)
m = scrubReturnValue(loc, m);
if (m == EXP_CANT_INTERPRET)
return false;
elems->tdata()[i] = m;
}
return true;
}
@@ -1360,7 +1435,7 @@ Expression *SwitchStatement::interpret(InterState *istate)
Expression * caseExp = cs->exp->interpret(istate);
if (exceptionOrCantInterpret(caseExp))
return caseExp;
e = ctfeEqual(TOKequal, Type::tint32, econdition, caseExp);
e = ctfeEqual(caseExp->loc, TOKequal, Type::tint32, econdition, caseExp);
if (exceptionOrCantInterpret(e))
return e;
if (e->isBool(TRUE))
@@ -1475,25 +1550,25 @@ Expression *TryCatchStatement::interpret(InterState *istate)
ThrownExceptionExp *ex = (ThrownExceptionExp *)e;
Type *extype = ex->thrown->originalClass()->type;
// Search for an appropriate catch clause.
for (size_t i = 0; i < catches->dim; i++)
{
for (size_t i = 0; i < catches->dim; i++)
{
#if DMDV1
Catch *ca = (Catch *)catches->data[i];
Catch *ca = (Catch *)catches->data[i];
#else
Catch *ca = catches->tdata()[i];
Catch *ca = catches->tdata()[i];
#endif
Type *catype = ca->type;
Type *catype = ca->type;
if (catype->equals(extype) || catype->isBaseOf(extype, NULL))
{ // Execute the handler
if (catype->equals(extype) || catype->isBaseOf(extype, NULL))
{ // Execute the handler
if (ca->var)
{
ctfeStack.push(ca->var);
ca->var->setValue(ex->thrown);
}
return ca->handler->interpret(istate);
}
return ca->handler ? ca->handler->interpret(istate) : NULL;
}
}
return e;
}
@@ -1734,6 +1809,8 @@ Expression *SymOffExp::interpret(InterState *istate, CtfeGoal goal)
}
Type *pointee = ((TypePointer *)type)->next;
Expression *val = getVarExp(loc, istate, var, goal);
if (val == EXP_CANT_INTERPRET)
return val;
if (val->type->ty == Tarray || val->type->ty == Tsarray)
{
// Check for unsupported type painting operations
@@ -1903,10 +1980,7 @@ Expression *getVarExp(Loc loc, InterState *istate, Declaration *d, CtfeGoal goal
if (e && e != EXP_CANT_INTERPRET && e->op != TOKthrownexception)
{
e = copyLiteral(e);
if (v->isDataseg())
ctfeStack.saveGlobalConstant(v, e);
else
v->setValueWithoutChecking(e);
ctfeStack.saveGlobalConstant(v, e);
}
}
else if (v->isCTFE() && !v->hasValue())
@@ -1915,11 +1989,16 @@ Expression *getVarExp(Loc loc, InterState *istate, Declaration *d, CtfeGoal goal
{
if (v->init->isVoidInitializer())
{
error(loc, "variable %s is used before initialization", v->toChars());
return EXP_CANT_INTERPRET;
// var should have been initialized when it was created
error(loc, "CTFE internal error - trying to access uninitialized var");
assert(0);
e = EXP_CANT_INTERPRET;
}
else
{
e = v->init->toExpression();
e = e->interpret(istate);
}
e = v->init->toExpression();
e = e->interpret(istate);
}
else
e = v->type->defaultInitLiteral(loc);
@@ -1935,7 +2014,11 @@ Expression *getVarExp(Loc loc, InterState *istate, Declaration *d, CtfeGoal goal
e = EXP_CANT_INTERPRET;
}
else if (!e)
error(loc, "variable %s is used before initialization", v->toChars());
{
assert(0);
assert(v->init && v->init->isVoidInitializer());
e = v->type->voidInitLiteral(v);
}
else if (exceptionOrCantInterpret(e))
return e;
else if (goal == ctfeNeedLvalue && v->isRef() && e->op == TOKindex)
@@ -1954,6 +2037,13 @@ Expression *getVarExp(Loc loc, InterState *istate, Declaration *d, CtfeGoal goal
|| e->op == TOKassocarrayliteral || e->op == TOKslice
|| e->type->toBasetype()->ty == Tpointer)
return e; // it's already an Lvalue
else if (e->op == TOKvoid)
{
VoidInitExp *ve = (VoidInitExp *)e;
error(loc, "cannot read uninitialized variable %s in ctfe", v->toPrettyChars());
errorSupplemental(ve->var->loc, "%s was uninitialized and used before set", ve->var->toChars());
e = EXP_CANT_INTERPRET;
}
else
e = e->interpret(istate, goal);
}
@@ -1963,10 +2053,12 @@ Expression *getVarExp(Loc loc, InterState *istate, Declaration *d, CtfeGoal goal
else if (s)
{ // Struct static initializers, for example
if (s->dsym->toInitializer() == s->sym)
{ e = s->dsym->type->defaultInitLiteral();
{ e = s->dsym->type->defaultInitLiteral(loc);
e = e->semantic(NULL);
if (e->op == TOKerror)
e = EXP_CANT_INTERPRET;
else // Convert NULL to VoidExp
e = e->interpret(istate, goal);
}
else
error(loc, "cannot interpret symbol %s at compile time", v->toChars());
@@ -2035,7 +2127,12 @@ Expression *DeclarationExp::interpret(InterState *istate, CtfeGoal goal)
if (ie)
e = ie->exp->interpret(istate);
else if (v->init->isVoidInitializer())
e = NULL;
{
e = v->type->voidInitLiteral(v);
// There is no AssignExp for void initializers,
// so set it here.
v->setValue(e);
}
else
{
error("Declaration %s is not yet implemented in CTFE", toChars());
@@ -2264,7 +2361,7 @@ Expression *AssocArrayLiteralExp::interpret(InterState *istate, CtfeGoal goal)
ekey = resolveSlice(ekey);
for (size_t j = i; j < keysx->dim; j++)
{ Expression *ekey2 = keysx->tdata()[j];
Expression *ex = ctfeEqual(TOKequal, Type::tbool, ekey, ekey2);
Expression *ex = ctfeEqual(loc, TOKequal, Type::tbool, ekey, ekey2);
if (ex == EXP_CANT_INTERPRET)
goto Lerr;
if (ex->isBool(TRUE)) // if a match
@@ -2438,10 +2535,10 @@ Expression *recursivelyCreateArrayLiteral(Loc loc, Type *newtype, InterState *is
if (elemType->ty == Tchar || elemType->ty == Twchar
|| elemType->ty == Tdchar)
return createBlockDuplicatedStringLiteral(loc, newtype,
(unsigned)(elemType->defaultInitLiteral()->toInteger()),
(unsigned)(elemType->defaultInitLiteral(loc)->toInteger()),
len, elemType->size());
return createBlockDuplicatedArrayLiteral(loc, newtype,
elemType->defaultInitLiteral(),
elemType->defaultInitLiteral(loc),
len);
}
@@ -2455,7 +2552,7 @@ Expression *NewExp::interpret(InterState *istate, CtfeGoal goal)
if (newtype->toBasetype()->ty == Tstruct)
{
Expression *se = newtype->defaultInitLiteral();
Expression *se = newtype->defaultInitLiteral(loc);
#if DMDV2
if (member)
{
@@ -2492,7 +2589,7 @@ Expression *NewExp::interpret(InterState *istate, CtfeGoal goal)
Dsymbol *s = c->fields.tdata()[i];
VarDeclaration *v = s->isVarDeclaration();
assert(v);
Expression *m = v->init ? v->init->toExpression() : v->type->defaultInitLiteral();
Expression *m = v->init ? v->init->toExpression() : v->type->defaultInitLiteral(loc);
if (exceptionOrCantInterpret(m))
return m;
elems->tdata()[fieldsSoFar+i] = copyLiteral(m);
@@ -2662,7 +2759,7 @@ Expression *pointerArithmetic(Loc loc, enum TOK op, Type *type,
}
if (indx < 0 || indx > len)
{
error(loc, "cannot assign pointer to index %jd inside memory block [0..%jd]", indx, len);
error(loc, "cannot assign pointer to index %lld inside memory block [0..%lld]", indx, len);
return EXP_CANT_INTERPRET;
}
@@ -2964,7 +3061,7 @@ Expression *assignAssocArrayElement(Loc loc, AssocArrayLiteralExp *aae, Expressi
for (size_t j = valuesx->dim; j; )
{ j--;
Expression *ekey = aae->keys->tdata()[j];
Expression *ex = ctfeEqual(TOKequal, Type::tbool, ekey, index);
Expression *ex = ctfeEqual(loc, TOKequal, Type::tbool, ekey, index);
if (exceptionOrCantInterpret(ex))
return ex;
if (ex->isBool(TRUE))
@@ -3134,7 +3231,7 @@ Expression *copyLiteral(Expression *e)
assert(v);
// If it is a void assignment, use the default initializer
if (!m)
m = v->type->defaultInitLiteral(e->loc);
m = v->type->voidInitLiteral(v);
if (m->op == TOKslice)
m = resolveSlice(m);
if ((v->type->ty != m->type->ty) && v->type->ty == Tsarray)
@@ -3161,7 +3258,8 @@ Expression *copyLiteral(Expression *e)
|| e->op == TOKsymoff || e->op == TOKnull
|| e->op == TOKvar
|| e->op == TOKint64 || e->op == TOKfloat64
|| e->op == TOKchar || e->op == TOKcomplex80)
|| e->op == TOKchar || e->op == TOKcomplex80
|| e->op == TOKvoid)
{ // Simple value types
Expression *r = e->syntaxCopy();
r->type = e->type;
@@ -3331,7 +3429,7 @@ void assignInPlace(Expression *dest, Expression *src)
assert(o->op == e->op);
assignInPlace(o, e);
}
else if (e->type->ty == Tsarray && o->type->ty == Tsarray)
else if (e->type->ty == Tsarray && o->type->ty == Tsarray && e->op != TOKvoid)
{
assignInPlace(o, e);
}
@@ -3626,7 +3724,7 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_
Type *elemType= NULL;
elemType = ((TypeArray *)t)->next;
assert(elemType);
Expression *defaultElem = elemType->defaultInitLiteral();
Expression *defaultElem = elemType->defaultInitLiteral(loc);
Expressions *elements = new Expressions();
elements->setDim(newlen);
@@ -3734,7 +3832,7 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_
// only modifying part of the variable. So we need to make sure
// that the parent variable exists.
if (e1->op != TOKvar && ultimateVar && !ultimateVar->getValue())
ultimateVar->setValue(copyLiteral(ultimateVar->type->defaultInitLiteral()));
ultimateVar->setValue(copyLiteral(ultimateVar->type->defaultInitLiteral(loc)));
// ---------------------------------------
// Deal with reference assignment
@@ -3812,7 +3910,7 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_
indx = resolveSlice(indx);
// Look up this index in it up in the existing AA, to get the next level of AA.
AssocArrayLiteralExp *newAA = (AssocArrayLiteralExp *)findKeyInAA(existingAA, indx);
AssocArrayLiteralExp *newAA = (AssocArrayLiteralExp *)findKeyInAA(loc, existingAA, indx);
if (exceptionOrCantInterpret(newAA))
return newAA;
if (!newAA)
@@ -3958,14 +4056,29 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_
? (StructLiteralExp *)exx
: ((ClassReferenceExp *)exx)->value;
int fieldi = exx->op == TOKstructliteral
? se->getFieldIndex(member->type, member->offset)
: ((ClassReferenceExp *)exx)->getFieldIndex(member->type, member->offset);
? findFieldIndexByName(se->sd, member)
: ((ClassReferenceExp *)exx)->findFieldIndexByName(member);
if (fieldi == -1)
{
error("CTFE internal error: cannot find field %s in %s", member->toChars(), exx->toChars());
return EXP_CANT_INTERPRET;
}
assert(fieldi>=0 && fieldi < se->elements->dim);
assert(fieldi >= 0 && fieldi < se->elements->dim);
// If it's a union, set all other members of this union to void
if (exx->op == TOKstructliteral)
{
assert(se->sd);
int unionStart = se->sd->firstFieldInUnion(fieldi);
int unionSize = se->sd->numFieldsInUnion(fieldi);
for(int i = unionStart; i < unionStart + unionSize; ++i)
{ if (i == fieldi)
continue;
Expression **el = &se->elements->tdata()[i];
if ((*el)->op != TOKvoid)
*el = (*el)->type->voidInitLiteral(member);
}
}
if (newval->op == TOKstructliteral)
assignInPlace(se->elements->tdata()[fieldi], newval);
else
@@ -4040,6 +4153,21 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_
}
aggregate = getAggregateFromPointer(aggregate, &ofs);
indexToModify += ofs;
if (aggregate->op != TOKslice && aggregate->op != TOKstring &&
aggregate->op != TOKarrayliteral && aggregate->op != TOKassocarrayliteral)
{
if (indexToModify != 0)
{
error("pointer index [%lld] lies outside memory block [0..1]", indexToModify);
return EXP_CANT_INTERPRET;
}
// It is equivalent to *aggregate = newval.
// Aggregate could be varexp, a dotvar, ...
// TODO: we could support this
error("indexed assignment of non-array pointers is not yet supported at compile time; use *%s = %s instead",
ie->e1->toChars(), e2->toChars());
return EXP_CANT_INTERPRET;
}
destarraylen = resolveArrayLength(aggregate);
}
if (indexToModify >= destarraylen)
@@ -4065,7 +4193,7 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_
((IndexExp *)aggregate)->e1->op == TOKassocarrayliteral)
{
IndexExp *ix = (IndexExp *)aggregate;
aggregate = findKeyInAA((AssocArrayLiteralExp *)ix->e1, ix->e2);
aggregate = findKeyInAA(loc, (AssocArrayLiteralExp *)ix->e1, ix->e2);
if (!aggregate)
{
error("key %s not found in associative array %s",
@@ -4167,6 +4295,8 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_
if (isPointer(oldval->type))
{ // Slicing a pointer
oldval = oldval->interpret(istate, ctfeNeedLvalue);
if (exceptionOrCantInterpret(oldval))
return oldval;
dinteger_t ofs;
oldval = getAggregateFromPointer(oldval, &ofs);
assignmentToSlicedPointer = true;
@@ -4176,7 +4306,13 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_
if (oldval->op != TOKarrayliteral && oldval->op != TOKstring
&& oldval->op != TOKslice && oldval->op != TOKnull)
{
error("CTFE ICE: cannot resolve array length");
if (assignmentToSlicedPointer)
{
error("pointer %s cannot be sliced at compile time (it does not point to an array)",
sexp->e1->toChars());
}
else
error("CTFE ICE: cannot resolve array length");
return EXP_CANT_INTERPRET;
}
uinteger_t dollar = resolveArrayLength(oldval);
@@ -4239,7 +4375,7 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_
((IndexExp *)aggregate)->e1->op == TOKassocarrayliteral)
{
IndexExp *ix = (IndexExp *)aggregate;
aggregate = findKeyInAA((AssocArrayLiteralExp *)ix->e1, ix->e2);
aggregate = findKeyInAA(loc, (AssocArrayLiteralExp *)ix->e1, ix->e2);
if (!aggregate)
{
error("key %s not found in associative array %s",
@@ -4263,7 +4399,7 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_
firstIndex = lowerbound + sexpold->lwr->toInteger();
if (hi > sexpold->upr->toInteger())
{
error("slice [%d..%d] exceeds array bounds [0..%jd]",
error("slice [%d..%d] exceeds array bounds [0..%lld]",
lowerbound, upperbound,
sexpold->upr->toInteger() - sexpold->lwr->toInteger());
return EXP_CANT_INTERPRET;
@@ -4275,11 +4411,16 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_
aggregate = sexp->e1->interpret(istate, ctfeNeedLvalue);
dinteger_t ofs;
aggregate = getAggregateFromPointer(aggregate, &ofs);
if (aggregate->op == TOKnull)
{
error("cannot slice null pointer %s", sexp->e1->toChars());
return EXP_CANT_INTERPRET;
}
dinteger_t hi = upperbound + ofs;
firstIndex = lowerbound + ofs;
if (firstIndex < 0 || hi > dim)
{
error("slice [%d..%jd] exceeds memory block bounds [0..%jd]",
error("slice [lld..%lld] exceeds memory block bounds [0..%lld]",
firstIndex, hi, dim);
return EXP_CANT_INTERPRET;
}
@@ -4420,9 +4561,6 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_
else
{
error("%s cannot be evaluated at compile time", toChars());
#ifdef DEBUG
dump(0);
#endif
}
return returnValue;
}
@@ -4802,6 +4940,10 @@ Expression *CallExp::interpret(InterState *istate, CtfeGoal goal)
if (!global.gag)
showCtfeBackTrace(istate, this, fd);
}
else if (eresult == EXP_VOID_INTERPRET)
;
else
eresult->loc = loc;
return eresult;
}
@@ -4820,7 +4962,6 @@ Expression *CommaExp::interpret(InterState *istate, CtfeGoal goal)
InterState istateComma;
if (!istate && firstComma->e1->op == TOKdeclaration)
{
assert(ctfeStack.stackPointer() == 0);
ctfeStack.startFrame();
istate = &istateComma;
}
@@ -4838,7 +4979,7 @@ Expression *CommaExp::interpret(InterState *istate, CtfeGoal goal)
ctfeStack.push(v);
if (!v->init && !v->getValue())
{
v->setValue(copyLiteral(v->type->defaultInitLiteral()));
v->setValue(copyLiteral(v->type->defaultInitLiteral(loc)));
}
if (!v->getValue()) {
Expression *newval = v->init->toExpression();
@@ -4934,7 +5075,7 @@ Expression *ArrayLengthExp::interpret(InterState *istate, CtfeGoal goal)
* Return ae[e2] if present, or NULL if not found.
* Return EXP_CANT_INTERPRET on error.
*/
Expression *findKeyInAA(AssocArrayLiteralExp *ae, Expression *e2)
Expression *findKeyInAA(Loc loc, AssocArrayLiteralExp *ae, Expression *e2)
{
/* Search the keys backwards, in case there are duplicate keys
*/
@@ -4942,13 +5083,9 @@ Expression *findKeyInAA(AssocArrayLiteralExp *ae, Expression *e2)
{
i--;
Expression *ekey = ae->keys->tdata()[i];
Expression *ex = ctfeEqual(TOKequal, Type::tbool, ekey, e2);
Expression *ex = ctfeEqual(loc, TOKequal, Type::tbool, ekey, e2);
if (ex == EXP_CANT_INTERPRET)
{
error("cannot evaluate %s==%s at compile time",
ekey->toChars(), e2->toChars());
return ex;
}
if (ex->isBool(TRUE))
{
return ae->values->tdata()[i];
@@ -5003,23 +5140,37 @@ Expression *IndexExp::interpret(InterState *istate, CtfeGoal goal)
if (exceptionOrCantInterpret(e2))
return e2;
dinteger_t indx = e2->toInteger();
dinteger_t ofs;
Expression *agg = getAggregateFromPointer(e1, &ofs);
if (agg->op == TOKnull)
{
error("cannot index null pointer %s", this->e1->toChars());
return EXP_CANT_INTERPRET;
}
assert(agg->op == TOKarrayliteral || agg->op == TOKstring);
dinteger_t len = ArrayLength(Type::tsize_t, agg)->toInteger();
Type *pointee = ((TypePointer *)agg->type)->next;
if ((indx + ofs) < 0 || (indx+ofs) > len)
if ( agg->op == TOKarrayliteral || agg->op == TOKstring)
{
error("pointer index [%jd] exceeds allocated memory block [0..%jd]",
indx+ofs, len);
return EXP_CANT_INTERPRET;
dinteger_t len = ArrayLength(Type::tsize_t, agg)->toInteger();
Type *pointee = ((TypePointer *)agg->type)->next;
if ((indx + ofs) < 0 || (indx+ofs) > len)
{
error("pointer index [%lld] exceeds allocated memory block [0..%lld]",
indx+ofs, len);
return EXP_CANT_INTERPRET;
}
return ctfeIndex(loc, type, agg, indx+ofs);
}
else
{ // Pointer to a non-array variable
if ((indx + ofs) != 0)
{
error("pointer index [%lld] lies outside memory block [0..1]",
indx+ofs);
return EXP_CANT_INTERPRET;
}
return agg->interpret(istate);
}
return ctfeIndex(loc, type, agg, indx+ofs);
}
e1 = this->e1;
if (!(e1->op == TOKarrayliteral && ((ArrayLiteralExp *)e1)->ownedByCtfe))
@@ -5060,7 +5211,7 @@ Expression *IndexExp::interpret(InterState *istate, CtfeGoal goal)
if (indx > iup - ilo)
{
error("index %ju exceeds array length %ju", indx, iup - ilo);
error("index %llu exceeds array length %llu", indx, iup - ilo);
return EXP_CANT_INTERPRET;
}
indx += ilo;
@@ -5081,7 +5232,7 @@ Expression *IndexExp::interpret(InterState *istate, CtfeGoal goal)
{
if (e2->op == TOKslice)
e2 = resolveSlice(e2);
e = findKeyInAA((AssocArrayLiteralExp *)e1, e2);
e = findKeyInAA(loc, (AssocArrayLiteralExp *)e1, e2);
if (!e)
{
error("key %s not found in associative array %s",
@@ -5102,6 +5253,12 @@ Expression *IndexExp::interpret(InterState *istate, CtfeGoal goal)
return e;
if (goal == ctfeNeedRvalue && (e->op == TOKslice || e->op == TOKdotvar))
e = e->interpret(istate);
if (goal == ctfeNeedRvalue && e->op == TOKvoid)
{
error("%s is used before initialized", toChars());
errorSupplemental(e->loc, "originally uninitialized here");
return EXP_CANT_INTERPRET;
}
e = paintTypeOntoLiteral(type, e);
return e;
}
@@ -5156,12 +5313,18 @@ Expression *SliceExp::interpret(InterState *istate, CtfeGoal goal)
error("cannot slice null pointer %s", this->e1->toChars());
return EXP_CANT_INTERPRET;
}
if (agg->op != TOKarrayliteral && agg->op != TOKstring)
{
error("pointer %s cannot be sliced at compile time (it does not point to an array)",
this->e1->toChars());
return EXP_CANT_INTERPRET;
}
assert(agg->op == TOKarrayliteral || agg->op == TOKstring);
dinteger_t len = ArrayLength(Type::tsize_t, agg)->toInteger();
Type *pointee = ((TypePointer *)agg->type)->next;
if ((ilwr + ofs) < 0 || (iupr+ofs) > (len + 1) || iupr < ilwr)
{
error("pointer slice [%jd..%jd] exceeds allocated memory block [0..%jd]",
error("pointer slice [%lld..%lld] exceeds allocated memory block [0..%lld]",
ilwr+ofs, iupr+ofs, len);
return EXP_CANT_INTERPRET;
}
@@ -5225,7 +5388,7 @@ Expression *SliceExp::interpret(InterState *istate, CtfeGoal goal)
{
if (ilwr== 0 && iupr == 0)
return e1;
e1->error("slice [%ju..%ju] is out of bounds", ilwr, iupr);
e1->error("slice [%llu..%llu] is out of bounds", ilwr, iupr);
return EXP_CANT_INTERPRET;
}
if (e1->op == TOKslice)
@@ -5237,7 +5400,7 @@ Expression *SliceExp::interpret(InterState *istate, CtfeGoal goal)
uinteger_t up1 = se->upr->toInteger();
if (ilwr > iupr || iupr > up1 - lo1)
{
error("slice[%ju..%ju] exceeds array bounds[%ju..%ju]",
error("slice[%llu..%llu] exceeds array bounds[%llu..%llu]",
ilwr, iupr, lo1, up1);
return EXP_CANT_INTERPRET;
}
@@ -5254,7 +5417,7 @@ Expression *SliceExp::interpret(InterState *istate, CtfeGoal goal)
{
if (iupr < ilwr || ilwr < 0 || iupr > dollar)
{
error("slice [%jd..%jd] exceeds array bounds [0..%jd]",
error("slice [%lld..%lld] exceeds array bounds [0..%lld]",
ilwr, iupr, dollar);
return EXP_CANT_INTERPRET;
}
@@ -5285,7 +5448,7 @@ Expression *InExp::interpret(InterState *istate, CtfeGoal goal)
}
if (e1->op == TOKslice)
e1 = resolveSlice(e1);
e = findKeyInAA((AssocArrayLiteralExp *)e2, e1);
e = findKeyInAA(loc, (AssocArrayLiteralExp *)e2, e1);
if (exceptionOrCantInterpret(e))
return e;
if (!e)
@@ -5344,8 +5507,12 @@ bool isAssocArray(Type *t)
if (t->ty != Tstruct)
return false;
StructDeclaration *sym = ((TypeStruct *)t)->sym;
if (sym->ident == Id::AssociativeArray)
if (sym->ident == Id::AssociativeArray && sym->parent &&
sym->parent->parent &&
sym->parent->parent->ident == Id::object)
{
return true;
}
#endif
return false;
}
@@ -5500,9 +5667,15 @@ Expression *CastExp::interpret(InterState *istate, CtfeGoal goal)
e->type = type;
return e;
}
error("pointer cast from %s to %s is not supported at compile time",
// Check if we have a null pointer (eg, inside a struct)
e1 = e1->interpret(istate);
if (e1->op != TOKnull)
{
error("pointer cast from %s to %s is not supported at compile time",
e1->type->toChars(), to->toChars());
return EXP_CANT_INTERPRET;
return EXP_CANT_INTERPRET;
}
}
if (to->ty == Tarray && e1->op == TOKslice)
{
@@ -5650,7 +5823,7 @@ Expression *PtrExp::interpret(InterState *istate, CtfeGoal goal)
assert(indx >=0 && indx <= len); // invalid pointer
if (indx == len)
{
error("dereference of pointer %s one past end of memory block limits [0..%jd]",
error("dereference of pointer %s one past end of memory block limits [0..%lld]",
toChars(), len);
return EXP_CANT_INTERPRET;
}
@@ -5695,7 +5868,7 @@ Expression *PtrExp::interpret(InterState *istate, CtfeGoal goal)
}
else if (e->op == TOKaddress)
e = ((AddrExp*)e)->e1; // *(&x) ==> x
if (e->op == TOKnull)
else if (e->op == TOKnull)
{
error("dereference of null pointer '%s'", e1->toChars());
return EXP_CANT_INTERPRET;
@@ -5784,6 +5957,13 @@ Expression *DotVarExp::interpret(InterState *istate, CtfeGoal goal)
if (e->op == TOKstructliteral || e->op == TOKarrayliteral ||
e->op == TOKassocarrayliteral || e->op == TOKstring)
return e;
if (e->op == TOKvoid)
{
VoidInitExp *ve = (VoidInitExp *)e;
error("cannot read uninitialized variable %s in ctfe", toChars());
ve->var->error("was uninitialized and used before set");
return EXP_CANT_INTERPRET;
}
if ( isPointer(type) )
{
return paintTypeOntoLiteral(type, e);
@@ -5828,7 +6008,7 @@ Expression *RemoveExp::interpret(InterState *istate, CtfeGoal goal)
size_t removed = 0;
for (size_t j = 0; j < valuesx->dim; ++j)
{ Expression *ekey = keysx->tdata()[j];
Expression *ex = ctfeEqual(TOKequal, Type::tbool, ekey, index);
Expression *ex = ctfeEqual(loc, TOKequal, Type::tbool, ekey, index);
if (exceptionOrCantInterpret(ex))
return ex;
if (ex->isBool(TRUE))
@@ -6007,7 +6187,7 @@ Expression *foreachApplyUtf(InterState *istate, Expression *str, Expression *del
else if (str->op == TOKarrayliteral)
ale = (ArrayLiteralExp *)str;
else
{ error("CTFE internal error: cannot foreach %s", str->toChars());
{ str->error("CTFE internal error: cannot foreach %s", str->toChars());
return EXP_CANT_INTERPRET;
}
Expressions args;
@@ -6462,6 +6642,10 @@ bool isCtfeValueValid(Expression *newval)
assert(((ArrayLiteralExp *)se->e1)->ownedByCtfe);
return true;
}
if (newval->op == TOKvoid)
{
return true;
}
newval->error("CTFE internal error: illegal value %s\n", newval->toChars());
return false;
}
@@ -6494,3 +6678,28 @@ void VarDeclaration::setValue(Expression *newval)
assert(isCtfeValueValid(newval));
ctfeStack.setValue(this, newval);
}
Expression *Type::voidInitLiteral(VarDeclaration *var)
{
return new VoidInitExp(var, this);
}
Expression *TypeSArray::voidInitLiteral(VarDeclaration *var)
{
return createBlockDuplicatedArrayLiteral(var->loc, this, next->voidInitLiteral(var), dim->toInteger());
}
Expression *TypeStruct::voidInitLiteral(VarDeclaration *var)
{
Expressions *exps = new Expressions();
exps->setDim(sym->fields.dim);
for (size_t i = 0; i < sym->fields.dim; i++)
{
(*exps)[i] = new VoidInitExp(var, sym->fields[i]->type);
}
StructLiteralExp *se = new StructLiteralExp(var->loc, sym, exps);
se->type = this;
se->ownedByCtfe = true;
return se;
}
+63 -19
View File
@@ -121,11 +121,11 @@ const char *Token::toChars()
break;
case TOKint64v:
sprintf(buffer,"%jdL",(intmax_t)int64value);
sprintf(buffer,"%lldL",(intmax_t)int64value);
break;
case TOKuns64v:
sprintf(buffer,"%juUL",(uintmax_t)uns64value);
sprintf(buffer,"%lluUL",(uintmax_t)uns64value);
break;
#if IN_GCC
@@ -143,27 +143,32 @@ const char *Token::toChars()
break;
#else
case TOKfloat32v:
sprintf(buffer,"%Lgf", float80value);
ld_sprint(buffer, 'g', float80value);
strcat(buffer, "f");
break;
case TOKfloat64v:
sprintf(buffer,"%Lg", float80value);
ld_sprint(buffer, 'g', float80value);
break;
case TOKfloat80v:
sprintf(buffer,"%LgL", float80value);
ld_sprint(buffer, 'g', float80value);
strcat(buffer, "L");
break;
case TOKimaginary32v:
sprintf(buffer,"%Lgfi", float80value);
ld_sprint(buffer, 'g', float80value);
strcat(buffer, "fi");
break;
case TOKimaginary64v:
sprintf(buffer,"%Lgi", float80value);
ld_sprint(buffer, 'g', float80value);
strcat(buffer, "i");
break;
case TOKimaginary80v:
sprintf(buffer,"%LgLi", float80value);
ld_sprint(buffer, 'g', float80value);
strcat(buffer, "Li");
break;
#endif
@@ -302,7 +307,7 @@ void Lexer::error(const char *format, ...)
{
va_list ap;
va_start(ap, format);
verror(loc, format, ap);
verror(tokenLoc(), format, ap);
va_end(ap);
}
@@ -365,7 +370,6 @@ Token *Lexer::peek(Token *ct)
{
t = new Token();
scan(t);
t->next = NULL;
ct->next = t;
}
return t;
@@ -1224,9 +1228,21 @@ void Lexer::scan(Token *t)
#undef DOUBLE
case '#':
{
p++;
pragma();
continue;
Token *n = peek(t);
if (n->value == TOKidentifier && n->ident == Id::line)
{
nextToken();
poundLine();
continue;
}
else
{
t->value = TOKpound;
return;
}
}
default:
{ unsigned c = *p;
@@ -2562,22 +2578,17 @@ done:
}
/*********************************************
* Do pragma.
* Currently, the only pragma supported is:
* parse:
* #line linnum [filespec]
*/
void Lexer::pragma()
void Lexer::poundLine()
{
Token tok;
int linnum;
char *filespec = NULL;
Loc loc = this->loc;
scan(&tok);
if (tok.value != TOKidentifier || tok.ident != Id::line)
goto Lerr;
scan(&tok);
if (tok.value == TOKint32v || tok.value == TOKint64v)
{ linnum = tok.uns64value - 1;
@@ -2861,6 +2872,38 @@ unsigned char *Lexer::combineComments(unsigned char *c1, unsigned char *c2)
return c;
}
/*******************************************
* Search actual location of current token
* even when infinite look-ahead was done.
*/
Loc Lexer::tokenLoc()
{
Loc result = this->loc;
Token* last = &token;
while (last->next)
last = last->next;
unsigned char* start = token.ptr;
unsigned char* stop = last->ptr;
for (unsigned char* p = start; p < stop; ++p)
{
switch (*p)
{
case '\n':
result.linnum--;
break;
case '\r':
if (p[1] != '\n')
result.linnum--;
break;
default:
break;
}
}
return result;
}
/********************************************
* Create an identifier in the string table.
*/
@@ -3160,6 +3203,7 @@ void Lexer::initKeywords()
Token::tochars[TOKpow] = "^^";
Token::tochars[TOKpowass] = "^^=";
Token::tochars[TOKgoesto] = "=>";
Token::tochars[TOKpound] = "#";
#endif
// For debugging
+5 -1
View File
@@ -170,6 +170,7 @@ enum TOK
TOKpowass,
TOKgoesto,
TOKvector,
TOKpound,
#endif
TOKMAX
@@ -251,6 +252,7 @@ struct Token
static const char *tochars[TOKMAX];
static void *operator new(size_t sz);
Token() : next(NULL) {}
int isKeyword();
void print();
const char *toChars();
@@ -305,12 +307,14 @@ struct Lexer
void error(const char *format, ...);
void error(Loc loc, const char *format, ...);
void verror(Loc loc, const char *format, va_list ap);
void pragma();
void poundLine();
unsigned decodeUTF();
void getDocComment(Token *t, unsigned lineComment);
static int isValidIdentifier(char *p);
static unsigned char *combineComments(unsigned char *c1, unsigned char *c2);
Loc tokenLoc();
};
#endif /* DMD_LEXER_H */
+14
View File
@@ -48,6 +48,20 @@ struct Library
unsigned short numDictPages(unsigned padding);
int FillDict(unsigned char *bucketsP, unsigned short uNumPages);
void WriteLibToBuffer(OutBuffer *libbuf);
void error(const char *format, ...)
{
Loc loc;
if (libfile)
{
loc.filename = libfile->name->toChars();
loc.linnum = 0;
}
va_list ap;
va_start(ap, format);
::verror(loc, format, ap);
va_end(ap);
}
};
#endif /* DMD_LIB_H */
+5 -3
View File
@@ -260,6 +260,7 @@ void Library::scanObjModule(ObjModule *om)
if (easyomf)
recTyp = COMDAT+1; // convert to MS format
case COMDAT+1:
{
int pickAny = 0;
if (*p++ & 5) // if continuation or local comdat
@@ -292,7 +293,7 @@ void Library::scanObjModule(ObjModule *om)
//printf("[s] name='%s'\n",name);
addSymbol(om, names.tdata()[idx],pickAny);
break;
}
case ALIAS:
while (p + 1 < pnext)
{
@@ -484,6 +485,7 @@ void Library::addObject(const char *module_name, void *buf, size_t buflen)
case MODEND :
case M386END:
{
if (om)
{ om->page = (om->base - pstart) / g_page_size;
om->length = pnext - om->base;
@@ -494,7 +496,7 @@ void Library::addObject(const char *module_name, void *buf, size_t buflen)
t = (t + g_page_size - 1) & ~(unsigned)(g_page_size - 1);
pnext = pstart + t;
break;
}
default:
// ignore
;
@@ -740,7 +742,7 @@ int Library::FillDict(unsigned char *bucketsP, unsigned short ndicpages)
}
// Sort the symbols
qsort( objsymbols.tdata(), objsymbols.dim, 4, (cmpfunc_t)NameCompare );
qsort( objsymbols.tdata(), objsymbols.dim, sizeof(objsymbols.tdata()[0]), (cmpfunc_t)NameCompare );
// Add each of the symbols
for (size_t i = 0; i < objsymbols.dim; i++)
+2 -2
View File
@@ -208,7 +208,7 @@ int runLINK()
flnk.setbuffer(p, plen);
flnk.ref = 1;
if (flnk.write())
error("error writing file %s", lnkfilename);
error(0, "error writing file %s", lnkfilename);
if (lnkfilename->len() < plen)
sprintf(p, "@%s", lnkfilename->toChars());
}
@@ -490,7 +490,7 @@ int executecmd(char *cmd, char *args, int useenv)
else
{
L1:
error("command line length of %d is too long",len);
error(0, "command line length of %d is too long",len);
}
}
+2 -2
View File
@@ -234,7 +234,7 @@ char *TemplateInstance::mangle()
buf.writestring(p);
}
}
buf.printf("%zu%s", strlen(id), id);
buf.printf("%llu%s", (ulonglong)strlen(id), id);
id = buf.toChars();
buf.data = NULL;
//printf("TemplateInstance::mangle() %s = %s\n", toChars(), id);
@@ -262,7 +262,7 @@ char *Dsymbol::mangle()
p += 2;
buf.writestring(p);
}
buf.printf("%zu%s", strlen(id), id);
buf.printf("%llu%s", (ulonglong)strlen(id), id);
id = buf.toChars();
buf.data = NULL;
//printf("Dsymbol::mangle() %s = %s\n", toChars(), id);
+47 -34
View File
@@ -94,7 +94,7 @@ Global::Global()
"\nMSIL back-end (alpha release) by Cristian L. Vlasceanu and associates.";
#endif
;
version = "v2.058";
version = "v2.059";
global.structalign = 8;
memset(&params, 0, sizeof(Param));
@@ -117,6 +117,11 @@ bool Global::endGagging(unsigned oldGagged)
return anyErrs;
}
bool Global::isSpeculativeGagging()
{
return gag && gag == speculativeGag;
}
char *Loc::toChars()
{
@@ -368,7 +373,7 @@ Usage:\n\
extern signed char tyalignsize[];
#if _WIN32
#if _WIN32 && __DMC__
extern "C"
{
extern int _xi_a;
@@ -376,11 +381,11 @@ extern "C"
}
#endif
int main(int argc, char *argv[])
int tryMain(int argc, char *argv[])
{
mem.init(); // initialize storage allocator
mem.setStackBottom(&argv);
#if _WIN32
#if _WIN32 && __DMC__
mem.addroots((char *)&_xi_a, (char *)&_end);
#endif
@@ -404,7 +409,7 @@ int main(int argc, char *argv[])
if (argc < 1 || !argv)
{
Largs:
error("missing or null command line arguments");
error(0, "missing or null command line arguments");
fatal();
}
for (size_t i = 0; i < argc; i++)
@@ -414,7 +419,7 @@ int main(int argc, char *argv[])
}
if (response_expand(&argc,&argv)) // expand response files
error("can't open response file");
error(0, "can't open response file");
files.reserve(argc - 1);
@@ -441,6 +446,7 @@ int main(int argc, char *argv[])
global.params.is64bit = (sizeof(size_t) == 8);
#if TARGET_WINDOS
global.params.is64bit = 0;
global.params.defaultlibname = "phobos";
#elif TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS
global.params.defaultlibname = "phobos2";
@@ -542,7 +548,7 @@ int main(int argc, char *argv[])
else if (strcmp(p + 1, "gs") == 0)
global.params.alwaysframe = 1;
else if (strcmp(p + 1, "gt") == 0)
{ error("use -profile instead of -gt\n");
{ error(0, "use -profile instead of -gt\n");
global.params.trace = 1;
}
else if (strcmp(p + 1, "m32") == 0)
@@ -562,7 +568,7 @@ int main(int argc, char *argv[])
#if DMDV1
global.params.Dversion = 1;
#else
error("use DMD 1.0 series compilers for -v1 switch");
error(0, "use DMD 1.0 series compilers for -v1 switch");
break;
#endif
}
@@ -599,7 +605,7 @@ int main(int argc, char *argv[])
break;
case 0:
error("-o no longer supported, use -of or -od");
error(0, "-o no longer supported, use -of or -od");
break;
default:
@@ -844,11 +850,11 @@ int main(int argc, char *argv[])
else
{
Lerror:
error("unrecognized switch '%s'", argv[i]);
error(0, "unrecognized switch '%s'", argv[i]);
continue;
Lnoarg:
error("argument expected for switch '%s'", argv[i]);
error(0, "argument expected for switch '%s'", argv[i]);
continue;
}
}
@@ -883,7 +889,7 @@ int main(int argc, char *argv[])
#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS
if (global.params.lib && global.params.dll)
error("cannot mix -lib and -shared\n");
error(0, "cannot mix -lib and -shared\n");
#endif
if (global.params.release)
@@ -945,7 +951,7 @@ int main(int argc, char *argv[])
}
else if (global.params.run)
{
error("flags conflict with -run");
error(0, "flags conflict with -run");
fatal();
}
else
@@ -1051,10 +1057,10 @@ int main(int argc, char *argv[])
#if _WIN32
// Convert / to \ so linker will work
for (size_t i = 0; p[i]; i++)
for (size_t j = 0; p[j]; j++)
{
if (p[i] == '/')
p[i] = '\\';
if (p[j] == '/')
p[j] = '\\';
}
#endif
@@ -1136,12 +1142,12 @@ int main(int argc, char *argv[])
strcmp(name, ".") == 0)
{
Linvalid:
error("invalid file name '%s'", files.tdata()[i]);
error(0, "invalid file name '%s'", files.tdata()[i]);
fatal();
}
}
else
{ error("unrecognized file extension %s\n", ext);
{ error(0, "unrecognized file extension %s\n", ext);
fatal();
}
}
@@ -1165,10 +1171,6 @@ int main(int argc, char *argv[])
}
}
#if WINDOWS_SEH
__try
{
#endif
// Read files
#define ASYNCREAD 1
#if ASYNCREAD
@@ -1205,7 +1207,8 @@ int main(int argc, char *argv[])
#if ASYNCREAD
if (aw->read(filei))
{
error("cannot read file %s", m->srcfile->name->toChars());
error(0, "cannot read file %s", m->srcfile->name->toChars());
fatal();
}
#endif
m->parse();
@@ -1239,7 +1242,7 @@ int main(int argc, char *argv[])
if (anydocfiles && modules.dim &&
(global.params.oneobj || global.params.objname))
{
error("conflicting Ddoc and obj generation options");
error(0, "conflicting Ddoc and obj generation options");
fatal();
}
if (global.errors)
@@ -1426,14 +1429,6 @@ int main(int argc, char *argv[])
if (global.params.lib && !global.errors)
library->write();
#if WINDOWS_SEH
}
__except (__ehfilter(GetExceptionInformation()))
{
printf("Stack overflow\n");
fatal();
}
#endif
backend_term();
if (global.errors)
fatal();
@@ -1441,7 +1436,7 @@ int main(int argc, char *argv[])
if (!global.params.objfiles->dim)
{
if (global.params.link)
error("no object files to link");
error(0, "no object files to link");
}
else
{
@@ -1471,6 +1466,24 @@ int main(int argc, char *argv[])
return status;
}
int main(int argc, char *argv[])
{
int status = -1;
#if WINDOWS_SEH
__try
{
#endif
status = tryMain(argc, argv);
#if WINDOWS_SEH
}
__except (__ehfilter(GetExceptionInformation()))
{
printf("Stack overflow\n");
fatal();
}
#endif
return status;
}
/***********************************
@@ -1584,7 +1597,7 @@ long __cdecl __ehfilter(LPEXCEPTION_POINTERS ep)
//printf("%x\n", ep->ExceptionRecord->ExceptionCode);
if (ep->ExceptionRecord->ExceptionCode == STATUS_STACK_OVERFLOW)
{
#ifndef DEBUG
#if 1 //ndef DEBUG
return EXCEPTION_EXECUTE_HANDLER;
#endif
}
+11 -3
View File
@@ -262,6 +262,12 @@ struct Global
unsigned gag; // !=0 means gag reporting of errors & warnings
unsigned gaggedErrors; // number of errors reported while gagged
/* Gagging can either be speculative (is(typeof()), etc)
* or because of forward references
*/
unsigned speculativeGag; // == gag means gagging is for is(typeof);
bool isSpeculativeGagging();
// Start gagging. Return the current number of gagged errors
unsigned startGagging();
@@ -278,10 +284,12 @@ extern Global global;
/* Set if Windows Structured Exception Handling C extensions are supported.
* Apparently, VC has dropped support for these?
*/
#define WINDOWS_SEH (_WIN32 && __DMC__)
#define WINDOWS_SEH _WIN32
#include "longdouble.h"
#ifdef __DMC__
#include <complex.h>
typedef _Complex long double complex_t;
#else
#ifndef IN_GCC
@@ -312,7 +320,7 @@ typedef uint64_t d_uns64;
typedef float d_float32;
typedef double d_float64;
typedef long double d_float80;
typedef longdouble d_float80;
typedef d_uns8 d_char;
typedef d_uns16 d_wchar;
@@ -321,7 +329,7 @@ typedef d_uns32 d_dchar;
#ifdef IN_GCC
#include "d-gcc-real.h"
#else
typedef long double real_t;
typedef longdouble real_t;
#endif
// Modify OutBuffer::writewchar to write the correct size of wchar
+20 -12
View File
@@ -342,7 +342,9 @@ Module *Module::load(Loc loc, Identifiers *packages, Identifier *ident)
printf("%s\t(%s)\n", ident->toChars(), m->srcfile->toChars());
}
m->read(loc);
if (!m->read(loc))
return NULL;
m->parse();
#ifdef IN_GCC
@@ -352,7 +354,7 @@ Module *Module::load(Loc loc, Identifiers *packages, Identifier *ident)
return m;
}
void Module::read(Loc loc)
bool Module::read(Loc loc)
{
//printf("Module::read('%s') file '%s'\n", toChars(), srcfile->toChars());
if (srcfile->read())
@@ -365,14 +367,16 @@ void Module::read(Loc loc)
for (size_t i = 0; i < global.path->dim; i++)
{
char *p = global.path->tdata()[i];
fprintf(stdmsg, "import path[%zd] = %s\n", i, p);
fprintf(stdmsg, "import path[%llu] = %s\n", (ulonglong)i, p);
}
}
else
fprintf(stdmsg, "Specify path to file '%s' with -I switch\n", srcfile->toChars());
fatal();
}
fatal();
return false;
}
return true;
}
inline unsigned readwordLE(unsigned short *p)
@@ -1167,19 +1171,23 @@ DsymbolTable *Package::resolve(Identifiers *packages, Dsymbol **pparent, Package
else
{
assert(p->isPackage());
#if TARGET_NET //dot net needs modules and packages with same name
#else
if (p->isModule())
{ p->error("module and package have the same name");
fatal();
break;
}
#endif
// It might already be a module, not a package, but that needs
// to be checked at a higher level, where a nice error message
// can be generated.
// dot net needs modules and packages with same name
}
parent = p;
dst = ((Package *)p)->symtab;
if (ppkg && !*ppkg)
*ppkg = (Package *)p;
#if TARGET_NET
#else
if (p->isModule())
{ // Return the module so that a nice error message can be generated
*ppkg = (Package *)p;
break;
}
#endif
}
if (pparent)
{
+1 -1
View File
@@ -120,7 +120,7 @@ struct Module : Package
void toJsonBuffer(OutBuffer *buf);
const char *kind();
void setDocfile(); // set docfile member
void read(Loc loc); // read file
bool read(Loc loc); // read file, returns 'true' if succeed, 'false' otherwise.
#if IN_GCC
void parse(bool dump_source = false); // syntactic parse
#else
+313 -126
View File
@@ -81,6 +81,10 @@ int REALALIGNSIZE = 4;
int REALSIZE = 10;
int REALPAD = 0;
int REALALIGNSIZE = 2;
#elif IN_GCC
int REALSIZE = 0;
int REALPAD = 0;
int REALALIGNSIZE = 0;
#else
#error "fix this"
#endif
@@ -247,7 +251,7 @@ void Type::init()
for (size_t i = 0; i < TMAX; i++)
{ if (!mangleChar[i])
fprintf(stdmsg, "ty = %zd\n", i);
fprintf(stdmsg, "ty = %llu\n", (ulonglong)i);
assert(mangleChar[i]);
}
@@ -413,6 +417,8 @@ Type *Type::mutableOf()
t = t->merge();
t->fixTo(this);
}
else
t = t->merge();
assert(t->isMutable());
return t;
}
@@ -504,6 +510,8 @@ Type *Type::unSharedOf()
t->fixTo(this);
}
else
t = t->merge();
assert(!t->isShared());
return t;
}
@@ -1280,7 +1288,19 @@ Type *Type::aliasthisOf()
Expression *ethis = this->defaultInit(0);
fd = fd->overloadResolve(0, ethis, NULL);
if (fd)
{ TypeFunction *tf = (TypeFunction *)fd->type;
if (!tf->next && fd->inferRetType)
{
TemplateInstance *spec = fd->isSpeculative();
int olderrs = global.errors;
fd->semantic3(fd->scope);
// Update the template instantiation with the number
// of errors which occured.
if (spec && global.errors != olderrs)
spec->errors = global.errors - olderrs;
}
t = ((TypeFunction *)fd->type)->next;
}
}
return t;
}
@@ -1290,6 +1310,32 @@ Type *Type::aliasthisOf()
Type *t = ed->type;
return t;
}
TemplateDeclaration *td = ad->aliasthis->isTemplateDeclaration();
if (td)
{ assert(td->scope);
Expression *ethis = defaultInit(0);
FuncDeclaration *fd = td->deduceFunctionTemplate(td->scope, 0, NULL, ethis, NULL, 1);
if (fd)
{
//if (!fd->type->nextOf() && fd->inferRetType)
{
TemplateInstance *spec = fd->isSpeculative();
int olderrs = global.errors;
fd->semantic3(fd->scope);
// Update the template instantiation with the number
// of errors which occured.
if (spec && global.errors != olderrs)
spec->errors = global.errors - olderrs;
}
if (!global.errors)
{
Type *t = fd->type->nextOf();
t = t->substWildTo(mod == 0 ? MODmutable : mod);
return t;
}
}
return Type::terror;
}
//printf("%s\n", ad->aliasthis->kind());
}
return NULL;
@@ -1580,6 +1626,8 @@ Type *Type::merge()
if (ty == Ttypeof) return this;
if (ty == Tident) return this;
if (ty == Tinstance) return this;
if (ty == Taarray && !((TypeAArray *)this)->index->merge()->deco)
return this;
if (nextOf() && !nextOf()->merge()->deco)
return this;
@@ -1836,12 +1884,12 @@ Type *Type::substWildTo(unsigned mod)
else if (ty == Taarray)
{
t = new TypeAArray(t, ((TypeAArray *)this)->index->syntaxCopy());
t = t->merge();
((TypeAArray *)t)->sc = ((TypeAArray *)this)->sc; // duplicate scope
}
else
assert(0);
t = t->addMod(this->mod);
t = t->merge();
}
}
else
@@ -1978,35 +2026,6 @@ Expression *Type::dotExp(Scope *sc, Expression *e, Identifier *ident)
}
else if (ident == Id::init)
{
#if 0
if (v->init)
{
if (v->init->isVoidInitializer())
error(e->loc, "%s.init is void", v->toChars());
else
{ Loc loc = e->loc;
e = v->init->toExpression();
if (e->op == TOKassign || e->op == TOKconstruct || e->op == TOKblit)
{
e = ((AssignExp *)e)->e2;
/* Take care of case where we used a 0
* to initialize the struct.
*/
if (e->type == Type::tint32 &&
e->isBool(0) &&
v->type->toBasetype()->ty == Tstruct)
{
e = v->type->defaultInit(e->loc);
}
}
e = e->optimize(WANTvalue | WANTinterpret);
// if (!e->isConst())
// error(loc, ".init cannot be evaluated at compile time");
}
goto Lreturn;
}
#endif
e = defaultInitLiteral(e->loc);
goto Lreturn;
}
@@ -2082,7 +2101,6 @@ Expression *Type::noMember(Scope *sc, Expression *e, Identifier *ident)
tiargs->push(se);
e = new DotTemplateInstanceExp(e->loc, e, Id::opDispatch, tiargs);
((DotTemplateInstanceExp *)e)->ti->tempdecl = td;
//return e;
e = e->semantic(sc);
return e;
}
@@ -2093,7 +2111,7 @@ Expression *Type::noMember(Scope *sc, Expression *e, Identifier *ident)
{ /* Rewrite e.ident as:
* e.aliasthis.ident
*/
e = new DotIdExp(e->loc, e, sym->aliasthis->ident);
e = resolveAliasThis(sc, e);
e = new DotIdExp(e->loc, e, ident);
return e->semantic(sc);
}
@@ -2170,11 +2188,15 @@ void Type::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps)
}
/*******************************
* If one of the subtypes of this type is a TypeIdentifier,
* i.e. it's an unresolved type, return that type.
* tparams == NULL:
* If one of the subtypes of this type is a TypeIdentifier,
* i.e. it's an unresolved type, return that type.
* tparams != NULL:
* Only when the TypeIdentifier is one of template parameters,
* return that type.
*/
Type *Type::reliesOnTident()
Type *Type::reliesOnTident(TemplateParameters *tparams)
{
return NULL;
}
@@ -2294,9 +2316,9 @@ void TypeNext::checkDeprecated(Loc loc, Scope *sc)
}
Type *TypeNext::reliesOnTident()
Type *TypeNext::reliesOnTident(TemplateParameters *tparams)
{
return next->reliesOnTident();
return next->reliesOnTident(tparams);
}
int TypeNext::hasWild()
@@ -2463,9 +2485,7 @@ Type *TypeNext::makeMutable()
{
//printf("TypeNext::makeMutable() %p, %s\n", this, toChars());
TypeNext *t = (TypeNext *)Type::makeMutable();
if ((ty != Tfunction && next->ty != Tfunction &&
//(next->deco || next->ty == Tfunction) &&
next->isWild()) || ty == Tsarray)
if (ty == Tsarray)
{
t->next = next->mutableOf();
}
@@ -3037,7 +3057,7 @@ Expression *TypeBasic::dotExp(Scope *sc, Expression *e, Identifier *ident)
case Timaginary64: t = tfloat64; goto L2;
case Timaginary80: t = tfloat80; goto L2;
L2:
e = new RealExp(0, 0.0, t);
e = new RealExp(e->loc, ldouble(0.0), t);
break;
default:
@@ -3069,7 +3089,7 @@ Expression *TypeBasic::dotExp(Scope *sc, Expression *e, Identifier *ident)
case Tfloat32:
case Tfloat64:
case Tfloat80:
e = new RealExp(0, 0.0, this);
e = new RealExp(e->loc, ldouble(0.0), this);
break;
default:
@@ -3096,7 +3116,7 @@ Expression *TypeBasic::defaultInit(Loc loc)
*/
union
{ unsigned short us[8];
long double ld;
longdouble ld;
} snan = {{ 0, 0, 0, 0xA000, 0x7FFF }};
/*
* Although long doubles are 10 bytes long, some
@@ -3324,11 +3344,25 @@ Type *TypeVector::semantic(Loc loc, Scope *sc)
if (errors != global.errors)
return terror;
basetype = basetype->toBasetype()->mutableOf();
if (basetype->ty != Tsarray || basetype->size() != 16)
{ error(loc, "base type of __vector must be a 16 byte static array, not %s", basetype->toChars());
if (basetype->ty != Tsarray)
{ error(loc, "T in __vector(T) must be a static array, not %s", basetype->toChars());
return terror;
}
TypeSArray *t = (TypeSArray *)basetype;
if (sc && sc->parameterSpecialization && t->dim->op == TOKvar &&
((VarExp *)t->dim)->var->storage_class & STCtemplateparameter)
{
/* It could be a template parameter N which has no value yet:
* template Foo(T : __vector(T[N]), size_t N);
*/
return this;
}
if (t->size(loc) != 16)
{ error(loc, "base type of __vector must be a 16 byte static array, not %s", t->toChars());
return terror;
}
TypeBasic *tb = t->nextOf()->isTypeBasic();
if (!tb || !(tb->flags & TFLAGSvector))
{ error(loc, "base type of __vector must be a static array of an arithmetic type, not %s", t->toChars());
@@ -3601,7 +3635,7 @@ d_uns64 TypeSArray::size(Loc loc)
return sz;
Loverflow:
error(loc, "index %jd overflow for static array", sz);
error(loc, "index %lld overflow for static array", sz);
return 1;
}
@@ -3649,7 +3683,10 @@ void TypeSArray::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol
//printf("s = %p, e = %p, t = %p\n", *ps, *pe, *pt);
if (*pe)
{ // It's really an index expression
Expression *e = new IndexExp(loc, *pe, dim);
Expressions *exps = new Expressions();
exps->setDim(1);
(*exps)[0] = dim;
Expression *e = new ArrayExp(loc, *pe, exps);
*pe = e;
}
else if (*ps)
@@ -3668,7 +3705,7 @@ void TypeSArray::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol
sc = sc->pop();
if (d >= td->objects->dim)
{ error(loc, "tuple index %ju exceeds length %u", d, td->objects->dim);
{ error(loc, "tuple index %llu exceeds length %u", d, td->objects->dim);
goto Ldefault;
}
Object *o = td->objects->tdata()[(size_t)d];
@@ -3728,7 +3765,7 @@ Type *TypeSArray::semantic(Loc loc, Scope *sc)
uinteger_t d = dim->toUInteger();
if (d >= sd->objects->dim)
{ error(loc, "tuple index %ju exceeds %u", d, sd->objects->dim);
{ error(loc, "tuple index %llu exceeds %u", d, sd->objects->dim);
return Type::terror;
}
Object *o = sd->objects->tdata()[(size_t)d];
@@ -3795,7 +3832,7 @@ Type *TypeSArray::semantic(Loc loc, Scope *sc)
if (n && n2 / n != d2)
{
Loverflow:
error(loc, "index %jd overflow for static array", d1);
error(loc, "index %lld overflow for static array", d1);
goto Lerror;
}
}
@@ -3809,7 +3846,7 @@ Type *TypeSArray::semantic(Loc loc, Scope *sc)
uinteger_t d = dim->toUInteger();
if (d >= tt->arguments->dim)
{ error(loc, "tuple index %ju exceeds %u", d, tt->arguments->dim);
{ error(loc, "tuple index %llu exceeds %u", d, tt->arguments->dim);
goto Lerror;
}
Parameter *arg = tt->arguments->tdata()[(size_t)d];
@@ -3850,7 +3887,7 @@ void TypeSArray::toDecoBuffer(OutBuffer *buf, int flag)
{
Type::toDecoBuffer(buf, flag);
if (dim)
buf->printf("%ju", dim->toInteger());
buf->printf("%llu", dim->toInteger());
if (next)
/* Note that static arrays are value types, so
* for a parameter, propagate the 0x100 to the next
@@ -4102,6 +4139,31 @@ Type *TypeDArray::semantic(Loc loc, Scope *sc)
return merge();
}
void TypeDArray::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps)
{
//printf("TypeDArray::resolve() %s\n", toChars());
next->resolve(loc, sc, pe, pt, ps);
//printf("s = %p, e = %p, t = %p\n", *ps, *pe, *pt);
if (*pe)
{ // It's really a slice expression
Expression *e = new SliceExp(loc, *pe, NULL, NULL);
*pe = e;
}
else if (*ps)
{
TupleDeclaration *td = (*ps)->isTupleDeclaration();
if (td)
; // keep *ps
else
goto Ldefault;
}
else
{
Ldefault:
Type::resolve(loc, sc, pe, pt, ps);
}
}
void TypeDArray::toDecoBuffer(OutBuffer *buf, int flag)
{
Type::toDecoBuffer(buf, flag);
@@ -4373,8 +4435,8 @@ StructDeclaration *TypeAArray::getImpl()
* which has Tident's instead of real types.
*/
Objects *tiargs = new Objects();
tiargs->push(index);
tiargs->push(next);
tiargs->push(index->substWildTo(MODconst)); // hack for bug7757
tiargs->push(next ->substWildTo(MODconst)); // hack for bug7757
// Create AssociativeArray!(index, next)
#if 1
@@ -4514,8 +4576,12 @@ Expression *TypeAArray::dotExp(Scope *sc, Expression *e, Identifier *ident)
ident != Id::stringof &&
ident != Id::offsetof)
{
e->type = getImpl()->type;
e = e->type->dotExp(sc, e, ident);
//printf("test1: %s, %s\n", e->toChars(), e->type->toChars());
Type *t = getImpl()->type;
//printf("test2: %s, %s\n", e->toChars(), e->type->toChars());
e->type = t;
e = t->dotExp(sc, e, ident);
//printf("test3: %s, %s\n", e->toChars(), e->type->toChars());
}
else
e = Type::dotExp(sc, e, ident);
@@ -4559,6 +4625,22 @@ int TypeAArray::checkBoolean()
return TRUE;
}
Expression *TypeAArray::toExpression()
{
Expression *e = next->toExpression();
if (e)
{
Expression *ei = index->toExpression();
if (ei)
{
Expressions *arguments = new Expressions();
arguments->push(ei);
return new ArrayExp(loc, e, arguments);
}
}
return NULL;
}
int TypeAArray::hasPointers()
{
return TRUE;
@@ -4590,11 +4672,7 @@ MATCH TypeAArray::implicitConvTo(Type *to)
MATCH mi = index->constConv(ta->index);
if (m != MATCHnomatch && mi != MATCHnomatch)
{
if (m == MATCHexact && mod != to->mod)
m = MATCHconst;
if (mi < m)
m = mi;
return m;
return MODimplicitConv(mod, to->mod) ? MATCHconst : MATCHnomatch;
}
}
else if (to->ty == Tstruct && ((TypeStruct *)to)->sym->ident == Id::AssociativeArray)
@@ -4660,7 +4738,8 @@ Type *TypePointer::semantic(Loc loc, Scope *sc)
deco = NULL;
}
next = n;
transitive();
if (next->ty != Tfunction)
transitive();
return merge();
}
@@ -4865,6 +4944,7 @@ TypeFunction::TypeFunction(Parameters *parameters, Type *treturn, int varargs, e
this->purity = PUREimpure;
this->isproperty = false;
this->isref = false;
this->iswild = false;
this->fargs = NULL;
if (stc & STCpure)
@@ -4910,9 +4990,10 @@ Type *TypeFunction::syntaxCopy()
* 2 arguments match as far as overloading goes,
* but types are not covariant
* 3 cannot determine covariance because of forward references
* *pstc STCxxxx which would make it covariant
*/
int Type::covariant(Type *t)
int Type::covariant(Type *t, StorageClass *pstc)
{
#if 0
printf("Type::covariant(t = %s) %s\n", t->toChars(), toChars());
@@ -4921,6 +5002,10 @@ int Type::covariant(Type *t)
printf("mod = %x, %x\n", mod, t->mod);
#endif
if (pstc)
*pstc = 0;
StorageClass stc = 0;
int inoutmismatch = 0;
TypeFunction *t1;
@@ -5024,35 +5109,39 @@ int Type::covariant(Type *t)
goto Lnotcovariant;
Lcovariant:
if (t1->isref != t2->isref)
goto Lnotcovariant;
/* Can convert mutable to const
*/
if (!MODimplicitConv(t2->mod, t1->mod))
goto Lnotcovariant;
#if 0
if (t1->mod != t2->mod)
{
if (!(t1->mod & MODconst) && (t2->mod & MODconst))
goto Lnotcovariant;
if (!(t1->mod & MODshared) && (t2->mod & MODshared))
// If adding 'const' will make it covariant
if (MODimplicitConv(t2->mod, MODmerge(t1->mod, MODconst)))
stc |= STCconst;
else
goto Lnotcovariant;
}
#endif
/* Can convert pure to impure, and nothrow to throw
*/
if (!t1->purity && t2->purity)
goto Lnotcovariant;
stc |= STCpure;
if (!t1->isnothrow && t2->isnothrow)
goto Lnotcovariant;
if (t1->isref != t2->isref)
goto Lnotcovariant;
stc |= STCnothrow;
/* Can convert safe/trusted to system
*/
if (t1->trust <= TRUSTsystem && t2->trust >= TRUSTtrusted)
// Should we infer trusted or safe? Go with safe.
stc |= STCsafe;
if (stc)
{ if (pstc)
*pstc = stc;
goto Lnotcovariant;
}
//printf("\tcovaraint: 1\n");
return 1;
@@ -5317,10 +5406,14 @@ Type *TypeFunction::semantic(Loc loc, Scope *sc)
tf->isnothrow = TRUE;
if (sc->stc & STCref)
tf->isref = TRUE;
if (sc->stc & STCsafe)
tf->trust = TRUSTsafe;
if (sc->stc & STCsystem)
tf->trust = TRUSTsystem;
if (sc->stc & STCtrusted)
tf->trust = TRUSTtrusted;
if (sc->stc & STCproperty)
tf->isproperty = TRUE;
@@ -5328,13 +5421,15 @@ Type *TypeFunction::semantic(Loc loc, Scope *sc)
/* If the parent is @safe, then this function defaults to safe
* too.
* If the parent's @safe-ty is inferred, then this function's @safe-ty needs
* to be inferred first.
*/
if (tf->trust == TRUSTdefault)
for (Dsymbol *p = sc->func; p; p = p->toParent2())
{ FuncDeclaration *fd = p->isFuncDeclaration();
if (fd)
{
if (fd->isSafe())
if (fd->isSafeBypassingInference())
tf->trust = TRUSTsafe; // default to @safe
break;
}
@@ -5371,7 +5466,6 @@ Type *TypeFunction::semantic(Loc loc, Scope *sc)
}
bool wildparams = FALSE;
bool wildsubparams = FALSE;
if (tf->parameters)
{
/* Create a scope for evaluating the default arguments for the parameters
@@ -5413,17 +5507,38 @@ Type *TypeFunction::semantic(Loc loc, Scope *sc)
!(t->ty == Tpointer && t->nextOf()->ty == Tfunction || t->ty == Tdelegate))
{
wildparams = TRUE;
if (tf->next && !wildreturn)
error(loc, "inout on parameter means inout must be on return type as well (if from D1 code, replace with 'ref')");
//if (tf->next && !wildreturn)
// error(loc, "inout on parameter means inout must be on return type as well (if from D1 code, replace with 'ref')");
}
else if (!wildsubparams && t->hasWild())
wildsubparams = TRUE;
if (fparam->defaultArg)
{
fparam->defaultArg = fparam->defaultArg->semantic(argsc);
fparam->defaultArg = resolveProperties(argsc, fparam->defaultArg);
fparam->defaultArg = fparam->defaultArg->implicitCastTo(argsc, fparam->type);
{ Expression *e = fparam->defaultArg;
e = e->inferType(fparam->type);
e = e->semantic(argsc);
e = resolveProperties(argsc, e);
if (e->op == TOKfunction) // see Bugzilla 4820
{ FuncExp *fe = (FuncExp *)e;
if (fe->fd)
{ if (fe->fd->tok == TOKreserved)
{
if (fe->type->ty == Tpointer)
{
fe->fd->vthis = NULL;
fe->fd->tok = TOKfunction;
}
else
fe->fd->tok = TOKdelegate;
}
// Replace function literal with a function symbol,
// since default arg expression must be copied when used
// and copying the literal itself is wrong.
e = new VarExp(e->loc, fe->fd, 0);
e = new AddrExp(e->loc, e);
e = e->semantic(argsc);
}
}
e = e->implicitCastTo(argsc, fparam->type);
fparam->defaultArg = e;
}
/* If fparam after semantic() turns out to be a tuple, the number of parameters may
@@ -5484,8 +5599,7 @@ Type *TypeFunction::semantic(Loc loc, Scope *sc)
if (wildreturn && !wildparams)
error(loc, "inout on return means inout must be on a parameter as well for %s", toChars());
if (wildsubparams && wildparams)
error(loc, "inout must be all or none on top level for %s", toChars());
tf->iswild = wildparams;
if (tf->next)
tf->deco = tf->merge()->deco;
@@ -5496,8 +5610,8 @@ Type *TypeFunction::semantic(Loc loc, Scope *sc)
return terror;
}
if (tf->isproperty && (tf->varargs || Parameter::dim(tf->parameters) > 1))
error(loc, "properties can only have zero or one parameter");
if (tf->isproperty && (tf->varargs || Parameter::dim(tf->parameters) > 2))
error(loc, "properties can only have zero, one, or two parameter");
if (tf->varargs == 1 && tf->linkage != LINKd && Parameter::dim(tf->parameters) == 0)
error(loc, "variadic functions with non-D linkage must have at least one parameter");
@@ -5690,9 +5804,8 @@ int TypeFunction::callMatch(Expression *ethis, Expressions *args, int flag)
assert(arg);
if (arg->op == TOKfunction)
{ FuncExp *fe = (FuncExp *)arg;
Type *pt = p->type;
arg = ((FuncExp *)arg)->inferType(NULL, pt);
{
arg = ((FuncExp *)arg)->inferType(p->type, 1);
if (!arg)
goto L1; // try typesafe variadics
}
@@ -5779,9 +5892,8 @@ int TypeFunction::callMatch(Expression *ethis, Expressions *args, int flag)
assert(arg);
#if 1
if (arg->op == TOKfunction)
{ FuncExp *fe = (FuncExp *)arg;
Type *pt = tb->nextOf();
arg = ((FuncExp *)arg)->inferType(NULL, pt);
{
arg = ((FuncExp *)arg)->inferType(tb->nextOf(), 1);
if (!arg)
goto Nomatch;
}
@@ -5841,16 +5953,16 @@ Nomatch:
return MATCHnomatch;
}
Type *TypeFunction::reliesOnTident()
Type *TypeFunction::reliesOnTident(TemplateParameters *tparams)
{
size_t dim = Parameter::dim(parameters);
for (size_t i = 0; i < dim; i++)
{ Parameter *fparam = Parameter::getNth(parameters, i);
Type *t = fparam->type->reliesOnTident();
Type *t = fparam->type->reliesOnTident(tparams);
if (t)
return t;
}
return next ? next->reliesOnTident() : NULL;
return next ? next->reliesOnTident(tparams) : NULL;
}
/********************************************
@@ -5908,6 +6020,36 @@ Expression *TypeFunction::defaultInit(Loc loc)
return new ErrorExp();
}
Type *TypeFunction::addStorageClass(StorageClass stc)
{
TypeFunction *t = (TypeFunction *)Type::addStorageClass(stc);
if ((stc & STCpure && !t->purity) ||
(stc & STCnothrow && !t->isnothrow) ||
(stc & STCsafe && t->trust < TRUSTtrusted))
{
// Klunky to change these
TypeFunction *tf = new TypeFunction(t->parameters, t->next, t->varargs, t->linkage, 0);
tf->mod = t->mod;
tf->fargs = fargs;
tf->purity = t->purity;
tf->isnothrow = t->isnothrow;
tf->isproperty = t->isproperty;
tf->isref = t->isref;
tf->trust = t->trust;
if (stc & STCpure)
tf->purity = PUREfwdref;
if (stc & STCnothrow)
tf->isnothrow = true;
if (stc & STCsafe)
tf->trust = TRUSTsafe;
tf->deco = tf->merge()->deco;
t = tf;
}
return t;
}
/***************************** TypeDelegate *****************************/
TypeDelegate::TypeDelegate(Type *t)
@@ -6200,7 +6342,19 @@ void TypeQualified::resolveHelper(Loc loc, Scope *sc,
else
{
Lerror:
error(loc, "identifier '%s' of '%s' is not defined", id->toChars(), toChars());
if (id->dyncast() == DYNCAST_DSYMBOL)
{ // searchX already handles errors for template instances
assert(global.errors);
}
else
{
sm = s->search_correct(id);
if (sm)
error(loc, "identifier '%s' of '%s' is not defined, did you mean '%s %s'?",
id->toChars(), toChars(), sm->kind(), sm->toChars());
else
error(loc, "identifier '%s' of '%s' is not defined", id->toChars(), toChars());
}
*pe = new ErrorExp();
}
return;
@@ -6437,10 +6591,6 @@ Type *TypeIdentifier::semantic(Loc loc, Scope *sc)
}
else
{
#ifdef DEBUG
if (!global.gag)
printf("1: ");
#endif
if (s)
{
s->error(loc, "is used as a type");
@@ -6454,9 +6604,23 @@ Type *TypeIdentifier::semantic(Loc loc, Scope *sc)
return t;
}
Type *TypeIdentifier::reliesOnTident()
Type *TypeIdentifier::reliesOnTident(TemplateParameters *tparams)
{
return this;
if (tparams)
{
if (idents.dim == 0)
{
for (size_t i = 0; i < tparams->dim; i++)
{ TemplateParameter *tp = tparams->tdata()[i];
if (tp->ident->equals(ident))
return this;
}
}
return NULL;
}
else
return this;
}
Expression *TypeIdentifier::toExpression()
@@ -6537,12 +6701,11 @@ Type *TypeInstance::semantic(Loc loc, Scope *sc)
Expression *e;
Dsymbol *s;
//printf("TypeInstance::semantic(%s)\n", toChars());
//printf("TypeInstance::semantic(%p, %s)\n", this, toChars());
if (sc->parameterSpecialization)
{
unsigned errors = global.startGagging();
resolve(loc, sc, &e, &t, &s);
if (global.endGagging(errors))
@@ -6691,8 +6854,14 @@ Type *TypeTypeof::semantic(Loc loc, Scope *sc)
{
Scope *sc2 = sc->push();
sc2->intypeof++;
sc2->speculative = true;
sc2->flags |= sc->flags & SCOPEstaticif;
unsigned oldspecgag = global.speculativeGag;
if (global.gag)
global.speculativeGag = global.gag;
exp = exp->semantic(sc2);
global.speculativeGag = oldspecgag;
#if DMDV2
if (exp->type && exp->type->ty == Tfunction &&
((TypeFunction *)exp->type)->isproperty)
@@ -6883,9 +7052,6 @@ unsigned TypeEnum::alignsize()
{
if (!sym->memtype)
{
#ifdef DEBUG
printf("1: ");
#endif
error(0, "enum %s is forward referenced", sym->toChars());
return 4;
}
@@ -6912,9 +7078,6 @@ Type *TypeEnum::toBasetype()
}
if (!sym->memtype)
{
#ifdef DEBUG
printf("2: ");
#endif
error(sym->loc, "enum %s is forward referenced", sym->toChars());
return tint32;
}
@@ -7099,9 +7262,6 @@ int TypeEnum::isZeroInit(Loc loc)
}
if (!sym->defaultval)
{
#ifdef DEBUG
printf("3: ");
#endif
error(loc, "enum %s is forward referenced", sym->toChars());
return 0;
}
@@ -7707,10 +7867,17 @@ Expression *TypeStruct::defaultInitLiteral(Loc loc)
e = vd->init->toExpression();
}
else
e = vd->type->defaultInitLiteral();
structelems->tdata()[j] = e;
e = vd->type->defaultInitLiteral(loc);
(*structelems)[j] = e;
}
StructLiteralExp *structinit = new StructLiteralExp(loc, (StructDeclaration *)sym, structelems);
/* Copy from the initializer symbol for larger symbols,
* otherwise the literals expressed as code get excessively large.
*/
if (size(loc) > PTRSIZE * 4)
structinit->sinit = sym->toInitializer();
// Why doesn't the StructLiteralExp constructor do this, when
// sym->type != NULL ?
structinit->type = sym->type;
@@ -7788,7 +7955,7 @@ MATCH TypeStruct::implicitConvTo(Type *to)
{ MATCH m;
//printf("TypeStruct::implicitConvTo(%s => %s)\n", toChars(), to->toChars());
if (to->ty == Taarray)
if (to->ty == Taarray && sym->ident == Id::AssociativeArray)
{
/* If there is an error instantiating AssociativeArray!(), it shouldn't
* be reported -- it just means implicit conversion is impossible.
@@ -8244,7 +8411,7 @@ L1:
return e;
}
DotVarExp *de = new DotVarExp(e->loc, e, d);
DotVarExp *de = new DotVarExp(e->loc, e, d, d->hasOverloads());
return de->semantic(sc);
}
@@ -8480,14 +8647,14 @@ int TypeTuple::equals(Object *o)
return 0;
}
Type *TypeTuple::reliesOnTident()
Type *TypeTuple::reliesOnTident(TemplateParameters *tparams)
{
if (arguments)
{
for (size_t i = 0; i < arguments->dim; i++)
{
Parameter *arg = arguments->tdata()[i];
Type *t = arg->type->reliesOnTident();
Type *t = arg->type->reliesOnTident(tparams);
if (t)
return t;
}
@@ -8538,6 +8705,10 @@ Expression *TypeTuple::getProperty(Loc loc, Identifier *ident)
{
e = new IntegerExp(loc, arguments->dim, Type::tsize_t);
}
else if (ident == Id::init)
{
e = defaultInitLiteral(loc);
}
else
{
error(loc, "no property '%s' for tuple '%s'", ident->toChars(), toChars());
@@ -8546,6 +8717,22 @@ Expression *TypeTuple::getProperty(Loc loc, Identifier *ident)
return e;
}
Expression *TypeTuple::defaultInit(Loc loc)
{
Expressions *exps = new Expressions();
exps->setDim(arguments->dim);
for (size_t i = 0; i < arguments->dim; i++)
{
Parameter *p = (*arguments)[i];
assert(p->type);
Expression *e = p->type->defaultInitLiteral(loc);
if (e->op == TOKerror)
return e;
(*exps)[i] = e;
}
return new TupleExp(loc, exps);
}
/***************************** TypeSlice *****************************/
/* This is so we can slice a TypeTuple */
@@ -8588,7 +8775,7 @@ Type *TypeSlice::semantic(Loc loc, Scope *sc)
uinteger_t i2 = upr->toUInteger();
if (!(i1 <= i2 && i2 <= tt->arguments->dim))
{ error(loc, "slice [%ju..%ju] is out of range of [0..%u]", i1, i2, tt->arguments->dim);
{ error(loc, "slice [%llu..%llu] is out of range of [0..%u]", i1, i2, tt->arguments->dim);
return Type::terror;
}
@@ -8634,7 +8821,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 [%ju..%ju] is out of range of [0..%u]", i1, i2, td->objects->dim);
{ error(loc, "slice [%llu..%llu] is out of range of [0..%u]", i1, i2, td->objects->dim);
goto Ldefault;
}
+18 -8
View File
@@ -223,7 +223,7 @@ struct Type : Object
virtual Type *syntaxCopy();
int equals(Object *o);
int dyncast() { return DYNCAST_TYPE; } // kludge for template.isType()
int covariant(Type *t);
int covariant(Type *t, StorageClass *pstc = NULL);
char *toChars();
static char needThisPrefix();
static void init();
@@ -275,7 +275,7 @@ struct Type : Object
Type *addSTC(StorageClass stc);
Type *castMod(unsigned mod);
Type *addMod(unsigned mod);
Type *addStorageClass(StorageClass stc);
virtual Type *addStorageClass(StorageClass stc);
Type *pointerTo();
Type *referenceTo();
Type *arrayOf();
@@ -301,7 +301,8 @@ struct Type : Object
Expression *noMember(Scope *sc, Expression *e, Identifier *ident);
virtual unsigned memalign(unsigned salign);
virtual Expression *defaultInit(Loc loc = 0);
virtual Expression *defaultInitLiteral(Loc loc = 0);
virtual Expression *defaultInitLiteral(Loc loc);
virtual Expression *voidInitLiteral(VarDeclaration *var);
virtual int isZeroInit(Loc loc = 0); // if initializer is 0
virtual dt_t **toDt(dt_t **pdt);
Identifier *getTypeInfoIdent(int internal);
@@ -311,7 +312,7 @@ struct Type : Object
Expression *getTypeInfo(Scope *sc);
virtual TypeInfoDeclaration *getTypeInfoDeclaration();
virtual int builtinTypeInfo();
virtual Type *reliesOnTident();
virtual Type *reliesOnTident(TemplateParameters *tparams = NULL);
virtual int hasWild();
virtual Expression *toExpression();
virtual int hasPointers();
@@ -354,7 +355,7 @@ struct TypeNext : Type
TypeNext(TY ty, Type *next);
void toDecoBuffer(OutBuffer *buf, int flag);
void checkDeprecated(Loc loc, Scope *sc);
Type *reliesOnTident();
Type *reliesOnTident(TemplateParameters *tparams = NULL);
int hasWild();
Type *nextOf();
Type *makeConst();
@@ -416,6 +417,7 @@ struct TypeVector : Type
char *toChars();
void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod);
void toDecoBuffer(OutBuffer *buf, int flag);
MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes, unsigned *wildmatch = NULL);
#if CPP_MANGLE
void toCppMangle(OutBuffer *buf, CppMangleState *cms);
#endif
@@ -459,6 +461,7 @@ struct TypeSArray : TypeArray
MATCH implicitConvTo(Type *to);
Expression *defaultInit(Loc loc);
Expression *defaultInitLiteral(Loc loc);
Expression *voidInitLiteral(VarDeclaration *var);
dt_t **toDt(dt_t **pdt);
dt_t **toDtElem(dt_t **pdt, Expression *e);
MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes, unsigned *wildmatch = NULL);
@@ -483,6 +486,7 @@ struct TypeDArray : TypeArray
d_uns64 size(Loc loc);
unsigned alignsize();
Type *semantic(Loc loc, Scope *sc);
void resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps);
void toDecoBuffer(OutBuffer *buf, int flag);
void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod);
Expression *dotExp(Scope *sc, Expression *e, Identifier *ident);
@@ -525,6 +529,7 @@ struct TypeAArray : TypeArray
int isZeroInit(Loc loc);
int checkBoolean();
TypeInfoDeclaration *getTypeInfoDeclaration();
Expression *toExpression();
int hasPointers();
TypeTuple *toArgTypes();
MATCH implicitConvTo(Type *to);
@@ -612,6 +617,7 @@ struct TypeFunction : TypeNext
enum LINK linkage; // calling convention
enum TRUST trust; // level of trust
enum PURE purity; // PURExxxx
bool iswild; // is inout function
Expressions *fargs; // function arguments
int inuse;
@@ -627,12 +633,13 @@ struct TypeFunction : TypeNext
void attributesToCBuffer(OutBuffer *buf, int mod);
MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes, unsigned *wildmatch = NULL);
TypeInfoDeclaration *getTypeInfoDeclaration();
Type *reliesOnTident();
Type *reliesOnTident(TemplateParameters *tparams = NULL);
bool hasLazyParameters();
#if CPP_MANGLE
void toCppMangle(OutBuffer *buf, CppMangleState *cms);
#endif
bool parameterEscapes(Parameter *p);
Type *addStorageClass(StorageClass stc);
int callMatch(Expression *ethis, Expressions *toargs, int flag = 0);
type *toCtype();
@@ -695,7 +702,7 @@ struct TypeIdentifier : TypeQualified
Dsymbol *toDsymbol(Scope *sc);
Type *semantic(Loc loc, Scope *sc);
MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes, unsigned *wildmatch = NULL);
Type *reliesOnTident();
Type *reliesOnTident(TemplateParameters *tparams = NULL);
Expression *toExpression();
};
@@ -755,6 +762,7 @@ struct TypeStruct : Type
unsigned memalign(unsigned salign);
Expression *defaultInit(Loc loc);
Expression *defaultInitLiteral(Loc loc);
Expression *voidInitLiteral(VarDeclaration *var);
int isZeroInit(Loc loc);
int isAssignable();
int checkBoolean();
@@ -911,10 +919,11 @@ struct TypeTuple : Type
Type *syntaxCopy();
Type *semantic(Loc loc, Scope *sc);
int equals(Object *o);
Type *reliesOnTident();
Type *reliesOnTident(TemplateParameters *tparams = NULL);
void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod);
void toDecoBuffer(OutBuffer *buf, int flag);
Expression *getProperty(Loc loc, Identifier *ident);
Expression *defaultInit(Loc loc);
TypeInfoDeclaration *getTypeInfoDeclaration();
};
@@ -979,6 +988,7 @@ struct Parameter : Object
extern int PTRSIZE;
extern int REALSIZE;
extern int REALPAD;
extern int REALALIGNSIZE;
extern int Tsize_t;
extern int Tptrdiff_t;
+31 -45
View File
@@ -354,11 +354,9 @@ Expression *UnaExp::op_overload(Scope *sc)
/* Rewrite op(e1) as:
* op(e1.aliasthis)
*/
Expression *e1 = new DotIdExp(loc, this->e1, ad->aliasthis->ident);
Expression *e = copy();
((UnaExp *)e)->e1 = e1;
e = e->trySemantic(sc);
return e;
UnaExp *e = (UnaExp *)syntaxCopy();
e->e1 = new DotIdExp(loc, e->e1, ad->aliasthis->ident);
return e->trySemantic(sc);
}
#endif
}
@@ -413,11 +411,9 @@ Expression *ArrayExp::op_overload(Scope *sc)
/* Rewrite op(e1) as:
* op(e1.aliasthis)
*/
Expression *e1 = new DotIdExp(loc, this->e1, ad->aliasthis->ident);
Expression *e = copy();
((UnaExp *)e)->e1 = e1;
e = e->trySemantic(sc);
return e;
UnaExp *e = (UnaExp *)syntaxCopy();
e->e1 = new DotIdExp(loc, e->e1, ad->aliasthis->ident);
return e->trySemantic(sc);
}
}
return NULL;
@@ -460,11 +456,9 @@ Expression *CastExp::op_overload(Scope *sc)
/* Rewrite op(e1) as:
* op(e1.aliasthis)
*/
Expression *e1 = new DotIdExp(loc, this->e1, ad->aliasthis->ident);
Expression *e = copy();
((UnaExp *)e)->e1 = e1;
e = e->trySemantic(sc);
return e;
UnaExp *e = (UnaExp *)syntaxCopy();
e->e1 = new DotIdExp(loc, e->e1, ad->aliasthis->ident);
return e->trySemantic(sc);
}
}
return NULL;
@@ -720,11 +714,9 @@ L1:
/* Rewrite (e1 op e2) as:
* (e1.aliasthis op e2)
*/
Expression *e1 = new DotIdExp(loc, this->e1, ad1->aliasthis->ident);
Expression *e = copy();
((BinExp *)e)->e1 = e1;
e = e->trySemantic(sc);
return e;
BinExp *e = (BinExp *)syntaxCopy();
e->e1 = new DotIdExp(loc, e->e1, ad1->aliasthis->ident);
return e->trySemantic(sc);
}
// Try alias this on second operand
@@ -737,11 +729,9 @@ L1:
/* Rewrite (e1 op e2) as:
* (e1 op e2.aliasthis)
*/
Expression *e2 = new DotIdExp(loc, this->e2, ad2->aliasthis->ident);
Expression *e = copy();
((BinExp *)e)->e2 = e2;
e = e->trySemantic(sc);
return e;
BinExp *e = (BinExp *)syntaxCopy();
e->e2 = new DotIdExp(loc, e->e2, ad2->aliasthis->ident);
return e->trySemantic(sc);
}
#endif
return NULL;
@@ -893,11 +883,9 @@ Expression *BinExp::compare_overload(Scope *sc, Identifier *id)
/* Rewrite (e1 op e2) as:
* (e1.aliasthis op e2)
*/
Expression *e1 = new DotIdExp(loc, this->e1, ad1->aliasthis->ident);
Expression *e = copy();
((BinExp *)e)->e1 = e1;
e = e->trySemantic(sc);
return e;
BinExp *e = (BinExp *)syntaxCopy();
e->e1 = new DotIdExp(loc, e->e1, ad1->aliasthis->ident);
return e->trySemantic(sc);
}
// Try alias this on second operand
@@ -906,11 +894,9 @@ Expression *BinExp::compare_overload(Scope *sc, Identifier *id)
/* Rewrite (e1 op e2) as:
* (e1 op e2.aliasthis)
*/
Expression *e2 = new DotIdExp(loc, this->e2, ad2->aliasthis->ident);
Expression *e = copy();
((BinExp *)e)->e2 = e2;
e = e->trySemantic(sc);
return e;
BinExp *e = (BinExp *)syntaxCopy();
e->e2 = new DotIdExp(loc, e->e2, ad2->aliasthis->ident);
return e->trySemantic(sc);
}
return NULL;
@@ -1055,6 +1041,10 @@ Expression *BinAssignExp::op_overload(Scope *sc)
e1 = resolveProperties(sc, e1);
e2 = resolveProperties(sc, e2);
// Don't attempt 'alias this' if an error occured
if (e1->type->ty == Terror || e2->type->ty == Terror)
return new ErrorExp();
Identifier *id = opId();
Expressions args2;
@@ -1141,11 +1131,9 @@ L1:
/* Rewrite (e1 op e2) as:
* (e1.aliasthis op e2)
*/
Expression *e1 = new DotIdExp(loc, this->e1, ad1->aliasthis->ident);
Expression *e = copy();
((BinExp *)e)->e1 = e1;
e = e->trySemantic(sc);
return e;
BinExp *e = (BinExp *)syntaxCopy();
e->e1 = new DotIdExp(loc, e->e1, ad1->aliasthis->ident);
return e->trySemantic(sc);
}
// Try alias this on second operand
@@ -1155,11 +1143,9 @@ L1:
/* Rewrite (e1 op e2) as:
* (e1 op e2.aliasthis)
*/
Expression *e2 = new DotIdExp(loc, this->e2, ad2->aliasthis->ident);
Expression *e = copy();
((BinExp *)e)->e2 = e2;
e = e->trySemantic(sc);
return e;
BinExp *e = (BinExp *)syntaxCopy();
e->e2 = new DotIdExp(loc, e->e2, ad2->aliasthis->ident);
return e->trySemantic(sc);
}
#endif
return NULL;
+6 -6
View File
@@ -381,7 +381,7 @@ Expression *AddrExp::optimize(int result)
TypeSArray *ts = (TypeSArray *)ve->type;
dinteger_t dim = ts->dim->toInteger();
if (index < 0 || index >= dim)
error("array index %jd is out of bounds [0..%jd]", index, dim);
error("array index %lld is out of bounds [0..%lld]", index, dim);
e = new SymOffExp(loc, ve->var, index * ts->nextOf()->size());
e->type = type;
return e;
@@ -633,7 +633,7 @@ Expression *CastExp::optimize(int result)
}
// We can convert 'head const' to mutable
if (to->constOf()->equals(e1->type->constOf()))
if (to->mutableOf()->constOf()->equals(e1->type->mutableOf()->constOf()))
{
e1->type = type;
if (X) printf(" returning5 %s\n", e1->toChars());
@@ -679,7 +679,7 @@ Expression *BinExp::optimize(int result)
dinteger_t i2 = e2->toInteger();
d_uns64 sz = e1->type->size() * 8;
if (i2 < 0 || i2 >= sz)
{ error("shift assign by %jd is outside the range 0..%zu", i2, sz - 1);
{ error("shift assign by %lld is outside the range 0..%llu", i2, (ulonglong)sz - 1);
e2 = new IntegerExp(0);
}
}
@@ -774,7 +774,7 @@ Expression *shift_optimize(int result, BinExp *e, Expression *(*shift)(Type *, E
dinteger_t i2 = e->e2->toInteger();
d_uns64 sz = e->e1->type->size() * 8;
if (i2 < 0 || i2 >= sz)
{ e->error("shift by %jd is outside the range 0..%zu", i2, sz - 1);
{ e->error("shift by %lld is outside the range 0..%llu", i2, (ulonglong)sz - 1);
e->e2 = new IntegerExp(0);
}
if (e->e1->isConst() == 1)
@@ -863,7 +863,7 @@ Expression *PowExp::optimize(int result)
if (e1->type->isintegral())
e = new IntegerExp(loc, 1, e1->type);
else
e = new RealExp(loc, 1.0, e1->type);
e = new RealExp(loc, ldouble(1.0), e1->type);
e = new CommaExp(loc, e1, e);
}
@@ -876,7 +876,7 @@ Expression *PowExp::optimize(int result)
// Replace x ^^ -1.0 by (1.0 / x)
else if ((e2->op == TOKfloat64 && e2->toReal() == -1.0))
{
e = new DivExp(loc, new RealExp(loc, 1.0, e2->type), e1);
e = new DivExp(loc, new RealExp(loc, ldouble(1.0), e2->type), e1);
}
// All other negative integral powers are illegal
else if ((e1->type->isintegral()) && (e2->op == TOKint64) && (sinteger_t)e2->toInteger() < 0)
+24 -10
View File
@@ -130,7 +130,7 @@ Dsymbols *Parser::parseModule()
decldefs = parseDeclDefs(0);
if (token.value != TOKeof)
{ error("unrecognized declaration");
{ error(loc, "unrecognized declaration");
goto Lerr;
}
return decldefs;
@@ -1377,8 +1377,15 @@ Parameters *Parser::parseParameters(int *pvarargs, TemplateParameters **tpl)
error("scope cannot be ref or out");
Token *t;
#if 0
if (tpl && !stc && token.value == TOKidentifier &&
(t = peek(&token), (t->value == TOKcomma || t->value == TOKrparen)))
#else
if (tpl && token.value == TOKidentifier &&
(t = peek(&token), (t->value == TOKcomma ||
t->value == TOKrparen ||
t->value == TOKdotdotdot)))
#endif
{ Identifier *id = Lexer::uniqueId("__T");
at = new TypeIdentifier(loc, id);
if (!*tpl)
@@ -3561,6 +3568,9 @@ Statement *Parser::parseStatement(int flags)
goto Ldeclaration;
case BASIC_TYPES:
// bug 7773: int.max is always a part of expression
if (peekNext() == TOKdot)
goto Lexp;
case TOKtypedef:
case TOKalias:
case TOKconst:
@@ -5472,15 +5482,18 @@ Expression *Parser::parsePrimaryExp()
}
case TOKlparen:
{ enum TOK past = peekPastParen(&token)->value;
if (past == TOKgoesto)
{ // (arguments) => expression
goto case_delegate;
}
else if (past == TOKlcurly)
{ // (arguments) { statements... }
goto case_delegate;
{ Token *tk = peekPastParen(&token);
if (skipAttributes(tk, &tk))
{
enum TOK past = tk->value;
if (past == TOKgoesto)
{ // (arguments) => expression
goto case_delegate;
}
else if (past == TOKlcurly)
{ // (arguments) { statements... }
goto case_delegate;
}
}
// ( expression )
nextToken();
@@ -6589,6 +6602,7 @@ void initPrecedence()
precedence[TOKtraits] = PREC_primary;
precedence[TOKdefault] = PREC_primary;
precedence[TOKoverloadset] = PREC_primary;
precedence[TOKvoid] = PREC_primary;
#endif
// post
+5 -4
View File
@@ -57,11 +57,11 @@ CC=$(HOST_CC) -m$(MODEL) $(TARGET_CFLAGS)
WARNINGS=-Wno-deprecated -Wstrict-aliasing
#GFLAGS = $(WARNINGS) -D__near= -D__pascal= -fno-exceptions -g -DDEBUG=1 -DUNITTEST $(COV)
GFLAGS = $(WARNINGS) -D__near= -D__pascal= -fno-exceptions -O2
#GFLAGS = $(WARNINGS) -D__pascal= -fno-exceptions -g -DDEBUG=1 -DUNITTEST $(COV)
GFLAGS = $(WARNINGS) -D__pascal= -fno-exceptions -O2
CFLAGS = $(GFLAGS) -I$(ROOT) -DMARS=1 -DTARGET_$(TARGET)=1
MFLAGS = $(GFLAGS) -I$C -I$(TK) -DMARS=1 -DTARGET_$(TARGET)=1
MFLAGS = $(GFLAGS) -I$C -I$(TK) -I$(ROOT) -DMARS=1 -DTARGET_$(TARGET)=1
CH= $C/cc.h $C/global.h $C/oper.h $C/code.h $C/type.h \
$C/dt.h $C/cgcv.h $C/el.h $C/iasm.h
@@ -137,6 +137,7 @@ SRC = win32.mak posix.mak \
$(ROOT)/stringtable.h $(ROOT)/stringtable.c \
$(ROOT)/response.c $(ROOT)/async.h $(ROOT)/async.c \
$(ROOT)/aav.h $(ROOT)/aav.c \
$(ROOT)/longdouble.h $(ROOT)/longdouble.c \
$(ROOT)/speller.h $(ROOT)/speller.c
@@ -528,7 +529,7 @@ stringtable.o: $(ROOT)/stringtable.c
$(CC) -c $(GFLAGS) -I$(ROOT) $<
strtold.o: $C/strtold.c
gcc -m$(MODEL) -c $<
gcc -m$(MODEL) -I$(ROOT) -c $<
struct.o: struct.c
$(CC) -c $(CFLAGS) $<
+2 -2
View File
@@ -152,10 +152,10 @@ typedef char dchar;
struct Dchar
{
static dchar *inc(dchar *p) { return p + 1; }
static dchar *dec(dchar *pstart, dchar *p) { return p - 1; }
static dchar *dec(dchar *pstart, dchar *p) { (void)pstart; return p - 1; }
static int len(const dchar *p) { return strlen(p); }
static int get(dchar *p) { return *p & 0xFF; }
static int getprev(dchar *pstart, dchar *p) { return p[-1] & 0xFF; }
static int getprev(dchar *pstart, dchar *p) { (void)pstart; return p[-1] & 0xFF; }
static dchar *put(dchar *p, unsigned c) { *p = c; return p + 1; }
static int cmp(dchar *s1, dchar *s2) { return strcmp(s1, s2); }
static int memcmp(const dchar *s1, const dchar *s2, int nchars) { return ::memcmp(s1, s2, nchars); }
+636
View File
@@ -0,0 +1,636 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2011 by Digital Mars
// All Rights Reserved
// written by Rainer Schuetze
// 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.
// 80 bit floating point value implementation for Microsoft compiler
#if _MSC_VER
#include "longdouble.h"
#include "assert.h"
#include <float.h>
#include <stdio.h>
#include <string.h>
extern "C"
{
// implemented in ldfpu.asm for _WIN64
int ld_initfpu(int bits, int mask);
void ld_expl(longdouble* ld, int exp);
longdouble ld_add(longdouble ld1, longdouble ld2);
longdouble ld_sub(longdouble ld1, longdouble ld2);
longdouble ld_mul(longdouble ld1, longdouble ld2);
longdouble ld_div(longdouble ld1, longdouble ld2);
longdouble ld_mod(longdouble ld1, longdouble ld2);
bool ld_cmpb(longdouble ld1, longdouble ld2);
bool ld_cmpbe(longdouble ld1, longdouble ld2);
bool ld_cmpa(longdouble ld1, longdouble ld2);
bool ld_cmpae(longdouble ld1, longdouble ld2);
bool ld_cmpe(longdouble ld1, longdouble ld2);
bool ld_cmpne(longdouble ld1, longdouble ld2);
longdouble ld_sqrt(longdouble ld1);
longdouble ld_sin(longdouble ld1);
longdouble ld_cos(longdouble ld1);
longdouble ld_tan(longdouble ld1);
}
bool initFPU()
{
#ifdef _WIN64
// int old_cw = ld_initfpu(_RC_NEAR);
int old_cw = ld_initfpu(0x300 /*_PC_64 | _RC_NEAR*/, // #defines NOT identical to CPU FPU control word!
0xF00 /*_MCW_PC | _MCW_RC*/);
#else
int old_cw = _control87(_MCW_EM | _PC_64 | _RC_NEAR,
_MCW_EM | _MCW_PC | _MCW_RC);
#endif
return true;
}
static bool doInitFPU = initFPU();
#ifndef _WIN64
extern "C"
{
double ld_read(const longdouble* pthis)
{
double res;
__asm
{
mov eax, pthis
fld tbyte ptr [eax]
fstp res
}
return res;
}
long long ld_readll(const longdouble* pthis)
{
#if 1
return ld_readull(pthis);
#elif defined _WIN64
return ld_readll(this);
#else
longdouble* pthis = this;
long long res;
__asm
{
mov eax, pthis
fld tbyte ptr [eax]
fistp qword ptr res
}
return res;
#endif
}
unsigned long long ld_readull(const longdouble* pthis)
{
#if 1
// somehow the FPU does not respect the CHOP mode of the rounding control
// in 64-bit mode
// so we roll our own conversion (it also allows the usual C wrap-around
// instead of the "invalid value" created by the FPU)
int expo = pthis->exponent - 0x3fff;
unsigned long long u;
if(expo < 0 || expo > 127)
return 0;
if(expo < 64)
u = pthis->mantissa >> (63 - expo);
else
u = pthis->mantissa << (expo - 63);
if(pthis->sign)
u = ~u + 1;
return u;
#else
longdouble* pthis = this;
long long res; // cannot use unsigned, VC will not generate "fistp qword"
longdouble twoPow63 = { 1ULL << 63, 0x3fff + 63, 0 };
__asm
{
mov eax, pthis
fld tbyte ptr [eax]
fld tbyte ptr twoPow63
fsubp ST(1),ST(0) // move it into signed range
lea eax, res
fistp qword ptr [eax]
}
res ^= (1LL << 63);
return res;
#endif
}
void ld_set(longdouble* pthis, double d)
{
__asm
{
mov eax, pthis
fld d
fstp tbyte ptr [eax]
}
}
void ld_setll(longdouble* pthis, long long d)
{
__asm
{
fild qword ptr d
mov eax, pthis
fstp tbyte ptr [eax]
}
}
void ld_setull(longdouble* pthis, unsigned long long d)
{
d ^= (1LL << 63);
longdouble twoPow63 = { 1ULL << 63, 0x3fff + 63, 0 };
__asm
{
fild qword ptr d
fld tbyte ptr twoPow63
faddp ST(1),ST(0)
mov eax, pthis
fstp tbyte ptr [eax]
}
}
} // extern "C"
#endif // !_WIN64
longdouble ldexpl(longdouble ld, int exp)
{
#ifdef _WIN64
ld_expl(&ld, exp);
#else
__asm
{
fild dword ptr exp
fld tbyte ptr ld
fscale // ST(0) = ST(0) * (2**ST(1))
fstp ST(1)
fstp tbyte ptr ld
}
#endif
return ld;
}
///////////////////////////////////////////////////////////////////////
longdouble operator+(longdouble ld1, longdouble ld2)
{
#ifdef _WIN64
return ld_add(ld1, ld2);
#else
longdouble res;
__asm
{
fld tbyte ptr ld1
fld tbyte ptr ld2
fadd
fstp tbyte ptr res;
}
return res;
#endif
}
longdouble operator-(longdouble ld1, longdouble ld2)
{
#ifdef _WIN64
return ld_sub(ld1, ld2);
#else
longdouble res;
__asm
{
fld tbyte ptr ld1
fld tbyte ptr ld2
fsub
fstp tbyte ptr res;
}
return res;
#endif
}
longdouble operator*(longdouble ld1, longdouble ld2)
{
#ifdef _WIN64
return ld_mul(ld1, ld2);
#else
longdouble res;
__asm
{
fld tbyte ptr ld1
fld tbyte ptr ld2
fmul
fstp tbyte ptr res;
}
return res;
#endif
}
longdouble operator/(longdouble ld1, longdouble ld2)
{
#ifdef _WIN64
return ld_div(ld1, ld2);
#else
longdouble res;
__asm
{
fld tbyte ptr ld1
fld tbyte ptr ld2
fdiv
fstp tbyte ptr res;
}
return res;
#endif
}
bool operator< (longdouble x, longdouble y)
{
#ifdef _WIN64
return ld_cmpb(x, y);
#else
short sw;
bool res;
__asm
{
fld tbyte ptr y
fld tbyte ptr x // ST = x, ST1 = y
fucomip ST(0),ST(1)
setb AL
setnp AH
and AL,AH
mov res,AL
fstp ST(0)
}
return res;
#endif
}
bool operator<=(longdouble x, longdouble y)
{
#ifdef _WIN64
return ld_cmpbe(x, y);
#else
short sw;
bool res;
__asm
{
fld tbyte ptr y
fld tbyte ptr x // ST = x, ST1 = y
fucomip ST(0),ST(1)
setbe AL
setnp AH
and AL,AH
mov res,AL
fstp ST(0)
}
return res;
#endif
}
bool operator> (longdouble x, longdouble y)
{
#ifdef _WIN64
return ld_cmpa(x, y);
#else
short sw;
bool res;
__asm
{
fld tbyte ptr y
fld tbyte ptr x // ST = x, ST1 = y
fucomip ST(0),ST(1)
seta AL
setnp AH
and AL,AH
mov res,AL
fstp ST(0)
}
return res;
#endif
}
bool operator>=(longdouble x, longdouble y)
{
#ifdef _WIN64
return ld_cmpae(x, y);
#else
short sw;
bool res;
__asm
{
fld tbyte ptr y
fld tbyte ptr x // ST = x, ST1 = y
fucomip ST(0),ST(1)
setae AL
setnp AH
and AL,AH
mov res,AL
fstp ST(0)
}
return res;
#endif
}
bool operator==(longdouble x, longdouble y)
{
#ifdef _WIN64
return ld_cmpe(x, y);
#else
short sw;
bool res;
__asm
{
fld tbyte ptr y
fld tbyte ptr x // ST = x, ST1 = y
fucomip ST(0),ST(1)
sete AL
setnp AH
and AL,AH
mov res,AL
fstp ST(0)
}
return res;
#endif
}
bool operator!=(longdouble x, longdouble y)
{
#ifdef _WIN64
return ld_cmpne(x, y);
#else
short sw;
bool res;
__asm
{
fld tbyte ptr y
fld tbyte ptr x // ST = x, ST1 = y
fucomip ST(0),ST(1)
setne AL
setp AH
or AL,AH
mov res,AL
fstp ST(0)
}
return res;
#endif
}
int _isnan(longdouble ld)
{
return (ld.exponent == 0x7fff && ld.mantissa != 0);
}
longdouble fabsl(longdouble ld)
{
ld.sign = 0;
return ld;
}
longdouble sqrtl(longdouble ld)
{
#ifdef _WIN64
return ld_sqrt(ld);
#else
longdouble res;
__asm
{
fld tbyte ptr ld;
fsqrt;
fstp tbyte ptr res;
}
return res;
#endif
}
longdouble sinl (longdouble ld)
{
#ifdef _WIN64
return ld_sin(ld);
#else
longdouble res;
__asm
{
fld tbyte ptr ld;
fsin; // exact for |x|<=PI/4
fstp tbyte ptr res
}
return res;
#endif
}
longdouble cosl (longdouble ld)
{
#ifdef _WIN64
return ld_cos(ld);
#else
longdouble res;
__asm
{
fld tbyte ptr ld;
fcos; // exact for |x|<=PI/4
fstp tbyte ptr res;
}
return res;
#endif
}
longdouble tanl (longdouble ld)
{
#ifdef _WIN64
return ld_tan(ld);
#else
longdouble res;
__asm
{
fld tbyte ptr ld;
fptan;
fstp ST(0); // always 1
fstp tbyte ptr res;
}
return res;
#endif
}
longdouble fmodl(longdouble x, longdouble y)
{
#ifdef _WIN64
return ld_mod(x, y);
#else
short sw;
longdouble res;
__asm
{
fld tbyte ptr y
fld tbyte ptr x // ST = x, ST1 = y
FM1: // We don't use fprem1 because for some inexplicable
// reason we get -5 when we do _modulo(15, 10)
fprem // ST = ST % ST1
fstsw word ptr sw
fwait
mov AH,byte ptr sw+1 // get msb of status word in AH
sahf // transfer to flags
jp FM1 // continue till ST < ST1
fstp ST(1) // leave remainder on stack
fstp tbyte ptr res;
}
return res;
#endif
}
//////////////////////////////////////////////////////////////
longdouble ld_qnan = { 0x8000000000000000ULL, 0x7fff, 0 };
longdouble ld_snan = { 0x0000000000000001ULL, 0x7fff, 0 };
longdouble ld_inf = { 0x0000000000000000ULL, 0x7fff, 0 };
longdouble ld_zero = { 0, 0, 0 };
longdouble ld_one = { 0x8000000000000000ULL, 0x3fff, 0 };
longdouble ld_pi = { 0xc90fdaa22168c235ULL, 0x4000, 0 };
longdouble ld_log2t = { 0xd49a784bcd1b8afeULL, 0x4000, 0 };
longdouble ld_log2e = { 0xb8aa3b295c17f0bcULL, 0x3fff, 0 };
longdouble ld_log2 = { 0x9a209a84fbcff799ULL, 0x3ffd, 0 };
longdouble ld_ln2 = { 0xb17217f7d1cf79acULL, 0x3ffe, 0 };
longdouble ld_pi2 = ld_pi*2;
longdouble ld_piOver2 = ld_pi*0.5;
longdouble ld_piOver4 = ld_pi*0.25;
//////////////////////////////////////////////////////////////
#define LD_TYPE_OTHER 0
#define LD_TYPE_ZERO 1
#define LD_TYPE_INFINITE 2
#define LD_TYPE_SNAN 3
#define LD_TYPE_QNAN 4
int ld_type(longdouble x)
{
if(x.exponent == 0)
return x.mantissa == 0 ? LD_TYPE_ZERO : LD_TYPE_OTHER; // dnormal if not zero
if(x.exponent != 0x7fff)
return LD_TYPE_OTHER;
if(x.mantissa == 0)
return LD_TYPE_INFINITE;
if(x.mantissa & (1LL << 63))
return LD_TYPE_QNAN;
return LD_TYPE_SNAN;
}
int ld_sprint(char* str, int fmt, longdouble x)
{
// fmt is 'a','A','f' or 'g'
if(fmt != 'a' && fmt != 'A')
{
char format[] = { '%', fmt, 0 };
return sprintf(str, format, ld_read(&x));
}
unsigned short exp = x.exponent;
unsigned long long mantissa = x.mantissa;
switch(ld_type(x))
{
case LD_TYPE_ZERO:
return sprintf(str, "0x0.0L");
case LD_TYPE_QNAN:
case LD_TYPE_SNAN:
return sprintf(str, "NAN");
case LD_TYPE_INFINITE:
return sprintf(str, x.sign ? "-INF" : "INF");
}
int len = 0;
if(x.sign)
str[len++] = '-';
len += sprintf(str + len, mantissa & (1LL << 63) ? "0x1." : "0x0.");
mantissa = mantissa << 1;
while(mantissa)
{
int dig = (mantissa >> 60) & 0xf;
dig += dig < 10 ? '0' : fmt - 10;
str[len++] = dig;
mantissa = mantissa << 4;
}
str[len++] = 'p';
if(exp < 0x3fff)
{
str[len++] = '-';
exp = 0x3fff - exp;
}
else
{
str[len++] = '+';
exp = exp - 0x3fff;
}
int exppos = len;
for(int i = 12; i >= 0; i -= 4)
{
int dig = (exp >> i) & 0xf;
if(dig != 0 || len > exppos || i == 0)
str[len++] = dig + (dig < 10 ? '0' : fmt - 10);
}
str[len] = 0;
return len;
}
//////////////////////////////////////////////////////////////
#if UNITTEST
static bool unittest()
{
char buffer[32];
ld_sprint(buffer, 'a', ld_pi);
assert(strcmp(buffer, "0x1.921fb54442d1846ap+1") == 0);
longdouble ldb = ldouble(0.4);
long long b = ldb;
assert(b == 0);
b = ldouble(0.9);
assert(b == 0);
long long x = 0x12345678abcdef78LL;
longdouble ldx = ldouble(x);
assert(ldx > 0);
long long y = ldx;
assert(x == y);
x = -0x12345678abcdef78LL;
ldx = ldouble(x);
assert(ldx < 0);
y = ldx;
assert(x == y);
unsigned long long u = 0x12345678abcdef78LL;
longdouble ldu = ldouble(u);
assert(ldu > 0);
unsigned long long v = ldu;
assert(u == v);
u = 0xf234567812345678ULL;
ldu = ldouble(u);
assert(ldu > 0);
v = ldu;
assert(u == v);
u = 0xf2345678;
ldu = ldouble(u);
ldu = ldu * ldu;
ldu = sqrt(ldu);
v = ldu;
assert(u == v);
u = 0x123456789A;
ldu = ldouble(u);
ldu = ldu * (1LL << 23);
v = ldu;
u = u * (1LL << 23);
assert(u == v);
return true;
}
static bool runUnittest = unittest();
#endif // UNITTEST
#endif // _MSC_VER
+254
View File
@@ -0,0 +1,254 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2011 by Digital Mars
// All Rights Reserved
// written by Rainer Schuetze
// 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.
// 80 bit floating point value implementation for Microsoft compiler
#ifndef __LONG_DOUBLE_H__
#define __LONG_DOUBLE_H__
#if IN_GCC
#include "d-gcc-real.h"
typedef real_t longdouble;
template<typename T> longdouble ldouble(T x) { return (longdouble) x; }
inline int ld_sprint(char* str, int fmt, longdouble x)
{
if(fmt == 'a' || fmt == 'A')
return x.formatHex(buffer, 46); // don't know the size here, but 46 is the max
return x.format(buffer, 46);
}
#elif !_MSC_VER // has native 10 byte doubles
#include <stdio.h>
typedef long double longdouble;
typedef volatile long double volatile_longdouble;
// also used from within C code, so use a #define rather than a template
// template<typename T> longdouble ldouble(T x) { return (longdouble) x; }
#define ldouble(x) ((longdouble)(x))
inline int ld_sprint(char* str, int fmt, longdouble x)
{
char sfmt[4] = "%Lg";
sfmt[2] = fmt;
return sprintf(str, sfmt, x);
}
#else
#include <float.h>
#include <limits>
struct longdouble;
extern "C"
{
// implemented in ldfpu.asm for _WIN64
double ld_read(const longdouble* ld);
long long ld_readll(const longdouble* ld);
unsigned long long ld_readull(const longdouble* ld);
void ld_set(longdouble* ld, double d);
void ld_setll(longdouble* ld, long long d);
void ld_setull(longdouble* ld, unsigned long long d);
}
struct longdouble
{
unsigned long long mantissa;
unsigned short exponent:15; // bias 0x3fff
unsigned short sign:1;
unsigned short fill:16; // for 12 byte alignment
// no constructor to be able to use this class in a union
// use ldouble() to explicitely create a longdouble value
template<typename T> longdouble& operator=(T x) { set(x); return *this; }
void set(longdouble ld) { mantissa = ld.mantissa; exponent = ld.exponent; sign = ld.sign; }
// we need to list all basic types to avoid ambiguities
void set(float d) { ld_set(this, d); }
void set(double d) { ld_set(this, d); }
void set(long double d) { ld_set(this, d); }
void set(signed char d) { ld_set(this, d); }
void set(short d) { ld_set(this, d); }
void set(int d) { ld_set(this, d); }
void set(long d) { ld_set(this, d); }
void set(long long d) { ld_setll(this, d); }
void set(unsigned char d) { ld_set(this, d); }
void set(unsigned short d) { ld_set(this, d); }
void set(unsigned int d) { ld_set(this, d); }
void set(unsigned long d) { ld_set(this, d); }
void set(unsigned long long d) { ld_setull(this, d); }
void set(bool d) { ld_set(this, d); }
operator float () { return ld_read(this); }
operator double () { return ld_read(this); }
operator signed char () { return ld_read(this); }
operator short () { return ld_read(this); }
operator int () { return ld_read(this); }
operator long () { return ld_read(this); }
operator long long () { return ld_readll(this); }
operator unsigned char () { return ld_read(this); }
operator unsigned short () { return ld_read(this); }
operator unsigned int () { return ld_read(this); }
operator unsigned long () { return ld_read(this); }
operator unsigned long long() { return ld_readull(this); }
operator bool () { return mantissa != 0 || exponent != 0; } // correct?
};
// some optimizations are avoided by adding volatile to the longdouble
// type, but this introduces bad ambiguities when using the class implementation above
// as we are going through asm these optimizations won't kick in anyway, so "volatile"
// is not required.
typedef longdouble volatile_longdouble;
inline longdouble ldouble(unsigned long long mantissa, int exp, int sign = 0)
{
longdouble d;
d.mantissa = mantissa;
d.exponent = exp;
d.sign = sign;
return d;
}
template<typename T> inline longdouble ldouble(T x) { longdouble d; d.set(x); return d; }
//template<typename T> inline longdouble ldouble(volatile T x) { longdouble d; d.set(x); return d; }
longdouble operator+(longdouble ld1, longdouble ld2);
longdouble operator-(longdouble ld1, longdouble ld2);
longdouble operator*(longdouble ld1, longdouble ld2);
longdouble operator/(longdouble ld1, longdouble ld2);
bool operator< (longdouble ld1, longdouble ld2);
bool operator<=(longdouble ld1, longdouble ld2);
bool operator> (longdouble ld1, longdouble ld2);
bool operator>=(longdouble ld1, longdouble ld2);
bool operator==(longdouble ld1, longdouble ld2);
bool operator!=(longdouble ld1, longdouble ld2);
inline longdouble operator-(longdouble ld1) { ld1.sign ^= 1; return ld1; }
inline longdouble operator+(longdouble ld1) { return ld1; }
template<typename T> inline longdouble operator+(longdouble ld, T x) { return ld + ldouble(x); }
template<typename T> inline longdouble operator-(longdouble ld, T x) { return ld - ldouble(x); }
template<typename T> inline longdouble operator*(longdouble ld, T x) { return ld * ldouble(x); }
template<typename T> inline longdouble operator/(longdouble ld, T x) { return ld / ldouble(x); }
template<typename T> inline longdouble operator+(T x, longdouble ld) { return ldouble(x) + ld; }
template<typename T> inline longdouble operator-(T x, longdouble ld) { return ldouble(x) - ld; }
template<typename T> inline longdouble operator*(T x, longdouble ld) { return ldouble(x) * ld; }
template<typename T> inline longdouble operator/(T x, longdouble ld) { return ldouble(x) / ld; }
template<typename T> inline longdouble& operator+=(longdouble& ld, T x) { return ld = ld + x; }
template<typename T> inline longdouble& operator-=(longdouble& ld, T x) { return ld = ld - x; }
template<typename T> inline longdouble& operator*=(longdouble& ld, T x) { return ld = ld * x; }
template<typename T> inline longdouble& operator/=(longdouble& ld, T x) { return ld = ld / x; }
template<typename T> inline bool operator< (longdouble ld, T x) { return ld < ldouble(x); }
template<typename T> inline bool operator<=(longdouble ld, T x) { return ld <= ldouble(x); }
template<typename T> inline bool operator> (longdouble ld, T x) { return ld > ldouble(x); }
template<typename T> inline bool operator>=(longdouble ld, T x) { return ld >= ldouble(x); }
template<typename T> inline bool operator==(longdouble ld, T x) { return ld == ldouble(x); }
template<typename T> inline bool operator!=(longdouble ld, T x) { return ld != ldouble(x); }
template<typename T> inline bool operator< (T x, longdouble ld) { return ldouble(x) < ld; }
template<typename T> inline bool operator<=(T x, longdouble ld) { return ldouble(x) <= ld; }
template<typename T> inline bool operator> (T x, longdouble ld) { return ldouble(x) > ld; }
template<typename T> inline bool operator>=(T x, longdouble ld) { return ldouble(x) >= ld; }
template<typename T> inline bool operator==(T x, longdouble ld) { return ldouble(x) == ld; }
template<typename T> inline bool operator!=(T x, longdouble ld) { return ldouble(x) != ld; }
int _isnan(longdouble ld);
longdouble fabsl(longdouble ld);
longdouble sqrtl(longdouble ld);
longdouble sinl (longdouble ld);
longdouble cosl (longdouble ld);
longdouble tanl (longdouble ld);
longdouble fmodl(longdouble x, longdouble y);
longdouble ldexpl(longdouble ldval, int exp); // see strtold
inline longdouble fabs (longdouble ld) { return fabsl(ld); }
inline longdouble sqrt (longdouble ld) { return sqrtl(ld); }
#undef LDBL_DIG
#undef LDBL_MAX
#undef LDBL_MIN
#undef LDBL_EPSILON
#undef LDBL_MANT_DIG
#undef LDBL_MAX_EXP
#undef LDBL_MIN_EXP
#undef LDBL_MAX_10_EXP
#undef LDBL_MIN_10_EXP
#define LDBL_DIG 18
#define LDBL_MAX ldouble(0xffffffffffffffffULL, 0x7ffe)
#define LDBL_MIN ldouble(0x8000000000000000ULL, 1)
#define LDBL_EPSILON ldouble(0x8000000000000000ULL, 0x3fff - 63) // allow denormal?
#define LDBL_MANT_DIG 64
#define LDBL_MAX_EXP 16384
#define LDBL_MIN_EXP (-16381)
#define LDBL_MAX_10_EXP 4932
#define LDBL_MIN_10_EXP (-4932)
extern longdouble ld_zero;
extern longdouble ld_one;
extern longdouble ld_pi;
extern longdouble ld_log2t;
extern longdouble ld_log2e;
extern longdouble ld_log2;
extern longdouble ld_ln2;
extern longdouble ld_inf;
extern longdouble ld_qnan;
extern longdouble ld_snan;
///////////////////////////////////////////////////////////////////////
// CLASS numeric_limits<longdouble>
template<> class _CRTIMP2_PURE std::numeric_limits<longdouble>
: public _Num_float_base
{ // limits for type long double
public:
typedef longdouble _Ty;
static _Ty (__CRTDECL min)() _THROW0() { return LDBL_MIN; }
static _Ty (__CRTDECL max)() _THROW0() { return LDBL_MAX; }
static _Ty __CRTDECL epsilon() _THROW0() { return LDBL_EPSILON; }
static _Ty __CRTDECL round_error() _THROW0() { return ldouble(0.5); }
static _Ty __CRTDECL denorm_min() _THROW0() { return ldouble(0x0000000000000001ULL, 1); }
static _Ty __CRTDECL infinity() _THROW0() { return ld_inf; }
static _Ty __CRTDECL quiet_NaN() _THROW0() { return ld_qnan; }
static _Ty __CRTDECL signaling_NaN() _THROW0() { return ld_snan; }
_STCONS(int, digits, LDBL_MANT_DIG);
_STCONS(int, digits10, LDBL_DIG);
_STCONS(int, max_exponent, (int)LDBL_MAX_EXP);
_STCONS(int, max_exponent10, (int)LDBL_MAX_10_EXP);
_STCONS(int, min_exponent, (int)LDBL_MIN_EXP);
_STCONS(int, min_exponent10, (int)LDBL_MIN_10_EXP);
};
//_STCONSDEF(numeric_limits<longdouble>, int, digits)
//_STCONSDEF(numeric_limits<longdouble>, int, digits10)
//_STCONSDEF(numeric_limits<longdouble>, int, max_exponent)
//_STCONSDEF(numeric_limits<longdouble>, int, max_exponent10)
//_STCONSDEF(numeric_limits<longdouble>, int, min_exponent)
//_STCONSDEF(numeric_limits<longdouble>, int, min_exponent10)
int ld_sprint(char* str, int fmt, longdouble x);
#endif // !_MSC_VER
#endif // __LONG_DOUBLE_H__
+2
View File
@@ -19,8 +19,10 @@ struct Lstring
{
unsigned length;
#ifndef IN_GCC
// Disable warning about nonstandard extension
#pragma warning (disable : 4200)
#endif
dchar string[];
static Lstring zero; // 0 length string
+19 -160
View File
@@ -17,14 +17,14 @@ double Port::nan = NAN;
double Port::infinity = INFINITY;
double Port::dbl_max = DBL_MAX;
double Port::dbl_min = DBL_MIN;
long double Port::ldbl_max = LDBL_MAX;
longdouble Port::ldbl_max = LDBL_MAX;
int Port::isNan(double r)
{
return ::isnan(r);
}
int Port::isNan(long double r)
int Port::isNan(longdouble r)
{
return ::isnan(r);
}
@@ -37,7 +37,7 @@ int Port::isSignallingNan(double r)
return isNan(r) && !((((unsigned char*)&r)[6]) & 8);
}
int Port::isSignallingNan(long double r)
int Port::isSignallingNan(longdouble r)
{
/* A signalling NaN is a NaN with 0 as the most significant bit of
* its significand, which is bit 62 of 0..79 for 80 bit reals.
@@ -70,7 +70,7 @@ double Port::pow(double x, double y)
return ::pow(x, y);
}
long double Port::fmodl(long double x, long double y)
longdouble Port::fmodl(longdouble x, longdouble y)
{
return ::fmodl(x, y);
}
@@ -140,7 +140,7 @@ double Port::infinity = 1 / zero;
double Port::dbl_max = DBL_MAX;
double Port::dbl_min = DBL_MIN;
long double Port::ldbl_max = LDBL_MAX;
longdouble Port::ldbl_max = LDBL_MAX;
struct PortInitializer
{
@@ -151,7 +151,7 @@ static PortInitializer portinitializer;
PortInitializer::PortInitializer()
{
Port::infinity = std::numeric_limits<long double>::infinity();
Port::infinity = std::numeric_limits<double>::infinity();
}
int Port::isNan(double r)
@@ -159,7 +159,7 @@ int Port::isNan(double r)
return ::_isnan(r);
}
int Port::isNan(long double r)
int Port::isNan(longdouble r)
{
return ::_isnan(r);
}
@@ -172,7 +172,7 @@ int Port::isSignallingNan(double r)
return isNan(r) && !((((unsigned char*)&r)[6]) & 8);
}
int Port::isSignallingNan(long double r)
int Port::isSignallingNan(longdouble r)
{
/* MSVC doesn't have 80 bit long doubles
*/
@@ -206,7 +206,7 @@ double Port::pow(double x, double y)
return ::pow(x, y);
}
long double Port::fmodl(long double x, long double y)
longdouble Port::fmodl(longdouble x, longdouble y)
{
return ::fmodl(x, y);
}
@@ -351,7 +351,7 @@ double Port::nan = copysign(NAN, 1.0);
double Port::infinity = 1 / zero;
double Port::dbl_max = 1.7976931348623157e308;
double Port::dbl_min = 5e-324;
long double Port::ldbl_max = LDBL_MAX;
longdouble Port::ldbl_max = LDBL_MAX;
struct PortInitializer
{
@@ -366,9 +366,9 @@ PortInitializer::PortInitializer()
#if __FreeBSD__ && __i386__
// LDBL_MAX comes out as infinity. Fix.
static unsigned char x[sizeof(long double)] =
static unsigned char x[sizeof(longdouble)] =
{ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x7F };
Port::ldbl_max = *(long double *)&x[0];
Port::ldbl_max = *(longdouble *)&x[0];
// FreeBSD defaults to double precision. Switch to extended precision.
fpsetprec(FP_PE);
#endif
@@ -386,7 +386,7 @@ int Port::isNan(double r)
#endif
}
int Port::isNan(long double r)
int Port::isNan(longdouble r)
{
#if __APPLE__
return __inline_isnan(r);
@@ -406,7 +406,7 @@ int Port::isSignallingNan(double r)
return isNan(r) && !((((unsigned char*)&r)[6]) & 8);
}
int Port::isSignallingNan(long double r)
int Port::isSignallingNan(longdouble r)
{
/* A signalling NaN is a NaN with 0 as the most significant bit of
* its significand, which is bit 62 of 0..79 for 80 bit reals.
@@ -450,7 +450,7 @@ double Port::pow(double x, double y)
return ::pow(x, y);
}
long double Port::fmodl(long double x, long double y)
longdouble Port::fmodl(longdouble x, longdouble y)
{
#if __FreeBSD__ || __OpenBSD__
return ::fmod(x, y); // hack for now, fix later
@@ -528,7 +528,7 @@ double Port::nan = NAN;
double Port::infinity = 1 / zero;
double Port::dbl_max = 1.7976931348623157e308;
double Port::dbl_min = 5e-324;
long double Port::ldbl_max = LDBL_MAX;
longdouble Port::ldbl_max = LDBL_MAX;
struct PortInitializer
{
@@ -542,7 +542,7 @@ PortInitializer::PortInitializer()
// gcc nan's have the sign bit set by default, so turn it off
// Need the volatile to prevent gcc from doing incorrect
// constant folding.
volatile long double foo;
volatile longdouble foo;
foo = NAN;
if (signbit(foo)) // signbit sometimes, not always, set
foo = -foo; // turn off sign bit
@@ -554,7 +554,7 @@ int Port::isNan(double r)
return isnan(r);
}
int Port::isNan(long double r)
int Port::isNan(longdouble r)
{
return isnan(r);
}
@@ -567,7 +567,7 @@ int Port::isSignallingNan(double r)
return isNan(r) && !((((unsigned char*)&r)[6]) & 8);
}
int Port::isSignallingNan(long double r)
int Port::isSignallingNan(longdouble r)
{
/* A signalling NaN is a NaN with 0 as the most significant bit of
* its significand, which is bit 62 of 0..79 for 80 bit reals.
@@ -649,144 +649,3 @@ char *Port::strupr(char *s)
#endif
#if IN_GCC
#include <math.h>
#include <bits/nan.h>
#include <bits/mathdef.h>
#include <time.h>
#include <sys/time.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
static double zero = 0;
double Port::nan = NAN;
double Port::infinity = 1 / zero;
double Port::dbl_max = 1.7976931348623157e308;
double Port::dbl_min = 5e-324;
long double Port::ldbl_max = LDBL_MAX;
#include "d-gcc-real.h"
extern "C" bool real_isnan (const real_t *);
struct PortInitializer
{
PortInitializer();
};
static PortInitializer portinitializer;
PortInitializer::PortInitializer()
{
Port::infinity = real_t::getinfinity();
Port::nan = real_t::getnan(real_t::LongDouble);
}
#undef isnan
int Port::isNan(double r)
{
#if __APPLE__
return __inline_isnan(r);
#else
return ::isnan(r);
#endif
}
int Port::isNan(long double r)
{
return real_isnan(&r);
}
int Port::isSignallingNan(double r)
{
/* A signalling NaN is a NaN with 0 as the most significant bit of
* its significand, which is bit 51 of 0..63 for 64 bit doubles.
*/
return isNan(r) && !((((unsigned char*)&r)[6]) & 8);
}
int Port::isSignallingNan(long double r)
{
/* A signalling NaN is a NaN with 0 as the most significant bit of
* its significand, which is bit 62 of 0..79 for 80 bit reals.
*/
return isNan(r) && !((((unsigned char*)&r)[7]) & 0x40);
}
#undef isfinite
int Port::isFinite(double r)
{
return ::finite(r);
}
#undef isinf
int Port::isInfinity(double r)
{
return ::isinf(r);
}
#undef signbit
int Port::Signbit(double r)
{
return (long)(((long *)&r)[1] & 0x80000000);
}
double Port::floor(double d)
{
return ::floor(d);
}
double Port::pow(double x, double y)
{
return ::pow(x, y);
}
unsigned long long Port::strtoull(const char *p, char **pend, int base)
{
return ::strtoull(p, pend, base);
}
char *Port::ull_to_string(char *buffer, ulonglong ull)
{
sprintf(buffer, "%llu", ull);
return buffer;
}
wchar_t *Port::ull_to_string(wchar_t *buffer, ulonglong ull)
{
swprintf(buffer, L"%llu", ull);
return buffer;
}
double Port::ull_to_double(ulonglong ull)
{
return (double) ull;
}
const char *Port::list_separator()
{
return ",";
}
const wchar_t *Port::wlist_separator()
{
return L",";
}
char *Port::strupr(char *s)
{
char *t = s;
while (*s)
{
*s = toupper(*s);
s++;
}
return t;
}
#endif
+7 -5
View File
@@ -10,6 +10,8 @@
// Portable wrapper around compiler/system specific things.
// The idea is to minimize #ifdef's in the app code.
#include "longdouble.h"
#ifndef TYPEDEFS
#define TYPEDEFS
@@ -20,7 +22,7 @@ typedef __int64 longlong;
typedef unsigned __int64 ulonglong;
// According to VC 8.0 docs, long double is the same as double
#define strtold strtod
longdouble strtold(const char *p,char **endp);
#define strtof strtod
#else
@@ -38,7 +40,7 @@ struct Port
static double infinity;
static double dbl_max;
static double dbl_min;
static long double ldbl_max;
static longdouble ldbl_max;
#if __OpenBSD__
#elif __GNUC__
@@ -49,10 +51,10 @@ struct Port
#undef signbit
#endif
static int isNan(double);
static int isNan(long double);
static int isNan(longdouble);
static int isSignallingNan(double);
static int isSignallingNan(long double);
static int isSignallingNan(longdouble);
static int isFinite(double);
static int isInfinity(double);
@@ -61,7 +63,7 @@ struct Port
static double floor(double);
static double pow(double x, double y);
static long double fmodl(long double x, long double y);
static longdouble fmodl(longdouble x, longdouble y);
static ulonglong strtoull(const char *p, char **pend, int base);
+7
View File
@@ -29,6 +29,13 @@
#include <utime.h>
#endif
#if _MSC_VER
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <errno.h>
#endif
/*********************************
* #include <stdlib.h>
* int response_expand(int *pargc,char ***pargv);
+3 -3
View File
@@ -1527,7 +1527,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%zx off end of file",toChars(),offset);
error("Corrupt file '%s': offset x%llx off end of file",toChars(),(ulonglong)offset);
}
char *File::toChars()
@@ -1796,7 +1796,7 @@ void OutBuffer::align(unsigned size)
// The compiler shipped with Visual Studio 2005 (and possible
// other versions) does not support C99 printf format specfiers
// such as %z and %j
#if _MSC_VER
#if 0 && _MSC_VER
using std::string;
using std::wstring;
@@ -1815,7 +1815,7 @@ search_and_replace(S& str, const S& what, const S& replacement)
#define WORKAROUND_C99_SPECIFIERS_BUG(S,tmp,f) \
S tmp = f; \
search_and_replace(fmt, S("%z"), S("%l")); \
search_and_replace(fmt, S("%j"), S("%i")); \
search_and_replace(fmt, S("%j"), S("%l")); \
f = tmp.c_str();
#else
#define WORKAROUND_C99_SPECIFIERS_BUG(S,tmp,f)
+2 -4
View File
@@ -23,6 +23,7 @@
typedef size_t hash_t;
#include "longdouble.h"
#include "dchar.h"
char *wchar2ascii(wchar_t *);
@@ -32,9 +33,6 @@ int wcharIsAscii(wchar_t *, unsigned len);
int bstrcmp(unsigned char *s1, unsigned char *s2);
char *bstr2str(unsigned char *b);
void error(const char *format, ...);
void error(const wchar_t *format, ...);
void warning(const char *format, ...);
#ifndef TYPEDEFS
#define TYPEDEFS
@@ -43,7 +41,7 @@ void warning(const char *format, ...);
#include <float.h> // for _isnan
#include <malloc.h> // for alloca
// According to VC 8.0 docs, long double is the same as double
#define strtold strtod
longdouble strtold(const char *p,char **endp);
#define strtof strtod
#define isnan _isnan
+1 -1
View File
@@ -4,7 +4,7 @@
#include <stdlib.h>
#include <assert.h>
#if __sun&&__SVR4
#if __sun&&__SVR4 || _MSC_VER
#include <alloca.h>
#endif
+2 -2
View File
@@ -74,10 +74,10 @@ Scope::Scope()
this->noaccesscheck = 0;
this->mustsemantic = 0;
this->intypeof = 0;
this->speculative = 0;
this->parameterSpecialization = 0;
this->callSuper = 0;
this->flags = 0;
this->anonAgg = NULL;
this->lastdc = NULL;
this->lastoffset = 0;
this->docbuf = NULL;
@@ -122,10 +122,10 @@ Scope::Scope(Scope *enclosing)
this->noaccesscheck = enclosing->noaccesscheck;
this->mustsemantic = enclosing->mustsemantic;
this->intypeof = enclosing->intypeof;
this->speculative = enclosing->speculative;
this->parameterSpecialization = enclosing->parameterSpecialization;
this->callSuper = enclosing->callSuper;
this->flags = 0;
this->anonAgg = NULL;
this->lastdc = NULL;
this->lastoffset = 0;
this->docbuf = enclosing->docbuf;

Some files were not shown because too many files have changed in this diff Show More