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