Пример #1
0
    def cStruct_build_info(self, db):
        """Defines the structure layout for this class,
           according to the gcc cxx ABI for virtual classes.

           The returned value is a triplet, (vptr, M, V) where

             - vptr is a virtual indicator,
             - M is the list of non-virtual fields,
             - V is the ordered dict of virtual fields.


        """
        self.unfold(db)
        M, V = [], OrderedDict()
        vptr = 0
        # iterate over classes' fields
        for (x, y, _) in self:
            qal, t = x
            mn, n = y
            # we don't care about scope & comments
            # we start by handling parent classes:
            if qal == "parent":
                n = cxx_type(n)
                nn = n.show_base()
                name = n.show_base(True, True)
                x = ccore._cache_.get(name, None)
                try:
                    if x._is_typedef:
                        x = ccore._cache_.get(x, None)
                except Exception:
                    pass
                if x is None:
                    raise TypeError("unkown type '%s'" % n)
                assert x._is_class
                # get layout of the parent class:
                vtbl, m, v = x.cStruct_build_info(db)
                if t == "virtual":
                    vptr = 2
                    if nn not in V:
                        V[nn] = (vtbl, m)
                else:
                    if vtbl:
                        vptr += vtbl
                        if len(m) > 0:
                            if not m[0][1].startswith("__vptr"):
                                t = cxx_type("void *")
                                M.append((t, "__vptr$%s" % nn))
                    M.extend(m)
                V.update(v)
            elif qal == "using":
                continue
            elif "virtual" in qal:
                vptr = 1
            else:
                t = cxx_type(t)
                if not t.is_method:
                    M.append((t, n))
        return (vptr, M, V)
Пример #2
0
Файл: C.py Проект: bdcht/ccrawl
def cTemplate_C(obj, db, recursive):
    identifier = obj.get_basename()
    template = obj.get_template()
    # get the cxx type object, for namespaces:
    tn = cxx_type(identifier)
    #namespace = tn.show_base(kw=False,ns=False)
    #prepare query if recursion is needed:
    if isinstance(recursive, set):
        #Q = True
        recursive.update(struct_letters)
        recursive.add(tn.lbase)
        for t in obj['params']:
            if t.startswith('typename '):
                t = t.replace('typename ', '')
                recursive.add(t)
    else:
        #Q = None
        pass
    R = []
    #S holds template output lines:
    S = [u'template%s' % template]
    if 'cClass' in obj:
        from ccrawl.core import cClass
        o = cClass(obj['cClass'])
        o.identifier = identifier
        x = cClass_C(o, db, recursive)
    if 'cFunc' in obj:
        from ccrawl.core import cFunc
        o = cFunc(obj['cFunc'])
        o.identifier = identifier
        x = cFunc_C(o, db, recursive)
    x = x.split('\n\n')
    S.append(x.pop())
    if len(x): R.append(x[0])
    return '\n'.join(R) + '\n'.join(S)
Пример #3
0
def get_c_or_cxx_type(x):
    if not ('&' in x):
        try:
            t = c_type(x)
        except pp.ParseException:
            pass
        else:
            return t
    t = cxx_type(x)
    return t
Пример #4
0
 def cStruct_build_info(self, db):
     self.unfold(db)
     M, V = [], OrderedDict()
     vptr = 0
     for (x, y, _) in self:
         qal, t = x
         mn, n = y
         if qal == 'parent':
             n = cxx_type(n)
             nn = n.show_base()
             name = n.show_base(True, True)
             x = ccore._cache_.get(name, None)
             try:
                 if x._is_typedef:
                     x = ccore._cache_.get(x, None)
             except Exception:
                 pass
             if x is None:
                 raise TypeError("unkown type '%s'" % n)
             assert x._is_class
             vtbl, m, v = x.cStruct_build_info(db)
             if t == 'virtual':
                 vptr = 2
                 if nn not in V:
                     V[nn] = (vtbl, m)
             else:
                 if vtbl:
                     vptr += vtbl
                     if len(m) > 0:
                         if not m[0][1].startswith('__vptr'):
                             t = cxx_type('void *')
                             M.append((t, '__vptr$%s' % nn))
                 M.extend(m)
             V.update(v)
         elif 'virtual' in qal:
             vptr = 1
         else:
             t = cxx_type(t)
             if not t.is_method:
                 M.append((t, n))
     return (vptr, M, V)
