public CLRSigCustomAttributeNamedArg(CLRSignatureParser parser)
        {
            CLRSigType.ElementType baseType = (CLRSigType.ElementType)parser.ReadU8();

            if (baseType == CLRSigType.ElementType.Special_CustomAttribField)
                ArgKind = ArgKindEnum.Field;
            else if (baseType == CLRSigType.ElementType.Special_CustomAttribProperty)
                ArgKind = ArgKindEnum.Property;
            else
                throw new ParseFailedException("Unusual named arg type");

            CLRSigType argType = CLRSigCustomAttributeElem.ReadFieldOrPropType(parser);
            Name = CLRSigCustomAttributeElem.ReadUTF8String(parser);
            Arg = new CLRSigCustomAttributeFixedArg(parser, argType);
        }
        public static CLRSigType ReadFieldOrPropType(CLRSignatureParser parser)
        {
            CLRSigType.ElementType basicType = (CLRSigType.ElementType)parser.ReadU8();

            switch (basicType)
            {
                case CLRSigType.ElementType.BOOLEAN:
                case CLRSigType.ElementType.CHAR:
                case CLRSigType.ElementType.R4:
                case CLRSigType.ElementType.R8:
                case CLRSigType.ElementType.I1:
                case CLRSigType.ElementType.U1:
                case CLRSigType.ElementType.I2:
                case CLRSigType.ElementType.U2:
                case CLRSigType.ElementType.I4:
                case CLRSigType.ElementType.U4:
                case CLRSigType.ElementType.I8:
                case CLRSigType.ElementType.U8:
                case CLRSigType.ElementType.STRING:
                    return new CLRSigTypeSimple(basicType);
                case CLRSigType.ElementType.Special_CustomAttribBoxedObject:
                    return new CLRSigTypeSimple(CLRSigType.ElementType.OBJECT);
                case CLRSigType.ElementType.Special_CustomAttribEnum:
                    {
                        string typeName = ReadUTF8String(parser);
                        throw new NotImplementedException();
                    }
                    break;
                case CLRSigType.ElementType.Special_SystemType:
                    // CLARITYTODO: Look up System.Type
                    throw new NotImplementedException();
                case CLRSigType.ElementType.SZARRAY:
                    {
                        CLRSigType containedType = ReadFieldOrPropType(parser);
                        return new CLRSigTypeArray(CLRSigType.ElementType.SZARRAY, containedType);
                    }
                default:
                    throw new ParseFailedException("Unexpected field or prop type");
            }
        }
        private void Parse(CLRSignatureParser parser, CLRSigType elemType)
        {
            ElementType = elemType.BasicType;

            switch (elemType.BasicType)
            {
                case CLRSigType.ElementType.BOOLEAN:
                    Value = (parser.ReadU8() != 0);
                    break;
                case CLRSigType.ElementType.CHAR:
                    Value = (char)(parser.ReadU16());
                    break;
                case CLRSigType.ElementType.R4:
                    Value = parser.ReadF32();
                    break;
                case CLRSigType.ElementType.R8:
                    Value = parser.ReadF64();
                    break;
                case CLRSigType.ElementType.I1:
                    Value = parser.ReadS8();
                    break;
                case CLRSigType.ElementType.U1:
                    Value = parser.ReadU8();
                    break;
                case CLRSigType.ElementType.I2:
                    Value = parser.ReadS16();
                    break;
                case CLRSigType.ElementType.U2:
                    Value = parser.ReadU16();
                    break;
                case CLRSigType.ElementType.I4:
                    Value = parser.ReadS32();
                    break;
                case CLRSigType.ElementType.U4:
                    Value = parser.ReadU32();
                    break;
                case CLRSigType.ElementType.I8:
                    Value = parser.ReadS64();
                    break;
                case CLRSigType.ElementType.U8:
                    Value = parser.ReadU64();
                    break;
                case CLRSigType.ElementType.STRING:
                    Value = ReadUTF8String(parser);
                    break;
                case CLRSigType.ElementType.OBJECT:
                    Parse(parser, ReadFieldOrPropType(parser));
                    return;
                case CLRSigType.ElementType.CLASS:
                case CLRSigType.ElementType.VALUETYPE:
                    {
                        CLRSigTypeStructured st = (CLRSigTypeStructured)elemType;
                        CLRTableRow underlyingType = st.TypeDefOrRefOrSpec;
                        string typeNamespace, typeName;
                        if (underlyingType is CLRTypeDefRow)
                        {
                            CLRTypeDefRow typeDef = (CLRTypeDefRow)underlyingType;
                            typeNamespace = typeDef.TypeNamespace;
                            typeName = typeDef.TypeName;
                        }
                        else if (underlyingType is CLRTypeRefRow)
                        {
                            CLRTypeRefRow typeRef = (CLRTypeRefRow)underlyingType;
                            typeNamespace = typeRef.TypeNamespace;
                            typeName = typeRef.TypeName;
                        }
                        else
                            throw new ParseFailedException("Unusual CA type");

                        if (typeNamespace == "System" && typeName == "Type")
                        {
                            Parse(parser, new CLRSigTypeSimple(CLRSigType.ElementType.STRING));
                            return;
                        }

                        // Must be an enum
                        {
                            CLRTypeDefRow enumType;

                            if (underlyingType is CLRTypeDefRow)
                                enumType = (CLRTypeDefRow)underlyingType;
                            else if (underlyingType is CLRTypeRefRow)
                            {
                                CLRTypeRefRow typeRef = (CLRTypeRefRow)underlyingType;
                                if (typeRef.Resolution == null)
                                    throw new ParseFailedException("Custom attribute references unresolved enum type");
                                enumType = typeRef.Resolution;
                            }
                            else
                                throw new ParseFailedException("Unexpected CA underlying type");

                            CLRSigType valueType = null;

                            foreach (CLRFieldRow field in enumType.Fields)
                            {
                                if (!field.Static)
                                {
                                    valueType = field.Signature.Type;
                                    break;
                                }
                            }

                            if (valueType == null)
                                throw new ParseFailedException("Unknown CA enum type");
                            Parse(parser, valueType);
                        }
                    }
                    break;
                default:
                    throw new NotSupportedException("Unsupported custom attrib type");
            }
        }