Exemplo n.º 1
0
 def check_assocs(self, n, inters, assocs):
     if assocs == thin.Null_Iir:
         # Also cover the case of no interfaces
         return
     inter = inters
     for assoc in thinutils.chain_iter(assocs):
         if iirs.Get_Kind(assoc) \
            == iirs.Iir_Kind.Association_Element_By_Individual:
             continue
         formal = iirs.Get_Formal(assoc)
         if formal == thin.Null_Iir:
             self.error(
                 Location.from_node(assoc),
                 "association by position for {}".format(
                     nodeutils.get_identifier_str(inter)))
             # Should the tool report all errors ?
             return
         assoc_inter = thin.Iirs_Utils.Get_Interface_Of_Formal(formal)
         while assoc_inter != inter:
             if inter == thin.Null_Iir:
                 self.error(
                     Location.from_node(assoc),
                     "incorrect association order for {}".format(
                         nodeutils.get_identifier_str(assoc_inter)))
                 return
             inter = iirs.Get_Chain(inter)
         if iirs.Get_Whole_Association_Flag(assoc):
             inter = iirs.Get_Chain(inter)
Exemplo n.º 2
0
def nodes_iter(n):
    """Iterate of all nodes of n, including n.
    Nodes are returned only once."""
    if n == Null_Iir:
        return


#    print 'nodes_iter for {0}'.format(n)
    yield n
    for f in fields_iter(n):
        typ = nodes_meta.get_field_type(f)
        #        print ' {0}: field {1} (type: {2})'.format(
        #            n, fields_image(f), types_image(typ))
        if typ == nodes_meta.types.Iir:
            attr = nodes_meta.get_field_attribute(f)
            if attr == Attr.ANone:
                for n1 in nodes_iter(nodes_meta.Get_Iir(n, f)):
                    yield n1
            elif attr == Attr.Chain:
                n2 = nodes_meta.Get_Iir(n, f)
                while n2 != Null_Iir:
                    for n1 in nodes_iter(n2):
                        yield n1
                    n2 = iirs.Get_Chain(n2)
            elif attr == Attr.Maybe_Ref:
                if not iirs.Get_Is_Ref(n, f):
                    for n1 in nodes_iter(nodes_meta.Get_Iir(n, f)):
                        yield n1
        elif typ == types.Iir_List:
            attr = nodes_meta.get_field_attribute(f)
            if attr == Attr.ANone:
                for n1 in list_iter(nodes_meta.Get_Iir_List(n, f)):
                    for n2 in nodes_iter(n1):
                        yield n2
Exemplo n.º 3
0
def sequential_iter(n):
    """Iterator on sequential statements.  The first node must be either
       a process or a subprogram body."""
    if n == thin.Null_Iir:
        return
    k = iirs.Get_Kind(n)
    if k in [
            iirs.Iir_Kind.Process_Statement,
            iirs.Iir_Kind.Sensitized_Process_Statement,
            iirs.Iir_Kind.Function_Body, iirs.Iir_Kind.Procedure_Body
    ]:
        for n1 in chain_iter(iirs.Get_Sequential_Statement_Chain(n)):
            yield n1
            for n2 in sequential_iter(n1):
                yield n2
    elif k == iirs.Iir_Kind.If_Statement:
        while True:
            n = iirs.Get_Chain(n)
            if n == thin.Null_Iir:
                break
            yield n
            for n1 in sequential_iter(n):
                yield n1
    elif k == iirs.Iir_Kind.Case_Statement:
        for ch in chain_iter(iirs.Get_Case_Statement_Alternative_Chain(n)):
            stmt = iirs.Get_Associated_Chain(ch)
            if stmt != thin.Null_Iir:
                for n1 in chain_iter(stmt):
                    yield n1
                    for n2 in sequential_iter(n1):
                        yield n2
    elif k in [
            iirs.Iir_Kind.For_Loop_Statement,
            iirs.Iir_Kind.While_Loop_Statement
    ]:
        for n1 in chain_iter(iirs.Get_Sequential_Statement_Chain(n)):
            yield n1
            for n2 in sequential_iter(n1):
                yield n2
    elif k in [
            iirs.Iir_Kind.Assertion_Statement, iirs.Iir_Kind.Wait_Statement,
            iirs.Iir_Kind.Null_Statement, iirs.Iir_Kind.Exit_Statement,
            iirs.Iir_Kind.Next_Statement, iirs.Iir_Kind.Return_Statement,
            iirs.Iir_Kind.Variable_Assignment_Statement,
            iirs.Iir_Kind.Simple_Signal_Assignment_Statement,
            iirs.Iir_Kind.Procedure_Call_Statement
    ]:
        return
    else:
        assert False, "unknown node of kind {}".format(kind_image(k))