Пример #5
0
 def as_cStruct(self, db):
     if self.identifier.startswith("union "):
         x = cUnion()
     else:
         x = cStruct()
     name = cxx_type(self.identifier)
     x.identifier = "struct __layout$%s" % (name.show_base(kw=False,
                                                           ns=True))
     # now get the structure information for this class:
     x.subtypes = None
     vptr, M, V = self.cStruct_build_info(db)
     if len(M) > 0 and vptr:
         if not M[0][1].startswith("__vptr"):
             n = cxx_type(self.identifier)
             x.append(("void *", "__vptr$%s" % n.show_base(), ""))
     for t, n in M:
         x.append((t.show(), n, ""))
     for nn, v in V.items():
         vptr, m = v
         if vptr:
             x.append(("void *", "__vptr$%s" % nn, ""))
         for t, n in m:
             x.append((t.show(), n, ""))
     return x
Пример #6
0
 def base_specifier_list(self):
     spe = []
     for x, y, z in self:
         qal, t = x
         if 'parent' in qal:
             mn, n = y
             n = cxx_type(n)
             p, _ = z
             s = ''
             if t:
                 s += ' virtual'
             s += ' %s %s' % (p.lower(), n.show_base())
             spe.append(s)
     if len(spe) > 0:
         return ' :' + (','.join(spe))
     else:
         return ''
Пример #7
0
 def base_specifier_list(self):
     spe = []
     for x, y, z in self:
         qal, t = x
         if "parent" in qal:
             mn, n = y
             n = cxx_type(n)
             p, _ = z
             s = ""
             if t:
                 s += " virtual"
             s += " %s %s" % (p.lower(), n.show_base())
             spe.append(s)
     if len(spe) > 0:
         return " :" + (",".join(spe))
     else:
         return ""
Пример #8
0
 def unfold(self, db, limit=None):
     if self.subtypes is None:
         self.subtypes = OrderedDict()
         T = list(struct_letters.keys())
         T.append(self.identifier)
         for (x, y, _) in self:
             qal, t = x
             mn, n = y
             if qal == 'parent':
                 elt = n
             else:
                 if mn or ('virtual' in qal):
                     continue
                 elt = cxx_type(t)
                 elt = elt.show_base(kw=True, ns=True)
             if (elt not in T):
                 T.append(elt)
                 self.add_subtype(db, elt, limit)
     return self
Пример #9
0
 def as_cStruct(self, db):
     if self.identifier.startswith('union '):
         x = cUnion()
     else:
         x = cStruct()
     x.identifier = self.identifier
     x.subtypes = None
     vptr, M, V = self.cStruct_build_info(db)
     if len(M) > 0 and vptr:
         if not M[0][1].startswith('__vptr'):
             n = cxx_type(self.identifier)
             x.append(('void *', '__vptr$%s' % n.show_base(), ''))
     for t, n in M:
         x.append((t.show(), n, ''))
     for nn, v in V.items():
         vptr, m = v
         if vptr: x.append(('void *', '__vptr$%s' % nn, ''))
         for t, n in m:
             x.append((t.show(), n, ''))
     return x
