V2: Update VfrCompiler to use member variable instead of global varable
to indicate whether current date type is Union.

Cc: Eric Dong <eric.d...@intel.com>
Cc: Liming Gao <liming....@intel.com>
Cc: Ruiyu Ni <ruiyu...@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Dandan Bi <dandan...@intel.com>
---
 BaseTools/Source/C/VfrCompile/VfrSyntax.g       | 19 ++++++++++++++++++-
 BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp | 16 ++++++++++++++--
 BaseTools/Source/C/VfrCompile/VfrUtilityLib.h   |  3 ++-
 3 files changed, 34 insertions(+), 4 deletions(-)

diff --git a/BaseTools/Source/C/VfrCompile/VfrSyntax.g 
b/BaseTools/Source/C/VfrCompile/VfrSyntax.g
index 406dbc5..9e1212a 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,12 +320,27 @@ vfrPragmaPackDefinition :
     | pragmaPackNumber
   }
   "\)"
   ;
 
+  vfrDataUnionDefinition :
+  { TypeDef } Union                                << 
gCVfrVarDataTypeDB.DeclareDataTypeBegin (TRUE); >>
+  { NonNvDataMap }
+  {
+    N1:StringIdentifier                             << 
_PCATCH(gCVfrVarDataTypeDB.SetNewTypeName (N1->getText()), N1); >>
+  }
+  OpenBrace
+    vfrDataStructFields
+  CloseBrace
+  {
+    N2:StringIdentifier                             << 
_PCATCH(gCVfrVarDataTypeDB.SetNewTypeName (N2->getText()), N2); >>
+  }
+  ";"                                               << 
gCVfrVarDataTypeDB.DeclareDataTypeEnd ();>>
+  ;
+
 vfrDataStructDefinition :
-  { TypeDef } Struct                                << 
gCVfrVarDataTypeDB.DeclareDataTypeBegin (); >>
+  { TypeDef } Struct                                << 
gCVfrVarDataTypeDB.DeclareDataTypeBegin (FALSE); >>
   { NonNvDataMap }
   {
     N1:StringIdentifier                             << 
_PCATCH(gCVfrVarDataTypeDB.SetNewTypeName (N1->getText()), N1); >>
   }
   OpenBrace
diff --git a/BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp 
b/BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp
index 2f97975..186b9c9 100644
--- a/BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp
+++ b/BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp
@@ -776,10 +776,11 @@ CVfrVarDataTypeDB::InternalTypesListInit (
     if (New != NULL) {
       strcpy (New->mTypeName, gInternalTypesTable[Index].mTypeName);
       New->mType        = gInternalTypesTable[Index].mType;
       New->mAlign       = gInternalTypesTable[Index].mAlign;
       New->mTotalSize   = gInternalTypesTable[Index].mSize;
+      New->mIsUnionType = FALSE;
       if (strcmp (gInternalTypesTable[Index].mTypeName, "EFI_HII_DATE") == 0) {
         SVfrDataField *pYearField  = new SVfrDataField;
         SVfrDataField *pMonthField = new SVfrDataField;
         SVfrDataField *pDayField   = new SVfrDataField;
 
@@ -964,11 +965,11 @@ CVfrVarDataTypeDB::Pack (
   return VFR_RETURN_SUCCESS;
 }
 
 VOID
 CVfrVarDataTypeDB::DeclareDataTypeBegin (
-  VOID
+  BOOLEAN  IsUnionType
   )
 {
   SVfrDataType *pNewType = NULL;
 
   pNewType               = new SVfrDataType;
@@ -976,10 +977,11 @@ CVfrVarDataTypeDB::DeclareDataTypeBegin (
   pNewType->mType        = EFI_IFR_TYPE_OTHER;
   pNewType->mAlign       = DEFAULT_ALIGN;
   pNewType->mTotalSize   = 0;
   pNewType->mMembers     = NULL;
   pNewType->mNext        = NULL;
+  pNewType->mIsUnionType = IsUnionType;
 
   mNewDataType           = pNewType;
 }
 
 EFI_VFR_RETURN_CODE
@@ -1018,12 +1020,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 +1059,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 (mNewDataType->mIsUnionType) {
+    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
diff --git a/BaseTools/Source/C/VfrCompile/VfrUtilityLib.h 
b/BaseTools/Source/C/VfrCompile/VfrUtilityLib.h
index 59509c3..13b75e4 100644
--- a/BaseTools/Source/C/VfrCompile/VfrUtilityLib.h
+++ b/BaseTools/Source/C/VfrCompile/VfrUtilityLib.h
@@ -124,10 +124,11 @@ struct SVfrDataType {
   UINT8                     mType;
   UINT32                    mAlign;
   UINT32                    mTotalSize;
   SVfrDataField             *mMembers;
   SVfrDataType              *mNext;
+  BOOLEAN                   mIsUnionType;
 };
 
 #define VFR_PACK_ASSIGN     0x01
 #define VFR_PACK_SHOW       0x02
 #define VFR_PACK_PUSH       0x04
@@ -201,11 +202,11 @@ private:
 
 public:
   CVfrVarDataTypeDB (VOID);
   ~CVfrVarDataTypeDB (VOID);
 
-  VOID                DeclareDataTypeBegin (VOID);
+  VOID                DeclareDataTypeBegin (BOOLEAN);
   EFI_VFR_RETURN_CODE SetNewTypeName (IN CHAR8 *);
   EFI_VFR_RETURN_CODE DataTypeAddField (IN CHAR8 *, IN CHAR8 *, IN UINT32);
   VOID                DeclareDataTypeEnd (VOID);
 
   EFI_VFR_RETURN_CODE GetDataType (IN CHAR8 *, OUT SVfrDataType **);
-- 
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