public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH] BaseTools: Enable Pcd Array support.
@ 2018-11-07  9:18 BobCF
  2018-11-09 15:24 ` Carsey, Jaben
  0 siblings, 1 reply; 2+ messages in thread
From: BobCF @ 2018-11-07  9:18 UTC (permalink / raw)
  To: edk2-devel; +Cc: bob.c.feng@intel.com, Liming Gao

From: "bob.c.feng@intel.com" <bob.c.feng@intel.com>

https://bugzilla.tianocore.org/show_bug.cgi?id=1292

This patch is going to enable Array data type for PCD.

1. Support Pcd ARRAY as Structure PCD type
   including basic datatype array and structure array.
   For example:
   gStructuredPcdPkgTokenSpaceGuid.PcdTest|{0x0}|TEST[10]|0x00010080
   gStructuredPcdPkgTokenSpaceGuid.PcdTest2|{0x0}|UINT8[10]|0x00010081
2. Support C CODE style value initialization in DEC/DSC.
   For example:
gStructuredPcdPkgTokenSpaceGuid.PcdTest|{CODE({
  {0, {0, 0, 0, 0,  0, 0, 0}},
  {0, {0, 0, 0, 0,  0, 0, 0}},
  {0, {0, 0, 0, 0,  0, 0, 0}},
  {0, {0, 0, 0, 0,  0, 0, 0}},
  {0, {0, 0, 0, 0,  0, 0, 0}},
  {0, {0, 0, 0, 0,  0, 0, 0}},
  {0, {0, 0, 0, 0,  0, 0, 0}},
  {0, {0, 0, 0, 0,  0, 0, 0}},
  {0, {0, 0, 0, 0,  0, 0, 0}},
  {0, {0, 0, 0, 0,  0, 0, 0}},
})}

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Bob Feng <bob.c.feng@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
---
 BaseTools/Source/Python/Common/Expression.py  | 396 +++++++++---------
 BaseTools/Source/Python/Common/Misc.py        |   2 +
 .../Python/Workspace/BuildClassObject.py      |  85 +++-
 .../Source/Python/Workspace/DecBuildData.py   |  29 +-
 .../Source/Python/Workspace/DscBuildData.py   | 384 +++++++++++------
 .../Source/Python/Workspace/MetaFileParser.py |  86 +++-
 6 files changed, 644 insertions(+), 338 deletions(-)

diff --git a/BaseTools/Source/Python/Common/Expression.py b/BaseTools/Source/Python/Common/Expression.py
index a21ab5daa7..f6e245be70 100644
--- a/BaseTools/Source/Python/Common/Expression.py
+++ b/BaseTools/Source/Python/Common/Expression.py
@@ -820,221 +820,219 @@ class ValueExpressionEx(ValueExpression):
 
     def __call__(self, RealValue=False, Depth=0):
         PcdValue = self.PcdValue
-        try:
-            PcdValue = ValueExpression.__call__(self, RealValue, Depth)
-            if self.PcdType == TAB_VOID and (PcdValue.startswith("'") or PcdValue.startswith("L'")):
-                PcdValue, Size = ParseFieldValue(PcdValue)
-                PcdValueList = []
-                for I in range(Size):
-                    PcdValueList.append('0x%02X'%(PcdValue & 0xff))
-                    PcdValue = PcdValue >> 8
-                PcdValue = '{' + ','.join(PcdValueList) + '}'
-            elif self.PcdType in TAB_PCD_NUMERIC_TYPES and (PcdValue.startswith("'") or \
-                      PcdValue.startswith('"') or PcdValue.startswith("L'") or PcdValue.startswith('L"') or PcdValue.startswith('{')):
-                raise BadExpression
-        except WrnExpression as Value:
-            PcdValue = Value.result
-        except BadExpression as Value:
-            if self.PcdType in TAB_PCD_NUMERIC_TYPES:
-                PcdValue = PcdValue.strip()
-                if PcdValue.startswith('{') and PcdValue.endswith('}'):
-                    PcdValue = SplitPcdValueString(PcdValue[1:-1])
-                if ERR_STRING_CMP.split(':')[0] in Value.message:
-                    raise BadExpression("Type: %s, Value: %s, %s" % (self.PcdType, PcdValue, Value))
-                if isinstance(PcdValue, type([])):
-                    TmpValue = 0
-                    Size = 0
-                    ValueType = ''
-                    for Item in PcdValue:
-                        Item = Item.strip()
-                        if Item.startswith(TAB_UINT8):
-                            ItemSize = 1
-                            ValueType = TAB_UINT8
-                        elif Item.startswith(TAB_UINT16):
-                            ItemSize = 2
-                            ValueType = TAB_UINT16
-                        elif Item.startswith(TAB_UINT32):
-                            ItemSize = 4
-                            ValueType = TAB_UINT32
-                        elif Item.startswith(TAB_UINT64):
-                            ItemSize = 8
-                            ValueType = TAB_UINT64
-                        elif Item[0] in {'"', "'", 'L'}:
-                            ItemSize = 0
-                            ValueType = TAB_VOID
-                        else:
-                            ItemSize = 0
-                            ValueType = TAB_UINT8
-                        Item = ValueExpressionEx(Item, ValueType, self._Symb)(True)
-
-                        if ItemSize == 0:
-                            try:
-                                tmpValue = int(Item, 0)
-                                if tmpValue > 255:
-                                    raise BadExpression("Byte  array number %s should less than 0xFF." % Item)
-                            except BadExpression as Value:
-                                raise BadExpression(Value)
-                            except ValueError:
-                                pass
-                            ItemValue, ItemSize = ParseFieldValue(Item)
-                        else:
-                            ItemValue = ParseFieldValue(Item)[0]
-
-                        if isinstance(ItemValue, type('')):
-                            ItemValue = int(ItemValue, 0)
-
-                        TmpValue = (ItemValue << (Size * 8)) | TmpValue
-                        Size = Size + ItemSize
-                else:
-                    try:
-                        TmpValue, Size = ParseFieldValue(PcdValue)
-                    except BadExpression as Value:
-                        raise BadExpression("Type: %s, Value: %s, %s" % (self.PcdType, PcdValue, Value))
-                if isinstance(TmpValue, type('')):
-                    try:
-                        TmpValue = int(TmpValue)
-                    except:
-                        raise  BadExpression(Value)
-                else:
-                    PcdValue = '0x%0{}X'.format(Size) % (TmpValue)
-                if TmpValue < 0:
-                    raise  BadExpression('Type %s PCD Value is negative' % self.PcdType)
-                if self.PcdType == TAB_UINT8 and Size > 1:
-                    raise BadExpression('Type %s PCD Value Size is Larger than 1 byte' % self.PcdType)
-                if self.PcdType == TAB_UINT16 and Size > 2:
-                    raise BadExpression('Type %s PCD Value Size is Larger than 2 byte' % self.PcdType)
-                if self.PcdType == TAB_UINT32 and Size > 4:
-                    raise BadExpression('Type %s PCD Value Size is Larger than 4 byte' % self.PcdType)
-                if self.PcdType == TAB_UINT64 and Size > 8:
-                    raise BadExpression('Type %s PCD Value Size is Larger than 8 byte' % self.PcdType)
-            else:
-                try:
-                    TmpValue = int(PcdValue)
-                    TmpList = []
-                    if TmpValue.bit_length() == 0:
-                        PcdValue = '{0x00}'
-                    else:
-                        for I in range((TmpValue.bit_length() + 7) / 8):
-                            TmpList.append('0x%02x' % ((TmpValue >> I * 8) & 0xff))
-                        PcdValue = '{' + ', '.join(TmpList) + '}'
-                except:
-                    if PcdValue.strip().startswith('{'):
-                        PcdValueList = SplitPcdValueString(PcdValue.strip()[1:-1])
-                        LabelDict = {}
-                        NewPcdValueList = []
-                        LabelOffset = 0
-                        for Item in PcdValueList:
-                            # compute byte offset of every LABEL
-                            LabelList = _ReLabel.findall(Item)
-                            Item = _ReLabel.sub('', Item)
+        if "{CODE(" not in PcdValue:
+            try:
+                PcdValue = ValueExpression.__call__(self, RealValue, Depth)
+                if self.PcdType == TAB_VOID and (PcdValue.startswith("'") or PcdValue.startswith("L'")):
+                    PcdValue, Size = ParseFieldValue(PcdValue)
+                    PcdValueList = []
+                    for I in range(Size):
+                        PcdValueList.append('0x%02X'%(PcdValue & 0xff))
+                        PcdValue = PcdValue >> 8
+                    PcdValue = '{' + ','.join(PcdValueList) + '}'
+                elif self.PcdType in TAB_PCD_NUMERIC_TYPES and (PcdValue.startswith("'") or \
+                          PcdValue.startswith('"') or PcdValue.startswith("L'") or PcdValue.startswith('L"') or PcdValue.startswith('{')):
+                    raise BadExpression
+            except WrnExpression as Value:
+                PcdValue = Value.result
+            except BadExpression as Value:
+                if self.PcdType in TAB_PCD_NUMERIC_TYPES:
+                    PcdValue = PcdValue.strip()
+                    if PcdValue.startswith('{') and PcdValue.endswith('}'):
+                        PcdValue = SplitPcdValueString(PcdValue[1:-1])
+                    if isinstance(PcdValue, type([])):
+                        TmpValue = 0
+                        Size = 0
+                        ValueType = ''
+                        for Item in PcdValue:
                             Item = Item.strip()
-                            if LabelList:
-                                for Label in LabelList:
-                                    if not IsValidCName(Label):
-                                        raise BadExpression('%s is not a valid c variable name' % Label)
-                                    if Label not in LabelDict:
-                                        LabelDict[Label] = str(LabelOffset)
                             if Item.startswith(TAB_UINT8):
-                                LabelOffset = LabelOffset + 1
+                                ItemSize = 1
+                                ValueType = TAB_UINT8
                             elif Item.startswith(TAB_UINT16):
-                                LabelOffset = LabelOffset + 2
+                                ItemSize = 2
+                                ValueType = TAB_UINT16
                             elif Item.startswith(TAB_UINT32):
-                                LabelOffset = LabelOffset + 4
+                                ItemSize = 4
+                                ValueType = TAB_UINT32
                             elif Item.startswith(TAB_UINT64):
-                                LabelOffset = LabelOffset + 8
+                                ItemSize = 8
+                                ValueType = TAB_UINT64
+                            elif Item[0] in {'"', "'", 'L'}:
+                                ItemSize = 0
+                                ValueType = TAB_VOID
                             else:
+                                ItemSize = 0
+                                ValueType = TAB_UINT8
+                            Item = ValueExpressionEx(Item, ValueType, self._Symb)(True)
+                            if ItemSize == 0:
                                 try:
-                                    ItemValue, ItemSize = ParseFieldValue(Item)
-                                    LabelOffset = LabelOffset + ItemSize
-                                except:
-                                    LabelOffset = LabelOffset + 1
-
-                        for Item in PcdValueList:
-                            # for LABEL parse
-                            Item = Item.strip()
-                            try:
-                                Item = _ReLabel.sub('', Item)
-                            except:
-                                pass
-                            try:
-                                OffsetList = _ReOffset.findall(Item)
-                            except:
-                                pass
-                            # replace each offset, except errors
-                            for Offset in OffsetList:
-                                try:
-                                    Item = Item.replace('OFFSET_OF({})'.format(Offset), LabelDict[Offset])
-                                except:
-                                    raise BadExpression('%s not defined' % Offset)
-
-                            NewPcdValueList.append(Item)
-
-                        AllPcdValueList = []
-                        for Item in NewPcdValueList:
-                            Size = 0
-                            ValueStr = ''
-                            TokenSpaceGuidName = ''
-                            if Item.startswith(TAB_GUID) and Item.endswith(')'):
-                                try:
-                                    TokenSpaceGuidName = re.search('GUID\((\w+)\)', Item).group(1)
-                                except:
+                                    tmpValue = int(Item, 0)
+                                    if tmpValue > 255:
+                                        raise BadExpression("Byte  array number %s should less than 0xFF." % Item)
+                                except BadExpression as Value:
+                                    raise BadExpression(Value)
+                                except ValueError:
                                     pass
-                                if TokenSpaceGuidName and TokenSpaceGuidName in self._Symb:
-                                    Item = 'GUID(' + self._Symb[TokenSpaceGuidName] + ')'
-                                elif TokenSpaceGuidName:
-                                    raise BadExpression('%s not found in DEC file' % TokenSpaceGuidName)
-                                Item, Size = ParseFieldValue(Item)
-                                for Index in range(0, Size):
-                                    ValueStr = '0x%02X' % (int(Item) & 255)
-                                    Item >>= 8
-                                    AllPcdValueList.append(ValueStr)
-                                continue
-                            elif Item.startswith('DEVICE_PATH') and Item.endswith(')'):
-                                Item, Size = ParseFieldValue(Item)
-                                AllPcdValueList.append(Item[1:-1])
-                                continue
+                                ItemValue, ItemSize = ParseFieldValue(Item)
                             else:
-                                ValueType = ""
+                                ItemValue = ParseFieldValue(Item)[0]
+
+                            if isinstance(ItemValue, type('')):
+                                ItemValue = int(ItemValue, 0)
+
+                            TmpValue = (ItemValue << (Size * 8)) | TmpValue
+                            Size = Size + ItemSize
+                    else:
+                        try:
+                            TmpValue, Size = ParseFieldValue(PcdValue)
+                        except BadExpression as Value:
+                            raise BadExpression("Type: %s, Value: %s, %s" % (self.PcdType, PcdValue, Value))
+                    if isinstance(TmpValue, type('')):
+                        try:
+                            TmpValue = int(TmpValue)
+                        except:
+                            raise  BadExpression(Value)
+                    else:
+                        PcdValue = '0x%0{}X'.format(Size) % (TmpValue)
+                    if TmpValue < 0:
+                        raise  BadExpression('Type %s PCD Value is negative' % self.PcdType)
+                    if self.PcdType == TAB_UINT8 and Size > 1:
+                        raise BadExpression('Type %s PCD Value Size is Larger than 1 byte' % self.PcdType)
+                    if self.PcdType == TAB_UINT16 and Size > 2:
+                        raise BadExpression('Type %s PCD Value Size is Larger than 2 byte' % self.PcdType)
+                    if self.PcdType == TAB_UINT32 and Size > 4:
+                        raise BadExpression('Type %s PCD Value Size is Larger than 4 byte' % self.PcdType)
+                    if self.PcdType == TAB_UINT64 and Size > 8:
+                        raise BadExpression('Type %s PCD Value Size is Larger than 8 byte' % self.PcdType)
+                else:
+                    try:
+                        TmpValue = int(PcdValue)
+                        TmpList = []
+                        if TmpValue.bit_length() == 0:
+                            PcdValue = '{0x00}'
+                        else:
+                            for I in range((TmpValue.bit_length() + 7) / 8):
+                                TmpList.append('0x%02x' % ((TmpValue >> I * 8) & 0xff))
+                            PcdValue = '{' + ', '.join(TmpList) + '}'
+                    except:
+                        if PcdValue.strip().startswith('{'):
+                            PcdValueList = SplitPcdValueString(PcdValue.strip()[1:-1])
+                            LabelDict = {}
+                            NewPcdValueList = []
+                            LabelOffset = 0
+                            for Item in PcdValueList:
+                                # compute byte offset of every LABEL
+                                LabelList = _ReLabel.findall(Item)
+                                Item = _ReLabel.sub('', Item)
+                                Item = Item.strip()
+                                if LabelList:
+                                    for Label in LabelList:
+                                        if not IsValidCName(Label):
+                                            raise BadExpression('%s is not a valid c variable name' % Label)
+                                        if Label not in LabelDict:
+                                            LabelDict[Label] = str(LabelOffset)
                                 if Item.startswith(TAB_UINT8):
-                                    ItemSize = 1
-                                    ValueType = TAB_UINT8
+                                    LabelOffset = LabelOffset + 1
                                 elif Item.startswith(TAB_UINT16):
-                                    ItemSize = 2
-                                    ValueType = TAB_UINT16
+                                    LabelOffset = LabelOffset + 2
                                 elif Item.startswith(TAB_UINT32):
-                                    ItemSize = 4
-                                    ValueType = TAB_UINT32
+                                    LabelOffset = LabelOffset + 4
                                 elif Item.startswith(TAB_UINT64):
-                                    ItemSize = 8
-                                    ValueType = TAB_UINT64
-                                else:
-                                    ItemSize = 0
-                                if ValueType:
-                                    TmpValue = ValueExpressionEx(Item, ValueType, self._Symb)(True)
+                                    LabelOffset = LabelOffset + 8
                                 else:
-                                    TmpValue = ValueExpressionEx(Item, self.PcdType, self._Symb)(True)
-                                Item = '0x%x' % TmpValue if not isinstance(TmpValue, type('')) else TmpValue
-                                if ItemSize == 0:
-                                    ItemValue, ItemSize = ParseFieldValue(Item)
-                                    if Item[0] not in {'"', 'L', '{'} and ItemSize > 1:
-                                        raise BadExpression("Byte  array number %s should less than 0xFF." % Item)
+                                    try:
+                                        ItemValue, ItemSize = ParseFieldValue(Item)
+                                        LabelOffset = LabelOffset + ItemSize
+                                    except:
+                                        LabelOffset = LabelOffset + 1
+
+                            for Item in PcdValueList:
+                                # for LABEL parse
+                                Item = Item.strip()
+                                try:
+                                    Item = _ReLabel.sub('', Item)
+                                except:
+                                    pass
+                                try:
+                                    OffsetList = _ReOffset.findall(Item)
+                                except:
+                                    pass
+                                # replace each offset, except errors
+                                for Offset in OffsetList:
+                                    try:
+                                        Item = Item.replace('OFFSET_OF({})'.format(Offset), LabelDict[Offset])
+                                    except:
+                                        raise BadExpression('%s not defined' % Offset)
+
+                                NewPcdValueList.append(Item)
+
+                            AllPcdValueList = []
+                            for Item in NewPcdValueList:
+                                Size = 0
+                                ValueStr = ''
+                                TokenSpaceGuidName = ''
+                                if Item.startswith(TAB_GUID) and Item.endswith(')'):
+                                    try:
+                                        TokenSpaceGuidName = re.search('GUID\((\w+)\)', Item).group(1)
+                                    except:
+                                        pass
+                                    if TokenSpaceGuidName and TokenSpaceGuidName in self._Symb:
+                                        Item = 'GUID(' + self._Symb[TokenSpaceGuidName] + ')'
+                                    elif TokenSpaceGuidName:
+                                        raise BadExpression('%s not found in DEC file' % TokenSpaceGuidName)
+                                    Item, Size = ParseFieldValue(Item)
+                                    for Index in range(0, Size):
+                                        ValueStr = '0x%02X' % (int(Item) & 255)
+                                        Item >>= 8
+                                        AllPcdValueList.append(ValueStr)
+                                    continue
+                                elif Item.startswith('DEVICE_PATH') and Item.endswith(')'):
+                                    Item, Size = ParseFieldValue(Item)
+                                    AllPcdValueList.append(Item[1:-1])
+                                    continue
                                 else:
-                                    ItemValue = ParseFieldValue(Item)[0]
-                                for I in range(0, ItemSize):
-                                    ValueStr = '0x%02X' % (int(ItemValue) & 255)
-                                    ItemValue >>= 8
-                                    AllPcdValueList.append(ValueStr)
-                                Size += ItemSize
-
-                        if Size > 0:
-                            PcdValue = '{' + ','.join(AllPcdValueList) + '}'
-                    else:
-                        raise  BadExpression("Type: %s, Value: %s, %s"%(self.PcdType, PcdValue, Value))
+                                    ValueType = ""
+                                    if Item.startswith(TAB_UINT8):
+                                        ItemSize = 1
+                                        ValueType = TAB_UINT8
+                                    elif Item.startswith(TAB_UINT16):
+                                        ItemSize = 2
+                                        ValueType = TAB_UINT16
+                                    elif Item.startswith(TAB_UINT32):
+                                        ItemSize = 4
+                                        ValueType = TAB_UINT32
+                                    elif Item.startswith(TAB_UINT64):
+                                        ItemSize = 8
+                                        ValueType = TAB_UINT64
+                                    else:
+                                        ItemSize = 0
+                                    if ValueType:
+                                        TmpValue = ValueExpressionEx(Item, ValueType, self._Symb)(True)
+                                    else:
+                                        TmpValue = ValueExpressionEx(Item, self.PcdType, self._Symb)(True)
+                                    Item = '0x%x' % TmpValue if not isinstance(TmpValue, type('')) else TmpValue
+                                    if ItemSize == 0:
+                                        ItemValue, ItemSize = ParseFieldValue(Item)
+                                        if Item[0] not in {'"', 'L', '{'} and ItemSize > 1:
+                                            raise BadExpression("Byte  array number %s should less than 0xFF." % Item)
+                                    else:
+                                        ItemValue = ParseFieldValue(Item)[0]
+                                    for I in range(0, ItemSize):
+                                        ValueStr = '0x%02X' % (int(ItemValue) & 255)
+                                        ItemValue >>= 8
+                                        AllPcdValueList.append(ValueStr)
+                                    Size += ItemSize
+
+                            if Size > 0:
+                                PcdValue = '{' + ','.join(AllPcdValueList) + '}'
+                        else:
+                            raise  BadExpression("Type: %s, Value: %s, %s"%(self.PcdType, PcdValue, Value))
 
-        if PcdValue == 'True':
-            PcdValue = '1'
-        if PcdValue == 'False':
-            PcdValue = '0'
+            if PcdValue == 'True':
+                PcdValue = '1'
+            if PcdValue == 'False':
+                PcdValue = '0'
 
         if RealValue:
             return PcdValue
diff --git a/BaseTools/Source/Python/Common/Misc.py b/BaseTools/Source/Python/Common/Misc.py
index 3b8efb2e71..e23772c297 100644
--- a/BaseTools/Source/Python/Common/Misc.py
+++ b/BaseTools/Source/Python/Common/Misc.py
@@ -1297,6 +1297,8 @@ def ParseDevPathValue (Value):
     return '{' + out + '}', Size
 
 def ParseFieldValue (Value):
+    if "{CODE(" in Value:
+        return Value, len(Value.split(","))
     if isinstance(Value, type(0)):
         return Value, (Value.bit_length() + 7) / 8
     if not isinstance(Value, type('')):
diff --git a/BaseTools/Source/Python/Workspace/BuildClassObject.py b/BaseTools/Source/Python/Workspace/BuildClassObject.py
index 95edc376fe..15bb822910 100644
--- a/BaseTools/Source/Python/Workspace/BuildClassObject.py
+++ b/BaseTools/Source/Python/Workspace/BuildClassObject.py
@@ -50,7 +50,7 @@ class PcdClassObject(object):
         self.TokenSpaceGuidCName = Guid
         self.TokenSpaceGuidValue = GuidValue
         self.Type = Type
-        self.DatumType = DatumType
+        self._DatumType = DatumType
         self.DefaultValue = Value
         self.TokenValue = Token
         self.MaxDatumSize = MaxDatumSize
@@ -72,6 +72,63 @@ class PcdClassObject(object):
         self.PcdValueFromFdf = ""
         self.CustomAttribute = {}
         self.UserDefinedDefaultStoresFlag = UserDefinedDefaultStoresFlag
+        self._Capacity = None
+
+    @property
+    def Capacity(self):
+        self._Capacity = []
+        dimension = ArrayIndex.findall(self._DatumType)
+        for item in dimension:
+            maxsize = item.lstrip("[").rstrip("]").strip()
+            if not maxsize:
+                maxsize = "-1"
+            self._Capacity.append(maxsize)
+        if hasattr(self, "SkuOverrideValues"):
+            for sku in self.SkuOverrideValues:
+                for defaultstore in self.SkuOverrideValues[sku]:
+                    fields = self.SkuOverrideValues[sku][defaultstore]
+                    for demesionattr in fields:
+                        deme = ArrayIndex.findall(demesionattr)
+                        for i in range(len(deme)-1):
+                            if int(deme[i].lstrip("[").rstrip("]").strip()) > int(self._Capacity[i]):
+                                print "error"
+        if hasattr(self,"DefaultValues"):
+            for demesionattr in self.DefaultValues:
+                deme = ArrayIndex.findall(demesionattr)
+                for i in range(len(deme)-1):
+                    if int(deme[i].lstrip("[").rstrip("]").strip()) > int(self._Capacity[i]):
+                        print "error"
+        self._Capacity = [str(int(d) + 1) for d in self._Capacity]
+        return self._Capacity
+    @property
+    def DatumType(self):
+        return self._DatumType
+
+    @DatumType.setter
+    def DatumType(self,DataType):
+        self._DatumType = DataType
+        self._Capacity = None
+
+    @property
+    def BaseDatumType(self):
+        if self.IsArray():
+            return self._DatumType[:self._DatumType.index("[")]
+        else:
+            return self._DatumType
+    def IsArray(self):
+        return True if len(self.Capacity) else False
+
+    def IsAggregateDatumType(self):
+        if self.DatumType in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, TAB_VOID, "BOOLEAN"]:
+            return False
+        if self.IsArray() or StructPattern.match(self.DatumType):
+            return True
+        return False
+
+    def IsSimpleTypeArray(self):
+        if self.IsArray() and self.BaseDatumType in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, "BOOLEAN"]:
+            return True
+        return False
 
     @staticmethod
     def GetPcdMaxSizeWorker(PcdString, MaxSize):
@@ -183,23 +240,27 @@ class StructurePcd(PcdClassObject):
     def __repr__(self):
         return self.TypeName
 
-    def AddDefaultValue (self, FieldName, Value, FileName="", LineNo=0):
-        if FieldName in self.DefaultValues:
-            del self.DefaultValues[FieldName]
-        self.DefaultValues[FieldName] = [Value.strip(), FileName, LineNo]
-        return self.DefaultValues[FieldName]
+    def AddDefaultValue (self, FieldName, Value, FileName="", LineNo=0,DimensionAttr ="-1"):
+        if DimensionAttr not in self.DefaultValues:
+            self.DefaultValues[DimensionAttr] = collections.OrderedDict()
+        if FieldName in self.DefaultValues[DimensionAttr]:
+            del self.DefaultValues[DimensionAttr][FieldName]
+        self.DefaultValues[DimensionAttr][FieldName] = [Value.strip(), FileName, LineNo]
+        return self.DefaultValues[DimensionAttr][FieldName]
 
     def SetDecDefaultValue(self, DefaultValue):
         self.DefaultValueFromDec = DefaultValue
-    def AddOverrideValue (self, FieldName, Value, SkuName, DefaultStoreName, FileName="", LineNo=0):
+    def AddOverrideValue (self, FieldName, Value, SkuName, DefaultStoreName, FileName="", LineNo=0, DimensionAttr = '-1'):
         if SkuName not in self.SkuOverrideValues:
             self.SkuOverrideValues[SkuName] = OrderedDict()
         if DefaultStoreName not in self.SkuOverrideValues[SkuName]:
             self.SkuOverrideValues[SkuName][DefaultStoreName] = OrderedDict()
-        if FieldName in self.SkuOverrideValues[SkuName][DefaultStoreName]:
-            del self.SkuOverrideValues[SkuName][DefaultStoreName][FieldName]
-        self.SkuOverrideValues[SkuName][DefaultStoreName][FieldName] = [Value.strip(), FileName, LineNo]
-        return self.SkuOverrideValues[SkuName][DefaultStoreName][FieldName]
+        if DimensionAttr not in self.SkuOverrideValues[SkuName][DefaultStoreName]:
+            self.SkuOverrideValues[SkuName][DefaultStoreName][DimensionAttr] = collections.OrderedDict()
+        if FieldName in self.SkuOverrideValues[SkuName][DefaultStoreName][DimensionAttr]:
+            del self.SkuOverrideValues[SkuName][DefaultStoreName][FieldName][DimensionAttr]
+        self.SkuOverrideValues[SkuName][DefaultStoreName][DimensionAttr][FieldName] = [Value.strip(), FileName, LineNo]
+        return self.SkuOverrideValues[SkuName][DefaultStoreName][DimensionAttr][FieldName]
 
     def SetPcdMode (self, PcdMode):
         self.PcdMode = PcdMode
@@ -209,7 +270,7 @@ class StructurePcd(PcdClassObject):
         self.TokenSpaceGuidCName = PcdObject.TokenSpaceGuidCName if PcdObject.TokenSpaceGuidCName else PcdObject.TokenSpaceGuidCName
         self.TokenSpaceGuidValue = PcdObject.TokenSpaceGuidValue if PcdObject.TokenSpaceGuidValue else self.TokenSpaceGuidValue
         self.Type = PcdObject.Type if PcdObject.Type else self.Type
-        self.DatumType = PcdObject.DatumType if PcdObject.DatumType else self.DatumType
+        self._DatumType = PcdObject.DatumType if PcdObject.DatumType else self.DatumType
         self.DefaultValue = PcdObject.DefaultValue if  PcdObject.DefaultValue else self.DefaultValue
         self.TokenValue = PcdObject.TokenValue if PcdObject.TokenValue else self.TokenValue
         self.MaxDatumSize = PcdObject.MaxDatumSize if PcdObject.MaxDatumSize else self.MaxDatumSize
diff --git a/BaseTools/Source/Python/Workspace/DecBuildData.py b/BaseTools/Source/Python/Workspace/DecBuildData.py
index 31ee13eca9..cc00409fee 100644
--- a/BaseTools/Source/Python/Workspace/DecBuildData.py
+++ b/BaseTools/Source/Python/Workspace/DecBuildData.py
@@ -361,6 +361,21 @@ class DecBuildData(PackageBuildClassObject):
             self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC_EX))
         return self._Pcds
 
+    def ParsePcdName(self,TokenCName):
+        TokenCName = TokenCName.strip()
+        if TokenCName.startswith("["):
+            if "." in TokenCName:
+                Demesionattr = TokenCName[:TokenCName.index(".")]
+                Fields = TokenCName[TokenCName.index(".")+1:]
+            else:
+                Demesionattr = TokenCName
+                Fields = ""
+        else:
+            Demesionattr = ""
+            Fields = TokenCName
+
+        return Demesionattr,Fields
+
     def ProcessStructurePcd(self, StructurePcdRawDataSet):
         s_pcd_set = OrderedDict()
         for s_pcd, LineNo in StructurePcdRawDataSet:
@@ -373,6 +388,8 @@ class DecBuildData(PackageBuildClassObject):
             dep_pkgs = []
             struct_pcd = StructurePcd()
             for item, LineNo in s_pcd_set[pcdname]:
+                if not item.TokenCName:
+                    continue
                 if "<HeaderFiles>" in item.TokenCName:
                     struct_pcd.StructuredPcdIncludeFile.append(item.DefaultValue)
                 elif "<Packages>" in item.TokenCName:
@@ -385,7 +402,8 @@ class DecBuildData(PackageBuildClassObject):
                     struct_pcd.PkgPath = self.MetaFile.File
                     struct_pcd.SetDecDefaultValue(item.DefaultValue)
                 else:
-                    struct_pcd.AddDefaultValue(item.TokenCName, item.DefaultValue, self.MetaFile.File, LineNo)
+                    DemesionAttr, Fields = self.ParsePcdName(item.TokenCName)
+                    struct_pcd.AddDefaultValue(Fields, item.DefaultValue, self.MetaFile.File, LineNo,DemesionAttr)
 
             struct_pcd.PackageDecs = dep_pkgs
             str_pcd_set.append(struct_pcd)
@@ -446,15 +464,12 @@ class DecBuildData(PackageBuildClassObject):
         StructurePcds = self.ProcessStructurePcd(StrPcdSet)
         for pcd in StructurePcds:
             Pcds[pcd.TokenCName, pcd.TokenSpaceGuidCName, self._PCD_TYPE_STRING_[Type]] = pcd
-        StructPattern = re.compile(r'[_a-zA-Z][0-9A-Za-z_]*$')
         for pcd in Pcds.values():
             if pcd.DatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, TAB_VOID, "BOOLEAN"]:
-                if StructPattern.match(pcd.DatumType) is None:
+                if not pcd.IsAggregateDatumType():
                     EdkLogger.error('build', FORMAT_INVALID, "DatumType only support BOOLEAN, UINT8, UINT16, UINT32, UINT64, VOID* or a valid struct name.", DefinitionPosition[pcd][0], DefinitionPosition[pcd][1])
-        for struct_pcd in Pcds.values():
-            if isinstance(struct_pcd, StructurePcd) and not struct_pcd.StructuredPcdIncludeFile:
-                EdkLogger.error("build", PCD_STRUCTURE_PCD_ERROR, "The structure Pcd %s.%s header file is not found in %s line %s \n" % (struct_pcd.TokenSpaceGuidCName, struct_pcd.TokenCName, DefinitionPosition[struct_pcd][0], DefinitionPosition[struct_pcd][1] ))
-
+                elif not pcd.IsArray() and not pcd.StructuredPcdIncludeFile:
+                    EdkLogger.error("build", PCD_STRUCTURE_PCD_ERROR, "The structure Pcd %s.%s header file is not found in %s line %s \n" % (pcd.TokenSpaceGuidCName, pcd.TokenCName, pcd.DefinitionPosition[0], pcd.DefinitionPosition[1] ))
         return Pcds
 
     @property
diff --git a/BaseTools/Source/Python/Workspace/DscBuildData.py b/BaseTools/Source/Python/Workspace/DscBuildData.py
index 11aa63fb26..66d1881aac 100644
--- a/BaseTools/Source/Python/Workspace/DscBuildData.py
+++ b/BaseTools/Source/Python/Workspace/DscBuildData.py
@@ -42,6 +42,7 @@ import subprocess
 from Common.Misc import SaveFileOnChange
 from Workspace.BuildClassObject import PlatformBuildClassObject, StructurePcd, PcdClassObject, ModuleBuildClassObject
 from collections import OrderedDict, defaultdict
+from .BuildClassObject import ArrayIndex
 
 PcdValueInitName = 'PcdValueInit'
 
@@ -912,25 +913,26 @@ class DscBuildData(PlatformBuildClassObject):
                                 ExtraData="%s.%s|%s" % (TokenSpaceGuid, PcdCName, Setting))
         if ValueList[Index]:
             DatumType = self._DecPcds[PcdCName, TokenSpaceGuid].DatumType
-            try:
-                ValueList[Index] = ValueExpressionEx(ValueList[Index], DatumType, self._GuidDict)(True)
-            except BadExpression as Value:
-                EdkLogger.error('Parser', FORMAT_INVALID, Value, File=self.MetaFile, Line=LineNo,
-                                ExtraData="PCD [%s.%s] Value \"%s\" " % (
-                                TokenSpaceGuid, PcdCName, ValueList[Index]))
-            except EvaluationException as Excpt:
-                if hasattr(Excpt, 'Pcd'):
-                    if Excpt.Pcd in GlobalData.gPlatformOtherPcds:
-                        EdkLogger.error('Parser', FORMAT_INVALID, "Cannot use this PCD (%s) in an expression as"
-                                        " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
-                                        " of the DSC file" % Excpt.Pcd,
-                                        File=self.MetaFile, Line=LineNo)
+            if "{CODE(" not in ValueList[Index]:
+                try:
+                    ValueList[Index] = ValueExpressionEx(ValueList[Index], DatumType, self._GuidDict)(True)
+                except BadExpression as Value:
+                    EdkLogger.error('Parser', FORMAT_INVALID, Value, File=self.MetaFile, Line=LineNo,
+                                    ExtraData="PCD [%s.%s] Value \"%s\" " % (
+                                    TokenSpaceGuid, PcdCName, ValueList[Index]))
+                except EvaluationException as Excpt:
+                    if hasattr(Excpt, 'Pcd'):
+                        if Excpt.Pcd in GlobalData.gPlatformOtherPcds:
+                            EdkLogger.error('Parser', FORMAT_INVALID, "Cannot use this PCD (%s) in an expression as"
+                                            " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
+                                            " of the DSC file" % Excpt.Pcd,
+                                            File=self.MetaFile, Line=LineNo)
+                        else:
+                            EdkLogger.error('Parser', FORMAT_INVALID, "PCD (%s) is not defined in DSC file" % Excpt.Pcd,
+                                            File=self.MetaFile, Line=LineNo)
                     else:
-                        EdkLogger.error('Parser', FORMAT_INVALID, "PCD (%s) is not defined in DSC file" % Excpt.Pcd,
+                        EdkLogger.error('Parser', FORMAT_INVALID, "Invalid expression: %s" % str(Excpt),
                                         File=self.MetaFile, Line=LineNo)
-                else:
-                    EdkLogger.error('Parser', FORMAT_INVALID, "Invalid expression: %s" % str(Excpt),
-                                    File=self.MetaFile, Line=LineNo)
 
         if ValueList[Index]:
             Valid, ErrStr = CheckPcdDatum(self._DecPcds[PcdCName, TokenSpaceGuid].DatumType, ValueList[Index])
@@ -1395,6 +1397,26 @@ class DscBuildData(PlatformBuildClassObject):
                         self.Pcds[Name, Guid].DefaultValue = Value
         return AllPcds
 
+    def ParsePcdNameStruct(self,NamePart1,NamePart2):
+        TokenSpaceCName = PcdCName = DimensionAttr = Field = ""
+        if "." in NamePart1:
+            TokenSpaceCName, TempPcdCName = NamePart1.split(".")
+            if "[" in TempPcdCName:
+                PcdCName = TempPcdCName[:TempPcdCName.index("[")]
+                DimensionAttr = TempPcdCName[TempPcdCName.index("["):]
+            else:
+                PcdCName = TempPcdCName
+            Field = NamePart2
+        else:
+            TokenSpaceCName = NamePart1
+            if "[" in NamePart2:
+                PcdCName = NamePart2[:NamePart2.index("[")]
+                DimensionAttr = NamePart2[NamePart2.index("["):]
+            else:
+                PcdCName = NamePart2
+
+        return TokenSpaceCName,PcdCName,DimensionAttr,Field
+
     def UpdateStructuredPcds(self, TypeList, AllPcds):
 
         DynamicPcdType = [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_DEFAULT],
@@ -1424,9 +1446,19 @@ class DscBuildData(PlatformBuildClassObject):
             SkuName = TAB_DEFAULT if SkuName == TAB_COMMON else SkuName
             if SkuName not in SkuIds:
                 continue
+            TCName,PCName,DimensionAttr,Field = self.ParsePcdNameStruct(TokenSpaceGuid, PcdCName)
+            pcd_in_dec = self._DecPcds.get((PCName,TCName), None)
+            if pcd_in_dec is None:
+                EdkLogger.error('build', PARSER_ERROR,
+                            "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (TCName, PCName, self._Arch),
+                            File=self.MetaFile, Line = Dummy5)
+            if SkuName in SkuIds and ("." in TokenSpaceGuid or "[" in PcdCName):
+                if not isinstance (pcd_in_dec, StructurePcd):
+                    EdkLogger.error('build', PARSER_ERROR,
+                                "Pcd (%s.%s) is not declared as Structure PCD in DEC files. Arch: ['%s']" % (TCName, PCName, self._Arch),
+                                File=self.MetaFile, Line = Dummy5)
 
-            if SkuName in SkuIds and "." in TokenSpaceGuid:
-                S_PcdSet.append([ TokenSpaceGuid.split(".")[0], TokenSpaceGuid.split(".")[1], PcdCName, SkuName, default_store, Dummy5, AnalyzePcdExpression(Setting)[0]])
+                S_PcdSet.append([ TCName,PCName,DimensionAttr,Field, SkuName, default_store, Dummy5, AnalyzePcdExpression(Setting)[0]])
 
         # handle pcd value override
         StrPcdSet = DscBuildData.GetStructurePcdInfo(S_PcdSet)
@@ -1434,27 +1466,19 @@ class DscBuildData(PlatformBuildClassObject):
         for str_pcd in StrPcdSet:
             str_pcd_obj = Pcds.get((str_pcd[1], str_pcd[0]), None)
             str_pcd_dec = self._DecPcds.get((str_pcd[1], str_pcd[0]), None)
-            if not isinstance (str_pcd_dec, StructurePcd):
-                EdkLogger.error('build', PARSER_ERROR,
-                            "Pcd (%s.%s) is not declared as Structure PCD in DEC files. Arch: ['%s']" % (str_pcd[0], str_pcd[1], self._Arch),
-                            File=self.MetaFile, Line = StrPcdSet[str_pcd][0][5])
-            if str_pcd_dec:
-                str_pcd_obj_str = StructurePcd()
-                str_pcd_obj_str.copy(str_pcd_dec)
-                if str_pcd_obj:
-                    str_pcd_obj_str.copy(str_pcd_obj)
-                    if str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
-                        str_pcd_obj_str.DefaultFromDSC = {skuname:{defaultstore: str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.get(defaultstore, str_pcd_obj.SkuInfoList[skuname].HiiDefaultValue) for defaultstore in DefaultStores} for skuname in str_pcd_obj.SkuInfoList}
-                    else:
-                        str_pcd_obj_str.DefaultFromDSC = {skuname:{defaultstore: str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.get(defaultstore, str_pcd_obj.SkuInfoList[skuname].DefaultValue) for defaultstore in DefaultStores} for skuname in str_pcd_obj.SkuInfoList}
-                for str_pcd_data in StrPcdSet[str_pcd]:
-                    if str_pcd_data[3] in SkuIds:
-                        str_pcd_obj_str.AddOverrideValue(str_pcd_data[2], str(str_pcd_data[6]), TAB_DEFAULT if str_pcd_data[3] == TAB_COMMON else str_pcd_data[3], TAB_DEFAULT_STORES_DEFAULT if str_pcd_data[4] == TAB_COMMON else str_pcd_data[4], self.MetaFile.File if self.WorkspaceDir not in self.MetaFile.File else self.MetaFile.File[len(self.WorkspaceDir) if self.WorkspaceDir.endswith(os.path.sep) else len(self.WorkspaceDir)+1:], LineNo=str_pcd_data[5])
-                S_pcd_set[str_pcd[1], str_pcd[0]] = str_pcd_obj_str
-            else:
-                EdkLogger.error('build', PARSER_ERROR,
-                            "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (str_pcd[0], str_pcd[1], self._Arch),
-                            File=self.MetaFile, Line = StrPcdSet[str_pcd][0][5])
+            str_pcd_obj_str = StructurePcd()
+            str_pcd_obj_str.copy(str_pcd_dec)
+            if str_pcd_obj:
+                str_pcd_obj_str.copy(str_pcd_obj)
+                if str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
+                    str_pcd_obj_str.DefaultFromDSC = {skuname:{defaultstore: str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.get(defaultstore, str_pcd_obj.SkuInfoList[skuname].HiiDefaultValue) for defaultstore in DefaultStores} for skuname in str_pcd_obj.SkuInfoList}
+                else:
+                    str_pcd_obj_str.DefaultFromDSC = {skuname:{defaultstore: str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.get(defaultstore, str_pcd_obj.SkuInfoList[skuname].DefaultValue) for defaultstore in DefaultStores} for skuname in str_pcd_obj.SkuInfoList}
+            for str_pcd_data in StrPcdSet[str_pcd]:
+                if str_pcd_data[4] in SkuIds:
+                    str_pcd_obj_str.AddOverrideValue(str_pcd_data[3], str(str_pcd_data[7]), TAB_DEFAULT if str_pcd_data[4] == TAB_COMMON else str_pcd_data[4], TAB_DEFAULT_STORES_DEFAULT if str_pcd_data[5] == TAB_COMMON else str_pcd_data[5], self.MetaFile.File if self.WorkspaceDir not in self.MetaFile.File else self.MetaFile.File[len(self.WorkspaceDir) if self.WorkspaceDir.endswith(os.path.sep) else len(self.WorkspaceDir)+1:], LineNo=str_pcd_data[6],DimensionAttr = str_pcd_data[2])
+            S_pcd_set[str_pcd[1], str_pcd[0]] = str_pcd_obj_str
+
         # Add the Structure PCD that only defined in DEC, don't have override in DSC file
         for Pcd in self.DecPcds:
             if isinstance(self._DecPcds[Pcd], StructurePcd):
@@ -1590,9 +1614,10 @@ class DscBuildData(PlatformBuildClassObject):
             if SkuName not in AvailableSkuIdSet:
                 EdkLogger.error('build ', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,
                                             File=self.MetaFile, Line=Dummy5)
-            if "." not in TokenSpaceGuid:
-                PcdSet.add((PcdCName, TokenSpaceGuid, SkuName, Dummy5))
-            PcdDict[Arch, PcdCName, TokenSpaceGuid, SkuName] = Setting
+            if SkuName in (self.SkuIdMgr.SystemSkuId, TAB_DEFAULT, TAB_COMMON):
+                if "." not in TokenSpaceGuid and "[" not in PcdCName:
+                    PcdSet.add((PcdCName, TokenSpaceGuid, SkuName, Dummy5))
+                PcdDict[Arch, PcdCName, TokenSpaceGuid, SkuName] = Setting
 
         for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdSet:
             Setting = PcdDict[self._Arch, PcdCName, TokenSpaceGuid, SkuName]
@@ -1688,7 +1713,20 @@ class DscBuildData(PlatformBuildClassObject):
     def GenerateSizeFunction(self, Pcd):
         CApp = "// Default Value in Dec \n"
         CApp = CApp + "void Cal_%s_%s_Size(UINT32 *Size){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
-        for FieldList in [Pcd.DefaultValues]:
+        if Pcd.IsArray():
+            if (len(Pcd.Capacity) == 1 and Pcd.Capacity[0] != '0') or (len(Pcd.Capacity) >1 and reduce(lambda x,y:int(x)*int(y), Pcd.Capacity)) > 0:
+                CApp += "  *Size = (sizeof (%s) * (%s) > *Size) ? sizeof (%s) * (%s): *Size; \n" % (Pcd.BaseDatumType, "*".join(Pcd.Capacity),Pcd.BaseDatumType, "*".join(Pcd.Capacity))
+            if "{CODE(" in Pcd.DefaultValueFromDec:
+                CApp += "  *Size = (sizeof (%s_%s_INIT_Value) > *Size ? sizeof (%s_%s_INIT_Value) : *Size);\n" % (Pcd.TokenSpaceGuidCName,Pcd.TokenCName,Pcd.TokenSpaceGuidCName,Pcd.TokenCName)
+            for skuname in Pcd.SkuInfoList:
+                skuobj = Pcd.SkuInfoList[skuname]
+                if skuobj.VariableName:
+                    for defaultstore in skuobj.DefaultStoreDict:
+                        CApp += "  *Size = (sizeof (%s_%s_%s_%s_Value) > *Size ? sizeof (%s_%s_%s_%s_Value) : *Size);\n" % (Pcd.TokenSpaceGuidCName,Pcd.TokenCName,skuname,defaultstore,Pcd.TokenSpaceGuidCName,Pcd.TokenCName,skuname,defaultstore)
+                else:
+                    CApp += "  *Size = (sizeof (%s_%s_%s_%s_Value) > *Size ? sizeof (%s_%s_%s_%s_Value) : *Size);\n" % (Pcd.TokenSpaceGuidCName,Pcd.TokenCName,skuname,TAB_DEFAULT_STORES_DEFAULT,Pcd.TokenSpaceGuidCName,Pcd.TokenCName,skuname,TAB_DEFAULT_STORES_DEFAULT)
+        for index in Pcd.DefaultValues:
+            FieldList = Pcd.DefaultValues[index]
             if not FieldList:
                 continue
             for FieldName in FieldList:
@@ -1718,31 +1756,32 @@ class DscBuildData(PlatformBuildClassObject):
                 continue
             for defaultstorenameitem in Pcd.SkuOverrideValues[skuname]:
                 CApp = CApp + "// SkuName: %s,  DefaultStoreName: %s \n" % (skuname, defaultstorenameitem)
-                for FieldList in [Pcd.SkuOverrideValues[skuname].get(defaultstorenameitem)]:
-                    if not FieldList:
-                        continue
-                    for FieldName in FieldList:
-                        FieldName = "." + FieldName
-                        IsArray = IsFieldValueAnArray(FieldList[FieldName.strip(".")][0])
-                        if IsArray and not (FieldList[FieldName.strip(".")][0].startswith('{GUID') and FieldList[FieldName.strip(".")][0].endswith('}')):
-                            try:
-                                Value = ValueExpressionEx(FieldList[FieldName.strip(".")][0], TAB_VOID, self._GuidDict)(True)
-                            except BadExpression:
-                                EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
-                                                (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2]))
-                            Value, ValueSize = ParseFieldValue(Value)
-                            CApp = CApp + '  __FLEXIBLE_SIZE(*Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s) + ((%d %% __ARRAY_ELEMENT_SIZE(%s, %s)) ? 1 : 0)); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2], FieldList[FieldName.strip(".")][0]);
-                        else:
-                            NewFieldName = ''
-                            FieldName_ori = FieldName.strip('.')
-                            while '[' in  FieldName:
-                                NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'
-                                ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])
-                                FieldName = FieldName.split(']', 1)[1]
-                            FieldName = NewFieldName + FieldName
-                            while '[' in FieldName:
-                                FieldName = FieldName.rsplit('[', 1)[0]
-                                CApp = CApp + '  __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %d Value %s \n' % (Pcd.DatumType, FieldName.strip("."), ArrayIndex + 1, FieldList[FieldName_ori][1], FieldList[FieldName_ori][2], FieldList[FieldName_ori][0])
+                for index in Pcd.SkuOverrideValues[skuname][defaultstorenameitem]:
+                    for FieldList in [Pcd.SkuOverrideValues[skuname][defaultstorenameitem][index]]:
+                        if not FieldList:
+                            continue
+                        for FieldName in FieldList:
+                            FieldName = "." + FieldName
+                            IsArray = IsFieldValueAnArray(FieldList[FieldName.strip(".")][0])
+                            if IsArray and not (FieldList[FieldName.strip(".")][0].startswith('{GUID') and FieldList[FieldName.strip(".")][0].endswith('}')):
+                                try:
+                                    Value = ValueExpressionEx(FieldList[FieldName.strip(".")][0], TAB_VOID, self._GuidDict)(True)
+                                except BadExpression:
+                                    EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
+                                                    (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2]))
+                                Value, ValueSize = ParseFieldValue(Value)
+                                CApp = CApp + '  __FLEXIBLE_SIZE(*Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s) + ((%d %% __ARRAY_ELEMENT_SIZE(%s, %s)) ? 1 : 0)); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2], FieldList[FieldName.strip(".")][0]);
+                            else:
+                                NewFieldName = ''
+                                FieldName_ori = FieldName.strip('.')
+                                while '[' in  FieldName:
+                                    NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'
+                                    ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])
+                                    FieldName = FieldName.split(']', 1)[1]
+                                FieldName = NewFieldName + FieldName
+                                while '[' in FieldName:
+                                    FieldName = FieldName.rsplit('[', 1)[0]
+                                    CApp = CApp + '  __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %d Value %s \n' % (Pcd.DatumType, FieldName.strip("."), ArrayIndex + 1, FieldList[FieldName_ori][1], FieldList[FieldName_ori][2], FieldList[FieldName_ori][0])
         if Pcd.PcdFieldValueFromFdf:
             CApp = CApp + "// From fdf \n"
         for FieldName in Pcd.PcdFieldValueFromFdf:
@@ -1791,19 +1830,64 @@ class DscBuildData(PlatformBuildClassObject):
                 while '[' in FieldName:
                     FieldName = FieldName.rsplit('[', 1)[0]
                     CApp = CApp + '  __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %d Value %s \n' % (Pcd.DatumType, FieldName.strip("."), ArrayIndex + 1, Pcd.PcdFieldValueFromComm[FieldName_ori][1], Pcd.PcdFieldValueFromComm[FieldName_ori][2], Pcd.PcdFieldValueFromComm[FieldName_ori][0])
-        CApp = CApp + "  *Size = (%d > *Size ? %d : *Size); // The Pcd maxsize is %d \n" % (Pcd.GetPcdMaxSize(), Pcd.GetPcdMaxSize(), Pcd.GetPcdMaxSize())
+        if Pcd.GetPcdMaxSize():
+            CApp = CApp + "  *Size = (%d > *Size ? %d : *Size); // The Pcd maxsize is %d \n" % (Pcd.GetPcdMaxSize(), Pcd.GetPcdMaxSize(), Pcd.GetPcdMaxSize())
         CApp = CApp + "}\n"
         return CApp
 
     @staticmethod
     def GenerateSizeStatments(Pcd):
-        CApp = '  Size = sizeof(%s);\n' % (Pcd.DatumType)
+        if Pcd.IsArray():
+            r_datatype = [Pcd.BaseDatumType]
+            for dem in Pcd.Capacity:
+                if dem == '0':
+                    r_datatype.append("[1]")
+                else:
+                    r_datatype.append("[" + dem + "]")
+            CApp = '  Size = sizeof(%s);\n' % ("".join(r_datatype))
+        else:
+            CApp = '  Size = sizeof(%s);\n' % (Pcd.DatumType)
         CApp = CApp + '  Cal_%s_%s_Size(&Size);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
         return CApp
 
+    def GetIndicator(self,index,FieldName,Pcd):
+        def cleanupindex(indexstr):
+            return indexstr.strip("[").strip("]").strip()
+        index_elements = ArrayIndex.findall(index)
+        pcd_capacity = Pcd.Capacity
+        if index:
+            indicator = "(Pcd"
+            if len(pcd_capacity)>2:
+                for i in xrange(0,len(index_elements)):
+                    index_ele = index_elements[i]
+                    index_num = index_ele.strip("[").strip("]").strip()
+                    if i == len(index_elements) -2:
+                        indicator += "+ %d*Size/sizeof(%s)/%d + %s)" %(int(cleanupindex(index_elements[i+1])),Pcd.BaseDatumType,reduce(lambda x,y: int(x)*int(y),pcd_capacity[:-1]), cleanupindex(index_elements[i]))
+                        break
+                    else:
+                        indicator += " + %d*%s*Size/sizeof(%s)/%d" %(int(cleanupindex(index_elements[i])),reduce(lambda x,y: int(x)*int(y),pcd_capacity[i+1:-1]),Pcd.BaseDatumType,reduce(lambda x,y: int(x)*int(y),pcd_capacity[:-1]))
+            elif len(pcd_capacity) == 2:
+                indicator += "+ %d*Size/sizeof(%s)/%d + %s)" %(int(cleanupindex(index_elements[0])),Pcd.BaseDatumType,int(pcd_capacity[0]), index_elements[1].strip("[").strip("]").strip())
+            elif len(pcd_capacity) == 1:
+                index_ele = index_elements[0]
+                index_num = index_ele.strip("[").strip("]").strip()
+                indicator += " + %s)" % (index_num)
+        else:
+            indicator = "Pcd"
+        if FieldName:
+            indicator += "->" + FieldName
+        return indicator
+
+    def GetStarNum(self,Pcd):
+        if not Pcd.IsArray():
+            return 1
+        elif Pcd.IsSimpleTypeArray():
+            return len(Pcd.Capacity)
+        else:
+            return len(Pcd.Capacity) + 1
     def GenerateDefaultValueAssignFunction(self, Pcd):
         CApp = "// Default value in Dec \n"
-        CApp = CApp + "void Assign_%s_%s_Default_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.DatumType)
+        CApp = CApp + "void Assign_%s_%s_Default_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.BaseDatumType)
         CApp = CApp + '  UINT32  FieldSize;\n'
         CApp = CApp + '  CHAR8   *Value;\n'
         DefaultValueFromDec = Pcd.DefaultValueFromDec
@@ -1822,9 +1906,13 @@ class DscBuildData(PlatformBuildClassObject):
         #
         # Use memcpy() to copy value into field
         #
-            CApp = CApp + '  Value     = %s; // From DEC Default Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), Pcd.DefaultValueFromDec)
-            CApp = CApp + '  memcpy (Pcd, Value, %d);\n' % (ValueSize)
-        for FieldList in [Pcd.DefaultValues]:
+            if "{CODE(" in Pcd.DefaultValueFromDec:
+                CApp = CApp + '  memcpy (Pcd, %s_%s_INIT_Value, sizeof(%s_%s_INIT_Value));\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
+            else:
+                CApp = CApp + '  Value     = %s; // From DEC Default Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), Pcd.DefaultValueFromDec)
+                CApp = CApp + '  memcpy (Pcd, Value, %d);\n' % (ValueSize)
+        for index in Pcd.DefaultValues:
+            FieldList = Pcd.DefaultValues[index]
             if not FieldList:
                 continue
             for FieldName in FieldList:
@@ -1840,8 +1928,10 @@ class DscBuildData(PlatformBuildClassObject):
                     Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])
                 except Exception:
                     EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " % (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))
+
+                indicator = self.GetIndicator(index, FieldName,Pcd)
                 if isinstance(Value, str):
-                    CApp = CApp + '  Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
+                    CApp = CApp + '  %s = %s; // From %s Line %d Value %s\n' % (indicator, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
                 elif IsArray:
                     #
                     # Use memcpy() to copy value into field
@@ -1850,14 +1940,16 @@ class DscBuildData(PlatformBuildClassObject):
                     CApp = CApp + '  Value     = %s; // From %s Line %d Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
                     CApp = CApp + '  __STATIC_ASSERT((__FIELD_SIZE(%s, %s) >= %d) || (__FIELD_SIZE(%s, %s) == 0), "Input buffer exceeds the buffer array"); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName, ValueSize, Pcd.DatumType, FieldName, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
                     CApp = CApp + '  memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)
+                    CApp = CApp + '  memcpy (&%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (indicator, ValueSize, ValueSize)
+
                 else:
                     if '[' in FieldName and ']' in FieldName:
                         Index = int(FieldName.split('[')[1].split(']')[0])
                         CApp = CApp + '  __STATIC_ASSERT((%d < __ARRAY_SIZE(Pcd->%s)) || (__ARRAY_SIZE(Pcd->%s) == 0), "array index exceeds the array number"); // From %s Line %d Index of %s\n' % (Index, FieldName.split('[')[0], FieldName.split('[')[0], FieldList[FieldName][1], FieldList[FieldName][2], FieldName)
                     if ValueSize > 4:
-                        CApp = CApp + '  Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
+                        CApp = CApp + '  %s = %dULL; // From %s Line %d Value %s\n' % (indicator, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
                     else:
-                        CApp = CApp + '  Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
+                        CApp = CApp + '  %s = %d; // From %s Line %d Value %s\n' % (indicator, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
         CApp = CApp + "}\n"
         return CApp
 
@@ -1868,7 +1960,7 @@ class DscBuildData(PlatformBuildClassObject):
 
     def GenerateInitValueFunction(self, Pcd, SkuName, DefaultStoreName):
         CApp = "// Value in Dsc for Sku: %s, DefaultStore %s\n" % (SkuName, DefaultStoreName)
-        CApp = CApp + "void Assign_%s_%s_%s_%s_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, SkuName, DefaultStoreName, Pcd.DatumType)
+        CApp = CApp + "void Assign_%s_%s_%s_%s_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, SkuName, DefaultStoreName, Pcd.BaseDatumType)
         CApp = CApp + '  UINT32  FieldSize;\n'
         CApp = CApp + '  CHAR8   *Value;\n'
 
@@ -1881,40 +1973,60 @@ class DscBuildData(PlatformBuildClassObject):
                 pcddefaultvalue = Pcd.DscRawValue.get(SkuName, {}).get(DefaultStoreName)
         else:
             pcddefaultvalue = Pcd.DscRawValue.get(SkuName, {}).get(TAB_DEFAULT_STORES_DEFAULT)
-        for FieldList in [pcddefaultvalue, inherit_OverrideValues.get(DefaultStoreName)]:
-            if not FieldList:
-                continue
-            if pcddefaultvalue and FieldList == pcddefaultvalue:
-                IsArray = IsFieldValueAnArray(FieldList)
-                if IsArray:
+
+        if pcddefaultvalue:
+            FieldList = pcddefaultvalue
+            IsArray = IsFieldValueAnArray(FieldList)
+            if IsArray:
+                if "{CODE(" not in FieldList:
                     try:
                         FieldList = ValueExpressionEx(FieldList, TAB_VOID)(True)
                     except BadExpression:
                         EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from DSC: %s" %
                                         (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldList))
-                Value, ValueSize = ParseFieldValue (FieldList)
+            Value, ValueSize = ParseFieldValue (FieldList)
 
-                if (SkuName, DefaultStoreName) == (TAB_DEFAULT, TAB_DEFAULT_STORES_DEFAULT):
-                    if isinstance(Value, str):
+            if (SkuName, DefaultStoreName) == (TAB_DEFAULT, TAB_DEFAULT_STORES_DEFAULT):
+                if isinstance(Value, str):
+                    if "{CODE(" in Value:
+                        CApp = CApp + '  memcpy (Pcd, %s_%s_%s_%s_Value, sizeof(%s_%s_%s_%s_Value));\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName)
+                    else:
                         CApp = CApp + '  Pcd = %s; // From DSC Default Value %s\n' % (Value, Pcd.DefaultFromDSC.get(TAB_DEFAULT, {}).get(TAB_DEFAULT_STORES_DEFAULT, Pcd.DefaultValue) if Pcd.DefaultFromDSC else Pcd.DefaultValue)
-                    elif IsArray:
-                    #
-                    # Use memcpy() to copy value into field
-                    #
+                elif IsArray:
+                #
+                # Use memcpy() to copy value into field
+                #
+                    if Pcd.IsArray():
+                        CApp = CApp + '  memcpy (Pcd, %s_%s_%s_%s_Value, sizeof(%s_%s_%s_%s_Value));\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName)
+                    else:
                         CApp = CApp + '  Value     = %s; // From DSC Default Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), Pcd.DefaultFromDSC.get(TAB_DEFAULT, {}).get(TAB_DEFAULT_STORES_DEFAULT, Pcd.DefaultValue) if Pcd.DefaultFromDSC else Pcd.DefaultValue)
                         CApp = CApp + '  memcpy (Pcd, Value, %d);\n' % (ValueSize)
-                else:
-                    if isinstance(Value, str):
+            else:
+                if isinstance(Value, str):
+                    if "{CODE(" in Value:
+                        CApp = CApp + '  memcpy (Pcd, %s_%s_%s_%s_Value, sizeof(%s_%s_%s_%s_Value));\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName)
+                    else:
                         CApp = CApp + '  Pcd = %s; // From DSC Default Value %s\n' % (Value, Pcd.DscRawValue.get(SkuName, {}).get(DefaultStoreName))
-                    elif IsArray:
-                    #
-                    # Use memcpy() to copy value into field
-                    #
+                elif IsArray:
+                #
+                # Use memcpy() to copy value into field
+                #
+                    if Pcd.IsArray():
+                        CApp = CApp + '  memcpy (Pcd, %s_%s_%s_%s_Value, sizeof(%s_%s_%s_%s_Value));\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName)
+                    else:
                         CApp = CApp + '  Value     = %s; // From DSC Default Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), Pcd.DscRawValue.get(SkuName, {}).get(DefaultStoreName))
                         CApp = CApp + '  memcpy (Pcd, Value, %d);\n' % (ValueSize)
+
+        inheritvalue = inherit_OverrideValues.get(DefaultStoreName)
+        if not inheritvalue:
+            inheritvalue = []
+        for index in inheritvalue:
+            FieldList = inheritvalue[index]
+            if not FieldList:
                 continue
             if (SkuName, DefaultStoreName) == (TAB_DEFAULT, TAB_DEFAULT_STORES_DEFAULT) or (( (SkuName, '') not in Pcd.ValueChain) and ( (SkuName, DefaultStoreName) not in Pcd.ValueChain )):
                 for FieldName in FieldList:
+                    indicator = self.GetIndicator(index, FieldName,Pcd)
                     IsArray = IsFieldValueAnArray(FieldList[FieldName][0])
                     if IsArray:
                         try:
@@ -1932,18 +2044,19 @@ class DscBuildData(PlatformBuildClassObject):
                     #
                     # Use memcpy() to copy value into field
                     #
-                        CApp = CApp + '  FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName)
+                        CApp = CApp + '  FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.BaseDatumType, FieldName)
                         CApp = CApp + '  Value     = %s; // From %s Line %d Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
                         CApp = CApp + '  __STATIC_ASSERT((__FIELD_SIZE(%s, %s) >= %d) || (__FIELD_SIZE(%s, %s) == 0), "Input buffer exceeds the buffer array"); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName, ValueSize, Pcd.DatumType, FieldName, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
                         CApp = CApp + '  memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)
+                        CApp = CApp + '  memcpy (&%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (indicator, ValueSize, ValueSize)
                     else:
                         if '[' in FieldName and ']' in FieldName:
                             Index = int(FieldName.split('[')[1].split(']')[0])
                             CApp = CApp + '  __STATIC_ASSERT((%d < __ARRAY_SIZE(Pcd->%s)) || (__ARRAY_SIZE(Pcd->%s) == 0), "array index exceeds the array number"); // From %s Line %d Index of %s\n' % (Index, FieldName.split('[')[0], FieldName.split('[')[0], FieldList[FieldName][1], FieldList[FieldName][2], FieldName)
                         if ValueSize > 4:
-                            CApp = CApp + '  Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
+                            CApp = CApp + '  %s = %dULL; // From %s Line %d Value %s\n' % (indicator, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
                         else:
-                            CApp = CApp + '  Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
+                            CApp = CApp + '  %s = %d; // From %s Line %d Value %s\n' % (indicator, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
         CApp = CApp + "}\n"
         return CApp
 
@@ -1954,7 +2067,7 @@ class DscBuildData(PlatformBuildClassObject):
 
     def GenerateCommandLineValue(self, Pcd):
         CApp = "// Value in CommandLine\n"
-        CApp = CApp + "void Assign_%s_%s_CommandLine_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.DatumType)
+        CApp = CApp + "void Assign_%s_%s_CommandLine_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.BaseDatumType)
         CApp = CApp + '  UINT32  FieldSize;\n'
         CApp = CApp + '  CHAR8   *Value;\n'
 
@@ -2001,7 +2114,7 @@ class DscBuildData(PlatformBuildClassObject):
                 #
                 # Use memcpy() to copy value into field
                 #
-                    CApp = CApp + '  FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName)
+                    CApp = CApp + '  FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.BaseDatumType, FieldName)
                     CApp = CApp + '  Value     = %s; // From %s Line %d Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
                     CApp = CApp + '  __STATIC_ASSERT((__FIELD_SIZE(%s, %s) >= %d) || (__FIELD_SIZE(%s, %s) == 0), "Input buffer exceeds the buffer array"); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName, ValueSize, Pcd.DatumType, FieldName, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
                     CApp = CApp + '  memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)
@@ -2022,7 +2135,7 @@ class DscBuildData(PlatformBuildClassObject):
         return CApp
     def GenerateFdfValue(self,Pcd):
         CApp = "// Value in Fdf\n"
-        CApp = CApp + "void Assign_%s_%s_Fdf_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType)
+        CApp = CApp + "void Assign_%s_%s_Fdf_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.BaseDatumType)
         CApp = CApp + '  UINT32  FieldSize;\n'
         CApp = CApp + '  CHAR8   *Value;\n'
 
@@ -2069,7 +2182,7 @@ class DscBuildData(PlatformBuildClassObject):
                 #
                 # Use memcpy() to copy value into field
                 #
-                    CApp = CApp + '  FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName)
+                    CApp = CApp + '  FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.BaseDatumType, FieldName)
                     CApp = CApp + '  Value     = %s; // From %s Line %d Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
                     CApp = CApp + '  __STATIC_ASSERT((__FIELD_SIZE(%s, %s) >= %d) || (__FIELD_SIZE(%s, %s) == 0), "Input buffer exceeds the buffer array"); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName, ValueSize, Pcd.DatumType, FieldName, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
                     CApp = CApp + '  memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)
@@ -2090,7 +2203,7 @@ class DscBuildData(PlatformBuildClassObject):
         return CApp
 
     def GenerateInitializeFunc(self, SkuName, DefaultStore, Pcd, InitByteValue, CApp):
-        OverrideValues = {DefaultStore:""}
+        OverrideValues = {DefaultStore:{}}
         if Pcd.SkuOverrideValues:
             OverrideValues = Pcd.SkuOverrideValues[SkuName]
         if not OverrideValues:
@@ -2106,16 +2219,14 @@ class DscBuildData(PlatformBuildClassObject):
             CApp = CApp + '  CHAR8   *Value;\n'
             CApp = CApp + '  UINT32  OriginalSize;\n'
             CApp = CApp + '  VOID    *OriginalPcd;\n'
-            CApp = CApp + '  %s      *Pcd;  // From %s Line %d \n' % (Pcd.DatumType, Pcd.PkgPath, Pcd.PcdDefineLineNo)
+
+            CApp = CApp + '  %s      *Pcd;  // From %s Line %d \n' % (Pcd.BaseDatumType,Pcd.PkgPath, Pcd.PcdDefineLineNo)
+
             CApp = CApp + '\n'
 
-            if SkuName in Pcd.SkuInfoList:
-                DefaultValue = Pcd.SkuInfoList[SkuName].DefaultStoreDict.get(DefaultStoreName, Pcd.SkuInfoList[SkuName].HiiDefaultValue if Pcd.SkuInfoList[SkuName].HiiDefaultValue  else Pcd.SkuInfoList[SkuName].DefaultValue)
-            else:
-                DefaultValue = Pcd.DefaultValue
-            PcdDefaultValue = StringToArray(DefaultValue.strip())
+            PcdDefaultValue = StringToArray(Pcd.DefaultValueFromDec.strip())
 
-            InitByteValue += '%s.%s.%s.%s|%s|%s\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.DatumType, PcdDefaultValue)
+            InitByteValue += '%s.%s.%s.%s|%s|%s\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.BaseDatumType, PcdDefaultValue)
 
             #
             # Get current PCD value and size
@@ -2138,7 +2249,7 @@ class DscBuildData(PlatformBuildClassObject):
             # Always keep that larger one as the current size
             #
             CApp = CApp + '  Size = (OriginalSize > Size ? OriginalSize : Size);\n'
-            CApp = CApp + '  Pcd     = (%s *)malloc (Size);\n' % (Pcd.DatumType)
+            CApp = CApp + '  Pcd     = (%s *)malloc (Size);\n' % (Pcd.BaseDatumType,)
             CApp = CApp + '  memset (Pcd, 0, Size);\n'
 
             #
@@ -2167,7 +2278,7 @@ class DscBuildData(PlatformBuildClassObject):
             #
             # Set new PCD value and size
             #
-            CApp = CApp + '  PcdSetPtr (%s, %s, %s, %s, Size, (UINT8 *)Pcd);\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
+            CApp = CApp + '  PcdSetPtr (%s, %s, %s, %s, Size, (void *)Pcd);\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
 
             #
             # Free PCD
@@ -2176,6 +2287,39 @@ class DscBuildData(PlatformBuildClassObject):
             CApp = CApp + '}\n'
             CApp = CApp + '\n'
         return InitByteValue, CApp
+
+    def GenerateArrayAssignment(self, Pcd):
+        CApp = ""
+        if not Pcd:
+            return CApp
+        if not Pcd.IsArray():
+            return CApp
+        Demesion = ""
+        for d in Pcd.Capacity:
+            if d == "0":
+                Demesion += "[]"
+            else:
+                Demesion += "["+d+"]"
+
+        Value = Pcd.DefaultValueFromDec
+        if "{CODE(" in Pcd.DefaultValueFromDec:
+            realvalue = Pcd.DefaultValueFromDec.strip()[6:-2] # "{CODE(").rstrip(")}"
+            CApp += "static %s %s_%s_INIT_Value%s = %s;\n" % (Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName,Pcd.TokenCName,Demesion,realvalue)
+
+        for skuname in Pcd.SkuInfoList:
+            skuinfo = Pcd.SkuInfoList[skuname]
+            if skuinfo.VariableName:
+                for defaultstore in skuinfo.DefaultStoreDict:
+                    Value = skuinfo[defaultstore]
+                    if "{CODE(" in Value:
+                        realvalue = Value.strip()[6:-2] # "{CODE(").rstrip(")}"
+                        CApp += "static %s %s_%s_%s_%s_Value%s = %s;\n" % (Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName,Pcd.TokenCName,skuname,defaultstore,Demesion,realvalue)
+            else:
+                Value = skuinfo.DefaultValue
+                if "{CODE(" in Value:
+                    realvalue = Value.strip()[6:-2] # "{CODE(").rstrip(")}"
+                    CApp += "static %s %s_%s_%s_%s_Value%s = %s;\n" % (Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName,Pcd.TokenCName,skuname,TAB_DEFAULT_STORES_DEFAULT,Demesion,realvalue)
+        return CApp
     def SkuOverrideValuesEmpty(self,OverrideValues):
         if not OverrideValues:
             return True
@@ -2215,6 +2359,8 @@ class DscBuildData(PlatformBuildClassObject):
                     IncludeFiles.add(IncludeFile)
                     CApp = CApp + '#include <%s>\n' % (IncludeFile)
         CApp = CApp + '\n'
+        for Pcd in StructuredPcds.values():
+            CApp = CApp + self.GenerateArrayAssignment(Pcd)
         for PcdName in StructuredPcds:
             Pcd = StructuredPcds[PcdName]
             CApp = CApp + self.GenerateSizeFunction(Pcd)
@@ -2395,6 +2541,8 @@ class DscBuildData(PlatformBuildClassObject):
                         FileLine = FileInfo [1].split (')')[0]
                     else:
                         FileInfo = Message.strip().split(':')
+                        if len(FileInfo) < 2:
+                            continue
                         FileName = FileInfo [0]
                         FileLine = FileInfo [1]
                     if FileLine.isdigit():
@@ -2478,7 +2626,7 @@ class DscBuildData(PlatformBuildClassObject):
             if SkuName not in AvailableSkuIdSet:
                 EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,
                                             File=self.MetaFile, Line=Dummy5)
-            if "." not in TokenSpaceGuid:
+            if "." not in TokenSpaceGuid and "[" not in PcdCName:
                 PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy5))
             PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting
 
@@ -2651,7 +2799,7 @@ class DscBuildData(PlatformBuildClassObject):
             if DefaultStore not in DefaultStoresDefine:
                 EdkLogger.error('build', PARAMETER_INVALID, 'DefaultStores %s is not defined in [DefaultStores] section' % DefaultStore,
                                             File=self.MetaFile, Line=Dummy5)
-            if "." not in TokenSpaceGuid:
+            if "." not in TokenSpaceGuid and "[" not in PcdCName:
                 PcdSet.add((PcdCName, TokenSpaceGuid, SkuName, DefaultStore, Dummy5))
             PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid, DefaultStore] = Setting
 
@@ -2814,7 +2962,7 @@ class DscBuildData(PlatformBuildClassObject):
             if SkuName not in AvailableSkuIdSet:
                 EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,
                                             File=self.MetaFile, Line=Dummy5)
-            if "." not in TokenSpaceGuid:
+            if "." not in TokenSpaceGuid and "[" not in PcdCName:
                 PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy5))
             PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting
 
diff --git a/BaseTools/Source/Python/Workspace/MetaFileParser.py b/BaseTools/Source/Python/Workspace/MetaFileParser.py
index 804a4aa5cb..6fde9e54f5 100644
--- a/BaseTools/Source/Python/Workspace/MetaFileParser.py
+++ b/BaseTools/Source/Python/Workspace/MetaFileParser.py
@@ -40,6 +40,7 @@ from .MetaFileCommentParser import CheckInfComment
 ## RegEx for finding file versions
 hexVersionPattern = re.compile(r'0[xX][\da-f-A-F]{5,8}')
 decVersionPattern = re.compile(r'\d+\.\d+')
+CODEPattern = re.compile(r"{CODE\([a-fA-F0-9Xx\{\},\s]*\)}")
 
 ## A decorator used to parse macro definition
 def ParseMacro(Parser):
@@ -913,6 +914,10 @@ class DscParser(MetaFileParser):
         #
         self._IdMapping = {-1:-1}
 
+        self._PcdCodeValue = ""
+        self._PcdDataTypeCODE = False
+        self._CurrentPcdName = ""
+
     ## Parser starter
     def Start(self):
         Content = ''
@@ -922,6 +927,9 @@ class DscParser(MetaFileParser):
             EdkLogger.error("Parser", FILE_READ_FAILURE, ExtraData=self.MetaFile)
 
         OwnerId = {}
+
+        Content = self.ProcessMultipleLineCODEValue(Content)
+
         for Index in range(0, len(Content)):
             Line = CleanString(Content[Index])
             # skip empty line
@@ -1133,6 +1141,41 @@ class DscParser(MetaFileParser):
     def _LibraryInstanceParser(self):
         self._ValueList[0] = self._CurrentLine
 
+    def ProcessMultipleLineCODEValue(self,Content):
+        CODEBegin = False
+        CODELine = ""
+        continuelinecount = 0
+        newContent = []
+        for Index in range(0, len(Content)):
+            Line = Content[Index]
+            if CODEBegin:
+                CODELine = CODELine + Line
+                continuelinecount +=1
+                if ")}" in Line:
+                    newContent.append(CODELine)
+                    for _ in range(continuelinecount):
+                        newContent.append("")
+                    CODEBegin = False
+                    CODELine = ""
+                    continuelinecount = 0
+            else:
+                if not Line:
+                    newContent.append(Line)
+                    continue
+                if "{CODE(" not in Line:
+                    newContent.append(Line)
+                    continue
+                elif CODEPattern.findall(Line):
+                    newContent.append(Line)
+                    continue
+                else:
+                    CODEBegin = True
+                    CODELine = Line
+
+        return newContent
+
+    def _DecodeCODEData(self):
+        pass
     ## PCD sections parser
     #
     #   [PcdsFixedAtBuild]
@@ -1149,7 +1192,28 @@ class DscParser(MetaFileParser):
     #
     @ParseMacro
     def _PcdParser(self):
+        if self._PcdDataTypeCODE:
+            self._PcdCodeValue = self._PcdCodeValue + "\n " + self._CurrentLine
+            if self._CurrentLine.endswith(")}"):
+                self._CurrentLine = "|".join((self._CurrentPcdName, self._PcdCodeValue))
+                self._PcdDataTypeCODE = False
+                self._PcdCodeValue = ""
+            else:
+                self._ValueList = None
+                return
         TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT, 1)
+        self._CurrentPcdName = TokenList[0]
+        if TokenList[1].strip().startswith("{CODE"):
+            self._PcdDataTypeCODE = True
+            self._PcdCodeValue = TokenList[1].strip()
+
+        if self._PcdDataTypeCODE:
+            if self._CurrentLine.endswith(")}"):
+                self._PcdDataTypeCODE = False
+                self._PcdCodeValue = ""
+            else:
+                self._ValueList = None
+                return
         self._ValueList[0:1] = GetSplitValueList(TokenList[0], TAB_SPLIT)
         PcdNameTockens = GetSplitValueList(TokenList[0], TAB_SPLIT)
         if len(PcdNameTockens) == 2:
@@ -1907,6 +1971,17 @@ class DecParser(MetaFileParser):
         if self._ValueList[0] not in self._GuidDict:
             self._GuidDict[self._ValueList[0]] = self._ValueList[1]
 
+    def ParsePcdName(self,namelist):
+        if "[" in namelist[1]:
+            pcdname = namelist[1][:namelist[1].index("[")]
+            arrayindex = namelist[1][namelist[1].index("["):]
+            namelist[1] = pcdname
+            if len(namelist) == 2:
+                namelist.append(arrayindex)
+            else:
+                namelist[2] = ".".join((arrayindex,namelist[2]))
+        return namelist
+
     ## PCD sections parser
     #
     #   [PcdsFixedAtBuild]
@@ -1945,9 +2020,16 @@ class DecParser(MetaFileParser):
                     return
             else:
                 PcdTockens = self._CurrentLine.split(TAB_VALUE_SPLIT)
-                PcdNames = PcdTockens[0].split(TAB_SPLIT)
+                PcdNames = self.ParsePcdName(PcdTockens[0].split(TAB_SPLIT))
                 if len(PcdNames) == 2:
-                    self._CurrentStructurePcdName = ""
+                    if PcdNames[1].strip().endswith("]"):
+                        PcdName = PcdNames[1][:PcdNames[1].index('[')]
+                        Index = PcdNames[1][PcdNames[1].index('['):]
+                        self._ValueList[0] = TAB_SPLIT.join((PcdNames[0],PcdName))
+                        self._ValueList[1] = Index
+                        self._ValueList[2] = PcdTockens[1]
+                    else:
+                        self._CurrentStructurePcdName = ""
                 else:
                     if self._CurrentStructurePcdName != TAB_SPLIT.join(PcdNames[:2]):
                         EdkLogger.error('Parser', FORMAT_INVALID, "Pcd Name does not match: %s and %s " % (self._CurrentStructurePcdName, TAB_SPLIT.join(PcdNames[:2])),
-- 
2.19.1.windows.1



^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] BaseTools: Enable Pcd Array support.
  2018-11-07  9:18 [PATCH] BaseTools: Enable Pcd Array support BobCF
@ 2018-11-09 15:24 ` Carsey, Jaben
  0 siblings, 0 replies; 2+ messages in thread