Пример #10
0
 def unfold(self, db, limit=None):
     if self.subtypes is None:
         self.subtypes = OrderedDict()
         T = list(struct_letters.keys())
         T.append(self.identifier)
         for (x, y, _) in self:
             qal, t = x
             mn, n = y
             if qal == "parent":
                 elt = [n]
             elif qal == "using":
                 elt = t
             else:
                 if mn or ("virtual" in qal):
                     continue
                 elt = cxx_type(t)
                 elt = elt.show_base(kw=True, ns=True)
                 elt = [elt]
             for e in elt:
                 if e not in T:
                     T.append(e)
                     self.add_subtype(db, e, limit)
     return self
Пример #11
0
def cClass_C(obj, db, recursive):
    # get the cxx type object:
    tn = cxx_type(obj.identifier)
    # get the current class name without keyword or namespace:
    classname = tn.show_base(kw=False, ns=False)
    # prepare query if recursion is needed:
    if isinstance(recursive, set):
        Q = True
        recursive.update(struct_letters)
        recursive.add(tn.lbase)
    else:
        Q = None
    # R holds recursive definition strings needed for obj
    R = []
    # S holds obj title and fields declaration strings
    # we need obj.identifier here and not tn.show() because
    # template specialization need to keep the template string.
    S = [u"%s%s {" % (obj.identifier, obj.base_specifier_list())]
    # P holds lists for each public/protected/private/friend members
    P = {"": [], "PUBLIC": [], "PROTECTED": [], "PRIVATE": []}
    # now, iterate through all fields:
    for (x, y, z) in obj:
        qal, t = x  # parent/virtual qualifier & type
        mn, n = y  # mangled name & name
        p, c = z  # public/protected/private & comment
        if qal == "parent":
            # the parent class name is found in n:
            r = cxx_type(n)
            e = r.lbase
            if Q and (e not in recursive):
                q = db.tag & (where("id") == e)
                x = obj.from_db(db.get(q)).show(db, recursive, form="C")
                R.append(x)
                recursive.add(e)
            continue
        elif qal == "using":
            # inherited type of attribute from parent is provided as a list in t:
            what = "::".join((cxx_type(u).show_base(kw=False) for u in t))
            using = "  using %s" % what
            # inherited name of attribute from parent is provided in n:
            # we append the attribute name unless its the class constructor
            using += "::%s;" % n if n != classname else ";"
            S.append(using)
            continue
        elif qal.startswith("template<"):
            P[p].append("    " + qal)
            qal = ""
        # decompose C-type t into specific parts:
        r = cxx_type(t)
        # get "element base" part of type t:
        e = r.lbase
        # is t a nested class ?
        nested = r.ns.split("::")[-1].startswith(classname)
        # is t a nested enum ?
        nested |= e.startswith("enum ?_")
        # query field element raw base type if needed:
        if Q and ((e not in recursive) or nested):
            # prepare query
            q = db.tag & (where("id") == e)
            # deal with nested type:
            if nested:
                q &= where("src") == tn.lbase
            if db.contains(q):
                # retreive the field type:
                x = obj.from_db(db.get(q))
                x = x.show(db, recursive, form="C")
                if not nested:
                    # if not nested, insert it directly in R
                    R.append(x)
                    recursive.add(e)
                else:
                    x = x.replace("%s::" % classname, "")
                    # nested struct/union/class: we need to transfer
                    # any predefs into R
                    x = x.split("\n\n")
                    r.lbase = x.pop().replace("\n", "\n    ").strip(";")
                    if len(x):
                        xr = x[0].split("\n")
                        for xrl in xr:
                            if xrl and xrl not in R:
                                R.append(xrl)
            else:
                secho("identifier %s not found" % r.lbase, fg="red", err=True)
        # finally add field type and name to the structure lines:
        fo = ""
        if qal:
            if "," in qal:
                qal, fo = qal.split(",")
            qal = "%s " % qal
        P[p].append(u"    {}{}{};".format(qal, r.show(n, kw=nested), fo))
    # access specifier (empty is for friend members):
    for p in ("PUBLIC", "PROTECTED", "PRIVATE", ""):
        if len(P[p]) > 0:
            if p:
                S.append("  %s:" % p.lower())
            for v in P[p]:
                S.append(v)
    # join R and S:
    if len(R) > 0:
        R.append("\n")
    S.append("};")
    return "\n".join(R) + "\n".join(S)
