int CmDoCompile ( void) { ACPI_STATUS Status; UINT8 FullCompile; UINT8 Event; FullCompile = UtBeginEvent ("*** Total Compile time ***"); Event = UtBeginEvent ("Open input and output files"); UtEndEvent (Event); Event = UtBeginEvent ("Preprocess input file"); if (AslGbl_PreprocessFlag) { /* Enter compiler name as a #define */ PrAddDefine (ASL_DEFINE, "", FALSE); /* Preprocessor */ PrDoPreprocess (); AslGbl_CurrentLineNumber = 1; AslGbl_LogicalLineNumber = 1; if (AslGbl_PreprocessOnly) { UtEndEvent (Event); CmCleanupAndExit (); return (0); } } UtEndEvent (Event); /* Build the parse tree */ Event = UtBeginEvent ("Parse source code and build parse tree"); AslCompilerparse(); UtEndEvent (Event); /* Check for parser-detected syntax errors */ if (AslGbl_SyntaxError) { fprintf (stderr, "Compiler aborting due to parser-detected syntax error(s)\n"); LsDumpParseTree (); goto ErrorExit; } /* Did the parse tree get successfully constructed? */ if (!AslGbl_ParseTreeRoot) { /* * If there are no errors, then we have some sort of * internal problem. */ AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, NULL, "- Could not resolve parse tree root node"); goto ErrorExit; } /* Flush out any remaining source after parse tree is complete */ Event = UtBeginEvent ("Flush source input"); CmFlushSourceCode (); /* Prune the parse tree if requested (debug purposes only) */ if (AslGbl_PruneParseTree) { AslPruneParseTree (AslGbl_PruneDepth, AslGbl_PruneType); } /* Optional parse tree dump, compiler debug output only */ LsDumpParseTree (); OpcGetIntegerWidth (AslGbl_ParseTreeRoot->Asl.Child); UtEndEvent (Event); /* Pre-process parse tree for any operator transforms */ Event = UtBeginEvent ("Parse tree transforms"); DbgPrint (ASL_DEBUG_OUTPUT, "\nParse tree transforms\n\n"); TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_TWICE, TrAmlTransformWalkBegin, TrAmlTransformWalkEnd, NULL); UtEndEvent (Event); /* Generate AML opcodes corresponding to the parse tokens */ Event = UtBeginEvent ("Generate AML opcodes"); DbgPrint (ASL_DEBUG_OUTPUT, "Generating AML opcodes\n\n"); TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD, NULL, OpcAmlOpcodeWalk, NULL); UtEndEvent (Event); /* * Now that the input is parsed, we can open the AML output file. * Note: by default, the name of this file comes from the table * descriptor within the input file. */ Event = UtBeginEvent ("Open AML output file"); Status = FlOpenAmlOutputFile (AslGbl_OutputFilenamePrefix); UtEndEvent (Event); if (ACPI_FAILURE (Status)) { AePrintErrorLog (ASL_FILE_STDERR); return (-1); } /* Interpret and generate all compile-time constants */ Event = UtBeginEvent ("Constant folding via AML interpreter"); DbgPrint (ASL_DEBUG_OUTPUT, "Interpreting compile-time constant expressions\n\n"); if (AslGbl_FoldConstants) { TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD, NULL, OpcAmlConstantWalk, NULL); } else { DbgPrint (ASL_PARSE_OUTPUT, " Optional folding disabled\n"); } UtEndEvent (Event); /* Update AML opcodes if necessary, after constant folding */ Event = UtBeginEvent ("Updating AML opcodes after constant folding"); DbgPrint (ASL_DEBUG_OUTPUT, "Updating AML opcodes after constant folding\n\n"); TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD, NULL, OpcAmlOpcodeUpdateWalk, NULL); UtEndEvent (Event); /* Calculate all AML package lengths */ Event = UtBeginEvent ("Generate AML package lengths"); DbgPrint (ASL_DEBUG_OUTPUT, "Generating Package lengths\n\n"); TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD, NULL, LnPackageLengthWalk, NULL); UtEndEvent (Event); if (AslGbl_ParseOnlyFlag) { AePrintErrorLog (ASL_FILE_STDERR); UtDisplaySummary (ASL_FILE_STDERR); if (AslGbl_DebugFlag) { /* Print error summary to the stdout also */ AePrintErrorLog (ASL_FILE_STDOUT); UtDisplaySummary (ASL_FILE_STDOUT); } UtEndEvent (FullCompile); return (0); } /* * Create an internal namespace and use it as a symbol table */ /* Namespace loading */ Event = UtBeginEvent ("Create ACPI Namespace"); DbgPrint (ASL_DEBUG_OUTPUT, "Creating ACPI Namespace\n\n"); Status = LdLoadNamespace (AslGbl_ParseTreeRoot); UtEndEvent (Event); if (ACPI_FAILURE (Status)) { goto ErrorExit; } /* Namespace cross-reference */ AslGbl_NamespaceEvent = UtBeginEvent ( "Cross reference parse tree and Namespace"); DbgPrint (ASL_DEBUG_OUTPUT, "Cross referencing namespace\n\n"); Status = XfCrossReferenceNamespace (); if (ACPI_FAILURE (Status)) { goto ErrorExit; } /* Namespace - Check for non-referenced objects */ LkFindUnreferencedObjects (); UtEndEvent (AslGbl_NamespaceEvent); /* Resolve External Declarations */ Event = UtBeginEvent ("Resolve all Externals"); DbgPrint (ASL_DEBUG_OUTPUT, "\nResolve Externals\n\n"); if (AslGbl_DoExternalsInPlace) { TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_DOWNWARD, ExAmlExternalWalkBegin, NULL, NULL); } else { TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_TWICE, ExAmlExternalWalkBegin, ExAmlExternalWalkEnd, NULL); } UtEndEvent (Event); /* * Semantic analysis. This can happen only after the * namespace has been loaded and cross-referenced. * * part one - check control methods */ Event = UtBeginEvent ("Analyze control method return types"); AslGbl_AnalysisWalkInfo.MethodStack = NULL; DbgPrint (ASL_DEBUG_OUTPUT, "Semantic analysis - Method analysis\n\n"); if (AslGbl_CrossReferenceOutput) { OtPrintHeaders ("Part 1: Object Reference Map " "(Object references from within each control method)"); } TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_TWICE, MtMethodAnalysisWalkBegin, MtMethodAnalysisWalkEnd, &AslGbl_AnalysisWalkInfo); UtEndEvent (Event); /* Generate the object cross-reference file if requested */ Event = UtBeginEvent ("Generate cross-reference file"); OtCreateXrefFile (); UtEndEvent (Event); /* Semantic error checking part two - typing of method returns */ Event = UtBeginEvent ("Determine object types returned by methods"); DbgPrint (ASL_DEBUG_OUTPUT, "Semantic analysis - Method typing\n\n"); TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD, NULL, AnMethodTypingWalkEnd, NULL); UtEndEvent (Event); /* Semantic error checking part three - operand type checking */ Event = UtBeginEvent ("Analyze AML operand types"); DbgPrint (ASL_DEBUG_OUTPUT, "Semantic analysis - Operand type checking\n\n"); if (AslGbl_DoTypechecking) { TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD, NULL, AnOperandTypecheckWalkEnd, &AslGbl_AnalysisWalkInfo); } UtEndEvent (Event); /* Semantic error checking part four - other miscellaneous checks */ Event = UtBeginEvent ("Miscellaneous analysis"); DbgPrint (ASL_DEBUG_OUTPUT, "Semantic analysis - miscellaneous\n\n"); TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_DOWNWARD, AnOtherSemanticAnalysisWalkBegin, NULL, &AslGbl_AnalysisWalkInfo); UtEndEvent (Event); /* * ASL-/ASL+ converter: Gbl_ParseTreeRoot->CommentList contains the * very last comment of a given ASL file because it's the last constructed * node during compilation. We take the very last comment and save it in a * global for it to be used by the disassembler. */ if (AcpiGbl_CaptureComments) { AcpiGbl_LastListHead = AslGbl_ParseTreeRoot->Asl.CommentList; AslGbl_ParseTreeRoot->Asl.CommentList = NULL; } /* Calculate all AML package lengths */ Event = UtBeginEvent ("Finish AML package length generation"); DbgPrint (ASL_DEBUG_OUTPUT, "Generating Package lengths\n\n"); TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD, NULL, LnInitLengthsWalk, NULL); TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD, NULL, LnPackageLengthWalk, NULL); UtEndEvent (Event); /* Code generation - emit the AML */ Event = UtBeginEvent ("Generate AML code and write output files"); DbgPrint (ASL_DEBUG_OUTPUT, "Writing AML byte code\n\n"); CgGenerateAmlOutput (); UtEndEvent (Event); Event = UtBeginEvent ("Write optional output files"); CmDoOutputFiles (); UtEndEvent (Event); UtEndEvent (FullCompile); AslCheckExpectedExceptions (); CmCleanupAndExit (); return (0); ErrorExit: UtEndEvent (FullCompile); CmCleanupAndExit (); return (-1); }
void CmCleanupAndExit ( void) { UINT32 i; BOOLEAN DeleteAmlFile = FALSE; AslCheckExpectedExceptions (); AePrintErrorLog (ASL_FILE_STDERR); if (AslGbl_DebugFlag) { /* Print error summary to stdout also */ AePrintErrorLog (ASL_FILE_STDOUT); } /* Emit compile times if enabled */ CmDumpAllEvents (); if (AslGbl_CompileTimesFlag) { printf ("\nMiscellaneous compile statistics\n\n"); printf ("%11u : %s\n", AslGbl_TotalParseNodes, "Parse nodes"); printf ("%11u : %s\n", AslGbl_NsLookupCount, "Namespace searches"); printf ("%11u : %s\n", AslGbl_TotalNamedObjects, "Named objects"); printf ("%11u : %s\n", AslGbl_TotalMethods, "Control methods"); printf ("%11u : %s\n", AslGbl_TotalAllocations, "Memory Allocations"); printf ("%11u : %s\n", AslGbl_TotalAllocated, "Total allocated memory"); printf ("%11u : %s\n", AslGbl_TotalFolds, "Constant subtrees folded"); printf ("\n"); } if (AslGbl_NsLookupCount) { DbgPrint (ASL_DEBUG_OUTPUT, "\n\nMiscellaneous compile statistics\n\n"); DbgPrint (ASL_DEBUG_OUTPUT, "%32s : %u\n", "Total Namespace searches", AslGbl_NsLookupCount); DbgPrint (ASL_DEBUG_OUTPUT, "%32s : %u usec\n", "Time per search", ((UINT32) (AslGbl_Events[AslGbl_NamespaceEvent].EndTime - AslGbl_Events[AslGbl_NamespaceEvent].StartTime) / 10) / AslGbl_NsLookupCount); } if (AslGbl_ExceptionCount[ASL_ERROR] > ASL_MAX_ERROR_COUNT) { printf ("\nMaximum error count (%d) exceeded\n", ASL_MAX_ERROR_COUNT); } UtDisplaySummary (ASL_FILE_STDOUT); /* * We will delete the AML file if there are errors and the * force AML output option has not been used. */ if ((AslGbl_ExceptionCount[ASL_ERROR] > 0) && (!AslGbl_IgnoreErrors) && AslGbl_Files[ASL_FILE_AML_OUTPUT].Handle) { DeleteAmlFile = TRUE; } /* Close all open files */ /* * Take care with the preprocessor file (.pre), it might be the same * as the "input" file, depending on where the compiler has terminated * or aborted. Prevent attempt to close the same file twice in * loop below. */ if (AslGbl_Files[ASL_FILE_PREPROCESSOR].Handle == AslGbl_Files[ASL_FILE_INPUT].Handle) { AslGbl_Files[ASL_FILE_PREPROCESSOR].Handle = NULL; } /* Close the standard I/O files */ for (i = ASL_FILE_INPUT; i < ASL_MAX_FILE_TYPE; i++) { FlCloseFile (i); } /* Delete AML file if there are errors */ if (DeleteAmlFile) { FlDeleteFile (ASL_FILE_AML_OUTPUT); } /* Delete the preprocessor temp file unless full debug was specified */ if (AslGbl_PreprocessFlag && !AslGbl_KeepPreprocessorTempFile) { FlDeleteFile (ASL_FILE_PREPROCESSOR); } /* * Delete intermediate ("combined") source file (if -ls flag not set) * This file is created during normal ASL/AML compiles. It is not * created by the data table compiler. * * If the -ls flag is set, then the .SRC file should not be deleted. * In this case, Gbl_SourceOutputFlag is set to TRUE. * * Note: Handles are cleared by FlCloseFile above, so we look at the * filename instead, to determine if the .SRC file was actually * created. */ if (!AslGbl_SourceOutputFlag) { FlDeleteFile (ASL_FILE_SOURCE_OUTPUT); } /* Final cleanup after compiling one file */ if (!AslGbl_DoAslConversion) { UtDeleteLocalCaches (); } }