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