FreeBASIC  0.91.0
parser-quirk-vafirst.bas
Go to the documentation of this file.
1 '' quirk varargs function (VA_FIRST) parsing
2 ''
3 '' chng: sep/2004 written [v1ctor]
4 
5 
6 #include once "fb.bi"
7 #include once "fbint.bi"
8 #include once "parser.bi"
9 #include once "ast.bi"
10 
11 '':::::
12 ''cVAFunct = VA_FIRST ('(' ')')? .
13 ''
14 function cVAFunct() as ASTNODE ptr
15  function = FALSE
16 
17  if( fbIsModLevel( ) ) then
18  exit function
19  end if
20 
21  dim as FBSYMBOL ptr proc = parser.currproc
22  if( symbGetProcMode( proc ) <> FB_FUNCMODE_CDECL ) then
23  exit function
24  end if
25 
26  dim as FBSYMBOL ptr param = symbGetProcTailParam( proc )
27  if( param = NULL ) then
28  exit function
29  end if
30  if( symbGetParamMode( param ) <> FB_PARAMMODE_VARARG ) then
31  exit function
32  end if
33  param = param->prev
34  if( param = NULL ) then
35  exit function
36  end if
37 
38  dim as FBSYMBOL ptr sym = symbGetParamVar( param )
39  if( sym = NULL ) then
40  exit function
41  end if
42 
43  '' VA_FIRST
44  lexSkipToken( )
45 
46  '' ('(' ')')?
47  if( hMatch( CHAR_LPRNT ) ) then
48  hMatchRPRNT( )
49  end if
50 
51  '' C backend? va_* not supported
52  if( env.clopt.backend = FB_BACKEND_GCC ) then
53  errReport( FB_ERRMSG_STMTUNSUPPORTEDINGCC, TRUE )
54 
55  '' error recovery: fake an expr
56  function = astNewCONSTi( 0 )
57  else
58  '' @param
59  var expr = astNewADDROF( astNewVAR( sym ) )
60 
61  '' Cast to ANY PTR to hide that it's based on the parameter
62  expr = astNewCONV( typeAddrOf( FB_DATATYPE_VOID ), NULL, expr )
63 
64  '' + paramlen( param )
65  function = astNewBOP( AST_OP_ADD, expr, astNewCONSTi( symbGetLen( param ), FB_DATATYPE_UINT ) )
66  end if
67 end function
68