Пример #12
0
Файл: C.py Проект: bdcht/ccrawl
def cClass_C(obj, db, recursive):
    # get the cxx type object:
    tn = cxx_type(obj.identifier)
    # get the current class namespace:
    namespace = tn.show_base(kw=False, ns=False)
    #prepare query if recursion is needed:
    if isinstance(recursive, set):
        Q = True
        recursive.update(struct_letters)
        recursive.add(tn.lbase)
    else:
        Q = None
    #R holds recursive definition strings needed for obj
    R = []
    #S holds obj title and fields declaration strings
    #we need obj.identifier here and not tn.show() because
    #template specialization need to keep the template string.
    S = [u'%s%s {' % (obj.identifier, obj.base_specifier_list())]
    #P holds lists for each public/protected/private/friend members
    P = {'': [], 'PUBLIC': [], 'PROTECTED': [], 'PRIVATE': []}
    #now, iterate through all fields:
    for (x, y, z) in obj:
        qal, t = x  # parent/virtual qualifier & type
        mn, n = y  # mangled name & name
        p, c = z  # public/protected/private & comment
        if qal == 'parent':
            r = cxx_type(n)
            e = r.lbase
            if Q and (e not in recursive):
                q = (where('id') == e)
                x = obj.from_db(db.get(q)).show(db, recursive, form='C')
                R.append(x)
                recursive.add(e)
            continue
        elif qal == 'using':
            what = '::'.join((cxx_type(u).show_base() for u in t))
            using = '  using %s' % what
            using += '::%s;' % n if n != namespace else ';'
            S.append(using)
            continue
        elif qal.startswith('template<'):
            P[p].append('    ' + qal)
            qal = ''
        #decompose C-type t into specific parts:
        r = cxx_type(t)
        #get "element base" part of type t:
        e = r.lbase
        #is t a nested class ?
        nested = r.ns.split('::')[-1].startswith(namespace)
        #is t a nested enum ?
        nested |= e.startswith('enum ?_')
        #query field element raw base type if needed:
        if Q and ((e not in recursive) or nested):
            #prepare query
            q = (where('id') == e)
            #deal with nested type:
            if nested:
                q &= (where('src') == tn.lbase)
            if db.contains(q):
                #retreive the field type:
                x = obj.from_db(db.get(q))
                x = x.show(db, recursive, form='C')
                if not nested:
                    #if not nested, insert it directly in R
                    R.append(x)
                    recursive.add(e)
                else:
                    x = x.replace('%s::' % namespace, '')
                    # nested struct/union/class: we need to transfer
                    # any predefs into R
                    x = x.split('\n\n')
                    r.lbase = x.pop().replace('\n', '\n    ').strip(';')
                    if len(x):
                        xr = x[0].split('\n')
                        for xrl in xr:
                            if xrl and xrl not in R:
                                R.append(xrl)
            else:
                secho('identifier %s not found' % r.lbase, fg='red', err=True)
        #finally add field type and name to the structure lines:
        fo = ''
        if qal:
            if ',' in qal: qal, fo = qal.split(',')
            qal = '%s ' % qal
        P[p].append(u'    {}{}{};'.format(qal, r.show(n, kw=nested), fo))
    # access specifier (empty is for friend members):
    for p in ('PUBLIC', 'PROTECTED', 'PRIVATE', ''):
        if len(P[p]) > 0:
            if p: S.append('  %s:' % p.lower())
            for v in P[p]:
                S.append(v)
    #join R and S:
    if len(R) > 0: R.append('\n')
    S.append('};')
    return '\n'.join(R) + '\n'.join(S)