xref: /freebsd/sys/contrib/dev/acpica/compiler/aslcompile.c (revision 3ef51c5fb9163f2aafb1c14729e06a8bf0c4d113)
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         InsertLineBuffer ((int) Buffer);
246     }
247 
248     ResetCurrentLineBuffer ();
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     /* Preprocessor */
461 
462     Event = UtBeginEvent ("Preprocess input file");
463     PrDoPreprocess ();
464     UtEndEvent (Event);
465     if (Gbl_PreprocessOnly)
466     {
467         CmCleanupAndExit ();
468         return 0;
469     }
470 
471     /* Build the parse tree */
472 
473     Event = UtBeginEvent ("Parse source code and build parse tree");
474     AslCompilerparse();
475     UtEndEvent (Event);
476 
477     /* Flush out any remaining source after parse tree is complete */
478 
479     Event = UtBeginEvent ("Flush source input");
480     CmFlushSourceCode ();
481 
482     /* Did the parse tree get successfully constructed? */
483 
484     if (!RootNode)
485     {
486         AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL,
487             NULL, "- Could not resolve parse tree root node");
488         goto ErrorExit;
489     }
490 
491     /* Optional parse tree dump, compiler debug output only */
492 
493     LsDumpParseTree ();
494 
495     OpcGetIntegerWidth (RootNode);
496     UtEndEvent (Event);
497 
498     /* Pre-process parse tree for any operator transforms */
499 
500     Event = UtBeginEvent ("Parse tree transforms");
501     DbgPrint (ASL_DEBUG_OUTPUT, "\nParse tree transforms\n\n");
502     TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD,
503         TrAmlTransformWalk, NULL, NULL);
504     UtEndEvent (Event);
505 
506     /* Generate AML opcodes corresponding to the parse tokens */
507 
508     Event = UtBeginEvent ("Generate AML opcodes");
509     DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating AML opcodes\n\n");
510     TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
511         OpcAmlOpcodeWalk, NULL);
512     UtEndEvent (Event);
513 
514     /*
515      * Now that the input is parsed, we can open the AML output file.
516      * Note: by default, the name of this file comes from the table descriptor
517      * within the input file.
518      */
519     Event = UtBeginEvent ("Open AML output file");
520     Status = FlOpenAmlOutputFile (Gbl_OutputFilenamePrefix);
521     UtEndEvent (Event);
522     if (ACPI_FAILURE (Status))
523     {
524         AePrintErrorLog (ASL_FILE_STDERR);
525         return -1;
526     }
527 
528     /* Interpret and generate all compile-time constants */
529 
530     Event = UtBeginEvent ("Constant folding via AML interpreter");
531     DbgPrint (ASL_DEBUG_OUTPUT,
532         "\nInterpreting compile-time constant expressions\n\n");
533     TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD,
534         OpcAmlConstantWalk, NULL, NULL);
535     UtEndEvent (Event);
536 
537     /* Update AML opcodes if necessary, after constant folding */
538 
539     Event = UtBeginEvent ("Updating AML opcodes after constant folding");
540     DbgPrint (ASL_DEBUG_OUTPUT,
541         "\nUpdating AML opcodes after constant folding\n\n");
542     TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD,
543         NULL, OpcAmlOpcodeUpdateWalk, NULL);
544     UtEndEvent (Event);
545 
546     /* Calculate all AML package lengths */
547 
548     Event = UtBeginEvent ("Generate AML package lengths");
549     DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating Package lengths\n\n");
550     TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
551         LnPackageLengthWalk, NULL);
552     UtEndEvent (Event);
553 
554     if (Gbl_ParseOnlyFlag)
555     {
556         AePrintErrorLog (ASL_FILE_STDOUT);
557         UtDisplaySummary (ASL_FILE_STDOUT);
558         if (Gbl_DebugFlag)
559         {
560             /* Print error summary to the debug file */
561 
562             AePrintErrorLog (ASL_FILE_STDERR);
563             UtDisplaySummary (ASL_FILE_STDERR);
564         }
565         UtEndEvent (FullCompile);
566         return 0;
567     }
568 
569     /*
570      * Create an internal namespace and use it as a symbol table
571      */
572 
573     /* Namespace loading */
574 
575     Event = UtBeginEvent ("Create ACPI Namespace");
576     Status = LdLoadNamespace (RootNode);
577     UtEndEvent (Event);
578     if (ACPI_FAILURE (Status))
579     {
580         goto ErrorExit;
581     }
582 
583     /* Namespace cross-reference */
584 
585     AslGbl_NamespaceEvent = UtBeginEvent ("Cross reference parse tree and Namespace");
586     Status = LkCrossReferenceNamespace ();
587     if (ACPI_FAILURE (Status))
588     {
589         goto ErrorExit;
590     }
591 
592     /* Namespace - Check for non-referenced objects */
593 
594     LkFindUnreferencedObjects ();
595     UtEndEvent (AslGbl_NamespaceEvent);
596 
597     /*
598      * Semantic analysis.  This can happen only after the
599      * namespace has been loaded and cross-referenced.
600      *
601      * part one - check control methods
602      */
603     Event = UtBeginEvent ("Analyze control method return types");
604     AnalysisWalkInfo.MethodStack = NULL;
605 
606     DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Method analysis\n\n");
607     TrWalkParseTree (RootNode, ASL_WALK_VISIT_TWICE,
608         AnMethodAnalysisWalkBegin,
609         AnMethodAnalysisWalkEnd, &AnalysisWalkInfo);
610     UtEndEvent (Event);
611 
612     /* Semantic error checking part two - typing of method returns */
613 
614     Event = UtBeginEvent ("Determine object types returned by methods");
615     DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Method typing\n\n");
616     TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD,
617         NULL, AnMethodTypingWalkEnd, NULL);
618     UtEndEvent (Event);
619 
620     /* Semantic error checking part three - operand type checking */
621 
622     Event = UtBeginEvent ("Analyze AML operand types");
623     DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Operand type checking\n\n");
624     TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD,
625         NULL, AnOperandTypecheckWalkEnd, &AnalysisWalkInfo);
626     UtEndEvent (Event);
627 
628     /* Semantic error checking part four - other miscellaneous checks */
629 
630     Event = UtBeginEvent ("Miscellaneous analysis");
631     DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - miscellaneous\n\n");
632     TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD,
633         AnOtherSemanticAnalysisWalkBegin,
634         NULL, &AnalysisWalkInfo);
635     UtEndEvent (Event);
636 
637     /* Calculate all AML package lengths */
638 
639     Event = UtBeginEvent ("Finish AML package length generation");
640     DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating Package lengths\n\n");
641     TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
642         LnInitLengthsWalk, NULL);
643     TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
644         LnPackageLengthWalk, NULL);
645     UtEndEvent (Event);
646 
647     /* Code generation - emit the AML */
648 
649     Event = UtBeginEvent ("Generate AML code and write output files");
650     CgGenerateAmlOutput ();
651     UtEndEvent (Event);
652 
653     Event = UtBeginEvent ("Write optional output files");
654     CmDoOutputFiles ();
655     UtEndEvent (Event);
656 
657     UtEndEvent (FullCompile);
658     CmCleanupAndExit ();
659     return 0;
660 
661 ErrorExit:
662     UtEndEvent (FullCompile);
663     CmCleanupAndExit ();
664     return (-1);
665 }
666 
667 
668 /*******************************************************************************
669  *
670  * FUNCTION:    CmDoOutputFiles
671  *
672  * PARAMETERS:  None
673  *
674  * RETURN:      None.
675  *
676  * DESCRIPTION: Create all "listing" type files
677  *
678  ******************************************************************************/
679 
680 void
681 CmDoOutputFiles (
682     void)
683 {
684 
685     /* Create listings and hex files */
686 
687     LsDoListings ();
688     LsDoHexOutput ();
689 
690     /* Dump the namespace to the .nsp file if requested */
691 
692     (void) LsDisplayNamespace ();
693 }
694 
695 
696 /*******************************************************************************
697  *
698  * FUNCTION:    CmDumpEvent
699  *
700  * PARAMETERS:  Event           - A compiler event struct
701  *
702  * RETURN:      None.
703  *
704  * DESCRIPTION: Dump a compiler event struct
705  *
706  ******************************************************************************/
707 
708 static void
709 CmDumpEvent (
710     ASL_EVENT_INFO          *Event)
711 {
712     UINT32                  Delta;
713     UINT32                  USec;
714     UINT32                  MSec;
715 
716     if (!Event->Valid)
717     {
718         return;
719     }
720 
721     /* Delta will be in 100-nanosecond units */
722 
723     Delta = (UINT32) (Event->EndTime - Event->StartTime);
724 
725     USec = Delta / 10;
726     MSec = Delta / 10000;
727 
728     /* Round milliseconds up */
729 
730     if ((USec - (MSec * 1000)) >= 500)
731     {
732         MSec++;
733     }
734 
735     DbgPrint (ASL_DEBUG_OUTPUT, "%8u usec %8u msec - %s\n",
736         USec, MSec, Event->EventName);
737 }
738 
739 
740 /*******************************************************************************
741  *
742  * FUNCTION:    CmCleanupAndExit
743  *
744  * PARAMETERS:  None
745  *
746  * RETURN:      None.
747  *
748  * DESCRIPTION: Close all open files and exit the compiler
749  *
750  ******************************************************************************/
751 
752 void
753 CmCleanupAndExit (
754     void)
755 {
756     UINT32                  i;
757 
758 
759     AePrintErrorLog (ASL_FILE_STDOUT);
760     if (Gbl_DebugFlag)
761     {
762         /* Print error summary to the debug file */
763 
764         AePrintErrorLog (ASL_FILE_STDERR);
765     }
766 
767     DbgPrint (ASL_DEBUG_OUTPUT, "\n\nElapsed time for major events\n\n");
768     for (i = 0; i < AslGbl_NextEvent; i++)
769     {
770         CmDumpEvent (&AslGbl_Events[i]);
771     }
772 
773     if (Gbl_CompileTimesFlag)
774     {
775         printf ("\nElapsed time for major events\n\n");
776         for (i = 0; i < AslGbl_NextEvent; i++)
777         {
778             CmDumpEvent (&AslGbl_Events[i]);
779         }
780 
781         printf ("\nMiscellaneous compile statistics\n\n");
782         printf ("%11u : %s\n", TotalParseNodes, "Parse nodes");
783         printf ("%11u : %s\n", Gbl_NsLookupCount, "Namespace searches");
784         printf ("%11u : %s\n", TotalNamedObjects, "Named objects");
785         printf ("%11u : %s\n", TotalMethods, "Control methods");
786         printf ("%11u : %s\n", TotalAllocations, "Memory Allocations");
787         printf ("%11u : %s\n", TotalAllocated, "Total allocated memory");
788         printf ("%11u : %s\n", TotalFolds, "Constant subtrees folded");
789         printf ("\n");
790     }
791 
792     if (Gbl_NsLookupCount)
793     {
794         DbgPrint (ASL_DEBUG_OUTPUT,
795             "\n\nMiscellaneous compile statistics\n\n");
796 
797         DbgPrint (ASL_DEBUG_OUTPUT,
798             "%32s : %u\n", "Total Namespace searches",
799             Gbl_NsLookupCount);
800 
801         DbgPrint (ASL_DEBUG_OUTPUT,
802             "%32s : %u usec\n", "Time per search", ((UINT32)
803             (AslGbl_Events[AslGbl_NamespaceEvent].EndTime -
804                 AslGbl_Events[AslGbl_NamespaceEvent].StartTime) / 10) /
805                 Gbl_NsLookupCount);
806     }
807 
808     if (Gbl_ExceptionCount[ASL_ERROR] > ASL_MAX_ERROR_COUNT)
809     {
810         printf ("\nMaximum error count (%u) exceeded\n",
811             ASL_MAX_ERROR_COUNT);
812     }
813 
814     UtDisplaySummary (ASL_FILE_STDOUT);
815 
816     /* Close all open files */
817 
818     Gbl_Files[ASL_FILE_PREPROCESSOR].Handle = NULL; /* the .i file is same as source file */
819 
820     for (i = ASL_FILE_INPUT; i < ASL_MAX_FILE_TYPE; i++)
821     {
822         FlCloseFile (i);
823     }
824 
825     /* Delete AML file if there are errors */
826 
827     if ((Gbl_ExceptionCount[ASL_ERROR] > 0) && (!Gbl_IgnoreErrors) &&
828         Gbl_Files[ASL_FILE_AML_OUTPUT].Handle)
829     {
830         if (remove (Gbl_Files[ASL_FILE_AML_OUTPUT].Filename))
831         {
832             printf ("%s: ",
833                 Gbl_Files[ASL_FILE_AML_OUTPUT].Filename);
834             perror ("Could not delete AML file");
835         }
836     }
837 
838     /* Delete the preprocessor output file (.i) unless -li flag is set */
839 
840     if (!Gbl_PreprocessorOutputFlag && Gbl_Files[ASL_FILE_PREPROCESSOR].Filename)
841     {
842         if (remove (Gbl_Files[ASL_FILE_PREPROCESSOR].Filename))
843         {
844             printf ("%s: ",
845                 Gbl_Files[ASL_FILE_PREPROCESSOR].Filename);
846             perror ("Could not delete preprocessor .i file");
847         }
848     }
849 
850     /*
851      * Delete intermediate ("combined") source file (if -ls flag not set)
852      * This file is created during normal ASL/AML compiles. It is not
853      * created by the data table compiler.
854      *
855      * If the -ls flag is set, then the .SRC file should not be deleted.
856      * In this case, Gbl_SourceOutputFlag is set to TRUE.
857      *
858      * Note: Handles are cleared by FlCloseFile above, so we look at the
859      * filename instead, to determine if the .SRC file was actually
860      * created.
861      *
862      * TBD: SourceOutput should be .TMP, then rename if we want to keep it?
863      */
864     if (!Gbl_SourceOutputFlag && Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename)
865     {
866         if (remove (Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename))
867         {
868             printf ("%s: ",
869                 Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename);
870             perror ("Could not delete SRC file");
871         }
872     }
873 }
874 
875 
876