Exemplo n.º 4
0
    def check_declarations(self, decl):
        decl_col = -1
        colon_col = -1
        subtype_col = -1
        assign_col = -1
        line = -1
        while decl != thin.Null_Iir:
            loc = elocations.Get_Start_Location(decl)
            fe, ln, co = utils.Location_To_File_Line_Col(loc)
            if ln <= line:
                self.error(Location.from_node(decl),
                           "one generic/port per line")
            else:
                if co != decl_col and decl_col >= 0:
                    self.error(Location.from_node(decl),
                               "name is not aligned with previous one")

                # Check alignment of ':'
                colon_loc = elocations.Get_Colon_Location(decl)
                _, ln1, colon_co = utils.Location_To_File_Line_Col(colon_loc)
                if colon_co != colon_col and colon_col >= 0:
                    self.error(Location.from_node(decl),
                               "':' is not aligned with previous one")
                colon_col = colon_co

                # Check alignment of subtype.
                st = iirs.Get_Subtype_Indication(decl)
                if st != thin.Null_Iir:
                    st_loc = thinutils.leftest_location(st)
                    _, ln1, st_co = utils.Location_To_File_Line_Col(st_loc)
                    if st_co != subtype_col and subtype_col >= 0:
                        self.error(Location.from_node(decl),
                                   "subtype is not aligned with previous one")
                    subtype_col = st_co

                # Check alignment of ':='
                assign_loc = elocations.Get_Assign_Location(decl)
                if assign_loc != thin.No_Location:
                    _, ln1, assign_co = \
                        utils.Location_To_File_Line_Col(assign_loc)
                    if assign_co != assign_col and assign_col >= 0:
                        self.error(Location.from_node(decl),
                                   "':=' is not aligned with previous one")
                    assign_col = assign_co
            decl_col = co
            line = ln
            decl = iirs.Get_Chain(decl)
Exemplo n.º 5
0
 def check(self, input, ast):
     for du in thinutils.chain_iter(iirs.Get_First_Design_Unit(ast)):
         ent = iirs.Get_Library_Unit(du)
         if iirs.Get_Kind(ent) != iirs.Iir_Kind.Entity_Declaration:
             continue
         gen = iirs.Get_Generic_Chain(ent)
         if gen != thin.Null_Iir:
             self.check_declarations(gen)
         ports = iirs.Get_Port_Chain(ent)
         if ports != thin.Null_Iir:
             self.check_declarations(ports)
             port = ports
             while port != thin.Null_Iir:
                 if not iirs.Get_Has_Mode(port):
                     self.error(Location.from_node(port),
                                "in/out/inout required for port")
                 port = iirs.Get_Chain(port)
Exemplo n.º 6
0
 def chk_case_alternatives(self, alt, level):
     when_loc = None
     while alt != thin.Null_Iir:
         alt_loc = iirs.Get_Location(alt)
         if not iirs.Get_Same_Alternative_Flag(alt):
             # Indentation of 'when'
             when_loc = alt_loc
             self.chk_level(alt, alt_loc, level)
             stmts = iirs.Get_Associated_Chain(alt)
             if nodeutils.is_one_stmt(stmts) \
                and nodeutils.is_same_line(iirs.Get_Location(stmts),
                                           alt_loc):
                 # This is ok (providing this is a simple statement...)
                 # TODO
                 pass
             else:
                 self.chk_sequential(stmts, level + self._l)
         elif not nodeutils.is_same_line(alt_loc, when_loc):
             self.chk_level(alt, alt_loc, level + 3)
         alt = iirs.Get_Chain(alt)
Exemplo n.º 7
0
def chain_iter(n):
    """Iterate of a chain headed by node n"""
    while n != Null_Iir:
        yield n
        n = iirs.Get_Chain(n)
