mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-09-30 17:19:24 +02:00
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:
+15
-8
@@ -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
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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__
|
||||
|
||||
@@ -28,8 +28,6 @@
|
||||
#define __stdcall __attribute__ ((__stdcall__))
|
||||
|
||||
#define __pascal
|
||||
#define __near
|
||||
#define _near
|
||||
#define __far
|
||||
#define _far
|
||||
#define __ss
|
||||
|
||||
+12
-15
@@ -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
@@ -17,7 +17,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
#if __sun&&__SVR4
|
||||
#if __sun&&__SVR4 || _MSC_VER
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
|
||||
|
||||
+1
-16
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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)
|
||||
|
||||
@@ -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
@@ -17,7 +17,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
#if __sun&&__SVR4
|
||||
#if __sun&&__SVR4 || _MSC_VER
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
|
||||
|
||||
+6
-6
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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));
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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++;
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
/**********************************
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
File diff suppressed because it is too large
Load Diff
@@ -261,6 +261,9 @@ void Module::gendocfile()
|
||||
Macro::define(¯otable, (unsigned char *)"YEAR", 4, (unsigned char *)p + 20, 4);
|
||||
}
|
||||
|
||||
char *srcfilename = srcfile->toChars();
|
||||
Macro::define(¯otable, (unsigned char *)"SRCFILENAME", 11, (unsigned char *)srcfilename, strlen(srcfilename));
|
||||
|
||||
char *docfilename = docfile->toChars();
|
||||
Macro::define(¯otable, (unsigned char *)"DOCFILENAME", 11, (unsigned char *)docfilename, strlen(docfilename));
|
||||
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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 *) { }
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
File diff suppressed because it is too large
Load Diff
+29
-13
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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" },
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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++)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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(¶ms, 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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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); }
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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__
|
||||
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -4,7 +4,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#if __sun&&__SVR4
|
||||
#if __sun&&__SVR4 || _MSC_VER
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user