* symconst.pas: remove tf_methods_specialized
* psub.pas: remove check for/inclusion of tf_methods_specialized as this isn't needed anymore since the generic is specialized in a temporary symtable
pgenutil.pas: remove merge artifacts
pdecl.pas: fix compilation ("s" was duplicate)
pexpr.pas:
* fix calling of generate_specialization
* disable the goto in sub_expr for now; this will be enabled again once right hand sides work as well
git-svn-id: branches/svenbarth/generics@19675 -
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 -
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 -
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@17539 -
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@17538 -
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@17535 -
- moved "postfixoperators" from local declaration of "factor" to implementation declarations of the unit, so it can be used in "sub_expr"
- for this a parameter "getaddr:boolean" needed to be added, because it used the parameter that was defined by "factor"
=> adjustments inside "factor" for calls to "postfixoperators"
- extended the "_LT" ("<") case of "sub_expr" with handling of inline generic specializations. If a potential generic is detected (Delphi mode, left and right node are type nodes, next token is ">" or ",") it is tried to parse the generic declaration and generate a specialization. If this succeeds, potential postfix operators are parsed and a node <> caddnode is returned.
*pgenutil.pas:
"generate_specialization" was extended so that the first type identifer can already have been parsed (which is the case in inline specializations)
*ptype.pas
adjustments because of the extension of "generate_specialization"
git-svn-id: branches/svenbarth/generics@17405 -
Note: I've added this mostly empty, because I used SVN instead of GIT SVN, as I don't know whether it would handle the properties for this new file correctly.
git-svn-id: branches/svenbarth/generics@17397 -