if a static field is encountered, ignore it gracefully
[IRC.git] / Robust / src / IR / Flat / BCXPointsToCheckVRuntime.java
1 package IR.Flat;
2
3 import Analysis.Disjoint.HeapAnalysis;
4 import Analysis.Disjoint.Alloc;
5 import IR.*;
6
7 import java.io.*;
8 import java.util.*;
9
10
11 // This BuildCode Extension (BCX) takes a heap analysis
12 // with points-to information and generates checks at runtime
13 // verifies the allocation site of objects pointed-to.  It
14 // doesn't fully verify an analysis but it can reveal bugs!
15
16
17 public class BCXPointsToCheckVRuntime implements BuildCodeExtension {
18   
19   protected State        state;
20   protected BuildCode    buildCode;
21   protected TypeUtil     typeUtil;
22   protected HeapAnalysis heapAnalysis;
23   
24   protected ClassDescriptor cdObject;
25
26   protected TypeDescriptor stringType;
27
28   private boolean DEBUG = false;
29
30
31
32   public BCXPointsToCheckVRuntime( State        state,
33                                    BuildCode    buildCode,
34                                    TypeUtil     typeUtil,
35                                    HeapAnalysis heapAnalysis ) {
36     this.state        = state;
37     this.buildCode    = buildCode;
38     this.typeUtil     = typeUtil;
39     this.heapAnalysis = heapAnalysis;
40
41     ClassDescriptor cdString = typeUtil.getClass( typeUtil.StringClass );
42     assert cdString != null;
43     stringType = new TypeDescriptor( cdString );
44   }
45
46
47   public void additionalIncludesMethodsHeader(PrintWriter outmethodheader) {    
48     outmethodheader.println( "#include<stdio.h>" );
49     outmethodheader.println( "#include<execinfo.h>" );
50   }
51
52
53   public void additionalCodeAtTopFlatMethodBody(PrintWriter output, FlatMethod fm) {
54     
55     for( int i = 0; i < fm.numParameters(); ++i ) {
56       TempDescriptor td   = fm.getParameter( i );
57       TypeDescriptor type = td.getType();
58       if( type.isPtr() ) {
59         output.println( "// Generating points-to checks for method params" );
60
61         genAssertRuntimePtrVsHeapResults( output,
62                                           fm,
63                                           td,
64                                           heapAnalysis.canPointToAfter( td, fm )
65                                           );
66
67         output.println( "// end method params" );
68
69         if( DEBUG ) {
70           System.out.println( "\nGenerating code for "+fm );
71           System.out.println( "  arg "+td+" can point to "+heapAnalysis.canPointToAfter( td, fm ) );
72         }
73       }
74     }
75   }
76
77
78   public void additionalCodePreNode(FlatMethod fm, FlatNode fn, PrintWriter output) {
79     
80     TempDescriptor  lhs;
81     TempDescriptor  rhs;
82     FieldDescriptor fld;
83     TempDescriptor  idx;
84     TypeDescriptor  type;
85     TempDescriptor  arg;
86     TempDescriptor  ret;
87     
88
89     // for PRE-NODE checks, only look at pointers we are reading from because
90     // pointers about to be set may be undefined and don't pass runtime checks nicely
91
92     
93     switch( fn.kind() ) {
94     
95       /*
96       case FKind.FlatLiteralNode: {
97         FlatLiteralNode fln = (FlatLiteralNode) fn;
98         
99         if( fln.getType().equals( stringType ) ) {
100           lhs = fln.getDst();
101
102           output.println( "// Generating points-to checks for pre-node string literal" );
103
104           genAssertRuntimePtrVsHeapResults( output,
105                                             fm,
106                                             lhs,
107                                             heapAnalysis.canPointToAt( lhs, fn )
108                                             );
109       
110           output.println( "// end pre-node string literal" );
111
112
113           if( DEBUG ) {
114             System.out.println( "  before "+fn );
115             System.out.println( "    "+lhs+" can point to "+heapAnalysis.canPointToAt( lhs, fn ) );
116           }            
117         }  
118       } break;
119       */
120
121       case FKind.FlatOpNode: {
122         FlatOpNode fon = (FlatOpNode) fn;
123         if( fon.getOp().getOp() == Operation.ASSIGN ) {
124           lhs = fon.getDest();
125           rhs = fon.getLeft();
126       
127           type = lhs.getType();
128           if( type.isPtr() ) {
129
130             output.println( "// Generating points-to checks for pre-node op assign" );
131             
132
133             //genAssertRuntimePtrVsHeapResults( output,
134             //                                  fm,
135             //                                  lhs,
136             //                                  heapAnalysis.canPointToAt( lhs, fn )
137             //                                  );
138       
139             genAssertRuntimePtrVsHeapResults( output,
140                                               fm,
141                                               rhs,
142                                               heapAnalysis.canPointToAt( rhs, fn )
143                                               );
144
145             output.println( "// end pre-node op assign" );
146
147             
148             if( DEBUG ) {
149               System.out.println( "  before "+fn );
150               //System.out.println( "    "+lhs+" can point to "+heapAnalysis.canPointToAt( lhs, fn ) );
151               System.out.println( "    "+rhs+" can point to "+heapAnalysis.canPointToAt( rhs, fn ) );
152             }            
153           }
154         }
155       } break;
156       
157       
158       case FKind.FlatCastNode: {
159         FlatCastNode fcn = (FlatCastNode) fn;
160         lhs = fcn.getDst();
161         rhs = fcn.getSrc();
162       
163         type = fcn.getType();
164         if( type.isPtr() ) {
165
166           output.println( "// Generating points-to checks for pre-node cast" );
167
168           //genAssertRuntimePtrVsHeapResults( output,
169           //                                  fm,
170           //                                  lhs,
171           //                                  heapAnalysis.canPointToAt( lhs, fn )
172           //                                  );
173       
174           genAssertRuntimePtrVsHeapResults( output,
175                                             fm,
176                                             rhs,
177                                             heapAnalysis.canPointToAt( rhs, fn )
178                                             );
179
180           output.println( "// end pre-node cast" );
181
182
183           if( DEBUG ) {
184             System.out.println( "  before "+fn );
185             //System.out.println( "    "+lhs+" can point to "+heapAnalysis.canPointToAt( lhs, fn ) );
186             System.out.println( "    "+rhs+" can point to "+heapAnalysis.canPointToAt( rhs, fn ) );
187           }            
188         }
189       } break;
190       
191       
192       case FKind.FlatFieldNode: {
193         FlatFieldNode ffn = (FlatFieldNode) fn;
194         lhs = ffn.getDst();
195         rhs = ffn.getSrc();
196         fld = ffn.getField();
197       
198         type = lhs.getType();
199         if( type.isPtr() ) {
200
201           output.println( "// Generating points-to checks for pre-node field" );
202
203           //genAssertRuntimePtrVsHeapResults( output,
204           //                                  fm,
205           //                                  lhs,
206           //                                  heapAnalysis.canPointToAt( lhs, fn )
207           //                                  );
208
209           genAssertRuntimePtrVsHeapResults( output,
210                                             fm,
211                                             rhs,
212                                             heapAnalysis.canPointToAt( rhs, fn )
213                                             );
214       
215           genAssertRuntimePtrVsHeapResults( output,
216                                             fm,
217                                             rhs,
218                                             fld,
219                                             null,
220                                             heapAnalysis.canPointToAt( rhs, fld, fn )
221                                             );
222
223           output.println( "// end pre-node field" );
224
225
226           if( DEBUG ) {
227             System.out.println( "  before "+fn );
228             //System.out.println( "    "+lhs+" can point to "+heapAnalysis.canPointToAt( lhs, fn ) );
229             System.out.println( "    "+rhs+" can point to "+heapAnalysis.canPointToAt( rhs, fn ) );
230             System.out.println( "    "+rhs+"."+fld+" can point to "+heapAnalysis.canPointToAt( rhs, fld, fn ) );
231           }            
232         }
233       } break;
234       
235       
236       case FKind.FlatElementNode: {
237         FlatElementNode fen = (FlatElementNode) fn;
238         lhs = fen.getDst();
239         rhs = fen.getSrc();
240         idx = fen.getIndex();
241       
242         type = lhs.getType();
243         if( type.isPtr() ) {
244
245           output.println( "// Generating points-to checks for pre-node element" );
246
247           //genAssertRuntimePtrVsHeapResults( output,
248           //                                  fm,
249           //                                  lhs,
250           //                                  heapAnalysis.canPointToAt( lhs, fn )
251           //                                  );
252
253           genAssertRuntimePtrVsHeapResults( output,
254                                             fm,
255                                             rhs,
256                                             heapAnalysis.canPointToAt( rhs, fn )
257                                             );
258       
259           genAssertRuntimePtrVsHeapResults( output,
260                                             fm,
261                                             rhs,
262                                             null,
263                                             idx,
264                                             heapAnalysis.canPointToAtElement( rhs, fn )
265                                             );
266
267           output.println( "// end pre-node element" );
268
269
270           if( DEBUG ) {
271             System.out.println( "  before "+fn );
272             //System.out.println( "    "+lhs+" can point to "+heapAnalysis.canPointToAt( lhs, fn ) );
273             System.out.println( "    "+rhs+" can point to "+heapAnalysis.canPointToAt( rhs, fn ) );
274             System.out.println( "    "+rhs+"["+idx+"] can point to "+heapAnalysis.canPointToAtElement( rhs, fn ) );
275           }            
276         }
277       } break;
278
279
280       case FKind.FlatCall: {
281         FlatCall fc = (FlatCall) fn;
282         //ret = fc.getReturnTemp();
283         
284         FlatMethod fmCallee = state.getMethodFlat( fc.getMethod() );
285
286         boolean somethingChecked = false;
287
288         output.println( "// Generating points-to checks for pre-node call" );
289
290         for( int i = 0; i < fmCallee.numParameters(); ++i ) {
291           arg  = fc.getArgMatchingParamIndex( fmCallee, i );
292           type = arg.getType();
293           if( type.isPtr() ) {
294             genAssertRuntimePtrVsHeapResults( output,
295                                               fm,
296                                               arg,
297                                               heapAnalysis.canPointToAt( arg, fn )
298                                               );
299             somethingChecked = true;
300           }
301         }
302         
303         //if( ret != null ) {
304         //  type = ret.getType();
305         //  if( type.isPtr() ) {
306         //    genAssertRuntimePtrVsHeapResults( output,
307         //                                      fm,
308         //                                      ret,
309         //                                      heapAnalysis.canPointToAt( ret, fn )
310         //                                      );
311         //    somethingChecked = true;
312         //  }
313         //}
314          
315         output.println( "// end pre-node call" );
316
317         if( DEBUG && somethingChecked ) {
318
319           System.out.println( "  before "+fn+":" );
320               
321           for( int i = 0; i < fmCallee.numParameters(); ++i ) {
322             arg  = fc.getArgMatchingParamIndex( fmCallee, i );
323             type = arg.getType();
324             if( type.isPtr() ) {
325               System.out.println( "    arg "+arg+" can point to "+heapAnalysis.canPointToAt( arg, fn ) );
326             }
327           }  
328
329           //if( ret != null ) {
330           //  type = ret.getType();
331           //  if( type.isPtr() ) {
332           //    System.out.println( "    return temp "+ret+" can point to "+heapAnalysis.canPointToAt( ret, fn ) );
333           //  }
334           //}
335           
336         }
337       } break;    
338     }
339   }
340
341
342
343   public void additionalCodePostNode(FlatMethod fm,
344                                      FlatNode fn,
345                                      PrintWriter output) {
346
347     TempDescriptor  lhs;
348     TempDescriptor  rhs;
349     FieldDescriptor fld;
350     TempDescriptor  idx;
351     TypeDescriptor  type;
352     TempDescriptor  arg;
353     TempDescriptor  ret;
354
355
356
357     switch( fn.kind() ) {
358
359
360       case FKind.FlatLiteralNode: {
361         FlatLiteralNode fln = (FlatLiteralNode) fn;
362         
363         if( fln.getType().equals( stringType ) ) {
364           lhs = fln.getDst();
365           
366           output.println( "// Generating points-to checks for post-node string literal" );
367
368           genAssertRuntimePtrVsHeapResults( output,
369                                             fm,
370                                             lhs,
371                                             heapAnalysis.canPointToAfter( lhs, fn )
372                                             );
373       
374           output.println( "// end post-node string literal" );
375
376
377           if( DEBUG ) {
378             System.out.println( "  after "+fn );
379             System.out.println( "    "+lhs+" can point to "+heapAnalysis.canPointToAfter( lhs, fn ) );
380           }            
381         }  
382       } break;
383
384
385       case FKind.FlatOpNode: {
386         FlatOpNode fon = (FlatOpNode) fn;
387         if( fon.getOp().getOp() == Operation.ASSIGN ) {
388           lhs = fon.getDest();
389       
390           type = lhs.getType();
391           if( type.isPtr() ) {
392
393             output.println( "// Generating points-to checks for post-node op assign" );
394             
395             genAssertRuntimePtrVsHeapResults( output,
396                                               fm,
397                                               lhs,
398                                               heapAnalysis.canPointToAfter( lhs, fn )
399                                               );
400       
401             output.println( "// end post-node op assign" );
402
403             
404             if( DEBUG ) {
405               System.out.println( "  after "+fn );
406               System.out.println( "    "+lhs+" can point to "+heapAnalysis.canPointToAfter( lhs, fn ) );
407             }            
408           }
409         }
410       } break;
411       
412       
413       case FKind.FlatCastNode: {
414         FlatCastNode fcn = (FlatCastNode) fn;
415         lhs = fcn.getDst();
416       
417         type = fcn.getType();
418         if( type.isPtr() ) {
419
420           output.println( "// Generating points-to checks for post-node cast" );
421
422           genAssertRuntimePtrVsHeapResults( output,
423                                             fm,
424                                             lhs,
425                                             heapAnalysis.canPointToAfter( lhs, fn )
426                                             );
427       
428           output.println( "// end post-node cast" );
429
430
431           if( DEBUG ) {
432             System.out.println( "  after "+fn );
433             System.out.println( "    "+lhs+" can point to "+heapAnalysis.canPointToAfter( lhs, fn ) );
434           }            
435         }
436       } break;
437       
438       
439       case FKind.FlatFieldNode: {
440         FlatFieldNode ffn = (FlatFieldNode) fn;
441         lhs = ffn.getDst();
442       
443         type = lhs.getType();
444         if( type.isPtr() ) {
445
446           output.println( "// Generating points-to checks for post-node field" );
447
448           genAssertRuntimePtrVsHeapResults( output,
449                                             fm,
450                                             lhs,
451                                             heapAnalysis.canPointToAfter( lhs, fn )
452                                             );
453
454           output.println( "// end post-node field" );
455
456
457           if( DEBUG ) {
458             System.out.println( "  after "+fn );
459             System.out.println( "    "+lhs+" can point to "+heapAnalysis.canPointToAfter( lhs, fn ) );
460           }            
461         }
462       } break;
463       
464       
465       case FKind.FlatElementNode: {
466         FlatElementNode fen = (FlatElementNode) fn;
467         lhs = fen.getDst();
468       
469         type = lhs.getType();
470         if( type.isPtr() ) {
471
472           output.println( "// Generating points-to checks for post-node element" );
473
474           genAssertRuntimePtrVsHeapResults( output,
475                                             fm,
476                                             lhs,
477                                             heapAnalysis.canPointToAfter( lhs, fn )
478                                             );
479
480           output.println( "// end post-node element" );
481
482
483           if( DEBUG ) {
484             System.out.println( "  after "+fn );
485             System.out.println( "    "+lhs+" can point to "+heapAnalysis.canPointToAfter( lhs, fn ) );
486           }            
487         }
488       } break;
489
490
491       case FKind.FlatCall: {
492         FlatCall fc = (FlatCall) fn;
493         ret = fc.getReturnTemp();
494         
495         FlatMethod fmCallee = state.getMethodFlat( fc.getMethod() );
496
497         boolean somethingChecked = false;
498
499         output.println( "// Generating points-to checks for post-node call" );
500
501         for( int i = 0; i < fmCallee.numParameters(); ++i ) {
502           arg  = fc.getArgMatchingParamIndex( fmCallee, i );
503           type = arg.getType();
504           if( type.isPtr() ) {
505             genAssertRuntimePtrVsHeapResults( output,
506                                               fm,
507                                               arg,
508                                               heapAnalysis.canPointToAfter( arg, fn )
509                                               );
510             somethingChecked = true;
511           }
512         }
513         
514         if( ret != null ) {
515           type = ret.getType();
516           if( type.isPtr() ) {
517             genAssertRuntimePtrVsHeapResults( output,
518                                               fm,
519                                               ret,
520                                               heapAnalysis.canPointToAfter( ret, fn )
521                                               );
522             somethingChecked = true;
523           }
524         }
525          
526         output.println( "// end post-node call" );
527
528         if( DEBUG && somethingChecked ) {
529
530           System.out.println( "  after "+fn+":" );
531               
532           for( int i = 0; i < fmCallee.numParameters(); ++i ) {
533             arg  = fc.getArgMatchingParamIndex( fmCallee, i );
534             type = arg.getType();
535             if( type.isPtr() ) {
536               System.out.println( "    arg "+arg+" can point to "+heapAnalysis.canPointToAfter( arg, fn ) );
537             }
538           }  
539
540           if( ret != null ) {
541             type = ret.getType();
542             if( type.isPtr() ) {
543               System.out.println( "    return temp "+ret+" can point to "+heapAnalysis.canPointToAfter( ret, fn ) );
544             }
545           }
546           
547         }
548       } break;
549     }
550   }
551
552
553
554   protected void 
555     printConditionFailed( PrintWriter output,
556                           String      condition,
557                           String      pointer ) {
558
559     // don't do this in the constructor of this extension object because
560     // build code hasn't created any types or classes yet!
561     if( cdObject == null ) { 
562       cdObject = typeUtil.getClass( typeUtil.ObjectClass );
563       assert cdObject != null;
564     }
565
566     output.println( "printf(\"[[[ CHECK VS HEAP RESULTS FAILED ]]] Condition for failure( "+
567                     condition+" ) allocsite=%d at %s:%d\\n\", ((struct "+
568                     cdObject.getSafeSymbol()+"*)"+
569                     pointer+")->allocsite, __FILE__, __LINE__ );" );
570
571     // spit out the stack trace (so fancy!)
572     output.println( "{" );
573     output.println( "void* buffer[100];" );
574     output.println( "char** strings;" );
575     output.println( "int nptrs,j;" );
576     output.println( "nptrs = backtrace(buffer, 100);" );
577     output.println( "strings = backtrace_symbols(buffer, nptrs);" );
578     output.println( "if (strings == NULL) {" );
579     output.println( "  perror(\"backtrace_symbols\");" );
580     output.println( "}" );
581     output.println( "for (j = 0; j < nptrs; j++) {" );
582     output.println( "  printf(\"%s\\n\", strings[j]);" );
583     output.println( "}" );
584     output.println( "}" );
585   }
586                           
587
588
589
590   protected void 
591     genAssertRuntimePtrVsHeapResults( PrintWriter    output,
592                                       FlatMethod     context,
593                                       TempDescriptor x,
594                                       Set<Alloc>     targetsByAnalysis ) {
595
596     assert targetsByAnalysis != null;
597
598     output.println( "" );
599     output.println( "// checks vs. heap results (DEBUG) for "+x );
600     
601
602     if( targetsByAnalysis == HeapAnalysis.DONTCARE_PTR ) {
603       output.println( "// ANALYSIS DIDN'T CARE WHAT "+x+" POINTS-TO" );
604       return;
605     }
606
607     String ptr = buildCode.generateTemp( context, x );
608
609     String condition;
610     
611     if( targetsByAnalysis.isEmpty() ) {
612       condition = ptr+" != NULL";      
613       
614     } else {
615       condition = ptr+" != NULL &&";
616       
617       Iterator<Alloc> aItr = targetsByAnalysis.iterator();
618       while( aItr.hasNext() ) {
619         Alloc a = aItr.next();
620         condition += ptr+"->allocsite != "+a.getUniqueAllocSiteID();
621
622         if( aItr.hasNext() ) {
623           condition += " &&";
624         }
625       }      
626     }
627
628     output.println( "if( "+condition+" ) {" );
629     printConditionFailed( output, condition, ptr );
630     output.println( "}\n" );
631   }
632
633
634
635   protected void 
636     genAssertRuntimePtrVsHeapResults( PrintWriter                    output,
637                                       FlatMethod                     context,
638                                       TempDescriptor                 x,
639                                       FieldDescriptor                f, // this null OR
640                                       TempDescriptor                 i, // this null
641                                       Hashtable< Alloc, Set<Alloc> > targetsByAnalysis ) {
642     // I assume when you invoke this method you already
643     // invoked a check on just what x points to, don't duplicate
644     // AND assume the check to x passed
645
646     assert targetsByAnalysis != null;
647     
648     assert f == null || i == null;
649     
650     if( f != null ) {
651       output.println( "// checks vs. heap results (DEBUG) for "+x+"."+f );
652     } else {
653       output.println( "// checks vs. heap results (DEBUG) for "+x+"["+i+"]" );
654     }
655
656
657     if( targetsByAnalysis == HeapAnalysis.DONTCARE_DREF ) {
658       output.println( "// ANALYSIS DIDN'T CARE WHAT "+x+" POINTS-TO" );
659       return;
660     }
661     
662     
663     if( targetsByAnalysis.isEmpty() ) {
664       output.println( "// Should have already checked "+x+" is NULL" );
665
666     } else {
667       output.println( "{" );
668       
669       // if the ptr is null, that's ok, if not check allocsite
670       output.println( "if( "+
671                       buildCode.generateTemp( context, x )+
672                       " != NULL ) {" );
673       
674       // precompute the allocsite, if any, of the object we will
675       // get from hopping through the first ptr
676       output.println( "int allocsiteOneHop = -1;" );
677       output.println( buildCode.strObjType+"* objOneHop;" );
678       
679       if( f != null ) {
680         if( f.isStatic() ) {
681
682           // jjenista - DON'T DEAL WITH THIS RIGHT NOW
683           //ClassDescriptor cdX = ;
684           //output.println( "objOneHop = ("+buildCode.strObjType+"*) "+
685           //                
686           //                "->"+f.getSafeSymbol()+";");          
687           output.println( "}" );
688           output.println( "}" );
689           return;
690
691         } else {
692           output.println( "objOneHop = ("+buildCode.strObjType+"*) "+
693                           buildCode.generateTemp( context, x )+
694                           "->"+f.getSafeSymbol()+";");
695         }
696       } else {
697         // element access
698         output.println( "objOneHop = ("+buildCode.strObjType+"*) "+
699                         "((struct "+x.getType().dereference().getSafeSymbol()+"**)"+
700                         "(((void*) &("+buildCode.generateTemp( context, x )+"->___length___))+sizeof(int)))"+
701                         "["+buildCode.generateTemp( context, i )+"];" );
702       }
703       
704       output.println( "if( objOneHop != NULL ) { allocsiteOneHop = objOneHop->allocsite; }" );
705       
706       output.println( "switch( "+
707                       buildCode.generateTemp( context, x )+
708                       "->allocsite ) {" );
709       
710       Iterator<Alloc> kItr = targetsByAnalysis.keySet().iterator();
711       while( kItr.hasNext() ) {
712         Alloc k = kItr.next();
713         
714         output.print( "case "+
715                       k.getUniqueAllocSiteID()+
716                       ":" );
717
718         Set<Alloc> hopTargets = targetsByAnalysis.get( k );
719         if( hopTargets == HeapAnalysis.DONTCARE_PTR ) {
720           output.print( "/* ANALYSIS DOESN'T CARE */" );
721       
722         } else {
723           String condition = "allocsiteOneHop != -1";
724       
725           if( !hopTargets.isEmpty() ) {
726             condition += " && ";
727           }
728       
729           Iterator<Alloc> aItr = hopTargets.iterator();
730           while( aItr.hasNext() ) {
731             Alloc a = aItr.next();
732             
733             condition += 
734               "allocsiteOneHop != "+
735               a.getUniqueAllocSiteID();
736             
737             if( aItr.hasNext() ) {
738               condition += " && ";
739             }
740           }
741       
742           output.println( "if( "+condition+" ) {" );
743           printConditionFailed( output, condition, "objOneHop" );
744           output.println( "}" );
745         }
746         
747         output.println( "break;" );
748       }
749       
750       output.println( "default:" );
751       output.println( "// the previous condition for "+x+
752                       " should already report this failure point" );
753       output.println( "break;" );
754       output.println( "}" );
755       output.println( "}" );
756       output.println( "}\n" );
757     }
758   }
759
760
761
762
763   public void printExtraArrayFields(PrintWriter outclassdefs) {}
764   public void outputTransCode(PrintWriter output) {}
765   public void buildCodeSetup() {}
766   public void generateSizeArrayExtensions(PrintWriter outclassdefs) {}
767   public void preCodeGenInitialization() {}
768   public void postCodeGenCleanUp() {}
769   public void additionalClassObjectFields(PrintWriter outclassdefs) {}
770   public void additionalCodeGen(PrintWriter outmethodheader,
771                                    PrintWriter outstructs,
772                                    PrintWriter outmethod) {}
773   public void additionalCodeAtTopOfMain(PrintWriter outmethod) {}
774   public void additionalCodeForCommandLineArgs(PrintWriter outmethod, String argsVar) {}
775   public void additionalCodeAtBottomOfMain(PrintWriter outmethod) {}
776   public void additionalIncludesMethodsImplementation(PrintWriter outmethod) {}
777   public void additionalIncludesStructsHeader(PrintWriter outstructs) {}
778   public void additionalCodeAtTopMethodsImplementation(PrintWriter outmethod) {}
779   public void additionalCodeNewObject(PrintWriter outmethod, String dstVar, FlatNew flatNew) {}
780   public void additionalCodeNewStringLiteral(PrintWriter output, String dstVar) {}
781 }