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