Fix the following issues:
authorqhuang8 <qhuang8@7335b38e-4728-0410-8992-fb3ffe349368>
Thu, 28 Feb 2008 06:24:17 +0000 (06:24 +0000)
committerqhuang8 <qhuang8@7335b38e-4728-0410-8992-fb3ffe349368>
Thu, 28 Feb 2008 06:24:17 +0000 (06:24 +0000)
1. Vfr compiler cannot handle #pragma pack(push, 1) well.
2. VfrCompiler should report error for the unsupported format e.g.option text = STRING_TOKEN(STR_DISABLE), ..., key = 1;
3. VfrCompiler error messages are unclear for referencing undefined Q ID

git-svn-id: https://buildtools.tianocore.org/svn/buildtools/trunk/BaseTools@1024 7335b38e-4728-0410-8992-fb3ffe349368

Source/C/VfrCompile/VfrError.cpp
Source/C/VfrCompile/VfrError.h
Source/C/VfrCompile/VfrFormPkg.cpp
Source/C/VfrCompile/VfrFormPkg.h
Source/C/VfrCompile/VfrSyntax.g
Source/C/VfrCompile/VfrUtilityLib.cpp
Source/C/VfrCompile/VfrUtilityLib.h

index 979fb5a..0ae08a5 100644 (file)
@@ -174,9 +174,10 @@ CVfrErrorHandle::GetFileNameLineNum (
 }\r
 \r
 VOID\r
