FreeBASIC  0.91.0
parser-quirk-mem.bas
Go to the documentation of this file.
1 '' memory operations
2 ''
3 '' chng: nov/2006 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 ''cOperatorNew = NEW DataType|Constructor()
13 '' | NEW DataType[Expr] .
14 ''
15 function cOperatorNew( ) as ASTNODE ptr
16  dim as integer dtype = any
17  dim as FBSYMBOL ptr subtype = any, tmp = any
18  dim as integer has_ctor = any, has_defctor = any, do_clear = any
19  dim as ASTNODE ptr initexpr = any, elementsexpr = any, placementexpr = any
20  dim as ASTNODE ptr expr = any
21  dim as AST_OP op = any
22 
23  do_clear = TRUE
24  op = AST_OP_NEW
25  elementsexpr = NULL
26  initexpr = NULL
27  placementexpr = NULL
28 
29  '' NEW
30  lexSkipToken( )
31 
32  '' '('?
33  if( hMatch( CHAR_LPRNT ) ) then
34  '' placement new
35  placementexpr = cExpression( )
36  if( placementexpr = NULL ) then
37  errReport( FB_ERRMSG_EXPECTEDEXPRESSION, TRUE )
38  end if
39 
40  '' ')'
41  if( hMatch( CHAR_RPRNT ) = FALSE ) then
42  errReport( FB_ERRMSG_EXPECTEDRPRNT )
43  end if
44  end if
45 
46  '' DataType
47  hSymbolType( dtype, subtype, 0 )
48 
49  '' check for invalid types
50  select case as const typeGet( dtype )
51  case FB_DATATYPE_STRING, FB_DATATYPE_FIXSTR, _
52  FB_DATATYPE_CHAR, FB_DATATYPE_WCHAR
53  errReport( FB_ERRMSG_NEWCANTBEUSEDWITHSTRINGS, TRUE )
54  '' error recovery: fake an expr
55  hSkipStmt( )
56  return astNewCONSTi( 0 )
57  end select
58 
59  '' Disallow creating objects of abstract classes
60  hComplainIfAbstractClass( dtype, subtype )
61 
62  has_ctor = typeHasCtor( dtype, subtype )
63  has_defctor = typeHasDefCtor( dtype, subtype )
64 
65  '' '['?
66  if( lexGetToken( ) = CHAR_LBRACKET ) then
67  lexSkipToken( )
68 
69  elementsexpr = cExpression( )
70  if( elementsexpr = NULL ) then
71  errReport( FB_ERRMSG_EXPECTEDEXPRESSION )
72  else
73  op = AST_OP_NEW_VEC
74  end if
75 
76  '' ']'
77  if( lexGetToken( ) <> CHAR_RBRACKET ) then
78  errReport( FB_ERRMSG_EXPECTEDRBRACKET )
79  hSkipUntil( CHAR_RBRACKET )
80  else
81  lexSkipToken( )
82  end if
83 
84  '' '{'?
85  if( lexGetToken( ) = CHAR_LBRACE ) then
86  lexSkipToken( )
87 
88  '' ANY?
89  if( lexGetToken( ) = FB_TK_ANY ) then
90  if( has_defctor ) then
91  errReportWarn( FB_WARNINGMSG_ANYINITHASNOEFFECT )
92  end if
93  lexSkipToken( )
94  do_clear = FALSE
95  else
96  errReport( FB_ERRMSG_VECTORCANTBEINITIALIZED )
97  end if
98 
99  '' '}'
100  if( lexGetToken( ) <> CHAR_RBRACE ) then
101  errReport( FB_ERRMSG_EXPECTEDRBRACE )
102  '' error recovery: skip until next '}'
103  hSkipUntil( CHAR_RBRACE, TRUE )
104  else
105  lexSkipToken( )
106  end if
107  end if
108  end if
109 
110  '' not a vector?
111  if( elementsexpr = NULL ) then
112  elementsexpr = astNewCONSTi( 1, FB_DATATYPE_UINT )
113  else
114  '' hack(?): make sure it's a uinteger, otherwise it may crash later, fixes bug #2533376 (counting_pine)
115  elementsexpr = astNewCONV( FB_DATATYPE_UINT, NULL, elementsexpr )
116  if( elementsexpr = NULL ) then
117  errReport( FB_ERRMSG_TYPEMISMATCH, TRUE )
118  elementsexpr = astNewCONSTi( 1, FB_DATATYPE_UINT )
119  end if
120  end if
121 
122  '' temp pointer
123  tmp = symbAddTempVar( typeAddrOf( dtype ), subtype )
124 
125  '' Constructor?
126  if( has_ctor ) then
127  '' '('?
128  if( lexGetToken( ) = CHAR_LPRNT ) then
129  '' ctor + vector? not allowed..
130  if( op = AST_OP_NEW_VEC ) then
131  errReport( FB_ERRMSG_EXPLICITCTORCALLINVECTOR, TRUE )
132  else
133  initexpr = cCtorCall( subtype )
134  if( initexpr = NULL ) then
135  return NULL
136  end if
137  end if
138  else
139  dim as FBSYMBOL ptr ctor = symbGetCompDefCtor( subtype )
140  '' no default ctor?
141  if( ctor = NULL ) then
142  errReport( FB_ERRMSG_NODEFAULTCTORDEFINED )
143  else
144  '' only if not a vector
145  if( op <> AST_OP_NEW_VEC ) then
146  initexpr = cCtorCall( subtype )
147  if( initexpr = NULL ) then
148  return NULL
149  end if
150  else
151  '' check visibility
152  if( symbCheckAccess( ctor ) = FALSE ) then
153  errReport( FB_ERRMSG_NOACCESSTODEFAULTCTOR )
154  end if
155  end if
156  end if
157  end if
158  else
159  '' '('?
160  if( lexGetToken( ) = CHAR_LPRNT ) then
161  '' vector? not allowed..
162  if( op = AST_OP_NEW_VEC ) then
163  errReport( FB_ERRMSG_VECTORCANTBEINITIALIZED, TRUE )
164  end if
165 
166  '' ANY?
167  if( lexGetLookAhead( 1 ) = FB_TK_ANY ) then
168  lexSkipToken( )
169  lexSkipToken( )
170 
171  do_clear = FALSE
172 
173  '' ')'
174  if( lexGetToken( ) <> CHAR_RPRNT ) then
175  errReport( FB_ERRMSG_EXPECTEDRPRNT )
176  '' error recovery: skip until next ')'
177  hSkipUntil( CHAR_RPRNT, TRUE )
178  else
179  lexSkipToken( )
180  end if
181  else
182  initexpr = cInitializer( tmp, FB_INIOPT_ISINI or FB_INIOPT_DODEREF )
183 
184  symbGetStats( tmp ) and= not FB_SYMBSTATS_INITIALIZED
185 
186  if( initexpr = NULL ) then
187  errReport( FB_ERRMSG_EXPECTEDEXPRESSION )
188  end if
189  end if
190  end if
191  end if
192 
193  expr = astBuildNewOp( op, tmp, elementsexpr, initexpr, _
194  dtype, subtype, do_clear, placementexpr )
195 
196  if( expr = NULL ) then
197  errReport( FB_ERRMSG_INVALIDDATATYPES )
198  end if
199 
200  '' return the pointer
201  function = astNewLINK( expr, astNewVAR( tmp ), FALSE )
202 end function
203 
204 '' DELETE ['[]'] expr
206  dim as ASTNODE ptr ptrexpr = any
207  dim as integer dtype = any, op = any
208  dim as FBSYMBOL ptr subtype = any
209 
210  '' DELETE
211  lexSkipToken( )
212 
213  op = AST_OP_DEL
214 
215  '' '[' ']'?
216  if( lexGetToken( ) = CHAR_LBRACKET ) then
217  lexSkipToken( )
218  op = AST_OP_DEL_VEC
219  if( lexGetToken( ) <> CHAR_RBRACKET ) then
220  errReport( FB_ERRMSG_EXPECTEDRBRACKET )
221  hSkipUntil( CHAR_RBRACKET )
222  return
223  end if
224  lexSkipToken( )
225  end if
226 
227  ptrexpr = cVarOrDeref( FB_VAREXPROPT_ISEXPR )
228  if( ptrexpr = NULL ) then
229  errReport( FB_ERRMSG_EXPECTEDIDENTIFIER )
230  hSkipStmt( )
231  return
232  end if
233 
234  dtype = astGetFullType( ptrexpr )
235  subtype = astGetSubType( ptrexpr )
236 
237  '' not a ptr?
238  if( typeIsPtr( dtype ) = FALSE ) then
239  errReport( FB_ERRMSG_EXPECTEDPOINTER )
240  hSkipStmt( )
241  return
242  end if
243 
244  dtype = typeDeref( dtype )
245 
246  select case( typeGetDtAndPtrOnly( dtype ) )
247  case FB_DATATYPE_VOID
248  '' Warn about ANY PTR
249  errReportWarn( FB_WARNINGMSG_DELETEANYPTR )
250  case FB_DATATYPE_FWDREF
251  '' Disallow DELETE on forward reference ptrs
252  '' (don't know whether the real type will have a dtor or not)
253  errReport( FB_ERRMSG_INCOMPLETETYPE, TRUE )
254  dtype = FB_DATATYPE_BYTE
255  end select
256 
257  '' check visibility
258  if( typeHasDtor( dtype, subtype ) ) then
259  if( symbCheckAccess( symbGetCompDtor( subtype ) ) = FALSE ) then
260  errReport( FB_ERRMSG_NOACCESSTODTOR )
261  end if
262  end if
263 
264  astAdd( astBuildDeleteOp( op, ptrexpr, dtype, subtype ) )
265 end sub
266