def resolve_decl(decl, typespecs, knowntypespecs, types): if decl.kind is KIND.ENUM: typedeps = [] else: if decl.kind is KIND.VARIABLE: vartypes = [decl.vartype] elif decl.kind is KIND.FUNCTION: vartypes = [decl.signature.returntype] elif decl.kind is KIND.TYPEDEF: vartypes = [decl.vartype] elif decl.kind is KIND.STRUCT or decl.kind is KIND.UNION: vartypes = [m.vartype for m in decl.members] else: # Skip this one! return None typedeps = [] for vartype in vartypes: typespec = vartype.typespec if is_pots(typespec): typedecl = POTSType(typespec) elif is_system_type(typespec): typedecl = SystemType(typespec) elif is_funcptr(vartype): typedecl = FuncPtr(vartype) else: typedecl = find_typedecl(decl, typespec, typespecs) if typedecl is None: typedecl = find_typedecl(decl, typespec, knowntypespecs) elif not isinstance(typedecl, TypeDeclaration): raise NotImplementedError(repr(typedecl)) if typedecl is None: # We couldn't find it! typedecl = UNKNOWN elif typedecl not in types: # XXX How can this happen? typedecl = UNKNOWN elif types[typedecl] is UNKNOWN: typedecl = UNKNOWN elif types[typedecl] is IGNORED: # We don't care if it didn't resolve. pass elif types[typedecl] is None: # The typedecl for the typespec hasn't been resolved yet. typedecl = None typedeps.append(typedecl) return typedeps
def _check_typespec(decl, typedecl, types, knowntypes): typespec = decl.vartype.typespec if typedecl is not None: found = types.get(typedecl) if found is None: found = knowntypes.get(typedecl) if found is not None: _, extra = found if extra is None: # XXX Under what circumstances does this happen? extra = {} unsupported = extra.get('unsupported') if unsupported is FIXED_TYPE: unsupported = None return 'typespec' if unsupported else None # Fall back to default known types. if is_pots(typespec): return None elif is_system_type(typespec): return None elif is_funcptr(decl.vartype): return None return 'typespec'
def _dump_unresolved(decl, types, analyze_decl): if isinstance(decl, str): typespec = decl decl, = (d for d in types if d.shortkey == typespec) elif type(decl) is tuple: filename, typespec = decl if '-' in typespec: found = [ d for d in types if d.shortkey == typespec and d.filename == filename ] #if not found: # raise NotImplementedError(decl) decl, = found else: found = [d for d in types if d.shortkey == typespec] if not found: print(f'*** {typespec} ???') return #raise NotImplementedError(decl) else: decl, = found resolved = analyze_decl(decl) if resolved: typedeps, _ = resolved or (None, None) if decl.kind is KIND.STRUCT or decl.kind is KIND.UNION: print(f'*** {decl.shortkey} {decl.filename}') for member, mtype in zip(decl.members, typedeps): typespec = member.vartype.typespec if typespec == decl.shortkey: print(f' ~~~~: {typespec:20} - {member!r}') continue status = None if is_pots(typespec): mtype = typespec status = 'okay' elif is_system_type(typespec): mtype = typespec status = 'okay' elif mtype is None: if '-' in member.vartype.typespec: mtype, = [ d for d in types if d.shortkey == member.vartype.typespec and d.filename == decl.filename ] else: found = [d for d in types if d.shortkey == typespec] if not found: print(f' ???: {typespec:20}') continue mtype, = found if status is None: status = 'okay' if types.get(mtype) else 'oops' if mtype is _SKIPPED: status = 'okay' mtype = '<skipped>' elif isinstance(mtype, FuncPtr): status = 'okay' mtype = str(mtype.vartype) elif not isinstance(mtype, str): if hasattr(mtype, 'vartype'): if is_funcptr(mtype.vartype): status = 'okay' mtype = str(mtype).rpartition('(')[0].rstrip() status = ' okay' if status == 'okay' else f'--> {status}' print(f' {status}: {typespec:20} - {member!r} ({mtype})') else: print(f'*** {decl} ({decl.vartype!r})') if decl.vartype.typespec.startswith('struct ') or is_funcptr(decl): _dump_unresolved( (decl.filename, decl.vartype.typespec), types, analyze_decl, )