ptype.pas 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Florian Klaempfl
  4. Does parsing types for Free Pascal
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. unit ptype;
  19. {$i fpcdefs.inc}
  20. interface
  21. uses
  22. globtype,symtype;
  23. const
  24. { forward types should only be possible inside a TYPE statement }
  25. typecanbeforward : boolean = false;
  26. var
  27. { hack, which allows to use the current parsed }
  28. { object type as function argument type }
  29. testcurobject : byte;
  30. curobjectname : stringid;
  31. { reads a string, file type or a type id and returns a name and }
  32. { tdef }
  33. procedure single_type(var tt:ttype;var s : string;isforwarddef:boolean);
  34. procedure read_type(var tt:ttype;const name : stringid);
  35. { reads a type definition }
  36. { to a appropriating tdef, s gets the name of }
  37. { the type to allow name mangling }
  38. procedure id_type(var tt : ttype;var s : string;isforwarddef:boolean);
  39. implementation
  40. uses
  41. { common }
  42. cutils,
  43. { global }
  44. globals,tokens,verbose,
  45. systems,
  46. { symtable }
  47. symconst,symbase,symdef,symsym,symtable,defbase,
  48. { pass 1 }
  49. node,
  50. nmat,nadd,ncal,nset,ncnv,ninl,ncon,nld,nflw,
  51. { parser }
  52. scanner,
  53. pbase,pexpr,pdecsub,pdecvar,pdecobj;
  54. procedure id_type(var tt : ttype;var s : string;isforwarddef:boolean);
  55. { reads a type definition }
  56. { to a appropriating tdef, s gets the name of }
  57. { the type to allow name mangling }
  58. var
  59. is_unit_specific : boolean;
  60. pos : tfileposinfo;
  61. srsym : tsym;
  62. srsymtable : tsymtable;
  63. sorg : stringid;
  64. begin
  65. s:=pattern;
  66. sorg:=orgpattern;
  67. pos:=akttokenpos;
  68. { classes can be used also in classes }
  69. if (curobjectname=pattern) and is_class_or_interface(aktobjectdef) then
  70. begin
  71. tt.setdef(aktobjectdef);
  72. consume(_ID);
  73. exit;
  74. end;
  75. { objects can be parameters }
  76. if (testcurobject=2) and (curobjectname=pattern) then
  77. begin
  78. tt.setdef(aktobjectdef);
  79. consume(_ID);
  80. exit;
  81. end;
  82. { try to load the symbol to see if it's a unitsym }
  83. is_unit_specific:=false;
  84. searchsym(s,srsym,srsymtable);
  85. consume(_ID);
  86. if assigned(srsym) and
  87. (srsym.typ=unitsym) then
  88. begin
  89. is_unit_specific:=true;
  90. consume(_POINT);
  91. if srsym.owner.unitid=0 then
  92. begin
  93. srsym:=searchsymonlyin(tunitsym(srsym).unitsymtable,pattern);
  94. pos:=akttokenpos;
  95. s:=pattern;
  96. end
  97. else
  98. srsym:=nil;
  99. consume(_ID);
  100. end;
  101. { Types are first defined with an error def before assigning
  102. the real type so check if it's an errordef. if so then
  103. give an error. Only check for typesyms in the current symbol
  104. table as forwarddef are not resolved directly }
  105. if assigned(srsym) and
  106. (srsym.typ=typesym) and
  107. (srsym.owner=symtablestack) and
  108. (ttypesym(srsym).restype.def.deftype=errordef) then
  109. begin
  110. Message1(type_e_type_is_not_completly_defined,ttypesym(srsym).realname);
  111. tt:=generrortype;
  112. exit;
  113. end;
  114. { are we parsing a possible forward def ? }
  115. if isforwarddef and
  116. not(is_unit_specific) then
  117. begin
  118. tt.setdef(tforwarddef.create(s,pos));
  119. exit;
  120. end;
  121. { unknown sym ? }
  122. if not assigned(srsym) then
  123. begin
  124. Message1(sym_e_id_not_found,sorg);
  125. tt:=generrortype;
  126. exit;
  127. end;
  128. { type sym ? }
  129. if (srsym.typ<>typesym) then
  130. begin
  131. Message(type_e_type_id_expected);
  132. tt:=generrortype;
  133. exit;
  134. end;
  135. { Give an error when referring to an errordef }
  136. if (ttypesym(srsym).restype.def.deftype=errordef) then
  137. begin
  138. Message(sym_e_error_in_type_def);
  139. tt:=generrortype;
  140. exit;
  141. end;
  142. { Only use the definitions for current unit, becuase
  143. they can be refered from the parameters and symbols are not
  144. loaded at that time. A symbol reference to an other unit
  145. is still possible, because it's already loaded (PFV)
  146. can't use in [] here, becuase unitid can be > 255 }
  147. if (ttypesym(srsym).owner.unitid=0) then
  148. tt.setdef(ttypesym(srsym).restype.def)
  149. else
  150. tt.setsym(srsym);
  151. end;
  152. procedure single_type(var tt:ttype;var s : string;isforwarddef:boolean);
  153. { reads a string, file type or a type id and returns a name and }
  154. { tdef }
  155. var
  156. hs : string;
  157. t2 : ttype;
  158. begin
  159. case token of
  160. _STRING:
  161. begin
  162. string_dec(tt);
  163. s:='STRING';
  164. end;
  165. _FILE:
  166. begin
  167. consume(_FILE);
  168. if token=_OF then
  169. begin
  170. consume(_OF);
  171. single_type(t2,hs,false);
  172. tt.setdef(tfiledef.createtyped(t2));
  173. s:='FILE$OF$'+hs;
  174. end
  175. else
  176. begin
  177. tt:=cfiletype;
  178. s:='FILE';
  179. end;
  180. end;
  181. _ID:
  182. begin
  183. id_type(tt,s,isforwarddef);
  184. end;
  185. else
  186. begin
  187. message(type_e_type_id_expected);
  188. s:='<unknown>';
  189. tt:=generrortype;
  190. end;
  191. end;
  192. end;
  193. { reads a record declaration }
  194. function record_dec : tdef;
  195. var
  196. symtable : tsymtable;
  197. storetypecanbeforward : boolean;
  198. old_object_option : tsymoptions;
  199. begin
  200. { create recdef }
  201. symtable:=trecordsymtable.create;
  202. record_dec:=trecorddef.create(symtable);
  203. { update symtable stack }
  204. symtable.next:=symtablestack;
  205. symtablestack:=symtable;
  206. { parse record }
  207. consume(_RECORD);
  208. old_object_option:=current_object_option;
  209. current_object_option:=[sp_public];
  210. storetypecanbeforward:=typecanbeforward;
  211. { for tp7 don't allow forward types }
  212. if m_tp7 in aktmodeswitches then
  213. typecanbeforward:=false;
  214. read_var_decs(true,false,false);
  215. consume(_END);
  216. typecanbeforward:=storetypecanbeforward;
  217. current_object_option:=old_object_option;
  218. { may be scale record size to a size of n*4 ? }
  219. symtablestack.datasize:=align(symtablestack.datasize,symtablestack.dataalignment);
  220. { restore symtable stack }
  221. symtablestack:=symtable.next;
  222. end;
  223. { reads a type definition and returns a pointer to it }
  224. procedure read_type(var tt : ttype;const name : stringid);
  225. var
  226. pt : tnode;
  227. tt2 : ttype;
  228. aktenumdef : tenumdef;
  229. ap : tarraydef;
  230. s : stringid;
  231. l,v : TConstExprInt;
  232. oldaktpackrecords : longint;
  233. hs : string;
  234. defpos,storepos : tfileposinfo;
  235. procedure expr_type;
  236. var
  237. pt1,pt2 : tnode;
  238. lv,hv : TConstExprInt;
  239. begin
  240. { use of current parsed object ? }
  241. if (token=_ID) and (testcurobject=2) and (curobjectname=pattern) then
  242. begin
  243. consume(_ID);
  244. tt.setdef(aktobjectdef);
  245. exit;
  246. end;
  247. { classes can be used also in classes }
  248. if (curobjectname=pattern) and is_class_or_interface(aktobjectdef) then
  249. begin
  250. tt.setdef(aktobjectdef);
  251. consume(_ID);
  252. exit;
  253. end;
  254. { we can't accept a equal in type }
  255. pt1:=comp_expr(not(ignore_equal));
  256. if (token=_POINTPOINT) then
  257. begin
  258. consume(_POINTPOINT);
  259. { get high value of range }
  260. pt2:=comp_expr(not(ignore_equal));
  261. { make both the same type }
  262. inserttypeconv(pt1,pt2.resulttype);
  263. { both must be evaluated to constants now }
  264. if (pt1.nodetype=ordconstn) and
  265. (pt2.nodetype=ordconstn) then
  266. begin
  267. lv:=tordconstnode(pt1).value;
  268. hv:=tordconstnode(pt2).value;
  269. { Check bounds }
  270. if hv<lv then
  271. Message(cg_e_upper_lower_than_lower)
  272. else
  273. begin
  274. { All checks passed, create the new def }
  275. case pt1.resulttype.def.deftype of
  276. enumdef :
  277. tt.setdef(tenumdef.create_subrange(tenumdef(pt1.resulttype.def),lv,hv));
  278. orddef :
  279. begin
  280. if is_char(pt1.resulttype.def) then
  281. tt.setdef(torddef.create(uchar,lv,hv))
  282. else
  283. if is_boolean(pt1.resulttype.def) then
  284. tt.setdef(torddef.create(bool8bit,l,hv))
  285. else
  286. tt.setdef(torddef.create(range_to_basetype(lv,hv),lv,hv));
  287. end;
  288. end;
  289. end;
  290. end
  291. else
  292. Message(sym_e_error_in_type_def);
  293. pt2.free;
  294. end
  295. else
  296. begin
  297. { a simple type renaming }
  298. if (pt1.nodetype=typen) then
  299. tt:=ttypenode(pt1).resulttype
  300. else
  301. Message(sym_e_error_in_type_def);
  302. end;
  303. pt1.free;
  304. end;
  305. procedure array_dec;
  306. var
  307. lowval,
  308. highval : longint;
  309. arraytype : ttype;
  310. ht : ttype;
  311. procedure setdefdecl(const t:ttype);
  312. begin
  313. case t.def.deftype of
  314. enumdef :
  315. begin
  316. lowval:=tenumdef(t.def).min;
  317. highval:=tenumdef(t.def).max;
  318. if tenumdef(t.def).has_jumps then
  319. Message(type_e_array_index_enums_with_assign_not_possible);
  320. arraytype:=t;
  321. end;
  322. orddef :
  323. begin
  324. if torddef(t.def).typ in [uchar,
  325. u8bit,u16bit,
  326. s8bit,s16bit,s32bit,
  327. bool8bit,bool16bit,bool32bit,
  328. uwidechar] then
  329. begin
  330. lowval:=torddef(t.def).low;
  331. highval:=torddef(t.def).high;
  332. arraytype:=t;
  333. end
  334. else
  335. Message1(parser_e_type_cant_be_used_in_array_index,t.def.gettypename);
  336. end;
  337. else
  338. Message(sym_e_error_in_type_def);
  339. end;
  340. end;
  341. begin
  342. consume(_ARRAY);
  343. { open array? }
  344. if token=_LECKKLAMMER then
  345. begin
  346. consume(_LECKKLAMMER);
  347. { defaults }
  348. arraytype:=generrortype;
  349. lowval:=longint($80000000);
  350. highval:=$7fffffff;
  351. tt.reset;
  352. repeat
  353. { read the expression and check it, check apart if the
  354. declaration is an enum declaration because that needs to
  355. be parsed by readtype (PFV) }
  356. if token=_LKLAMMER then
  357. begin
  358. read_type(ht,'');
  359. setdefdecl(ht);
  360. end
  361. else
  362. begin
  363. pt:=expr;
  364. if pt.nodetype=typen then
  365. setdefdecl(pt.resulttype)
  366. else
  367. begin
  368. if (pt.nodetype=rangen) then
  369. begin
  370. if (trangenode(pt).left.nodetype=ordconstn) and
  371. (trangenode(pt).right.nodetype=ordconstn) then
  372. begin
  373. lowval:=tordconstnode(trangenode(pt).left).value;
  374. highval:=tordconstnode(trangenode(pt).right).value;
  375. if highval<lowval then
  376. begin
  377. Message(parser_e_array_lower_less_than_upper_bound);
  378. highval:=lowval;
  379. end;
  380. arraytype:=trangenode(pt).right.resulttype;
  381. end
  382. else
  383. Message(type_e_cant_eval_constant_expr);
  384. end
  385. else
  386. Message(sym_e_error_in_type_def)
  387. end;
  388. pt.free;
  389. end;
  390. { create arraydef }
  391. if not assigned(tt.def) then
  392. begin
  393. ap:=tarraydef.create(lowval,highval,arraytype);
  394. tt.setdef(ap);
  395. end
  396. else
  397. begin
  398. ap.elementtype.setdef(tarraydef.create(lowval,highval,arraytype));
  399. ap:=tarraydef(ap.elementtype.def);
  400. end;
  401. if token=_COMMA then
  402. consume(_COMMA)
  403. else
  404. break;
  405. until false;
  406. consume(_RECKKLAMMER);
  407. end
  408. else
  409. begin
  410. ap:=tarraydef.create(0,-1,s32bittype);
  411. ap.IsDynamicArray:=true;
  412. tt.setdef(ap);
  413. end;
  414. consume(_OF);
  415. read_type(tt2,'');
  416. { if no error, set element type }
  417. if assigned(ap) then
  418. ap.setelementtype(tt2);
  419. end;
  420. var
  421. p : tnode;
  422. enumdupmsg : boolean;
  423. begin
  424. tt.reset;
  425. case token of
  426. _STRING,_FILE:
  427. begin
  428. single_type(tt,hs,false);
  429. end;
  430. _LKLAMMER:
  431. begin
  432. consume(_LKLAMMER);
  433. { allow negativ value_str }
  434. l:=-1;
  435. enumdupmsg:=false;
  436. aktenumdef:=tenumdef.create;
  437. repeat
  438. s:=orgpattern;
  439. defpos:=akttokenpos;
  440. consume(_ID);
  441. { only allow assigning of specific numbers under fpc mode }
  442. if (m_fpc in aktmodeswitches) and
  443. (token=_ASSIGNMENT) then
  444. begin
  445. consume(_ASSIGNMENT);
  446. p:=comp_expr(true);
  447. if (p.nodetype=ordconstn) then
  448. begin
  449. { we expect an integer or an enum of the
  450. same type }
  451. if is_integer(p.resulttype.def) or
  452. is_char(p.resulttype.def) or
  453. is_equal(p.resulttype.def,aktenumdef) then
  454. v:=tordconstnode(p).value
  455. else
  456. Message2(type_e_incompatible_types,p.resulttype.def.typename,s32bittype.def.typename);
  457. end
  458. else
  459. Message(cg_e_illegal_expression);
  460. p.free;
  461. { please leave that a note, allows type save }
  462. { declarations in the win32 units ! }
  463. if (v<=l) and (not enumdupmsg) then
  464. begin
  465. Message(parser_n_duplicate_enum);
  466. enumdupmsg:=true;
  467. end;
  468. l:=v;
  469. end
  470. else if (m_delphi in aktmodeswitches) and
  471. (token=_EQUAL) then
  472. begin
  473. consume(_EQUAL);
  474. p:=comp_expr(true);
  475. if (p.nodetype=ordconstn) then
  476. begin
  477. { we expect an integer or an enum of the
  478. same type }
  479. if is_integer(p.resulttype.def) or
  480. is_equal(p.resulttype.def,aktenumdef) then
  481. l:=tordconstnode(p).value
  482. else
  483. Message2(type_e_incompatible_types,p.resulttype.def.typename,s32bittype.def.typename);
  484. end
  485. else
  486. Message(cg_e_illegal_expression);
  487. p.free;
  488. end
  489. else
  490. inc(l);
  491. storepos:=akttokenpos;
  492. akttokenpos:=defpos;
  493. constsymtable.insert(tenumsym.create(s,aktenumdef,l));
  494. akttokenpos:=storepos;
  495. until not try_to_consume(_COMMA);
  496. tt.setdef(aktenumdef);
  497. consume(_RKLAMMER);
  498. end;
  499. _ARRAY:
  500. begin
  501. array_dec;
  502. end;
  503. _SET:
  504. begin
  505. consume(_SET);
  506. consume(_OF);
  507. read_type(tt2,'');
  508. if assigned(tt2.def) then
  509. begin
  510. case tt2.def.deftype of
  511. { don't forget that min can be negativ PM }
  512. enumdef :
  513. if tenumdef(tt2.def).min>=0 then
  514. tt.setdef(tsetdef.create(tt2,tenumdef(tt2.def).max))
  515. else
  516. Message(sym_e_ill_type_decl_set);
  517. orddef :
  518. begin
  519. case torddef(tt2.def).typ of
  520. uchar :
  521. tt.setdef(tsetdef.create(tt2,255));
  522. u8bit,u16bit,u32bit,
  523. s8bit,s16bit,s32bit :
  524. begin
  525. if (torddef(tt2.def).low>=0) then
  526. tt.setdef(tsetdef.create(tt2,torddef(tt2.def).high))
  527. else
  528. Message(sym_e_ill_type_decl_set);
  529. end;
  530. else
  531. Message(sym_e_ill_type_decl_set);
  532. end;
  533. end;
  534. else
  535. Message(sym_e_ill_type_decl_set);
  536. end;
  537. end
  538. else
  539. tt:=generrortype;
  540. end;
  541. _CARET:
  542. begin
  543. consume(_CARET);
  544. single_type(tt2,hs,typecanbeforward);
  545. tt.setdef(tpointerdef.create(tt2));
  546. end;
  547. _RECORD:
  548. begin
  549. tt.setdef(record_dec);
  550. end;
  551. _PACKED:
  552. begin
  553. consume(_PACKED);
  554. if token=_ARRAY then
  555. array_dec
  556. else
  557. begin
  558. oldaktpackrecords:=aktalignment.recordalignmax;
  559. aktalignment.recordalignmax:=1;
  560. if token in [_CLASS,_OBJECT] then
  561. tt.setdef(object_dec(name,nil))
  562. else
  563. tt.setdef(record_dec);
  564. aktalignment.recordalignmax:=oldaktpackrecords;
  565. end;
  566. end;
  567. _CLASS,
  568. _CPPCLASS,
  569. _INTERFACE,
  570. _OBJECT:
  571. begin
  572. tt.setdef(object_dec(name,nil));
  573. end;
  574. _PROCEDURE:
  575. begin
  576. consume(_PROCEDURE);
  577. tt.setdef(tprocvardef.create);
  578. if token=_LKLAMMER then
  579. parameter_dec(tprocvardef(tt.def));
  580. if token=_OF then
  581. begin
  582. consume(_OF);
  583. consume(_OBJECT);
  584. include(tprocvardef(tt.def).procoptions,po_methodpointer);
  585. end;
  586. end;
  587. _FUNCTION:
  588. begin
  589. consume(_FUNCTION);
  590. tt.def:=tprocvardef.create;
  591. if token=_LKLAMMER then
  592. parameter_dec(tprocvardef(tt.def));
  593. consume(_COLON);
  594. single_type(tprocvardef(tt.def).rettype,hs,false);
  595. if token=_OF then
  596. begin
  597. consume(_OF);
  598. consume(_OBJECT);
  599. include(tprocvardef(tt.def).procoptions,po_methodpointer);
  600. end;
  601. end;
  602. else
  603. expr_type;
  604. end;
  605. if tt.def=nil then
  606. tt:=generrortype;
  607. end;
  608. end.
  609. {
  610. $Log$
  611. Revision 1.45 2002-09-27 21:13:29 carl
  612. * low-highval always checked if limit ober 2GB is reached (to avoid overflow)
  613. Revision 1.44 2002/09/10 16:26:39 peter
  614. * safety check for typesym added for incomplete type def check
  615. Revision 1.43 2002/09/09 19:34:07 peter
  616. * check for incomplete types in the current symtable when parsing
  617. forwarddef. Maybe this shall be delphi/tp only
  618. Revision 1.42 2002/07/20 11:57:56 florian
  619. * types.pas renamed to defbase.pas because D6 contains a types
  620. unit so this would conflicts if D6 programms are compiled
  621. + Willamette/SSE2 instructions to assembler added
  622. Revision 1.41 2002/05/18 13:34:16 peter
  623. * readded missing revisions
  624. Revision 1.40 2002/05/16 19:46:44 carl
  625. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  626. + try to fix temp allocation (still in ifdef)
  627. + generic constructor calls
  628. + start of tassembler / tmodulebase class cleanup
  629. Revision 1.38 2002/05/12 16:53:10 peter
  630. * moved entry and exitcode to ncgutil and cgobj
  631. * foreach gets extra argument for passing local data to the
  632. iterator function
  633. * -CR checks also class typecasts at runtime by changing them
  634. into as
  635. * fixed compiler to cycle with the -CR option
  636. * fixed stabs with elf writer, finally the global variables can
  637. be watched
  638. * removed a lot of routines from cga unit and replaced them by
  639. calls to cgobj
  640. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  641. u32bit then the other is typecasted also to u32bit without giving
  642. a rangecheck warning/error.
  643. * fixed pascal calling method with reversing also the high tree in
  644. the parast, detected by tcalcst3 test
  645. Revision 1.37 2002/04/19 15:46:03 peter
  646. * mangledname rewrite, tprocdef.mangledname is now created dynamicly
  647. in most cases and not written to the ppu
  648. * add mangeledname_prefix() routine to generate the prefix of
  649. manglednames depending on the current procedure, object and module
  650. * removed static procprefix since the mangledname is now build only
  651. on demand from tprocdef.mangledname
  652. Revision 1.36 2002/04/16 16:12:47 peter
  653. * give error when using enums with jumps as array index
  654. * allow char as enum value
  655. Revision 1.35 2002/04/04 19:06:04 peter
  656. * removed unused units
  657. * use tlocation.size in cg.a_*loc*() routines
  658. Revision 1.34 2002/01/24 18:25:49 peter
  659. * implicit result variable generation for assembler routines
  660. * removed m_tp modeswitch, use m_tp7 or not(m_fpc) instead
  661. Revision 1.33 2002/01/15 16:13:34 jonas
  662. * fixed web bugs 1758 and 1760
  663. Revision 1.32 2002/01/06 12:08:15 peter
  664. * removed uauto from orddef, use new range_to_basetype generating
  665. the correct ordinal type for a range
  666. }