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