-CVfrErrorHandle::PrintError (\r
+CVfrErrorHandle::PrintMsg (\r
   IN UINT32               LineNum,\r
   IN CHAR8                *TokName,\r
+  IN CHAR8                *MsgType,\r
   IN CHAR8                *ErrorMsg\r
   )\r
 {\r
@@ -184,7 +185,7 @@ CVfrErrorHandle::PrintError (
   UINT32                 FileLine;\r
 \r
   GetFileNameLineNum (LineNum, &FileName, &FileLine);\r
-  printf ("%s line %d: error %s %s\n", FileName, FileLine, TokName, ErrorMsg);\r
+  printf ("%s line %d: %s %s %s\n", FileName, FileLine, MsgType, TokName, ErrorMsg);\r
 }\r
 \r
 UINT8\r
index f845ff1..73234f4 100644 (file)
@@ -58,7 +58,7 @@ public:
   VOID  ParseFileScopeRecord (IN CHAR8 *, IN UINT32);\r
   VOID  GetFileNameLineNum (IN UINT32, OUT CHAR8 **, OUT UINT32 *);\r
   UINT8 HandleError (IN EFI_VFR_RETURN_CODE, IN UINT32 LineNum = 0, IN CHAR8 *TokName = "\0");\r
-  VOID  PrintError (IN UINT32 LineNum = 0, IN CHAR8 *TokName = "\0", IN CHAR8 *ErrorMsg = "\0");\r
+  VOID  PrintMsg (IN UINT32 LineNum = 0, IN CHAR8 *TokName = "\0", IN CHAR8 *MsgType = "Error", IN CHAR8 *ErrorMsg = "\0");\r
 };\r
 \r
 #define CHECK_ERROR_RETURN(f, v) do { EFI_VFR_RETURN_CODE r; if ((r = (f)) != (v)) { return r; } } while (0)\r
index 4491f59..1154893 100644 (file)
@@ -9,22 +9,30 @@ SPendingAssign::SPendingAssign (
   IN CHAR8  *Key, \r
   IN VOID   *Addr, \r
   IN UINT32 Len, \r
-  IN UINT32 LineNo\r
+  IN UINT32 LineNo,\r
+  IN CHAR8  *Msg\r
   )\r
 {\r
+  mKey    = NULL;\r
+  mAddr   = Addr;\r
+  mLen    = Len;\r
+  mFlag   = PENDING;\r
+  mLineNo = LineNo;\r
+  mMsg    = NULL;\r
+  mNext   = NULL;\r
   if (Key != NULL) {\r
     mKey = new CHAR8[strlen (Key) + 1];\r
     if (mKey != NULL) {\r
       strcpy (mKey, Key);\r
     }\r
-  } else {\r
-    mKey = NULL;\r
   }\r
-  mAddr   = Addr;\r
-  mLen    = Len;\r
-  mFlag   = PENDING;\r
-  mLineNo = LineNo;\r
-  mNext   = NULL;\r
+\r
+  if (Msg != NULL) {\r
+    mMsg = new CHAR8[strlen (Msg) + 1];\r
+    if (mMsg != NULL) {\r
+      strcpy (mMsg, Msg);\r
+    }\r
+  }\r
 }\r
 \r
 SPendingAssign::~SPendingAssign (\r
@@ -37,6 +45,9 @@ SPendingAssign::~SPendingAssign (
   mAddr   = NULL;\r
   mLen    = 0;\r
   mLineNo = 0;\r
+  if (mMsg != NULL) {\r
+    delete mMsg;\r
+  }\r
   mNext   = NULL;\r
 }\r
 \r
@@ -391,12 +402,13 @@ CFormPkg::AssignPending (
   IN CHAR8  *Key, \r
   IN VOID   *ValAddr, \r
   IN UINT32 ValLen,\r
-  IN UINT32 LineNo\r
+  IN UINT32 LineNo,\r
+  IN CHAR8  *Msg\r
   )\r
 {\r
   SPendingAssign *pNew;\r
 \r
-  pNew = new SPendingAssign (Key, ValAddr, ValLen, LineNo);\r
+  pNew = new SPendingAssign (Key, ValAddr, ValLen, LineNo, Msg);\r
   if (pNew == NULL) {\r
     return VFR_RETURN_OUT_FOR_RESOURCES;\r
   }\r
@@ -451,7 +463,7 @@ CFormPkg::PendingAssignPrintAll (
 \r
   for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {\r
     if (pNode->mFlag == PENDING) {\r
-      gCVfrErrorHandle.PrintError (pNode->mLineNo, pNode->mKey, "can not assign value because not defined");\r
+      gCVfrErrorHandle.PrintMsg (pNode->mLineNo, pNode->mKey, "Error", pNode->mMsg);\r
     }\r
   }\r
 }\r
index 1feca9f..8dc5476 100644 (file)
@@ -6,6 +6,8 @@
 #include "VfrError.h"\r
 #include "VfrUtilityLib.h"\r
 \r
+#define NO_QST_REFED "no question refered"\r
+\r
 /*\r
  * The functions below are used for flags setting\r
  */\r
@@ -56,9 +58,10 @@ struct SPendingAssign {
   UINT32                  mLen;\r
   ASSIGN_FLAG             mFlag;\r
   UINT32                  mLineNo;\r
+  CHAR8                   *mMsg;\r
   struct SPendingAssign   *mNext;\r
 \r
-  SPendingAssign (IN CHAR8 *, IN VOID *, IN UINT32, IN UINT32);\r
+  SPendingAssign (IN CHAR8 *, IN VOID *, IN UINT32, IN UINT32, IN CHAR8 *);\r
   ~SPendingAssign ();\r
 \r
   VOID   SetAddrAndLen (IN VOID *, IN UINT32);\r
@@ -107,7 +110,7 @@ public:
   EFI_VFR_RETURN_CODE GenCFile (IN CHAR8 *, IN FILE *);\r
 \r
 public:\r
-  EFI_VFR_RETURN_CODE AssignPending (IN CHAR8 *, IN VOID *, IN UINT32, IN UINT32);\r
+  EFI_VFR_RETURN_CODE AssignPending (IN CHAR8 *, IN VOID *, IN UINT32, IN UINT32, IN CHAR8 *Msg = NULL);\r
   VOID                DoPendingAssign (IN CHAR8 *, IN VOID *, IN UINT32);\r
   bool                HavePendingUnassigned (VOID);\r
   VOID                PendingAssignPrintAll (VOID);\r
@@ -1409,7 +1412,7 @@ public:
     if (QuestionId != EFI_QUESTION_ID_INVALID) {\r
       mEqIdId->QuestionId1 = QuestionId;\r
     } else {\r
-      gCFormPkg.AssignPending (VarIdStr, (VOID *)(&mEqIdId->QuestionId1), sizeof (EFI_QUESTION_ID), LineNo);\r
+      gCFormPkg.AssignPending (VarIdStr, (VOID *)(&mEqIdId->QuestionId1), sizeof (EFI_QUESTION_ID), LineNo, NO_QST_REFED);\r
     }\r
   }\r
 \r
@@ -1421,7 +1424,7 @@ public:
     if (QuestionId != EFI_QUESTION_ID_INVALID) {\r
       mEqIdId->QuestionId2 = QuestionId;\r
     } else {\r
-      gCFormPkg.AssignPending (VarIdStr, (VOID *)(&mEqIdId->QuestionId2), sizeof (EFI_QUESTION_ID), LineNo);\r
+      gCFormPkg.AssignPending (VarIdStr, (VOID *)(&mEqIdId->QuestionId2), sizeof (EFI_QUESTION_ID), LineNo, NO_QST_REFED);\r
     }\r
   }\r
 };\r
@@ -1447,7 +1450,7 @@ public:
     if (QuestionId != EFI_QUESTION_ID_INVALID) {\r
       mEqIdVal->QuestionId = QuestionId;\r
     } else {\r
-      gCFormPkg.AssignPending (VarIdStr, (VOID *)(&mEqIdVal->QuestionId), sizeof (EFI_QUESTION_ID), LineNo);\r
+      gCFormPkg.AssignPending (VarIdStr, (VOID *)(&mEqIdVal->QuestionId), sizeof (EFI_QUESTION_ID), LineNo, NO_QST_REFED);\r
     }\r
   }\r
 \r
