symtype.h

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C头文件 代码 · 共 1,407 行 · 第 1/5 页

H
1,407
字号
/*
    - we shouldn't need 'using_list' to be in 'SCOPE' since the ISO C++ WP
      is arranged so that 'using_list''s are only part of namespaces
      (common scope will always be a namespace).  We have 'using_list'
      in scope in case we have to support the "bug" in MS/MetaWare where
      using takes effect in the current scope (which may be a block scope).
      If both MetaWare and MS (and Borland) eventually get it right, we
      can move 'using_list' into NAME_SPACE.

    - struct scope can be reduced in size if 'id' moves into the flags
        as "unsigned id : 8;" (this removes 1 DWORD from the size
        with no loss of alignment or efficiency; remember to fix
        PCH read/write code in SCOPE.C to not explicitly save/restore
        'id' since it will be covered by 'flags')

        note: for debugging the current layout is best (id is an enum)
                so the above change should only be done for the production
                (not development) version
*/

// all fields should be treated as read-only and private to SCOPE.C
PCH_struct scope {
    SCOPE               enclosing;      // - lexically enclosing scope
    HASHTAB             names;          // - names in this scope
    SYMBOL              ordered;        // - list of variables in order of decl
    USING_NS            *using_list;    // - list of "using namespace X"'s
    union {                             // - owner of scope
        NAME_SPACE      *ns;            // -- name space for SCOPE_FILE
        SYMBOL          sym;            // -- function owning SCOPE_FUNCTION
        TYPE            type;           // -- class owning SCOPE_CLASS
        unsigned        index;          // -- index for SCOPE_BLOCK
        TEMPLATE_INFO   *tinfo;         // -- SCOPE_TEMPLATE_PARM (classes)
        FN_TEMPLATE_DEFN *defn;         // -- SCOPE_TEMPLATE_PARM (functions)
    } owner;
    union {
        unsigned        flags;
        struct {
          unsigned      keep : 1;       // - indicates scope contains info
          unsigned      dtor_reqd : 1;  // - SCOPE_BLK -- need to dtor
          unsigned      dtor_naked : 1; // - SCOPE_BLK -- has naked dtor syms
          unsigned      try_catch : 1;  // - SCOPE_BLK -- try/catch block
          unsigned      arg_check : 1;  // - check decls against arg scope
          unsigned      cg_stab   : 1;  // - generate for scope
          unsigned      in_unnamed : 1; // - enclosed in an unnamed namespace
          unsigned      colour : 1;     // - using in common enclosing algorithm
          unsigned      fn_template : 1;// - SCOPE_TEMPLATE_PARM -- function
          unsigned      dirty : 1;      // - a symbol has been added
        };
    };
    scope_type_t        id;             // - type of scope
};

/*
  Accessing a member or virtual member function involves two phases

  (1) accessing the final class
        if( exact type of class is known )then
            class_addr = addr + 'exact_delta'
        else
            if( 'non_virtual' is FALSE )then
                vbptr_addr = addr + 'vb_offset'
                vb_delta = (*vb_ptr_addr)['vb_index']
                addr = vbptr_addr + vb_delta
            endif
            class_addr = addr + 'delta'
        endif
  (2) accessing the member within the final class
        - accessing a data member
          member_addr = class_addr + 'offset'
        - calling a member function
          "this" = class_addr
          if( virtual call is required )then
              vfptr_addr = class_addr + 'vf_offset'
              member_addr = (*vf_ptr_addr)['sym->u.offset']
          else
              member_addr = direct call address
          endif

    general notes:

    - if( 'regions' != NULL )then
        ignore 'sym_name', it is included in the sym region list
        which gives the full list of symbols to consider
      endif
*/
struct search_result {                  // * means private to SCOPE.C
    SCOPE               scope;          // - scope containing sym_name/sym
    SYMBOL_NAME         sym_name;       // - SYMBOL_NAME found
    SYMBOL              sym;            // - set if user-defd conversion found
    SCOPE               start;          // * scope that initiated the search
    SCOPE               access_decl;    // - first access-decl encountered
    SYM_REGION          *region;        // - list of symbols (if req'd)
    MSG_NUM             error_msg;      // * error message
    MSG_NUM             info_msg;       // * info message
    SYMBOL              info1;          // * parm for info message #1
    SYMBOL              info2;          // * parm for info message #2
    target_offset_t     vb_offset;      // - offset of vftable pointer
    target_offset_t     vb_index;       // - index of virtual base
    target_offset_t     delta;          // - last base class offset
    target_offset_t     exact_delta;    // - last base class direct offset
    target_offset_t     offset;         // - member offset
    target_offset_t     vf_offset;      // - offset of vftable pointer
    TOKEN_LOCN          errlocn;        // * location for errors
    inherit_flag        perm;           // * access permission
    unsigned            simple : 1;     // - name is in a FILE or BLOCK scope
    unsigned            non_virtual : 1;// - use delta offset to find scope
                                        // - only valid for lexical lookup
    unsigned            use_this : 1;   // - may use "this" to access
    unsigned            no_this : 1;    // - cannot use "this" to access
    unsigned            ambiguous : 1;  // * name was ambiguously found
    unsigned            mixed_static :1;// * ovload; if non-static, it's ambig!
    unsigned            cant_be_auto :1;// * nested function refs an auto
    unsigned            protected_OK :1;// * protected SYMBOL access is OK
    unsigned            ignore_access:1;// * don't report access errors
    unsigned            lookup_error :1;// * general lookup error detected
    int                 : 0;
};

