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