Permalink
Browse files

Check for design units that need reanalysing

  • Loading branch information...
nickg committed Apr 15, 2012
1 parent 9cd4f4c commit 1a7a3aedd3d65dcc0f37972b5ddc20257ff14008
Showing with 35 additions and 1 deletion.
  1. +1 −1 src/lib.h
  2. +1 −0 src/parse.y
  3. +33 −0 src/sem.c
View
@@ -1,5 +1,5 @@
//
-// Copyright (C) 2011 Nick Gasson
+// Copyright (C) 2011-2012 Nick Gasson
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
View
@@ -339,6 +339,7 @@ package_decl
: tPACKAGE id tIS package_decl_part tEND opt_package_token opt_id tSEMI
{
$$ = tree_new(T_PACKAGE);
+ tree_set_loc($$, &@$);
tree_set_ident($$, $2);
copy_trees($4, tree_add_decl, $$);
View
@@ -23,6 +23,9 @@
#include <stdarg.h>
#include <string.h>
#include <ctype.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <sys/types.h>
struct ident_list {
ident_t ident;
@@ -277,6 +280,30 @@ static void scope_replace(tree_t t, tree_t with)
scope_replace_at(t, with, top_scope->decls);
}
+static bool sem_check_stale(lib_t lib, tree_t t)
+{
+ // Check if the source file corresponding to t has been modified
+ // more recently than the library unit
+
+ const loc_t *l = tree_loc(t);
+ if (l->file == NULL)
+ return true;
+
+ struct stat st;
+ if (stat(l->file, &st) < 0) {
+ if (errno != ENOENT)
+ fatal_errno("%s", l->file);
+ else
+ return true;
+ }
+
+ if (st.st_mtime > lib_mtime(lib, tree_ident(t)))
+ sem_error(NULL, "source file %s for unit %s has changed and must "
+ "be reanalysed", l->file, istr(tree_ident(t)));
+ else
+ return true;
+}
+
static bool scope_import_unit(context_t ctx, lib_t lib, bool all)
{
// Check we haven't already imported this
@@ -296,6 +323,9 @@ static bool scope_import_unit(context_t ctx, lib_t lib, bool all)
return false;
}
+ if (!sem_check_stale(lib, unit))
+ return false;
+
for (unsigned n = 0; n < tree_decls(unit); n++) {
tree_t decl = tree_decl(unit, n);
if (!sem_declare(decl))
@@ -1760,6 +1790,9 @@ static bool sem_check_arch(tree_t t)
sem_error(t, "missing declaration for entity %s",
istr(tree_ident2(t)));
+ if (!sem_check_stale(lib_work(), e))
+ return false;
+
assert(top_scope == NULL);
scope_push(NULL);

0 comments on commit 1a7a3ae

Please sign in to comment.