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 + -
显示快捷键?