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