xref: /freebsd/sys/contrib/dev/acpica/compiler/aslcompile.c (revision c243e4902be8df1e643c76b5f18b68bb77cc5268)
1 
2 /******************************************************************************
3  *
4  * Module Name: aslcompile - top level compile module
5  *
6  *****************************************************************************/
7 
8 /*
9  * Copyright (C) 2000 - 2012, Intel Corp.
10  * All rights reserved.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions, and the following disclaimer,
17  *    without modification.
18  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19  *    substantially similar to the "NO WARRANTY" disclaimer below
20  *    ("Disclaimer") and any redistribution must be conditioned upon
21  *    including a substantially similar Disclaimer requirement for further
22  *    binary redistribution.
23  * 3. Neither the names of the above-listed copyright holders nor the names
24  *    of any contributors may be used to endorse or promote products derived
25  *    from this software without specific prior written permission.
26  *
27  * Alternatively, this software may be distributed under the terms of the
28  * GNU General Public License ("GPL") version 2 as published by the Free
29  * Software Foundation.
30  *
31  * NO WARRANTY
32  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42  * POSSIBILITY OF SUCH DAMAGES.
43  */
44 
45 #include <contrib/dev/acpica/compiler/aslcompiler.h>
46 
47 #include <stdio.h>
48 #include <time.h>
49 #include <contrib/dev/acpica/include/acapps.h>
50 
51 #define _COMPONENT          ACPI_COMPILER
52         ACPI_MODULE_NAME    ("aslcompile")
53 
54 /* Local prototypes */
55 
56 static void
57 CmFlushSourceCode (
58     void);
59 
60 static void
61 FlConsumeAnsiComment (
62     FILE                    *Handle,
63     ASL_FILE_STATUS         *Status);
64 
65 static void
66 FlConsumeNewComment (
67     FILE                    *Handle,
68     ASL_FILE_STATUS         *Status);
69 
70 static void
71 CmDumpAllEvents (
72     void);
73 
74 
75 /*******************************************************************************
76  *
77  * FUNCTION:    AslCompilerSignon
78  *
79  * PARAMETERS:  FileId      - ID of the output file
80  *
81  * RETURN:      None
82  *
83  * DESCRIPTION: Display compiler signon
84  *
85  ******************************************************************************/
86 
87 void
88 AslCompilerSignon (
89     UINT32                  FileId)
90 {
91     char                    *Prefix = "";
92     char                    *UtilityName;
93 
94 
95     /* Set line prefix depending on the destination file type */
96 
97     switch (FileId)
98     {
99     case ASL_FILE_ASM_SOURCE_OUTPUT:
100     case ASL_FILE_ASM_INCLUDE_OUTPUT:
101 
102         Prefix = "; ";
103         break;
104 
105     case ASL_FILE_HEX_OUTPUT:
106 
107         if (Gbl_HexOutputFlag == HEX_OUTPUT_ASM)
108         {
109             Prefix = "; ";
110         }
111         else if ((Gbl_HexOutputFlag == HEX_OUTPUT_C) ||
112                  (Gbl_HexOutputFlag == HEX_OUTPUT_ASL))
113         {
114             FlPrintFile (ASL_FILE_HEX_OUTPUT, "/*\n");
115             Prefix = " * ";
116         }
117         break;
118 
119     case ASL_FILE_C_SOURCE_OUTPUT:
120     case ASL_FILE_C_INCLUDE_OUTPUT:
121 
122         Prefix = " * ";
123         break;
124 
125     default:
126         /* No other output types supported */
127         break;
128     }
129 
130     /* Running compiler or disassembler? */
131 
132     if (Gbl_DisasmFlag)
133     {
134         UtilityName = AML_DISASSEMBLER_NAME;
135     }
136     else
137     {
138         UtilityName = ASL_COMPILER_NAME;
139     }
140 
141     /* Compiler signon with copyright */
142 
143     FlPrintFile (FileId, "%s\n", Prefix);
144     FlPrintFile (FileId, ACPI_COMMON_HEADER (UtilityName, Prefix));
145 }
146 
147 
148 /*******************************************************************************
149  *
150  * FUNCTION:    AslCompilerFileHeader
151  *
152  * PARAMETERS:  FileId      - ID of the output file
153  *
154  * RETURN:      None
155  *
156  * DESCRIPTION: Header used at the beginning of output files
157  *
158  ******************************************************************************/
159 
160 void
161 AslCompilerFileHeader (
162     UINT32                  FileId)
163 {
164     struct tm               *NewTime;
165     time_t                  Aclock;
166     char                    *Prefix = "";
167 
168 
169     /* Set line prefix depending on the destination file type */
170 
171     switch (FileId)
172     {
173     case ASL_FILE_ASM_SOURCE_OUTPUT:
174     case ASL_FILE_ASM_INCLUDE_OUTPUT:
175 
176         Prefix = "; ";
177         break;
178 
179     case ASL_FILE_HEX_OUTPUT:
180 
181         if (Gbl_HexOutputFlag == HEX_OUTPUT_ASM)
182         {
183             Prefix = "; ";
184         }
185         else if ((Gbl_HexOutputFlag == HEX_OUTPUT_C) ||
186                  (Gbl_HexOutputFlag == HEX_OUTPUT_ASL))
187         {
188             Prefix = " * ";
189         }
190         break;
191 
192     case ASL_FILE_C_SOURCE_OUTPUT:
193     case ASL_FILE_C_INCLUDE_OUTPUT:
194 
195         Prefix = " * ";
196         break;
197 
198     default:
199         /* No other output types supported */
200         break;
201     }
202 
203     /* Compilation header with timestamp */
204 
205     (void) time (&Aclock);
206     NewTime = localtime (&Aclock);
207 
208     FlPrintFile (FileId,
209         "%sCompilation of \"%s\" - %s%s\n",
210         Prefix, Gbl_Files[ASL_FILE_INPUT].Filename, asctime (NewTime),
211         Prefix);
212 
213     switch (FileId)
214     {
215     case ASL_FILE_C_SOURCE_OUTPUT:
216     case ASL_FILE_C_INCLUDE_OUTPUT:
217         FlPrintFile (FileId, " */\n");
218         break;
219 
220     default:
221         /* Nothing to do for other output types */
222         break;
223     }
224 }
225 
226 
227 /*******************************************************************************
228  *
229  * FUNCTION:    CmFlushSourceCode
230  *
231  * PARAMETERS:  None
232  *
233  * RETURN:      None
234  *
235  * DESCRIPTION: Read in any remaining source code after the parse tree
236  *              has been constructed.
237  *
238  ******************************************************************************/
239 
240 static void
241 CmFlushSourceCode (
242     void)
243 {
244     char                    Buffer;
245 
246 
247     while (FlReadFile (ASL_FILE_INPUT, &Buffer, 1) != AE_ERROR)
248     {
249         AslInsertLineBuffer ((int) Buffer);
250     }
251 
252     AslResetCurrentLineBuffer ();
253 }
254 
255 
256 /*******************************************************************************
257  *
258  * FUNCTION:    FlConsume*
259  *
260  * PARAMETERS:  Handle              - Open input file
261  *              Status              - File current status struct
262  *
263  * RETURN:      Number of lines consumed
264  *
265  * DESCRIPTION: Step over both types of comment during check for ascii chars
266  *
267  ******************************************************************************/
268 
269 static void
270 FlConsumeAnsiComment (
271     FILE                    *Handle,
272     ASL_FILE_STATUS         *Status)
273 {
274     UINT8                   Byte;
275     BOOLEAN                 ClosingComment = FALSE;
276 
277 
278     while (fread (&Byte, 1, 1, Handle))
279     {
280         /* Scan until comment close is found */
281 
282         if (ClosingComment)
283         {
284             if (Byte == '/')
285             {
286                 return;
287             }
288 
289             if (Byte != '*')
290             {
291                 /* Reset */
292 
293                 ClosingComment = FALSE;
294             }
295         }
296         else if (Byte == '*')
297         {
298             ClosingComment = TRUE;
299         }
300 
301         /* Maintain line count */
302 
303         if (Byte == 0x0A)
304         {
305             Status->Line++;
306         }
307 
308         Status->Offset++;
309     }
310 }
311 
312 
313 static void
314 FlConsumeNewComment (
315     FILE                    *Handle,
316     ASL_FILE_STATUS         *Status)
317 {
318     UINT8                   Byte;
319 
320 
321     while (fread (&Byte, 1, 1, Handle))
322     {
323         Status->Offset++;
324 
325         /* Comment ends at newline */
326 
327         if (Byte == 0x0A)
328         {
329             Status->Line++;
330             return;
331         }
332     }
333 }
334 
335 
336 /*******************************************************************************
337  *
338  * FUNCTION:    FlCheckForAscii
339  *
340  * PARAMETERS:  Handle              - Open input file
341  *              Filename            - Input filename
342  *              DisplayErrors       - TRUE if error messages desired
343  *
344  * RETURN:      Status
345  *
346  * DESCRIPTION: Verify that the input file is entirely ASCII. Ignores characters
347  *              within comments. Note: does not handle nested comments and does
348  *              not handle comment delimiters within string literals. However,
349  *              on the rare chance this happens and an invalid character is
350  *              missed, the parser will catch the error by failing in some
351  *              spectactular manner.
352  *
353  ******************************************************************************/
354 
355 ACPI_STATUS
356 FlCheckForAscii (
357     FILE                    *Handle,
358     char                    *Filename,
359     BOOLEAN                 DisplayErrors)
360 {
361     UINT8                   Byte;
362     ACPI_SIZE               BadBytes = 0;
363     BOOLEAN                 OpeningComment = FALSE;
364     ASL_FILE_STATUS         Status;
365 
366 
367     Status.Line = 1;
368     Status.Offset = 0;
369 
370     /* Read the entire file */
371 
372     while (fread (&Byte, 1, 1, Handle))
373     {
374         /* Ignore comment fields (allow non-ascii within) */
375 
376         if (OpeningComment)
377         {
378             /* Check for second comment open delimiter */
379 
380             if (Byte == '*')
381             {
382                 FlConsumeAnsiComment (Handle, &Status);
383             }
384 
385             if (Byte == '/')
386             {
387                 FlConsumeNewComment (Handle, &Status);
388             }
389 
390             /* Reset */
391 
392             OpeningComment = FALSE;
393         }
394         else if (Byte == '/')
395         {
396             OpeningComment = TRUE;
397         }
398 
399         /* Check for an ASCII character */
400 
401         if (!ACPI_IS_ASCII (Byte))
402         {
403             if ((BadBytes < 10) && (DisplayErrors))
404             {
405                 AcpiOsPrintf (
406                     "Non-ASCII character [0x%2.2X] found in line %u, file offset 0x%.2X\n",
407                     Byte, Status.Line, Status.Offset);
408             }
409 
410             BadBytes++;
411         }
412 
413         /* Update line counter */
414 
415         else if (Byte == 0x0A)
416         {
417             Status.Line++;
418         }
419 
420         Status.Offset++;
421     }
422 
423     /* Seek back to the beginning of the source file */
424 
425     fseek (Handle, 0, SEEK_SET);
426 
427     /* Were there any non-ASCII characters in the file? */
428 
429     if (BadBytes)
430     {
431         if (DisplayErrors)
432         {
433             AcpiOsPrintf (
434                 "%u non-ASCII characters found in input source text, could be a binary file\n",
435                 BadBytes);
436             AslError (ASL_ERROR, ASL_MSG_NON_ASCII, NULL, Filename);
437         }
438 
439         return (AE_BAD_CHARACTER);
440     }
441 
442     /* File is OK (100% ASCII) */
443 
444     return (AE_OK);
445 }
446 
447 
448 /*******************************************************************************
449  *
450  * FUNCTION:    CmDoCompile
451  *
452  * PARAMETERS:  None
453  *
454  * RETURN:      Status (0 = OK)
455  *
456  * DESCRIPTION: This procedure performs the entire compile
457  *
458  ******************************************************************************/
459 
460 int
461 CmDoCompile (
462     void)
463 {
464     ACPI_STATUS             Status;
465     UINT8                   FullCompile;
466     UINT8                   Event;
467 
468 
469     FullCompile = UtBeginEvent ("*** Total Compile time ***");
470     Event = UtBeginEvent ("Open input and output files");
471     UtEndEvent (Event);
472 
473     Event = UtBeginEvent ("Preprocess input file");
474     if (Gbl_PreprocessFlag)
475     {
476         /* Preprocessor */
477 
478         PrDoPreprocess ();
479         if (Gbl_PreprocessOnly)
480         {
481             UtEndEvent (Event);
482             CmCleanupAndExit ();
483             return 0;
484         }
485     }
486     UtEndEvent (Event);
487 
488     /* Build the parse tree */
489 
490     Event = UtBeginEvent ("Parse source code and build parse tree");
491     AslCompilerparse();
492     UtEndEvent (Event);
493 
494     /* Flush out any remaining source after parse tree is complete */
495 
496     Event = UtBeginEvent ("Flush source input");
497     CmFlushSourceCode ();
498 
499     /* Did the parse tree get successfully constructed? */
500 
501     if (!RootNode)
502     {
503         /*
504          * If there are no errors, then we have some sort of
505          * internal problem.
506          */
507         Status = AslCheckForErrorExit ();
508         if (Status == AE_OK)
509         {
510             AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL,
511                 NULL, "- Could not resolve parse tree root node");
512         }
513 
514         goto ErrorExit;
515     }
516 
517     /* Optional parse tree dump, compiler debug output only */
518 
519     LsDumpParseTree ();
520 
521     OpcGetIntegerWidth (RootNode);
522     UtEndEvent (Event);
523 
524     /* Pre-process parse tree for any operator transforms */
525 
526     Event = UtBeginEvent ("Parse tree transforms");
527     DbgPrint (ASL_DEBUG_OUTPUT, "\nParse tree transforms\n\n");
528     TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD,
529         TrAmlTransformWalk, NULL, NULL);
530     UtEndEvent (Event);
531 
532     /* Generate AML opcodes corresponding to the parse tokens */
533 
534     Event = UtBeginEvent ("Generate AML opcodes");
535     DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating AML opcodes\n\n");
536     TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
537         OpcAmlOpcodeWalk, NULL);
538     UtEndEvent (Event);
539 
540     /*
541      * Now that the input is parsed, we can open the AML output file.
542      * Note: by default, the name of this file comes from the table descriptor
543      * within the input file.
544      */
545     Event = UtBeginEvent ("Open AML output file");
546     Status = FlOpenAmlOutputFile (Gbl_OutputFilenamePrefix);
547     UtEndEvent (Event);
548     if (ACPI_FAILURE (Status))
549     {
550         AePrintErrorLog (ASL_FILE_STDERR);
551         return -1;
552     }
553 
554     /* Interpret and generate all compile-time constants */
555 
556     Event = UtBeginEvent ("Constant folding via AML interpreter");
557     DbgPrint (ASL_DEBUG_OUTPUT,
558         "\nInterpreting compile-time constant expressions\n\n");
559     TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD,
560         OpcAmlConstantWalk, NULL, NULL);
561     UtEndEvent (Event);
562 
563     /* Update AML opcodes if necessary, after constant folding */
564 
565     Event = UtBeginEvent ("Updating AML opcodes after constant folding");
566     DbgPrint (ASL_DEBUG_OUTPUT,
567         "\nUpdating AML opcodes after constant folding\n\n");
568     TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD,
569         NULL, OpcAmlOpcodeUpdateWalk, NULL);
570     UtEndEvent (Event);
571 
572     /* Calculate all AML package lengths */
573 
574     Event = UtBeginEvent ("Generate AML package lengths");
575     DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating Package lengths\n\n");
576     TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
577         LnPackageLengthWalk, NULL);
578     UtEndEvent (Event);
579 
580     if (Gbl_ParseOnlyFlag)
581     {
582         AePrintErrorLog (ASL_FILE_STDERR);
583         UtDisplaySummary (ASL_FILE_STDERR);
584         if (Gbl_DebugFlag)
585         {
586             /* Print error summary to the stdout also */
587 
588             AePrintErrorLog (ASL_FILE_STDOUT);
589             UtDisplaySummary (ASL_FILE_STDOUT);
590         }
591         UtEndEvent (FullCompile);
592         return 0;
593     }
594 
595     /*
596      * Create an internal namespace and use it as a symbol table
597      */
598 
599     /* Namespace loading */
600 
601     Event = UtBeginEvent ("Create ACPI Namespace");
602     Status = LdLoadNamespace (RootNode);
603     UtEndEvent (Event);
604     if (ACPI_FAILURE (Status))
605     {
606         goto ErrorExit;
607     }
608 
609     /* Namespace cross-reference */
610 
611     AslGbl_NamespaceEvent = UtBeginEvent ("Cross reference parse tree and Namespace");
612     Status = LkCrossReferenceNamespace ();
613     if (ACPI_FAILURE (Status))
614     {
615         goto ErrorExit;
616     }
617 
618     /* Namespace - Check for non-referenced objects */
619 
620     LkFindUnreferencedObjects ();
621     UtEndEvent (AslGbl_NamespaceEvent);
622 
623     /*
624      * Semantic analysis.  This can happen only after the
625      * namespace has been loaded and cross-referenced.
626      *
627      * part one - check control methods
628      */
629     Event = UtBeginEvent ("Analyze control method return types");
630     AnalysisWalkInfo.MethodStack = NULL;
631 
632     DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Method analysis\n\n");
633     TrWalkParseTree (RootNode, ASL_WALK_VISIT_TWICE,
634         AnMethodAnalysisWalkBegin,
635         AnMethodAnalysisWalkEnd, &AnalysisWalkInfo);
636     UtEndEvent (Event);
637 
638     /* Semantic error checking part two - typing of method returns */
639 
640     Event = UtBeginEvent ("Determine object types returned by methods");
641     DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Method typing\n\n");
642     TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD,
643         NULL, AnMethodTypingWalkEnd, NULL);
644     UtEndEvent (Event);
645 
646     /* Semantic error checking part three - operand type checking */
647 
648     Event = UtBeginEvent ("Analyze AML operand types");
649     DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Operand type checking\n\n");
650     TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD,
651         NULL, AnOperandTypecheckWalkEnd, &AnalysisWalkInfo);
652     UtEndEvent (Event);
653 
654     /* Semantic error checking part four - other miscellaneous checks */
655 
656     Event = UtBeginEvent ("Miscellaneous analysis");
657     DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - miscellaneous\n\n");
658     TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD,
659         AnOtherSemanticAnalysisWalkBegin,
660         NULL, &AnalysisWalkInfo);
661     UtEndEvent (Event);
662 
663     /* Calculate all AML package lengths */
664 
665     Event = UtBeginEvent ("Finish AML package length generation");
666     DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating Package lengths\n\n");
667     TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
668         LnInitLengthsWalk, NULL);
669     TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
670         LnPackageLengthWalk, NULL);
671     UtEndEvent (Event);
672 
673     /* Code generation - emit the AML */
674 
675     Event = UtBeginEvent ("Generate AML code and write output files");
676     CgGenerateAmlOutput ();
677     UtEndEvent (Event);
678 
679     Event = UtBeginEvent ("Write optional output files");
680     CmDoOutputFiles ();
681     UtEndEvent (Event);
682 
683     UtEndEvent (FullCompile);
684     CmCleanupAndExit ();
685     return 0;
686 
687 ErrorExit:
688     UtEndEvent (FullCompile);
689     CmCleanupAndExit ();
690     return (-1);
691 }
692 
693 
694 /*******************************************************************************
695  *
696  * FUNCTION:    CmDoOutputFiles
697  *
698  * PARAMETERS:  None
699  *
700  * RETURN:      None.
701  *
702  * DESCRIPTION: Create all "listing" type files
703  *
704  ******************************************************************************/
705 
706 void
707 CmDoOutputFiles (
708     void)
709 {
710 
711     /* Create listings and hex files */
712 
713     LsDoListings ();
714     LsDoHexOutput ();
715 
716     /* Dump the namespace to the .nsp file if requested */
717 
718     (void) LsDisplayNamespace ();
719 }
720 
721 
722 /*******************************************************************************
723  *
724  * FUNCTION:    CmDumpAllEvents
725  *
726  * PARAMETERS:  None
727  *
728  * RETURN:      None.
729  *
730  * DESCRIPTION: Dump all compiler events
731  *
732  ******************************************************************************/
733 
734 static void
735 CmDumpAllEvents (
736     void)
737 {
738     ASL_EVENT_INFO          *Event;
739     UINT32                  Delta;
740     UINT32                  USec;
741     UINT32                  MSec;
742     UINT32                  i;
743 
744 
745     Event = AslGbl_Events;
746 
747     DbgPrint (ASL_DEBUG_OUTPUT, "\n\nElapsed time for major events\n\n");
748     if (Gbl_CompileTimesFlag)
749     {
750         printf ("\nElapsed time for major events\n\n");
751     }
752 
753     for (i = 0; i < AslGbl_NextEvent; i++)
754     {
755         if (Event->Valid)
756         {
757             /* Delta will be in 100-nanosecond units */
758 
759             Delta = (UINT32) (Event->EndTime - Event->StartTime);
760 
761             USec = Delta / 10;
762             MSec = Delta / 10000;
763 
764             /* Round milliseconds up */
765 
766             if ((USec - (MSec * 1000)) >= 500)
767             {
768                 MSec++;
769             }
770 
771             DbgPrint (ASL_DEBUG_OUTPUT, "%8u usec %8u msec - %s\n",
772                 USec, MSec, Event->EventName);
773 
774             if (Gbl_CompileTimesFlag)
775             {
776                 printf ("%8u usec %8u msec - %s\n",
777                     USec, MSec, Event->EventName);
778             }
779         }
780 
781         Event++;
782     }
783 }
784 
785 
786 /*******************************************************************************
787  *
788  * FUNCTION:    CmCleanupAndExit
789  *
790  * PARAMETERS:  None
791  *
792  * RETURN:      None.
793  *
794  * DESCRIPTION: Close all open files and exit the compiler
795  *
796  ******************************************************************************/
797 
798 void
799 CmCleanupAndExit (
800     void)
801 {
802     UINT32                  i;
803 
804 
805     AePrintErrorLog (ASL_FILE_STDERR);
806     if (Gbl_DebugFlag)
807     {
808         /* Print error summary to stdout also */
809 
810         AePrintErrorLog (ASL_FILE_STDOUT);
811     }
812 
813     /* Emit compile times if enabled */
814 
815     CmDumpAllEvents ();
816 
817     if (Gbl_CompileTimesFlag)
818     {
819         printf ("\nMiscellaneous compile statistics\n\n");
820         printf ("%11u : %s\n", TotalParseNodes, "Parse nodes");
821         printf ("%11u : %s\n", Gbl_NsLookupCount, "Namespace searches");
822         printf ("%11u : %s\n", TotalNamedObjects, "Named objects");
823         printf ("%11u : %s\n", TotalMethods, "Control methods");
824         printf ("%11u : %s\n", TotalAllocations, "Memory Allocations");
825         printf ("%11u : %s\n", TotalAllocated, "Total allocated memory");
826         printf ("%11u : %s\n", TotalFolds, "Constant subtrees folded");
827         printf ("\n");
828     }
829 
830     if (Gbl_NsLookupCount)
831     {
832         DbgPrint (ASL_DEBUG_OUTPUT,
833             "\n\nMiscellaneous compile statistics\n\n");
834 
835         DbgPrint (ASL_DEBUG_OUTPUT,
836             "%32s : %u\n", "Total Namespace searches",
837             Gbl_NsLookupCount);
838 
839         DbgPrint (ASL_DEBUG_OUTPUT,
840             "%32s : %u usec\n", "Time per search", ((UINT32)
841             (AslGbl_Events[AslGbl_NamespaceEvent].EndTime -
842                 AslGbl_Events[AslGbl_NamespaceEvent].StartTime) / 10) /
843                 Gbl_NsLookupCount);
844     }
845 
846     if (Gbl_ExceptionCount[ASL_ERROR] > ASL_MAX_ERROR_COUNT)
847     {
848         printf ("\nMaximum error count (%u) exceeded\n",
849             ASL_MAX_ERROR_COUNT);
850     }
851 
852     UtDisplaySummary (ASL_FILE_STDOUT);
853 
854     /* Close all open files */
855 
856     Gbl_Files[ASL_FILE_PREPROCESSOR].Handle = NULL; /* the .i file is same as source file */
857 
858     for (i = ASL_FILE_INPUT; i < ASL_MAX_FILE_TYPE; i++)
859     {
860         FlCloseFile (i);
861     }
862 
863     /* Delete AML file if there are errors */
864 
865     if ((Gbl_ExceptionCount[ASL_ERROR] > 0) && (!Gbl_IgnoreErrors) &&
866         Gbl_Files[ASL_FILE_AML_OUTPUT].Handle)
867     {
868         if (remove (Gbl_Files[ASL_FILE_AML_OUTPUT].Filename))
869         {
870             printf ("%s: ",
871                 Gbl_Files[ASL_FILE_AML_OUTPUT].Filename);
872             perror ("Could not delete AML file");
873         }
874     }
875 
876     /* Delete the preprocessor output file (.i) unless -li flag is set */
877 
878     if (!Gbl_PreprocessorOutputFlag &&
879         Gbl_PreprocessFlag &&
880         Gbl_Files[ASL_FILE_PREPROCESSOR].Filename)
881     {
882         if (remove (Gbl_Files[ASL_FILE_PREPROCESSOR].Filename))
883         {
884             printf ("%s: ",
885                 Gbl_Files[ASL_FILE_PREPROCESSOR].Filename);
886             perror ("Could not delete preprocessor .i file");
887         }
888     }
889 
890     /*
891      * Delete intermediate ("combined") source file (if -ls flag not set)
892      * This file is created during normal ASL/AML compiles. It is not
893      * created by the data table compiler.
894      *
895      * If the -ls flag is set, then the .SRC file should not be deleted.
896      * In this case, Gbl_SourceOutputFlag is set to TRUE.
897      *
898      * Note: Handles are cleared by FlCloseFile above, so we look at the
899      * filename instead, to determine if the .SRC file was actually
900      * created.
901      *
902      * TBD: SourceOutput should be .TMP, then rename if we want to keep it?
903      */
904     if (!Gbl_SourceOutputFlag && Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename)
905     {
906         if (remove (Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename))
907         {
908             printf ("%s: ",
909                 Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename);
910             perror ("Could not delete SRC file");
911         }
912     }
913 }
914 
915 
916