コード例 #1
0
ファイル: stab.cpp プロジェクト: sigurdle/FirstProject2
Type* StabDebugInfo::get_type2(const char* &p, StringIn name, int file_num, int type_num)
{
    Type* pType = nullptr;

    char typeDescriptor = *p++;
//	TRACE("%c", typeDescriptor);
    switch (typeDescriptor)
    {
    case 's':	// struct
    {
        ClassType* pClass = new ClassType();
        pType = pClass;
        //pClass->AddRef();

        pClass->m_kwType = ClassKey_struct;
        pClass->m_name = name;

        ASSERT(pType != NULL);
        //ASSERT(m_types[file_num*100 + type_num] == NULL);

        //Class* pClass2 = (Class*)m_types[file_num*100 + type_num];

        //if (pClass2 == NULL)
        m_types[file_num*100 + type_num] = pType;

//			TRACE("struct");
        int size = get_number(p);
        pClass->m_sizeof = size;// / 8;

        if (*p == '!')
        {
            p++;

            int nbases = get_number(p);
            eat(p, ',');

            for (int i = 0; i < nbases; i++)
            {
                char virtualChar = *p++;
                char visibilityChar = *p++;
                long offset = get_number(p);
                eat(p, ',');
                System::Type* baseType = get_type(p, nullptr);
                eat(p, ';');
            }
        }

        while (*p != ';')
        {
            Declarator* pMemberDecl = new Declarator;
            pMemberDecl->m_name = get_name(p);

            if (*p == '/')
            {
                p++;
                char visibility = *p++;
                ASSERT(isdigit(visibility));
            }

            if (pMemberDecl->m_name.GetLength() && pMemberDecl->m_name.LeftOf(3) == "$vb")
            {
                System::Type* pType = get_type(p, nullptr);

                eat(p, ',');
                pMemberDecl->m_offset = get_number(p) / 8;
            }
            else if (pMemberDecl->m_name.GetLength() && pMemberDecl->m_name.LeftOf(3) == "$vf")
            {
                System::Type* pType = get_type(p, nullptr);

                eat(p, ',');
                pMemberDecl->m_offset = get_number(p) / 8;
            }
            else if (*p == ':')	// Method
            {
                p++;
                do
                {
                    System::Type* pType = get_type(p, nullptr);

                    eat(p, ':');

                    while (*p)
                    {
                        if (*p == ';')
                            break;
                        p++;
                    }
                    eat(p, ';');
                    char number = *p++;
                    ASSERT(isdigit(number));
                    char letter = *p++; //ASSERT(isalpha(letter));
                    ASSERT(letter == 'A' || letter == 'B' || letter == 'C' || letter == 'D');

                    int next = *p++;
                    switch (next)
                    {
                    case '.':	// normal
                        break;

                    case '*':	// virtual
                    {
                        get_number(p);
                        //ASSERT(0);
                        eat(p, ';');
                        get_type(p, nullptr);
                        eat(p, ';');
                    }
                    break;

                    case '?':	// static;
                        break;

                    default:
                        ASSERT(0);
                    }
                }
                while (*p != ';');

                /*
                if (*p != ';')
                {
                Type* pType = get_type(p, StringA());
                eat(p, ':');

                while (*p)
                {
                	if (*p == ';')
                		break;
                	p++;
                }

                eat(p, ';');
                char number = *p++; ASSERT(isdigit(number));
                char letter = *p++; //ASSERT(isalpha(letter));
                ASSERT(letter == 'A' || letter == 'B' || letter == 'C' || letter == 'D');

                int next = *p++; ASSERT(next == '.' || next == '*');
                ASSERT(next == '.');

                }
                */
            }
            else
            {
                pMemberDecl->m_pType = get_type(p, nullptr);

                if (*p == ':')	// static member
                {
                    p++;
                    while (*p)
                    {
                        if (*p == ';')
                            break;

                        p++;
                    }

                    //	get_name(p);
                }
                else
                {
                    eat(p, ',');
                    pMemberDecl->m_offset = get_number(p) / 8;

                    eat(p, ',');
                    int numbits = get_number(p) / 8;

                    pClass->m_pScope->AddDeclarator(pMemberDecl);
                }
            }

            eat(p, ';');
        }
        eat(p, ';');

        // For classes containing virtual functions the very last section of the string part of the stab holds a type reference to the first base class.
        if (*p == '~')
        {
            p++;
            eat(p, '%');
            get_type(p, nullptr);
            eat(p, ';');
        }

        /*
        if (pClass2)
        {
        	if (!pClass->Equals(pClass2))
        	{
        		ASSERT(0);
        	}
        }
        */
    }
    break;

    case 'u':	// union
    {
        ClassType* pClass = new ClassType();
        pType = pClass;
        //	pClass->AddRef();
        pClass->m_kwType = ClassKey_union;

        pClass->m_name = name;

        ASSERT(pType != NULL);
        //	ASSERT(m_types[file_num*100 + type_num] == NULL);
        m_types[file_num*100 + type_num] = pType;

//			TRACE("union");
        int size = get_number(p);
        pClass->m_sizeof = size;// / 8;

        while (*p != ';')
        {
            Declarator* pMemberDecl = new Declarator;
            pMemberDecl->m_name = get_name(p);

            if (*p == ':')	// Method
            {
                p++;

                do
                {
                    System::Type* pType = get_type(p, nullptr);

                    eat(p, ':');

                    while (*p)
                    {
                        if (*p == ';')
                            break;
                        p++;
                    }
                    eat(p, ';');
                    char number = *p++;
                    ASSERT(isdigit(number));
                    char letter = *p++;
                    ASSERT(isalpha(letter));
                    int next = *p++;
                    ASSERT(next == '.' || next == '*');
                    ASSERT(next == '.');
                }
                while (*p != ';');
            }
            else
            {

                pMemberDecl->m_pType = get_type(p, nullptr);

                eat(p, ',');
                pMemberDecl->m_offset = get_number(p) / 8;

                eat(p, ',');
                int numbits = get_number(p) / 8;

                pClass->m_pScope->AddDeclarator(pMemberDecl);
            }

            eat(p, ';');
        }
        eat(p, ';');
    }
    break;

    case 'e':	// enum
    {
        NamedType* pType2 = m_pReceiver->LookupNamedType(name);

        EnumType* pEnum = new EnumType;
        pEnum->m_name = name;

        while (*p != ';')
        {
            String name = get_name(p);
            long value = get_number(p);

            //EnumDef& enumDef = new ;

            pEnum->m_deflist.push_back(EnumDef(name, value));

            eat(p, ',');
        }
        eat(p, ';');

        if (pType2)
        {
#if 0
            if (!pType2->Equals(*pEnum))
            {
                //	ASSERT(0);
            }
#endif
            pType = pType2;

        }
        else
        {
            pType = pEnum;
        }

        m_types[file_num*100 + type_num] = pType;
    }
    break;

    case 'a':	// array
    {
        get_type2(p, nullptr, -1, -1);	// index type

        get_type(p, nullptr);	// element type
    }
    break;

    case 'f':	// function type
    {
        pType = new FunctionType;//new Type(type_function);
        //pType->m_pFunction = ;
        pType->AsFunction()->m_pReturnType = get_type(p, nullptr);
    }
    break;
#if 0
    case 'f': /* || typeDescriptor == 'F' */
    {
        Type* pReturnType = get_type(p);
        // TODO
        /*
        if (*p == ',')
        {
        p++;
        }
        eatchar(';');
        */
    }
    break;
#endif

    case 'r':	// subrange type
    {
        /*
        pType = new PrimitiveType;//(type_int, 4);
        ASSERT(pType);
        ASSERT(m_types[file_num*100 + type_num] == NULL);
        m_types[file_num*100 + type_num] = pType;
        	*/

        Type* pType2 = get_type(p, nullptr);
        eat(p, ';');

        int lower = get_number(p);
        eat(p, ';');

        int upper = get_number(p);
        eat(p, ';');

        //Type_type type;

        LONGLONG range = (LONGLONG)upper - (LONGLONG)lower;
        if (range <= 255)
        {
            pType = &Types::type_char;
            //	pType->m_sizeof = 1;
        }
        else if (range <= 65535)
        {
            pType = &Types::type_short;
            //	pType->m_sizeof = 2;
        }
        else// if (range <= MAX_INT)
        {
            pType = &Types::type_int;
            //	pType->m_sizeof = 4;
        }
        //pType = System::PrimitiveType(type);//(type_int, 4);

        if (type_num != -1)
        {
            if (m_types[file_num*100 + type_num] != NULL)
            {
                /*
                if (!m_types[file_num*100 + type_num]->Equals(pType))
                {
                	ASSERT(0);
                }
                */
            }
            //ASSERT(m_types[file_num*100 + type_num] == NULL);
            m_types[file_num*100 + type_num] = pType;
        }
    }
    break;

    case 'R':
    {
        char fp_type = *p++;

        if (fp_type == '1')			pType = &Types::type_float;
        else if (fp_type == '2')	pType = &Types::type_double;
        else
            ASSERT(0);	// TODO

        eat(p, ';');
        int /*pType->m_*/ _sizeof = get_number(p);
        VERIFY(pType->get_sizeof() == _sizeof);

        //	ASSERT(m_types[file_num*100 + type_num] == NULL || m_types[file_num*100 + type_num]->Equals(pType));
        m_types[file_num*100 + type_num] = pType;
    }
    break;

    case '*':
    {
        pType = new PointerType(get_type(p, nullptr));

//			ASSERT(m_types[file_num*100 + type_num] == NULL || m_types[file_num*100 + type_num]->Equals(pType));
        m_types[file_num*100 + type_num] = pType;
    }
    break;

    case '&':
    {
        pType = new ReferenceType(get_type(p, nullptr));

        //	ASSERT(m_types[file_num*100 + type_num] == NULL);
        m_types[file_num*100 + type_num] = pType;
    }
    break;

    case 'k':
    {
        pType = new ModifierType(get_type(p, nullptr), true, false);
        //	((CVType*)pType)->m_bConst = true;

        //	ASSERT(m_types[file_num*100 + type_num] == NULL || m_types[file_num*100 + type_num]->Equals(pType));
        m_types[file_num*100 + type_num] = pType;
    }
    break;

    case 'B':
    {
        pType = new ModifierType(get_type(p, nullptr), false, true);
        //	((CVType*)pType)->m_bVolatile = true;

        //	ASSERT(m_types[file_num*100 + type_num] == NULL || m_types[file_num*100 + type_num]->Equals(pType));
        m_types[file_num*100 + type_num] = pType;
    }
    break;

    case '#':
    {
        if (*p == '#')
        {
            p++;

            Type* returnType = get_type(p, nullptr);
            eat(p, ';');

            // the class and argument types are not specified, specified, and must be
            // determined by demangling the name of the method if it is available
        }
        else
        {
            Type* classType = get_type(p, nullptr);
            eat(p, ',');
            Type* returnType = get_type(p, nullptr);
            //eat(p, ',');
            while (*p == ',')
            {
                p++;
                Type* paramType = get_type(p, nullptr);
            }
            eat(p, ';');
        }
    }
    break;

    case '-':	// negative type descriptor
    {
        int num = -get_number(p);
        eat(p, ';');

        switch (num)
        {
        case -16:
            pType = &Types::type_int;	// 32bit boolean
            break;

        default:
            ASSERT(0);
            throw new Exception(L"parse error");
        }

        //		pType = new Type(type_pointer, sizeof_pointer);
        //		pType->m_pPointerTo = get_type(p);

        //	ASSERT(m_types[file_num*100 + type_num] == NULL || m_types[file_num*100 + type_num]->Equals(pType));
        m_types[file_num*100 + type_num] = pType;
    }
    break;

    case 'x':	// forward reference
    {
        char type = *p++;
        ASSERT(type == 's' || type == 'u' || type == 'e');
        String name = get_name(p);
    }
    break;

    default:
    {
        ASSERT(0);
        // TODO
        pType = &Types::type_int;
        ASSERT(pType != NULL);
        //	ASSERT(m_types[file_num*100 + type_num] == NULL);
        m_types[file_num*100 + type_num] = pType;
    }
    }

    return pType;
}