typedef enum {
    DERIVED_NO                  = 0,    // class not derived from base
    DERIVED_YES                 = 1,    // class derived from base
    DERIVED_YES_BUT_VIRTUAL     = 2,    // class derived through virtual base
    DERIVED_YES_BUT_AMBIGUOUS   = 3,    // class ambiguously derived from base
    DERIVED_YES_BUT_PRIVATE     = 4,    // class derived through private base
    DERIVED_YES_BUT_PROTECTED   = 5,    // class derived through protected base
} derived_status;

struct class_table {
    CLASS_TABLE         *next;          /* must be RingFreed after use */
    target_offset_t     vb_offset;      /* offset of vbptr */
    target_offset_t     vb_index;       /* index into vbtable */
    target_offset_t     delta;          /* delta table ptr goes in */
    target_offset_t     exact_delta;    /* exact delta table ptr goes in */
    unsigned            count;          /* number of things def'd */
    unsigned            ctor_disp : 1;  /* apply ctor-disp adjustment */
};

struct class_vbtable {
    CLASS_TABLE         h;              /* header */
    TYPE                data[1];        /* NULL terminated */
};

/* sequence:
        (1) this -= delta
        (2) if ctor_disp then
                this -= *(this - sizeof(unsigned))
        (3)     if input_virtual then
                    this += vb_offset
                    this += (*this)[vb_index]
                endif
                this += delta
            endif
        (4) call override
        (5) if output_virtual then
                this += vb_offset
                this += (*this)[vb_index]
            endif
            this += delta
*/
struct thunk_cast {
    target_offset_t     vb_offset;
    target_offset_t     vb_index;
    target_offset_t     delta;
};

struct thunk_action {
    SYMBOL              sym;
    SYMBOL              thunk;                  // symbol for thunk function
    target_offset_t     delta;                  // step 1
    THUNK_CAST          in;                     // step 3
    SYMBOL              override;               // step 4
    THUNK_CAST          out;                    // step 5
    unsigned            ctor_disp : 1;          // control for step 2
    unsigned            input_virtual : 1;      // control for step 3
    unsigned            output_virtual : 1;     // control for step 5
    unsigned            non_empty : 1;          // thunk is necessary
    unsigned            last_entry : 1;         // last entry in vftable
    unsigned            possible_ambiguity : 1; // vftable entry may be ambiguous
    int                 : 0;
};

struct class_vftable {
    CLASS_TABLE         h;              /* header */
    unsigned            amt_left;       /* # of vfns left to go */
    unsigned            ambiguities : 1;/* has potentially ambiguous entries */
    unsigned            corrupted : 1;  /* definitely has bad entries */
    int                 : 0;
    THUNK_ACTION        data[1];        /* terminated if last_entry is TRUE */
};

/*
    - ANALYSE code must determine that 'derived' is derived from 'base' in an
      accessible manner (i.e., there should be no ambiguity/permission errors)
    - set fields labelled 'I' and call ScopeMemberPtrCastAction
    - steps for a safe (B -> D) member pointer cast are:

        GENERATE:
            new_delta = mp.delta;
            new_index = mp.index;
        if( 'delta_reqd' )then          -- delta adjustment
            if( 'test_reqd' )then
                GENERATE:
                    if( new_index == 0 ) {
                        new_delta += 'delta'
                    }
            else
                GENERATE:
                    new_delta += 'delta'
            endif
        endif
        if( 'mapping_reqd' )then                -- index mapping
            if( 'mapping' == NULL )then
                if( 'single_mapping' ) then
                    if( 'vb_index' == 0 )then
                        GENERATE:
                            if( new_index > 'single_test' ) {
                                new_index = 'vb_index'
                            }
                    else
                        GENERATE:
                            if( new_index == 'single_test' ) {
                                new_index = 'vb_index'
                            }
                    endif
                else
                    GENERATE:
                        new_index = 'vb_index'
                endif
            else
                GENERATE:
                    new_index = 'mapping'[ new_index ]
            endif
        endif

    - steps for an unsafe (D->B) member pointer cast are the same except that
      the "index mapping" executes before the "delta adjustment" (which uses
      a "-=" instead of a "+=")

    - future: we could generate exceptions when we know the conversion will
      never work properly
*/
struct member_ptr_cast {                /* I - input, O - output, * - private */
    SCOPE               base;           /* I: base class cope */
    SCOPE               derived;        /* I: derived from 'base' */
    target_offset_t     delta;          /* O: amount to adjust delta by */
    target_offset_t     single_test;    /* O: single idx val that needs mapping */
    target_offset_t     vb_index;       /* O: new value for 'index' */
    SYMBOL              mapping;        /* O: unsigned array to map indices */
    unsigned            safe : 1;       /* I: casting from 'base' to 'derived' */
    unsigned            init_conv : 1;  /* I: convert from found base to final base */
    unsigned            delta_reqd : 1; /* O: TRUE if delta adjustment is req'd */
    unsigned            mapping_reqd : 1;/*O: TRUE is index mapping req'd */
    unsigned            test_reqd : 1;  /* O: TRUE if index == 0 test is req'd */
    unsigned            single_mapping:1;/*O: only one index value needs mapping */
};

/*
    RTTI base class access leaps:

        if( control & RL_VIRTUAL ) {
            this += RTTI.vbptr;
            this += (*this)[ vb_index ];
        }
        this += offset;
*/
struct gen_leap {
    GEN_LEAP            *next;
    TYPE                type;           /* base class type */
    target_offset_t     vb_index;       /* index into virtual base table */
    target_offset_t     offset;         /* offset to add */
    unsigned            control;        /* RL_* control mask */
};

typedef enum {
    BGT_EXACT           = 0,            // exact match
    BGT_TRIVIAL         = 1,            // trivial conversion req'd
    BGT_DERIVED         = 2,            // derived class conversion req'd
    BGT_MAX
} bgt_control;

// defined in LINKAGE.C

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?