Cc: Eric Dong <eric.d...@intel.com>
Cc: Liming Gao <liming....@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Dandan Bi <dandan...@intel.com>
---
 BaseTools/Source/C/VfrCompile/VfrSyntax.g       | 17 +++++++++++++++++
 BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp | 13 ++++++++++++-
 BaseTools/Source/C/VfrCompile/VfrUtilityLib.h   |  1 +
 3 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/BaseTools/Source/C/VfrCompile/VfrSyntax.g 
b/BaseTools/Source/C/VfrCompile/VfrSyntax.g
index 406dbc5..bd8457d 100644
--- a/BaseTools/Source/C/VfrCompile/VfrSyntax.g
+++ b/BaseTools/Source/C/VfrCompile/VfrSyntax.g
@@ -155,10 +155,11 @@ VfrParserStart (
 #token Label("label")                           "label"
 #token Timeout("timeout")                       "timeout"
 #token Inventory("inventory")                   "inventory"
 #token NonNvDataMap("_NON_NV_DATA_MAP")         "_NON_NV_DATA_MAP"
 #token Struct("struct")                         "struct"
+#token Union("union")                           "union"
 #token Boolean("BOOLEAN")                       "BOOLEAN"
 #token Uint64("UINT64")                         "UINT64"
 #token Uint32("UINT32")                         "UINT32"
 #token Uint16("UINT16")                         "UINT16"
 #token Char16("CHAR16")                         "CHAR16"
@@ -270,10 +271,11 @@ vfrProgram > [UINT8 Return] :
      mConstantOnlyInExpression = FALSE;
   >>
   (
       vfrPragmaPackDefinition
     | vfrDataStructDefinition
+    | vfrDataUnionDefinition
   )*
   vfrFormSetDefinition
   << $Return = mParserStatus; >>
   ;
 
@@ -318,10 +320,25 @@ vfrPragmaPackDefinition :
     | pragmaPackNumber
   }
   "\)"
   ;
 
+  vfrDataUnionDefinition :
+  { TypeDef } Union                                << gUnionTypeStructure = 
TRUE; gCVfrVarDataTypeDB.DeclareDataTypeBegin (); >>
+  { NonNvDataMap }
+  {
+    N1:StringIdentifier                             << 
_PCATCH(gCVfrVarDataTypeDB.SetNewTypeName (N1->getText()), N1); >>
+  }
+  OpenBrace
+    vfrDataStructFields
+  CloseBrace
+  {
+    N2:StringIdentifier                             << 
_PCATCH(gCVfrVarDataTypeDB.SetNewTypeName (N2->getText()), N2); >>
+  }
+  ";"                                               << 
gCVfrVarDataTypeDB.DeclareDataTypeEnd (); gUnionTypeStructure = FALSE;>>
+  ;
+
 vfrDataStructDefinition :
   { TypeDef } Struct                                << 
gCVfrVarDataTypeDB.DeclareDataTypeBegin (); >>
   { NonNvDataMap }
   {
     N1:StringIdentifier                             << 
_PCATCH(gCVfrVarDataTypeDB.SetNewTypeName (N1->getText()), N1); >>
diff --git a/BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp 
b/BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp
index 2f97975..b392476 100644
--- a/BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp
+++ b/BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp
@@ -1018,12 +1018,14 @@ CVfrVarDataTypeDB::DataTypeAddField (
 {
   SVfrDataField       *pNewField  = NULL;
   SVfrDataType        *pFieldType = NULL;
   SVfrDataField       *pTmp;
   UINT32              Align;
+  UINT32              MaxDataTypeSize;
 
   CHECK_ERROR_RETURN (GetDataType (TypeName, &pFieldType), VFR_RETURN_SUCCESS);
+  MaxDataTypeSize = mNewDataType->mTotalSize;
 
   if (strlen (FieldName) >= MAX_NAME_LEN) {
    return VFR_RETURN_INVALID_PARAMETER;
   }
 
@@ -1055,11 +1057,19 @@ CVfrVarDataTypeDB::DataTypeAddField (
     pTmp->mNext            = pNewField;
     pNewField->mNext       = NULL;
   }
 
   mNewDataType->mAlign     = MIN (mPackAlign, MAX (pFieldType->mAlign, 
mNewDataType->mAlign));
-  mNewDataType->mTotalSize = pNewField->mOffset + 
(pNewField->mFieldType->mTotalSize) * ((ArrayNum == 0) ? 1 : ArrayNum);
+
+  if (gUnionTypeStructure) {
+    if (MaxDataTypeSize < pNewField->mFieldType->mTotalSize) {
+      mNewDataType->mTotalSize = pNewField->mFieldType->mTotalSize;
+    }
+    pNewField->mOffset = 0;
+  } else {
+    mNewDataType->mTotalSize = pNewField->mOffset + 
(pNewField->mFieldType->mTotalSize) * ((ArrayNum == 0) ? 1 : ArrayNum);
+  }
 
   return VFR_RETURN_SUCCESS;
 }
 
 VOID
@@ -3715,10 +3725,11 @@ CVfrStringDB::GetUnicodeStringTextSize (
   }
 
   return StringSize;
 }
 
+BOOLEAN  gUnionTypeStructure = FALSE;
 BOOLEAN  VfrCompatibleMode = FALSE;
 
 CVfrVarDataTypeDB gCVfrVarDataTypeDB;
 CVfrDefaultStore  gCVfrDefaultStore;
 CVfrDataStorage  gCVfrDataStorage;
diff --git a/BaseTools/Source/C/VfrCompile/VfrUtilityLib.h 
b/BaseTools/Source/C/VfrCompile/VfrUtilityLib.h
index 59509c3..b6791ec 100644
--- a/BaseTools/Source/C/VfrCompile/VfrUtilityLib.h
+++ b/BaseTools/Source/C/VfrCompile/VfrUtilityLib.h
@@ -19,10 +19,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER 
EXPRESS OR IMPLIED.
 #include "string.h"
 #include "Common/UefiBaseTypes.h"
 #include "EfiVfr.h"
 #include "VfrError.h"
 
+extern BOOLEAN  gUnionTypeStructure;
 extern BOOLEAN  VfrCompatibleMode;
 
 #define MAX_NAME_LEN                       64
 #define MAX_STRING_LEN                     0x100
 #define DEFAULT_ALIGN                      1
-- 
1.9.5.msysgit.1

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to