From: Carsey, Jaben @ 2018-11-09 15:24 UTC (permalink / raw)
  To: Feng, Bob C, edk2-devel@lists.01.org; +Cc: Gao, Liming

How concerned with spaces in the DSC lines are we?  The following looks very sensitive to spaces and could be replaced with a regular expression that would be more flexible.

if "{CODE(" not in PcdValue:

aprox:
if re.match('[{]\w*CODE\w*[(]', PcdValue)

> -----Original Message-----
> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of
> BobCF
> Sent: Wednesday, November 07, 2018 1:19 AM
> To: edk2-devel@lists.01.org
> Cc: Gao, Liming <liming.gao@intel.com>
> Subject: [edk2] [PATCH] BaseTools: Enable Pcd Array support.
> 
> From: "bob.c.feng@intel.com" <bob.c.feng@intel.com>
> 
> https://bugzilla.tianocore.org/show_bug.cgi?id=1292
> 
> This patch is going to enable Array data type for PCD.
> 
> 1. Support Pcd ARRAY as Structure PCD type
>    including basic datatype array and structure array.
>    For example:
>    gStructuredPcdPkgTokenSpaceGuid.PcdTest|{0x0}|TEST[10]|0x00010080
> 
> gStructuredPcdPkgTokenSpaceGuid.PcdTest2|{0x0}|UINT8[10]|0x00010081
> 2. Support C CODE style value initialization in DEC/DSC.
>    For example:
> gStructuredPcdPkgTokenSpaceGuid.PcdTest|{CODE({
>   {0, {0, 0, 0, 0,  0, 0, 0}},
>   {0, {0, 0, 0, 0,  0, 0, 0}},
>   {0, {0, 0, 0, 0,  0, 0, 0}},
>   {0, {0, 0, 0, 0,  0, 0, 0}},
>   {0, {0, 0, 0, 0,  0, 0, 0}},
>   {0, {0, 0, 0, 0,  0, 0, 0}},
>   {0, {0, 0, 0, 0,  0, 0, 0}},
>   {0, {0, 0, 0, 0,  0, 0, 0}},
>   {0, {0, 0, 0, 0,  0, 0, 0}},
>   {0, {0, 0, 0, 0,  0, 0, 0}},
> })}
> 
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Bob Feng <bob.c.feng@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> ---
>  BaseTools/Source/Python/Common/Expression.py  | 396 +++++++++--------
> -
>  BaseTools/Source/Python/Common/Misc.py        |   2 +
>  .../Python/Workspace/BuildClassObject.py      |  85 +++-
>  .../Source/Python/Workspace/DecBuildData.py   |  29 +-
>  .../Source/Python/Workspace/DscBuildData.py   | 384 +++++++++++------
>  .../Source/Python/Workspace/MetaFileParser.py |  86 +++-
>  6 files changed, 644 insertions(+), 338 deletions(-)
> 
> diff --git a/BaseTools/Source/Python/Common/Expression.py
> b/BaseTools/Source/Python/Common/Expression.py
> index a21ab5daa7..f6e245be70 100644
> --- a/BaseTools/Source/Python/Common/Expression.py
> +++ b/BaseTools/Source/Python/Common/Expression.py
> @@ -820,221 +820,219 @@ class ValueExpressionEx(ValueExpression):
> 
>      def __call__(self, RealValue=False, Depth=0):
>          PcdValue = self.PcdValue
> -        try:
> -            PcdValue = ValueExpression.__call__(self, RealValue, Depth)
> -            if self.PcdType == TAB_VOID and (PcdValue.startswith("'") or
> PcdValue.startswith("L'")):
> -                PcdValue, Size = ParseFieldValue(PcdValue)
> -                PcdValueList = []
> -                for I in range(Size):
> -                    PcdValueList.append('0x%02X'%(PcdValue & 0xff))
> -                    PcdValue = PcdValue >> 8
> -                PcdValue = '{' + ','.join(PcdValueList) + '}'
> -            elif self.PcdType in TAB_PCD_NUMERIC_TYPES and
> (PcdValue.startswith("'") or \
> -                      PcdValue.startswith('"') or PcdValue.startswith("L'") or
> PcdValue.startswith('L"') or PcdValue.startswith('{')):
> -                raise BadExpression
> -        except WrnExpression as Value:
> -            PcdValue = Value.result
> -        except BadExpression as Value:
> -            if self.PcdType in TAB_PCD_NUMERIC_TYPES:
> -                PcdValue = PcdValue.strip()
> -                if PcdValue.startswith('{') and PcdValue.endswith('}'):
> -                    PcdValue = SplitPcdValueString(PcdValue[1:-1])
> -                if ERR_STRING_CMP.split(':')[0] in Value.message:
> -                    raise BadExpression("Type: %s, Value: %s, %s" % (self.PcdType,
> PcdValue, Value))
> -                if isinstance(PcdValue, type([])):
> -                    TmpValue = 0
> -                    Size = 0
> -                    ValueType = ''
> -                    for Item in PcdValue:
> -                        Item = Item.strip()
> -                        if Item.startswith(TAB_UINT8):
> -                            ItemSize = 1
> -                            ValueType = TAB_UINT8
> -                        elif Item.startswith(TAB_UINT16):
> -                            ItemSize = 2
> -                            ValueType = TAB_UINT16
> -                        elif Item.startswith(TAB_UINT32):
> -                            ItemSize = 4
> -                            ValueType = TAB_UINT32
> -                        elif Item.startswith(TAB_UINT64):
> -                            ItemSize = 8
> -                            ValueType = TAB_UINT64
> -                        elif Item[0] in {'"', "'", 'L'}:
> -                            ItemSize = 0
> -                            ValueType = TAB_VOID
> -                        else:
> -                            ItemSize = 0
> -                            ValueType = TAB_UINT8
> -                        Item = ValueExpressionEx(Item, ValueType, self._Symb)(True)
> -
> -                        if ItemSize == 0:
> -                            try:
> -                                tmpValue = int(Item, 0)
> -                                if tmpValue > 255:
> -                                    raise BadExpression("Byte  array number %s should less
> than 0xFF." % Item)
> -                            except BadExpression as Value:
> -                                raise BadExpression(Value)
> -                            except ValueError:
> -                                pass
> -                            ItemValue, ItemSize = ParseFieldValue(Item)
> -                        else:
> -                            ItemValue = ParseFieldValue(Item)[0]
> -
> -                        if isinstance(ItemValue, type('')):
> -                            ItemValue = int(ItemValue, 0)
> -
> -                        TmpValue = (ItemValue << (Size * 8)) | TmpValue
> -                        Size = Size + ItemSize
> -                else:
> -                    try:
> -                        TmpValue, Size = ParseFieldValue(PcdValue)
> -                    except BadExpression as Value:
> -                        raise BadExpression("Type: %s, Value: %s, %s" % (self.PcdType,
> PcdValue, Value))
> -                if isinstance(TmpValue, type('')):
> -                    try:
> -                        TmpValue = int(TmpValue)
> -                    except:
> -                        raise  BadExpression(Value)
> -                else:
> -                    PcdValue = '0x%0{}X'.format(Size) % (TmpValue)
> -                if TmpValue < 0:
> -                    raise  BadExpression('Type %s PCD Value is negative' %
> self.PcdType)
> -                if self.PcdType == TAB_UINT8 and Size > 1:
> -                    raise BadExpression('Type %s PCD Value Size is Larger than 1 byte'
> % self.PcdType)
> -                if self.PcdType == TAB_UINT16 and Size > 2:
> -                    raise BadExpression('Type %s PCD Value Size is Larger than 2 byte'
> % self.PcdType)
> -                if self.PcdType == TAB_UINT32 and Size > 4:
> -                    raise BadExpression('Type %s PCD Value Size is Larger than 4 byte'
> % self.PcdType)
> -                if self.PcdType == TAB_UINT64 and Size > 8:
> -                    raise BadExpression('Type %s PCD Value Size is Larger than 8 byte'
> % self.PcdType)
> -            else:
> -                try:
> -                    TmpValue = int(PcdValue)
> -                    TmpList = []
> -                    if TmpValue.bit_length() == 0:
> -                        PcdValue = '{0x00}'
> -                    else:
> -                        for I in range((TmpValue.bit_length() + 7) / 8):
> -                            TmpList.append('0x%02x' % ((TmpValue >> I * 8) & 0xff))
> -                        PcdValue = '{' + ', '.join(TmpList) + '}'
> -                except:
> -                    if PcdValue.strip().startswith('{'):
> -                        PcdValueList = SplitPcdValueString(PcdValue.strip()[1:-1])
> -                        LabelDict = {}
> -                        NewPcdValueList = []
> -                        LabelOffset = 0
> -                        for Item in PcdValueList:
> -                            # compute byte offset of every LABEL
> -                            LabelList = _ReLabel.findall(Item)
> -                            Item = _ReLabel.sub('', Item)
> +        if "{CODE(" not in PcdValue:
> +            try:
> +                PcdValue = ValueExpression.__call__(self, RealValue, Depth)
> +                if self.PcdType == TAB_VOID and (PcdValue.startswith("'") or
> PcdValue.startswith("L'")):
> +                    PcdValue, Size = ParseFieldValue(PcdValue)
> +                    PcdValueList = []
> +                    for I in range(Size):
> +                        PcdValueList.append('0x%02X'%(PcdValue & 0xff))
> +                        PcdValue = PcdValue >> 8
> +                    PcdValue = '{' + ','.join(PcdValueList) + '}'
> +                elif self.PcdType in TAB_PCD_NUMERIC_TYPES and
> (PcdValue.startswith("'") or \
> +                          PcdValue.startswith('"') or PcdValue.startswith("L'") or
> PcdValue.startswith('L"') or PcdValue.startswith('{')):
> +                    raise BadExpression
> +            except WrnExpression as Value:
> +                PcdValue = Value.result
> +            except BadExpression as Value:
> +                if self.PcdType in TAB_PCD_NUMERIC_TYPES:
> +                    PcdValue = PcdValue.strip()
> +                    if PcdValue.startswith('{') and PcdValue.endswith('}'):
> +                        PcdValue = SplitPcdValueString(PcdValue[1:-1])
> +                    if isinstance(PcdValue, type([])):
> +                        TmpValue = 0
> +                        Size = 0
> +                        ValueType = ''
> +                        for Item in PcdValue:
>                              Item = Item.strip()
> -                            if LabelList:
> -                                for Label in LabelList:
> -                                    if not IsValidCName(Label):
> -                                        raise BadExpression('%s is not a valid c variable name' %
> Label)
> -                                    if Label not in LabelDict:
> -                                        LabelDict[Label] = str(LabelOffset)
>                              if Item.startswith(TAB_UINT8):
> -                                LabelOffset = LabelOffset + 1
> +                                ItemSize = 1
> +                                ValueType = TAB_UINT8
>                              elif Item.startswith(TAB_UINT16):
> -                                LabelOffset = LabelOffset + 2
> +                                ItemSize = 2
> +                                ValueType = TAB_UINT16
>                              elif Item.startswith(TAB_UINT32):
> -                                LabelOffset = LabelOffset + 4
> +                                ItemSize = 4
> +                                ValueType = TAB_UINT32
>                              elif Item.startswith(TAB_UINT64):
> -                                LabelOffset = LabelOffset + 8
> +                                ItemSize = 8
> +                                ValueType = TAB_UINT64
> +                            elif Item[0] in {'"', "'", 'L'}:
> +                                ItemSize = 0
> +                                ValueType = TAB_VOID
>                              else:
> +                                ItemSize = 0
> +                                ValueType = TAB_UINT8
> +                            Item = ValueExpressionEx(Item, ValueType,
> self._Symb)(True)
> +                            if ItemSize == 0:
>                                  try:
> -                                    ItemValue, ItemSize = ParseFieldValue(Item)
> -                                    LabelOffset = LabelOffset + ItemSize
> -                                except:
> -                                    LabelOffset = LabelOffset + 1
> -
> -                        for Item in PcdValueList:
> -                            # for LABEL parse
> -                            Item = Item.strip()
> -                            try:
> -                                Item = _ReLabel.sub('', Item)
> -                            except:
> -                                pass
> -                            try:
> -                                OffsetList = _ReOffset.findall(Item)
> -                            except:
> -                                pass
> -                            # replace each offset, except errors
> -                            for Offset in OffsetList:
> -                                try:
> -                                    Item = Item.replace('OFFSET_OF({})'.format(Offset),
> LabelDict[Offset])
> -                                except:
> -                                    raise BadExpression('%s not defined' % Offset)
> -
> -                            NewPcdValueList.append(Item)
> -
> -                        AllPcdValueList = []
> -                        for Item in NewPcdValueList:
> -                            Size = 0
> -                            ValueStr = ''
> -                            TokenSpaceGuidName = ''
> -                            if Item.startswith(TAB_GUID) and Item.endswith(')'):
> -                                try:
> -                                    TokenSpaceGuidName = re.search('GUID\((\w+)\)',
> Item).group(1)
> -                                except:
> +                                    tmpValue = int(Item, 0)
> +                                    if tmpValue > 255:
> +                                        raise BadExpression("Byte  array number %s should less
> than 0xFF." % Item)
> +                                except BadExpression as Value:
> +                                    raise BadExpression(Value)
> +                                except ValueError:
>                                      pass
> -                                if TokenSpaceGuidName and TokenSpaceGuidName in
> self._Symb:
> -                                    Item = 'GUID(' + self._Symb[TokenSpaceGuidName] + ')'
> -                                elif TokenSpaceGuidName:
> -                                    raise BadExpression('%s not found in DEC file' %
> TokenSpaceGuidName)
> -                                Item, Size = ParseFieldValue(Item)
> -                                for Index in range(0, Size):
> -                                    ValueStr = '0x%02X' % (int(Item) & 255)
> -                                    Item >>= 8
> -                                    AllPcdValueList.append(ValueStr)
> -                                continue
> -                            elif Item.startswith('DEVICE_PATH') and Item.endswith(')'):
> -                                Item, Size = ParseFieldValue(Item)
> -                                AllPcdValueList.append(Item[1:-1])
> -                                continue
> +                                ItemValue, ItemSize = ParseFieldValue(Item)
>                              else:
> -                                ValueType = ""
> +                                ItemValue = ParseFieldValue(Item)[0]
> +
> +                            if isinstance(ItemValue, type('')):
> +                                ItemValue = int(ItemValue, 0)
> +
> +                            TmpValue = (ItemValue << (Size * 8)) | TmpValue
> +                            Size = Size + ItemSize
> +                    else:
> +                        try:
> +                            TmpValue, Size = ParseFieldValue(PcdValue)
> +                        except BadExpression as Value:
> +                            raise BadExpression("Type: %s, Value: %s, %s" %
> (self.PcdType, PcdValue, Value))
> +                    if isinstance(TmpValue, type('')):
> +                        try:
> +                            TmpValue = int(TmpValue)
> +                        except:
> +                            raise  BadExpression(Value)
> +                    else:
> +                        PcdValue = '0x%0{}X'.format(Size) % (TmpValue)
> +                    if TmpValue < 0:
> +                        raise  BadExpression('Type %s PCD Value is negative' %
> self.PcdType)
> +                    if self.PcdType == TAB_UINT8 and Size > 1:
> +                        raise BadExpression('Type %s PCD Value Size is Larger than 1
> byte' % self.PcdType)
> +                    if self.PcdType == TAB_UINT16 and Size > 2:
> +                        raise BadExpression('Type %s PCD Value Size is Larger than 2
> byte' % self.PcdType)
> +                    if self.PcdType == TAB_UINT32 and Size > 4:
> +                        raise BadExpression('Type %s PCD Value Size is Larger than 4
> byte' % self.PcdType)
> +                    if self.PcdType == TAB_UINT64 and Size > 8:
> +                        raise BadExpression('Type %s PCD Value Size is Larger than 8
> byte' % self.PcdType)
> +                else:
> +                    try:
> +                        TmpValue = int(PcdValue)
> +                        TmpList = []
> +                        if TmpValue.bit_length() == 0:
> +                            PcdValue = '{0x00}'
> +                        else:
> +                            for I in range((TmpValue.bit_length() + 7) / 8):
> +                                TmpList.append('0x%02x' % ((TmpValue >> I * 8) & 0xff))
> +                            PcdValue = '{' + ', '.join(TmpList) + '}'
> +                    except:
> +                        if PcdValue.strip().startswith('{'):
> +                            PcdValueList = SplitPcdValueString(PcdValue.strip()[1:-1])
> +                            LabelDict = {}
> +                            NewPcdValueList = []
> +                            LabelOffset = 0
> +                            for Item in PcdValueList:
> +                                # compute byte offset of every LABEL
> +                                LabelList = _ReLabel.findall(Item)
> +                                Item = _ReLabel.sub('', Item)
> +                                Item = Item.strip()
> +                                if LabelList:
> +                                    for Label in LabelList:
> +                                        if not IsValidCName(Label):
> +                                            raise BadExpression('%s is not a valid c variable name'
> % Label)
> +                                        if Label not in LabelDict:
> +                                            LabelDict[Label] = str(LabelOffset)
>                                  if Item.startswith(TAB_UINT8):
> -                                    ItemSize = 1
> -                                    ValueType = TAB_UINT8
> +                                    LabelOffset = LabelOffset + 1
>                                  elif Item.startswith(TAB_UINT16):
> -                                    ItemSize = 2
> -                                    ValueType = TAB_UINT16
> +                                    LabelOffset = LabelOffset + 2
>                                  elif Item.startswith(TAB_UINT32):
> -                                    ItemSize = 4
> -                                    ValueType = TAB_UINT32
> +                                    LabelOffset = LabelOffset + 4
>                                  elif Item.startswith(TAB_UINT64):
> -                                    ItemSize = 8
> -                                    ValueType = TAB_UINT64
> -                                else:
> -                                    ItemSize = 0
> -                                if ValueType:
> -                                    TmpValue = ValueExpressionEx(Item, ValueType,
> self._Symb)(True)
> +                                    LabelOffset = LabelOffset + 8
>                                  else:
> -                                    TmpValue = ValueExpressionEx(Item, self.PcdType,
> self._Symb)(True)
> -                                Item = '0x%x' % TmpValue if not isinstance(TmpValue,
> type('')) else TmpValue
> -                                if ItemSize == 0:
> -                                    ItemValue, ItemSize = ParseFieldValue(Item)
> -                                    if Item[0] not in {'"', 'L', '{'} and ItemSize > 1:
> -                                        raise BadExpression("Byte  array number %s should less
> than 0xFF." % Item)
> +                                    try:
> +                                        ItemValue, ItemSize = ParseFieldValue(Item)
> +                                        LabelOffset = LabelOffset + ItemSize
> +                                    except:
> +                                        LabelOffset = LabelOffset + 1
> +
> +                            for Item in PcdValueList:
> +                                # for LABEL parse
> +                                Item = Item.strip()
> +                                try:
> +                                    Item = _ReLabel.sub('', Item)
> +                                except:
> +                                    pass
> +                                try:
> +                                    OffsetList = _ReOffset.findall(Item)
> +                                except:
> +                                    pass
> +                                # replace each offset, except errors
> +                                for Offset in OffsetList:
> +                                    try:
> +                                        Item = Item.replace('OFFSET_OF({})'.format(Offset),
> LabelDict[Offset])
> +                                    except:
> +                                        raise BadExpression('%s not defined' % Offset)
> +
> +                                NewPcdValueList.append(Item)
> +
> +                            AllPcdValueList = []
> +                            for Item in NewPcdValueList:
> +                                Size = 0
> +                                ValueStr = ''
> +                                TokenSpaceGuidName = ''
> +                                if Item.startswith(TAB_GUID) and Item.endswith(')'):
> +                                    try:
> +                                        TokenSpaceGuidName = re.search('GUID\((\w+)\)',
> Item).group(1)
> +                                    except:
> +                                        pass
> +                                    if TokenSpaceGuidName and TokenSpaceGuidName in
> self._Symb:
> +                                        Item = 'GUID(' + self._Symb[TokenSpaceGuidName] +
> ')'
> +                                    elif TokenSpaceGuidName:
> +                                        raise BadExpression('%s not found in DEC file' %
> TokenSpaceGuidName)
> +                                    Item, Size = ParseFieldValue(Item)
> +                                    for Index in range(0, Size):
> +                                        ValueStr = '0x%02X' % (int(Item) & 255)
> +                                        Item >>= 8
> +                                        AllPcdValueList.append(ValueStr)
> +                                    continue
> +                                elif Item.startswith('DEVICE_PATH') and Item.endswith(')'):
> +                                    Item, Size = ParseFieldValue(Item)
> +                                    AllPcdValueList.append(Item[1:-1])
> +                                    continue
>                                  else:
> -                                    ItemValue = ParseFieldValue(Item)[0]
> -                                for I in range(0, ItemSize):
> -                                    ValueStr = '0x%02X' % (int(ItemValue) & 255)
> -                                    ItemValue >>= 8
> -                                    AllPcdValueList.append(ValueStr)
> -                                Size += ItemSize
> -
> -                        if Size > 0:
> -                            PcdValue = '{' + ','.join(AllPcdValueList) + '}'
> -                    else:
> -                        raise  BadExpression("Type: %s, Value: %s, %s"%(self.PcdType,
> PcdValue, Value))
> +                                    ValueType = ""
> +                                    if Item.startswith(TAB_UINT8):
> +                                        ItemSize = 1
> +                                        ValueType = TAB_UINT8
> +                                    elif Item.startswith(TAB_UINT16):
> +                                        ItemSize = 2
> +                                        ValueType = TAB_UINT16
> +                                    elif Item.startswith(TAB_UINT32):
> +                                        ItemSize = 4
> +                                        ValueType = TAB_UINT32
> +                                    elif Item.startswith(TAB_UINT64):
> +                                        ItemSize = 8
> +                                        ValueType = TAB_UINT64
> +                                    else:
> +                                        ItemSize = 0
> +                                    if ValueType:
> +                                        TmpValue = ValueExpressionEx(Item, ValueType,
> self._Symb)(True)
> +                                    else:
> +                                        TmpValue = ValueExpressionEx(Item, self.PcdType,
> self._Symb)(True)
> +                                    Item = '0x%x' % TmpValue if not isinstance(TmpValue,
> type('')) else TmpValue
> +                                    if ItemSize == 0:
> +                                        ItemValue, ItemSize = ParseFieldValue(Item)
> +                                        if Item[0] not in {'"', 'L', '{'} and ItemSize > 1:
> +                                            raise BadExpression("Byte  array number %s should
> less than 0xFF." % Item)
> +                                    else:
> +                                        ItemValue = ParseFieldValue(Item)[0]
> +                                    for I in range(0, ItemSize):
> +                                        ValueStr = '0x%02X' % (int(ItemValue) & 255)
> +                                        ItemValue >>= 8
> +                                        AllPcdValueList.append(ValueStr)
> +                                    Size += ItemSize
> +
> +                            if Size > 0:
> +                                PcdValue = '{' + ','.join(AllPcdValueList) + '}'
> +                        else:
> +                            raise  BadExpression("Type: %s, Value: %s,
> %s"%(self.PcdType, PcdValue, Value))
> 
> -        if PcdValue == 'True':
> -            PcdValue = '1'
> -        if PcdValue == 'False':
> -            PcdValue = '0'
> +            if PcdValue == 'True':
> +                PcdValue = '1'
> +            if PcdValue == 'False':
> +                PcdValue = '0'
> 
>          if RealValue:
>              return PcdValue
> diff --git a/BaseTools/Source/Python/Common/Misc.py
> b/BaseTools/Source/Python/Common/Misc.py
> index 3b8efb2e71..e23772c297 100644
> --- a/BaseTools/Source/Python/Common/Misc.py
> +++ b/BaseTools/Source/Python/Common/Misc.py
> @@ -1297,6 +1297,8 @@ def ParseDevPathValue (Value):
>      return '{' + out + '}', Size
> 
>  def ParseFieldValue (Value):
> +    if "{CODE(" in Value:
> +        return Value, len(Value.split(","))
>      if isinstance(Value, type(0)):
>          return Value, (Value.bit_length() + 7) / 8
>      if not isinstance(Value, type('')):
> diff --git a/BaseTools/Source/Python/Workspace/BuildClassObject.py
> b/BaseTools/Source/Python/Workspace/BuildClassObject.py
> index 95edc376fe..15bb822910 100644
> --- a/BaseTools/Source/Python/Workspace/BuildClassObject.py
> +++ b/BaseTools/Source/Python/Workspace/BuildClassObject.py
> @@ -50,7 +50,7 @@ class PcdClassObject(object):
>          self.TokenSpaceGuidCName = Guid
>          self.TokenSpaceGuidValue = GuidValue
>          self.Type = Type
> -        self.DatumType = DatumType
> +        self._DatumType = DatumType
>          self.DefaultValue = Value
>          self.TokenValue = Token
>          self.MaxDatumSize = MaxDatumSize
> @@ -72,6 +72,63 @@ class PcdClassObject(object):
>          self.PcdValueFromFdf = ""
>          self.CustomAttribute = {}
>          self.UserDefinedDefaultStoresFlag = UserDefinedDefaultStoresFlag
> +        self._Capacity = None
> +
> +    @property
> +    def Capacity(self):
> +        self._Capacity = []
> +        dimension = ArrayIndex.findall(self._DatumType)
> +        for item in dimension:
> +            maxsize = item.lstrip("[").rstrip("]").strip()
> +            if not maxsize:
> +                maxsize = "-1"
> +            self._Capacity.append(maxsize)
> +        if hasattr(self, "SkuOverrideValues"):
> +            for sku in self.SkuOverrideValues:
> +                for defaultstore in self.SkuOverrideValues[sku]:
> +                    fields = self.SkuOverrideValues[sku][defaultstore]
> +                    for demesionattr in fields:
> +                        deme = ArrayIndex.findall(demesionattr)
> +                        for i in range(len(deme)-1):
> +                            if int(deme[i].lstrip("[").rstrip("]").strip()) >
> int(self._Capacity[i]):
> +                                print "error"
> +        if hasattr(self,"DefaultValues"):
> +            for demesionattr in self.DefaultValues:
> +                deme = ArrayIndex.findall(demesionattr)
> +                for i in range(len(deme)-1):
> +                    if int(deme[i].lstrip("[").rstrip("]").strip()) > int(self._Capacity[i]):
> +                        print "error"
> +        self._Capacity = [str(int(d) + 1) for d in self._Capacity]
> +        return self._Capacity
> +    @property
> +    def DatumType(self):
> +        return self._DatumType
> +
> +    @DatumType.setter
> +    def DatumType(self,DataType):
> +        self._DatumType = DataType
> +        self._Capacity = None
> +
> +    @property
> +    def BaseDatumType(self):
> +        if self.IsArray():
> +            return self._DatumType[:self._DatumType.index("[")]
> +        else:
> +            return self._DatumType
> +    def IsArray(self):
> +        return True if len(self.Capacity) else False
> +
> +    def IsAggregateDatumType(self):
> +        if self.DatumType in [TAB_UINT8, TAB_UINT16, TAB_UINT32,
> TAB_UINT64, TAB_VOID, "BOOLEAN"]:
> +            return False
> +        if self.IsArray() or StructPattern.match(self.DatumType):
> +            return True
> +        return False
> +
> +    def IsSimpleTypeArray(self):
> +        if self.IsArray() and self.BaseDatumType in [TAB_UINT8, TAB_UINT16,
> TAB_UINT32, TAB_UINT64, "BOOLEAN"]:
> +            return True
> +        return False
> 
>      @staticmethod
>      def GetPcdMaxSizeWorker(PcdString, MaxSize):
> @@ -183,23 +240,27 @@ class StructurePcd(PcdClassObject):
>      def __repr__(self):
>          return self.TypeName
> 
> -    def AddDefaultValue (self, FieldName, Value, FileName="", LineNo=0):
> -        if FieldName in self.DefaultValues:
> -            del self.DefaultValues[FieldName]
> -        self.DefaultValues[FieldName] = [Value.strip(), FileName, LineNo]
> -        return self.DefaultValues[FieldName]
> +    def AddDefaultValue (self, FieldName, Value, FileName="",
> LineNo=0,DimensionAttr ="-1"):
> +        if DimensionAttr not in self.DefaultValues:
> +            self.DefaultValues[DimensionAttr] = collections.OrderedDict()
> +        if FieldName in self.DefaultValues[DimensionAttr]:
> +            del self.DefaultValues[DimensionAttr][FieldName]
> +        self.DefaultValues[DimensionAttr][FieldName] = [Value.strip(),
> FileName, LineNo]
> +        return self.DefaultValues[DimensionAttr][FieldName]
> 
>      def SetDecDefaultValue(self, DefaultValue):
>          self.DefaultValueFromDec = DefaultValue
> -    def AddOverrideValue (self, FieldName, Value, SkuName,
> DefaultStoreName, FileName="", LineNo=0):
> +    def AddOverrideValue (self, FieldName, Value, SkuName,
> DefaultStoreName, FileName="", LineNo=0, DimensionAttr = '-1'):
>          if SkuName not in self.SkuOverrideValues:
>              self.SkuOverrideValues[SkuName] = OrderedDict()
>          if DefaultStoreName not in self.SkuOverrideValues[SkuName]:
>              self.SkuOverrideValues[SkuName][DefaultStoreName] =
> OrderedDict()
> -        if FieldName in self.SkuOverrideValues[SkuName][DefaultStoreName]:
> -            del
> self.SkuOverrideValues[SkuName][DefaultStoreName][FieldName]
> -        self.SkuOverrideValues[SkuName][DefaultStoreName][FieldName] =
> [Value.strip(), FileName, LineNo]
> -        return
> self.SkuOverrideValues[SkuName][DefaultStoreName][FieldName]
> +        if DimensionAttr not in
> self.SkuOverrideValues[SkuName][DefaultStoreName]:
> +
> self.SkuOverrideValues[SkuName][DefaultStoreName][DimensionAttr] =
> collections.OrderedDict()
> +        if FieldName in
> self.SkuOverrideValues[SkuName][DefaultStoreName][DimensionAttr]:
> +            del
> self.SkuOverrideValues[SkuName][DefaultStoreName][FieldName][Dimensi
> onAttr]
> +
> self.SkuOverrideValues[SkuName][DefaultStoreName][DimensionAttr][Field
> Name] = [Value.strip(), FileName, LineNo]
> +        return
> self.SkuOverrideValues[SkuName][DefaultStoreName][DimensionAttr][Field
> Name]
> 
>      def SetPcdMode (self, PcdMode):
>          self.PcdMode = PcdMode
> @@ -209,7 +270,7 @@ class StructurePcd(PcdClassObject):
>          self.TokenSpaceGuidCName = PcdObject.TokenSpaceGuidCName if
> PcdObject.TokenSpaceGuidCName else PcdObject.TokenSpaceGuidCName
>          self.TokenSpaceGuidValue = PcdObject.TokenSpaceGuidValue if
> PcdObject.TokenSpaceGuidValue else self.TokenSpaceGuidValue
>          self.Type = PcdObject.Type if PcdObject.Type else self.Type
> -        self.DatumType = PcdObject.DatumType if PcdObject.DatumType else
> self.DatumType
> +        self._DatumType = PcdObject.DatumType if PcdObject.DatumType else
> self.DatumType
>          self.DefaultValue = PcdObject.DefaultValue if  PcdObject.DefaultValue
> else self.DefaultValue
>          self.TokenValue = PcdObject.TokenValue if PcdObject.TokenValue else
> self.TokenValue
>          self.MaxDatumSize = PcdObject.MaxDatumSize if
> PcdObject.MaxDatumSize else self.MaxDatumSize
> diff --git a/BaseTools/Source/Python/Workspace/DecBuildData.py
> b/BaseTools/Source/Python/Workspace/DecBuildData.py
> index 31ee13eca9..cc00409fee 100644
> --- a/BaseTools/Source/Python/Workspace/DecBuildData.py
> +++ b/BaseTools/Source/Python/Workspace/DecBuildData.py
> @@ -361,6 +361,21 @@ class DecBuildData(PackageBuildClassObject):
>              self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC_EX))
>          return self._Pcds
> 
> +    def ParsePcdName(self,TokenCName):
> +        TokenCName = TokenCName.strip()
> +        if TokenCName.startswith("["):
> +            if "." in TokenCName:
> +                Demesionattr = TokenCName[:TokenCName.index(".")]
> +                Fields = TokenCName[TokenCName.index(".")+1:]
> +            else:
> +                Demesionattr = TokenCName
> +                Fields = ""
> +        else:
> +            Demesionattr = ""
> +            Fields = TokenCName
> +
> +        return Demesionattr,Fields
> +
>      def ProcessStructurePcd(self, StructurePcdRawDataSet):
>          s_pcd_set = OrderedDict()
>          for s_pcd, LineNo in StructurePcdRawDataSet:
> @@ -373,6 +388,8 @@ class DecBuildData(PackageBuildClassObject):
>              dep_pkgs = []
>              struct_pcd = StructurePcd()
>              for item, LineNo in s_pcd_set[pcdname]:
> +                if not item.TokenCName:
> +                    continue
>                  if "<HeaderFiles>" in item.TokenCName:
>                      struct_pcd.StructuredPcdIncludeFile.append(item.DefaultValue)
>                  elif "<Packages>" in item.TokenCName:
> @@ -385,7 +402,8 @@ class DecBuildData(PackageBuildClassObject):
>                      struct_pcd.PkgPath = self.MetaFile.File
>                      struct_pcd.SetDecDefaultValue(item.DefaultValue)
>                  else:
> -                    struct_pcd.AddDefaultValue(item.TokenCName,
> item.DefaultValue, self.MetaFile.File, LineNo)
> +                    DemesionAttr, Fields = self.ParsePcdName(item.TokenCName)
> +                    struct_pcd.AddDefaultValue(Fields, item.DefaultValue,
> self.MetaFile.File, LineNo,DemesionAttr)
> 
>              struct_pcd.PackageDecs = dep_pkgs
>              str_pcd_set.append(struct_pcd)
> @@ -446,15 +464,12 @@ class DecBuildData(PackageBuildClassObject):
>          StructurePcds = self.ProcessStructurePcd(StrPcdSet)
>          for pcd in StructurePcds:
>              Pcds[pcd.TokenCName, pcd.TokenSpaceGuidCName,
> self._PCD_TYPE_STRING_[Type]] = pcd
> -        StructPattern = re.compile(r'[_a-zA-Z][0-9A-Za-z_]*$')
>          for pcd in Pcds.values():
>              if pcd.DatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32,
> TAB_UINT64, TAB_VOID, "BOOLEAN"]:
> -                if StructPattern.match(pcd.DatumType) is None:
> +                if not pcd.IsAggregateDatumType():
>                      EdkLogger.error('build', FORMAT_INVALID, "DatumType only
> support BOOLEAN, UINT8, UINT16, UINT32, UINT64, VOID* or a valid struct
> name.", DefinitionPosition[pcd][0], DefinitionPosition[pcd][1])
> -        for struct_pcd in Pcds.values():
> -            if isinstance(struct_pcd, StructurePcd) and not
> struct_pcd.StructuredPcdIncludeFile:
> -                EdkLogger.error("build", PCD_STRUCTURE_PCD_ERROR, "The
> structure Pcd %s.%s header file is not found in %s line %s \n" %
> (struct_pcd.TokenSpaceGuidCName, struct_pcd.TokenCName,
> DefinitionPosition[struct_pcd][0], DefinitionPosition[struct_pcd][1] ))
> -
> +                elif not pcd.IsArray() and not pcd.StructuredPcdIncludeFile:
> +                    EdkLogger.error("build", PCD_STRUCTURE_PCD_ERROR, "The
> structure Pcd %s.%s header file is not found in %s line %s \n" %
> (pcd.TokenSpaceGuidCName, pcd.TokenCName, pcd.DefinitionPosition[0],
> pcd.DefinitionPosition[1] ))
>          return Pcds
> 
>      @property
> diff --git a/BaseTools/Source/Python/Workspace/DscBuildData.py
> b/BaseTools/Source/Python/Workspace/DscBuildData.py
> index 11aa63fb26..66d1881aac 100644
> --- a/BaseTools/Source/Python/Workspace/DscBuildData.py
> +++ b/BaseTools/Source/Python/Workspace/DscBuildData.py
> @@ -42,6 +42,7 @@ import subprocess
>  from Common.Misc import SaveFileOnChange
>  from Workspace.BuildClassObject import PlatformBuildClassObject,
> StructurePcd, PcdClassObject, ModuleBuildClassObject
>  from collections import OrderedDict, defaultdict
> +from .BuildClassObject import ArrayIndex
> 
>  PcdValueInitName = 'PcdValueInit'
> 
> @@ -912,25 +913,26 @@ class DscBuildData(PlatformBuildClassObject):
>                                  ExtraData="%s.%s|%s" % (TokenSpaceGuid, PcdCName,
> Setting))
>          if ValueList[Index]:
>              DatumType = self._DecPcds[PcdCName,
> TokenSpaceGuid].DatumType
> -            try:
> -                ValueList[Index] = ValueExpressionEx(ValueList[Index], DatumType,
> self._GuidDict)(True)
> -            except BadExpression as Value:
> -                EdkLogger.error('Parser', FORMAT_INVALID, Value,
> File=self.MetaFile, Line=LineNo,
> -                                ExtraData="PCD [%s.%s] Value \"%s\" " % (
> -                                TokenSpaceGuid, PcdCName, ValueList[Index]))
> -            except EvaluationException as Excpt:
> -                if hasattr(Excpt, 'Pcd'):
> -                    if Excpt.Pcd in GlobalData.gPlatformOtherPcds:
> -                        EdkLogger.error('Parser', FORMAT_INVALID, "Cannot use this
> PCD (%s) in an expression as"
> -                                        " it must be defined in a [PcdsFixedAtBuild] or
> [PcdsFeatureFlag] section"
> -                                        " of the DSC file" % Excpt.Pcd,
> -                                        File=self.MetaFile, Line=LineNo)
> +            if "{CODE(" not in ValueList[Index]:
> +                try:
> +                    ValueList[Index] = ValueExpressionEx(ValueList[Index],
> DatumType, self._GuidDict)(True)
> +                except BadExpression as Value:
> +                    EdkLogger.error('Parser', FORMAT_INVALID, Value,
> File=self.MetaFile, Line=LineNo,
> +                                    ExtraData="PCD [%s.%s] Value \"%s\" " % (
> +                                    TokenSpaceGuid, PcdCName, ValueList[Index]))
> +                except EvaluationException as Excpt:
> +                    if hasattr(Excpt, 'Pcd'):
> +                        if Excpt.Pcd in GlobalData.gPlatformOtherPcds:
> +                            EdkLogger.error('Parser', FORMAT_INVALID, "Cannot use this
> PCD (%s) in an expression as"
> +                                            " it must be defined in a [PcdsFixedAtBuild] or
> [PcdsFeatureFlag] section"
> +                                            " of the DSC file" % Excpt.Pcd,
> +                                            File=self.MetaFile, Line=LineNo)
> +                        else:
> +                            EdkLogger.error('Parser', FORMAT_INVALID, "PCD (%s) is not
> defined in DSC file" % Excpt.Pcd,
> +                                            File=self.MetaFile, Line=LineNo)
>                      else:
> -                        EdkLogger.error('Parser', FORMAT_INVALID, "PCD (%s) is not
> defined in DSC file" % Excpt.Pcd,
> +                        EdkLogger.error('Parser', FORMAT_INVALID, "Invalid
> expression: %s" % str(Excpt),
>                                          File=self.MetaFile, Line=LineNo)
> -                else:
> -                    EdkLogger.error('Parser', FORMAT_INVALID, "Invalid expression:
> %s" % str(Excpt),
> -                                    File=self.MetaFile, Line=LineNo)
> 
>          if ValueList[Index]:
>              Valid, ErrStr = CheckPcdDatum(self._DecPcds[PcdCName,
> TokenSpaceGuid].DatumType, ValueList[Index])
> @@ -1395,6 +1397,26 @@ class DscBuildData(PlatformBuildClassObject):
>                          self.Pcds[Name, Guid].DefaultValue = Value
>          return AllPcds
> 
> +    def ParsePcdNameStruct(self,NamePart1,NamePart2):
> +        TokenSpaceCName = PcdCName = DimensionAttr = Field = ""
> +        if "." in NamePart1:
> +            TokenSpaceCName, TempPcdCName = NamePart1.split(".")
> +            if "[" in TempPcdCName:
> +                PcdCName = TempPcdCName[:TempPcdCName.index("[")]
> +                DimensionAttr = TempPcdCName[TempPcdCName.index("["):]
> +            else:
> +                PcdCName = TempPcdCName
> +            Field = NamePart2
> +        else:
> +            TokenSpaceCName = NamePart1
> +            if "[" in NamePart2:
> +                PcdCName = NamePart2[:NamePart2.index("[")]
> +                DimensionAttr = NamePart2[NamePart2.index("["):]
> +            else:
> +                PcdCName = NamePart2
> +
> +        return TokenSpaceCName,PcdCName,DimensionAttr,Field
> +
>      def UpdateStructuredPcds(self, TypeList, AllPcds):
> 
>          DynamicPcdType =
> [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_DEFAULT],
> @@ -1424,9 +1446,19 @@ class DscBuildData(PlatformBuildClassObject):
>              SkuName = TAB_DEFAULT if SkuName == TAB_COMMON else
> SkuName
>              if SkuName not in SkuIds:
>                  continue
> +            TCName,PCName,DimensionAttr,Field =
> self.ParsePcdNameStruct(TokenSpaceGuid, PcdCName)
> +            pcd_in_dec = self._DecPcds.get((PCName,TCName), None)
> +            if pcd_in_dec is None:
> +                EdkLogger.error('build', PARSER_ERROR,
> +                            "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch:
> ['%s']" % (TCName, PCName, self._Arch),
> +                            File=self.MetaFile, Line = Dummy5)
> +            if SkuName in SkuIds and ("." in TokenSpaceGuid or "[" in PcdCName):
> +                if not isinstance (pcd_in_dec, StructurePcd):
> +                    EdkLogger.error('build', PARSER_ERROR,
> +                                "Pcd (%s.%s) is not declared as Structure PCD in DEC files.
> Arch: ['%s']" % (TCName, PCName, self._Arch),
> +                                File=self.MetaFile, Line = Dummy5)
> 
> -            if SkuName in SkuIds and "." in TokenSpaceGuid:
> -                S_PcdSet.append([ TokenSpaceGuid.split(".")[0],
> TokenSpaceGuid.split(".")[1], PcdCName, SkuName, default_store,
> Dummy5, AnalyzePcdExpression(Setting)[0]])
> +                S_PcdSet.append([ TCName,PCName,DimensionAttr,Field,
> SkuName, default_store, Dummy5, AnalyzePcdExpression(Setting)[0]])
> 
>          # handle pcd value override
>          StrPcdSet = DscBuildData.GetStructurePcdInfo(S_PcdSet)
> @@ -1434,27 +1466,19 @@ class DscBuildData(PlatformBuildClassObject):
>          for str_pcd in StrPcdSet:
>              str_pcd_obj = Pcds.get((str_pcd[1], str_pcd[0]), None)
>              str_pcd_dec = self._DecPcds.get((str_pcd[1], str_pcd[0]), None)
> -            if not isinstance (str_pcd_dec, StructurePcd):
> -                EdkLogger.error('build', PARSER_ERROR,
> -                            "Pcd (%s.%s) is not declared as Structure PCD in DEC files.
> Arch: ['%s']" % (str_pcd[0], str_pcd[1], self._Arch),
> -                            File=self.MetaFile, Line = StrPcdSet[str_pcd][0][5])
> -            if str_pcd_dec:
> -                str_pcd_obj_str = StructurePcd()
> -                str_pcd_obj_str.copy(str_pcd_dec)
> -                if str_pcd_obj:
> -                    str_pcd_obj_str.copy(str_pcd_obj)
> -                    if str_pcd_obj.Type in
> [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],
> self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
> -                        str_pcd_obj_str.DefaultFromDSC = {skuname:{defaultstore:
> str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.get(defaultstore,
> str_pcd_obj.SkuInfoList[skuname].HiiDefaultValue) for defaultstore in
> DefaultStores} for skuname in str_pcd_obj.SkuInfoList}
> -                    else:
> -                        str_pcd_obj_str.DefaultFromDSC = {skuname:{defaultstore:
> str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.get(defaultstore,
> str_pcd_obj.SkuInfoList[skuname].DefaultValue) for defaultstore in
> DefaultStores} for skuname in str_pcd_obj.SkuInfoList}
> -                for str_pcd_data in StrPcdSet[str_pcd]:
> -                    if str_pcd_data[3] in SkuIds:
> -                        str_pcd_obj_str.AddOverrideValue(str_pcd_data[2],
> str(str_pcd_data[6]), TAB_DEFAULT if str_pcd_data[3] == TAB_COMMON
> else str_pcd_data[3], TAB_DEFAULT_STORES_DEFAULT if str_pcd_data[4] ==
> TAB_COMMON else str_pcd_data[4], self.MetaFile.File if self.WorkspaceDir
> not in self.MetaFile.File else self.MetaFile.File[len(self.WorkspaceDir) if
> self.WorkspaceDir.endswith(os.path.sep) else len(self.WorkspaceDir)+1:],
> LineNo=str_pcd_data[5])
> -                S_pcd_set[str_pcd[1], str_pcd[0]] = str_pcd_obj_str
> -            else:
> -                EdkLogger.error('build', PARSER_ERROR,
> -                            "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch:
> ['%s']" % (str_pcd[0], str_pcd[1], self._Arch),
> -                            File=self.MetaFile, Line = StrPcdSet[str_pcd][0][5])
> +            str_pcd_obj_str = StructurePcd()
> +            str_pcd_obj_str.copy(str_pcd_dec)
> +            if str_pcd_obj:
> +                str_pcd_obj_str.copy(str_pcd_obj)
> +                if str_pcd_obj.Type in
> [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],
> self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
> +                    str_pcd_obj_str.DefaultFromDSC = {skuname:{defaultstore:
> str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.get(defaultstore,
> str_pcd_obj.SkuInfoList[skuname].HiiDefaultValue) for defaultstore in
> DefaultStores} for skuname in str_pcd_obj.SkuInfoList}
> +                else:
> +                    str_pcd_obj_str.DefaultFromDSC = {skuname:{defaultstore:
> str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.get(defaultstore,
> str_pcd_obj.SkuInfoList[skuname].DefaultValue) for defaultstore in
> DefaultStores} for skuname in str_pcd_obj.SkuInfoList}
> +            for str_pcd_data in StrPcdSet[str_pcd]:
> +                if str_pcd_data[4] in SkuIds:
> +                    str_pcd_obj_str.AddOverrideValue(str_pcd_data[3],
> str(str_pcd_data[7]), TAB_DEFAULT if str_pcd_data[4] == TAB_COMMON
> else str_pcd_data[4], TAB_DEFAULT_STORES_DEFAULT if str_pcd_data[5] ==
> TAB_COMMON else str_pcd_data[5], self.MetaFile.File if self.WorkspaceDir
> not in self.MetaFile.File else self.MetaFile.File[len(self.WorkspaceDir) if
> self.WorkspaceDir.endswith(os.path.sep) else len(self.WorkspaceDir)+1:],
> LineNo=str_pcd_data[6],DimensionAttr = str_pcd_data[2])
> +            S_pcd_set[str_pcd[1], str_pcd[0]] = str_pcd_obj_str
> +
>          # Add the Structure PCD that only defined in DEC, don't have override in
> DSC file
>          for Pcd in self.DecPcds:
>              if isinstance(self._DecPcds[Pcd], StructurePcd):
> @@ -1590,9 +1614,10 @@ class DscBuildData(PlatformBuildClassObject):
>              if SkuName not in AvailableSkuIdSet:
>                  EdkLogger.error('build ', PARAMETER_INVALID, 'Sku %s is not
> defined in [SkuIds] section' % SkuName,
>                                              File=self.MetaFile, Line=Dummy5)
> -            if "." not in TokenSpaceGuid:
> -                PcdSet.add((PcdCName, TokenSpaceGuid, SkuName, Dummy5))
> -            PcdDict[Arch, PcdCName, TokenSpaceGuid, SkuName] = Setting
> +            if SkuName in (self.SkuIdMgr.SystemSkuId, TAB_DEFAULT,
> TAB_COMMON):
> +                if "." not in TokenSpaceGuid and "[" not in PcdCName:
> +                    PcdSet.add((PcdCName, TokenSpaceGuid, SkuName, Dummy5))
> +                PcdDict[Arch, PcdCName, TokenSpaceGuid, SkuName] = Setting
> 
>          for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdSet:
>              Setting = PcdDict[self._Arch, PcdCName, TokenSpaceGuid, SkuName]
> @@ -1688,7 +1713,20 @@ class DscBuildData(PlatformBuildClassObject):
>      def GenerateSizeFunction(self, Pcd):
>          CApp = "// Default Value in Dec \n"
>          CApp = CApp + "void Cal_%s_%s_Size(UINT32 *Size){\n" %
> (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
> -        for FieldList in [Pcd.DefaultValues]:
> +        if Pcd.IsArray():
> +            if (len(Pcd.Capacity) == 1 and Pcd.Capacity[0] != '0') or
> (len(Pcd.Capacity) >1 and reduce(lambda x,y:int(x)*int(y), Pcd.Capacity)) > 0:
> +                CApp += "  *Size = (sizeof (%s) * (%s) > *Size) ? sizeof (%s) * (%s):
> *Size; \n" % (Pcd.BaseDatumType,
> "*".join(Pcd.Capacity),Pcd.BaseDatumType, "*".join(Pcd.Capacity))
> +            if "{CODE(" in Pcd.DefaultValueFromDec:
> +                CApp += "  *Size = (sizeof (%s_%s_INIT_Value) > *Size ? sizeof
> (%s_%s_INIT_Value) : *Size);\n" %
> (Pcd.TokenSpaceGuidCName,Pcd.TokenCName,Pcd.TokenSpaceGuidCName
> ,Pcd.TokenCName)
> +            for skuname in Pcd.SkuInfoList:
> +                skuobj = Pcd.SkuInfoList[skuname]
> +                if skuobj.VariableName:
> +                    for defaultstore in skuobj.DefaultStoreDict:
> +                        CApp += "  *Size = (sizeof (%s_%s_%s_%s_Value) > *Size ?
> sizeof (%s_%s_%s_%s_Value) : *Size);\n" %
> (Pcd.TokenSpaceGuidCName,Pcd.TokenCName,skuname,defaultstore,Pcd.T
> okenSpaceGuidCName,Pcd.TokenCName,skuname,defaultstore)
> +                else:
> +                    CApp += "  *Size = (sizeof (%s_%s_%s_%s_Value) > *Size ? sizeof
> (%s_%s_%s_%s_Value) : *Size);\n" %
> (Pcd.TokenSpaceGuidCName,Pcd.TokenCName,skuname,TAB_DEFAULT_ST
> ORES_DEFAULT,Pcd.TokenSpaceGuidCName,Pcd.TokenCName,skuname,TA
> B_DEFAULT_STORES_DEFAULT)
> +        for index in Pcd.DefaultValues:
> +            FieldList = Pcd.DefaultValues[index]
>              if not FieldList:
>                  continue
>              for FieldName in FieldList:
> @@ -1718,31 +1756,32 @@ class DscBuildData(PlatformBuildClassObject):
>                  continue
>              for defaultstorenameitem in Pcd.SkuOverrideValues[skuname]:
>                  CApp = CApp + "// SkuName: %s,  DefaultStoreName: %s \n" %
> (skuname, defaultstorenameitem)
> -                for FieldList in
> [Pcd.SkuOverrideValues[skuname].get(defaultstorenameitem)]:
> -                    if not FieldList:
> -                        continue
> -                    for FieldName in FieldList:
> -                        FieldName = "." + FieldName
> -                        IsArray = IsFieldValueAnArray(FieldList[FieldName.strip(".")][0])
> -                        if IsArray and not
> (FieldList[FieldName.strip(".")][0].startswith('{GUID') and
> FieldList[FieldName.strip(".")][0].endswith('}')):
> -                            try:
> -                                Value =
> ValueExpressionEx(FieldList[FieldName.strip(".")][0], TAB_VOID,
> self._GuidDict)(True)
> -                            except BadExpression:
> -                                EdkLogger.error('Build', FORMAT_INVALID, "Invalid value
> format for %s. From %s Line %d " %
> -                                                (".".join((Pcd.TokenSpaceGuidCName,
> Pcd.TokenCName, FieldName.strip('.'))), FieldList[FieldName.strip(".")][1],
> FieldList[FieldName.strip(".")][2]))
> -                            Value, ValueSize = ParseFieldValue(Value)
> -                            CApp = CApp + '  __FLEXIBLE_SIZE(*Size, %s, %s, %d /
> __ARRAY_ELEMENT_SIZE(%s, %s) + ((%d %% __ARRAY_ELEMENT_SIZE(%s,
> %s)) ? 1 : 0)); // From %s Line %d Value %s\n' % (Pcd.DatumType,
> FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."),
> ValueSize, Pcd.DatumType, FieldName.strip("."),
> FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2],
> FieldList[FieldName.strip(".")][0]);
> -                        else:
> -                            NewFieldName = ''
> -                            FieldName_ori = FieldName.strip('.')
> -                            while '[' in  FieldName:
> -                                NewFieldName = NewFieldName + FieldName.split('[', 1)[0]
> + '[0]'
> -                                ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])
> -                                FieldName = FieldName.split(']', 1)[1]
> -                            FieldName = NewFieldName + FieldName
> -                            while '[' in FieldName:
> -                                FieldName = FieldName.rsplit('[', 1)[0]
> -                                CApp = CApp + '  __FLEXIBLE_SIZE(*Size, %s, %s, %d); //
> From %s Line %d Value %s \n' % (Pcd.DatumType, FieldName.strip("."),
> ArrayIndex + 1, FieldList[FieldName_ori][1], FieldList[FieldName_ori][2],
> FieldList[FieldName_ori][0])
> +                for index in
> Pcd.SkuOverrideValues[skuname][defaultstorenameitem]:
> +                    for FieldList in
> [Pcd.SkuOverrideValues[skuname][defaultstorenameitem][index]]:
> +                        if not FieldList:
> +                            continue
> +                        for FieldName in FieldList:
> +                            FieldName = "." + FieldName
> +                            IsArray =
> IsFieldValueAnArray(FieldList[FieldName.strip(".")][0])
> +                            if IsArray and not
> (FieldList[FieldName.strip(".")][0].startswith('{GUID') and
> FieldList[FieldName.strip(".")][0].endswith('}')):
> +                                try:
> +                                    Value =
> ValueExpressionEx(FieldList[FieldName.strip(".")][0], TAB_VOID,
> self._GuidDict)(True)
> +                                except BadExpression:
> +                                    EdkLogger.error('Build', FORMAT_INVALID, "Invalid value
> format for %s. From %s Line %d " %
> +                                                    (".".join((Pcd.TokenSpaceGuidCName,
> Pcd.TokenCName, FieldName.strip('.'))), FieldList[FieldName.strip(".")][1],
> FieldList[FieldName.strip(".")][2]))
> +                                Value, ValueSize = ParseFieldValue(Value)
> +                                CApp = CApp + '  __FLEXIBLE_SIZE(*Size, %s, %s, %d /
> __ARRAY_ELEMENT_SIZE(%s, %s) + ((%d %% __ARRAY_ELEMENT_SIZE(%s,
> %s)) ? 1 : 0)); // From %s Line %d Value %s\n' % (Pcd.DatumType,
> FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."),
> ValueSize, Pcd.DatumType, FieldName.strip("."),
> FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2],
> FieldList[FieldName.strip(".")][0]);
> +                            else:
> +                                NewFieldName = ''
> +                                FieldName_ori = FieldName.strip('.')
> +                                while '[' in  FieldName:
> +                                    NewFieldName = NewFieldName + FieldName.split('[',
> 1)[0] + '[0]'
> +                                    ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])
> +                                    FieldName = FieldName.split(']', 1)[1]
> +                                FieldName = NewFieldName + FieldName
> +                                while '[' in FieldName:
> +                                    FieldName = FieldName.rsplit('[', 1)[0]
> +                                    CApp = CApp + '  __FLEXIBLE_SIZE(*Size, %s, %s, %d); //
> From %s Line %d Value %s \n' % (Pcd.DatumType, FieldName.strip("."),
> ArrayIndex + 1, FieldList[FieldName_ori][1], FieldList[FieldName_ori][2],
> FieldList[FieldName_ori][0])
>          if Pcd.PcdFieldValueFromFdf:
>              CApp = CApp + "// From fdf \n"
>          for FieldName in Pcd.PcdFieldValueFromFdf:
> @@ -1791,19 +1830,64 @@ class DscBuildData(PlatformBuildClassObject):
>                  while '[' in FieldName:
>                      FieldName = FieldName.rsplit('[', 1)[0]
>                      CApp = CApp + '  __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s
> Line %d Value %s \n' % (Pcd.DatumType, FieldName.strip("."), ArrayIndex +
> 1, Pcd.PcdFieldValueFromComm[FieldName_ori][1],
> Pcd.PcdFieldValueFromComm[FieldName_ori][2],
> Pcd.PcdFieldValueFromComm[FieldName_ori][0])
> -        CApp = CApp + "  *Size = (%d > *Size ? %d : *Size); // The Pcd maxsize is
> %d \n" % (Pcd.GetPcdMaxSize(), Pcd.GetPcdMaxSize(),
> Pcd.GetPcdMaxSize())
> +        if Pcd.GetPcdMaxSize():
> +            CApp = CApp + "  *Size = (%d > *Size ? %d : *Size); // The Pcd maxsize
> is %d \n" % (Pcd.GetPcdMaxSize(), Pcd.GetPcdMaxSize(),
> Pcd.GetPcdMaxSize())
>          CApp = CApp + "}\n"
>          return CApp
> 
>      @staticmethod
>      def GenerateSizeStatments(Pcd):
> -        CApp = '  Size = sizeof(%s);\n' % (Pcd.DatumType)
> +        if Pcd.IsArray():
> +            r_datatype = [Pcd.BaseDatumType]
> +            for dem in Pcd.Capacity:
> +                if dem == '0':
> +                    r_datatype.append("[1]")
> +                else:
> +                    r_datatype.append("[" + dem + "]")
> +            CApp = '  Size = sizeof(%s);\n' % ("".join(r_datatype))
> +        else:
> +            CApp = '  Size = sizeof(%s);\n' % (Pcd.DatumType)
>          CApp = CApp + '  Cal_%s_%s_Size(&Size);\n' %
> (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
>          return CApp
> 
> +    def GetIndicator(self,index,FieldName,Pcd):
> +        def cleanupindex(indexstr):
> +            return indexstr.strip("[").strip("]").strip()
> +        index_elements = ArrayIndex.findall(index)
> +        pcd_capacity = Pcd.Capacity
> +        if index:
> +            indicator = "(Pcd"
> +            if len(pcd_capacity)>2:
> +                for i in xrange(0,len(index_elements)):
> +                    index_ele = index_elements[i]
> +                    index_num = index_ele.strip("[").strip("]").strip()
> +                    if i == len(index_elements) -2:
> +                        indicator += "+ %d*Size/sizeof(%s)/%d + %s)"
> %(int(cleanupindex(index_elements[i+1])),Pcd.BaseDatumType,reduce(lam
> bda x,y: int(x)*int(y),pcd_capacity[:-1]), cleanupindex(index_elements[i]))
> +                        break
> +                    else:
> +                        indicator += " + %d*%s*Size/sizeof(%s)/%d"
> %(int(cleanupindex(index_elements[i])),reduce(lambda x,y:
> int(x)*int(y),pcd_capacity[i+1:-1]),Pcd.BaseDatumType,reduce(lambda x,y:
> int(x)*int(y),pcd_capacity[:-1]))
> +            elif len(pcd_capacity) == 2:
> +                indicator += "+ %d*Size/sizeof(%s)/%d + %s)"
> %(int(cleanupindex(index_elements[0])),Pcd.BaseDatumType,int(pcd_capac
> ity[0]), index_elements[1].strip("[").strip("]").strip())
> +            elif len(pcd_capacity) == 1:
> +                index_ele = index_elements[0]
> +                index_num = index_ele.strip("[").strip("]").strip()
> +                indicator += " + %s)" % (index_num)
> +        else:
> +            indicator = "Pcd"
> +        if FieldName:
> +            indicator += "->" + FieldName
> +        return indicator
> +
> +    def GetStarNum(self,Pcd):
> +        if not Pcd.IsArray():
> +            return 1
> +        elif Pcd.IsSimpleTypeArray():
> +            return len(Pcd.Capacity)
> +        else:
> +            return len(Pcd.Capacity) + 1
>      def GenerateDefaultValueAssignFunction(self, Pcd):
>          CApp = "// Default value in Dec \n"
> -        CApp = CApp + "void Assign_%s_%s_Default_Value(%s *Pcd){\n" %
> (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.DatumType)
> +        CApp = CApp + "void Assign_%s_%s_Default_Value(%s *Pcd){\n" %
> (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.BaseDatumType)
>          CApp = CApp + '  UINT32  FieldSize;\n'
>          CApp = CApp + '  CHAR8   *Value;\n'
>          DefaultValueFromDec = Pcd.DefaultValueFromDec
> @@ -1822,9 +1906,13 @@ class DscBuildData(PlatformBuildClassObject):
>          #
>          # Use memcpy() to copy value into field
>          #
> -            CApp = CApp + '  Value     = %s; // From DEC Default Value %s\n' %
> (DscBuildData.IntToCString(Value, ValueSize), Pcd.DefaultValueFromDec)
> -            CApp = CApp + '  memcpy (Pcd, Value, %d);\n' % (ValueSize)
> -        for FieldList in [Pcd.DefaultValues]:
> +            if "{CODE(" in Pcd.DefaultValueFromDec:
> +                CApp = CApp + '  memcpy (Pcd, %s_%s_INIT_Value,
> sizeof(%s_%s_INIT_Value));\n' % (Pcd.TokenSpaceGuidCName,
> Pcd.TokenCName,Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
> +            else:
> +                CApp = CApp + '  Value     = %s; // From DEC Default Value %s\n' %
> (DscBuildData.IntToCString(Value, ValueSize), Pcd.DefaultValueFromDec)
> +                CApp = CApp + '  memcpy (Pcd, Value, %d);\n' % (ValueSize)
> +        for index in Pcd.DefaultValues:
> +            FieldList = Pcd.DefaultValues[index]
>              if not FieldList:
>                  continue
>              for FieldName in FieldList:
> @@ -1840,8 +1928,10 @@ class DscBuildData(PlatformBuildClassObject):
>                      Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])
>                  except Exception:
>                      EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format
> for %s. From %s Line %d " % (".".join((Pcd.TokenSpaceGuidCName,
> Pcd.TokenCName, FieldName)), FieldList[FieldName][1],
> FieldList[FieldName][2]))
> +
> +                indicator = self.GetIndicator(index, FieldName,Pcd)
>                  if isinstance(Value, str):
> -                    CApp = CApp + '  Pcd->%s = %s; // From %s Line %d Value %s\n' %
> (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2],
> FieldList[FieldName][0])
> +                    CApp = CApp + '  %s = %s; // From %s Line %d Value %s\n' %
> (indicator, Value, FieldList[FieldName][1], FieldList[FieldName][2],
> FieldList[FieldName][0])
>                  elif IsArray:
>                      #
>                      # Use memcpy() to copy value into field
> @@ -1850,14 +1940,16 @@ class DscBuildData(PlatformBuildClassObject):
>                      CApp = CApp + '  Value     = %s; // From %s Line %d Value %s\n' %
> (DscBuildData.IntToCString(Value, ValueSize), FieldList[FieldName][1],
> FieldList[FieldName][2], FieldList[FieldName][0])
>                      CApp = CApp + '  __STATIC_ASSERT((__FIELD_SIZE(%s, %s) >= %d)
> || (__FIELD_SIZE(%s, %s) == 0), "Input buffer exceeds the buffer array"); //
> From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName, ValueSize,
> Pcd.DatumType, FieldName, FieldList[FieldName][1],
> FieldList[FieldName][2], FieldList[FieldName][0])
>                      CApp = CApp + '  memcpy (&Pcd->%s, Value, (FieldSize > 0 &&
> FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)
> +                    CApp = CApp + '  memcpy (&%s, Value, (FieldSize > 0 && FieldSize
> < %d) ? FieldSize : %d);\n' % (indicator, ValueSize, ValueSize)
> +
>                  else:
>                      if '[' in FieldName and ']' in FieldName:
>                          Index = int(FieldName.split('[')[1].split(']')[0])
>                          CApp = CApp + '  __STATIC_ASSERT((%d < __ARRAY_SIZE(Pcd-
> >%s)) || (__ARRAY_SIZE(Pcd->%s) == 0), "array index exceeds the array
> number"); // From %s Line %d Index of %s\n' % (Index,
> FieldName.split('[')[0], FieldName.split('[')[0], FieldList[FieldName][1],
> FieldList[FieldName][2], FieldName)
>                      if ValueSize > 4:
> -                        CApp = CApp + '  Pcd->%s = %dULL; // From %s Line %d Value
> %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2],
> FieldList[FieldName][0])
> +                        CApp = CApp + '  %s = %dULL; // From %s Line %d Value %s\n' %
> (indicator, Value, FieldList[FieldName][1], FieldList[FieldName][2],
> FieldList[FieldName][0])
>                      else:
> -                        CApp = CApp + '  Pcd->%s = %d; // From %s Line %d Value %s\n'
> % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2],
> FieldList[FieldName][0])
> +                        CApp = CApp + '  %s = %d; // From %s Line %d Value %s\n' %
> (indicator, Value, FieldList[FieldName][1], FieldList[FieldName][2],
> FieldList[FieldName][0])
>          CApp = CApp + "}\n"
>          return CApp
> 
> @@ -1868,7 +1960,7 @@ class DscBuildData(PlatformBuildClassObject):
> 
>      def GenerateInitValueFunction(self, Pcd, SkuName, DefaultStoreName):
>          CApp = "// Value in Dsc for Sku: %s, DefaultStore %s\n" % (SkuName,
> DefaultStoreName)
> -        CApp = CApp + "void Assign_%s_%s_%s_%s_Value(%s *Pcd){\n" %
> (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, SkuName,
> DefaultStoreName, Pcd.DatumType)
> +        CApp = CApp + "void Assign_%s_%s_%s_%s_Value(%s *Pcd){\n" %
> (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, SkuName,
> DefaultStoreName, Pcd.BaseDatumType)
>          CApp = CApp + '  UINT32  FieldSize;\n'
>          CApp = CApp + '  CHAR8   *Value;\n'
> 
> @@ -1881,40 +1973,60 @@ class DscBuildData(PlatformBuildClassObject):
>                  pcddefaultvalue = Pcd.DscRawValue.get(SkuName,
> {}).get(DefaultStoreName)
>          else:
>              pcddefaultvalue = Pcd.DscRawValue.get(SkuName,
> {}).get(TAB_DEFAULT_STORES_DEFAULT)
> -        for FieldList in [pcddefaultvalue,
> inherit_OverrideValues.get(DefaultStoreName)]:
> -            if not FieldList:
> -                continue
> -            if pcddefaultvalue and FieldList == pcddefaultvalue:
> -                IsArray = IsFieldValueAnArray(FieldList)
> -                if IsArray:
> +
> +        if pcddefaultvalue:
> +            FieldList = pcddefaultvalue
> +            IsArray = IsFieldValueAnArray(FieldList)
> +            if IsArray:
> +                if "{CODE(" not in FieldList:
>                      try:
>                          FieldList = ValueExpressionEx(FieldList, TAB_VOID)(True)
>                      except BadExpression:
>                          EdkLogger.error("Build", FORMAT_INVALID, "Invalid value
> format for %s.%s, from DSC: %s" %
>                                          (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,
> FieldList))
> -                Value, ValueSize = ParseFieldValue (FieldList)
> +            Value, ValueSize = ParseFieldValue (FieldList)
> 
> -                if (SkuName, DefaultStoreName) == (TAB_DEFAULT,
> TAB_DEFAULT_STORES_DEFAULT):
> -                    if isinstance(Value, str):
> +            if (SkuName, DefaultStoreName) == (TAB_DEFAULT,
> TAB_DEFAULT_STORES_DEFAULT):
> +                if isinstance(Value, str):
> +                    if "{CODE(" in Value:
> +                        CApp = CApp + '  memcpy (Pcd, %s_%s_%s_%s_Value,
> sizeof(%s_%s_%s_%s_Value));\n' % (Pcd.TokenSpaceGuidCName,
> Pcd.TokenCName,SkuName,
> DefaultStoreName,Pcd.TokenSpaceGuidCName,
> Pcd.TokenCName,SkuName, DefaultStoreName)
> +                    else:
>                          CApp = CApp + '  Pcd = %s; // From DSC Default Value %s\n' %
> (Value, Pcd.DefaultFromDSC.get(TAB_DEFAULT,
> {}).get(TAB_DEFAULT_STORES_DEFAULT, Pcd.DefaultValue) if
> Pcd.DefaultFromDSC else Pcd.DefaultValue)
> -                    elif IsArray:
> -                    #
> -                    # Use memcpy() to copy value into field
> -                    #
> +                elif IsArray:
> +                #
> +                # Use memcpy() to copy value into field
> +                #
> +                    if Pcd.IsArray():
> +                        CApp = CApp + '  memcpy (Pcd, %s_%s_%s_%s_Value,
> sizeof(%s_%s_%s_%s_Value));\n' % (Pcd.TokenSpaceGuidCName,
> Pcd.TokenCName,SkuName,
> DefaultStoreName,Pcd.TokenSpaceGuidCName,
> Pcd.TokenCName,SkuName, DefaultStoreName)
> +                    else:
>                          CApp = CApp + '  Value     = %s; // From DSC Default Value %s\n'
> % (DscBuildData.IntToCString(Value, ValueSize),
> Pcd.DefaultFromDSC.get(TAB_DEFAULT,
> {}).get(TAB_DEFAULT_STORES_DEFAULT, Pcd.DefaultValue) if
> Pcd.DefaultFromDSC else Pcd.DefaultValue)
>                          CApp = CApp + '  memcpy (Pcd, Value, %d);\n' % (ValueSize)
> -                else:
> -                    if isinstance(Value, str):
> +            else:
> +                if isinstance(Value, str):
> +                    if "{CODE(" in Value:
> +                        CApp = CApp + '  memcpy (Pcd, %s_%s_%s_%s_Value,
> sizeof(%s_%s_%s_%s_Value));\n' % (Pcd.TokenSpaceGuidCName,
> Pcd.TokenCName,SkuName,
> DefaultStoreName,Pcd.TokenSpaceGuidCName,
> Pcd.TokenCName,SkuName, DefaultStoreName)
> +                    else:
>                          CApp = CApp + '  Pcd = %s; // From DSC Default Value %s\n' %
> (Value, Pcd.DscRawValue.get(SkuName, {}).get(DefaultStoreName))
> -                    elif IsArray:
> -                    #
> -                    # Use memcpy() to copy value into field
> -                    #
> +                elif IsArray:
> +                #
> +                # Use memcpy() to copy value into field
> +                #
> +                    if Pcd.IsArray():
> +                        CApp = CApp + '  memcpy (Pcd, %s_%s_%s_%s_Value,
> sizeof(%s_%s_%s_%s_Value));\n' % (Pcd.TokenSpaceGuidCName,
> Pcd.TokenCName,SkuName,
> DefaultStoreName,Pcd.TokenSpaceGuidCName,
> Pcd.TokenCName,SkuName, DefaultStoreName)
> +                    else:
>                          CApp = CApp + '  Value     = %s; // From DSC Default Value %s\n'
> % (DscBuildData.IntToCString(Value, ValueSize),
> Pcd.DscRawValue.get(SkuName, {}).get(DefaultStoreName))
>                          CApp = CApp + '  memcpy (Pcd, Value, %d);\n' % (ValueSize)
> +
> +        inheritvalue = inherit_OverrideValues.get(DefaultStoreName)
> +        if not inheritvalue:
> +            inheritvalue = []
> +        for index in inheritvalue:
> +            FieldList = inheritvalue[index]
> +            if not FieldList:
>                  continue
>              if (SkuName, DefaultStoreName) == (TAB_DEFAULT,
> TAB_DEFAULT_STORES_DEFAULT) or (( (SkuName, '') not in Pcd.ValueChain)
> and ( (SkuName, DefaultStoreName) not in Pcd.ValueChain )):
>                  for FieldName in FieldList:
> +                    indicator = self.GetIndicator(index, FieldName,Pcd)
>                      IsArray = IsFieldValueAnArray(FieldList[FieldName][0])
>                      if IsArray:
>                          try:
> @@ -1932,18 +2044,19 @@ class DscBuildData(PlatformBuildClassObject):
>                      #
>                      # Use memcpy() to copy value into field
>                      #
> -                        CApp = CApp + '  FieldSize = __FIELD_SIZE(%s, %s);\n' %
> (Pcd.DatumType, FieldName)
> +                        CApp = CApp + '  FieldSize = __FIELD_SIZE(%s, %s);\n' %
> (Pcd.BaseDatumType, FieldName)
>                          CApp = CApp + '  Value     = %s; // From %s Line %d Value %s\n' %
> (DscBuildData.IntToCString(Value, ValueSize), FieldList[FieldName][1],
> FieldList[FieldName][2], FieldList[FieldName][0])
>                          CApp = CApp + '  __STATIC_ASSERT((__FIELD_SIZE(%s, %s) >=
> %d) || (__FIELD_SIZE(%s, %s) == 0), "Input buffer exceeds the buffer
> array"); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName,
> ValueSize, Pcd.DatumType, FieldName, FieldList[FieldName][1],
> FieldList[FieldName][2], FieldList[FieldName][0])
>                          CApp = CApp + '  memcpy (&Pcd->%s, Value, (FieldSize > 0 &&
> FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)
> +                        CApp = CApp + '  memcpy (&%s, Value, (FieldSize > 0 &&
> FieldSize < %d) ? FieldSize : %d);\n' % (indicator, ValueSize, ValueSize)
>                      else:
>                          if '[' in FieldName and ']' in FieldName:
>                              Index = int(FieldName.split('[')[1].split(']')[0])
>                              CApp = CApp + '  __STATIC_ASSERT((%d < __ARRAY_SIZE(Pcd-
> >%s)) || (__ARRAY_SIZE(Pcd->%s) == 0), "array index exceeds the array
> number"); // From %s Line %d Index of %s\n' % (Index,
> FieldName.split('[')[0], FieldName.split('[')[0], FieldList[FieldName][1],
> FieldList[FieldName][2], FieldName)
>                          if ValueSize > 4:
> -                            CApp = CApp + '  Pcd->%s = %dULL; // From %s Line %d Value
> %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2],
> FieldList[FieldName][0])
> +                            CApp = CApp + '  %s = %dULL; // From %s Line %d Value %s\n'
> % (indicator, Value, FieldList[FieldName][1], FieldList[FieldName][2],
> FieldList[FieldName][0])
>                          else:
> -                            CApp = CApp + '  Pcd->%s = %d; // From %s Line %d Value
> %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2],
> FieldList[FieldName][0])
> +                            CApp = CApp + '  %s = %d; // From %s Line %d Value %s\n' %
> (indicator, Value, FieldList[FieldName][1], FieldList[FieldName][2],
> FieldList[FieldName][0])
>          CApp = CApp + "}\n"
>          return CApp
> 
> @@ -1954,7 +2067,7 @@ class DscBuildData(PlatformBuildClassObject):
> 
>      def GenerateCommandLineValue(self, Pcd):
>          CApp = "// Value in CommandLine\n"
> -        CApp = CApp + "void Assign_%s_%s_CommandLine_Value(%s
> *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,
> Pcd.DatumType)
> +        CApp = CApp + "void Assign_%s_%s_CommandLine_Value(%s
> *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,
> Pcd.BaseDatumType)
>          CApp = CApp + '  UINT32  FieldSize;\n'
>          CApp = CApp + '  CHAR8   *Value;\n'
> 
> @@ -2001,7 +2114,7 @@ class DscBuildData(PlatformBuildClassObject):
>                  #
>                  # Use memcpy() to copy value into field
>                  #
> -                    CApp = CApp + '  FieldSize = __FIELD_SIZE(%s, %s);\n' %
> (Pcd.DatumType, FieldName)
> +                    CApp = CApp + '  FieldSize = __FIELD_SIZE(%s, %s);\n' %
> (Pcd.BaseDatumType, FieldName)
>                      CApp = CApp + '  Value     = %s; // From %s Line %d Value %s\n' %
> (DscBuildData.IntToCString(Value, ValueSize), FieldList[FieldName][1],
> FieldList[FieldName][2], FieldList[FieldName][0])
>                      CApp = CApp + '  __STATIC_ASSERT((__FIELD_SIZE(%s, %s) >= %d)
> || (__FIELD_SIZE(%s, %s) == 0), "Input buffer exceeds the buffer array"); //
> From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName, ValueSize,
> Pcd.DatumType, FieldName, FieldList[FieldName][1],
> FieldList[FieldName][2], FieldList[FieldName][0])
>                      CApp = CApp + '  memcpy (&Pcd->%s, Value, (FieldSize > 0 &&
> FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)
> @@ -2022,7 +2135,7 @@ class DscBuildData(PlatformBuildClassObject):
>          return CApp
>      def GenerateFdfValue(self,Pcd):
>          CApp = "// Value in Fdf\n"
> -        CApp = CApp + "void Assign_%s_%s_Fdf_Value(%s *Pcd){\n" %
> (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType)
> +        CApp = CApp + "void Assign_%s_%s_Fdf_Value(%s *Pcd){\n" %
> (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.BaseDatumType)
>          CApp = CApp + '  UINT32  FieldSize;\n'
>          CApp = CApp + '  CHAR8   *Value;\n'
> 
> @@ -2069,7 +2182,7 @@ class DscBuildData(PlatformBuildClassObject):
>                  #
>                  # Use memcpy() to copy value into field
>                  #
> -                    CApp = CApp + '  FieldSize = __FIELD_SIZE(%s, %s);\n' %
> (Pcd.DatumType, FieldName)
> +                    CApp = CApp + '  FieldSize = __FIELD_SIZE(%s, %s);\n' %
> (Pcd.BaseDatumType, FieldName)
>                      CApp = CApp + '  Value     = %s; // From %s Line %d Value %s\n' %
> (DscBuildData.IntToCString(Value, ValueSize), FieldList[FieldName][1],
> FieldList[FieldName][2], FieldList[FieldName][0])
>                      CApp = CApp + '  __STATIC_ASSERT((__FIELD_SIZE(%s, %s) >= %d)
> || (__FIELD_SIZE(%s, %s) == 0), "Input buffer exceeds the buffer array"); //
> From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName, ValueSize,
> Pcd.DatumType, FieldName, FieldList[FieldName][1],
> FieldList[FieldName][2], FieldList[FieldName][0])
>                      CApp = CApp + '  memcpy (&Pcd->%s, Value, (FieldSize > 0 &&
> FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)
> @@ -2090,7 +2203,7 @@ class DscBuildData(PlatformBuildClassObject):
>          return CApp
> 
>      def GenerateInitializeFunc(self, SkuName, DefaultStore, Pcd,
> InitByteValue, CApp):
> -        OverrideValues = {DefaultStore:""}
> +        OverrideValues = {DefaultStore:{}}
>          if Pcd.SkuOverrideValues:
>              OverrideValues = Pcd.SkuOverrideValues[SkuName]
>          if not OverrideValues:
> @@ -2106,16 +2219,14 @@ class DscBuildData(PlatformBuildClassObject):
>              CApp = CApp + '  CHAR8   *Value;\n'
>              CApp = CApp + '  UINT32  OriginalSize;\n'
>              CApp = CApp + '  VOID    *OriginalPcd;\n'
> -            CApp = CApp + '  %s      *Pcd;  // From %s Line %d \n' %
> (Pcd.DatumType, Pcd.PkgPath, Pcd.PcdDefineLineNo)
> +
> +            CApp = CApp + '  %s      *Pcd;  // From %s Line %d \n' %
> (Pcd.BaseDatumType,Pcd.PkgPath, Pcd.PcdDefineLineNo)
> +
>              CApp = CApp + '\n'
> 
> -            if SkuName in Pcd.SkuInfoList:
> -                DefaultValue =
> Pcd.SkuInfoList[SkuName].DefaultStoreDict.get(DefaultStoreName,
> Pcd.SkuInfoList[SkuName].HiiDefaultValue if
> Pcd.SkuInfoList[SkuName].HiiDefaultValue  else
> Pcd.SkuInfoList[SkuName].DefaultValue)
> -            else:
> -                DefaultValue = Pcd.DefaultValue
> -            PcdDefaultValue = StringToArray(DefaultValue.strip())
> +            PcdDefaultValue = StringToArray(Pcd.DefaultValueFromDec.strip())
> 
> -            InitByteValue += '%s.%s.%s.%s|%s|%s\n' % (SkuName,
> DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName,
> Pcd.DatumType, PcdDefaultValue)
> +            InitByteValue += '%s.%s.%s.%s|%s|%s\n' % (SkuName,
> DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName,
> Pcd.BaseDatumType, PcdDefaultValue)
> 
>              #
>              # Get current PCD value and size
> @@ -2138,7 +2249,7 @@ class DscBuildData(PlatformBuildClassObject):
>              # Always keep that larger one as the current size
>              #
>              CApp = CApp + '  Size = (OriginalSize > Size ? OriginalSize : Size);\n'
> -            CApp = CApp + '  Pcd     = (%s *)malloc (Size);\n' % (Pcd.DatumType)
> +            CApp = CApp + '  Pcd     = (%s *)malloc (Size);\n' %
> (Pcd.BaseDatumType,)
>              CApp = CApp + '  memset (Pcd, 0, Size);\n'
> 
>              #
> @@ -2167,7 +2278,7 @@ class DscBuildData(PlatformBuildClassObject):
>              #
>              # Set new PCD value and size
>              #
> -            CApp = CApp + '  PcdSetPtr (%s, %s, %s, %s, Size, (UINT8 *)Pcd);\n' %
> (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName,
> Pcd.TokenCName)
> +            CApp = CApp + '  PcdSetPtr (%s, %s, %s, %s, Size, (void *)Pcd);\n' %
> (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName,
> Pcd.TokenCName)
> 
>              #
>              # Free PCD
> @@ -2176,6 +2287,39 @@ class DscBuildData(PlatformBuildClassObject):
>              CApp = CApp + '}\n'
>              CApp = CApp + '\n'
>          return InitByteValue, CApp
> +
> +    def GenerateArrayAssignment(self, Pcd):
> +        CApp = ""
> +        if not Pcd:
> +            return CApp
> +        if not Pcd.IsArray():
> +            return CApp
> +        Demesion = ""
> +        for d in Pcd.Capacity:
> +            if d == "0":
> +                Demesion += "[]"
> +            else:
> +                Demesion += "["+d+"]"
> +
> +        Value = Pcd.DefaultValueFromDec
> +        if "{CODE(" in Pcd.DefaultValueFromDec:
> +            realvalue = Pcd.DefaultValueFromDec.strip()[6:-2] #
> "{CODE(").rstrip(")}"
> +            CApp += "static %s %s_%s_INIT_Value%s = %s;\n" %
> (Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName,Pcd.TokenCName,Demes
> ion,realvalue)
> +
> +        for skuname in Pcd.SkuInfoList:
> +            skuinfo = Pcd.SkuInfoList[skuname]
> +            if skuinfo.VariableName:
> +                for defaultstore in skuinfo.DefaultStoreDict:
> +                    Value = skuinfo[defaultstore]
> +                    if "{CODE(" in Value:
> +                        realvalue = Value.strip()[6:-2] # "{CODE(").rstrip(")}"
> +                        CApp += "static %s %s_%s_%s_%s_Value%s = %s;\n" %
> (Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName,Pcd.TokenCName,skuna
> me,defaultstore,Demesion,realvalue)
> +            else:
> +                Value = skuinfo.DefaultValue
> +                if "{CODE(" in Value:
> +                    realvalue = Value.strip()[6:-2] # "{CODE(").rstrip(")}"
> +                    CApp += "static %s %s_%s_%s_%s_Value%s = %s;\n" %
> (Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName,Pcd.TokenCName,skuna
> me,TAB_DEFAULT_STORES_DEFAULT,Demesion,realvalue)
> +        return CApp
>      def SkuOverrideValuesEmpty(self,OverrideValues):
>          if not OverrideValues:
>              return True
> @@ -2215,6 +2359,8 @@ class DscBuildData(PlatformBuildClassObject):
>                      IncludeFiles.add(IncludeFile)
>                      CApp = CApp + '#include <%s>\n' % (IncludeFile)
>          CApp = CApp + '\n'
> +        for Pcd in StructuredPcds.values():
> +            CApp = CApp + self.GenerateArrayAssignment(Pcd)
>          for PcdName in StructuredPcds:
>              Pcd = StructuredPcds[PcdName]
>              CApp = CApp + self.GenerateSizeFunction(Pcd)
> @@ -2395,6 +2541,8 @@ class DscBuildData(PlatformBuildClassObject):
>                          FileLine = FileInfo [1].split (')')[0]
>                      else:
>                          FileInfo = Message.strip().split(':')
> +                        if len(FileInfo) < 2:
> +                            continue
>                          FileName = FileInfo [0]
>                          FileLine = FileInfo [1]
>                      if FileLine.isdigit():
> @@ -2478,7 +2626,7 @@ class DscBuildData(PlatformBuildClassObject):
>              if SkuName not in AvailableSkuIdSet:
>                  EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not
> defined in [SkuIds] section' % SkuName,
>                                              File=self.MetaFile, Line=Dummy5)
> -            if "." not in TokenSpaceGuid:
> +            if "." not in TokenSpaceGuid and "[" not in PcdCName:
>                  PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy5))
>              PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting
> 
> @@ -2651,7 +2799,7 @@ class DscBuildData(PlatformBuildClassObject):
>              if DefaultStore not in DefaultStoresDefine:
>                  EdkLogger.error('build', PARAMETER_INVALID, 'DefaultStores %s is
> not defined in [DefaultStores] section' % DefaultStore,
>                                              File=self.MetaFile, Line=Dummy5)
> -            if "." not in TokenSpaceGuid:
> +            if "." not in TokenSpaceGuid and "[" not in PcdCName:
>                  PcdSet.add((PcdCName, TokenSpaceGuid, SkuName, DefaultStore,
> Dummy5))
>              PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid, DefaultStore] =
> Setting
> 
> @@ -2814,7 +2962,7 @@ class DscBuildData(PlatformBuildClassObject):
>              if SkuName not in AvailableSkuIdSet:
>                  EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not
> defined in [SkuIds] section' % SkuName,
>                                              File=self.MetaFile, Line=Dummy5)
> -            if "." not in TokenSpaceGuid:
> +            if "." not in TokenSpaceGuid and "[" not in PcdCName:
>                  PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy5))
>              PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting
> 
> diff --git a/BaseTools/Source/Python/Workspace/MetaFileParser.py
> b/BaseTools/Source/Python/Workspace/MetaFileParser.py
> index 804a4aa5cb..6fde9e54f5 100644
> --- a/BaseTools/Source/Python/Workspace/MetaFileParser.py
> +++ b/BaseTools/Source/Python/Workspace/MetaFileParser.py
> @@ -40,6 +40,7 @@ from .MetaFileCommentParser import
> CheckInfComment
>  ## RegEx for finding file versions
>  hexVersionPattern = re.compile(r'0[xX][\da-f-A-F]{5,8}')
>  decVersionPattern = re.compile(r'\d+\.\d+')
> +CODEPattern = re.compile(r"{CODE\([a-fA-F0-9Xx\{\},\s]*\)}")
> 
>  ## A decorator used to parse macro definition
>  def ParseMacro(Parser):
> @@ -913,6 +914,10 @@ class DscParser(MetaFileParser):
>          #
>          self._IdMapping = {-1:-1}
> 
> +        self._PcdCodeValue = ""
> +        self._PcdDataTypeCODE = False
> +        self._CurrentPcdName = ""
> +
>      ## Parser starter
>      def Start(self):
>          Content = ''
> @@ -922,6 +927,9 @@ class DscParser(MetaFileParser):
>              EdkLogger.error("Parser", FILE_READ_FAILURE,
> ExtraData=self.MetaFile)
> 
>          OwnerId = {}
> +
> +        Content = self.ProcessMultipleLineCODEValue(Content)
> +
>          for Index in range(0, len(Content)):
>              Line = CleanString(Content[Index])
>              # skip empty line
> @@ -1133,6 +1141,41 @@ class DscParser(MetaFileParser):
>      def _LibraryInstanceParser(self):
>          self._ValueList[0] = self._CurrentLine
> 
> +    def ProcessMultipleLineCODEValue(self,Content):
> +        CODEBegin = False
> +        CODELine = ""
> +        continuelinecount = 0
> +        newContent = []
> +        for Index in range(0, len(Content)):
> +            Line = Content[Index]
> +            if CODEBegin:
> +                CODELine = CODELine + Line
> +                continuelinecount +=1
> +                if ")}" in Line:
> +                    newContent.append(CODELine)
> +                    for _ in range(continuelinecount):
> +                        newContent.append("")
> +                    CODEBegin = False
> +                    CODELine = ""
> +                    continuelinecount = 0
> +            else:
> +                if not Line:
> +                    newContent.append(Line)
> +                    continue
> +                if "{CODE(" not in Line:
> +                    newContent.append(Line)
> +                    continue
> +                elif CODEPattern.findall(Line):
> +                    newContent.append(Line)
> +                    continue
> +                else:
> +                    CODEBegin = True
> +                    CODELine = Line
> +
> +        return newContent
> +
> +    def _DecodeCODEData(self):
> +        pass
>      ## PCD sections parser
>      #
>      #   [PcdsFixedAtBuild]
> @@ -1149,7 +1192,28 @@ class DscParser(MetaFileParser):
>      #
>      @ParseMacro
>      def _PcdParser(self):
> +        if self._PcdDataTypeCODE:
> +            self._PcdCodeValue = self._PcdCodeValue + "\n " + self._CurrentLine
> +            if self._CurrentLine.endswith(")}"):
> +                self._CurrentLine = "|".join((self._CurrentPcdName,
> self._PcdCodeValue))
> +                self._PcdDataTypeCODE = False
> +                self._PcdCodeValue = ""
> +            else:
> +                self._ValueList = None
> +                return
>          TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT, 1)
> +        self._CurrentPcdName = TokenList[0]
> +        if TokenList[1].strip().startswith("{CODE"):
> +            self._PcdDataTypeCODE = True
> +            self._PcdCodeValue = TokenList[1].strip()
> +
> +        if self._PcdDataTypeCODE:
> +            if self._CurrentLine.endswith(")}"):
> +                self._PcdDataTypeCODE = False
> +                self._PcdCodeValue = ""
> +            else:
> +                self._ValueList = None
> +                return
>          self._ValueList[0:1] = GetSplitValueList(TokenList[0], TAB_SPLIT)
>          PcdNameTockens = GetSplitValueList(TokenList[0], TAB_SPLIT)
>          if len(PcdNameTockens) == 2:
> @@ -1907,6 +1971,17 @@ class DecParser(MetaFileParser):
>          if self._ValueList[0] not in self._GuidDict:
>              self._GuidDict[self._ValueList[0]] = self._ValueList[1]
> 
> +    def ParsePcdName(self,namelist):
> +        if "[" in namelist[1]:
> +            pcdname = namelist[1][:namelist[1].index("[")]
> +            arrayindex = namelist[1][namelist[1].index("["):]
> +            namelist[1] = pcdname
> +            if len(namelist) == 2:
> +                namelist.append(arrayindex)
> +            else:
> +                namelist[2] = ".".join((arrayindex,namelist[2]))
> +        return namelist
> +
>      ## PCD sections parser
>      #
>      #   [PcdsFixedAtBuild]
> @@ -1945,9 +2020,16 @@ class DecParser(MetaFileParser):
>                      return
>              else:
>                  PcdTockens = self._CurrentLine.split(TAB_VALUE_SPLIT)
> -                PcdNames = PcdTockens[0].split(TAB_SPLIT)
> +                PcdNames = self.ParsePcdName(PcdTockens[0].split(TAB_SPLIT))
>                  if len(PcdNames) == 2:
> -                    self._CurrentStructurePcdName = ""
> +                    if PcdNames[1].strip().endswith("]"):
> +                        PcdName = PcdNames[1][:PcdNames[1].index('[')]
> +                        Index = PcdNames[1][PcdNames[1].index('['):]
> +                        self._ValueList[0] = TAB_SPLIT.join((PcdNames[0],PcdName))
> +                        self._ValueList[1] = Index
> +                        self._ValueList[2] = PcdTockens[1]
> +                    else:
> +                        self._CurrentStructurePcdName = ""
>                  else:
>                      if self._CurrentStructurePcdName !=
> TAB_SPLIT.join(PcdNames[:2]):
>                          EdkLogger.error('Parser', FORMAT_INVALID, "Pcd Name does
> not match: %s and %s " % (self._CurrentStructurePcdName,
> TAB_SPLIT.join(PcdNames[:2])),
> --
> 2.19.1.windows.1
> 
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2018-11-09 15:24 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-11-07  9:18 [PATCH] BaseTools: Enable Pcd Array support BobCF
2018-11-09 15:24 ` Carsey, Jaben

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox