1 /****************************************************************************** 2 * 3 * Module Name: aslcompile - top level compile module 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2012, 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 46 #include <stdio.h> 47 #include <time.h> 48 #include <contrib/dev/acpica/include/acapps.h> 49 50 #define _COMPONENT ACPI_COMPILER 51 ACPI_MODULE_NAME ("aslcompile") 52 53 /* 54 * Main parser entry 55 * External is here in case the parser emits the same external in the 56 * generated header. (Newer versions of Bison) 57 */ 58 int 59 AslCompilerparse( 60 void); 61 62 /* Local prototypes */ 63 64 static void 65 CmFlushSourceCode ( 66 void); 67 68 static void 69 FlConsumeAnsiComment ( 70 FILE *Handle, 71 ASL_FILE_STATUS *Status); 72 73 static void 74 FlConsumeNewComment ( 75 FILE *Handle, 76 ASL_FILE_STATUS *Status); 77 78 static void 79 CmDumpAllEvents ( 80 void); 81 82 83 /******************************************************************************* 84 * 85 * FUNCTION: AslCompilerSignon 86 * 87 * PARAMETERS: FileId - ID of the output file 88 * 89 * RETURN: None 90 * 91 * DESCRIPTION: Display compiler signon 92 * 93 ******************************************************************************/ 94 95 void 96 AslCompilerSignon ( 97 UINT32 FileId) 98 { 99 char *Prefix = ""; 100 char *UtilityName; 101 102 103 /* Set line prefix depending on the destination file type */ 104 105 switch (FileId) 106 { 107 case ASL_FILE_ASM_SOURCE_OUTPUT: 108 case ASL_FILE_ASM_INCLUDE_OUTPUT: 109 110 Prefix = "; "; 111 break; 112 113 case ASL_FILE_HEX_OUTPUT: 114 115 if (Gbl_HexOutputFlag == HEX_OUTPUT_ASM) 116 { 117 Prefix = "; "; 118 } 119 else if ((Gbl_HexOutputFlag == HEX_OUTPUT_C) || 120 (Gbl_HexOutputFlag == HEX_OUTPUT_ASL)) 121 { 122 FlPrintFile (ASL_FILE_HEX_OUTPUT, "/*\n"); 123 Prefix = " * "; 124 } 125 break; 126 127 case ASL_FILE_C_SOURCE_OUTPUT: 128 case ASL_FILE_C_INCLUDE_OUTPUT: 129 130 Prefix = " * "; 131 break; 132 133 default: 134 /* No other output types supported */ 135 break; 136 } 137 138 /* Running compiler or disassembler? */ 139 140 if (Gbl_DisasmFlag) 141 { 142 UtilityName = AML_DISASSEMBLER_NAME; 143 } 144 else 145 { 146 UtilityName = ASL_COMPILER_NAME; 147 } 148 149 /* Compiler signon with copyright */ 150 151 FlPrintFile (FileId, "%s\n", Prefix); 152 FlPrintFile (FileId, ACPI_COMMON_HEADER (UtilityName, Prefix)); 153 } 154 155 156 /******************************************************************************* 157 * 158 * FUNCTION: AslCompilerFileHeader 159 * 160 * PARAMETERS: FileId - ID of the output file 161 * 162 * RETURN: None 163 * 164 * DESCRIPTION: Header used at the beginning of output files 165 * 166 ******************************************************************************/ 167 168 void 169 AslCompilerFileHeader ( 170 UINT32 FileId) 171 { 172 struct tm *NewTime; 173 time_t Aclock; 174 char *Prefix = ""; 175 176 177 /* Set line prefix depending on the destination file type */ 178 179 switch (FileId) 180 { 181 case ASL_FILE_ASM_SOURCE_OUTPUT: 182 case ASL_FILE_ASM_INCLUDE_OUTPUT: 183 184 Prefix = "; "; 185 break; 186 187 case ASL_FILE_HEX_OUTPUT: 188 189 if (Gbl_HexOutputFlag == HEX_OUTPUT_ASM) 190 { 191 Prefix = "; "; 192 } 193 else if ((Gbl_HexOutputFlag == HEX_OUTPUT_C) || 194 (Gbl_HexOutputFlag == HEX_OUTPUT_ASL)) 195 { 196 Prefix = " * "; 197 } 198 break; 199 200 case ASL_FILE_C_SOURCE_OUTPUT: 201 case ASL_FILE_C_INCLUDE_OUTPUT: 202 203 Prefix = " * "; 204 break; 205 206 default: 207 /* No other output types supported */ 208 break; 209 } 210 211 /* Compilation header with timestamp */ 212 213 (void) time (&Aclock); 214 NewTime = localtime (&Aclock); 215 216 FlPrintFile (FileId, 217 "%sCompilation of \"%s\" - %s%s\n", 218 Prefix, Gbl_Files[ASL_FILE_INPUT].Filename, asctime (NewTime), 219 Prefix); 220 221 switch (FileId) 222 { 223 case ASL_FILE_C_SOURCE_OUTPUT: 224 case ASL_FILE_C_INCLUDE_OUTPUT: 225 FlPrintFile (FileId, " */\n"); 226 break; 227 228 default: 229 /* Nothing to do for other output types */ 230 break; 231 } 232 } 233 234 235 /******************************************************************************* 236 * 237 * FUNCTION: CmFlushSourceCode 238 * 239 * PARAMETERS: None 240 * 241 * RETURN: None 242 * 243 * DESCRIPTION: Read in any remaining source code after the parse tree 244 * has been constructed. 245 * 246 ******************************************************************************/ 247 248 static void 249 CmFlushSourceCode ( 250 void) 251 { 252 char Buffer; 253 254 255 while (FlReadFile (ASL_FILE_INPUT, &Buffer, 1) != AE_ERROR) 256 { 257 AslInsertLineBuffer ((int) Buffer); 258 } 259 260 AslResetCurrentLineBuffer (); 261 } 262 263 264 /******************************************************************************* 265 * 266 * FUNCTION: FlConsume* 267 * 268 * PARAMETERS: Handle - Open input file 269 * Status - File current status struct 270 * 271 * RETURN: Number of lines consumed 272 * 273 * DESCRIPTION: Step over both types of comment during check for ascii chars 274 * 275 ******************************************************************************/ 276 277 static void 278 FlConsumeAnsiComment ( 279 FILE *Handle, 280 ASL_FILE_STATUS *Status) 281 { 282 UINT8 Byte; 283 BOOLEAN ClosingComment = FALSE; 284 285 286 while (fread (&Byte, 1, 1, Handle) == 1) 287 { 288 /* Scan until comment close is found */ 289 290 if (ClosingComment) 291 { 292 if (Byte == '/') 293 { 294 return; 295 } 296 297 if (Byte != '*') 298 { 299 /* Reset */ 300 301 ClosingComment = FALSE; 302 } 303 } 304 else if (Byte == '*') 305 { 306 ClosingComment = TRUE; 307 } 308 309 /* Maintain line count */ 310 311 if (Byte == 0x0A) 312 { 313 Status->Line++; 314 } 315 316 Status->Offset++; 317 } 318 } 319 320 321 static void 322 FlConsumeNewComment ( 323 FILE *Handle, 324 ASL_FILE_STATUS *Status) 325 { 326 UINT8 Byte; 327 328 329 while (fread (&Byte, 1, 1, Handle) == 1) 330 { 331 Status->Offset++; 332 333 /* Comment ends at newline */ 334 335 if (Byte == 0x0A) 336 { 337 Status->Line++; 338 return; 339 } 340 } 341 } 342 343 344 /******************************************************************************* 345 * 346 * FUNCTION: FlCheckForAscii 347 * 348 * PARAMETERS: Handle - Open input file 349 * Filename - Input filename 350 * DisplayErrors - TRUE if error messages desired 351 * 352 * RETURN: Status 353 * 354 * DESCRIPTION: Verify that the input file is entirely ASCII. Ignores characters 355 * within comments. Note: does not handle nested comments and does 356 * not handle comment delimiters within string literals. However, 357 * on the rare chance this happens and an invalid character is 358 * missed, the parser will catch the error by failing in some 359 * spectactular manner. 360 * 361 ******************************************************************************/ 362 363 ACPI_STATUS 364 FlCheckForAscii ( 365 FILE *Handle, 366 char *Filename, 367 BOOLEAN DisplayErrors) 368 { 369 UINT8 Byte; 370 ACPI_SIZE BadBytes = 0; 371 BOOLEAN OpeningComment = FALSE; 372 ASL_FILE_STATUS Status; 373 374 375 Status.Line = 1; 376 Status.Offset = 0; 377 378 /* Read the entire file */ 379 380 while (fread (&Byte, 1, 1, Handle) == 1) 381 { 382 /* Ignore comment fields (allow non-ascii within) */ 383 384 if (OpeningComment) 385 { 386 /* Check for second comment open delimiter */ 387 388 if (Byte == '*') 389 { 390 FlConsumeAnsiComment (Handle, &Status); 391 } 392 393 if (Byte == '/') 394 { 395 FlConsumeNewComment (Handle, &Status); 396 } 397 398 /* Reset */ 399 400 OpeningComment = FALSE; 401 } 402 else if (Byte == '/') 403 { 404 OpeningComment = TRUE; 405 } 406 407 /* Check for an ASCII character */ 408 409 if (!ACPI_IS_ASCII (Byte)) 410 { 411 if ((BadBytes < 10) && (DisplayErrors)) 412 { 413 AcpiOsPrintf ( 414 "Non-ASCII character [0x%2.2X] found in line %u, file offset 0x%.2X\n", 415 Byte, Status.Line, Status.Offset); 416 } 417 418 BadBytes++; 419 } 420 421 /* Update line counter */ 422 423 else if (Byte == 0x0A) 424 { 425 Status.Line++; 426 } 427 428 Status.Offset++; 429 } 430 431 /* Seek back to the beginning of the source file */ 432 433 fseek (Handle, 0, SEEK_SET); 434 435 /* Were there any non-ASCII characters in the file? */ 436 437 if (BadBytes) 438 { 439 if (DisplayErrors) 440 { 441 AcpiOsPrintf ( 442 "%u non-ASCII characters found in input source text, could be a binary file\n", 443 BadBytes); 444 AslError (ASL_ERROR, ASL_MSG_NON_ASCII, NULL, Filename); 445 } 446 447 return (AE_BAD_CHARACTER); 448 } 449 450 /* File is OK (100% ASCII) */ 451 452 return (AE_OK); 453 } 454 455 456 /******************************************************************************* 457 * 458 * FUNCTION: CmDoCompile 459 * 460 * PARAMETERS: None 461 * 462 * RETURN: Status (0 = OK) 463 * 464 * DESCRIPTION: This procedure performs the entire compile 465 * 466 ******************************************************************************/ 467 468 int 469 CmDoCompile ( 470 void) 471 { 472 ACPI_STATUS Status; 473 UINT8 FullCompile; 474 UINT8 Event; 475 476 477 FullCompile = UtBeginEvent ("*** Total Compile time ***"); 478 Event = UtBeginEvent ("Open input and output files"); 479 UtEndEvent (Event); 480 481 Event = UtBeginEvent ("Preprocess input file"); 482 if (Gbl_PreprocessFlag) 483 { 484 /* Preprocessor */ 485 486 PrDoPreprocess (); 487 if (Gbl_PreprocessOnly) 488 { 489 UtEndEvent (Event); 490 CmCleanupAndExit (); 491 return (0); 492 } 493 } 494 UtEndEvent (Event); 495 496 /* Build the parse tree */ 497 498 Event = UtBeginEvent ("Parse source code and build parse tree"); 499 AslCompilerparse(); 500 UtEndEvent (Event); 501 502 /* Flush out any remaining source after parse tree is complete */ 503 504 Event = UtBeginEvent ("Flush source input"); 505 CmFlushSourceCode (); 506 507 /* Did the parse tree get successfully constructed? */ 508 509 if (!RootNode) 510 { 511 /* 512 * If there are no errors, then we have some sort of 513 * internal problem. 514 */ 515 Status = AslCheckForErrorExit (); 516 if (Status == AE_OK) 517 { 518 AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, 519 NULL, "- Could not resolve parse tree root node"); 520 } 521 522 goto ErrorExit; 523 } 524 525 /* Optional parse tree dump, compiler debug output only */ 526 527 LsDumpParseTree (); 528 529 OpcGetIntegerWidth (RootNode); 530 UtEndEvent (Event); 531 532 /* Pre-process parse tree for any operator transforms */ 533 534 Event = UtBeginEvent ("Parse tree transforms"); 535 DbgPrint (ASL_DEBUG_OUTPUT, "\nParse tree transforms\n\n"); 536 TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD, 537 TrAmlTransformWalk, NULL, NULL); 538 UtEndEvent (Event); 539 540 /* Generate AML opcodes corresponding to the parse tokens */ 541 542 Event = UtBeginEvent ("Generate AML opcodes"); 543 DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating AML opcodes\n\n"); 544 TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL, 545 OpcAmlOpcodeWalk, NULL); 546 UtEndEvent (Event); 547 548 /* 549 * Now that the input is parsed, we can open the AML output file. 550 * Note: by default, the name of this file comes from the table descriptor 551 * within the input file. 552 */ 553 Event = UtBeginEvent ("Open AML output file"); 554 Status = FlOpenAmlOutputFile (Gbl_OutputFilenamePrefix); 555 UtEndEvent (Event); 556 if (ACPI_FAILURE (Status)) 557 { 558 AePrintErrorLog (ASL_FILE_STDERR); 559 return (-1); 560 } 561 562 /* Interpret and generate all compile-time constants */ 563 564 Event = UtBeginEvent ("Constant folding via AML interpreter"); 565 DbgPrint (ASL_DEBUG_OUTPUT, 566 "\nInterpreting compile-time constant expressions\n\n"); 567 TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD, 568 OpcAmlConstantWalk, NULL, NULL); 569 UtEndEvent (Event); 570 571 /* Update AML opcodes if necessary, after constant folding */ 572 573 Event = UtBeginEvent ("Updating AML opcodes after constant folding"); 574 DbgPrint (ASL_DEBUG_OUTPUT, 575 "\nUpdating AML opcodes after constant folding\n\n"); 576 TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, 577 NULL, OpcAmlOpcodeUpdateWalk, NULL); 578 UtEndEvent (Event); 579 580 /* Calculate all AML package lengths */ 581 582 Event = UtBeginEvent ("Generate AML package lengths"); 583 DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating Package lengths\n\n"); 584 TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL, 585 LnPackageLengthWalk, NULL); 586 UtEndEvent (Event); 587 588 if (Gbl_ParseOnlyFlag) 589 { 590 AePrintErrorLog (ASL_FILE_STDERR); 591 UtDisplaySummary (ASL_FILE_STDERR); 592 if (Gbl_DebugFlag) 593 { 594 /* Print error summary to the stdout also */ 595 596 AePrintErrorLog (ASL_FILE_STDOUT); 597 UtDisplaySummary (ASL_FILE_STDOUT); 598 } 599 UtEndEvent (FullCompile); 600 return (0); 601 } 602 603 /* 604 * Create an internal namespace and use it as a symbol table 605 */ 606 607 /* Namespace loading */ 608 609 Event = UtBeginEvent ("Create ACPI Namespace"); 610 Status = LdLoadNamespace (RootNode); 611 UtEndEvent (Event); 612 if (ACPI_FAILURE (Status)) 613 { 614 goto ErrorExit; 615 } 616 617 /* Namespace cross-reference */ 618 619 AslGbl_NamespaceEvent = UtBeginEvent ("Cross reference parse tree and Namespace"); 620 Status = LkCrossReferenceNamespace (); 621 if (ACPI_FAILURE (Status)) 622 { 623 goto ErrorExit; 624 } 625 626 /* Namespace - Check for non-referenced objects */ 627 628 LkFindUnreferencedObjects (); 629 UtEndEvent (AslGbl_NamespaceEvent); 630 631 /* 632 * Semantic analysis. This can happen only after the 633 * namespace has been loaded and cross-referenced. 634 * 635 * part one - check control methods 636 */ 637 Event = UtBeginEvent ("Analyze control method return types"); 638 AnalysisWalkInfo.MethodStack = NULL; 639 640 DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Method analysis\n\n"); 641 TrWalkParseTree (RootNode, ASL_WALK_VISIT_TWICE, 642 AnMethodAnalysisWalkBegin, 643 AnMethodAnalysisWalkEnd, &AnalysisWalkInfo); 644 UtEndEvent (Event); 645 646 /* Semantic error checking part two - typing of method returns */ 647 648 Event = UtBeginEvent ("Determine object types returned by methods"); 649 DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Method typing\n\n"); 650 TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, 651 NULL, AnMethodTypingWalkEnd, NULL); 652 UtEndEvent (Event); 653 654 /* Semantic error checking part three - operand type checking */ 655 656 Event = UtBeginEvent ("Analyze AML operand types"); 657 DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Operand type checking\n\n"); 658 TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, 659 NULL, AnOperandTypecheckWalkEnd, &AnalysisWalkInfo); 660 UtEndEvent (Event); 661 662 /* Semantic error checking part four - other miscellaneous checks */ 663 664 Event = UtBeginEvent ("Miscellaneous analysis"); 665 DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - miscellaneous\n\n"); 666 TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD, 667 AnOtherSemanticAnalysisWalkBegin, 668 NULL, &AnalysisWalkInfo); 669 UtEndEvent (Event); 670 671 /* Calculate all AML package lengths */ 672 673 Event = UtBeginEvent ("Finish AML package length generation"); 674 DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating Package lengths\n\n"); 675 TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL, 676 LnInitLengthsWalk, NULL); 677 TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL, 678 LnPackageLengthWalk, NULL); 679 UtEndEvent (Event); 680 681 /* Code generation - emit the AML */ 682 683 Event = UtBeginEvent ("Generate AML code and write output files"); 684 CgGenerateAmlOutput (); 685 UtEndEvent (Event); 686 687 Event = UtBeginEvent ("Write optional output files"); 688 CmDoOutputFiles (); 689 UtEndEvent (Event); 690 691 UtEndEvent (FullCompile); 692 CmCleanupAndExit (); 693 return (0); 694 695 ErrorExit: 696 UtEndEvent (FullCompile); 697 CmCleanupAndExit (); 698 return (-1); 699 } 700 701 702 /******************************************************************************* 703 * 704 * FUNCTION: CmDoOutputFiles 705 * 706 * PARAMETERS: None 707 * 708 * RETURN: None. 709 * 710 * DESCRIPTION: Create all "listing" type files 711 * 712 ******************************************************************************/ 713 714 void 715 CmDoOutputFiles ( 716 void) 717 { 718 719 /* Create listings and hex files */ 720 721 LsDoListings (); 722 LsDoHexOutput (); 723 724 /* Dump the namespace to the .nsp file if requested */ 725 726 (void) LsDisplayNamespace (); 727 } 728 729 730 /******************************************************************************* 731 * 732 * FUNCTION: CmDumpAllEvents 733 * 734 * PARAMETERS: None 735 * 736 * RETURN: None. 737 * 738 * DESCRIPTION: Dump all compiler events 739 * 740 ******************************************************************************/ 741 742 static void 743 CmDumpAllEvents ( 744 void) 745 { 746 ASL_EVENT_INFO *Event; 747 UINT32 Delta; 748 UINT32 USec; 749 UINT32 MSec; 750 UINT32 i; 751 752 753 Event = AslGbl_Events; 754 755 DbgPrint (ASL_DEBUG_OUTPUT, "\n\nElapsed time for major events\n\n"); 756 if (Gbl_CompileTimesFlag) 757 { 758 printf ("\nElapsed time for major events\n\n"); 759 } 760 761 for (i = 0; i < AslGbl_NextEvent; i++) 762 { 763 if (Event->Valid) 764 { 765 /* Delta will be in 100-nanosecond units */ 766 767 Delta = (UINT32) (Event->EndTime - Event->StartTime); 768 769 USec = Delta / 10; 770 MSec = Delta / 10000; 771 772 /* Round milliseconds up */ 773 774 if ((USec - (MSec * 1000)) >= 500) 775 { 776 MSec++; 777 } 778 779 DbgPrint (ASL_DEBUG_OUTPUT, "%8u usec %8u msec - %s\n", 780 USec, MSec, Event->EventName); 781 782 if (Gbl_CompileTimesFlag) 783 { 784 printf ("%8u usec %8u msec - %s\n", 785 USec, MSec, Event->EventName); 786 } 787 } 788 789 Event++; 790 } 791 } 792 793 794 /******************************************************************************* 795 * 796 * FUNCTION: CmCleanupAndExit 797 * 798 * PARAMETERS: None 799 * 800 * RETURN: None. 801 * 802 * DESCRIPTION: Close all open files and exit the compiler 803 * 804 ******************************************************************************/ 805 806 void 807 CmCleanupAndExit ( 808 void) 809 { 810 UINT32 i; 811 BOOLEAN DeleteAmlFile = FALSE; 812 813 814 AePrintErrorLog (ASL_FILE_STDERR); 815 if (Gbl_DebugFlag) 816 { 817 /* Print error summary to stdout also */ 818 819 AePrintErrorLog (ASL_FILE_STDOUT); 820 } 821 822 /* Emit compile times if enabled */ 823 824 CmDumpAllEvents (); 825 826 if (Gbl_CompileTimesFlag) 827 { 828 printf ("\nMiscellaneous compile statistics\n\n"); 829 printf ("%11u : %s\n", TotalParseNodes, "Parse nodes"); 830 printf ("%11u : %s\n", Gbl_NsLookupCount, "Namespace searches"); 831 printf ("%11u : %s\n", TotalNamedObjects, "Named objects"); 832 printf ("%11u : %s\n", TotalMethods, "Control methods"); 833 printf ("%11u : %s\n", TotalAllocations, "Memory Allocations"); 834 printf ("%11u : %s\n", TotalAllocated, "Total allocated memory"); 835 printf ("%11u : %s\n", TotalFolds, "Constant subtrees folded"); 836 printf ("\n"); 837 } 838 839 if (Gbl_NsLookupCount) 840 { 841 DbgPrint (ASL_DEBUG_OUTPUT, 842 "\n\nMiscellaneous compile statistics\n\n"); 843 844 DbgPrint (ASL_DEBUG_OUTPUT, 845 "%32s : %u\n", "Total Namespace searches", 846 Gbl_NsLookupCount); 847 848 DbgPrint (ASL_DEBUG_OUTPUT, 849 "%32s : %u usec\n", "Time per search", ((UINT32) 850 (AslGbl_Events[AslGbl_NamespaceEvent].EndTime - 851 AslGbl_Events[AslGbl_NamespaceEvent].StartTime) / 10) / 852 Gbl_NsLookupCount); 853 } 854 855 if (Gbl_ExceptionCount[ASL_ERROR] > ASL_MAX_ERROR_COUNT) 856 { 857 printf ("\nMaximum error count (%u) exceeded\n", 858 ASL_MAX_ERROR_COUNT); 859 } 860 861 UtDisplaySummary (ASL_FILE_STDOUT); 862 863 /* 864 * We will delete the AML file if there are errors and the 865 * force AML output option has not been used. 866 */ 867 if ((Gbl_ExceptionCount[ASL_ERROR] > 0) && (!Gbl_IgnoreErrors) && 868 Gbl_Files[ASL_FILE_AML_OUTPUT].Handle) 869 { 870 DeleteAmlFile = TRUE; 871 } 872 873 /* Close all open files */ 874 875 Gbl_Files[ASL_FILE_PREPROCESSOR].Handle = NULL; /* the .i file is same as source file */ 876 877 for (i = ASL_FILE_INPUT; i < ASL_MAX_FILE_TYPE; i++) 878 { 879 FlCloseFile (i); 880 } 881 882 /* Delete AML file if there are errors */ 883 884 if (DeleteAmlFile) 885 { 886 FlDeleteFile (ASL_FILE_AML_OUTPUT); 887 } 888 889 /* Delete the preprocessor output file (.i) unless -li flag is set */ 890 891 if (!Gbl_PreprocessorOutputFlag && 892 Gbl_PreprocessFlag) 893 { 894 FlDeleteFile (ASL_FILE_PREPROCESSOR); 895 } 896 897 /* 898 * Delete intermediate ("combined") source file (if -ls flag not set) 899 * This file is created during normal ASL/AML compiles. It is not 900 * created by the data table compiler. 901 * 902 * If the -ls flag is set, then the .SRC file should not be deleted. 903 * In this case, Gbl_SourceOutputFlag is set to TRUE. 904 * 905 * Note: Handles are cleared by FlCloseFile above, so we look at the 906 * filename instead, to determine if the .SRC file was actually 907 * created. 908 * 909 * TBD: SourceOutput should be .TMP, then rename if we want to keep it? 910 */ 911 if (!Gbl_SourceOutputFlag) 912 { 913 FlDeleteFile (ASL_FILE_SOURCE_OUTPUT); 914 } 915 } 916