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