@@ -1479,7 +1482,7 @@ public:
     if (QuestionId != EFI_QUESTION_ID_INVALID) {\r
       mEqIdVList->QuestionId = QuestionId;\r
     } else {\r
-      gCFormPkg.AssignPending (VarIdStr, (VOID *)(&mEqIdVList->QuestionId), sizeof (EFI_QUESTION_ID), LineNo);\r
+      gCFormPkg.AssignPending (VarIdStr, (VOID *)(&mEqIdVList->QuestionId), sizeof (EFI_QUESTION_ID), LineNo, NO_QST_REFED);\r
     }\r
   }\r
 \r
@@ -1521,7 +1524,7 @@ public:
     if (QuestionId != EFI_QUESTION_ID_INVALID) {\r
       mQuestionRef1->QuestionId = QuestionId;\r
     } else {\r
-      gCFormPkg.AssignPending (VarIdStr, (VOID *)(&mQuestionRef1->QuestionId), sizeof (EFI_QUESTION_ID), LineNo);\r
+      gCFormPkg.AssignPending (VarIdStr, (VOID *)(&mQuestionRef1->QuestionId), sizeof (EFI_QUESTION_ID), LineNo, NO_QST_REFED);\r
     }\r
   }\r
 };\r
index 92d0cf7..9110f3f 100644 (file)
@@ -41,6 +41,12 @@ VfrParserStart (
 }\r
 >>\r
 \r
+#lexaction\r
+<<\r
+#include <Error.h>\r
+\r
+>>\r
+\r
 //\r
 // Define a lexical class for parsing quoted strings. Basically\r
 // starts with a double quote, and ends with a double quote that\r
@@ -231,29 +237,58 @@ VfrParserStart (
 //\r
 \r
 vfrProgram > [UINT8 Return] :\r
-  << UINT32 PackAlign = DEFAULT_PACK_ALIGN; >>\r
   << mParserStatus = 0; >>\r
   (\r
-    (\r
-         "\#pragma" "pack" "\(" \r
-      { \r
-        A:Number                                    << PackAlign = _STOU32(A->getText()); >>\r
-      }\r
-      "\)"                                          << _PCATCH(mCVfrVarDataTypeDB.Pack (PackAlign)); >>\r
-    )\r
-    |\r
-    (\r
-      vfrDataStructDefinition\r
-    )\r
+      vfrPragmaPackDefinition\r
+    | vfrDataStructDefinition\r
   )*\r
   vfrFromSetDefinition\r
   << $Return = mParserStatus; >>\r
   ;\r
 \r
-//*****************************************************************************\r
-//\r
-// the syntax of data struct definition\r
-//\r
+pragmaPackShowDef :\r
+  L:"show"                                          << mCVfrVarDataTypeDB.Pack (L->getLine(), VFR_PACK_SHOW); >>\r
+  ;\r
+\r
+pragmaPackStackDef :\r
+  <<\r
+     UINT32 LineNum;\r
+     UINT8  PackAction;\r
+     INT8   *Identifier = NULL;\r
+     UINT32 PackNumber  = DEFAULT_PACK_ALIGN;\r
+  >>\r
+  (\r
+      L1:"push"                                     << LineNum = L1->getLine(); PackAction = VFR_PACK_PUSH; >>\r
+    | L2:"pop"                                      << LineNum = L2->getLine(); PackAction = VFR_PACK_POP; >>\r
+  ) \r
+  {\r
+    "," ID:StringIdentifier                         << Identifier = ID->getText(); >>\r
+  } \r
+  {\r
+    "," N:Number                                    << PackAction |= VFR_PACK_ASSIGN; PackNumber = _STOU32(N->getText()); >>\r
+  }\r
+                                                    << mCVfrVarDataTypeDB.Pack (LineNum, PackAction, Identifier, PackNumber); >>\r
+  ;\r
+\r
+pragmaPackNumber :\r
+  <<\r
+     UINT32 LineNum;\r
+     UINT32 PackNumber = DEFAULT_PACK_ALIGN;\r
+  >>\r
+  N:Number                                          << LineNum = N->getLine(); PackNumber = _STOU32(N->getText()); >>\r
+                                                    << mCVfrVarDataTypeDB.Pack (LineNum, VFR_PACK_ASSIGN, NULL, PackNumber); >>\r
+  ;\r
+\r
+vfrPragmaPackDefinition :\r
+  "\#pragma" "pack" "\(" \r
+  {\r
+      pragmaPackShowDef\r
+    | pragmaPackStackDef\r
+    | pragmaPackNumber\r
+  }\r
+  "\)"\r
+  ;\r
+\r
 vfrDataStructDefinition :\r
   { TypeDef } Struct                                << mCVfrVarDataTypeDB.DeclareDataTypeBegin (); >>\r
   { NonNVDataMap }\r
@@ -1739,7 +1774,6 @@ vfrStatementOneOfOption :
                                                                                                                                                                        ), L->getLine());\r
                                                           }\r
                                                        >>\r
