示例#1
0
int directive( int i, long direct )
/* Handle all directives */
{
    int         ret;

    /* no expansion on the following */
    switch( direct ) {
    case T_MASM:
        Options.mode &= ~MODE_IDEAL;
        return( NOT_ERROR );
    case T_IDEAL:
        Options.mode |= MODE_IDEAL;
        return( NOT_ERROR );
    case T_DOT_286C:
        direct = T_DOT_286;
    case T_DOT_8086:
    case T_DOT_186:
    case T_DOT_286:
    case T_DOT_286P:
    case T_DOT_386:
    case T_DOT_386P:
    case T_DOT_486:
    case T_DOT_486P:
    case T_DOT_586:
    case T_DOT_586P:
    case T_DOT_686:
    case T_DOT_686P:
    case T_DOT_8087:
    case T_DOT_287:
    case T_DOT_387:
    case T_DOT_NO87:
    case T_DOT_K3D:
    case T_DOT_MMX:
    case T_DOT_XMM:
    case T_DOT_XMM2:
    case T_DOT_XMM3:
        if( Options.mode & MODE_IDEAL ) {
            AsmError( UNKNOWN_DIRECTIVE );
            return( ERROR );
        } else {
            ret = cpu_directive(direct);
            if( Parse_Pass != PASS_1 )
                ret = NOT_ERROR;
            return( ret );
        }
    case T_P286N:
        direct = T_P286;
    case T_P8086:
    case T_P186:
    case T_P286:
    case T_P286P:
    case T_P386:
    case T_P386P:
    case T_P486:
    case T_P486P:
    case T_P586:
    case T_P586P:
    case T_P686:
    case T_P686P:
    case T_P8087:
    case T_P287:
    case T_P387:
    case T_PK3D:
    case T_PMMX:
    case T_PXMM:
    case T_PXMM2:
    case T_PXMM3:
        ret = cpu_directive(direct);
        if( Parse_Pass != PASS_1 )
            ret = NOT_ERROR;
        return( ret );
    case T_DOT_DOSSEG:
        if( Options.mode & MODE_IDEAL ) {
            AsmError( UNKNOWN_DIRECTIVE );
            return( ERROR );
        }
    case T_DOSSEG:
        Globals.dosseg = TRUE;
        return( NOT_ERROR );
    case T_PUBLIC:
        /* special case - expanded inside iff it is an EQU to a symbol */
        return( Parse_Pass == PASS_1 ? PubDef(i+1) : NOT_ERROR );
    case T_ELSE:
    case T_ELSEIF:
    case T_ELSEIF1:
    case T_ELSEIF2:
    case T_ELSEIFB:
    case T_ELSEIFDEF:
    case T_ELSEIFE:
    case T_ELSEIFNB:
    case T_ELSEIFNDEF:
    case T_ELSEIFDIF:
    case T_ELSEIFDIFI:
    case T_ELSEIFIDN:
    case T_ELSEIFIDNI:
    case T_ENDIF:
    case T_IF:
    case T_IF1:
    case T_IF2:
    case T_IFB:
    case T_IFDEF:
    case T_IFE:
    case T_IFNB:
    case T_IFNDEF:
    case T_IFDIF:
    case T_IFDIFI:
    case T_IFIDN:
    case T_IFIDNI:
        return( conditional_assembly_directive( i ) );
    case T_DOT_ERR:
    case T_DOT_ERRB:
    case T_DOT_ERRDEF:
    case T_DOT_ERRDIF:
    case T_DOT_ERRDIFI:
    case T_DOT_ERRE:
    case T_DOT_ERRIDN:
    case T_DOT_ERRIDNI:
    case T_DOT_ERRNB:
    case T_DOT_ERRNDEF:
    case T_DOT_ERRNZ:
        if( Options.mode & MODE_IDEAL ) {
            AsmError( UNKNOWN_DIRECTIVE );
            return( ERROR );
        }
    case T_ERR:
    case T_ERRIFB:
    case T_ERRIFDEF:
    case T_ERRIFDIF:
    case T_ERRIFDIFI:
    case T_ERRIFE:
    case T_ERRIFIDN:
    case T_ERRIFIDNI:
    case T_ERRIFNDEF:
        return( conditional_error_directive( i ) );
    case T_ENDS:
        if( Definition.struct_depth != 0 )
            return( StructDef( i ) );
        // else fall through to T_SEGMENT
    case T_SEGMENT:
        return( Parse_Pass == PASS_1 ? SegDef(i) : SetCurrSeg(i) );
    case T_GROUP:
        return( Parse_Pass == PASS_1 ? GrpDef(i) : NOT_ERROR );
    case T_PROC:
        return( ProcDef( i, TRUE ) );
    case T_ENDP:
        return( ProcEnd(i) );
    case T_ENUM:
        return( EnumDef( i ) );
    case T_DOT_CODE:
    case T_DOT_STACK:
    case T_DOT_DATA:
    case T_DOT_DATA_UN:
    case T_DOT_FARDATA:
    case T_DOT_FARDATA_UN:
    case T_DOT_CONST:
        if( Options.mode & MODE_IDEAL ) {
            AsmError( UNKNOWN_DIRECTIVE );
            return( ERROR );
        }
    case T_CODESEG:
    case T_STACK:
    case T_DATASEG:
    case T_UDATASEG:
    case T_FARDATA:
    case T_UFARDATA:
    case T_CONST:
        return( SimSeg(i) );
    case T_WARN:
    case T_NOWARN:
        return( NOT_ERROR ); /* Not implemented yet */
    case T_DOT_ALPHA:
    case T_DOT_SEQ:
    case T_DOT_LIST:
    case T_DOT_LISTALL:
    case T_DOT_LISTIF:
    case T_DOT_LISTMACRO:
    case T_DOT_LISTMACROALL:
    case T_DOT_NOLIST:
    case T_DOT_XLIST:
    case T_DOT_TFCOND:
    case T_DOT_SFCOND:
    case T_DOT_LFCOND:
    case T_DOT_CREF:
    case T_DOT_XCREF:
    case T_DOT_NOCREF:
    case T_DOT_SALL:
    case T_PAGE:
    case T_TITLE:
    case T_SUBTITLE:
    case T_SUBTTL:
        if( Options.mode & MODE_IDEAL ) {
            AsmError( UNKNOWN_DIRECTIVE );
            return( ERROR );
        }
        AsmWarn( 4, IGNORING_DIRECTIVE );
        return( NOT_ERROR );
    case T_DOT_BREAK:
    case T_DOT_CONTINUE:
    case T_DOT_ELSE:
    case T_DOT_ENDIF:
    case T_DOT_ENDW:
    case T_DOT_IF:
    case T_DOT_RADIX:
    case T_DOT_REPEAT:
    case T_DOT_UNTIL:
    case T_DOT_WHILE:
        if( Options.mode & MODE_IDEAL ) {
            AsmError( UNKNOWN_DIRECTIVE );
            return( ERROR );
        }
    case T_ECHO:
    case T_HIGH:
    case T_HIGHWORD:
    case T_LOW:
    case T_LOWWORD:
    case T_ADDR:
    case T_BOUND:
    case T_CASEMAP:
    case T_INVOKE:
    case T_LROFFSET:
    case T_OPATTR:
    case T_OPTION:
    case T_POPCONTEXT:
    case T_PUSHCONTEXT:
    case T_PROTO:
    case T_THIS:
    case T_WIDTH:
        if( Options.mode & MODE_IDEAL ) {
            AsmError( UNKNOWN_DIRECTIVE );
            return( ERROR );
        }
    case T_CATSTR:
    case T_MASK:
    case T_PURGE:
    case T_RECORD:
    case T_TYPEDEF:
    case T_UNION:
        AsmError( NOT_SUPPORTED );
        return( ERROR );
    case T_ORG:
        ExpandTheWorld( 0, FALSE, TRUE );
        break;
    case T_TEXTEQU:     /* TEXTEQU */
        if( Options.mode & MODE_IDEAL ) {
            AsmError( UNKNOWN_DIRECTIVE );
            return( ERROR );
        }
    case T_EQU2:        /* = */
    case T_EQU:         /* EQU */
        /* expand any constants and simplify any expressions */
        ExpandTheConstant( 0, FALSE, TRUE );
        break;
    case T_NAME:        /* no expand parameters */
        break;
    case T_DOT_STARTUP:
    case T_DOT_EXIT:
        if( Options.mode & MODE_IDEAL ) {
            AsmError( UNKNOWN_DIRECTIVE );
            return( ERROR );
        }
    case T_STARTUPCODE:
    case T_EXITCODE:
    default:
        /* expand any constants in all other directives */
        ExpandAllConsts( 0, FALSE );
        break;
    }

    switch( direct ) {
    case T_ALIAS:
        if( Parse_Pass == PASS_1 )
            return( AddAlias( i ) );
        return( NOT_ERROR );
    case T_EXTERN:
        if( Options.mode & MODE_IDEAL ) {
            break;
        }
    case T_EXTRN:
        return( Parse_Pass == PASS_1 ? ExtDef( i+1, FALSE ) : NOT_ERROR );
    case T_COMM:
        return( Parse_Pass == PASS_1 ? CommDef(i+1) : NOT_ERROR );
    case T_EXTERNDEF:
        if( Options.mode & MODE_IDEAL ) {
            break;
        }
    case T_GLOBAL:
        return( Parse_Pass == PASS_1 ? ExtDef( i+1, TRUE ) : NOT_ERROR );
    case T_DOT_MODEL:
        if( Options.mode & MODE_IDEAL ) {
            break;
        }
    case T_MODEL:
        return( Model(i) );
    case T_INCLUDE:
        return( Include(i+1) );
    case T_INCLUDELIB:
        return( Parse_Pass == PASS_1 ? IncludeLib(i+1) : NOT_ERROR );
    case T_ASSUME:
        return( SetAssume(i) );
    case T_END:
        return( ModuleEnd(Token_Count) );
    case T_EQU:
        return( DefineConstant( i-1, FALSE, FALSE ) );
    case T_EQU2:
        return( DefineConstant( i-1, TRUE, FALSE ) );
    case T_TEXTEQU:
        return( DefineConstant( i-1, TRUE, TRUE ) );
    case T_MACRO:
        return( MacroDef(i, FALSE ) );
    case T_ENDM:
        return( MacroEnd( FALSE ) );
    case T_EXITM:
        return( MacroEnd( TRUE ) );
    case T_ARG:
        return( Parse_Pass == PASS_1 ? ArgDef(i) : NOT_ERROR );
    case T_USES:
        return( Parse_Pass == PASS_1 ? UsesDef(i) : NOT_ERROR );
    case T_LOCAL:
        return( Parse_Pass == PASS_1 ? LocalDef(i) : NOT_ERROR );
    case T_COMMENT:
        if( Options.mode & MODE_IDEAL )
            break;
        return( Comment( START_COMMENT, i ) );
    case T_STRUCT:
        if( Options.mode & MODE_IDEAL ) {
            break;
        }
    case T_STRUC:
        return( StructDef( i ) );
    case T_NAME:
        return( Parse_Pass == PASS_1 ? NameDirective(i) : NOT_ERROR );
    case T_LABEL:
        return( LabelDirective( i ) );
    case T_ORG:
        return( OrgDirective( i ) );
    case T_ALIGN:
    case T_EVEN:
        return( AlignDirective( direct, i ) );
    case T_FOR:
        if( Options.mode & MODE_IDEAL ) {
            break;
        }
    case T_IRP:
        return( ForDirective ( i+1, IRP_WORD ) );
    case T_FORC:
        if( Options.mode & MODE_IDEAL ) {
            break;
        }
    case T_IRPC:
        return( ForDirective ( i+1, IRP_CHAR ) );
    case T_REPEAT:
        if( Options.mode & MODE_IDEAL ) {
            break;
        }
    case T_REPT:
        return( ForDirective ( i+1, IRP_REPEAT ) );
    case T_DOT_STARTUP:
    case T_DOT_EXIT:
    case T_STARTUPCODE:
    case T_EXITCODE:
        return( Startup ( i ) );
    case T_LOCALS:
    case T_NOLOCALS:
        return( Locals( i ) );
    }
    AsmError( UNKNOWN_DIRECTIVE );
    return( ERROR );
}
示例#2
0
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;
}