aslcompile.c revision 243347
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/*
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 */
58int
59AslCompilerparse(
60    void);
61
62/* Local prototypes */
63
64static void
65CmFlushSourceCode (
66    void);
67
68static void
69FlConsumeAnsiComment (
70    FILE                    *Handle,
71    ASL_FILE_STATUS         *Status);
72
73static void
74FlConsumeNewComment (
75    FILE                    *Handle,
76    ASL_FILE_STATUS         *Status);
77
78static void
79CmDumpAllEvents (
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
95void
96AslCompilerSignon (
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
168void
169AslCompilerFileHeader (
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
248static void
249CmFlushSourceCode (
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
277static void
278FlConsumeAnsiComment (
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
321static void
322FlConsumeNewComment (
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
363ACPI_STATUS
364FlCheckForAscii (
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
468int
469CmDoCompile (
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 = LkCrossReferenceNamespace ();
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        AnMethodAnalysisWalkBegin,
643        AnMethodAnalysisWalkEnd, &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
695ErrorExit:
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
714void
715CmDoOutputFiles (
716    void)
717{
718
719    /* Create listings and hex files */
720
721    LsDoListings ();
722    LsDoHexOutput ();
723
724    /* Dump the namespace to the .nsp file if requested */
725
726    (void) LsDisplayNamespace ();
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
742static void
743CmDumpAllEvents (
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 / 10;
770            MSec = Delta / 10000;
771
772            /* Round milliseconds up */
773
774            if ((USec - (MSec * 1000)) >= 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
806void
807CmCleanupAndExit (
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}
916