aslcompile.c revision 235945
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    FILE                    *Handle,
63    ASL_FILE_STATUS         *Status);
64
65static void
66FlConsumeNewComment (
67    FILE                    *Handle,
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:  Handle              - Open input file
257 *              Status              - File current status struct
258 *
259 * RETURN:      Number of lines consumed
260 *
261 * DESCRIPTION: Step over both types of comment during check for ascii chars
262 *
263 ******************************************************************************/
264
265static void
266FlConsumeAnsiComment (
267    FILE                    *Handle,
268    ASL_FILE_STATUS         *Status)
269{
270    UINT8                   Byte;
271    BOOLEAN                 ClosingComment = FALSE;
272
273
274    while (fread (&Byte, 1, 1, Handle))
275    {
276        /* Scan until comment close is found */
277
278        if (ClosingComment)
279        {
280            if (Byte == '/')
281            {
282                return;
283            }
284
285            if (Byte != '*')
286            {
287                /* Reset */
288
289                ClosingComment = FALSE;
290            }
291        }
292        else if (Byte == '*')
293        {
294            ClosingComment = TRUE;
295        }
296
297        /* Maintain line count */
298
299        if (Byte == 0x0A)
300        {
301            Status->Line++;
302        }
303
304        Status->Offset++;
305    }
306}
307
308
309static void
310FlConsumeNewComment (
311    FILE                    *Handle,
312    ASL_FILE_STATUS         *Status)
313{
314    UINT8                   Byte;
315
316
317    while (fread (&Byte, 1, 1, Handle))
318    {
319        Status->Offset++;
320
321        /* Comment ends at newline */
322
323        if (Byte == 0x0A)
324        {
325            Status->Line++;
326            return;
327        }
328    }
329}
330
331
332/*******************************************************************************
333 *
334 * FUNCTION:    FlCheckForAscii
335 *
336 * PARAMETERS:  Handle              - Open input file
337 *              Filename            - Input filename
338 *              DisplayErrors       - TRUE if error messages desired
339 *
340 * RETURN:      Status
341 *
342 * DESCRIPTION: Verify that the input file is entirely ASCII. Ignores characters
343 *              within comments. Note: does not handle nested comments and does
344 *              not handle comment delimiters within string literals. However,
345 *              on the rare chance this happens and an invalid character is
346 *              missed, the parser will catch the error by failing in some
347 *              spectactular manner.
348 *
349 ******************************************************************************/
350
351ACPI_STATUS
352FlCheckForAscii (
353    FILE                    *Handle,
354    char                    *Filename,
355    BOOLEAN                 DisplayErrors)
356{
357    UINT8                   Byte;
358    ACPI_SIZE               BadBytes = 0;
359    BOOLEAN                 OpeningComment = FALSE;
360    ASL_FILE_STATUS         Status;
361
362
363    Status.Line = 1;
364    Status.Offset = 0;
365
366    /* Read the entire file */
367
368    while (fread (&Byte, 1, 1, Handle))
369    {
370        /* Ignore comment fields (allow non-ascii within) */
371
372        if (OpeningComment)
373        {
374            /* Check for second comment open delimiter */
375
376            if (Byte == '*')
377            {
378                FlConsumeAnsiComment (Handle, &Status);
379            }
380
381            if (Byte == '/')
382            {
383                FlConsumeNewComment (Handle, &Status);
384            }
385
386            /* Reset */
387
388            OpeningComment = FALSE;
389        }
390        else if (Byte == '/')
391        {
392            OpeningComment = TRUE;
393        }
394
395        /* Check for an ASCII character */
396
397        if (!ACPI_IS_ASCII (Byte))
398        {
399            if ((BadBytes < 10) && (DisplayErrors))
400            {
401                AcpiOsPrintf (
402                    "Non-ASCII character [0x%2.2X] found in line %u, file offset 0x%.2X\n",
403                    Byte, Status.Line, Status.Offset);
404            }
405
406            BadBytes++;
407        }
408
409        /* Update line counter */
410
411        else if (Byte == 0x0A)
412        {
413            Status.Line++;
414        }
415
416        Status.Offset++;
417    }
418
419    /* Seek back to the beginning of the source file */
420
421    fseek (Handle, 0, SEEK_SET);
422
423    /* Were there any non-ASCII characters in the file? */
424
425    if (BadBytes)
426    {
427        if (DisplayErrors)
428        {
429            AcpiOsPrintf (
430                "%u non-ASCII characters found in input source text, could be a binary file\n",
431                BadBytes);
432            AslError (ASL_ERROR, ASL_MSG_NON_ASCII, NULL, Filename);
433        }
434
435        return (AE_BAD_CHARACTER);
436    }
437
438    /* File is OK (100% ASCII) */
439
440    return (AE_OK);
441}
442
443
444/*******************************************************************************
445 *
446 * FUNCTION:    CmDoCompile
447 *
448 * PARAMETERS:  None
449 *
450 * RETURN:      Status (0 = OK)
451 *
452 * DESCRIPTION: This procedure performs the entire compile
453 *
454 ******************************************************************************/
455
456int
457CmDoCompile (
458    void)
459{
460    ACPI_STATUS             Status;
461    UINT8                   FullCompile;
462    UINT8                   Event;
463
464
465    FullCompile = UtBeginEvent ("*** Total Compile time ***");
466    Event = UtBeginEvent ("Open input and output files");
467    UtEndEvent (Event);
468
469    Event = UtBeginEvent ("Preprocess input file");
470    if (Gbl_PreprocessFlag)
471    {
472        /* Preprocessor */
473
474        PrDoPreprocess ();
475        if (Gbl_PreprocessOnly)
476        {
477            UtEndEvent (Event);
478            CmCleanupAndExit ();
479            return 0;
480        }
481    }
482    UtEndEvent (Event);
483
484    /* Build the parse tree */
485
486    Event = UtBeginEvent ("Parse source code and build parse tree");
487    AslCompilerparse();
488    UtEndEvent (Event);
489
490    /* Flush out any remaining source after parse tree is complete */
491
492    Event = UtBeginEvent ("Flush source input");
493    CmFlushSourceCode ();
494
495    /* Did the parse tree get successfully constructed? */
496
497    if (!RootNode)
498    {
499        /*
500         * If there are no errors, then we have some sort of
501         * internal problem.
502         */
503        Status = AslCheckForErrorExit ();
504        if (Status == AE_OK)
505        {
506            AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL,
507                NULL, "- Could not resolve parse tree root node");
508        }
509
510        goto ErrorExit;
511    }
512
513    /* Optional parse tree dump, compiler debug output only */
514
515    LsDumpParseTree ();
516
517    OpcGetIntegerWidth (RootNode);
518    UtEndEvent (Event);
519
520    /* Pre-process parse tree for any operator transforms */
521
522    Event = UtBeginEvent ("Parse tree transforms");
523    DbgPrint (ASL_DEBUG_OUTPUT, "\nParse tree transforms\n\n");
524    TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD,
525        TrAmlTransformWalk, NULL, NULL);
526    UtEndEvent (Event);
527
528    /* Generate AML opcodes corresponding to the parse tokens */
529
530    Event = UtBeginEvent ("Generate AML opcodes");
531    DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating AML opcodes\n\n");
532    TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
533        OpcAmlOpcodeWalk, NULL);
534    UtEndEvent (Event);
535
536    /*
537     * Now that the input is parsed, we can open the AML output file.
538     * Note: by default, the name of this file comes from the table descriptor
539     * within the input file.
540     */
541    Event = UtBeginEvent ("Open AML output file");
542    Status = FlOpenAmlOutputFile (Gbl_OutputFilenamePrefix);
543    UtEndEvent (Event);
544    if (ACPI_FAILURE (Status))
545    {
546        AePrintErrorLog (ASL_FILE_STDERR);
547        return -1;
548    }
549
550    /* Interpret and generate all compile-time constants */
551
552    Event = UtBeginEvent ("Constant folding via AML interpreter");
553    DbgPrint (ASL_DEBUG_OUTPUT,
554        "\nInterpreting compile-time constant expressions\n\n");
555    TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD,
556        OpcAmlConstantWalk, NULL, NULL);
557    UtEndEvent (Event);
558
559    /* Update AML opcodes if necessary, after constant folding */
560
561    Event = UtBeginEvent ("Updating AML opcodes after constant folding");
562    DbgPrint (ASL_DEBUG_OUTPUT,
563        "\nUpdating AML opcodes after constant folding\n\n");
564    TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD,
565        NULL, OpcAmlOpcodeUpdateWalk, NULL);
566    UtEndEvent (Event);
567
568    /* Calculate all AML package lengths */
569
570    Event = UtBeginEvent ("Generate AML package lengths");
571    DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating Package lengths\n\n");
572    TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
573        LnPackageLengthWalk, NULL);
574    UtEndEvent (Event);
575
576    if (Gbl_ParseOnlyFlag)
577    {
578        AePrintErrorLog (ASL_FILE_STDERR);
579        UtDisplaySummary (ASL_FILE_STDERR);
580        if (Gbl_DebugFlag)
581        {
582            /* Print error summary to the stdout also */
583
584            AePrintErrorLog (ASL_FILE_STDOUT);
585            UtDisplaySummary (ASL_FILE_STDOUT);
586        }
587        UtEndEvent (FullCompile);
588        return 0;
589    }
590
591    /*
592     * Create an internal namespace and use it as a symbol table
593     */
594
595    /* Namespace loading */
596
597    Event = UtBeginEvent ("Create ACPI Namespace");
598    Status = LdLoadNamespace (RootNode);
599    UtEndEvent (Event);
600    if (ACPI_FAILURE (Status))
601    {
602        goto ErrorExit;
603    }
604
605    /* Namespace cross-reference */
606
607    AslGbl_NamespaceEvent = UtBeginEvent ("Cross reference parse tree and Namespace");
608    Status = LkCrossReferenceNamespace ();
609    if (ACPI_FAILURE (Status))
610    {
611        goto ErrorExit;
612    }
613
614    /* Namespace - Check for non-referenced objects */
615
616    LkFindUnreferencedObjects ();
617    UtEndEvent (AslGbl_NamespaceEvent);
618
619    /*
620     * Semantic analysis.  This can happen only after the
621     * namespace has been loaded and cross-referenced.
622     *
623     * part one - check control methods
624     */
625    Event = UtBeginEvent ("Analyze control method return types");
626    AnalysisWalkInfo.MethodStack = NULL;
627
628    DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Method analysis\n\n");
629    TrWalkParseTree (RootNode, ASL_WALK_VISIT_TWICE,
630        AnMethodAnalysisWalkBegin,
631        AnMethodAnalysisWalkEnd, &AnalysisWalkInfo);
632    UtEndEvent (Event);
633
634    /* Semantic error checking part two - typing of method returns */
635
636    Event = UtBeginEvent ("Determine object types returned by methods");
637    DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Method typing\n\n");
638    TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD,
639        NULL, AnMethodTypingWalkEnd, NULL);
640    UtEndEvent (Event);
641
642    /* Semantic error checking part three - operand type checking */
643
644    Event = UtBeginEvent ("Analyze AML operand types");
645    DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Operand type checking\n\n");
646    TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD,
647        NULL, AnOperandTypecheckWalkEnd, &AnalysisWalkInfo);
648    UtEndEvent (Event);
649
650    /* Semantic error checking part four - other miscellaneous checks */
651
652    Event = UtBeginEvent ("Miscellaneous analysis");
653    DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - miscellaneous\n\n");
654    TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD,
655        AnOtherSemanticAnalysisWalkBegin,
656        NULL, &AnalysisWalkInfo);
657    UtEndEvent (Event);
658
659    /* Calculate all AML package lengths */
660
661    Event = UtBeginEvent ("Finish AML package length generation");
662    DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating Package lengths\n\n");
663    TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
664        LnInitLengthsWalk, NULL);
665    TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
666        LnPackageLengthWalk, NULL);
667    UtEndEvent (Event);
668
669    /* Code generation - emit the AML */
670
671    Event = UtBeginEvent ("Generate AML code and write output files");
672    CgGenerateAmlOutput ();
673    UtEndEvent (Event);
674
675    Event = UtBeginEvent ("Write optional output files");
676    CmDoOutputFiles ();
677    UtEndEvent (Event);
678
679    UtEndEvent (FullCompile);
680    CmCleanupAndExit ();
681    return 0;
682
683ErrorExit:
684    UtEndEvent (FullCompile);
685    CmCleanupAndExit ();
686    return (-1);
687}
688
689
690/*******************************************************************************
691 *
692 * FUNCTION:    CmDoOutputFiles
693 *
694 * PARAMETERS:  None
695 *
696 * RETURN:      None.
697 *
698 * DESCRIPTION: Create all "listing" type files
699 *
700 ******************************************************************************/
701
702void
703CmDoOutputFiles (
704    void)
705{
706
707    /* Create listings and hex files */
708
709    LsDoListings ();
710    LsDoHexOutput ();
711
712    /* Dump the namespace to the .nsp file if requested */
713
714    (void) LsDisplayNamespace ();
715}
716
717
718/*******************************************************************************
719 *
720 * FUNCTION:    CmDumpEvent
721 *
722 * PARAMETERS:  Event           - A compiler event struct
723 *
724 * RETURN:      None.
725 *
726 * DESCRIPTION: Dump a compiler event struct
727 *
728 ******************************************************************************/
729
730static void
731CmDumpEvent (
732    ASL_EVENT_INFO          *Event)
733{
734    UINT32                  Delta;
735    UINT32                  USec;
736    UINT32                  MSec;
737
738    if (!Event->Valid)
739    {
740        return;
741    }
742
743    /* Delta will be in 100-nanosecond units */
744
745    Delta = (UINT32) (Event->EndTime - Event->StartTime);
746
747    USec = Delta / 10;
748    MSec = Delta / 10000;
749
750    /* Round milliseconds up */
751
752    if ((USec - (MSec * 1000)) >= 500)
753    {
754        MSec++;
755    }
756
757    DbgPrint (ASL_DEBUG_OUTPUT, "%8u usec %8u msec - %s\n",
758        USec, MSec, Event->EventName);
759}
760
761
762/*******************************************************************************
763 *
764 * FUNCTION:    CmCleanupAndExit
765 *
766 * PARAMETERS:  None
767 *
768 * RETURN:      None.
769 *
770 * DESCRIPTION: Close all open files and exit the compiler
771 *
772 ******************************************************************************/
773
774void
775CmCleanupAndExit (
776    void)
777{
778    UINT32                  i;
779
780
781    AePrintErrorLog (ASL_FILE_STDERR);
782    if (Gbl_DebugFlag)
783    {
784        /* Print error summary to stdout also */
785
786        AePrintErrorLog (ASL_FILE_STDOUT);
787    }
788
789    DbgPrint (ASL_DEBUG_OUTPUT, "\n\nElapsed time for major events\n\n");
790    for (i = 0; i < AslGbl_NextEvent; i++)
791    {
792        CmDumpEvent (&AslGbl_Events[i]);
793    }
794
795    if (Gbl_CompileTimesFlag)
796    {
797        printf ("\nElapsed time for major events\n\n");
798        for (i = 0; i < AslGbl_NextEvent; i++)
799        {
800            CmDumpEvent (&AslGbl_Events[i]);
801        }
802
803        printf ("\nMiscellaneous compile statistics\n\n");
804        printf ("%11u : %s\n", TotalParseNodes, "Parse nodes");
805        printf ("%11u : %s\n", Gbl_NsLookupCount, "Namespace searches");
806        printf ("%11u : %s\n", TotalNamedObjects, "Named objects");
807        printf ("%11u : %s\n", TotalMethods, "Control methods");
808        printf ("%11u : %s\n", TotalAllocations, "Memory Allocations");
809        printf ("%11u : %s\n", TotalAllocated, "Total allocated memory");
810        printf ("%11u : %s\n", TotalFolds, "Constant subtrees folded");
811        printf ("\n");
812    }
813
814    if (Gbl_NsLookupCount)
815    {
816        DbgPrint (ASL_DEBUG_OUTPUT,
817            "\n\nMiscellaneous compile statistics\n\n");
818
819        DbgPrint (ASL_DEBUG_OUTPUT,
820            "%32s : %u\n", "Total Namespace searches",
821            Gbl_NsLookupCount);
822
823        DbgPrint (ASL_DEBUG_OUTPUT,
824            "%32s : %u usec\n", "Time per search", ((UINT32)
825            (AslGbl_Events[AslGbl_NamespaceEvent].EndTime -
826                AslGbl_Events[AslGbl_NamespaceEvent].StartTime) / 10) /
827                Gbl_NsLookupCount);
828    }
829
830    if (Gbl_ExceptionCount[ASL_ERROR] > ASL_MAX_ERROR_COUNT)
831    {
832        printf ("\nMaximum error count (%u) exceeded\n",
833            ASL_MAX_ERROR_COUNT);
834    }
835
836    UtDisplaySummary (ASL_FILE_STDOUT);
837
838    /* Close all open files */
839
840    Gbl_Files[ASL_FILE_PREPROCESSOR].Handle = NULL; /* the .i file is same as source file */
841
842    for (i = ASL_FILE_INPUT; i < ASL_MAX_FILE_TYPE; i++)
843    {
844        FlCloseFile (i);
845    }
846
847    /* Delete AML file if there are errors */
848
849    if ((Gbl_ExceptionCount[ASL_ERROR] > 0) && (!Gbl_IgnoreErrors) &&
850        Gbl_Files[ASL_FILE_AML_OUTPUT].Handle)
851    {
852        if (remove (Gbl_Files[ASL_FILE_AML_OUTPUT].Filename))
853        {
854            printf ("%s: ",
855                Gbl_Files[ASL_FILE_AML_OUTPUT].Filename);
856            perror ("Could not delete AML file");
857        }
858    }
859
860    /* Delete the preprocessor output file (.i) unless -li flag is set */
861
862    if (!Gbl_PreprocessorOutputFlag &&
863        Gbl_PreprocessFlag &&
864        Gbl_Files[ASL_FILE_PREPROCESSOR].Filename)
865    {
866        if (remove (Gbl_Files[ASL_FILE_PREPROCESSOR].Filename))
867        {
868            printf ("%s: ",
869                Gbl_Files[ASL_FILE_PREPROCESSOR].Filename);
870            perror ("Could not delete preprocessor .i file");
871        }
872    }
873
874    /*
875     * Delete intermediate ("combined") source file (if -ls flag not set)
876     * This file is created during normal ASL/AML compiles. It is not
877     * created by the data table compiler.
878     *
879     * If the -ls flag is set, then the .SRC file should not be deleted.
880     * In this case, Gbl_SourceOutputFlag is set to TRUE.
881     *
882     * Note: Handles are cleared by FlCloseFile above, so we look at the
883     * filename instead, to determine if the .SRC file was actually
884     * created.
885     *
886     * TBD: SourceOutput should be .TMP, then rename if we want to keep it?
887     */
888    if (!Gbl_SourceOutputFlag && Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename)
889    {
890        if (remove (Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename))
891        {
892            printf ("%s: ",
893                Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename);
894            perror ("Could not delete SRC file");
895        }
896    }
897}
898
899
900