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