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     TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD,
306         NULL, AnOperandTypecheckWalkEnd, &AnalysisWalkInfo);
307     UtEndEvent (Event);
308 
309     /* Semantic error checking part four - other miscellaneous checks */
310 
311     Event = UtBeginEvent ("Miscellaneous analysis");
312     DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - miscellaneous\n\n");
313     TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD,
314         AnOtherSemanticAnalysisWalkBegin,
315         NULL, &AnalysisWalkInfo);
316     UtEndEvent (Event);
317 
318     /* Calculate all AML package lengths */
319 
320     Event = UtBeginEvent ("Finish AML package length generation");
321     DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating Package lengths\n\n");
322     TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
323         LnInitLengthsWalk, NULL);
324     TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
325         LnPackageLengthWalk, NULL);
326     UtEndEvent (Event);
327 
328     /* Code generation - emit the AML */
329 
330     Event = UtBeginEvent ("Generate AML code and write output files");
331     CgGenerateAmlOutput ();
332     UtEndEvent (Event);
333 
334     Event = UtBeginEvent ("Write optional output files");
335     CmDoOutputFiles ();
336     UtEndEvent (Event);
337 
338     UtEndEvent (FullCompile);
339     CmCleanupAndExit ();
340     return (0);
341 
342 ErrorExit:
343     UtEndEvent (FullCompile);
344     CmCleanupAndExit ();
345     return (-1);
346 }
347 
348 
349 /*******************************************************************************
350  *
351  * FUNCTION:    AslCompilerSignon
352  *
353  * PARAMETERS:  FileId      - ID of the output file
354  *
355  * RETURN:      None
356  *
357  * DESCRIPTION: Display compiler signon
358  *
359  ******************************************************************************/
360 
361 void
362 AslCompilerSignon (
363     UINT32                  FileId)
364 {
365     char                    *Prefix = "";
366     char                    *UtilityName;
367 
368 
369     /* Set line prefix depending on the destination file type */
370 
371     switch (FileId)
372     {
373     case ASL_FILE_ASM_SOURCE_OUTPUT:
374     case ASL_FILE_ASM_INCLUDE_OUTPUT:
375 
376         Prefix = "; ";
377         break;
378 
379     case ASL_FILE_HEX_OUTPUT:
380 
381         if (Gbl_HexOutputFlag == HEX_OUTPUT_ASM)
382         {
383             Prefix = "; ";
384         }
385         else if ((Gbl_HexOutputFlag == HEX_OUTPUT_C) ||
386                  (Gbl_HexOutputFlag == HEX_OUTPUT_ASL))
387         {
388             FlPrintFile (ASL_FILE_HEX_OUTPUT, "/*\n");
389             Prefix = " * ";
390         }
391         break;
392 
393     case ASL_FILE_C_SOURCE_OUTPUT:
394     case ASL_FILE_C_OFFSET_OUTPUT:
395     case ASL_FILE_C_INCLUDE_OUTPUT:
396 
397         Prefix = " * ";
398         break;
399 
400     default:
401 
402         /* No other output types supported */
403 
404         break;
405     }
406 
407     /* Running compiler or disassembler? */
408 
409     if (Gbl_DisasmFlag)
410     {
411         UtilityName = AML_DISASSEMBLER_NAME;
412     }
413     else
414     {
415         UtilityName = ASL_COMPILER_NAME;
416     }
417 
418     /* Compiler signon with copyright */
419 
420     FlPrintFile (FileId, "%s\n", Prefix);
421     FlPrintFile (FileId, ACPI_COMMON_HEADER (UtilityName, Prefix));
422 }
423 
424 
425 /*******************************************************************************
426  *
427  * FUNCTION:    AslCompilerFileHeader
428  *
429  * PARAMETERS:  FileId      - ID of the output file
430  *
431  * RETURN:      None
432  *
433  * DESCRIPTION: Header used at the beginning of output files
434  *
435  ******************************************************************************/
436 
437 void
438 AslCompilerFileHeader (
439     UINT32                  FileId)
440 {
441     struct tm               *NewTime;
442     time_t                  Aclock;
443     char                    *Prefix = "";
444 
445 
446     /* Set line prefix depending on the destination file type */
447 
448     switch (FileId)
449     {
450     case ASL_FILE_ASM_SOURCE_OUTPUT:
451     case ASL_FILE_ASM_INCLUDE_OUTPUT:
452 
453         Prefix = "; ";
454         break;
455 
456     case ASL_FILE_HEX_OUTPUT:
457 
458         if (Gbl_HexOutputFlag == HEX_OUTPUT_ASM)
459         {
460             Prefix = "; ";
461         }
462         else if ((Gbl_HexOutputFlag == HEX_OUTPUT_C) ||
463                  (Gbl_HexOutputFlag == HEX_OUTPUT_ASL))
464         {
465             Prefix = " * ";
466         }
467         break;
468 
469     case ASL_FILE_C_SOURCE_OUTPUT:
470     case ASL_FILE_C_OFFSET_OUTPUT:
471     case ASL_FILE_C_INCLUDE_OUTPUT:
472 
473         Prefix = " * ";
474         break;
475 
476     default:
477 
478         /* No other output types supported */
479 
480         break;
481     }
482 
483     /* Compilation header with timestamp */
484 
485     (void) time (&Aclock);
486     NewTime = localtime (&Aclock);
487 
488     FlPrintFile (FileId,
489         "%sCompilation of \"%s\" - %s%s\n",
490         Prefix, Gbl_Files[ASL_FILE_INPUT].Filename, asctime (NewTime),
491         Prefix);
492 
493     switch (FileId)
494     {
495     case ASL_FILE_C_SOURCE_OUTPUT:
496     case ASL_FILE_C_OFFSET_OUTPUT:
497     case ASL_FILE_C_INCLUDE_OUTPUT:
498 
499         FlPrintFile (FileId, " */\n");
500         break;
501 
502     default:
503 
504         /* Nothing to do for other output types */
505 
506         break;
507     }
508 }
509 
510 
511 /*******************************************************************************
512  *
513  * FUNCTION:    CmFlushSourceCode
514  *
515  * PARAMETERS:  None
516  *
517  * RETURN:      None
518  *
519  * DESCRIPTION: Read in any remaining source code after the parse tree
520  *              has been constructed.
521  *
522  ******************************************************************************/
523 
524 static void
525 CmFlushSourceCode (
526     void)
527 {
528     char                    Buffer;
529 
530 
531     while (FlReadFile (ASL_FILE_INPUT, &Buffer, 1) != AE_ERROR)
532     {
533         AslInsertLineBuffer ((int) Buffer);
534     }
535 
536     AslResetCurrentLineBuffer ();
537 }
538 
539 
540 /*******************************************************************************
541  *
542  * FUNCTION:    CmDoOutputFiles
543  *
544  * PARAMETERS:  None
545  *
546  * RETURN:      None.
547  *
548  * DESCRIPTION: Create all "listing" type files
549  *
550  ******************************************************************************/
551 
552 void
553 CmDoOutputFiles (
554     void)
555 {
556 
557     /* Create listings and hex files */
558 
559     LsDoListings ();
560     HxDoHexOutput ();
561 
562     /* Dump the namespace to the .nsp file if requested */
563 
564     (void) NsDisplayNamespace ();
565 
566     /* Dump the device mapping file */
567 
568     MpEmitMappingInfo ();
569 }
570 
571 
572 /*******************************************************************************
573  *
574  * FUNCTION:    CmDumpAllEvents
575  *
576  * PARAMETERS:  None
577  *
578  * RETURN:      None.
579  *
580  * DESCRIPTION: Dump all compiler events
581  *
582  ******************************************************************************/
583 
584 static void
585 CmDumpAllEvents (
586     void)
587 {
588     ASL_EVENT_INFO          *Event;
589     UINT32                  Delta;
590     UINT32                  USec;
591     UINT32                  MSec;
592     UINT32                  i;
593 
594 
595     Event = AslGbl_Events;
596 
597     DbgPrint (ASL_DEBUG_OUTPUT, "\n\nElapsed time for major events\n\n");
598     if (Gbl_CompileTimesFlag)
599     {
600         printf ("\nElapsed time for major events\n\n");
601     }
602 
603     for (i = 0; i < AslGbl_NextEvent; i++)
604     {
605         if (Event->Valid)
606         {
607             /* Delta will be in 100-nanosecond units */
608 
609             Delta = (UINT32) (Event->EndTime - Event->StartTime);
610 
611             USec = Delta / ACPI_100NSEC_PER_USEC;
612             MSec = Delta / ACPI_100NSEC_PER_MSEC;
613 
614             /* Round milliseconds up */
615 
616             if ((USec - (MSec * ACPI_USEC_PER_MSEC)) >= 500)
617             {
618                 MSec++;
619             }
620 
621             DbgPrint (ASL_DEBUG_OUTPUT, "%8u usec %8u msec - %s\n",
622                 USec, MSec, Event->EventName);
623 
624             if (Gbl_CompileTimesFlag)
625             {
626                 printf ("%8u usec %8u msec - %s\n",
627                     USec, MSec, Event->EventName);
628             }
629         }
630 
631         Event++;
632     }
633 }
634 
635 
636 /*******************************************************************************
637  *
638  * FUNCTION:    CmCleanupAndExit
639  *
640  * PARAMETERS:  None
641  *
642  * RETURN:      None.
643  *
644  * DESCRIPTION: Close all open files and exit the compiler
645  *
646  ******************************************************************************/
647 
648 void
649 CmCleanupAndExit (
650     void)
651 {
652     UINT32                  i;
653     BOOLEAN                 DeleteAmlFile = FALSE;
654 
655 
656     AePrintErrorLog (ASL_FILE_STDERR);
657     if (Gbl_DebugFlag)
658     {
659         /* Print error summary to stdout also */
660 
661         AePrintErrorLog (ASL_FILE_STDOUT);
662     }
663 
664     /* Emit compile times if enabled */
665 
666     CmDumpAllEvents ();
667 
668     if (Gbl_CompileTimesFlag)
669     {
670         printf ("\nMiscellaneous compile statistics\n\n");
671         printf ("%11u : %s\n", TotalParseNodes, "Parse nodes");
672         printf ("%11u : %s\n", Gbl_NsLookupCount, "Namespace searches");
673         printf ("%11u : %s\n", TotalNamedObjects, "Named objects");
674         printf ("%11u : %s\n", TotalMethods, "Control methods");
675         printf ("%11u : %s\n", TotalAllocations, "Memory Allocations");
676         printf ("%11u : %s\n", TotalAllocated, "Total allocated memory");
677         printf ("%11u : %s\n", TotalFolds, "Constant subtrees folded");
678         printf ("\n");
679     }
680 
681     if (Gbl_NsLookupCount)
682     {
683         DbgPrint (ASL_DEBUG_OUTPUT,
684             "\n\nMiscellaneous compile statistics\n\n");
685 
686         DbgPrint (ASL_DEBUG_OUTPUT,
687             "%32s : %u\n", "Total Namespace searches",
688             Gbl_NsLookupCount);
689 
690         DbgPrint (ASL_DEBUG_OUTPUT,
691             "%32s : %u usec\n", "Time per search", ((UINT32)
692             (AslGbl_Events[AslGbl_NamespaceEvent].EndTime -
693                 AslGbl_Events[AslGbl_NamespaceEvent].StartTime) / 10) /
694                 Gbl_NsLookupCount);
695     }
696 
697     if (Gbl_ExceptionCount[ASL_ERROR] > ASL_MAX_ERROR_COUNT)
698     {
699         printf ("\nMaximum error count (%u) exceeded\n",
700             ASL_MAX_ERROR_COUNT);
701     }
702 
703     UtDisplaySummary (ASL_FILE_STDOUT);
704 
705     /*
706      * We will delete the AML file if there are errors and the
707      * force AML output option has not been used.
708      */
709     if ((Gbl_ExceptionCount[ASL_ERROR] > 0) &&
710         (!Gbl_IgnoreErrors) &&
711         Gbl_Files[ASL_FILE_AML_OUTPUT].Handle)
712     {
713         DeleteAmlFile = TRUE;
714     }
715 
716     /* Close all open files */
717 
718     /*
719      * Take care with the preprocessor file (.pre), it might be the same
720      * as the "input" file, depending on where the compiler has terminated
721      * or aborted. Prevent attempt to close the same file twice in
722      * loop below.
723      */
724     if (Gbl_Files[ASL_FILE_PREPROCESSOR].Handle ==
725         Gbl_Files[ASL_FILE_INPUT].Handle)
726     {
727         Gbl_Files[ASL_FILE_PREPROCESSOR].Handle = NULL;
728     }
729 
730     /* Close the standard I/O files */
731 
732     for (i = ASL_FILE_INPUT; i < ASL_MAX_FILE_TYPE; i++)
733     {
734         FlCloseFile (i);
735     }
736 
737     /* Delete AML file if there are errors */
738 
739     if (DeleteAmlFile)
740     {
741         FlDeleteFile (ASL_FILE_AML_OUTPUT);
742     }
743 
744     /* Delete the preprocessor temp file unless full debug was specified */
745 
746     if (Gbl_PreprocessFlag && !Gbl_KeepPreprocessorTempFile)
747     {
748         FlDeleteFile (ASL_FILE_PREPROCESSOR);
749     }
750 
751     /*
752      * Delete intermediate ("combined") source file (if -ls flag not set)
753      * This file is created during normal ASL/AML compiles. It is not
754      * created by the data table compiler.
755      *
756      * If the -ls flag is set, then the .SRC file should not be deleted.
757      * In this case, Gbl_SourceOutputFlag is set to TRUE.
758      *
759      * Note: Handles are cleared by FlCloseFile above, so we look at the
760      * filename instead, to determine if the .SRC file was actually
761      * created.
762      */
763     if (!Gbl_SourceOutputFlag)
764     {
765         FlDeleteFile (ASL_FILE_SOURCE_OUTPUT);
766     }
767 
768     /* Final cleanup after compiling one file */
769 
770     CmDeleteCaches ();
771 }
772 
773 
774 /*******************************************************************************
775  *
776  * FUNCTION:    CmDeleteCaches
777  *
778  * PARAMETERS:  None
779  *
780  * RETURN:      None
781  *
782  * DESCRIPTION: Delete all local cache buffer blocks
783  *
784  ******************************************************************************/
785 
786 void
787 CmDeleteCaches (
788     void)
789 {
790     UINT32                  BufferCount;
791     ASL_CACHE_INFO          *Next;
792 
793 
794     /* Parse Op cache */
795 
796     BufferCount = 0;
797     while (Gbl_ParseOpCacheList)
798     {
799         Next = Gbl_ParseOpCacheList->Next;
800         ACPI_FREE (Gbl_ParseOpCacheList);
801         Gbl_ParseOpCacheList = Next;
802         BufferCount++;
803     }
804 
805     DbgPrint (ASL_DEBUG_OUTPUT,
806         "%u ParseOps, Buffer size: %u ops (%u bytes), %u Buffers\n",
807         Gbl_ParseOpCount, ASL_PARSEOP_CACHE_SIZE,
808         (sizeof (ACPI_PARSE_OBJECT) * ASL_PARSEOP_CACHE_SIZE), BufferCount);
809 
810     Gbl_ParseOpCount = 0;
811     Gbl_ParseOpCacheNext = NULL;
812     Gbl_ParseOpCacheLast = NULL;
813     RootNode = NULL;
814 
815     /* Generic string cache */
816 
817     BufferCount = 0;
818     while (Gbl_StringCacheList)
819     {
820         Next = Gbl_StringCacheList->Next;
821         ACPI_FREE (Gbl_StringCacheList);
822         Gbl_StringCacheList = Next;
823         BufferCount++;
824     }
825 
826     DbgPrint (ASL_DEBUG_OUTPUT,
827         "%u Strings (%u bytes), Buffer size: %u bytes, %u Buffers\n",
828         Gbl_StringCount, Gbl_StringSize, ASL_STRING_CACHE_SIZE, BufferCount);
829 
830     Gbl_StringSize = 0;
831     Gbl_StringCount = 0;
832     Gbl_StringCacheNext = NULL;
833     Gbl_StringCacheLast = NULL;
834 }
835