Home | History | Annotate | Line # | Download | only in compiler
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