2 * Copyright 2005-2007 Adrian Thurston <thurston@cs.queensu.ca>
5 /* This file is part of Ragel.
7 * Ragel is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * Ragel is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Ragel; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 /* Total error count. */
29 int gblErrorCount
= 0;
31 CodeGenData::CodeGenData( ostream
&out
)
56 hasLongestMatch(false),
59 writeFirstFinal(true),
65 void CodeGenData::createMachine()
67 redFsm
= new RedFsmAp();
70 void CodeGenData::initActionList( unsigned long length
)
72 allActions
= new Action
[length
];
73 for ( unsigned long a
= 0; a
< length
; a
++ )
74 actionList
.append( allActions
+a
);
77 void CodeGenData::newAction( int anum
, char *name
, int line
,
78 int col
, InlineList
*inlineList
)
80 allActions
[anum
].actionId
= anum
;
81 allActions
[anum
].name
= name
;
82 allActions
[anum
].loc
.line
= line
;
83 allActions
[anum
].loc
.col
= col
;
84 allActions
[anum
].inlineList
= inlineList
;
87 void CodeGenData::initActionTableList( unsigned long length
)
89 allActionTables
= new RedAction
[length
];
92 void CodeGenData::initStateList( unsigned long length
)
94 allStates
= new RedStateAp
[length
];
95 for ( unsigned long s
= 0; s
< length
; s
++ )
96 redFsm
->stateList
.append( allStates
+s
);
98 /* We get the start state as an offset, set the pointer now. */
99 if ( startState
>= 0 )
100 redFsm
->startState
= allStates
+ startState
;
102 redFsm
->errState
= allStates
+ errState
;
103 for ( EntryIdVect::Iter en
= entryPointIds
; en
.lte(); en
++ )
104 redFsm
->entryPoints
.insert( allStates
+ *en
);
106 /* The nextStateId is no longer used to assign state ids (they come in set
107 * from the frontend now), however generation code still depends on it.
108 * Should eventually remove this variable. */
109 redFsm
->nextStateId
= redFsm
->stateList
.length();
112 void CodeGenData::setStartState( unsigned long startState
)
114 this->startState
= startState
;
117 void CodeGenData::setErrorState( unsigned long errState
)
119 this->errState
= errState
;
122 void CodeGenData::addEntryPoint( char *name
, unsigned long entryState
)
124 entryPointIds
.append( entryState
);
125 entryPointNames
.append( name
);
128 void CodeGenData::initTransList( int snum
, unsigned long length
)
130 /* Could preallocate the out range to save time growing it. For now do
134 void CodeGenData::newTrans( int snum
, int tnum
, Key lowKey
,
135 Key highKey
, long targ
, long action
)
137 /* Get the current state and range. */
138 RedStateAp
*curState
= allStates
+ snum
;
139 RedTransList
&destRange
= curState
->outRange
;
141 if ( curState
== redFsm
->errState
)
144 /* Make the new transitions. */
145 RedStateAp
*targState
= targ
>= 0 ? (allStates
+ targ
) :
146 wantComplete
? redFsm
->getErrorState() : 0;
147 RedAction
*actionTable
= action
>= 0 ? (allActionTables
+ action
) : 0;
148 RedTransAp
*trans
= redFsm
->allocateTrans( targState
, actionTable
);
149 RedTransEl
transEl( lowKey
, highKey
, trans
);
151 if ( wantComplete
) {
152 /* If the machine is to be complete then we need to fill any gaps with
153 * the error transitions. */
154 if ( destRange
.length() == 0 ) {
155 /* Range is currently empty. */
156 if ( keyOps
->minKey
< lowKey
) {
157 /* The first range doesn't start at the low end. */
158 Key fillHighKey
= lowKey
;
159 fillHighKey
.decrement();
161 /* Create the filler with the state's error transition. */
162 RedTransEl
newTel( keyOps
->minKey
, fillHighKey
, redFsm
->getErrorTrans() );
163 destRange
.append( newTel
);
167 /* The range list is not empty, get the the last range. */
168 RedTransEl
*last
= &destRange
[destRange
.length()-1];
169 Key nextKey
= last
->highKey
;
171 if ( nextKey
< lowKey
) {
172 /* There is a gap to fill. Make the high key. */
173 Key fillHighKey
= lowKey
;
174 fillHighKey
.decrement();
176 /* Create the filler with the state's error transtion. */
177 RedTransEl
newTel( nextKey
, fillHighKey
, redFsm
->getErrorTrans() );
178 destRange
.append( newTel
);
183 /* Filler taken care of. Append the range. */
184 destRange
.append( RedTransEl( lowKey
, highKey
, trans
) );
187 void CodeGenData::finishTransList( int snum
)
189 /* Get the current state and range. */
190 RedStateAp
*curState
= allStates
+ snum
;
191 RedTransList
&destRange
= curState
->outRange
;
193 if ( curState
== redFsm
->errState
)
196 /* If building a complete machine we may need filler on the end. */
197 if ( wantComplete
) {
198 /* Check if there are any ranges already. */
199 if ( destRange
.length() == 0 ) {
200 /* Fill with the whole alphabet. */
201 /* Add the range on the lower and upper bound. */
202 RedTransEl
newTel( keyOps
->minKey
, keyOps
->maxKey
, redFsm
->getErrorTrans() );
203 destRange
.append( newTel
);
206 /* Get the last and check for a gap on the end. */
207 RedTransEl
*last
= &destRange
[destRange
.length()-1];
208 if ( last
->highKey
< keyOps
->maxKey
) {
209 /* Make the high key. */
210 Key fillLowKey
= last
->highKey
;
211 fillLowKey
.increment();
213 /* Create the new range with the error trans and append it. */
214 RedTransEl
newTel( fillLowKey
, keyOps
->maxKey
, redFsm
->getErrorTrans() );
215 destRange
.append( newTel
);
221 void CodeGenData::setId( int snum
, int id
)
223 RedStateAp
*curState
= allStates
+ snum
;
227 void CodeGenData::setFinal( int snum
)
229 RedStateAp
*curState
= allStates
+ snum
;
230 curState
->isFinal
= true;
234 void CodeGenData::setStateActions( int snum
, long toStateAction
,
235 long fromStateAction
, long eofAction
)
237 RedStateAp
*curState
= allStates
+ snum
;
238 if ( toStateAction
>= 0 )
239 curState
->toStateAction
= allActionTables
+ toStateAction
;
240 if ( fromStateAction
>= 0 )
241 curState
->fromStateAction
= allActionTables
+ fromStateAction
;
242 if ( eofAction
>= 0 )
243 curState
->eofAction
= allActionTables
+ eofAction
;
246 void CodeGenData::resolveTargetStates( InlineList
*inlineList
)
248 for ( InlineList::Iter item
= *inlineList
; item
.lte(); item
++ ) {
249 switch ( item
->type
) {
250 case InlineItem::Goto
: case InlineItem::Call
:
251 case InlineItem::Next
: case InlineItem::Entry
:
252 item
->targState
= allStates
+ item
->targId
;
258 if ( item
->children
!= 0 )
259 resolveTargetStates( item
->children
);
263 void CodeGenData::closeMachine()
265 for ( ActionList::Iter a
= actionList
; a
.lte(); a
++ )
266 resolveTargetStates( a
->inlineList
);
268 /* Note that even if we want a complete graph we do not give the error
269 * state a default transition. All machines break out of the processing
270 * loop when in the error state. */
272 for ( RedStateList::Iter st
= redFsm
->stateList
; st
.lte(); st
++ ) {
273 for ( StateCondList::Iter sci
= st
->stateCondList
; sci
.lte(); sci
++ )
274 st
->stateCondVect
.append( sci
);
279 bool CodeGenData::setAlphType( char *data
)
281 HostType
*alphType
= findAlphTypeInternal( data
);
285 thisKeyOps
.setAlphType( alphType
);
289 void CodeGenData::initCondSpaceList( ulong length
)
291 allCondSpaces
= new CondSpace
[length
];
292 for ( ulong c
= 0; c
< length
; c
++ )
293 condSpaceList
.append( allCondSpaces
+ c
);
296 void CodeGenData::newCondSpace( int cnum
, int condSpaceId
, Key baseKey
)
298 CondSpace
*cond
= allCondSpaces
+ cnum
;
299 cond
->condSpaceId
= condSpaceId
;
300 cond
->baseKey
= baseKey
;
303 void CodeGenData::condSpaceItem( int cnum
, long condActionId
)
305 CondSpace
*cond
= allCondSpaces
+ cnum
;
306 cond
->condSet
.append( allActions
+ condActionId
);
309 void CodeGenData::initStateCondList( int snum
, ulong length
)
311 /* Could preallocate these, as we could with transitions. */
314 void CodeGenData::addStateCond( int snum
, Key lowKey
, Key highKey
, long condNum
)
316 RedStateAp
*curState
= allStates
+ snum
;
318 /* Create the new state condition. */
319 StateCond
*stateCond
= new StateCond
;
320 stateCond
->lowKey
= lowKey
;
321 stateCond
->highKey
= highKey
;
323 /* Assign it a cond space. */
324 CondSpace
*condSpace
= allCondSpaces
+ condNum
;
325 stateCond
->condSpace
= condSpace
;
327 curState
->stateCondList
.append( stateCond
);
331 CondSpace
*CodeGenData::findCondSpace( Key lowKey
, Key highKey
)
333 for ( CondSpaceList::Iter cs
= condSpaceList
; cs
.lte(); cs
++ ) {
334 Key csHighKey
= cs
->baseKey
;
335 csHighKey
+= keyOps
->alphSize() * (1 << cs
->condSet
.length());
337 if ( lowKey
>= cs
->baseKey
&& highKey
<= csHighKey
)
343 Condition
*CodeGenData::findCondition( Key key
)
345 for ( ConditionList::Iter cond
= conditionList
; cond
.lte(); cond
++ ) {
346 Key upperKey
= cond
->baseKey
+ (1 << cond
->condSet
.length());
347 if ( cond
->baseKey
<= key
&& key
<= upperKey
)
353 Key
CodeGenData::findMaxKey()
355 Key maxKey
= keyOps
->maxKey
;
356 for ( RedStateList::Iter st
= redFsm
->stateList
; st
.lte(); st
++ ) {
357 assert( st
->outSingle
.length() == 0 );
358 assert( st
->defTrans
== 0 );
360 long rangeLen
= st
->outRange
.length();
361 if ( rangeLen
> 0 ) {
362 Key highKey
= st
->outRange
[rangeLen
-1].highKey
;
363 if ( highKey
> maxKey
)
370 void CodeGenData::findFinalActionRefs()
372 for ( RedStateList::Iter st
= redFsm
->stateList
; st
.lte(); st
++ ) {
373 /* Rerence count out of single transitions. */
374 for ( RedTransList::Iter rtel
= st
->outSingle
; rtel
.lte(); rtel
++ ) {
375 if ( rtel
->value
->action
!= 0 ) {
376 rtel
->value
->action
->numTransRefs
+= 1;
377 for ( ActionTable::Iter item
= rtel
->value
->action
->key
; item
.lte(); item
++ )
378 item
->value
->numTransRefs
+= 1;
382 /* Reference count out of range transitions. */
383 for ( RedTransList::Iter rtel
= st
->outRange
; rtel
.lte(); rtel
++ ) {
384 if ( rtel
->value
->action
!= 0 ) {
385 rtel
->value
->action
->numTransRefs
+= 1;
386 for ( ActionTable::Iter item
= rtel
->value
->action
->key
; item
.lte(); item
++ )
387 item
->value
->numTransRefs
+= 1;
391 /* Reference count default transition. */
392 if ( st
->defTrans
!= 0 && st
->defTrans
->action
!= 0 ) {
393 st
->defTrans
->action
->numTransRefs
+= 1;
394 for ( ActionTable::Iter item
= st
->defTrans
->action
->key
; item
.lte(); item
++ )
395 item
->value
->numTransRefs
+= 1;
398 /* Reference count to state actions. */
399 if ( st
->toStateAction
!= 0 ) {
400 st
->toStateAction
->numToStateRefs
+= 1;
401 for ( ActionTable::Iter item
= st
->toStateAction
->key
; item
.lte(); item
++ )
402 item
->value
->numToStateRefs
+= 1;
405 /* Reference count from state actions. */
406 if ( st
->fromStateAction
!= 0 ) {
407 st
->fromStateAction
->numFromStateRefs
+= 1;
408 for ( ActionTable::Iter item
= st
->fromStateAction
->key
; item
.lte(); item
++ )
409 item
->value
->numFromStateRefs
+= 1;
412 /* Reference count EOF actions. */
413 if ( st
->eofAction
!= 0 ) {
414 st
->eofAction
->numEofRefs
+= 1;
415 for ( ActionTable::Iter item
= st
->eofAction
->key
; item
.lte(); item
++ )
416 item
->value
->numEofRefs
+= 1;
421 void CodeGenData::analyzeAction( Action
*act
, InlineList
*inlineList
)
423 for ( InlineList::Iter item
= *inlineList
; item
.lte(); item
++ ) {
424 /* Only consider actions that are referenced. */
425 if ( act
->numRefs() > 0 ) {
426 if ( item
->type
== InlineItem::Goto
|| item
->type
== InlineItem::GotoExpr
)
427 redFsm
->bAnyActionGotos
= true;
428 else if ( item
->type
== InlineItem::Call
|| item
->type
== InlineItem::CallExpr
)
429 redFsm
->bAnyActionCalls
= true;
430 else if ( item
->type
== InlineItem::Ret
)
431 redFsm
->bAnyActionRets
= true;
434 /* Check for various things in regular actions. */
435 if ( act
->numTransRefs
> 0 || act
->numToStateRefs
> 0 || act
->numFromStateRefs
> 0 ) {
436 /* Any returns in regular actions? */
437 if ( item
->type
== InlineItem::Ret
)
438 redFsm
->bAnyRegActionRets
= true;
440 /* Any next statements in the regular actions? */
441 if ( item
->type
== InlineItem::Next
|| item
->type
== InlineItem::NextExpr
)
442 redFsm
->bAnyRegNextStmt
= true;
444 /* Any by value control in regular actions? */
445 if ( item
->type
== InlineItem::CallExpr
|| item
->type
== InlineItem::GotoExpr
)
446 redFsm
->bAnyRegActionByValControl
= true;
448 /* Any references to the current state in regular actions? */
449 if ( item
->type
== InlineItem::Curs
)
450 redFsm
->bAnyRegCurStateRef
= true;
452 if ( item
->type
== InlineItem::Break
)
453 redFsm
->bAnyRegBreak
= true;
456 if ( item
->children
!= 0 )
457 analyzeAction( act
, item
->children
);
461 void CodeGenData::analyzeActionList( RedAction
*redAct
, InlineList
*inlineList
)
463 for ( InlineList::Iter item
= *inlineList
; item
.lte(); item
++ ) {
464 /* Any next statements in the action table? */
465 if ( item
->type
== InlineItem::Next
|| item
->type
== InlineItem::NextExpr
)
466 redAct
->bAnyNextStmt
= true;
468 /* Any references to the current state. */
469 if ( item
->type
== InlineItem::Curs
)
470 redAct
->bAnyCurStateRef
= true;
472 if ( item
->type
== InlineItem::Break
)
473 redAct
->bAnyBreakStmt
= true;
475 if ( item
->children
!= 0 )
476 analyzeActionList( redAct
, item
->children
);
480 /* Assign ids to referenced actions. */
481 void CodeGenData::assignActionIds()
483 int nextActionId
= 0;
484 for ( ActionList::Iter act
= actionList
; act
.lte(); act
++ ) {
485 /* Only ever interested in referenced actions. */
486 if ( act
->numRefs() > 0 )
487 act
->actionId
= nextActionId
++;
491 void CodeGenData::setValueLimits()
493 redFsm
->maxSingleLen
= 0;
494 redFsm
->maxRangeLen
= 0;
495 redFsm
->maxKeyOffset
= 0;
496 redFsm
->maxIndexOffset
= 0;
497 redFsm
->maxActListId
= 0;
498 redFsm
->maxActionLoc
= 0;
499 redFsm
->maxActArrItem
= 0;
501 redFsm
->maxCondSpan
= 0;
502 redFsm
->maxFlatIndexOffset
= 0;
503 redFsm
->maxCondOffset
= 0;
504 redFsm
->maxCondLen
= 0;
505 redFsm
->maxCondSpaceId
= 0;
506 redFsm
->maxCondIndexOffset
= 0;
508 /* In both of these cases the 0 index is reserved for no value, so the max
509 * is one more than it would be if they started at 0. */
510 redFsm
->maxIndex
= redFsm
->transSet
.length();
511 redFsm
->maxCond
= condSpaceList
.length();
513 /* The nextStateId - 1 is the last state id assigned. */
514 redFsm
->maxState
= redFsm
->nextStateId
- 1;
516 for ( CondSpaceList::Iter csi
= condSpaceList
; csi
.lte(); csi
++ ) {
517 if ( csi
->condSpaceId
> redFsm
->maxCondSpaceId
)
518 redFsm
->maxCondSpaceId
= csi
->condSpaceId
;
521 for ( RedStateList::Iter st
= redFsm
->stateList
; st
.lte(); st
++ ) {
522 /* Maximum cond length. */
523 if ( st
->stateCondList
.length() > redFsm
->maxCondLen
)
524 redFsm
->maxCondLen
= st
->stateCondList
.length();
526 /* Maximum single length. */
527 if ( st
->outSingle
.length() > redFsm
->maxSingleLen
)
528 redFsm
->maxSingleLen
= st
->outSingle
.length();
530 /* Maximum range length. */
531 if ( st
->outRange
.length() > redFsm
->maxRangeLen
)
532 redFsm
->maxRangeLen
= st
->outRange
.length();
534 /* The key offset index offset for the state after last is not used, skip it.. */
536 redFsm
->maxCondOffset
+= st
->stateCondList
.length();
537 redFsm
->maxKeyOffset
+= st
->outSingle
.length() + st
->outRange
.length()*2;
538 redFsm
->maxIndexOffset
+= st
->outSingle
.length() + st
->outRange
.length() + 1;
542 if ( st
->condList
!= 0 ) {
543 unsigned long long span
= keyOps
->span( st
->condLowKey
, st
->condHighKey
);
544 if ( span
> redFsm
->maxCondSpan
)
545 redFsm
->maxCondSpan
= span
;
549 if ( st
->transList
!= 0 ) {
550 unsigned long long span
= keyOps
->span( st
->lowKey
, st
->highKey
);
551 if ( span
> redFsm
->maxSpan
)
552 redFsm
->maxSpan
= span
;
555 /* Max cond index offset. */
557 if ( st
->condList
!= 0 )
558 redFsm
->maxCondIndexOffset
+= keyOps
->span( st
->condLowKey
, st
->condHighKey
);
561 /* Max flat index offset. */
563 if ( st
->transList
!= 0 )
564 redFsm
->maxFlatIndexOffset
+= keyOps
->span( st
->lowKey
, st
->highKey
);
565 redFsm
->maxFlatIndexOffset
+= 1;
569 for ( ActionTableMap::Iter at
= redFsm
->actionMap
; at
.lte(); at
++ ) {
570 /* Maximum id of action lists. */
571 if ( at
->actListId
+1 > redFsm
->maxActListId
)
572 redFsm
->maxActListId
= at
->actListId
+1;
574 /* Maximum location of items in action array. */
575 if ( at
->location
+1 > redFsm
->maxActionLoc
)
576 redFsm
->maxActionLoc
= at
->location
+1;
578 /* Maximum values going into the action array. */
579 if ( at
->key
.length() > redFsm
->maxActArrItem
)
580 redFsm
->maxActArrItem
= at
->key
.length();
581 for ( ActionTable::Iter item
= at
->key
; item
.lte(); item
++ ) {
582 if ( item
->value
->actionId
> redFsm
->maxActArrItem
)
583 redFsm
->maxActArrItem
= item
->value
->actionId
;
590 /* Gather various info on the machine. */
591 void CodeGenData::analyzeMachine()
593 /* Find the true count of action references. */
594 findFinalActionRefs();
596 /* Check if there are any calls in action code. */
597 for ( ActionList::Iter act
= actionList
; act
.lte(); act
++ ) {
598 /* Record the occurrence of various kinds of actions. */
599 if ( act
->numToStateRefs
> 0 )
600 redFsm
->bAnyToStateActions
= true;
601 if ( act
->numFromStateRefs
> 0 )
602 redFsm
->bAnyFromStateActions
= true;
603 if ( act
->numEofRefs
> 0 )
604 redFsm
->bAnyEofActions
= true;
605 if ( act
->numTransRefs
> 0 )
606 redFsm
->bAnyRegActions
= true;
608 /* Recurse through the action's parse tree looking for various things. */
609 analyzeAction( act
, act
->inlineList
);
612 /* Analyze reduced action lists. */
613 for ( ActionTableMap::Iter redAct
= redFsm
->actionMap
; redAct
.lte(); redAct
++ ) {
614 for ( ActionTable::Iter act
= redAct
->key
; act
.lte(); act
++ )
615 analyzeActionList( redAct
, act
->value
->inlineList
);
618 /* Find states that have transitions with actions that have next
620 for ( RedStateList::Iter st
= redFsm
->stateList
; st
.lte(); st
++ ) {
621 /* Check any actions out of outSinge. */
622 for ( RedTransList::Iter rtel
= st
->outSingle
; rtel
.lte(); rtel
++ ) {
623 if ( rtel
->value
->action
!= 0 && rtel
->value
->action
->anyCurStateRef() )
624 st
->bAnyRegCurStateRef
= true;
627 /* Check any actions out of outRange. */
628 for ( RedTransList::Iter rtel
= st
->outRange
; rtel
.lte(); rtel
++ ) {
629 if ( rtel
->value
->action
!= 0 && rtel
->value
->action
->anyCurStateRef() )
630 st
->bAnyRegCurStateRef
= true;
633 /* Check any action out of default. */
634 if ( st
->defTrans
!= 0 && st
->defTrans
->action
!= 0 &&
635 st
->defTrans
->action
->anyCurStateRef() )
636 st
->bAnyRegCurStateRef
= true;
638 if ( st
->stateCondList
.length() > 0 )
639 redFsm
->bAnyConditions
= true;
642 /* Assign ids to actions that are referenced. */
645 /* Set the maximums of various values used for deciding types. */
649 void CodeGenData::writeStatement( InputLoc
&loc
, int nargs
, char **args
)
651 /* FIXME: This should be moved to the virtual functions in the code
654 * Force a newline. */
656 genLineDirective( out
);
658 if ( strcmp( args
[0], "data" ) == 0 ) {
659 for ( int i
= 1; i
< nargs
; i
++ ) {
660 if ( strcmp( args
[i
], "noerror" ) == 0 )
662 else if ( strcmp( args
[i
], "noprefix" ) == 0 )
664 else if ( strcmp( args
[i
], "nofinal" ) == 0 )
665 writeFirstFinal
= false;
667 source_warning(loc
) << "unrecognized write option \"" <<
668 args
[i
] << "\"" << endl
;
673 else if ( strcmp( args
[0], "init" ) == 0 ) {
674 for ( int i
= 1; i
< nargs
; i
++ ) {
675 if ( strcmp( args
[i
], "nocs" ) == 0 )
678 source_warning(loc
) << "unrecognized write option \"" <<
679 args
[i
] << "\"" << endl
;
684 else if ( strcmp( args
[0], "exec" ) == 0 ) {
685 for ( int i
= 1; i
< nargs
; i
++ ) {
686 if ( strcmp( args
[i
], "noend" ) == 0 )
689 source_warning(loc
) << "unrecognized write option \"" <<
690 args
[i
] << "\"" << endl
;
695 else if ( strcmp( args
[0], "eof" ) == 0 ) {
696 for ( int i
= 1; i
< nargs
; i
++ ) {
697 source_warning(loc
) << "unrecognized write option \"" <<
698 args
[i
] << "\"" << endl
;
702 else if ( strcmp( args
[0], "exports" ) == 0 ) {
703 for ( int i
= 1; i
< nargs
; i
++ ) {
704 source_warning(loc
) << "unrecognized write option \"" <<
705 args
[i
] << "\"" << endl
;
710 /* EMIT An error here. */
711 source_error(loc
) << "unrecognized write command \"" <<
712 args
[0] << "\"" << endl
;
716 ostream
&CodeGenData::source_warning( const InputLoc
&loc
)
718 cerr
<< sourceFileName
<< ":" << loc
.line
<< ":" << loc
.col
<< ": warning: ";
722 ostream
&CodeGenData::source_error( const InputLoc
&loc
)
725 assert( sourceFileName
!= 0 );
726 cerr
<< sourceFileName
<< ":" << loc
.line
<< ":" << loc
.col
<< ": ";