This file is indexed.

/usr/lib/python2.7/dist-packages/pygccxml/declarations/class_declaration.py is in python-pygccxml 1.8.0-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
# Copyright 2014-2016 Insight Software Consortium.
# Copyright 2004-2008 Roman Yakovenko.
# Distributed under the Boost Software License, Version 1.0.
# See http://www.boost.org/LICENSE_1_0.txt

"""
defines classes, that describes C++ classes

This modules contains definition for next C++ declarations:
    - class definition
    - class declaration
    - small helper class for describing C++ class hierarchy
"""

import warnings
from . import scopedef
from . import declaration_utils
from . import declaration
from . import templates
from . import cpptypes
from .. import utils


class ACCESS_TYPES(object):

    """class that defines "access" constants"""
    PUBLIC = "public"
    PRIVATE = "private"
    PROTECTED = "protected"
    ALL = [PUBLIC, PRIVATE, PROTECTED]


class CLASS_TYPES(object):

    """class that defines "class" type constants"""
    CLASS = "class"
    STRUCT = "struct"
    UNION = "union"
    ALL = [CLASS, STRUCT, UNION]


def get_partial_name(name):
    from . import container_traits  # prevent cyclic dependencies
    ct = container_traits.find_container_traits(name)
    if ct:
        return ct.remove_defaults(name)
    elif templates.is_instantiation(name):
        tmpl_name, args = templates.split(name)
        for i, arg_name in enumerate(args):
            args[i] = get_partial_name(arg_name.strip())
        return templates.join(tmpl_name, args)
    else:
        return name


class hierarchy_info_t(object):

    """describes class relationship"""

    def __init__(self, related_class=None, access=None, is_virtual=False):
        """creates class that contains partial information about class
        relationship"""
        if related_class:
            assert(isinstance(related_class, class_t))
        self._related_class = related_class
        if access:
            assert(access in ACCESS_TYPES.ALL)
        self._access = access
        self._is_virtual = is_virtual
        self._declaration_path = None
        self._declaration_path_hash = None

    def __eq__(self, other):
        if not isinstance(other, hierarchy_info_t):
            return False
        return (self.declaration_path_hash ==
                other.declaration_path_hash) \
            and self._declaration_path == other._declaration_path \
            and self._access == other._access \
            and self._is_virtual == other._is_virtual

    def __hash__(self):
        return self.declaration_path_hash

    def __ne__(self, other):
        return not self.__eq__(other)

    def __lt__(self, other):
        if not isinstance(other, self.__class__):
            return self.__class__.__name__ < other.__class__.__name__
        return (self.declaration_path, self.access, self.is_virtual) < \
            (other.declaration_path, other.access, other.is_virtual)

    @property
    def related_class(self):
        """reference to base or derived :class:`class <class_t>`"""
        return self._related_class

    @related_class.setter
    def related_class(self, new_related_class):
        if new_related_class:
            assert(isinstance(new_related_class, class_t))
        self._related_class = new_related_class
        self._declaration_path = None
        self._declaration_path_hash = None

    @property
    def access(self):
        return self._access

    @access.setter
    def access(self, new_access):
        assert(new_access in ACCESS_TYPES.ALL)
        self._access = new_access

    # TODO: Why is there an access_type / access which are the same ?
    @property
    def access_type(self):
        """describes :class:`hierarchy type <ACCESS_TYPES>`"""
        return self.access

    @access_type.setter
    def access_type(self, new_access_type):
        self.access = new_access_type

    # TODO: check whether GCC XML support this and if so parser this
    # information
    @property
    def is_virtual(self):
        """indicates whether the inheritance is virtual or not"""
        return self._is_virtual

    @is_virtual.setter
    def is_virtual(self, new_is_virtual):
        self._is_virtual = new_is_virtual

    @property
    def declaration_path(self):
        if self._declaration_path is None:
            self._declaration_path = declaration_utils.declaration_path(
                self.related_class)
        return self._declaration_path

    @property
    def declaration_path_hash(self):
        if self._declaration_path_hash is None:
            self._declaration_path_hash = hash(tuple(self.declaration_path))
        return self._declaration_path_hash


