1 //
2 //     In memory storage for C/C++ objects.
3 //
4
5 #include  "_TempSupp.HXX"
6
7 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
8 //     ====== Part 1. ==========  Cpp objects infrastructure  =============
9 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
10
11 //
12 //  Base class of all objects in the C/C++ database.
13 //
14 class TCppItemBase : public TListItem
15 {
16 protected:
17
18     ID                            m_cib_id;
19                                                 // This is an identifier of the object in the Cpp database. This id has nothing
20                                                 // to do with ids of the objects in the mid scan layer storage.
21     TCppItemType                m_cib_type;
22
23     TCppItemBase                *m_cib_parent;    
24                                                 // All objects, registered in the Cpp database except for global namespace
25                                                 // object itself have non NULL parent object.
26 public:
27
28         TCppItemBase(TCppItemType cxt, ID id = 0) { m_cib_id = id; m_cib_type = cxt; m_cib_parent = NULL; }
29         ~TCppItemBase();
30                     // Destructor of the derived class is responsible for freeing the subtree of the owned children if any.
31
32     inline  ID                    ItemId() const { return(m_cib_id); }
33     inline  TCppItemType        ItemType() const { return(m_cib_type); }
34
35     inline  TCppItemBase        *ItemParent() const { return(m_cib_parent); }
36
37     inline  bool                IsPublished() const;
38                                             // The item is considered to be published when it is a direct or an indirect child of the global namespace.
39
40     inline  bool                IsParentOf(TCppItemBase *child_item) const;
41     inline  bool                IsChildOf(TCppItemBase *parent_item) const;
42
43     inline  bool                IsTemplateInstantiation() const;
44                                             // Return value is TRUE if the object is either a template instantiation itself or if it is a child of a template
45                                             // instantiation object. Note that all children of template instantiations are created only during the template
46                                             // instantiation process.
47 public:
48
49     virtual bool                IsStatementBase() const { return(FALSE); }
50     virtual bool                IsDefinition() const { return(FALSE); }
51
52     virtual bool                IsDataType(bool template_context) const { return(FALSE); }
53     virtual bool                IsFunctionType(bool template_context) const { return(FALSE); }
54                                             // These methods need parameter because in non template contexts the class template is not a data
55                                             // type while in template context it is a data type. Similar situation takes place with function type.
56
57     virtual bool                IsClassTemplateFamily() const { return(FALSE); }
58                                             // Class templates family consists of ClassTemplate, ClassTemplateSpec and ClassTemplateInst.
59                                             // This is first group of overloadable objects. Note that simple class is NOT part of this group.
60
61     virtual bool                IsFunctionFamily() const { return(FALSE); }
62                                             // Functions family consists of CodeEntryPoint, FuncTemplate, FuncTemplateSpec and FuncTemplateInst.
63                                             // This is second group of overloadable objects. Note that simple function IS part of this group.
64
65     virtual bool                IsFunctionName() const { return(FALSE); }
66                                             // This method returns TRUE for all objects that can be named not only with identifier, but also with
67                                             // token of overloaded operator, dest type of overloaded conversion, or destructor form of the name.
68
69     virtual bool                IsNamespace() const { return(FALSE); }
70     virtual bool                IsStructType() const { return(FALSE); }
71     virtual bool                IsBlock() const { return(FALSE); }
72
73     virtual bool                IsExpression() const { return(FALSE); }
74
75     virtual bool                IsUnresolvedObject() const { return(FALSE); }
76                                             // Unresolved objects are created when parsing code references something that was not defined
77                                             // or when the name or overloaded operator/conversion is ambiguous.
78
79     virtual bool                CanHaveChildren() const { return(FALSE); }
80
81 public:
82
83     virtual void                AddChildItem(TCppItemBase *item, int item_destination = -1) { assert(FALSE); }
84     virtual void                NewIndirectChildNotification(TCppItemBase *items_subtree_root) { assert(FALSE); }
85                                             // These methods are overwritten only by those classes that support children. Owned children
86                                             // should be added ONLY using either the AddChildItem() or AddListOfChildren() methods.
87
88     void                              AddListOfChildren(TList &items_to_add, int items_destination = -1);
89                                             // Method moves elements of the list one by one. It is simple wrapper over the AddChildItem().
90
91     inline  int                    NumDirectChildren() const;
92                                             // Method returns the number of owned items.
93
94     inline  int                    NumSubtreeItems() const;
95                                             // This method returns number of objects in the subtree including the object itself.
96
97     inline  int                    GetItemNesting() const;
98                                             // This method should be called for published objects only. It returns the distance from this object
99                                             // to the global namespace. Members of the global namespace have distance equal to 1.
100
101     TCppLabelDefn            *FindNamedLabelHier(ID key_id);
102     TCppCaseLabelDefn        *FindCaseLabelHier(TCppCaseLabelDefn *case_label);
103                                             // The named labels searcher is searching the whole subtree. The case label searcher ignores
104                                             // case labels that stay inside the SWITCH statements.
105
106     inline  TCppDefnBase        *GetNamespaceParent() const;
107
108     static bool                IsTemplateParam(TCppItemBase *item);
109     static bool                IsTemplateDefinitionArgsList(TList *params_list, TList *args_list);
110     static bool                CompareTemplateParams(TCppItemBase *param1, TCppItemBase *param2);
111     static bool                CompareTemplateParamLists(TList *params_list1, TList *params_list2);
112                                             // Comparison of template params is placed into the core object because class templates and function
113                                             // templates reside in different branches of the classes inheritance tree.
114
115     static bool                CompareSameDatabaseDataTypes(TCppDataTypeBase *type1, TCppDataTypeBase *type2);
116     static bool                CompareSameDatabaseFunctionTypes(TCppFunctionTypeBase *type1, TCppFunctionTypeBase *type2, bool do_full_compare = TRUE);
117                                             // These methods assume that enums, structs (and derived types), type params, etc are identical
118                                             // once they have the same Id of the item.
119
120     static const wchar_t        *GetItemStructName(TCppItemType item_type);
121 };
122
123 //
124 //  The major property of the statement object is that it can have a label in front of it.
125 //
126 class TCppStatementBase : public TCppItemBase
127 {
128 public:
129
130     TCppStatementBase(TCppItemType cxt, ID id = 0);
131
132     virtual bool        IsStatementBase() const { return(TRUE); }
133 };
134
135 //
136 //  This enum suports specific C/C++ feature that allows defining "enum Blah" and "union Blah" in the same
137 //  context. Such definitions are not creating the names collision. When it is necessary to define variables of these
138 //  types it is necessary to add specifier "enum" or specifier "union" to avoid the ambiguity.
139 //
140 enum TCppElabType
141 {
142     elab_none,
143     elab_enum,
144     elab_struct,
145     elab_union,
146     elab_class,
147     elab_num_types,
148 };
149
150 //
151 //  This enumerator has two slightly different meanings. One meaning is straightforward. It describes the storage
152 //  class specifier that was retrieved from the source code. Effectively these are first 6 members of this enum.
153 //  Other meaning is used when the m_strg_class data field in the TCppDataFieldDefn is interpreted. In this case
154 //  meaning of the field depends on the type of container (namespace/class/block) where this variable is defined.
155 //
156 enum TCppStorageClass
157 {
158     strgc_none,                        // This storage class is used for non static (instance) data members in classes.
159     strgc_register,
160     strgc_auto,
161     strgc_static,
162     strgc_extern,
163     strgc_mutable,
164                                             // This is not a storage class but rather an optional attr that is applicable only to the non static
165                                             // data members of the classes. This attribute allows changing this data member from the class
166                                             // member functions, that are declared as const.
167     strgc_param,                    // Param of the function. This value has no corresponding keyword in the C/C++ grammar.
168     strgc_template_param,            // This enum member has no corresponding keyword in the C/C++ grammar.
169     strgc_catch_block_param,        // Param from the catch block header. There is no corresp keyword in the C/C++ grammar.
170     strgc_num_types,
171 };
172
173 enum TCppSpecFuncType
174 {
175     spcft_none,                        // Ordinary function that has name, return value type, etc.
176     spcft_ctor,                        // Constructor.
177     spcft_dector,                    // Destructor.
178     spcft_operator,                    // Overloaded operator.
179     spcft_typecast,                    // Overloaded conversion.
180     spcft_num_types,
181 };
182
183 //
184 //  Base class for C/C++ language definitions.
185 //
186 //  This class is based on the statement class because definitions, that are located inside the block,
187 //  are statements and they can be labeled. On the contrary, definitions in the classes and namespaces
188 //  cannot have labels.
189 //
190 class TCppDefnBase : public TCppStatementBase
191 {
192 protected:
193
194     TCppElabType                    m_defn_elab_type;
195                                                                 // Elaboration type is tightly linked to the type of the object. For example elab type
196                                                                 // enum can be present only in the TCppEnumTypeDefn instances.
197     wchar_t                        *m_defn_name;
198                                                                 // Name can be empty (NULL) in rare cases like nameless namespaces or classes.
199                                                                 // The value of this field is never owned.
200     ID                            m_defn_key_id;
201                                                                 // When the name is empty (NULL), the key id field (key id of the name) should be
202                                                                 // zero. Key id is not zero for all names that were taken directly from the source
203                                                                 // code. In several other cases like names collision, nameless definitions, etc.,
204                                                                 // the value of the key id is zero.
205     int                            m_defn_cnt_use;
206
207 public:
208
209         TCppDefnBase(TCppItemType cxt, ID id = 0);
210
211     virtual    bool                IsDefinition() const { return(TRUE); }
212
213     inline    TCppElabType            DefnElabType() const { return(m_defn_elab_type); }
214     inline    const wchar_t            *DefnName() const { return(m_defn_name); }                // Defn name can be NULL.
215     inline    ID                    DefnKeyId() const { return(m_defn_key_id); }                // Defn key id can be zero.
216
217     void                        SetNameInfo(const wchar_t *name, ID key_id) { m_defn_name = (wchar_t*)name; m_defn_key_id = key_id; }
218                                         // Note that NULL name and key_id equal to zero are legal values that are used in the code.
219                                         // Ownership on the name string is not passed.
220
221     const    wchar_t            *GetElabTypeName(bool want_first_cap = FALSE, bool plural_case = FALSE) const { return(GetElabTypeName(m_defn_elab_type, want_first_cap, plural_case)); }
222     const    wchar_t            *GetObjectTypeFriendlyName(wchar_t *buff80, bool want_first_cap = FALSE) const { return(GetObjectTypeFriendlyName(buff80, m_cib_type, m_defn_elab_type, want_first_cap)); }
223
224     static    const  wchar_t        *GetElabTypeName(TCppElabType elab, bool want_first_cap = FALSE, bool plural_case = FALSE);
225                                         // Return value will be one of: "none", "enum", "struct", "union", "class", possibly with the first capital letter.
226
227     static    const wchar_t        *GetObjectTypeFriendlyName(wchar_t *buff80, TCppItemType item_type, TCppElabType elab, bool want_first_cap = FALSE);
228                                         // Method generates human readable names of the type for enums, classes and class templates that are good
229                                         // for using them in error messages, like "struct", "class template", "union template instantiation", etc.
230
231     virtual    TList                *GetNestedMembersList() const { return(NULL); }
232     virtual    TList                *GetUnresolvedNamesList() const { return(NULL); }
233                                         // Note that there is no assert inside these methods. This means that they can be called on any object.
234 protected:
235
236     virtual    TCppDefnsSpace    *GetNestedDefnsSpace() { assert(FALSE); return(NULL); }
237                                         // This method should be used only with those derived classes, that support nested defns spaces.
238                                         // Retrieveing the nested space is needed for calling various query methods.
239
240     virtual    TList                *GetAssocDefnsSpaceRefsList() { assert(FALSE); return(NULL); }
241                                         // Associated definition spaces are spaces of definitions that are visible inside the current container
242                                         // besides the local definitions. Examples are base classes and "USE NAMESPACE" directives.
243
244     virtual    void                AddToNestedDefnsSpace(TCppDefnBase *defn_item, bool named_modifier_defn) { assert(FALSE); }
245                                         // This method should be used when it is necessary to add object to the namespace that is not a child
246                                         // of the current object (typically the child of the child) or when the object will be added as a child later.
247                                         // Second param does not tell anything about the nature of the name of the passed definition. Value of
248                                         // this param can be FALSE only for CVPtrRefType, ArrayType and FunctionType objects. It instructs
249                                         // to put these objects into special buckets once it is specified as FALSE.
250
251     void        AddToMembersListAndDefnsSpace(TCppItemBase *item, TList &members_list, TCppDefnsSpace &defns_space);
252                         // This is protected worker method that is expected to be used only in the namespace, struct type
253                         // and block classes. Similar functionality for the global namespace class is implemented directly in
254                         // the TCppGlobalNamespaceDefn::AddChildItem() because this method cannot be used in the global
255                         // namespace class. This method adds defns only to the named buckets of the defns space.
256 };
257
258 class TCppDataTypeBase : public TCppDefnBase
259 {
260 public:
261
262     TCppDataTypeBase(TCppItemType cxt, ID id = 0);
263
264     virtual bool        IsDataType(bool template_context) const { return(TRUE); }
265
266     static TCppDataTypeBase    *GetUnderlyingNumericType(TCppDataTypeBase *data_type, bool template_conext);
267                                 //
268                                 //    The return value is NULL when passed data type cannot be converted into the numeric type.
269                                 //    Otherwise the return value can be:
270                                 //
271                                 //         --    BuiltInType (bltin_type_bool, bltin_type_char, bltin_type_int  subtypes only).
272                                 //         --    EnumType (only with NULL base type).
273                                 //         --    TemplateTypeParam, UnresolvedDataType, UnresolvedStructType (if tempate context is TRUE).
274                                 //
275 };
276
277 class TCppFunctionTypeBase : public TCppDefnBase
278 {
279 public:
280
281     TCppFunctionTypeBase(TCppItemType cxt, ID id = 0);
282
283     virtual bool        IsFunctionType(bool template_context) const { return(TRUE); }
284 };
285
286 class TCppExpressionBase : public TCppStatementBase
287 {
288 public:
289
290     TCppExpressionBase(TCppItemType cxt, ID id = 0);
291
292     virtual bool        IsExpression() const { return(TRUE); }
293     inline    bool        IsOperandExpr() const { return(m_cib_type == cxx_operand_expr); }
294
295     const wchar_t        *OperationEnumName() const;
296
297     virtual bool        CanHaveChildren() const { return(TRUE); }
298                                     // Out of 16 types of expresssions 15 types can have children. Only the operand expression cannot
299                                     // have children. This method is overwritten in the TCppOperandExpr class one more time.
300
301     virtual bool        GetConstOperandValue(TCppOperandExpr &expr_value) const { return(FALSE); }
302                                     // Return value of thhis method is FALSE when expression is not const or, in other words, when some
303                                     // operation of the expression tree does not allow static computation, like the call of the function.
304                                     // Note that this method is slightly wider than the m_const_expr flag. It allows to retrieve const oprnd
305                                     // values in some cases when this flag is not set.
306 public:
307
308     TOperatorToken                m_operation;
309                                                 // Majort part of the values of TOperatorToken enum can be present in this field. Nevertheless
310                                                 // there are some exceptions.. When the value of the field is opr_none,/ this means that object
311                                                 // represents an operand.
312
313     bool                            m_lvalue_expr;
314                                                 // The value of the field is TRUE when curent expression can be used in the LEFT hand side of
315                                                 // the assignment expression.
316
317     bool                            m_const_expr;
318                                                 // The value of the field is TRUE when expression can be computed at the time of compilation.
319
320     TCppDefnBase                *m_result_type;
321                                                 // The type of the expression result is always known because it is comuted statically.
322                                                 // In typical case expression is a data manipilation expression. In this situation this field contains
323                                                 // the data type of the expression result. Expression can also be the code entry point expression.
324 };
325
326 struct TCppCvPtrRefSpec
327 {
328     union
329     {
330         struct
331         {
332             bool            cvpr_const;
333             bool            cvpr_volatile;
334
335             bool            cvpr_pointer;
336             bool            cvpr_reference;
337         };                                    // Note that if pointer and const flags are set at the same time, this means "int * const var",
338                                             // not the "int const * var". Second example will be expressed using two indirection layers.
339         DWORD            cvpr_flags;
340     };
341
342     TCppDataTypeBase    *cvpr_struct;
343                                             // Pointer in this field is not NULL only when structure describes a pointer/reference to
344                                             // the member of the class/struct/union. Ordinary pointers and refs have NULL in this field.
345                                             // Type of the field is not the struct type because an unresolved name can be present here.
346
347     inline void    Clear();
348     inline bool    IsEmpty() const { return(cvpr_flags == 0); }
349     inline bool    IsSimplePointer() const { return(cvpr_const == FALSE && cvpr_volatile == FALSE && cvpr_pointer == TRUE && cvpr_struct == NULL); }
350     inline bool    Compare(TCppCvPtrRefSpec &inst);
351
352     inline void    SetPointer(TCppDataTypeBase *ptr_strust = NULL) { cvpr_flags = 0; cvpr_pointer = TRUE; cvpr_struct = ptr_strust; }
353     inline void    SetReference(TCppDataTypeBase *ref_strust = NULL) { cvpr_flags = 0; cvpr_reference = TRUE; cvpr_struct = ref_strust; }
354 };
355
356 struct TCppArrayDimensionSpec
357 {
358     __int64                    m_num_elements;
359                                                             // The number of elements should be either positive or zero. When the value
360                                                             // of this field is -1, this means that expression that was defining the size of array
361                                                             // was not const or it was not numeric or its value was negative.
362     TCppExpressionBase        *m_num_elements_expr;
363                                                             // Expression that was used to specify the size. When an array definition is used
364                                                             // in the template code and expression is not constant the error is not generated.
365                                                             // Note that this pointer describes an owned child.
366 };
367
368 typedef TCppCvPtrRefSpec TCppCvPtrRefSpecsArray[4];
369 typedef TCppArrayDimensionSpec TCppArrayDimensionsArray[4];
370
371 enum TCppDeclaratorModifierType
372 {
373     dclmdf_cvpr,
374     dclmdf_array,
375     dclmdf_function,
376 };
377
378 //
379 //  C/C++ language allows three types of declarator modifiers:
380 //
381 //      --    Pointer/reference to something. This modifier can also specify the const/volatile property;
382 //      --    Array of something. This can be either singe dimensional or multi dimensional array;
383 //      --    Function returning something. Function has list of parameters and can also have list of exception
384 //            specs and/or const/volatile specifier.
385 //
386 //  This structure describes one of these 3 possible modifiers. For great extent this structure is more part
387 //  of the Cpp parser rather the cpp classes library. Nevertheless defining it here simplifies the code.
388 //
389 struct TCppDeclaratorModifier
390 {
391     TCppDeclaratorModifierType            m_dmt;
392
393     union
394     {
395         TCppCvPtrRefSpec                m_cvpr_spec;
396
397         TCppArrayDimensionSpec        m_array_spec;
398
399         struct
400         {
401             TCppCvPtrRefSpec            m_func_cv_spec;                // Only const and volatile flags are allowed in this field. These flags can
402                                                                     // be present in the non static member functions only. Essentially they are
403                                                                     // modifiers of the implicit first parameter "this".
404             PrEventHeader            m_func_cv_spec_context;
405
406             TCppItemBase            *m_func_prms_beg;                // Pointer to the first item of the list or NULL.
407             TCppItemBase            *m_func_prms_end;                // Pointer to the last item of the list or NULL.
408                                                 //
409                                                 // When the list of params is present and empty, both pointers are NULL.
410                                                 // Besides the parameters this list can contain possible exception types.
411                                                 //
412                                                 // Data structure with these two pointers is rather specific. It is very similar to the regular
413                                                 // double linked list. This pair of pointers allows moving the structure in memory that the regular
414                                                 // list does not allow. On the other hand, it is not heeded here to add/remove items to the list
415                                                 // one by one. This list is created outside and it is given out as a whole. That is it.
416                                                 //
417
418         };
419     };
420
421     PrEventHeader                    m_modifier_context;
422                                         // This context is needed only for issuing syntax errors while assembling the declarator.
423 };
424
425 //
426 // This struct has very limited use. It should be used only as a data member in the base class spec class and
427 // in the using namespace directive class.
428 //
429 struct TCppAssocDefnsSpaceRef : public TListItem
430 {
431     TCppDefnBase                    *m_assoc_space_ref_object;
432                                         // This poniter points to an object where this object is a data member.
433 };
434
435 //
436 // Defns bucket class is used both for named and special buckets in the spaces of definitions.
437 // Members of this list can be only instances of TCppDefnProxy class.
438 //
439 class TCppDefnsBucket : public TList
440 {
441 public:
442
443     inline int    GetNumObjects(TCppItemType item_type, TCppElabType elab_type, ID key_id) const;
444 };
445
446 //
447 //  Defns space is an interface to the hash table of various definitions. This hash table stores only refrences
448 //  to named and unnamed (special) definitions. Named definitions are always searched using the key_id
449 //  of their names. It is not possible to search for name using its string representation. Unnamed definitions
450 //  have various different search keys depending on its nature.
451 //
452 class TCppDefnsSpace
453 {
454 public:
455
456     void                            Clear();
457                                     //
458                                     //     Remove all definitions from the space.
459                                     //
460
461     void                            AddDefinition(TCppDefnBase *defn, bool named_defn_hint = TRUE);
462                                     //
463                                     //     This method adds passed definition to the defns space. Note that upper layer is responsible for
464                                     //     maintaining the inambiguity of the space.
465                                     //
466                                     //     This class is only storing the passed pointers in its storage buckets. It is not owning them.
467                                     //
468                                     //     Second param of this method has meaning only for CvPtrRefType, ArrayType and FunctionType
469                                     //     definitions. All other types of definitions are added/not added to named/special buckets regardles
470                                     //     of the value of the second parameter.
471                                     //
472                                     //     Note that it is allowed to pass named definitions with key_id equal to zero. In this case these defns
473                                     //     are not added to the space.
474                                     //
475 };
476
477 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
478 //     ====== Part 2. ==========  App level defns  ================
479 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
480
481 enum TCppDeclTypeSpecPrefix
482 {
483     declpr_none,
484     declpr_typedef,
485     declpr_friend,
486 };
487
488 enum TCppAccessLevel
489 {
490     accs_public,
491     accs_protected,
492     accs_private,
493     accs_num_types,
494 };
495
496 enum TCppFunctionAttr
497 {
498     fcta_none            =     0,
499
500     fcta_inline            =     1,
501     fcta_virtual            =     2,
502     fcta_explicit            =     4,        // This specifier can be used only with constructors.
503                                     // It denies using such constructor as an implicit type converter.
504
505     fcta_static            =     8,        // This flag is applicable only to the class member functions. Note that
506                                     // function types do not have storage class attribute like data fields.
507
508     fcta_this_const        =  32,        // This is const specifier, that stays at the end of the function prototype.
509     fcta_this_volatile    =  64,        // This is volatile spec, that stays at the end of the function prototype.
510             //
511             // Const and volatile flags in the function prototype and function header are applicable
512             // only to the non static class member functions. They specify propertiess of the first
513             // implicit parameter "this".
514             //
515
516     fcta_pure            = 128,        // This flag has no corresponding keyword in the C++ grammar.
517 };
518
519 enum TCppBuiltInTypeType
520 {
521     bltin_type_void,
522     bltin_type_bool,
523     bltin_type_char,
524     bltin_type_int,
525     bltin_type_float,
526     bltin_type_ellips,
527
528     bltin_num_types,
529 };
530
531 //
532 //  Built in types have fixed ids that do not change from one compilation to another.
533 //  All other objects in the Cpp database have dynamically assigned ids.
534 //
535 enum TCppBuiltInTypeIdent
536 {
537     bltin_ids_base = 0x1220000,
538
539     bltin_id_void,        bltin_id_bool,
540
541     bltin_id_schar8,        bltin_id_uchar8,
542     bltin_id_schar16,    bltin_id_uchar16,
543
544     bltin_id_sint8,        bltin_id_uint8,
545     bltin_id_sint16,        bltin_id_uint16,
546     bltin_id_sint32,        bltin_id_uint32,
547     bltin_id_sint64,        bltin_id_uint64,
548
549     bltin_id_float4,        bltin_id_float8,
550     bltin_id_float16,
551
552     bltin_id_ellips,
553
554     bltin_ids_max_plus1,
555 };
556
557 enum TCppInitalizerType
558 {
559     cinit_none,
560
561     cinit_single_expr,
562     cinit_exprs_list,
563     cinit_aggregate,
564
565     cinit_num_types,
566 };
567
568 // ---------------------------------------------------------------------------
569 //  - - (Defns1) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
570 // ---------------------------------------------------------------------------
571
572 struct TCppBuiltInTypeDefn : public TCppDataTypeBase
573 {
574     TCppBuiltInTypeDefn(ID id = 0);
575
576     TCppBuiltInTypeType                m_type;
577     bool                                m_unsigned;
578     short                            m_byte_length;
579                                         // These data fields are not expected to be set directly. Use SetBuiltInTypeProps() method
580                                         // to set them up.
581 public:
582
583     void        SetBuiltInTypeProps(TCppBuiltInTypeIdent ident);
584
585     static const wchar_t    *GetBuiltInTypeFriendlyName(TCppBuiltInTypeIdent ident);
586     static const wchar_t    *GetBuiltInTypeTypeEnumName(TCppBuiltInTypeType val);
587 };
588
589 struct TCppBitFieldTypeDefn : public TCppDataTypeBase
590 {
591     TCppBitFieldTypeDefn(ID id = 0);
592     ~TCppBitFieldTypeDefn();
593             // These objects are created with generated names only. When this object is inserted into the defns
594             // space its base type should be a valid pointer to some integral type. Otherwise JPF will happen.
595
596             //
597             //  Note that bit field members can be specified as CONST/VOLATILE. These flags are stored in the base
598             //  type of the bit field type. To get these props of the data field the base type of the current object should
599             //  be checked.
600             //
601
602     TCppDataTypeBase                *m_base_type;                    // Base type can be only either integer or enum. The pointer is not owned.
603
604     short                            m_bit_length;                    // Bit length is a positive value. It cannot be zero. The value can be bigger than
605                                                                     // the bit size of the base type. In this case extra bits if any are used as padding
606                                                                     // and they do not increase the max possible value of the data field of this data
607                                                                     // type. When the value of the field is -1, this means that expression was not
608                                                                     // const or it was not numeric or its value was out of the reasonable range.
609     TCppExpressionBase                *m_bit_length_expr;                // Expression that was used to specify the bit length. When bit feild is used in
610                                                                     // the template code and expression is not constant no error is generated.
611                                                                     // Note that this pointer describes an owned child.
612 public:
613
614     virtual bool    CanHaveChildren() const { return(TRUE); }
615
616     virtual void    AddChildItem(TCppItemBase *item, int item_destination = -1);                //    Possible destination: cdefn_chdest_default.
617     virtual void    NewIndirectChildNotification(TCppItemBase *items_subtree_root) { if (m_cib_parent != NULL) m_cib_parent->NewIndirectChildNotification(items_subtree_root); }
618 };
619
620 struct TCppCvPtrRefTypeDefn : public TCppDataTypeBase
621 {
622     TCppCvPtrRefTypeDefn(ID id = 0);
623             // These objects can be have either a user defiend or a generated names. The base type should
624             // always be some valid non NULL pointer.
625
626     TCppDefnBase                    *m_base_type;                    //
627                                                                     // The pointer is not owned. It can be one of:
628                                                                     //
629                                                                     //      TCppDataTypeBase            or its derivatives;
630                                                                     //      TCppFunctionTypeBase        or its derivatives;
631                                                                     //
632     TCppCvPtrRefSpecsArray            m_layers;                        // The order of layers is the same to the order of stars in the source code.
633                                                                     // In other words, the layer[0] should be applied to the base type first.
634                                                                     // This order can also be called "from the base type to type of the variable".
635 };                                                                    //
636
637 struct TCppArrayTypeDefn : public TCppDataTypeBase
638 {
639     TCppArrayTypeDefn(ID id = 0);
640     ~TCppArrayTypeDefn();
641
642     TCppDataTypeBase                *m_base_type;                    // This pointer is not owned. Note that the base type is always a data type.
643                                                                     // It cannot be a function type.
644     TCppArrayDimensionsArray            m_dimensions;                    // The order of array elements in this data field is the same to the order of indexes
645                                                                     // in the source code where the array is being defined. When this type is constructed,
646                                                                     // dimensions should be added with the NULL expression subtree. The expr objects
647                                                                     // should be added later using the AddChildItem() method.
648 public:
649
650     virtual bool    CanHaveChildren() const { return(TRUE); }
651
652     virtual void    AddChildItem(TCppItemBase *item, int item_destination_layer_index = -1);
653     virtual void    NewIndirectChildNotification(TCppItemBase *items_subtree_root) { if (m_cib_parent != NULL) m_cib_parent->NewIndirectChildNotification(items_subtree_root); }
654 };
655
656 struct TCppDataTypeAliasDefn : public TCppDataTypeBase
657 {
658     TCppDataTypeAliasDefn(ID id = 0);
659             // When this object is added to the defns space the name and its non zero key_id should be set.
660
661     TCppDataTypeBase                *m_base_type;                    // The pointer is not owned.
662 };
663
664 // ---------------------------------------------------------------------------
665 //  - - (Defns2) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
666 // ---------------------------------------------------------------------------
667
668 struct TCppEnumTypeDefn : public TCppDataTypeBase
669 {
670     TCppEnumTypeDefn(ID id = 0);
671     ~TCppEnumTypeDefn();
672
673         //
674         //  When the m_defn_key_id field is zero this means that either this is nameless enum or that
675         //  there was a name collision and as a consequence the enum object got an alternative name.
676         //
677
678     bool                                m_defined;                        // This field shows if enum definition is already processed or only one or
679                                                                     // several possible forward declarations were noticed.
680     TCppDataTypeBase                *m_base_type;                    // For now the base type of enum can be only an integral type. This can be
681                                                                     // a built in type, CvPtrRef (with const and/or volatile) or the data type alias.
682     TList                                m_members;                    // Emun does not have its own hash table for its members because they are
683                                                                     // placed into the hash table of the containing named structure.
684 public:
685
686     int            GetNumEnumMembers() const;
687
688     virtual bool    CanHaveChildren() const { return(TRUE); }
689
690     virtual void    AddChildItem(TCppItemBase *item, int item_destination = -1);                //  Possible destination: cdefn_chdest_default.
691     virtual void    NewIndirectChildNotification(TCppItemBase *items_subtree_root) { if (m_cib_parent != NULL) m_cib_parent->NewIndirectChildNotification(items_subtree_root); }
692 };
693
694 struct TCppEnumMemberDefn : public TCppDefnBase
695 {
696     TCppEnumMemberDefn(ID id = 0);
697     ~TCppEnumMemberDefn();
698
699     bool                                m_const_value;                    // The value was expressed using const and numeric expression or the value
700                                                                     // was implicit. When the value of this field is TRUE, this also means that
701                                                                     // the m_value field is meaningful.
702     __int64                            m_value;
703     TLexNumberType                    m_value_num_subt;
704
705     TCppExpressionBase                *m_value_expr;                    // Expression that was used to specify the value. Value of this field is NULL when
706                                                                     // the value of the enum member is implicit.
707 public:
708
709     virtual bool    CanHaveChildren() const { return(TRUE); }
710
711     virtual void    AddChildItem(TCppItemBase *item, int item_destination = -1);                //  Possible destination: cdefn_chdest_default.
712     virtual void    NewIndirectChildNotification(TCppItemBase *items_subtree_root) { if (m_cib_parent != NULL) m_cib_parent->NewIndirectChildNotification(items_subtree_root); }
713 };
714
715 //
716 //  This is important structure. It describes classes, structures and unions. Note that structs/unions/classes
717 //  can be named and nameless.
718 //
719 struct TCppStructTypeDefn : public TCppDataTypeBase
720 {
721     TCppStructTypeDefn(ID id = 0);
722             // Note that this ctor sets an incorrect elaboration type. Correct elab type should be set up later.
723
724     ~TCppStructTypeDefn();
725             // Defns table does not need destruction.
726
727     void        SetupStructType(TCppElabType elab_type) { assert(elab_type != elab_none && elab_type != elab_enum); m_defn_elab_type = elab_type; }
728     void        SetupNamedParent(TCppStructTypeDefn *named_parent);
729     void        AddBaseClassesList(TList *base_classes_list);
730
731     bool                                m_defined;                        // This field shows if struct/union/class definition is already processed
732                                                                     // or just some number of forward declarations were noticed.
733     TList                                m_members;
734
735     TList                                m_assoc_defn_spaces;            // This list contains instances of TCppAssocDefnsSpaceRef and
736                                                                     // it is not owning its members.
737 public:
738
739     virtual bool        IsStructType() const { return(TRUE); }
740     bool                IsNamelessStruct() const { return(m_defn_key_id == 0); }
741     virtual bool        CanHaveChildren() const { return(TRUE); }
742
743     virtual void    AddChildItem(TCppItemBase *item, int item_destination = -1);
744     virtual void    NewIndirectChildNotification(TCppItemBase *items_subtree_root) { if (m_cib_parent != NULL) m_cib_parent->NewIndirectChildNotification(items_subtree_root); }
745
746     virtual TList    *GetNestedMembersList();
747
748     int                GetNumTemplateParams() const;
749     TCppDefnBase    *GetFirstTemplateParam() const;
750     TCppDefnBase    *GetNextTemplateParam(TCppDefnBase *param);
751                         // Methods for iterating template parameters are defined in this class because ClassTemplateSpecialization
752                         // class and ClassTemplateInstantiation are derived directly from the struct type class.
753 protected:
754
755     virtual TCppDefnsSpace        *GetNestedDefnsSpace();
756     virtual TList                *GetAssocDefnsSpaceRefsList() { return(&m_assoc_defn_spaces); }
757     virtual void                AddToNestedDefnsSpace(TCppDefnBase *defn_item, bool named_modifier_defn);
758 };
759
760 struct TCppBaseClassSpec : public TCppDefnBase
761 {
762     TCppBaseClassSpec(ID id = 0);
763             // The name of the base class is expected to be duplicated into the m_defn_name of the instance.
764             // Important: Elaboration of this object is always elab_none regardless of the nature (struct/union/class)
765             // of the base class itself. This is needed for proper work of the defns space search classes.
766
767     bool                                m_virtual;
768     TCppAccessLevel                    m_accs_level;
769     TCppStructTypeDefn                *m_base_class;                    // The pointer is not owned. In non template contexts this pointer can point to TCppStructTypeDefn,
770                                                                     // TCppClassTemplateInstantiation and TCppUnresolvedStructType. In the context of a template definition
771                                                                     // this can also be a TCppClassTemplateDefn.
772     TCppAssocDefnsSpaceRef            m_assoc_ref;
773 };
774
775 struct TCppFieldAlignSpec : public TCppItemBase
776 {
777     TCppFieldAlignSpec(ID id = 0);
778     ~TCppFieldAlignSpec();
779
780     short                            m_align_value;                    // Field alignment is a positive value or zero. When the value of this field is -1,
781                                                                     // this means that expression was not const or it was not numeric or its value
782                                                                     // was negative or the value was out of positive reasonable range.
783     TCppExpressionBase                *m_align_value_expr;            // Expression that was used to specify the align value. When align spec is used
784                                                                     // in the template code and expression is not constant no error is generated.
785                                                                     // Note that this pointer describes an owned child.
786 public:
787
788     virtual bool    CanHaveChildren() const { return(TRUE); }
789
790     virtual void    AddChildItem(TCppItemBase *item, int item_destination = -1);                //    Possible destination: cdefn_chdest_default.
791     virtual void    NewIndirectChildNotification(TCppItemBase *items_subtree_root) { if (m_cib_parent != NULL) m_cib_parent->NewIndirectChildNotification(items_subtree_root); }
792 };
793
794 struct TCppFriendSpec : public TCppItemBase
795 {
796     TCppFriendSpec(ID id = 0);
797
798     TCppDefnBase                    *m_friendly_object;                // The pointer is not owned. This pointer always points to the definition of the real object,
799                                                                     // that can be searched by its name, used for creating data fields if this is appropriate, etc.
800                                                                     // The friend can be one of: structure, class template, template specialization, template
801                                                                     // instantiation and 4 similar object types for function templates.
802 };
803
804 //
805 //  Data field describes location in the static memory, stack of the process or the heap memory.
806 //
807 struct TCppDataFieldDefn : public TCppDefnBase
808 {
809     TCppDataFieldDefn(ID id = 0);
810     ~TCppDataFieldDefn();
811
812     ID                                m_visibility_pars_sess;            // This data field has meaning only for data fields from the namespace layers. If the value of
813                                                                     // the field is not zero, this means that this data field is visible only inside this specific parsing
814                                                                     // session. In databases that describe only one parsing session, different data fields with zero
815                                                                     // and non zero values for a given name are not allowed. In multisession databases only one
816                                                                     // object for a given layer/name pair can have zero in this data field.
817     TCppLinkageSpec                    *m_linkage_spec;
818
819     TCppAccessLevel                    m_accs_level;
820     TCppStorageClass                    m_strg_class;
821
822     short                            m_param_index;                    // This field has meaning only when the strg_class field is equal either to strgc_param or to
823                                                                     // strgc_template_param. This is zero based index.
824     bool                                m_mutable;                        // This flag has meaning only for non static data members of the classes. It allows changing
825                                                                     // data field from member functions, that are declared as const.
826     TCppDataTypeBase                *m_field_type;
827
828     TCppItemBase                    *m_field_initializer;                // Initializer is an owned child. For function parameters this is a default value.
829                                                                     // Value of this field can only be either TCppDataFieldInitializer or some derivative
830                                                                     // from TCppExpressionBase.
831 public:
832
833     virtual bool    CanHaveChildren() const { return(TRUE); }
834
835     virtual void    AddChildItem(TCppItemBase *item, int item_destination = -1);
836     virtual void    NewIndirectChildNotification(TCppItemBase *items_subtree_root) { if (m_cib_parent != NULL) m_cib_parent->NewIndirectChildNotification(items_subtree_root); }
837
838     static const wchar_t    *GetAccessLevelFriendlyName(TCppAccessLevel accs);
839     static const wchar_t    *GetStorageClassFriendlyName(TCppStorageClass strgc);
840     static const wchar_t    *GetStorageClassEnumName(TCppStorageClass strgc);
841 };
842
843 struct TCppDataFieldInitializer : public TCppItemBase
844 {
845     TCppDataFieldInitializer(ID id = 0);
846     ~TCppDataFieldInitializer();
847             // By its nature the initializer is very close to the list of expressions. Nevertheless it is not derived from
848             // expression because it cannot be part of any expression. Plus deriving it from expression will require
849             // defining new type of operation since all expressions have something in their m_operation field.
850
851     TCppInitalizerType            m_init_type;
852     TList                        m_init_elements;                        // This list contains mixture of TCppDataFieldInitializer instances and
853                                                                     // derivatives form TCppExpressionBase.
854 public:
855
856     virtual bool    CanHaveChildren() const { return(TRUE); }
857
858     virtual void    AddChildItem(TCppItemBase *item, int item_destination = -1);
859     virtual void    NewIndirectChildNotification(TCppItemBase *items_subtree_root) { if (m_cib_parent != NULL) m_cib_parent->NewIndirectChildNotification(items_subtree_root); }
860
861     static const wchar_t    *GetInitializerTypeEnumName(TCppInitalizerType init_type);
862 };
863
864 // ---------------------------------------------------------------------------
865 //  - - (Defns3) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
866 // ---------------------------------------------------------------------------
867
868 struct TCppFunctionTypeDefn : public TCppFunctionTypeBase
869 {
870     TCppFunctionTypeDefn(ID id = 0);
871     ~TCppFunctionTypeDefn();
872             // Members of the list (parameters) are mapped into the names space of the function body.
873
874     ID                                m_visibility_pars_sess;            // This data field has meaning only for the namespace level functions. If the value of the field
875                                                                     // is not zero, this means that this function is visible only inside this specific parsing session.
876     TCppLinkageSpec                    *m_linkage_spec;
877
878     TCppAccessLevel                    m_accs_level;
879     TCppFunctionAttr                    m_func_attrs;
880
881     TCppSpecFuncType                m_spec_type;
882     TOperatorToken                    m_operator_token;                // This field has meaning only if m_spec_type == spcft_operator.
883     TCppDataTypeBase                *m_return_value_type;            // The pointer is not owned. This field has meaning for all functions and methods that can
884                                                                     // return value and also when m_spec_type == spcft_typecast.
885
886     TList                                m_members;                    // Members of this list can be: parameters and possible exception specs. Note that derived
887                                                                     // classes store other objects in this list like the body of the function and/or parameters of
888                                                                     // the function template.
889     virtual bool        IsFunctionName() const { return(TRUE); }
890     virtual bool        CanHaveChildren() const { return(TRUE); }
891
892 public:
893
894     static bool            IsParamItem(TCppItemBase *item);
895
896     int                    GetNumParams() const;
897     TCppDataFieldDefn        *GetFirstParam() const;
898     TCppDataFieldDefn        *GetNextParam(TCppDataFieldDefn *param) const;
899
900     int                            GetNumThrowSpecs() const;
901     TCppPossibleExceptionSpec        *GetFirstThrowSpec() const;
902     TCppPossibleExceptionSpec        *GetNextThrowSpec(TCppPossibleExceptionSpec *curr_throw_spec) const;
903
904     virtual void    AddChildItem(TCppItemBase *item, int item_destination = -1);
905     virtual void    NewIndirectChildNotification(TCppItemBase *items_subtree_root) { if (m_cib_parent != NULL) m_cib_parent->NewIndirectChildNotification(items_subtree_root); }
906
907     static const wchar_t    *GetSpecFuncTypeEnumName(TCppSpecFuncType spcft);
908 };
909
910 struct TCppFunctionTypeAliasDefn : public TCppFunctionTypeBase
911 {
912     TCppFunctionTypeAliasDefn(ID id = 0);
913
914     TCppFunctionTypeBase                *m_base_type;                    // The pointer is not owned.
915 };
916
917 //
918 //  Code entry point describes some function or method of the class.
919 //
920 struct TCppCodeEntryPointDefn : public TCppFunctionTypeDefn
921 {
922     TCppCodeEntryPointDefn(ID id = 0);
923
924     TCppBlockDefn                    *m_function_body;                // This is pointer into the list of members that is defined in the base class.
925                                                                     // Note that this field can point either to a simple block or to a try block.
926                                                                     // When objects represents the function prototype, the value of this field is NULL.
927     virtual bool        IsFunctionFamily() const { return(TRUE); }
928 };
929
930 struct TCppPossibleExceptionSpec : public TCppItemBase
931 {
932     TCppPossibleExceptionSpec(ID id = 0);
933
934     TCppDataTypeBase                *m_exception_type;                // The pointer is not owned. In fact, this pointer can be NULL. This case represents
935                                                                     // situation when the list of possible exceptions is present and it is empty. Such empty
936                                                                     // list is described by an exceptions spec object with a NULL in its data field.
937 };
938
939 // ---------------------------------------------------------------------------
940 //  - - (Defns4) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
941 // ---------------------------------------------------------------------------
942
943 struct TCppNamespaceDefn : public TCppDefnBase
944 {
945     TCppNamespaceDefn(ID id = 0);
946             // Note that namespaces can be named and nameless.
947
948     ~TCppNamespaceDefn();
949             // Defns table does not need destruction.
950
951     TList                                m_members;
952
953     TList                                m_assoc_defn_spaces;            // This list contains instances of TCppAssocDefnsSpaceRef and
954                                                                     // it is not owning its members.
955 public:
956
957     virtual bool    IsNamespace() const { return(TRUE); }
958     virtual bool    CanHaveChildren() const { return(TRUE); }
959
960     virtual void    AddChildItem(TCppItemBase *item, int item_destination = -1);
961     virtual void    NewIndirectChildNotification(TCppItemBase *items_subtree_root) { if (m_cib_parent != NULL) m_cib_parent->NewIndirectChildNotification(items_subtree_root); }
962
963     virtual TList    *GetNestedMembersList();
964
965 protected:
966
967     virtual TCppDefnsSpace        *GetNestedDefnsSpace();
968     virtual TList                *GetAssocDefnsSpaceRefsList() { return(&m_assoc_defn_spaces); }
969     virtual void                AddToNestedDefnsSpace(TCppDefnBase *defn_item, bool named_modifier_defn);
970 };
971
972 struct TCppGlobalNamespaceDefn : public TCppDefnBase
973 {
974     TCppGlobalNamespaceDefn(ID id = 0);
975             // Global namespace does not have any name. In typical scenario it is never created
976             // using the cpp items factory. It is data field of the cpp database object.
977
978     ~TCppGlobalNamespaceDefn();
979             // Defns table does not need destruction.
980
981     TList                                m_members;
982
983     TList                                m_assoc_defn_spaces;            // This list contains instances of TCppAssocDefnsSpaceRef and
984                                                                     // it is not owning its members.
985 public:
986
987     virtual bool    IsNamespace() const { return(TRUE); }
988     virtual bool    CanHaveChildren() const { return(TRUE); }
989
990     virtual void    AddChildItem(TCppItemBase *item, int item_destination = -1);
991     virtual void    NewIndirectChildNotification(TCppItemBase *items_subtree_root);
992
993     virtual TList    *GetNestedMembersList();
994
995 protected:
996
997     void            Clear();
998
999     virtual TCppDefnsSpace        *GetNestedDefnsSpace();
1000     virtual TList                *GetAssocDefnsSpaceRefsList() { return(&m_assoc_defn_spaces); }
1001     virtual void                AddToNestedDefnsSpace(TCppDefnBase *defn_item, bool named_modifier_defn);
1002 };
1003
1004 struct TCppNamespaceAliasDefn : public TCppDefnBase
1005 {
1006     TCppNamespaceAliasDefn(ID id = 0);
1007
1008     TCppNamespaceDefn                *m_base_namespace;            // The pointer is not owned. The value of the field is NULL when
1009                                                                     // the name of the namespace was not resolved.
1010 };
1011
1012 struct TCppUsingDeclarationDefn : public TCppDefnBase
1013 {
1014     TCppUsingDeclarationDefn(ID id = 0);
1015
1016     TCppDefnBase                    *m_defn_to_use;                // The pointer is not owned.
1017 };
1018
1019 struct TCppUsingDirectiveDefn : public TCppDefnBase
1020 {
1021     TCppUsingDirectiveDefn(ID id = 0);
1022
1023     bool                                m_use_global_namespace;        // This flag is needed because the global namespace is defined with
1024                                                                     // a different  cpp class, not the same to a user defined namespace.
1025     TCppNamespaceDefn                *m_namespace_to_use;            // The pointer is not owned. The value of the field is NULL when "use
1026                                                                     // namespace" directive is not pointing to an existing namespace.
1027     TCppAssocDefnsSpaceRef            m_assoc_ref;
1028 };
1029
1030 struct TCppAsmInsertDefn : public TCppDefnBase
1031 {
1032     TCppAsmInsertDefn(ID id = 0);
1033
1034     TStrPtrInfo                        m_asm_insert;                    // The string is not owned by the object. The field has TStrPtrInfo type
1035                                                                     // because the string may contain NULL characters inside it.
1036 };
1037
1038 struct TCppLinkageSpec : public TCppItemBase
1039 {
1040     TCppLinkageSpec(ID id = 0);
1041
1042     wchar_t                            *m_spec_name;                    // Note that the string is not owned.
1043     ID                                m_spec_key_id;
1044     int                                m_spec_cnt_use;
1045
1046 public:
1047
1048     static bool    CompareLinkageSpecs(const TCppLinkageSpec *spec1, const TCppLinkageSpec *spec2);
1049                     // This method allows passing NULL specs. Two NULL specs are compatible.
1050 };
1051
1052 // ---------------------------------------------------------------------------
1053 //  - - (Templates) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1054 // ---------------------------------------------------------------------------
1055
1056 struct TCppClassTemplateDefn : public TCppStructTypeDefn
1057 {
1058     TCppClassTemplateDefn(ID id = 0);
1059                 // Template parameters are added into the list of the struct type members. They can be distinguished
1060                 // from other members of this list by their object types for type params and template params and by
1061                 // their storage class (strgc_template_param) for data params.
1062
1063     //
1064     //  Important: Elaboration of this object (also the class template spex and the class template inst) should always be
1065     //  non empty. This is needed for proper work of the defns space search classes.
1066     //
1067
1068     virtual bool    IsDataType(bool template_context) const { return(template_context); }
1069     virtual bool    IsClassTemplateFamily() const { return(TRUE); }
1070
1071     //
1072     //  Note that struct type contains methods for iterating template parameters like GetFirstTemplateParam(),
1073     //  GetNextTemplateParam(), etc. These methods are not defined here because template specialization and
1074     //  template instantiation are derived directly from the struct type.
1075     //
1076 };
1077
1078 struct TCppClassTemplateSpecialization : public TCppStructTypeDefn
1079 {
1080     TCppClassTemplateSpecialization(ID id = 0);
1081     ~TCppClassTemplateSpecialization();
1082
1083     TCppClassTemplateDefn            *m_base_template;                // The pointer is not owned.
1084     TList                                m_specialization_params;
1085
1086 public:
1087
1088     virtual bool    IsDataType(bool template_context) const { return(FALSE); }
1089     virtual bool    IsClassTemplateFamily() const { return(TRUE); }
1090     virtual bool    CanHaveChildren() const { return(TRUE); }
1091
1092     virtual void    AddChildItem(TCppItemBase *item, int item_destination = -1);
1093     virtual void    NewIndirectChildNotification(TCppItemBase *items_subtree_root) { if (m_cib_parent != NULL) m_cib_parent->NewIndirectChildNotification(items_subtree_root); }
1094 };
1095
1096 struct TCppClassTemplateInstantiation : public TCppStructTypeDefn
1097 {
1098     TCppClassTemplateInstantiation(ID id = 0);
1099     ~TCppClassTemplateInstantiation();
1100             // Note that template instantiation cannot be a forward declaration.
1101
1102     TCppClassTemplateDefn            *m_original_template;            // The pointer is not owned.
1103     TList                                m_instantiation_arguments;
1104
1105 public:
1106
1107     virtual bool    IsClassTemplateFamily() const { return(TRUE); }
1108     virtual bool    CanHaveChildren() const { return(TRUE); }
1109
1110     virtual void    AddChildItem(TCppItemBase *item, int item_destination = -1);                // Possible destinations: cdefn_chdest_cltplt_iprm, cdefn_chdest_default.
1111     virtual void    NewIndirectChildNotification(TCppItemBase *items_subtree_root) { if (m_cib_parent != NULL) m_cib_parent->NewIndirectChildNotification(items_subtree_root); }
1112 };
1113
1114 struct TCppFunctionTemplateDefn : public TCppCodeEntryPointDefn
1115 {
1116     TCppFunctionTemplateDefn(ID id = 0);
1117                 // Template parameters are added into the list of the function type members. They can be distinguished
1118                 // from other members of this list by their object types for type params and template params and by
1119                 // their storage class (strgc_template_param) for data params.
1120
1121     virtual bool    IsFunctionType(bool template_context) const { return(template_context); }
1122
1123     //
1124     //  Note that code entry point type contains methods for template params iteration like GetFirstTemplateParam(),
1125     //  GetNextTemplateParam(), etc. These methods are not defined in this class because func template specialization
1126     //  and function template instantiation classes are derived directly from the code entry point class.
1127     //
1128 };
1129
1130 struct TCppFunctionTemplateSpecialization : public TCppCodeEntryPointDefn
1131 {
1132     TCppFunctionTemplateSpecialization(ID id = 0);
1133     ~TCppFunctionTemplateSpecialization();
1134
1135     TCppFunctionTemplateDefn            *m_base_template;                // The pointer is not owned.
1136     TList                                m_specialization_params;
1137
1138 public:
1139
1140     virtual bool    IsFunctionType(bool template_context) const { return(FALSE); }
1141     virtual bool    CanHaveChildren() const { return(TRUE); }
1142
1143     virtual void    AddChildItem(TCppItemBase *item, int item_destination = -1);
1144     virtual void    NewIndirectChildNotification(TCppItemBase *items_subtree_root) { if (m_cib_parent != NULL) m_cib_parent->NewIndirectChildNotification(items_subtree_root); }
1145 };
1146
1147 struct TCppFunctionTemplateInstantiation : public TCppCodeEntryPointDefn
1148 {
1149     TCppFunctionTemplateInstantiation(ID id = 0);
1150     ~TCppFunctionTemplateInstantiation();
1151
1152     TCppFunctionTemplateDefn            *m_original_template;            // The pointer is not owned.
1153     TList                                m_instantiation_arguments;
1154
1155 public:
1156
1157     virtual bool    CanHaveChildren() const { return(TRUE); }
1158
1159     virtual void    AddChildItem(TCppItemBase *item, int item_destination = -1);
1160     virtual void    NewIndirectChildNotification(TCppItemBase *items_subtree_root) { if (m_cib_parent != NULL) m_cib_parent->NewIndirectChildNotification(items_subtree_root); }
1161 };
1162
1163 struct TCppTemplateTypeParamDefn : public TCppDataTypeBase
1164 {
1165     TCppTemplateTypeParamDefn(ID id = 0);
1166             // Note that the type parameter itself does not have any properties.
1167
1168     short                            m_param_index;
1169     TCppDataTypeBase                *m_default_value;                // The pointer can be NULL and it is not owned.
1170 };
1171
1172 struct TCppTemplateTemplateParamDefn : public TCppDefnBase
1173 {
1174     TCppTemplateTemplateParamDefn(ID id = 0);
1175     ~TCppTemplateTemplateParamDefn();
1176
1177     short                            m_param_index;
1178     TList                                m_template_params;
1179     TCppClassTemplateDefn            *m_default_value;                // The pointer can be NULL and it is not owned.
1180
1181 public:
1182
1183     virtual bool    CanHaveChildren() const { return(TRUE); }
1184
1185     virtual void    AddChildItem(TCppItemBase *item, int item_destination = -1);
1186     virtual void    NewIndirectChildNotification(TCppItemBase *items_subtree_root) { if (m_cib_parent != NULL) m_cib_parent->NewIndirectChildNotification(items_subtree_root); }
1187 };
1188
1189 struct TCppTemplateTypeArgument : public TCppItemBase
1190 {
1191     TCppTemplateTypeArgument(ID id = 0);
1192
1193     TCppDataTypeBase                *m_argument_value;                // The pointer is not owned.
1194 };
1195
1196 struct TCppTemplateTemplateArgument : public TCppItemBase
1197 {
1198     TCppTemplateTemplateArgument(ID id = 0);
1199
1200     enum TCppTemplTemplArgType
1201     {
1202         ctarg_none,
1203         ctarg_template_defn,
1204         ctarg_template_template_param,
1205         ctarg_class_templates_bucket,
1206         ctarg_num_types,
1207     };
1208
1209     TCppTemplTemplArgType            m_arg_type;
1210
1211     union
1212     {
1213         TCppClassTemplateDefn            *m_argument_value;            // Option for "ctarg_template_defn". This is either a resolved class template definition or
1214                                                                     // an unresolved class template object. The pointer is not owned.
1215         TCppTemplateTemplateParamDefn    *m_template_param;        // Option for "ctarg_template_template_param". This is pointer to the object in the template
1216                                                                     // header. This value cannot be present in the in the args list of the full template instantiation.
1217                                                                     // It is used while scanning template ids. The pointer is not owned.
1218         TCppDefnBase                    *m_search_res_single_defn;
1219     };
1220
1221     const wchar_t            *GetReferencedDefnName();
1222     static const wchar_t    *GetArgTypeEnumName(TCppTemplTemplArgType ctarg);
1223 };
1224
1225 // ---------------------------------------------------------------------------
1226 //  - - (Unresolved) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1227 // ---------------------------------------------------------------------------
1228
1229 struct TCppUnresolvedNameInfo : public TCppDefnBase
1230 {
1231     TCppUnresolvedNameInfo(ID id = 0);
1232     ~TCppUnresolvedNameInfo();
1233
1234     TCppNameInfoType                m_node_type;                    // Note that the key_id for name, template id and destructor is stored in m_defn_key_id
1235                                                                     // data field of the base class.
1236     TOperatorToken                    m_operator_token;                // Token of the overloaded operator.
1237     TCppDataTypeBase                *m_conversion_dest_type;        // Type of the overloaded conversion destination. The pointer is not owned.
1238
1239     TList                                m_template_id_args;            // This list can contain: TCppTemplateTypeArgument, TCppTemplateTemplateArgument
1240                                                                     // and a derivatife of the TCppExpressionBase.
1241 public:
1242
1243     virtual bool    CanHaveChildren() const { return(TRUE); }
1244
1245     virtual void    AddChildItem(TCppItemBase *item, int item_destination = -1);
1246     virtual void    NewIndirectChildNotification(TCppItemBase *items_subtree_root) { if (m_cib_parent != NULL) m_cib_parent->NewIndirectChildNotification(items_subtree_root); }
1247
1248 protected:
1249
1250     static bool    CompareNameInfoSequencies(TList *list1, TList *list2);
1251     static bool    CompareNameInfoInstances(TCppUnresolvedNameInfo *obj1, TCppUnresolvedNameInfo *obj2);
1252     static bool    CompareNameInfoTemplateArgLists(TList &list1, TList &list2);
1253
1254     DWORD            GetHashValue();
1255     static DWORD        GetHashValueForNamesSeq(TList *unres_names_list);
1256 };
1257
1258 struct TCppUnresolvedDataType : public TCppDataTypeBase
1259 {
1260     TCppUnresolvedDataType(ID id = 0);
1261     ~TCppUnresolvedDataType();
1262
1263     TList                                m_name_elements;
1264                                         // List of TCppUnresolvedNameInfo objects. In a regular case this list should be not empty.
1265 public:
1266
1267     virtual bool    IsUnresolvedObject() const { return(TRUE); }
1268     virtual bool    CanHaveChildren() const { return(TRUE); }
1269
1270     virtual TList    *GetUnresolvedNamesList();
1271
1272     virtual void    AddChildItem(TCppItemBase *item, int item_destination = -1);                //    Possible destination: cdefn_chdest_default.
1273     virtual void    NewIndirectChildNotification(TCppItemBase *items_subtree_root) { if (m_cib_parent != NULL) m_cib_parent->NewIndirectChildNotification(items_subtree_root); }
1274 };
1275
1276 //
1277 // Typical elaboration for this type is elab_none.
1278 //
1279 struct TCppUnresolvedStructType : public TCppStructTypeDefn
1280 {
1281     TCppUnresolvedStructType(ID id = 0);
1282     ~TCppUnresolvedStructType();
1283
1284     TList                                m_name_elements;
1285                                         // List of TCppUnresolvedNameInfo objects. In a regular case this list should be not empty.
1286 public:
1287
1288     virtual bool    IsUnresolvedObject() const { return(TRUE); }
1289     virtual bool    CanHaveChildren() const { return(TRUE); }
1290
1291     virtual TList    *GetUnresolvedNamesList();
1292
1293     virtual void    AddChildItem(TCppItemBase *item, int item_destination = -1);                //    Possible destination: cdefn_chdest_default.
1294     virtual void    NewIndirectChildNotification(TCppItemBase *items_subtree_root) { if (m_cib_parent != NULL) m_cib_parent->NewIndirectChildNotification(items_subtree_root); }
1295 };
1296
1297 struct TCppUnresolvedDataField : public TCppDataFieldDefn
1298 {
1299     TCppUnresolvedDataField(ID id = 0);
1300     ~TCppUnresolvedDataField();
1301
1302     TList                                m_name_elements;
1303                                         // List of TCppUnresolvedNameInfo objects. In a regular case this list should be not empty.
1304 public:
1305
1306     virtual bool    IsUnresolvedObject() const { return(TRUE); }
1307     virtual bool    CanHaveChildren() const { return(TRUE); }
1308
1309     virtual TList    *GetUnresolvedNamesList();
1310
1311     virtual void    AddChildItem(TCppItemBase *item, int item_destination = -1);                //    Possible destination: cdefn_chdest_default.
1312     virtual void    NewIndirectChildNotification(TCppItemBase *items_subtree_root) { if (m_cib_parent != NULL) m_cib_parent->NewIndirectChildNotification(items_subtree_root); }
1313 };
1314
1315 struct TCppUnresolvedCodeEntryPoint : public TCppCodeEntryPointDefn
1316 {
1317     TCppUnresolvedCodeEntryPoint(ID id = 0);
1318     ~TCppUnresolvedCodeEntryPoint();
1319
1320     TList                                m_name_elements;
1321                                         // List of TCppUnresolvedNameInfo objects. In a regular case this list should be not empty.
1322 public:
1323
1324     virtual bool    IsFunctionFamily() const { return(FALSE); }
1325     virtual bool    IsUnresolvedObject() const { return(TRUE); }
1326     virtual bool    CanHaveChildren() const { return(TRUE); }
1327
1328     virtual TList    *GetUnresolvedNamesList();
1329
1330     virtual void    AddChildItem(TCppItemBase *item, int item_destination = -1);                //    Possible destination: cdefn_chdest_default.
1331     virtual void    NewIndirectChildNotification(TCppItemBase *items_subtree_root) { if (m_cib_parent != NULL) m_cib_parent->NewIndirectChildNotification(items_subtree_root); }
1332 };
1333
1334 struct TCppUnresolvedClassTemplate : public TCppClassTemplateDefn
1335 {
1336     TCppUnresolvedClassTemplate(ID id = 0);
1337     ~TCppUnresolvedClassTemplate();
1338
1339     TList                                m_name_elements;
1340                                         // List of TCppUnresolvedNameInfo objects. In a regular case this list should be not empty.
1341 public:
1342
1343     virtual bool    IsUnresolvedObject() const { return(TRUE); }
1344     virtual bool    CanHaveChildren() const { return(TRUE); }
1345
1346     virtual TList    *GetUnresolvedNamesList();
1347
1348     virtual void    AddChildItem(TCppItemBase *item, int item_destination = -1);                //    Possible destination: cdefn_chdest_default.
1349     virtual void    NewIndirectChildNotification(TCppItemBase *items_subtree_root) { if (m_cib_parent != NULL) m_cib_parent->NewIndirectChildNotification(items_subtree_root); }
1350 };
1351
1352 struct TCppUnresolvedFunctionTemplate : public TCppFunctionTemplateDefn
1353 {
1354     TCppUnresolvedFunctionTemplate(ID id = 0);
1355     ~TCppUnresolvedFunctionTemplate();
1356
1357     TList                                m_name_elements;
1358                                         // List of TCppUnresolvedNameInfo objects. In a regular case this list should be not empty.
1359 public:
1360
1361     virtual bool    IsUnresolvedObject() const { return(TRUE); }
1362     virtual bool    CanHaveChildren() const { return(TRUE); }
1363
1364     virtual TList    *GetUnresolvedNamesList();
1365
1366     virtual void    AddChildItem(TCppItemBase *item, int item_destination = -1);                //    Possible destination: cdefn_chdest_default.
1367     virtual void    NewIndirectChildNotification(TCppItemBase *items_subtree_root) { if (m_cib_parent != NULL) m_cib_parent->NewIndirectChildNotification(items_subtree_root); }
1368 };
1369
1370 // ---------------------------------------------------------------------------
1371 //  - - (Stmts1) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1372 // ---------------------------------------------------------------------------
1373
1374 struct TCppEmptyStatement : public TCppStatementBase
1375 {
1376     TCppEmptyStatement(ID id = 0);
1377 };
1378
1379 struct TCppIfStatement : public TCppStatementBase
1380 {
1381     TCppIfStatement(ID id = 0);
1382     ~TCppIfStatement();
1383
1384     TCppStatementBase                *m_if_condition;                    // This can be either definition of ONE variable (with initializer) or an expression.
1385                                                                     // When condition introduces a variable, the whole statement is wrapped inyo a block.
1386     TCppStatementBase                *m_then_statement;
1387     TCppStatementBase                *m_else_statement;
1388
1389     inline bool    HasThenPart() const { return(m_then_statement != NULL && m_then_statement->ItemType() != cxx_empty_stmt); }
1390     inline bool    HasElsePart() const { return(m_else_statement != NULL && m_else_statement->ItemType() != cxx_empty_stmt); }
1391
1392 public:
1393
1394     virtual bool    CanHaveChildren() const { return(TRUE); }
1395
1396     virtual void    AddChildItem(TCppItemBase *item, int item_destination = -1);
1397                     // Possible destinations: cstmt_chdest_if_cond, cstmt_chdest_if_then, cstmt_chdest_if_else.
1398
1399     virtual void    NewIndirectChildNotification(TCppItemBase *items_subtree_root) { if (m_cib_parent != NULL) m_cib_parent->NewIndirectChildNotification(items_subtree_root); }
1400 };
1401
1402 struct TCppSwitchStatement : public TCppStatementBase
1403 {
1404     TCppSwitchStatement(ID id = 0);
1405     ~TCppSwitchStatement();
1406
1407     TCppStatementBase                *m_condition;                    // This can be either definition of ONE variable (with initializer) or an expression.
1408                                                                     // When condition introduces a variable, the whole statement is wrapped into a block.
1409     TCppStatementBase                *m_statement;                    // In typical case this will be the block statement.
1410
1411 public:
1412
1413     virtual bool    CanHaveChildren() const { return(TRUE); }
1414
1415     virtual void    AddChildItem(TCppItemBase *item, int item_destination = -1);
1416     virtual void    NewIndirectChildNotification(TCppItemBase *items_subtree_root) { if (m_cib_parent != NULL) m_cib_parent->NewIndirectChildNotification(items_subtree_root); }
1417
1418     int            NumCaseLabels() const;
1419 };
1420
1421 struct TCppForStatement : public TCppStatementBase
1422 {
1423     TCppForStatement(ID id = 0);
1424     ~TCppForStatement();
1425
1426     TCppStatementBase                *m_init_statement;                // This can be definition of ONE variable, defenition of SEVERAL vars (all these variables
1427                                                                     // should have the same base type) or simply an expression.
1428     TCppStatementBase                *m_check_continue;                // Continue check may contain definition of ONE variable. This is extremely rare but
1429                                                                     // standard and compilers allow this. This is why the type of this field is statement,
1430                                                                     // not an expression.
1431     TCppStatementBase                *m_reinit_expression;            // This is either an empty statement or a non empty expression. Since this class library
1432                                                                     // does not have empty expression class (only an empty statement is available), the type
1433                                                                     // of this field is statement, not an expression.
1434     TCppStatementBase                *m_body_statement;                // Body of the loop. This is real or empty statement.
1435
1436 public:
1437
1438     virtual bool    CanHaveChildren() const { return(TRUE); }
1439
1440     virtual void    AddChildItem(TCppItemBase *item, int item_destination = -1);
1441     virtual void    NewIndirectChildNotification(TCppItemBase *items_subtree_root) { if (m_cib_parent != NULL) m_cib_parent->NewIndirectChildNotification(items_subtree_root); }
1442 };
1443
1444 struct TCppWhileStatement : public TCppStatementBase
1445 {
1446     TCppWhileStatement(ID id = 0);
1447     ~TCppWhileStatement();
1448
1449     TCppStatementBase                *m_while_condition;                // Note that condition may contain definition of ONE variable. This is why the type
1450                                                                     // of this field is statement, not an expression.
1451     TCppStatementBase                *m_body_statement;                // Body of the loop.
1452
1453 public:
1454
1455     virtual bool    CanHaveChildren() const { return(TRUE); }
1456
1457     virtual void    AddChildItem(TCppItemBase *item, int item_destination = -1);
1458     virtual void    NewIndirectChildNotification(TCppItemBase *items_subtree_root) { if (m_cib_parent != NULL) m_cib_parent->NewIndirectChildNotification(items_subtree_root); }
1459 };
1460
1461 struct TCppDoWhileStatement : public TCppStatementBase
1462 {
1463     TCppDoWhileStatement(ID id = 0);
1464     ~TCppDoWhileStatement();
1465
1466     TCppStatementBase                *m_body_statement;
1467     TCppExpressionBase                *m_do_while_expression;
1468
1469 public:
1470
1471     virtual bool    CanHaveChildren() const { return(TRUE); }
1472
1473     virtual void    AddChildItem(TCppItemBase *item, int item_destination = -1);
1474     virtual void    NewIndirectChildNotification(TCppItemBase *items_subtree_root) { if (m_cib_parent != NULL) m_cib_parent->NewIndirectChildNotification(items_subtree_root); }
1475 };
1476
1477 struct TCppGotoStatement : public TCppStatementBase
1478 {
1479     TCppGotoStatement(ID id = 0);
1480
1481     TCppLabelDefn                    *m_label;                        // The pointer to the label is not owned. Each label always has its own definition.
1482                                                                     // When the GOTO statement jumps to an undefined label, the compiler places this
1483                                                                     // label at the end of the function and issues an error message.
1484 };
1485
1486 struct TCppBreakStatement : public TCppStatementBase
1487 {
1488     TCppBreakStatement(ID id = 0);
1489 };
1490
1491 struct TCppContinueStatement : public TCppStatementBase
1492 {
1493     TCppContinueStatement(ID id = 0);
1494 };
1495
1496 struct TCppReturnStatement : public TCppStatementBase
1497 {
1498     TCppReturnStatement(ID id = 0);
1499     ~TCppReturnStatement();
1500
1501     TCppExpressionBase                *m_return_value;                // This is an expression that computes a return value.
1502
1503 public:
1504
1505     virtual bool    CanHaveChildren() const { return(TRUE); }
1506
1507     virtual void    AddChildItem(TCppItemBase *item, int item_destination = -1);
1508     virtual void    NewIndirectChildNotification(TCppItemBase *items_subtree_root) { if (m_cib_parent != NULL) m_cib_parent->NewIndirectChildNotification(items_subtree_root); }
1509 };
1510
1511 // ---------------------------------------------------------------------------
1512 //  - - (Stmts2) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1513 // ---------------------------------------------------------------------------
1514
1515 struct TCppBlockDefn : public TCppDefnBase
1516 {
1517     TCppBlockDefn(ID id = 0);
1518     ~TCppBlockDefn();
1519
1520     TList                                m_members;
1521
1522     TList                                m_assoc_defn_spaces;            // This list contains instances of TCppAssocDefnsSpaceRef and
1523                                                                     // it is not owning its members.
1524 public:
1525
1526     virtual bool    IsBlock() const { return(TRUE); }
1527     virtual bool    CanHaveChildren() const { return(TRUE); }
1528
1529     virtual void    AddChildItem(TCppItemBase *item, int item_destination = -1);
1530     virtual void    NewIndirectChildNotification(TCppItemBase *items_subtree_root) { if (m_cib_parent != NULL) m_cib_parent->NewIndirectChildNotification(items_subtree_root); }
1531
1532     virtual TList    *GetNestedMembersList();
1533
1534 protected:
1535
1536     virtual TCppDefnsSpace        *GetNestedDefnsSpace();
1537     virtual TList                *GetAssocDefnsSpaceRefsList() { return(&m_assoc_defn_spaces); }
1538     virtual void                AddToNestedDefnsSpace(TCppDefnBase *defn_item, bool named_modifier_defn);
1539 };
1540
1541 struct TCppTryBlockDefn : public TCppBlockDefn
1542 {
1543     TCppTryBlockDefn(ID id = 0);
1544             // The only difference between the simple block and the TRY block is the type of the object.
1545 };
1546
1547 struct TCppCatchBlockDefn : public TCppBlockDefn
1548 {
1549     TCppCatchBlockDefn(ID id = 0);
1550
1551     TCppDataFieldDefn                    *m_exception;                    // This pointer points into the list of members of the TCppBlockDefn class.
1552                                                                     // The object under this pointer is not owned.
1553 };
1554
1555 struct TCppLightBlockDefn : public TCppStatementBase
1556 {
1557     TCppLightBlockDefn(ID id = 0);
1558     ~TCppLightBlockDefn();
1559
1560     TList                                m_members;
1561
1562 public:
1563
1564     virtual bool    CanHaveChildren() const { return(TRUE); }
1565
1566     virtual void    AddChildItem(TCppItemBase *item, int item_destination = -1);
1567                     // Note that child item can be either appended or prepended depending on the value of the destination param.
1568
1569     virtual void    NewIndirectChildNotification(TCppItemBase *items_subtree_root) { if (m_cib_parent != NULL) m_cib_parent->NewIndirectChildNotification(items_subtree_root); }
1570 };
1571
1572 struct TCppLabelDefn : public TCppDefnBase
1573 {
1574     TCppLabelDefn(ID id = 0);
1575                 // Note that names of the labels constitute their own space of names inside each function body. Cpp standard
1576                 // explicitly states that it is ok to create variables and labels with the same names in the same context.
1577                 // Parser guarantees that all labels in the function have different names. In the case of the names collision label
1578                 // with an alternative name is created.
1579
1580     bool                                m_defined;
1581 };
1582
1583 struct TCppCaseLabelDefn : public TCppDefnBase
1584 {
1585     TCppCaseLabelDefn(ID id = 0);
1586     ~TCppCaseLabelDefn();
1587                 // Parser does not guarantee that case labels in the structured code will have different values. In case of
1588                 // the case lable values duplication or when case label stays outside of the SWITCH statement, the parser
1589                 // generates syntax error and places the case label whereever it is with its value as specified.
1590
1591     bool                                m_default;
1592
1593     bool                                m_const_value;                    // When the value of this field is TRUE, this means that the value of the label
1594                                                                     // was expressed using constant and numeric expression. This also means that
1595                                                                     // the m_value field is meaningful.
1596     __int64                            m_value;
1597
1598     TCppExpressionBase                *m_value_expr;                    // Expression that was used to specify the value. When case label is used in
1599                                                                     // the template code and expression is not constant no error is generated.
1600 public:
1601
1602     virtual bool    CanHaveChildren() const { return(TRUE); }
1603
1604     virtual void    AddChildItem(TCppItemBase *item, int item_destination = -1);                //    Possible destination: cstmt_chdest_default.
1605     virtual void    NewIndirectChildNotification(TCppItemBase *items_subtree_root) { if (m_cib_parent != NULL) m_cib_parent->NewIndirectChildNotification(items_subtree_root); }
1606 };
1607
1608 // ---------------------------------------------------------------------------
1609 //  - - (Exprs1) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1610 // ---------------------------------------------------------------------------
1611
1612 enum TCppExprOperandType
1613 {
1614     eopr_none,
1615
1616     eopr_bool_literal,
1617     eopr_num_literal,
1618     eopr_charconst_literal,
1619     eopr_string_literal,
1620     eopr_enum_literal,
1621
1622     eopr_this,
1623     eopr_base_class,
1624
1625     eopr_data_field,                    // Data field that can range from a simple integer to a complex class.
1626     eopr_code_entry_point,            // Function can range from a simple function to a user defined typecast.
1627
1628     eopr_ovld_defns_bucket,            // Bucket of overloaded definitions. This is transient operand type that
1629                                     // can exist only during the parsing process.
1630     eopr_num_types,
1631 };
1632
1633 struct TCppOperandExpr : public TCppExpressionBase
1634 {
1635 protected:    
1636     
1637     TCppExprOperandType     m_oprnd_type;
1638
1639     union
1640     {
1641         struct
1642         {
1643             bool                    m_bool_value;
1644         };
1645
1646         struct
1647         {
1648             TLexNumberType        m_num_subt;
1649             __int64                m_num_value;
1650         };
1651
1652         struct
1653         {
1654             TLexCharConstType    m_charconst_subt;
1655             __int64                m_charconst_value;
1656         };
1657
1658         struct
1659         {
1660             TLexStringType        m_string_subt;
1661             TStrPtrInfo            m_string_value;                        // The string is not owned by the object. Pointer in this field always points
1662                                                                     // to the non NULL terminated unicode string. Length of the string should be
1663                                                                     // determined using the length field. There is no other way.
1664         };
1665
1666         TCppEnumMemberDefn        *m_enum_member_ref;                // The pointer is not owned.
1667         TCppDataFieldDefn            *m_data_field_ref;                    // The pointer is not owned.
1668         TCppCodeEntryPointDefn    *m_code_entry_point_ref;            // The pointer is not owned.
1669     };
1670
1671 public:
1672
1673     TCppOperandExpr(ID id = 0);
1674             // Operand expression cannot have children and none of its pointers is owned.
1675
1676     void            Clear() { m_oprnd_type = eopr_none; }
1677
1678     void            SetBoolLiteral(bool bool_value) { m_oprnd_type = eopr_bool_literal; m_bool_value = bool_value; }
1679     void            SetNumericLiteral(TLexNumberType subt, __int64 value) { m_oprnd_type = eopr_num_literal; m_num_subt = subt; m_num_value = value; }
1680     void            SetCharConstLiteral(TLexCharConstType subt, __int64 value) { m_oprnd_type = eopr_charconst_literal; m_charconst_subt = subt; m_charconst_value = value; }
1681     void            SetStringLiteral(TLexStringType subt, const TStrPtrInfo &value) { m_oprnd_type = eopr_string_literal; m_string_subt = subt; m_string_value = value; }
1682     void            SetEnumLiteral(TCppEnumMemberDefn *enum_member) { m_oprnd_type = eopr_enum_literal; m_enum_member_ref = enum_member; }
1683
1684     void            SetDataField(TCppDataFieldDefn *data_field) { m_oprnd_type = eopr_data_field; m_data_field_ref = data_field; if (data_field != NULL) m_result_type = data_field->m_field_type; }
1685     void            SetCodeEntryPoint(TCppCodeEntryPointDefn *code_entry_point)
1686                                     { m_oprnd_type = eopr_code_entry_point; m_code_entry_point_ref = code_entry_point; if (code_entry_point != NULL) m_result_type = code_entry_point->m_return_value_type; }
1687
1688     bool            GetConstBoolValue(bool &bool_value) const;
1689
1690     bool            ConvertToNumericLiteral();
1691                     // In case of successful conversion the subtype of the object is always eopr_num_literal.
1692
1693     virtual bool    GetConstOperandValue(TCppOperandExpr &expr_value) const;
1694
1695     virtual bool    CanHaveChildren() const { return(FALSE); }
1696
1697     const wchar_t            *GetTextRepresentation(wchar_t *buffer, int buffer_len, bool want_ref_num);
1698     static const wchar_t    *GetOperandTypeEnumName(TCppExprOperandType oprnd_type);
1699 };
1700
1701 //
1702 //  Unary expression can be (10 possible operation codes): ++op, --op, *op, &op, +op, -op, !op, ~op, op++, op--.
1703 //
1704 struct TCppUnaryExpr : public TCppExpressionBase
1705 {
1706     TCppUnaryExpr(ID id = 0);
1707     ~TCppUnaryExpr();
1708
1709     TCppExpressionBase            *m_operand;
1710
1711 public:
1712
1713     void            SetOperation(TOperatorToken opr);
1714
1715     virtual bool    GetConstOperandValue(TCppOperandExpr &expr_value) const;
1716
1717     virtual void    AddChildItem(TCppItemBase *item, int item_destination = -1);
1718     virtual void    NewIndirectChildNotification(TCppItemBase *items_subtree_root) { if (m_cib_parent != NULL) m_cib_parent->NewIndirectChildNotification(items_subtree_root); }
1719 };
1720
1721 //
1722 //  Binary expression can be (11 possible operation codes): ==, !=, <, >, <=, >=, <<, >>, -, /, %.
1723 //
1724 struct TCppBinaryExpr : public TCppExpressionBase
1725 {
1726     TCppBinaryExpr(ID id = 0);
1727     ~TCppBinaryExpr();
1728
1729     TCppExpressionBase            *m_operand1;
1730     TCppExpressionBase            *m_operand2;
1731
1732 public:
1733
1734     void            SetOperation(TOperatorToken opr);
1735
1736     virtual bool    GetConstOperandValue(TCppOperandExpr &expr_value) const;
1737
1738     virtual void    AddChildItem(TCppItemBase *item, int item_destination = -1);
1739     virtual void    NewIndirectChildNotification(TCppItemBase *items_subtree_root);
1740 };
1741
1742 //
1743 //  Multi operation expression can be (8 possible  operation codes): ',' (comma), &&, ||, &, |, ^, +, *.
1744 //
1745 //  Note that in rare cases expression with comma operation may have empty list of operands and this situation is legal.
1746 //
1747 struct TCppMultiOpExpr : public TCppExpressionBase
1748 {
1749     TCppMultiOpExpr(ID id = 0);
1750     ~TCppMultiOpExpr();
1751
1752     TList                            m_operands;
1753
1754 public:
1755
1756     void            SetOperation(TOperatorToken opr);
1757
1758     virtual bool    GetConstOperandValue(TCppOperandExpr &expr_value) const;
1759
1760     virtual void    AddChildItem(TCppItemBase *item, int item_destination = -1);
1761     virtual void    NewIndirectChildNotification(TCppItemBase *items_subtree_root) { if (m_cib_parent != NULL) m_cib_parent->NewIndirectChildNotification(items_subtree_root); }
1762 };
1763
1764 //
1765 //  Assignment expression can be (11 possible operation codes): =, +=, -=, *=, /=, %=, <<=, >>=, &=, |=, ^=.
1766 //
1767 struct TCppAssignmentExpr : public TCppExpressionBase
1768 {
1769     TCppAssignmentExpr(ID id = 0);
1770     ~TCppAssignmentExpr();
1771
1772     TCppExpressionBase            *m_operand1;
1773     TCppExpressionBase            *m_operand2;
1774
1775 public:
1776
1777     void            SetOperation(TOperatorToken opr);
1778
1779     virtual void    AddChildItem(TCppItemBase *item, int item_destination = -1);
1780     virtual void    NewIndirectChildNotification(TCppItemBase *items_subtree_root) { if (m_cib_parent != NULL) m_cib_parent->NewIndirectChildNotification(items_subtree_root); }
1781 };
1782
1783 // ---------------------------------------------------------------------------
1784 //  - - (Exprs2) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1785 // ---------------------------------------------------------------------------
1786
1787 struct TCppThrowExpr : public TCppExpressionBase
1788 {
1789     TCppThrowExpr(ID id = 0);
1790     ~TCppThrowExpr();
1791
1792     TCppExpressionBase            *m_operand;    
1793                                                                     // Note that operand can be NULL. This is legal case, but such expression
1794                                                                     // may occur only in the context of the catch block.
1795 public:
1796
1797     virtual void    AddChildItem(TCppItemBase *item, int item_destination = -1);
1798     virtual void    NewIndirectChildNotification(TCppItemBase *items_subtree_root) { if (m_cib_parent != NULL) m_cib_parent->NewIndirectChildNotification(items_subtree_root); }
1799 };
1800
1801 struct TCppConditionalExpr : public TCppExpressionBase
1802 {
1803     TCppConditionalExpr(ID id = 0);
1804     ~TCppConditionalExpr();
1805
1806     TCppExpressionBase            *m_operand1;
1807     TCppExpressionBase            *m_operand2;
1808     TCppExpressionBase            *m_operand3;
1809
1810 public:
1811
1812     virtual bool    GetConstOperandValue(TCppOperandExpr &expr_value) const;
1813
1814     virtual void    AddChildItem(TCppItemBase *item, int item_destination = -1);
1815     virtual void    NewIndirectChildNotification(TCppItemBase *items_subtree_root) { if (m_cib_parent != NULL) m_cib_parent->NewIndirectChildNotification(items_subtree_root); }
1816 };
1817
1818 struct TCppFieldAccessExpr : public TCppExpressionBase
1819 {
1820     TCppFieldAccessExpr(ID id = 0);
1821     ~TCppFieldAccessExpr();
1822             // This class supports "dot" and "arrow" operations.
1823
1824     TCppExpressionBase            *m_struct_operand;
1825     TCppDefnBase                *m_struct_member_defn;            // The pointer is not owned.
1826
1827 public:
1828
1829     void            SetOperation(TOperatorToken opr) { assert(opr == 0 || opr == opr_none || opr == opr_dot || opr == opr_arrow); m_operation = opr; }
1830
1831     virtual void    AddChildItem(TCppItemBase *item, int item_destination = -1);
1832     virtual void    NewIndirectChildNotification(TCppItemBase *items_subtree_root) { if (m_cib_parent != NULL) m_cib_parent->NewIndirectChildNotification(items_subtree_root); }
1833 };
1834
1835 struct TCppFieldAccessPtrExpr : public TCppExpressionBase
1836 {
1837     TCppFieldAccessPtrExpr(ID id = 0);
1838     ~TCppFieldAccessPtrExpr();
1839             // This class supports "dot-star" and "arrow-star" operations.
1840
1841     TCppExpressionBase            *m_struct_operand;
1842     TCppExpressionBase            *m_struct_member_ptr;                // The pointer is an owned expression.
1843                                                                     // Both data fields are children of the current expr.
1844 public:
1845
1846     void            SetOperation(TOperatorToken opr) { assert(opr == 0 || opr == opr_none || opr == opr_dotstar || opr == opr_arrowstar); m_operation = opr; }
1847
1848     virtual void    AddChildItem(TCppItemBase *item, int item_destination = -1);
1849     virtual void    NewIndirectChildNotification(TCppItemBase *items_subtree_root) { if (m_cib_parent != NULL) m_cib_parent->NewIndirectChildNotification(items_subtree_root); }
1850 };
1851
1852 struct TCppArrayIndexExpr : public TCppExpressionBase
1853 {
1854     TCppArrayIndexExpr(ID id = 0);
1855     ~TCppArrayIndexExpr();
1856
1857     TCppExpressionBase            *m_array_operand;
1858     TList                            m_index_expressions;
1859
1860 public:
1861
1862     virtual bool    GetConstOperandValue(TCppOperandExpr &expr_value) const;
1863
1864     virtual void    AddChildItem(TCppItemBase *item, int item_destination = -1);
1865     virtual void    NewIndirectChildNotification(TCppItemBase *items_subtree_root) { if (m_cib_parent != NULL) m_cib_parent->NewIndirectChildNotification(items_subtree_root); }
1866 };
1867
1868 struct TCppFunctionCallExpr : public TCppExpressionBase
1869 {
1870     TCppFunctionCallExpr(ID id = 0);
1871     ~TCppFunctionCallExpr();
1872
1873     TCppExpressionBase            *m_function;
1874
1875     TList                            m_parameters;
1876
1877 public:
1878
1879     virtual void    AddChildItem(TCppItemBase *item, int item_destination = -1);            // Possible dests: cexpr_chdest_fcall_func or cexpr_chdest_fcall_params.
1880     virtual void    NewIndirectChildNotification(TCppItemBase *items_subtree_root) { if (m_cib_parent != NULL) m_cib_parent->NewIndirectChildNotification(items_subtree_root); }
1881
1882     void            AddCallParameters(TCppExpressionBase *params_expr);
1883                     // When the passed expression is a comma expr, its subexpressions are added as separate
1884                     // parameters. Otherwise the whole passed expr is added as one parameter.
1885 };
1886
1887 //
1888 //  Cast expression can have the following variants: (TypeId)operand, const_cast, dyna_cast, rein_cast, static_cast.
1889 //
1890 //  In the moment parser implements the cast operation only partially. It assumes that any type can be casted to any
1891 //  data type. Parser is not generating syntax errors unless the destination type is data type and not a function type.
1892 //  It is up the code generator/interpreter to decide if error messages are needed or not and how exactly the casting
1893 //  should be implemented.
1894 //
1895 //  The result type is always statically known.
1896 //
1897 struct TCppCastExpr : public TCppExpressionBase
1898 {
1899     TCppCastExpr(ID id = 0);
1900     ~TCppCastExpr();
1901
1902     TCppDataTypeBase            *m_dest_type;                        // This type pointer is just referenced. It is not owned.
1903     TCppExpressionBase            *m_operand;
1904
1905 public:
1906
1907     void            SetOperation(TOperatorToken opr) { m_operation = opr; }
1908
1909     virtual bool    GetConstOperandValue(TCppOperandExpr &expr_value) const;
1910
1911     virtual void    AddChildItem(TCppItemBase *item, int item_destination = -1);
1912     virtual void    NewIndirectChildNotification(TCppItemBase *items_subtree_root) { if (m_cib_parent != NULL) m_cib_parent->NewIndirectChildNotification(items_subtree_root); }
1913 };
1914
1915 struct TCppSizeofExpr : public TCppExpressionBase
1916 {
1917     TCppSizeofExpr(ID id = 0);
1918     ~TCppSizeofExpr();
1919         //
1920         // When the SIZEOF operation is processed, parser searches for the "size_t" type. Parser expects that
1921         // this type should be defined before the first use of the SIZEOF operator. This type should be one of
1922         // the integral types. Definition of this type is the ony one way to tell to the parser what type should be
1923         // used for handling sizes and as underlying type for pointers. This type is used as the result type of
1924         // this operation.
1925         //
1926
1927     bool                            m_expr_operand;
1928
1929     union
1930     {
1931         TCppDataTypeBase        *m_data_type;                        // Pointer is not owned.
1932         TCppExpressionBase        *m_operand;                        // This is an owned child.
1933     };
1934
1935     __int64                        m_sizeof_value;                        // Note that size of the object can be zero.
1936
1937 public:
1938
1939     virtual bool    GetConstOperandValue(TCppOperandExpr &expr_value) const;
1940
1941     void            SetDataTypeOperand(TCppItemBase *item);
1942                                 // This method should be called only when the operand of the sizeof operator is DATA TYPE.
1943 protected:
1944                                 
1945     virtual void    AddChildItem(TCppItemBase *item, int item_destination = -1);
1946                                 // This method should be called ONLY when the operand is an expression.
1947     virtual void    NewIndirectChildNotification(TCppItemBase *items_subtree_root) { if (m_cib_parent != NULL) m_cib_parent->NewIndirectChildNotification(items_subtree_root); }
1948 };
1949
1950 struct TCppNewExpr : public TCppExpressionBase
1951 {
1952     TCppNewExpr(ID id = 0);
1953     ~TCppNewExpr();
1954
1955     bool                            m_global_new;
1956     TList                            m_new_placement_exprs;            // The list can be empty.
1957     TCppDataTypeBase            *m_new_type;                        // The pointer is not owned.
1958     TList                            m_init_param_exprs;                // The list can be empty.
1959     TCppFunctionCallExpr            *m_ctor_call;                        // This is child expression.
1960
1961 public:
1962
1963     virtual void    AddChildItem(TCppItemBase *item, int item_destination = -1);
1964     virtual void    NewIndirectChildNotification(TCppItemBase *items_subtree_root) { if (m_cib_parent != NULL) m_cib_parent->NewIndirectChildNotification(items_subtree_root); }
1965 };
1966
1967 struct TCppDeleteExpr : public TCppExpressionBase
1968 {
1969     TCppDeleteExpr(ID id = 0);
1970     ~TCppDeleteExpr();
1971
1972     bool                            m_global_delete;
1973     bool                            m_array_delete;
1974     TCppExpressionBase            *m_operand;
1975
1976 public:
1977
1978     virtual void    AddChildItem(TCppItemBase *item, int item_destination = -1);
1979     virtual void    NewIndirectChildNotification(TCppItemBase *items_subtree_root) { if (m_cib_parent != NULL) m_cib_parent->NewIndirectChildNotification(items_subtree_root); }
1980 };
1981
1982 struct TCppTypeidExpr : public TCppExpressionBase
1983 {
1984     TCppTypeidExpr(ID id = 0);
1985     ~TCppTypeidExpr();
1986         //
1987         // When the TYPEID operation is processed, parser searches for std::type_info. Parser expects that
1988         // this structure should be defined before the first use of the TYPEID operator. This structure is used
1989         // as the type of the result of the expression.
1990         //
1991
1992     bool                            m_expr_operand;
1993     bool                            m_dynamic_result;
1994
1995     union
1996     {
1997         TCppDataTypeBase        *m_data_type;                        // Pointer is not owned.
1998         TCppExpressionBase        *m_operand;                        // This is an owned child.
1999     };
2000
2001     union
2002     {
2003         TCppDataFieldDefn            *m_static_type_struct;                // Pointer is not owned.
2004         TCppItemBase            *m_type_resolution_code;            // This is an owned child.
2005                                                     //
2006                                                     // Core parser is placing NULLs in these fields. The callback handler from the TCppObjectsFactory
2007                                                     // may assign appropriate non NULL values. This design was selected because C++ standard is not
2008                                                     // defining constuctors and/or data fields in the std::type_info structure
2009                                                     //
2010     };
2011
2012 public:
2013
2014     virtual void    AddChildItem(TCppItemBase *item, int item_destination = -1);
2015                     // This method should be called ONLY when the operand is an expression.
2016
2017     virtual void    NewIndirectChildNotification(TCppItemBase *items_subtree_root) { if (m_cib_parent != NULL) m_cib_parent->NewIndirectChildNotification(items_subtree_root); }
2018 };
2019
2020
2021