2 /******************************************************************************
4 * Module Name: asltree - parse tree management
7 *****************************************************************************/
9 /******************************************************************************
13 * Some or all of this work - Copyright (c) 1999 - 2005, Intel Corp.
14 * All rights reserved.
18 * 2.1. This is your license from Intel Corp. under its intellectual property
19 * rights. You may have additional license terms from the party that provided
20 * you this software, covering your right to use that party's intellectual
23 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
24 * copy of the source code appearing in this file ("Covered Code") an
25 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
26 * base code distributed originally by Intel ("Original Intel Code") to copy,
27 * make derivatives, distribute, use and display any portion of the Covered
28 * Code in any form, with the right to sublicense such rights; and
30 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
31 * license (with the right to sublicense), under only those claims of Intel
32 * patents that are infringed by the Original Intel Code, to make, use, sell,
33 * offer to sell, and import the Covered Code and derivative works thereof
34 * solely to the minimum extent necessary to exercise the above copyright
35 * license, and in no event shall the patent license extend to any additions
36 * to or modifications of the Original Intel Code. No other license or right
37 * is granted directly or by implication, estoppel or otherwise;
39 * The above copyright and patent license is granted only if the following
44 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
45 * Redistribution of source code of any substantial portion of the Covered
46 * Code or modification with rights to further distribute source must include
47 * the above Copyright Notice, the above License, this list of Conditions,
48 * and the following Disclaimer and Export Compliance provision. In addition,
49 * Licensee must cause all Covered Code to which Licensee contributes to
50 * contain a file documenting the changes Licensee made to create that Covered
51 * Code and the date of any change. Licensee must include in that file the
52 * documentation of any changes made by any predecessor Licensee. Licensee
53 * must include a prominent statement that the modification is derived,
54 * directly or indirectly, from Original Intel Code.
56 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
57 * Redistribution of source code of any substantial portion of the Covered
58 * Code or modification without rights to further distribute source must
59 * include the following Disclaimer and Export Compliance provision in the
60 * documentation and/or other materials provided with distribution. In
61 * addition, Licensee may not authorize further sublicense of source of any
62 * portion of the Covered Code, and must include terms to the effect that the
63 * license from Licensee to its licensee is limited to the intellectual
64 * property embodied in the software Licensee provides to its licensee, and
65 * not to intellectual property embodied in modifications its licensee may
68 * 3.3. Redistribution of Executable. Redistribution in executable form of any
69 * substantial portion of the Covered Code or modification must reproduce the
70 * above Copyright Notice, and the following Disclaimer and Export Compliance
71 * provision in the documentation and/or other materials provided with the
74 * 3.4. Intel retains all right, title, and interest in and to the Original
77 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
78 * Intel shall be used in advertising or otherwise to promote the sale, use or
79 * other dealings in products derived from or relating to the Covered Code
80 * without prior written authorization from Intel.
82 * 4. Disclaimer and Export Compliance
84 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
85 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
86 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
87 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
88 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
89 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
92 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
93 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
94 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
95 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
96 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
97 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
98 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
101 * 4.3. Licensee shall not export, either directly or indirectly, any of this
102 * software or system incorporating such software without first obtaining any
103 * required license or other approval from the U. S. Department of Commerce or
104 * any other agency or department of the United States Government. In the
105 * event Licensee exports any such software from the United States or
106 * re-exports any such software from a foreign destination, Licensee shall
107 * ensure that the distribution and export/re-export of the software is in
108 * compliance with all laws, regulations, orders, or other restrictions of the
109 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
110 * any of its subsidiaries will export/re-export any technical data, process,
111 * software, or service, directly or indirectly, to any country for which the
112 * United States government or any agency thereof requires an export license,
113 * other governmental approval, or letter of assurance, without first obtaining
114 * such license, approval or letter.
116 *****************************************************************************/
119 #include "aslcompiler.h"
120 #include "aslcompiler.y.h"
122 #define _COMPONENT ACPI_COMPILER
123 ACPI_MODULE_NAME ("asltree")
126 /*******************************************************************************
128 * FUNCTION: TrGetNextNode
132 * RETURN: New parse node. Aborts on allocation failure
134 * DESCRIPTION: Allocate a new parse node for the parse tree. Bypass the local
135 * dynamic memory manager for performance reasons (This has a
136 * major impact on the speed of the compiler.)
138 ******************************************************************************/
144 if (Gbl_NodeCacheNext
>= Gbl_NodeCacheLast
)
146 Gbl_NodeCacheNext
= UtLocalCalloc (sizeof (ACPI_PARSE_OBJECT
) * ASL_NODE_CACHE_SIZE
);
147 Gbl_NodeCacheLast
= Gbl_NodeCacheNext
+ ASL_NODE_CACHE_SIZE
;
150 return (Gbl_NodeCacheNext
++);
154 /*******************************************************************************
156 * FUNCTION: TrAllocateNode
158 * PARAMETERS: ParseOpcode - Opcode to be assigned to the node
160 * RETURN: New parse node. Aborts on allocation failure
162 * DESCRIPTION: Allocate and initialize a new parse node for the parse tree
164 ******************************************************************************/
170 ACPI_PARSE_OBJECT
*Op
;
173 Op
= TrGetNextNode ();
175 Op
->Asl
.ParseOpcode
= (UINT16
) ParseOpcode
;
176 Op
->Asl
.Filename
= Gbl_Files
[ASL_FILE_INPUT
].Filename
;
177 Op
->Asl
.LineNumber
= Gbl_CurrentLineNumber
;
178 Op
->Asl
.LogicalLineNumber
= Gbl_LogicalLineNumber
;
179 Op
->Asl
.LogicalByteOffset
= Gbl_CurrentLineOffset
;
180 Op
->Asl
.Column
= Gbl_CurrentColumn
;
182 UtSetParseOpName (Op
);
187 /*******************************************************************************
189 * FUNCTION: TrReleaseNode
191 * PARAMETERS: Op - Op to be released
195 * DESCRIPTION: "release" a node. In truth, nothing is done since the node
196 * is part of a larger buffer
198 ******************************************************************************/
202 ACPI_PARSE_OBJECT
*Op
)
209 /*******************************************************************************
211 * FUNCTION: TrUpdateNode
213 * PARAMETERS: ParseOpcode - New opcode to be assigned to the node
214 * Op - An existing parse node
216 * RETURN: The updated node
218 * DESCRIPTION: Change the parse opcode assigned to a node. Usually used to
219 * change an opcode to DEFAULT_ARG so that the node is ignored
220 * during the code generation. Also used to set generic integers
221 * to a specific size (8, 16, 32, or 64 bits)
223 ******************************************************************************/
228 ACPI_PARSE_OBJECT
*Op
)
236 DbgPrint (ASL_PARSE_OUTPUT
,
237 "\nUpdateNode: Old - %s, New - %s\n\n",
238 UtGetOpName (Op
->Asl
.ParseOpcode
),
239 UtGetOpName (ParseOpcode
));
241 /* Assign new opcode and name */
243 if (Op
->Asl
.ParseOpcode
== PARSEOP_ONES
)
247 case PARSEOP_BYTECONST
:
248 Op
->Asl
.Value
.Integer
= 0xFF;
251 case PARSEOP_WORDCONST
:
252 Op
->Asl
.Value
.Integer
= 0xFFFF;
255 case PARSEOP_DWORDCONST
:
256 Op
->Asl
.Value
.Integer
= 0xFFFFFFFF;
260 /* Don't care about others, don't need to check QWORD */
265 Op
->Asl
.ParseOpcode
= (UINT16
) ParseOpcode
;
266 UtSetParseOpName (Op
);
269 * For the BYTE, WORD, and DWORD constants, make sure that the integer
270 * that was passed in will actually fit into the data type
274 case PARSEOP_BYTECONST
:
275 Op
= UtCheckIntegerRange (Op
, 0x00, ACPI_UINT8_MAX
);
278 case PARSEOP_WORDCONST
:
279 Op
= UtCheckIntegerRange (Op
, 0x00, ACPI_UINT16_MAX
);
282 case PARSEOP_DWORDCONST
:
283 Op
= UtCheckIntegerRange (Op
, 0x00, ACPI_UINT32_MAX
);
287 /* Don't care about others, don't need to check QWORD */
295 /*******************************************************************************
297 * FUNCTION: TrGetNodeFlagName
299 * PARAMETERS: Flags - Flags word to be decoded
301 * RETURN: Name string
303 * DESCRIPTION: Decode a flags word
305 ******************************************************************************/
315 return ("NODE_VISITED");
317 case NODE_AML_PACKAGE
:
318 return ("NODE_AML_PACKAGE");
321 return ("NODE_IS_TARGET");
323 case NODE_IS_RESOURCE_DESC
:
324 return ("NODE_IS_RESOURCE_DESC");
326 case NODE_IS_RESOURCE_FIELD
:
327 return ("NODE_IS_RESOURCE_FIELD");
329 case NODE_HAS_NO_EXIT
:
330 return ("NODE_HAS_NO_EXIT");
332 case NODE_IF_HAS_NO_EXIT
:
333 return ("NODE_IF_HAS_NO_EXIT");
335 case NODE_NAME_INTERNALIZED
:
336 return ("NODE_NAME_INTERNALIZED");
338 case NODE_METHOD_NO_RETVAL
:
339 return ("NODE_METHOD_NO_RETVAL");
341 case NODE_METHOD_SOME_NO_RETVAL
:
342 return ("NODE_METHOD_SOME_NO_RETVAL");
344 case NODE_RESULT_NOT_USED
:
345 return ("NODE_RESULT_NOT_USED");
347 case NODE_METHOD_TYPED
:
348 return ("NODE_METHOD_TYPED");
350 case NODE_IS_BIT_OFFSET
:
351 return ("NODE_IS_BIT_OFFSET");
353 case NODE_COMPILE_TIME_CONST
:
354 return ("NODE_COMPILE_TIME_CONST");
356 case NODE_IS_TERM_ARG
:
357 return ("NODE_IS_TERM_ARG");
359 case NODE_WAS_ONES_OP
:
360 return ("NODE_WAS_ONES_OP");
362 case NODE_IS_NAME_DECLARATION
:
363 return ("NODE_IS_NAME_DECLARATION");
366 return ("Multiple Flags (or unknown flag) set");
371 /*******************************************************************************
373 * FUNCTION: TrSetNodeFlags
375 * PARAMETERS: Op - An existing parse node
376 * Flags - New flags word
378 * RETURN: The updated node
380 * DESCRIPTION: Set bits in the node flags word. Will not clear bits, only set
382 ******************************************************************************/
386 ACPI_PARSE_OBJECT
*Op
,
390 DbgPrint (ASL_PARSE_OUTPUT
,
391 "\nSetNodeFlags: Op %p, %8.8X %s\n\n", Op
, Flags
, TrGetNodeFlagName (Flags
));
398 Op
->Asl
.CompileFlags
|= Flags
;
404 /*******************************************************************************
406 * FUNCTION: TrSetEndLineNumber
408 * PARAMETERS: Op - An existing parse node
412 * DESCRIPTION: Set the ending line numbers (file line and logical line) of a
413 * parse node to the current line numbers.
415 ******************************************************************************/
419 ACPI_PARSE_OBJECT
*Op
)
422 /* If the end line # is already set, just return */
429 Op
->Asl
.EndLine
= Gbl_CurrentLineNumber
;
430 Op
->Asl
.EndLogicalLine
= Gbl_LogicalLineNumber
;
434 /*******************************************************************************
436 * FUNCTION: TrCreateLeafNode
438 * PARAMETERS: ParseOpcode - New opcode to be assigned to the node
440 * RETURN: Pointer to the new node. Aborts on allocation failure
442 * DESCRIPTION: Create a simple leaf node (no children or peers, and no value
443 * assigned to the node)
445 ******************************************************************************/
451 ACPI_PARSE_OBJECT
*Op
;
454 Op
= TrAllocateNode (ParseOpcode
);
456 DbgPrint (ASL_PARSE_OUTPUT
,
457 "\nCreateLeafNode Line %d NewNode %p Op %s\n\n",
458 Op
->Asl
.LineNumber
, Op
, UtGetOpName(ParseOpcode
));
464 /*******************************************************************************
466 * FUNCTION: TrCreateValuedLeafNode
468 * PARAMETERS: ParseOpcode - New opcode to be assigned to the node
469 * Value - Value to be assigned to the node
471 * RETURN: Pointer to the new node. Aborts on allocation failure
473 * DESCRIPTION: Create a leaf node (no children or peers) with a value
476 ******************************************************************************/
479 TrCreateValuedLeafNode (
483 ACPI_PARSE_OBJECT
*Op
;
486 Op
= TrAllocateNode (ParseOpcode
);
488 DbgPrint (ASL_PARSE_OUTPUT
,
489 "\nCreateValuedLeafNode Line %d NewNode %p Op %s Value %8.8X%8.8X ",
490 Op
->Asl
.LineNumber
, Op
, UtGetOpName(ParseOpcode
),
491 ACPI_FORMAT_UINT64 (Value
));
492 Op
->Asl
.Value
.Integer
= Value
;
496 case PARSEOP_STRING_LITERAL
:
497 DbgPrint (ASL_PARSE_OUTPUT
, "STRING->%s", Value
);
500 case PARSEOP_NAMESEG
:
501 DbgPrint (ASL_PARSE_OUTPUT
, "NAMESEG->%s", Value
);
504 case PARSEOP_NAMESTRING
:
505 DbgPrint (ASL_PARSE_OUTPUT
, "NAMESTRING->%s", Value
);
509 DbgPrint (ASL_PARSE_OUTPUT
, "EISAID->%s", Value
);
513 DbgPrint (ASL_PARSE_OUTPUT
, "METHOD");
516 case PARSEOP_INTEGER
:
517 DbgPrint (ASL_PARSE_OUTPUT
, "INTEGER");
524 DbgPrint (ASL_PARSE_OUTPUT
, "\n\n");
529 /*******************************************************************************
531 * FUNCTION: TrCreateNode
533 * PARAMETERS: ParseOpcode - Opcode to be assigned to the node
534 * NumChildren - Number of children to follow
535 * ... - A list of child nodes to link to the new
536 * node. NumChildren long.
538 * RETURN: Pointer to the new node. Aborts on allocation failure
540 * DESCRIPTION: Create a new parse node and link together a list of child
541 * nodes underneath the new node.
543 ******************************************************************************/
551 ACPI_PARSE_OBJECT
*Op
;
552 ACPI_PARSE_OBJECT
*Child
;
553 ACPI_PARSE_OBJECT
*PrevChild
;
559 va_start (ap
, NumChildren
);
561 /* Allocate one new node */
563 Op
= TrAllocateNode (ParseOpcode
);
565 DbgPrint (ASL_PARSE_OUTPUT
,
566 "\nCreateNode Line %d NewParent %p Child %d Op %s ",
567 Op
->Asl
.LineNumber
, Op
, NumChildren
, UtGetOpName(ParseOpcode
));
569 /* Some extra debug output based on the parse opcode */
573 case PARSEOP_DEFINITIONBLOCK
:
575 DbgPrint (ASL_PARSE_OUTPUT
, "DEFINITION_BLOCK (Tree Completed)->");
578 case PARSEOP_OPERATIONREGION
:
579 DbgPrint (ASL_PARSE_OUTPUT
, "OPREGION->");
583 DbgPrint (ASL_PARSE_OUTPUT
, "OR->");
587 /* Nothing to do for other opcodes */
591 /* Link the new node to its children */
595 for (i
= 0; i
< NumChildren
; i
++)
597 /* Get the next child */
599 Child
= va_arg (ap
, ACPI_PARSE_OBJECT
*);
600 DbgPrint (ASL_PARSE_OUTPUT
, "%p, ", Child
);
603 * If child is NULL, this means that an optional argument
604 * was omitted. We must create a placeholder with a special
605 * opcode (DEFAULT_ARG) so that the code generator will know
606 * that it must emit the correct default for this argument
610 Child
= TrAllocateNode (PARSEOP_DEFAULT_ARG
);
613 /* Link first child to parent */
618 Op
->Asl
.Child
= Child
;
621 /* Point all children to parent */
623 Child
->Asl
.Parent
= Op
;
625 /* Link children in a peer list */
629 PrevChild
->Asl
.Next
= Child
;
633 * This child might be a list, point all nodes in the list
636 while (Child
->Asl
.Next
)
638 Child
= Child
->Asl
.Next
;
639 Child
->Asl
.Parent
= Op
;
646 DbgPrint (ASL_PARSE_OUTPUT
, "\n\n");
651 /*******************************************************************************
653 * FUNCTION: TrLinkChildren
655 * PARAMETERS: Op - An existing parse node
656 * NumChildren - Number of children to follow
657 * ... - A list of child nodes to link to the new
658 * node. NumChildren long.
660 * RETURN: The updated (linked) node
662 * DESCRIPTION: Link a group of nodes to an existing parse node
664 ******************************************************************************/
668 ACPI_PARSE_OBJECT
*Op
,
672 ACPI_PARSE_OBJECT
*Child
;
673 ACPI_PARSE_OBJECT
*PrevChild
;
679 va_start (ap
, NumChildren
);
682 TrSetEndLineNumber (Op
);
684 DbgPrint (ASL_PARSE_OUTPUT
,
685 "\nLinkChildren Line [%d to %d] NewParent %p Child %d Op %s ",
686 Op
->Asl
.LineNumber
, Op
->Asl
.EndLine
,
687 Op
, NumChildren
, UtGetOpName(Op
->Asl
.ParseOpcode
));
689 switch (Op
->Asl
.ParseOpcode
)
691 case PARSEOP_DEFINITIONBLOCK
:
693 DbgPrint (ASL_PARSE_OUTPUT
, "DEFINITION_BLOCK (Tree Completed)->");
696 case PARSEOP_OPERATIONREGION
:
697 DbgPrint (ASL_PARSE_OUTPUT
, "OPREGION->");
701 DbgPrint (ASL_PARSE_OUTPUT
, "OR->");
705 /* Nothing to do for other opcodes */
709 /* Link the new node to it's children */
713 for (i
= 0; i
< NumChildren
; i
++)
715 Child
= va_arg (ap
, ACPI_PARSE_OBJECT
*);
717 if ((Child
== PrevChild
) && (Child
!= NULL
))
719 AslError (ASL_WARNING
, ASL_MSG_COMPILER_INTERNAL
, Child
, "Child node list invalid");
723 DbgPrint (ASL_PARSE_OUTPUT
, "%p, ", Child
);
726 * If child is NULL, this means that an optional argument
727 * was omitted. We must create a placeholder with a special
728 * opcode (DEFAULT_ARG) so that the code generator will know
729 * that it must emit the correct default for this argument
733 Child
= TrAllocateNode (PARSEOP_DEFAULT_ARG
);
736 /* Link first child to parent */
741 Op
->Asl
.Child
= Child
;
744 /* Point all children to parent */
746 Child
->Asl
.Parent
= Op
;
748 /* Link children in a peer list */
752 PrevChild
->Asl
.Next
= Child
;
756 * This child might be a list, point all nodes in the list
759 while (Child
->Asl
.Next
)
761 Child
= Child
->Asl
.Next
;
762 Child
->Asl
.Parent
= Op
;
768 DbgPrint (ASL_PARSE_OUTPUT
, "\n\n");
773 /*******************************************************************************
775 * FUNCTION: TrLinkPeerNode
777 * PARAMETERS: Op1 - First peer
780 * RETURN: Op1 or the non-null node.
782 * DESCRIPTION: Link two nodes as peers. Handles cases where one peer is null.
784 ******************************************************************************/
788 ACPI_PARSE_OBJECT
*Op1
,
789 ACPI_PARSE_OBJECT
*Op2
)
791 ACPI_PARSE_OBJECT
*Next
;
794 DbgPrint (ASL_PARSE_OUTPUT
,
795 "\nLinkPeerNode: 1=%p (%s), 2=%p (%s)\n\n",
796 Op1
, Op1
? UtGetOpName(Op1
->Asl
.ParseOpcode
) : NULL
,
797 Op2
, Op2
? UtGetOpName(Op2
->Asl
.ParseOpcode
) : NULL
);
800 if ((!Op1
) && (!Op2
))
802 DbgPrint (ASL_PARSE_OUTPUT
, "\nTwo Null nodes!\n");
806 /* If one of the nodes is null, just return the non-null node */
820 DbgPrint (ASL_DEBUG_OUTPUT
,
821 "\n\n************* Internal error, linking node to itself %p\n\n\n", Op1
);
822 AslError (ASL_WARNING
, ASL_MSG_COMPILER_INTERNAL
, Op1
, "Linking node to itself");
826 Op1
->Asl
.Parent
= Op2
->Asl
.Parent
;
829 * Op 1 may already have a peer list (such as an IF/ELSE pair),
830 * so we must walk to the end of the list and attach the new
834 while (Next
->Asl
.Next
)
836 Next
= Next
->Asl
.Next
;
839 Next
->Asl
.Next
= Op2
;
844 /*******************************************************************************
846 * FUNCTION: TrLinkPeerNodes
848 * PARAMETERS: NumPeers - The number of nodes in the list to follow
849 * ... - A list of nodes to link together as peers
851 * RETURN: The first node in the list (head of the peer list)
853 * DESCRIPTION: Link together an arbitrary number of peer nodes.
855 ******************************************************************************/
862 ACPI_PARSE_OBJECT
*This
;
863 ACPI_PARSE_OBJECT
*Next
;
866 ACPI_PARSE_OBJECT
*Start
;
869 DbgPrint (ASL_PARSE_OUTPUT
,
870 "\nLinkPeerNodes: (%d) ", NumPeers
);
872 va_start (ap
, NumPeers
);
873 This
= va_arg (ap
, ACPI_PARSE_OBJECT
*);
879 for (i
= 0; i
< (NumPeers
-1); i
++)
881 DbgPrint (ASL_PARSE_OUTPUT
, "%d=%p ", (i
+1), This
);
883 while (This
->Asl
.Next
)
885 This
= This
->Asl
.Next
;
888 /* Get another peer node */
890 Next
= va_arg (ap
, ACPI_PARSE_OBJECT
*);
893 Next
= TrAllocateNode (PARSEOP_DEFAULT_ARG
);
896 /* link new node to the current node */
898 This
->Asl
.Next
= Next
;
902 DbgPrint (ASL_PARSE_OUTPUT
,"\n\n");
907 /*******************************************************************************
909 * FUNCTION: TrLinkChildNode
911 * PARAMETERS: Op1 - Parent node
912 * Op2 - Op to become a child
914 * RETURN: The parent node
916 * DESCRIPTION: Link two nodes together as a parent and child
918 ******************************************************************************/
922 ACPI_PARSE_OBJECT
*Op1
,
923 ACPI_PARSE_OBJECT
*Op2
)
925 ACPI_PARSE_OBJECT
*Next
;
928 DbgPrint (ASL_PARSE_OUTPUT
,
929 "\nLinkChildNode: Parent=%p (%s), Child=%p (%s)\n\n",
930 Op1
, Op1
? UtGetOpName(Op1
->Asl
.ParseOpcode
): NULL
,
931 Op2
, Op2
? UtGetOpName(Op2
->Asl
.ParseOpcode
): NULL
);
938 Op1
->Asl
.Child
= Op2
;
940 /* Set the child and all peers of the child to point to the parent */
945 Next
->Asl
.Parent
= Op1
;
946 Next
= Next
->Asl
.Next
;
953 /*******************************************************************************
955 * FUNCTION: TrWalkParseTree
957 * PARAMETERS: Visitation - Type of walk
958 * DescendingCallback - Called during tree descent
959 * AscendingCallback - Called during tree ascent
960 * Context - To be passed to the callbacks
962 * RETURN: Status from callback(s)
964 * DESCRIPTION: Walk the entire parse tree.
966 ******************************************************************************/
970 ACPI_PARSE_OBJECT
*Op
,
972 ASL_WALK_CALLBACK DescendingCallback
,
973 ASL_WALK_CALLBACK AscendingCallback
,
977 BOOLEAN NodePreviouslyVisited
;
978 ACPI_PARSE_OBJECT
*StartOp
= Op
;
988 NodePreviouslyVisited
= FALSE
;
992 case ASL_WALK_VISIT_DOWNWARD
:
996 if (!NodePreviouslyVisited
)
999 * Let the callback process the node.
1001 Status
= DescendingCallback (Op
, Level
, Context
);
1002 if (ACPI_SUCCESS (Status
))
1004 /* Visit children first, once */
1013 else if (Status
!= AE_CTRL_DEPTH
)
1015 /* Exit immediately on any error */
1021 /* Terminate walk at start op */
1028 /* No more children, visit peers */
1033 NodePreviouslyVisited
= FALSE
;
1037 /* No children or peers, re-visit parent */
1043 Op
= Op
->Asl
.Parent
;
1044 NodePreviouslyVisited
= TRUE
;
1050 case ASL_WALK_VISIT_UPWARD
:
1054 /* Visit leaf node (no children) or parent node on return trip */
1056 if ((!Op
->Asl
.Child
) ||
1057 (NodePreviouslyVisited
))
1060 * Let the callback process the node.
1063 Status
= AscendingCallback (Op
, Level
, Context
);
1064 if (ACPI_FAILURE (Status
))
1071 /* Visit children first, once */
1078 /* Terminate walk at start op */
1085 /* No more children, visit peers */
1090 NodePreviouslyVisited
= FALSE
;
1094 /* No children or peers, re-visit parent */
1100 Op
= Op
->Asl
.Parent
;
1101 NodePreviouslyVisited
= TRUE
;
1107 case ASL_WALK_VISIT_TWICE
:
1111 if (NodePreviouslyVisited
)
1113 Status
= AscendingCallback (Op
, Level
, Context
);
1114 if (ACPI_FAILURE (Status
))
1122 * Let the callback process the node.
1124 Status
= DescendingCallback (Op
, Level
, Context
);
1125 if (ACPI_SUCCESS (Status
))
1127 /* Visit children first, once */
1136 else if (Status
!= AE_CTRL_DEPTH
)
1138 /* Exit immediately on any error */
1144 /* Terminate walk at start op */
1151 /* No more children, visit peers */
1156 NodePreviouslyVisited
= FALSE
;
1160 /* No children or peers, re-visit parent */
1166 Op
= Op
->Asl
.Parent
;
1167 NodePreviouslyVisited
= TRUE
;
1173 /* No other types supported */
1177 /* If we get here, the walk completed with no errors */