summaryrefslogtreecommitdiff
path: root/compiler/pbase.pas
diff options
context:
space:
mode:
authorsvenbarth <svenbarth@3ad0048d-3df7-0310-abae-a5850022a9f2>2015-02-20 16:23:40 +0000
committersvenbarth <svenbarth@3ad0048d-3df7-0310-abae-a5850022a9f2>2015-02-20 16:23:40 +0000
commit05465677dc2c627e8dee9c16a3a715e75aaa5729 (patch)
tree0c15f2cd27985cbc5597199567d5732982960b99 /compiler/pbase.pas
parent181787f195ae74404d74bfd8d819db8ba89ac272 (diff)
downloadfpc-05465677dc2c627e8dee9c16a3a715e75aaa5729.tar.gz
Rework the way how "specialize" is handled. Instead of initializing the specialization of a full type declaration (including unit name and parent types) it is now considered part of the specialized type itself. This means that for example the following code:
type TTestLongInt = specialize SomeOtherUnit.TTest<LongInt>; will now have to read as type TTestLongInt = SomeOtherUnit.specialize TTest<LongInt>; While this is not backwards compatible this situation should arise seldomly enough and the benefits especially in context with generic functions/procedures/methods outway the drawbacks. pbase.pas: * try_consume_unitsym: add a allow_specialize parameter that allows to parse "specialize" in front of a non-unit symbol; whether it was a specialization or not is reported using a new is_specialize parameter + add a new overload try_consume_unitsym_no_specialize that calls try_consume_unit sym with allow_specialize=false and a dummy is_specialize parameter * switch calls to try_consume_unitsym to try_consume_unitsym_no_specialize pstatmnt.pas, try_statement: * switch call to try_consume_unitsym to try_consume_unitsym_no_specialize * adjust call to parse_nested_types ptype.pas: + extend id_type with the possibility to disallow unit symbols (needed if a specialize was already parsed) and to report whether a specialize was parsed + extend parse_nested_types with the possibility to tell it whether specializations are allowed * have parse_nested_types specialize generic defs if one is encountered and local type defs are allowed * id_type: only allow "unitsym.specialize sym" or "specialize sym", but not "specialize unitsym.sym" * single_type: correctly handle specializations with "specialize" keyword * read_named_type.expr_type: there is no longer a need to check for "specialize" keyword pexpr.pas: + new function handle_specialize_inline_specialization which tries to specialize a type symbol * handle_factor_typenode: handle specializations after a point that follows a record or object (why isn't this part of postfixoperators anyway? O.o) * postfixoperators: handle "specialize" after records and objectdefs * factor_read_id: handle "specialize" in front of an identifier (and after unit symbols) + added tests * adjusted test webtbs/tw16090.pp git-svn-id: http://svn.freepascal.org/svn/fpc/trunk@29768 3ad0048d-3df7-0310-abae-a5850022a9f2
Diffstat (limited to 'compiler/pbase.pas')
-rw-r--r--compiler/pbase.pas27
1 files changed, 22 insertions, 5 deletions
diff --git a/compiler/pbase.pas b/compiler/pbase.pas
index 92d6e99c9d..3c812adfc1 100644
--- a/compiler/pbase.pas
+++ b/compiler/pbase.pas
@@ -89,7 +89,8 @@ interface
function consume_sym(var srsym:tsym;var srsymtable:TSymtable):boolean;
function consume_sym_orgid(var srsym:tsym;var srsymtable:TSymtable;var s : string):boolean;
- function try_consume_unitsym(var srsym:tsym;var srsymtable:TSymtable;var tokentoconsume:ttoken;consume_id:boolean):boolean;
+ function try_consume_unitsym(var srsym:tsym;var srsymtable:TSymtable;var tokentoconsume:ttoken;consume_id,allow_specialize:boolean;out is_specialize:boolean):boolean;
+ function try_consume_unitsym_no_specialize(var srsym:tsym;var srsymtable:TSymtable;var tokentoconsume:ttoken;consume_id:boolean):boolean;
function try_consume_hintdirective(var symopt:tsymoptions; var deprecatedmsg:pshortstring):boolean;
@@ -204,7 +205,7 @@ implementation
end;
searchsym(pattern,srsym,srsymtable);
{ handle unit specification like System.Writeln }
- try_consume_unitsym(srsym,srsymtable,t,true);
+ try_consume_unitsym_no_specialize(srsym,srsymtable,t,true);
{ if nothing found give error and return errorsym }
if assigned(srsym) then
check_hints(srsym,srsym.symoptions,srsym.deprecatedmsg)
@@ -237,7 +238,7 @@ implementation
end;
searchsym(pattern,srsym,srsymtable);
{ handle unit specification like System.Writeln }
- try_consume_unitsym(srsym,srsymtable,t,true);
+ try_consume_unitsym_no_specialize(srsym,srsymtable,t,true);
{ if nothing found give error and return errorsym }
if assigned(srsym) then
check_hints(srsym,srsym.symoptions,srsym.deprecatedmsg)
@@ -253,7 +254,7 @@ implementation
end;
- function try_consume_unitsym(var srsym:tsym;var srsymtable:TSymtable;var tokentoconsume:ttoken;consume_id:boolean):boolean;
+ function try_consume_unitsym(var srsym:tsym;var srsymtable:TSymtable;var tokentoconsume:ttoken;consume_id,allow_specialize:boolean;out is_specialize:boolean):boolean;
var
hmodule: tmodule;
ns:ansistring;
@@ -261,6 +262,7 @@ implementation
begin
result:=false;
tokentoconsume:=_ID;
+ is_specialize:=false;
if assigned(srsym) and (srsym.typ in [unitsym,namespacesym]) then
begin
@@ -320,7 +322,15 @@ implementation
searchsym_in_module(tunitsym(srsym).module,'ANSICHAR',srsym,srsymtable)
end
else
- searchsym_in_module(tunitsym(srsym).module,pattern,srsym,srsymtable);
+ if allow_specialize and (idtoken=_SPECIALIZE) then
+ begin
+ consume(_ID);
+ is_specialize:=true;
+ if token=_ID then
+ searchsym_in_module(tunitsym(srsym).module,pattern,srsym,srsymtable);
+ end
+ else
+ searchsym_in_module(tunitsym(srsym).module,pattern,srsym,srsymtable);
_STRING:
begin
{ system.string? }
@@ -350,6 +360,13 @@ implementation
end;
+ function try_consume_unitsym_no_specialize(var srsym:tsym;var srsymtable:TSymtable;var tokentoconsume:ttoken;consume_id:boolean):boolean;
+ var
+ dummy: Boolean;
+ begin
+ result:=try_consume_unitsym(srsym,srsymtable,tokentoconsume,consume_id,false,dummy);
+ end;
+
function try_consume_hintdirective(var symopt:tsymoptions; var deprecatedmsg:pshortstring):boolean;
var
last_is_deprecated:boolean;