class class_declaration_t(declaration.declaration_t):

    """describes class declaration"""

    def __init__(self, name=''):
        """creates class that describes C++ class declaration
        ( and not definition )"""
        declaration.declaration_t.__init__(self, name)
        self._aliases = []
        self._container_traits = None  # Deprecated
        self._container_traits_set = False  # Deprecated
        self._container_traits_cache = None

    def _get__cmp__items(self):
        """implementation details"""
        return []

    def i_depend_on_them(self, recursive=True):
        return []

    @property
    def aliases(self):
        """List of :class:`aliases <typedef_t>` to this instance"""
        return self._aliases

    @aliases.setter
    def aliases(self, new_aliases):
        self._aliases = new_aliases

    @property
    def container_traits(self):
        """reference to :class:`container_traits_impl_t` or None"""

        # Deprecated since 1.8.0. Will be removed in 1.9.0
        warnings.warn(
            "The container_traits attribute is deprecated. \n" +
            "Please use the find_container_traits function from the"
            "declarations module instead.",
            DeprecationWarning)

        if self._container_traits_set is False:
            from . import container_traits  # prevent cyclic dependencies
            self._container_traits_set = True
            self._container_traits = container_traits.find_container_traits(
                self)
            self._container_traits_cache = self._container_traits
        return self._container_traits

    def _get_partial_name_impl(self):
        return get_partial_name(self.name)


