The changes regarding pretty names for generics and token buffer endianess were integrated into my changes. Not every call to generate_specialization is fixed though, so compilation will fail.
git-svn-id: branches/svenbarth/generics@19674 -
Conflicts:
compiler/pdecl.pas
compiler/pexpr.pas
compiler/pgenutil.pas
compiler/ptype.pas
The original log messages as git was a bit forgetting here :( (newest at the top):
commit 7ef252de8023494ee6d39910e289f9e31658d47b
Author: Sven Barth <pascaldragon@minerva>
Date: Mon Nov 21 17:13:36 2011 +0100
Fix the compilation of inline specializations of which the generic is derived from another generic.
pgenutil.pas, generate_specialization:
* Set the "block_type" to "bt_type" when parsing the type parameters, so that the nodes are returned as "ttypenode" instead of e.g. "tloadvmtaddrnode" in case of classes outside of type sections.
* Set the "block_type" to "bt_type" before calling "read_name_type", so that no unexpected sideeffects happen, because types like classes normally only are declared inside type sections (e.g. for the case a generic class is derived from another generic class a classrefdef for the specialized parent class will be created inside the derived specialized class if the block type is not a type one).
commit 1041a8f7a3a41f4fdf2975ce40055c698281ce71
Author: Sven Barth <pascaldragon@minerva>
Date: Fri Nov 18 19:03:50 2011 +0100
Improve inline specializations a bit, so now expressions like "TSomeGeneric<TSomeType>.SomeClassProc OP SomeNonGeneric" is possible. Using another class function of a generic as the right side is not yet working (that still needs some thinking).
To achive this the generalization code must basically continue directly after the "factor" call, so that the operator and the right side are correctly parsed when walking up the call stack. This is done by jumping from the end of the specialization code in the "<"-case to the start of "sub_expr". The freshly generated node (in the above example a callnode) will be passed down the callstack through a new parameter "factornode". If that is set (currently only in the case of a specialization on the left side) "factor" won't be called and the right side will be parsed with the "factornode" as the left side. If it is not set (which is the case for all other calls to "sub_expr" in the unit) then the usual call to "factor" will be done and the result will be used as the left side.
commit a01ccd265f8d6cc5a2f3e88e23afbcd3d5960afb
Author: Sven Barth <pascaldragon@minerva>
Date: Fri Nov 18 18:37:04 2011 +0100
Fix compilation of ppudump.
symconst.pas:
* Remove sto_has_generic, which was the last remainer of my "overloaded type symbols" approach.
* Remove df_methods_specialized, as it isn't needed anymore with the recent "temporary symtable" solution.
psub.pas, specialize_objectdefs, process_abstractrecorddef:
Remove the checks for/inclusion of df_methods_specialized.
utils/ppudump.pp:
Add "sp_generic_dummy" to the symbol options.
commit d16deac060e65d4b53e8fe9c27fe7e1f6d00a416
Author: Sven Barth <pascaldragon@minerva>
Date: Wed Nov 16 16:34:51 2011 +0100
Fix compilation of "gset.pp" from fcl-stl.
nld.pas:
Extend ttypenode by a reference to the type symbol. Normally this is simply the typesym of the given def, but for specializations in type sections of generics this is not the case, because generate_specialization will return a reference to the generic definition and not the new one (thus the symbol will be wrong).
ppu.pas:
Increase PPU version because of the extension of ttypenode.
pexpr.pas:
* handle_factor_typenode: Extend the function by a "sym" parameter which will normally be "nil". In that case it is set to the def's typesym. The "typesym" field of the created type node is then set to this sym.
* For now pass nearly always "nil" for the above mentioned sym except inside factor_read_id when we've encountered a typesym.
ptype.pas, read_named_type, expr_type:
Exchange the "is_owned_by" check with a "sym_is_owned_by" check so that we can correctly detect that we are using a specialized type declaration inside a generic (once nested generic are allowed this condition needs to be checked).
commit 23668d2fc9070afc26b4288ed0db9a8eaf6f40e6
Author: Sven Barth <pascaldragon@minerva>
Date: Wed Nov 16 07:51:12 2011 +0100
psub.pas:
* tcgprocinfo.parse_body: Methods of generic classes need to set "parse_generic" as well, so that variables for "stacked generics" (generic array => generic record) inside the method body are handled correctly.
* specialize_objectdefs: Don't try to generate method bodies for abstract methods.
pdecvar.pas, read_property_dec:
Allow specializations for the return types of properties (should they be allowed for index types as well?).
symtable.pas:
Add a new class "tspecializesymtable" which is basically a globalsymtable but is always assuming to be the current unit. This symtable is used in "generate_specializations" (see below) and is needed to allow visibilty checks for "private", etc. to succeed.
pgenutil.pas, generate_specializations:
Instead of hackily pushing a symtable that may contain conflicting symbols onto the symtable stack for the specialization, a temporary global symtable using the above mentioned "tspecializesymtable" is created and pushed. After the specialization is done all symbols and defs that were added to the temporary symtable are moved to their final symtable (either the global- or localsymtable of the unit, depending on the current position of compilation). This way symbols are correctly added to a top level symtable, but without potential side effects like resolving the wrong symbol.
git-svn-id: branches/svenbarth/generics@19671 -
It's still not an ideal solution as the usage of generic classes/records (without specialization!) that are declared inside the current parsed class/record will compromise this check again.
git-svn-id: branches/svenbarth/generics@19434 -
The classes in "fgl.pas" implement an enumerator in the generic class "TFPGListEnumerator" and "specialize" that inside themselves. If we now specialize one of the generic classes (e.g. "TFPGList") the "TFPGListEnumerator" is really specialized as well. That means a def is added to the global symtable (the local one in case of a program or library file). If we now use the enumerator class in the same file (e.g. by using a "for ... in", which has a temporary variable of that type) then the methods of the enumerator are specialized again (the def itself is not). To avoid this (and time consuming searches for existing method specializations) we flag the specialized def as "done" once we're finished.
symconst.pas
* add a new flag "df_methods_specialized" to the "tdefoption" enumeration
psub.pas, process_abstractrecorddef
* check the def for the "df_methods_specialized" flag and continue only if that is not set
* set the "df_methods_specialized" flag before leaving the function
git-svn-id: branches/svenbarth/generics@19432 -
symtable.pas:
* reduce the "childdef" parameter of "is_owned_by" from "tabstractrecorddef" to "tdef", so that more primitive defs can be checked as well
* add a new function "sym_is_owned_by" which is similar to "is_owned_by", but takes a symbol and a symtable as parameter; the owner chain of the symtable is checked until a non-object- and non-record-symtable is reached
ptype.pas:
* extend "id_type", so that the symbol and the symtable that belongs to the returned def is returned as well
* this is needed to check inside "single_type" whether a def that is a generic was specialized inside another generic, because in that case the genericdef is returned by "generate_specialization" and not a new specialized def, but the corresponding type symbol (which is different from "hdef.typesym") belongs to the class itself; I need to admit that this solution isn't very clean and one could try to circumvent some of the checks, so I need to find a better detection for such a case (concrete example: the enumerator specialization inside the classes of "fgl.pas")
* in "read_named_type.expr_type" the check for "df_generic" is extended analogous to the previous change, but instead of relying on the symbol it uses the def. This is needed so that types like method pointers that are defined inside the current generic are not disallowed as they contain the "df_generic" flag as well; like the previous change this change isn't clean either and maybe it's better to remove the inclusion of the "df_generic" flag from everything except records and "objects" inside records/"objects" again. Such a solution will "only" reduce the problem to records and "objects" though...
pgenutil.pas:
* only add a new undefined def if we're not parsing the parent class or interfaces ("parse_class_parent" is true), otherwise the InternalError regarding the "equal count of defs" will trigger
* there are now two cases where we need to return a generic def instead of a undefined one when we're parsing a generic:
a) we have the previously mentioned case that "parse_class_parent" is true
b) an undefined def was added, but we need to return a generic def, so that checks can be passed
* use the correct variable when building the generic name, otherwise we get errors like "identifier '$1' not found"
* don't push the symtable if we're currently parsing the list of interfaces or the parent class, because then e.g. a generic interface will be included in the symtable of the implementing class which isn't what we want; the current solution is not clean though, so this needs to be investigated more
* Note: In the current state of "generate_specialization" the function could be simplyfied a bit more; this will be done when the implementation is satisfactory enough
git-svn-id: branches/svenbarth/generics@19430 -
* symconst.pas:
add an entry for the generic dummy symbol to the symbol options enumeration
* pgenutil.pas:
- extend "generate_specialization" by the possibility to pass a symbol name instead of a def
- if "symname" is given that is used; otherwise "genericdef" or "tt" is used
* pexpr.pas:
- in case of "<" we are trying to receive a generic dummy symbol from the left node (new function "getgenericsym")
- it's name is then passed to "generate_specialization" which in turn fills genericdef
- adjust call to "generate_specialization"
* pdecl.pas:
- we can now check for "sp_generic_dummy instead of "not sp_generic_para" to check whether we've found the dummy symbol of a previous generic declaration
- if a new dummy symbol is created we need to include "sp_generic_dummy"
- if we've found a non-generic symbol with the same name we need to include the "sp_generic_dummy" flag as well
* symtable.pas
- add a new function "searchsym_with_symoption" that more or less works the same as "searchsym", but only returns successfully if the found symbol contains the given flag
- "searchsym_with_symoption" and "searchsym" are based on the same function "maybe_searchsym_with_symoption" which is the extended implementation of "searchsym" (note: object symtables are not yet searched if a symoption is to be looked for)
- add a function "handle_generic_dummysym" which can be used to hide the undefineddef symbol in a symtable
- correctly handle generic dummy symbols in case of variables in "tstaticsymtable.checkduplicate"
git-svn-id: branches/svenbarth/generics@19429 -
- fix a comment
- the created undefineddef must not be freed, as the count of the list the def is contained in, is used to find other defs again
git-svn-id: branches/svenbarth/generics@19428 -
pgenutils.pas/generate_specialization:
- parse hint directives of the generic if they are recorded
- output hint messages of the generic after the ">" is successfully parsed
pexpr.pas:
- factor: don't display hints of a potential generic type if the next token is a "<"
- sub_expr:
* added two inline methods which
a) checks whether a node is a typenode or a loadvmtaddrnode with a typenode
b) returns the typedef of such a node
* check hint directives for the first parsed type argument of a specialization
* in the case of parsing a non-generic type the hints of the left and right node of the resulting "<" node need to be checked (the right ones only if another "<" is following)
git-svn-id: branches/svenbarth/generics@19427 -
This fixes the compilation of test tests\test\tgeneric29.pp and the reminder in pdecobj.pas is not needed anymore.
Note: Perhaps this behavior should be enabled in general if "parse_generic" is true (and not only if parse_parent_class if true as well).
git-svn-id: branches/svenbarth/generics@19426 -
Reasons for the "unique symbol" approach:
- no special search operations for cross unit search needed (which is supported by Delphi) => less performance impact
- no special care needed to really find the correct generic => less increase of parser complexity
Currently all generic tests except tgeneric29.pp compile and inline specializations work as well.
The changes in detail:
* pdecl.pas/types_dec:
- The variables used to hold the final name of the symbol are now prefixed with "gen". In case of non-generics the prefixed ones are equal to the non-prefixed ones (e.g. orgtypename=genorgtypename). In case of a generic symbol the "gen"-variants contain the type parameter count suffix (e.g. '$1' in case of 'TTest<T>') as well.
- The unmodified pattern is used to insert and detect a dummy symbol with that name, so that type declarations and - more important - inline specializations can find that symbol.
- In non-Delphi modes this symbol is also used to detect whether we have a type redefinition which is not allowed currently; its typedef points to the generic def.
- In mode Delphi the def of that dummy symbol (which contains an undefineddef) is modified when a corresponding non-generic type is parsed, so that it contains the def of the real type.
* pdecsub.pas/parse_proc_head
- consume_generic_type_parameter now only parses the type parameters and picks the generic with the correct amount of parameters. The verification of the order and names of the parameters needs to be added again.
- it also does not use "def" anymore, but it sets "srsym"
- in parse_proc_head the symbol (srsym) is only searched if the symbol isn't assigned already; in case of a generic in mode FPC it will find the dummy symbol that points to the generic def
* pexpr.pas
- in factor_read_id there are three cases to handle:
+ the symbol is not assigned => error
+ a possible generic symbol (either an undefined def or the non-generic variant) => no error and no hints
+ a non-generic symbol => hints
Point 1 is handled correctly, point 2 and 3 aren't currently and also they might be needed to be moved somewhere else
- sub_expr:
+ a node can be a tloadvmtaddrnode as well if the non-generic variant of a generic symbol is a class
+ we can only check afterwards whether the specialization was successful
* pgenutil.pas/generate_specialization
using the count of the parsed types the correct symbol can be found easily
git-svn-id: branches/svenbarth/generics@19424 -
* Changed alignment of .pdata section to 4.
+ Support saving RELOC_NONE relocations to .o files and reading them back on x86_64.
git-svn-id: trunk@19070 -
cs_create_smart if using dwarf information and external assembler
debug information as this is not compatible.
* Added a different message for cs_create_smart.
git-svn-id: trunk@19065 -
smartlink creation if using external assembler and Dwarf debugging
* Call CheckOptionsCompatibility again after setting currentt assembler
git-svn-id: trunk@19061 -
FreeB-licensed SGI version
* deleted constants that belong in glext.pp (and which are already
defined there)
* replaced "This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon
Graphics, Inc." license header with FreeB license; see
http://bugs.freepascal.org/view.php?id=20200 for details)
-> fixes http://bugs.freepascal.org/view.php?id=20200
git-svn-id: trunk@19037 -
Every startup code must now provide an additional entry point called "_dynamic_start" that is set as new the entry point if the program links to a Pascal shared library. Its purpose is to set up an exit hook usually passed via a register, which should be called during program finalization if non-nil.
We use this additional entry point because this register only has meaningful content when there are any compile-time linked shared libraries, otherwise it often contains random garbage. The difference between the _dynamic_start and the original code is minimal; actually in all implementations the _dynamic_start code passes on control to the old startup code, so we use an additional entry point instead of an additional startup file.
Detailed changes and fixes list:
compiler:
always link to the dynamic loader (ld.so) when compiling shared libraries. Fixes crashes in the loader during shared library finalization on some Linuxes
remove additional ENTRY() section in arm linker script
select either _dynamic_start or _start as entry point depending on whether this is a static or dynamic executable
powerpc*:
do not set System.isLibrary in startup code, it will be set during library initialization anyway
trap in case of reaching code locations that should not be reached instead of looping (possibly endlessly)
powerpc:
register atexit() function pointer if supplied to the executable and call it during shutdown
correctly set argc/argv/envp in shared library code and return correctly to the caller after initialization
pass on exitcode in shared library haltproc
use the more recent exit_group system call if available for shutdown
powerpc64
fix .ptrgl stub, do not set the environment register to the value of the GOT entry in the function descriptor
arm
do not set System.isLibrary in startup code, it will be set during library initialization anyway
reload exitcode to pass to shutdown
mips,mipsel,sparc
added stubs to allow correct linking
git-svn-id: trunk@19036 -