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