Exemplo n.º 8
0
    def execute(self, files):
        inputs = []
        props = ['synth']
        # First file
        for filename in files:
            if filename.startswith('--'):
                # Handle properties
                if filename == '--import':
                    props = ['import']
                elif filename == '--synth':
                    props = ['synth']
                elif filename == '--top':
                    props = ['synth', 'top']
                elif filename == '--tb':
                    props = ['tb']
                else:
                    fatal("unknown property '{0}'".format(filename))
                continue

            # Read the file
            fid = thin.Get_Identifier(filename.encode('utf-8'))
            fe = thin.Read_Source_File(0, fid)
            if fe == thin.No_Source_File_Entry:
                fatal('cannot open {0}'.format(filename))

            fbuf = thin.Get_File_Buffer(fe)
            flen = thin.Get_File_Length(fe)

            # Not very efficient (it copies the string), but let's use it
            # for now.
            filebuf = ctypes.string_at(fbuf, flen)

            input = RuleInput(filename, fe)
            input.filebuf = filebuf
            input.props = props
            inputs.append(input)

            if 'import' not in input.props:
                self._nbr_files += 1

                # Again, not very efficient (creates the substrings).
                flines = filebuf.splitlines(True)

                loc = Location(filename)
                for r in self._file_rules:
                    r.check(loc, flines)

        # Then tokens
        thin.Scanner.Flag_Comment.value = True
        for input in inputs:
            if 'import' not in input.props:
                thin.Scanner.Set_File(input.fe)
                filebuf = input.filebuf
                while True:
                    thin.Scanner.Scan()
                    tok = thin.Scanner.Current_Token.value
                    loc = TokLocation(input.filename,
                                      thin.Scanner.Get_Current_Line(),
                                      thin.Scanner.Get_Token_Column(),
                                      thin.Scanner.Get_Token_Position(),
                                      thin.Scanner.Get_Position())
                    if tok == tokens.Tok.Comment:
                        input.comments[loc.line] = (loc.start, loc.end)
                    for r in self._lex_rules:
                        r.check(loc, filebuf, tok)
                    if tok == tokens.Tok.Eof:
                        break
                thin.Scanner.Close_File()
        if not (self._syntax_rules or self._syntax_node_rules or
                self._sem_rules or self._sem_node_rules or self._synth_rules):
            return

        # Then syntax
        # The parser doesn't handle comments
        thin.Scanner.Flag_Comment.value = False
        # Keep extra locations
        thin.Flags.Flag_Elocations.value = True
        # Keep all parenthesis
        thin.Parse.Flag_Parse_Parenthesis.value = True
        # Be sure to initialize std and work (and only once).
        # Humm, not very elegant.
        if thin.Get_Libraries_Chain() == thin.Null_Iir:
            thin.analyze_init()
        for input in inputs:
            thin.Scanner.Set_File(input.fe)
            loc = Location(input.filename)
            input.ast = thin.Parse.Parse_Design_File()
            if 'import' not in input.props:
                for r in self._syntax_rules:
                    r.check(input, input.ast)
                if self._syntax_node_rules:
                    for n in thinutils.nodes_iter(input.ast):
                        for r in self._syntax_node_rules:
                            r.check(loc, n)
            thin.Scanner.Close_File()

        # Then semantic
        if self._sem_rules or self._sem_node_rules or self._synth_rules:
            # Reduce Canon
            thin.Canon.Flag_Concurrent_Stmts.value = False
            thin.Canon.Flag_Configurations.value = False
            thin.Canon.Flag_Associations.value = False
            # First add all units in the work library, so that they they are
            # known by the analyzer.
            for input in inputs:
                unit_ast = iirs.Get_First_Design_Unit(input.ast)
                while unit_ast != thin.Null_Iir:
                    # Detach the unit from its design file
                    next_unit_ast = iirs.Get_Chain(unit_ast)
                    iirs.Set_Chain(unit_ast, thin.Null_Iir)
                    # Add
                    thin.Add_Design_Unit_Into_Library(unit_ast, False)
                    input.units_ast.append(unit_ast)
                    unit_ast = next_unit_ast
            # Handle all unit
            for input in inputs:
                if 'import' not in input.props:
                    for unit in input.units_ast:
                        if iirs.Get_Library_Unit(unit) == thin.Null_Iir:
                            # Over-written.
                            # FIXME: remove from the list ?
                            continue
                        # Be sure the unit was analyzed. It could have been
                        # already analyzed if referenced. And a unit cannot be
                        # analyzed twice.
                        if iirs.Get_Date_State(unit) == iirs.Date_State.Parse:
                            thin.Finish_Compilation(unit, False)
                            iirs.Set_Date_State(unit, iirs.Date_State.Analyze)
                        for r in self._sem_rules:
                            r.check(input, unit)
                        for n in thinutils.nodes_iter(unit):
                            for r in self._sem_node_rules:
                                r.check(input, n)

            for input in inputs:
                if 'synth' in input.props:
                    for unit in input.units_ast:
                        if iirs.Get_Library_Unit(unit) == thin.Null_Iir:
                            # Over-written.
                            continue
                        for r in self._synth_rules:
                            r.check(input, unit)
Exemplo n.º 9
0
def is_one_alt(alts):
    assert not iirs.Get_Same_Alternative_Flag(alts)
    next_alt = iirs.Get_Chain(alts)
    return next_alt == thin.Null_Iir \
        or not iirs.Get_Same_Alternative_Flag(next_alt)
Exemplo n.º 10
0
def is_one_stmt(chain):
    return chain != thin.Null_Iir \
        and iirs.Get_Chain(chain) == thin.Null_Iir