-  { "," Key "=" Number }                               // no use in UEFI2.1 VFR\r
   (\r
     "," vfrImageTag                                    << OOOObj.SetScope (1); CIfrEnd EOOOObj; >>\r
   )*\r
@@ -2592,7 +2626,7 @@ EfiVfrParser::_PCATCH (
 {\r
   if (ReturnCode != ExpectCode) {\r
     mParserStatus++;\r
-    gCVfrErrorHandle.PrintError (Tok->getLine(), Tok->getText(), ErrorMsg);\r
+    gCVfrErrorHandle.PrintMsg (Tok->getLine(), Tok->getText(), "Error", ErrorMsg);\r
   }\r
 }\r
 \r
index 43ee287..a33376d 100644 (file)
@@ -834,6 +834,7 @@ CVfrVarDataTypeDB::CVfrVarDataTypeDB (
   mNewDataType   = NULL;\r
   mCurrDataField = NULL;\r
   mPackAlign     = DEFAULT_PACK_ALIGN;\r
+  mPackStack     = NULL;\r
 \r
   InternalTypesListInit ();\r
 }\r
@@ -842,8 +843,9 @@ CVfrVarDataTypeDB::~CVfrVarDataTypeDB (
   VOID\r
   )\r
 {\r
-  SVfrDataType  *pType;\r
-  SVfrDataField *pField;\r
+  SVfrDataType      *pType;\r
+  SVfrDataField     *pField;\r
+  SVfrPackStackNode *pPack;\r
 \r
   if (mNewDataType != NULL) {\r
     delete mNewDataType;\r
@@ -860,22 +862,60 @@ CVfrVarDataTypeDB::~CVfrVarDataTypeDB (
        delete pType;\r
   }\r
 \r
+  while (mPackStack != NULL) {\r
+    pPack = mPackStack;\r
+    mPackStack = mPackStack->mNext;\r
+    delete pPack;\r
+  }\r
 }\r
 \r
 EFI_VFR_RETURN_CODE\r
 CVfrVarDataTypeDB::Pack (\r
-  IN UINT32        Align\r
+  IN UINT32         LineNum,\r
+  IN UINT8          Action, \r
+  IN CHAR8          *Identifier, \r
+  IN UINT32         Number\r
   )\r
 {\r
-  if (Align == DEFAULT_PACK_ALIGN) {\r
-    return VFR_RETURN_SUCCESS;\r
-  } else {\r
-    if (Align == 0) {\r
-      return VFR_RETURN_INVALID_PARAMETER;\r
-    } else if (Align > 1) {\r
-      mPackAlign = Align + Align % 2;\r
+  UINT32            PackAlign;\r
+  CHAR8             Msg[64] = {0, };\r
+\r
+  if (Action & VFR_PACK_SHOW) {\r
+    sprintf (Msg, "value of pragma pack(show) == %d", mPackAlign);\r
+    gCVfrErrorHandle.PrintMsg (LineNum, "", "Warning", Msg);\r
+  }\r
+\r
+  if (Action & VFR_PACK_PUSH) {\r
+    SVfrPackStackNode *pNew = NULL;\r
+\r
+    if ((pNew = new SVfrPackStackNode (Identifier, mPackAlign)) == NULL) {\r
+      return VFR_RETURN_FATAL_ERROR;\r
+    }\r
+    pNew->mNext = mPackStack;\r
+    mPackStack  = pNew;\r
+  }\r
+\r
+  if (Action & VFR_PACK_POP) {\r
+    SVfrPackStackNode *pNode = NULL;\r
+\r
+    if (mPackStack == NULL) {\r
+      gCVfrErrorHandle.PrintMsg (LineNum, "", "Warning", "#pragma pack(pop...) : more pops than pushes");\r
+    }\r
+\r
+    for (pNode = mPackStack; pNode != NULL; pNode = pNode->mNext) {\r
+      if (pNode->Match (Identifier) == TRUE) {\r
+        mPackAlign = pNode->mNumber;\r
+        mPackStack = pNode->mNext;\r
+      }\r
+    }\r
+  }\r
+\r
+  if (Action & VFR_PACK_ASSIGN) {\r
+    PackAlign = (Number > 1) ? Number + Number % 2 : Number;\r
+    if ((PackAlign == 0) || (PackAlign > 16)) {\r
+      gCVfrErrorHandle.PrintMsg (LineNum, "", "Warning", "expected pragma parameter to be '1', '2', '4', '8', or '16'");\r
     } else {\r
-      mPackAlign = Align;\r
+      mPackAlign = PackAlign;\r
     }\r
   }\r
 \r
index 10940ae..d631a0c 100644 (file)
@@ -8,7 +8,7 @@
 \r
 #define MAX_NAME_LEN                       64\r
 #define DEFAULT_ALIGN                      1\r
-#define DEFAULT_PACK_ALIGN                 0xFFFFFFFF\r
+#define DEFAULT_PACK_ALIGN                 0x8\r
 #define DEFAULT_NAME_TABLE_ITEMS           1024\r
 \r
 #define EFI_BITS_SHIFT_PER_UINT32          0x5\r
@@ -95,10 +95,59 @@ struct SVfrDataType {
   SVfrDataType              *mNext;\r
 };\r
 \r
+#define VFR_PACK_ASSIGN     0x01\r
+#define VFR_PACK_SHOW       0x02\r
+#define VFR_PACK_PUSH       0x04\r
+#define VFR_PACK_POP        0x08\r
+\r
+#define PACKSTACK_MAX_SIZE  0x400\r
+\r
+struct SVfrPackStackNode {\r
+  CHAR8                     *mIdentifier;\r
+  UINT32                    mNumber;\r
+  SVfrPackStackNode         *mNext;\r
+\r
+  SVfrPackStackNode (IN INT8 *Identifier, IN UINT32 Number) {\r
+    mIdentifier = NULL;\r
+    mNumber     = Number;\r
+    mNext       = NULL;\r
+\r
+    if (Identifier != NULL) {\r
+      mIdentifier = new INT8[strlen (Identifier) + 1];\r
+      strcpy (mIdentifier, Identifier);\r
+    }\r
+  }\r
+\r
+  ~SVfrPackStackNode (VOID) {\r
+    if (mIdentifier != NULL) {\r
+      delete mIdentifier;\r
+    }\r
+    mNext = NULL;\r
+  }\r
+\r
+  bool Match (IN INT8 *Identifier) {\r
+    if (Identifier == NULL) {\r
+      return TRUE;\r
+    } else if (mIdentifier == NULL) {\r
+      return FALSE;\r
+    } else if (strcmp (Identifier, mIdentifier) == 0) {\r
+      return TRUE;\r
+    } else {\r
+      return FALSE;\r
+    }\r
+  }\r
+};\r
+\r
 class CVfrVarDataTypeDB {\r
 private:\r
-  SVfrDataType              *mDataTypeList;\r
   UINT32                    mPackAlign;\r
+  SVfrPackStackNode         *mPackStack;\r
+\r
+public:\r
+  EFI_VFR_RETURN_CODE       Pack (IN UINT32, IN UINT8, IN CHAR8 *Identifier = NULL, IN UINT32 Number = DEFAULT_PACK_ALIGN);\r
+\r
+private:\r
+  SVfrDataType              *mDataTypeList;\r
 \r
   SVfrDataType              *mNewDataType;\r
   SVfrDataType              *mCurrDataType;\r
@@ -118,8 +167,6 @@ public:
   CVfrVarDataTypeDB (VOID);\r
   ~CVfrVarDataTypeDB (VOID);\r
 \r
-  EFI_VFR_RETURN_CODE Pack (IN UINT32 Align);\r
-\r
   VOID                DeclareDataTypeBegin (VOID);\r
   EFI_VFR_RETURN_CODE SetNewTypeName (IN CHAR8 *);\r
   EFI_VFR_RETURN_CODE DataTypeAddField (IN CHAR8 *, IN CHAR8 *, IN UINT32);\r