class class_t(scopedef.scopedef_t):

    """describes class definition"""

    # Can be set from outside
    USE_DEMANGLED_AS_NAME = True

    def __init__(
            self,
            name='',
            class_type=CLASS_TYPES.CLASS,
            is_abstract=False):
        """creates class that describes C++ class definition"""
        scopedef.scopedef_t.__init__(self, name)
        if class_type:
            assert(class_type in CLASS_TYPES.ALL)
        self._class_type = class_type
        self._bases = []
        self._derived = []
        self._is_abstract = is_abstract
        self._public_members = []
        self._private_members = []
        self._protected_members = []
        self._aliases = []
        self._byte_size = 0
        self._byte_align = 0
        self._container_traits_cache = None
        self._container_traits = None  # Deprecated
        self._container_traits_set = False  # Deprecated
        self._recursive_bases = None
        self._recursive_derived = None
        self._use_demangled_as_name = False

    @property
    def use_demangled_as_name(self):
        if "GCC" in utils.xml_generator:
            return class_t.USE_DEMANGLED_AS_NAME
        elif "CastXML" in utils.xml_generator:
            return False

    @use_demangled_as_name.setter
    def use_demangled_as_name(self, use_demangled_as_name):
        self._use_demangled_as_name = use_demangled_as_name

    def _get_name_impl(self):
        if not self._name:  # class with empty name
            return self._name
        elif self.use_demangled_as_name and self.demangled:

            if not self.cache.demangled_name:
                fname = declaration_utils.full_name(self.parent)
                if fname.startswith('::') and \
                        not self.demangled.startswith('::'):
                    fname = fname[2:]
                if self.demangled.startswith(fname):
                    tmp = self.demangled[len(fname):]  # demangled::name
                    if tmp.startswith('::'):
                        tmp = tmp[2:]
                    if '<' not in tmp and '<' in self._name:
                        # we have template class, but for some reason demangled
                        # name doesn't contain any template
                        # This happens for std::string class, but this breaks
                        # other cases, because this behaviour is not consistent
                        self.cache.demangled_name = self._name
                        return self.cache.demangled_name
                    else:
                        self.cache.demangled_name = tmp
                        return tmp
                else:
                    self.cache.demangled_name = self._name
                    return self._name
            else:
                return self.cache.demangled_name
        else:
            return self._name

    def __str__(self):
        name = declaration_utils.full_name(self)
        if name[:2] == "::":
            name = name[2:]
        return "%s [%s]" % (name, self.class_type)

    def _get__cmp__scope_items(self):
        """implementation details"""
        return [
                self.class_type,
                [declaration_utils.declaration_path(base.related_class) for
                 base in self.bases].sort(),
                [declaration_utils.declaration_path(derive.related_class) for
                 derive in self.derived].sort(),
                self.is_abstract,
                self.public_members.sort(),
                self.private_members.sort(),
                self.protected_members.sort()]

    def __eq__(self, other):
        if not scopedef.scopedef_t.__eq__(self, other):
            return False
        return self.class_type == other.class_type \
            and [declaration_utils.declaration_path(base.related_class) for
                 base in self.bases].sort() \
            == [declaration_utils.declaration_path(base.related_class) for
                base in other.bases].sort() \
            and [declaration_utils.declaration_path(derive.related_class) for
                 derive in self.derived].sort() \
            == [declaration_utils.declaration_path(derive.related_class) for
                derive in other.derived].sort() \
            and self.is_abstract == other.is_abstract \
            and self.public_members.sort() \
            == other.public_members.sort() \
            and self.private_members.sort() \
            == other.private_members.sort() \
            and self.protected_members.sort() \
            == other.protected_members.sort()

    def __hash__(self):
        return hash(self.class_type)

    @property
    def class_type(self):
        """describes class :class:`type <CLASS_TYPES>`"""
        return self._class_type

    @class_type.setter
    def class_type(self, new_class_type):
        if new_class_type:
            assert(new_class_type in CLASS_TYPES.ALL)
        self._class_type = new_class_type

    @property
    def bases(self):
        """list of :class:`base classes <hierarchy_info_t>`"""
        return self._bases

    @bases.setter
    def bases(self, new_bases):
        self._bases = new_bases

    @property
    def recursive_bases(self):
        """list of all :class:`base classes <hierarchy_info_t>`"""
        if self._recursive_bases is None:
            to_go = self.bases[:]
            all_bases = []
            while to_go:
                base = to_go.pop()
                if base not in all_bases:
                    all_bases.append(base)
                    to_go.extend(base.related_class.bases)
            self._recursive_bases = all_bases
        return self._recursive_bases

    @property
    def derived(self):
        """list of :class:`derived classes <hierarchy_info_t>`"""
        return self._derived

    @derived.setter
    def derived(self, new_derived):
        self._derived = new_derived

    @property
    def recursive_derived(self):
        """list of all :class:`derive classes <hierarchy_info_t>`"""
        if self._recursive_derived is None:
            to_go = self.derived[:]
            all_derived = []
            while to_go:
                derive = to_go.pop()
                if derive not in all_derived:
                    all_derived.append(derive)
                    to_go.extend(derive.related_class.derived)
            self._recursive_derived = all_derived
        return self._recursive_derived

    @property
    def is_abstract(self):
        """describes whether class abstract or not"""
        return self._is_abstract

    @is_abstract.setter
    def is_abstract(self, is_abstract):
        self._is_abstract = is_abstract

    @property
    def public_members(self):
        """list of all public :class:`members <declarationt_>`"""
        return self._public_members

    @public_members.setter
    def public_members(self, new_public_members):
        self._public_members = new_public_members

    @property
    def private_members(self):
        """list of all private :class:`members <declarationt_>`"""
        return self._private_members

    @private_members.setter
    def private_members(self, new_private_members):
        self._private_members = new_private_members

    @property
    def protected_members(self):
        """list of all protected :class:`members <declarationt_>`"""
        return self._protected_members

    @protected_members.setter
    def protected_members(self, new_protected_members):
        self._protected_members = new_protected_members

    @property
    def aliases(self):
        """List of :class:`aliases <typedef_t>` to this instance"""
        return self._aliases

    @aliases.setter
    def aliases(self, new_aliases):
        self._aliases = new_aliases

    @property
    def byte_size(self):
        """Size of this class in bytes @type: int"""
        return self._byte_size

    @byte_size.setter
    def byte_size(self, new_byte_size):
        self._byte_size = new_byte_size

    @property
    def byte_align(self):
        """Alignment of this class in bytes @type: int"""
        return self._byte_align

    @byte_align.setter
    def byte_align(self, new_byte_align):
        self._byte_align = new_byte_align

    def _get_declarations_impl(self):
        return self.get_members()

    def get_members(self, access=None):
        """
        returns list of members according to access type

        If access equals to None, then returned list will contain all members.
        You should not modify the list content, otherwise different
        optimization data will stop work and may to give you wrong results.

        :param access: describes desired members
        :type access: :class:ACCESS_TYPES

        :rtype: [ members ]
        """
        if access == ACCESS_TYPES.PUBLIC:
            return self.public_members
        elif access == ACCESS_TYPES.PROTECTED:
            return self.protected_members
        elif access == ACCESS_TYPES.PRIVATE:
            return self.private_members
        else:
            all_members = []
            all_members.extend(self.public_members)
            all_members.extend(self.protected_members)
            all_members.extend(self.private_members)
            return all_members

    def adopt_declaration(self, decl, access):
        """adds new declaration to the class

        :param decl: reference to a :class:`declaration_t`

        :param access: member access type
        :type access: :class:ACCESS_TYPES
        """
        if access == ACCESS_TYPES.PUBLIC:
            self.public_members.append(decl)
        elif access == ACCESS_TYPES.PROTECTED:
            self.protected_members.append(decl)
        elif access == ACCESS_TYPES.PRIVATE:
            self.private_members.append(decl)
        else:
            raise RuntimeError("Invalid access type: %s." % access)
        decl.parent = self
        decl.cache.reset()
        decl.cache.access_type = access

    def remove_declaration(self, decl):
        """
        removes decl from  members list

        :param decl: declaration to be removed
        :type decl: :class:`declaration_t`
        """

        access_type = self.find_out_member_access_type(decl)
        if access_type == ACCESS_TYPES.PUBLIC:
            container = self.public_members
        elif access_type == ACCESS_TYPES.PROTECTED:
            container = self.protected_members
        else:  # decl.cache.access_type == ACCESS_TYPES.PRVATE
            container = self.private_members
        del container[container.index(decl)]
        decl.cache.reset()

    def find_out_member_access_type(self, member):
        """
        returns member access type

        :param member: member of the class
        :type member: :class:`declaration_t`

        :rtype: :class:ACCESS_TYPES
        """
        assert member.parent is self
        if not member.cache.access_type:
            if member in self.public_members:
                access_type = ACCESS_TYPES.PUBLIC
            elif member in self.protected_members:
                access_type = ACCESS_TYPES.PROTECTED
            elif member in self.private_members:
                access_type = ACCESS_TYPES.PRIVATE
            else:
                raise RuntimeError(
                    "Unable to find member within internal members list.")
            member.cache.access_type = access_type
            return access_type
        else:
            return member.cache.access_type

    def __find_out_member_dependencies(self, access_type):
        members = self.get_members(access_type)
        answer = []
        for mem in members:
            answer.extend(mem.i_depend_on_them(recursive=True))
        member_ids = set([id(m) for m in members])
        for dependency in answer:
            if id(dependency.declaration) in member_ids:
                dependency.access_type = access_type
        return answer

    def i_depend_on_them(self, recursive=True):

        answer = []

        for base in self.bases:
            answer.append(
                dependency_info_t(
                    self,
                    base.related_class,
                    base.access_type,
                    "base class"))

        if recursive:
            for access_type in ACCESS_TYPES.ALL:
                answer.extend(self.__find_out_member_dependencies(access_type))

        return answer

    @property
    def container_traits(self):
        """reference to :class:`container_traits_impl_t` or None"""

        # Deprecated since 1.8.0. Will be removed in 1.9.0
        warnings.warn(
            "The container_traits attribute is deprecated. \n" +
            "Please use the find_container_traits function from the"
            "declarations module instead.",
            DeprecationWarning)

        if self._container_traits_set is False:
            from . import container_traits  # prevent cyclic dependencies
            self._container_traits_set = True
            self._container_traits = container_traits.find_container_traits(
                self)
            self._container_traits_cache = self.container_traits
        return self._container_traits

    def find_copy_constructor(self):

        # Deprecated since 1.8.0. Will be removed in 1.9.0
        warnings.warn(
            "The find_copy_constructor method is deprecated. \n" +
            "Please use the find_copy_constructor function from the"
            "declarations module instead.",
            DeprecationWarning)

        from . import type_traits_classes  # prevent cyclic dependencies
        return type_traits_classes.find_copy_constructor(self)

    def find_trivial_constructor(self):

        # Deprecated since 1.8.0. Will be removed in 1.9.0
        warnings.warn(
            "The find_trivial_constructor method is deprecated. \n" +
            "Please use the find_trivial_constructor function from the"
            "declarations module instead.",
            DeprecationWarning)

        from . import type_traits_classes  # prevent cyclic dependencies
        return type_traits_classes.find_trivial_constructor(self)

    def _get_partial_name_impl(self):
        from . import type_traits  # prevent cyclic dependencies
        if type_traits.is_std_string(self):
            return 'string'
        elif type_traits.is_std_wstring(self):
            return 'wstring'
        else:
            return get_partial_name(self.name)

    def find_noncopyable_vars(self):
        """returns list of all `noncopyable` variables"""

        # Deprecated since 1.8.0. Will be removed in 1.9.0
        warnings.warn(
            "The find_noncopyable_vars method is deprecated. \n" +
            "Please use the find_noncopyable_vars function from the"
            "declarations module instead.",
            DeprecationWarning)

        from . import type_traits_classes  # prevent cyclic dependencies
        type_traits_classes.find_noncopyable_vars(self)

    @property
    def has_vtable(self):
        """True, if class has virtual table, False otherwise"""

        # Deprecated since 1.8.0. Will be removed in 1.9.0
        warnings.warn(
            "The has_vtable argument is deprecated. \n" +
            "Please use the has_vtable function from the declarations \n" +
            "module instead.",
            DeprecationWarning)

        # prevent cyclic import
        from . import type_traits_classes
        return type_traits_classes.has_vtable(self)

    @property
    def top_class(self):
        """reference to a parent class, which contains this class and defined
        within a namespace

        if this class is defined under a namespace, self will be returned"""
        curr = self
        parent = self.parent
        while isinstance(parent, class_t):
            curr = parent
            parent = parent.parent
        return curr

