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