def chk_sequential(self, head, level): nlevel = level + self._l for n in thinutils.chain_iter(head): k = iirs.Get_Kind(n) self.chk_level(n, iirs.Get_Location(n), level) if k == iirs.Iir_Kind.If_Statement: self.chk_if_stmt(n, level) elif (k == iirs.Iir_Kind.For_Loop_Statement or k == iirs.Iir_Kind.While_Loop_Statement): self.chk_line_or_col( n, iirs.Get_Location(n), elocs.Get_Loop_Location(n)) self.chk_sequential( iirs.Get_Sequential_Statement_Chain(n), nlevel) self.chk_level(n, elocs.Get_End_Location(n), level) elif k == iirs.Iir_Kind.Case_Statement: alts = iirs.Get_Case_Statement_Alternative_Chain(n) self.chk_case_alternatives(alts, nlevel) elif (k == iirs.Iir_Kind.Wait_Statement or k == iirs.Iir_Kind.Return_Statement or k == iirs.Iir_Kind.Assertion_Statement or k == iirs.Iir_Kind.Report_Statement or k == iirs.Iir_Kind.Procedure_Call_Statement or k == iirs.Iir_Kind.Null_Statement or k == iirs.Iir_Kind.Exit_Statement or k == iirs.Iir_Kind.Next_Statement): pass elif (k == iirs.Iir_Kind.Simple_Signal_Assignment_Statement or k == iirs.Iir_Kind.Variable_Assignment_Statement): pass else: assert False, "Indent: unhandled node {}".format( thinutils.kind_image(k))
def extract_use(self, n): if iirs.Get_Use_Clause_Chain(n): self.error(Location.from_node(n), "there must be an one package per use") name = iirs.Get_Selected_Name(n) if iirs.Get_Kind(name) != iirs.Iir_Kind.Selected_By_All_Name: self.error(Location.from_node(n), "missing .all after package name") return [] prefix = iirs.Get_Prefix(name) if iirs.Get_Kind(prefix) != iirs.Iir_Kind.Selected_Name: self.error(Location.from_node(n), "use-d name must be a selected name") return [] lib_prefix = iirs.Get_Prefix(prefix) if iirs.Get_Kind(lib_prefix) != iirs.Iir_Kind.Simple_Name: self.error(Location.from_node(n), "use-d prefix name must be a simple name") return [] loc = iirs.Get_Location(n) _, ln, _ = utils.Location_To_File_Line_Col(loc) return [{'kind': 'use', 'node': n, 'name': iirs.Get_Identifier(prefix), 'library': iirs.Get_Identifier(lib_prefix), 'line': ln}]
def chk_if_stmt(self, n): while n != thin.Null_Iir: loc = iirs.Get_Location(n) then_loc = elocs.Get_Then_Location(n) if then_loc != 0: self.chk_line_or_col(n, loc, then_loc) n = iirs.Get_Else_Clause(n)
def leftest_location(n): while True: if n == Null_Iir: return No_Location k = iirs.Get_Kind(n) if k == iirs.Iir_Kind.Array_Subtype_Definition: n = iirs.Get_Subtype_Type_Mark(n) else: return iirs.Get_Location(n)
def chk_if_stmt(self, n, level): nlevel = level + self._l while n != thin.Null_Iir: # if/else/elsif loc = iirs.Get_Location(n) self.chk_level(n, loc, level) self.chk_sequential(iirs.Get_Sequential_Statement_Chain(n), nlevel) self.chk_level(n, elocs.Get_End_Location(n), level) n = iirs.Get_Else_Clause(n)
def chk_context_clauses(self, parent, level): for n in thinutils.chain_iter(iirs.Get_Context_Items(parent)): k = iirs.Get_Kind(n) if k == iirs.Iir_Kind.Library_Clause: self.chk_level(n, elocs.Get_Start_Location(n), level) # Check: same line for next clauses elif k == iirs.Iir_Kind.Use_Clause: self.chk_level(n, iirs.Get_Location(n), level) # Check: same line for next clauses else: assert False, "unhandled context clause"
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)
def get_identifier_str(n): """Return the identifier (as it appears in the sources) for node n. The node n must have an identifier field. There is no case conversion.""" ident = iirs.Get_Identifier(n) id_len = thin.Get_Name_Length(ident) loc = iirs.Get_Location(n) fe = thin.Location_To_File(loc) pos = thin.Location_File_To_Pos(loc, fe) fptr = thin.Get_File_Buffer(fe) return ctypes.string_at(fptr + pos, id_len).decode('latin-1')
def chk_concurrent(self, head, level): nlevel = level + self._l for n in thinutils.chain_iter(head): self.chk_level(n, iirs.Get_Location(n), level) k = iirs.Get_Kind(n) if k == iirs.Iir_Kind.Component_Instantiation_Statement: # TODO pass elif (k == iirs.Iir_Kind.Concurrent_Assertion_Statement or k == iirs.Iir_Kind.Concurrent_Simple_Signal_Assignment or k == iirs.Iir_Kind.Concurrent_Conditional_Signal_Assignment or k == iirs.Iir_Kind.Concurrent_Selected_Signal_Assignment): pass elif k == iirs.Iir_Kind.Concurrent_Procedure_Call_Statement: pass elif k == iirs.Iir_Kind.Block_Statement: self.chk_declarations(iirs.Get_Declaration_Chain(n), nlevel) self.chk_level(n, elocs.Get_Begin_Location(n), level) self.chk_concurrent( iirs.Get_Concurrent_Statement_Chain(n), nlevel) self.chk_level(n, elocs.Get_End_Location(n), level) elif k == iirs.Iir_Kind.For_Generate_Statement: self.chk_line_or_col( n, iirs.Get_Location(n), elocs.Get_Generate_Location(n)) self.chk_generate_body( iirs.Get_Generate_Statement_Body(n), level) self.chk_level(n, elocs.Get_End_Location(n), level) elif k == iirs.Iir_Kind.If_Generate_Statement: self.chk_line_or_col( n, iirs.Get_Location(n), elocs.Get_Generate_Location(n)) self.chk_generate_body( iirs.Get_Generate_Statement_Body(n), level) self.chk_level(n, elocs.Get_End_Location(n), level) elif (k == iirs.Iir_Kind.Sensitized_Process_Statement or k == iirs.Iir_Kind.Process_Statement): self.chk_declarations(iirs.Get_Declaration_Chain(n), nlevel) self.chk_level(n, elocs.Get_Begin_Location(n), level) self.chk_sequential( iirs.Get_Sequential_Statement_Chain(n), nlevel) self.chk_level(n, elocs.Get_End_Location(n), level)
def check(self, input, ast): for n in thinutils.constructs_iter(ast): k = iirs.Get_Kind(n) if k in iirs.Iir_Kinds.Subprogram_Body \ or k in iirs.Iir_Kinds.Process_Statement: for n1 in thinutils.sequential_iter(n): k = iirs.Get_Kind(n1) if k == iirs.Iir_Kind.If_Statement: self.chk_if_stmt(n1) elif (k == iirs.Iir_Kind.For_Loop_Statement or k == iirs.Iir_Kind.While_Loop_Statement): self.chk_line_or_col(n1, iirs.Get_Location(n1), elocs.Get_Loop_Location(n1)) elif k == iirs.Iir_Kind.Case_Statement: pass elif k == iirs.Iir_Kind.For_Generate_Statement: self.chk_line_or_col(n, iirs.Get_Location(n), elocs.Get_Generate_Location(n)) elif k == iirs.Iir_Kind.If_Generate_Statement: self.chk_line_or_col(n, iirs.Get_Location(n), elocs.Get_Generate_Location(n))
def chk_declarations(self, head, level): nlevel = level + self._l for n in thinutils.chain_iter(head): k = iirs.Get_Kind(n) if k == iirs.Iir_Kind.Constant_Declaration \ or k == iirs.Iir_Kind.Signal_Declaration \ or k == iirs.Iir_Kind.Variable_Declaration \ or k == iirs.Iir_Kind.File_Declaration \ or k == iirs.Iir_Kind.Object_Alias_Declaration \ or k == iirs.Iir_Kind.Attribute_Declaration \ or k == iirs.Iir_Kind.Attribute_Specification: self.chk_level(n, elocs.Get_Start_Location(n), level) elif (k == iirs.Iir_Kind.Configuration_Specification or k == iirs.Iir_Kind.Disconnection_Specification): self.chk_level(n, iirs.Get_Location(n), level) elif (k == iirs.Iir_Kind.Subtype_Declaration or k == iirs.Iir_Kind.Type_Declaration or k == iirs.Iir_Kind.Anonymous_Type_Declaration): self.chk_level(n, elocs.Get_Start_Location(n), level) elif k == iirs.Iir_Kind.Component_Declaration: self.chk_level(n, elocs.Get_Start_Location(n), level) self.chk_level(n, elocs.Get_Generic_Location(n), nlevel) self.chk_level(n, elocs.Get_Port_Location(n), nlevel) self.chk_level(n, elocs.Get_End_Location(n), level) elif (k == iirs.Iir_Kind.Function_Declaration or k == iirs.Iir_Kind.Procedure_Declaration): self.chk_level(n, elocs.Get_Start_Location(n), level) elif (k == iirs.Iir_Kind.Function_Body or k == iirs.Iir_Kind.Procedure_Body): self.chk_declarations(iirs.Get_Declaration_Chain(n), nlevel) self.chk_level(n, elocs.Get_Begin_Location(n), level) self.chk_sequential( iirs.Get_Sequential_Statement_Chain(n), nlevel) self.chk_level(n, elocs.Get_End_Location(n), level) # check start elif k == iirs.Iir_Kind.Use_Clause: self.chk_level(n, iirs.Get_Location(n), level) else: assert False, "unhandled declaration {}".format( thinutils.kind_image(k))
def check(self, input, ast): for node in thinutils.concurrent_stmts_iter(ast): if iirs.Get_Kind(node) not in iirs.Iir_Kinds.Process_Statement: continue if iirs.Get_Label(node) != thin.Null_Identifier: continue loc = iirs.Get_Location(node) fil = thin.Location_To_File(loc) line = thin.Location_File_To_Line(loc, fil) if input.comments.get(line - 1, None) is None: self.error( Location.from_node(node), "missing label or comment for process")
def extract_library(self, n): name = iirs.Get_Identifier(n) if iirs.Get_Has_Identifier_List(n): self.error(Location.from_node(n), "library must be alone") if name == std_names.Name.Std: self.error(Location.from_node(n), "do not use library clause for 'std'") elif name == std_names.Name.Work: self.error(Location.from_node(n), "do not use library clause for 'work'") loc = iirs.Get_Location(n) _, ln, _ = utils.Location_To_File_Line_Col(loc) return [{'kind': 'library', 'node': n, 'name': name, 'line': ln}]
def check_parenthesis(self, expr): if expr == thin.Null_Iir: # For else clause. return if iirs.Get_Kind(expr) != iirs.Iir_Kind.Parenthesis_Expression: return left_loc = iirs.Get_Location(expr) right_loc = elocations.Get_Right_Paren_Location(expr) fe = thin.Location_To_File(left_loc) assert fe == thin.Location_To_File(right_loc) left_line = thin.Location_File_To_Line(left_loc, fe) right_line = thin.Location_File_To_Line(right_loc, fe) if left_line != right_line: # Assume that's for grouping return self.error(Location.from_node(expr), "useless parenthesis around expression")
def find_handler(self, n): """Return the function to comparse the definition with the reference.""" dfn_loc = iirs.Get_Location(n) dfn_file = thin.Location_To_File(dfn_loc) handler = self._handlers.get(dfn_file, None) if handler: return handler if dfn_loc == thin.Library_Location.value: handler = self.get_lower else: while iirs.Get_Kind(n) != iirs.Iir_Kind.Library_Declaration: n = iirs.Get_Parent(n) lib_id = iirs.Get_Identifier(n) if lib_id == std_names.Name.Std: handler = self.get_standard elif lib_id == std_names.Name.Ieee: handler = self.get_lower else: handler = self.get_user self._handlers[dfn_file] = handler return handler
def from_node(cls, n): return Location.from_location(iirs.Get_Location(n))