class_types = (class_t, class_declaration_t)


class impl_details(object):

    @staticmethod
    def dig_declarations(depend_on_it):

        # FIXME: prevent cyclic imports
        from . import type_traits

        if isinstance(depend_on_it, declaration.declaration_t):
            return [depend_on_it]
        base_type = type_traits.base_type(
            type_traits.remove_alias(depend_on_it))
        if isinstance(base_type, cpptypes.declarated_t):
            return [base_type.declaration]
        elif isinstance(base_type, cpptypes.calldef_type_t):
            result = []
            result.extend(impl_details.dig_declarations(base_type.return_type))
            for argtype in base_type.arguments_types:
                result.extend(impl_details.dig_declarations(argtype))
            if isinstance(base_type, cpptypes.member_function_type_t):
                result.extend(
                    impl_details.dig_declarations(
                        base_type.class_inst))
            return result
        return []


class dependency_info_t(object):

    def __init__(self, declaration, depend_on_it, access_type=None, hint=None):
        object.__init__(self)

        assert isinstance(
            depend_on_it,
            (class_t,
             cpptypes.type_t))
        self._declaration = declaration
        self._depend_on_it = depend_on_it
        self._access_type = access_type
        self._hint = hint

    @property
    def declaration(self):
        return self._declaration
    # short name
    decl = declaration

    @property
    def depend_on_it(self):
        return self._depend_on_it

    @property
    def access_type(self):
        return self._access_type

    @access_type.setter
    def access_type(self, access_type):
        self._access_type = access_type

    def __str__(self):
        return 'declaration "%s" depends( %s ) on "%s" ' \
               % (self.declaration, self.access_type, self.depend_on_it)

    @property
    def hint(self):
        """The declaration, that report dependency can put some additional
        inforamtion about dependency. It can be used later"""
        return self._hint

    def find_out_depend_on_it_declarations(self):
        """If declaration depends on other declaration and not on some type
        this function will return reference to it. Otherwise None will be
        returned
        """
        return impl_details.dig_declarations(self.depend_on_it)

    @staticmethod
    def i_depend_on_them(decl):
        """Returns set of declarations. every item in the returned set,
        depends on a declaration from the input"""

        to_be_included = set()
        for dependency_info in decl.i_depend_on_them():
            for ddecl in dependency_info.find_out_depend_on_it_declarations():
                if ddecl:
                    to_be_included.add(ddecl)

        if isinstance(decl.parent, class_t):
            to_be_included.add(decl.parent)
        return to_be_included

    @staticmethod
    def we_depend_on_them(decls):
        """Returns set of declarations. every item in the returned set,
        depends on a declaration from the input"""
        to_be_included = set()
        for decl in decls:
            to_be_included.update(dependency_info_t.i_depend_on_them(decl))
        return to_be_included