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