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