summaryrefslogtreecommitdiff
path: root/source/compiler/asltree.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/compiler/asltree.c')
-rw-r--r--source/compiler/asltree.c70
1 files changed, 62 insertions, 8 deletions
diff --git a/source/compiler/asltree.c b/source/compiler/asltree.c
index 6bb40888ed5d..62efc5fa907c 100644
--- a/source/compiler/asltree.c
+++ b/source/compiler/asltree.c
@@ -462,6 +462,7 @@ TrLinkOpChildren (
{
ACPI_PARSE_OBJECT *Child;
ACPI_PARSE_OBJECT *PrevChild;
+ ACPI_PARSE_OBJECT *LastSibling;
va_list ap;
UINT32 i;
BOOLEAN FirstChild;
@@ -480,8 +481,18 @@ TrLinkOpChildren (
{
case PARSEOP_ASL_CODE:
- AslGbl_ParseTreeRoot = Op;
- Op->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
+ if (!AslGbl_ParseTreeRoot)
+ {
+ DbgPrint (ASL_PARSE_OUTPUT, "Creating first Definition Block\n");
+ AslGbl_ParseTreeRoot = Op;
+ Op->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
+ }
+ else
+ {
+ DbgPrint (ASL_PARSE_OUTPUT, "Creating subsequent Definition Block\n");
+ Op = AslGbl_ParseTreeRoot;
+ }
+
DbgPrint (ASL_PARSE_OUTPUT, "ASLCODE (Tree Completed)->");
break;
@@ -560,7 +571,27 @@ TrLinkOpChildren (
if (FirstChild)
{
FirstChild = FALSE;
- Op->Asl.Child = Child;
+
+ /*
+ * In the case that multiple definition blocks are being compiled,
+ * append the definition block to the end of the child list as the
+ * last sibling. This is done to facilitate namespace cross-
+ * reference between multiple definition blocks.
+ */
+ if (Op->Asl.Child &&
+ (Op->Asl.Child->Asl.ParseOpcode == PARSEOP_DEFINITION_BLOCK))
+ {
+ LastSibling = Op->Asl.Child;
+ while (LastSibling->Asl.Next)
+ {
+ LastSibling = LastSibling->Asl.Next;
+ }
+ LastSibling->Asl.Next = Child;
+ }
+ else
+ {
+ Op->Asl.Child = Child;
+ }
}
/* Point all children to parent */
@@ -825,6 +856,8 @@ TrWalkParseTree (
BOOLEAN OpPreviouslyVisited;
ACPI_PARSE_OBJECT *StartOp = Op;
ACPI_STATUS Status;
+ ACPI_PARSE_OBJECT *Restore = NULL;
+ BOOLEAN WalkOneDefinitionBlock = Visitation & ASL_WALK_VISIT_DB_SEPARATELY;
if (!AslGbl_ParseTreeRoot)
@@ -835,7 +868,13 @@ TrWalkParseTree (
Level = 0;
OpPreviouslyVisited = FALSE;
- switch (Visitation)
+ if (Op->Asl.ParseOpcode == PARSEOP_DEFINITION_BLOCK &&
+ WalkOneDefinitionBlock)
+ {
+ Restore = Op->Asl.Next;
+ Op->Asl.Next = NULL;
+ }
+ switch (Visitation & ~ASL_WALK_VISIT_DB_SEPARATELY)
{
case ASL_WALK_VISIT_DOWNWARD:
@@ -861,7 +900,7 @@ TrWalkParseTree (
{
/* Exit immediately on any error */
- return (Status);
+ goto ErrorExit;
}
}
@@ -907,7 +946,7 @@ TrWalkParseTree (
Status = AscendingCallback (Op, Level, Context);
if (ACPI_FAILURE (Status))
{
- return (Status);
+ goto ErrorExit;
}
}
else
@@ -956,7 +995,7 @@ TrWalkParseTree (
Status = AscendingCallback (Op, Level, Context);
if (ACPI_FAILURE (Status))
{
- return (Status);
+ goto ErrorExit;
}
}
else
@@ -979,7 +1018,7 @@ TrWalkParseTree (
{
/* Exit immediately on any error */
- return (Status);
+ goto ErrorExit;
}
}
@@ -1018,5 +1057,20 @@ TrWalkParseTree (
/* If we get here, the walk completed with no errors */
+ if (Op->Asl.ParseOpcode == PARSEOP_DEFINITION_BLOCK &&
+ WalkOneDefinitionBlock)
+ {
+ Op->Asl.Next = Restore;
+ }
+
return (AE_OK);
+
+ErrorExit:
+
+ if (Op->Asl.ParseOpcode == PARSEOP_DEFINITION_BLOCK &&
+ WalkOneDefinitionBlock)
+ {
+ Op->Asl.Next = Restore;
+ }
+ return (Status);
}