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