diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2023-08-02 09:58:28 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2023-08-02 09:58:28 +0200 |
commit | 54a0c41081f2bfd11054c3e7456b6ab4a915f28f (patch) | |
tree | 794e167b84f6659fd273c039a5ecdc6274fe3aba | |
parent | 934b4f4bdaca78bf8b0fc42331dcf7403b1d8086 (diff) |
Diagnose declarations of targets/prerequisites with abstract target types
-rw-r--r-- | libbuild2/parser.cxx | 25 | ||||
-rw-r--r-- | libbuild2/target.hxx | 2 |
2 files changed, 26 insertions, 1 deletions
diff --git a/libbuild2/parser.cxx b/libbuild2/parser.cxx index 5d77e2b..9ced841 100644 --- a/libbuild2/parser.cxx +++ b/libbuild2/parser.cxx @@ -172,6 +172,10 @@ namespace build2 tracer& tr) { auto r (p.scope_->find_target_type (n, o, loc)); + + if (r.first.factory == nullptr) + p.fail (loc) << "abstract target type " << r.first.name << "{}"; + return p.ctx->targets.insert ( r.first, // target type move (n.dir), @@ -192,6 +196,10 @@ namespace build2 tracer& tr) { auto r (p.scope_->find_target_type (n, o, loc)); + + if (r.first.factory == nullptr) + p.fail (loc) << "abstract target type " << r.first.name << "{}"; + return p.ctx->targets.find (r.first, // target type n.dir, o.dir, @@ -916,6 +924,8 @@ namespace build2 // Resolve target type. If none is specified, then it's file{}. // + // Note: abstract target type is ok here. + // const target_type* ttype (n.untyped () ? &file::static_type : scope_->find_target_type (n.type)); @@ -2765,6 +2775,9 @@ namespace build2 if (t == nullptr) fail (ploc) << "unknown target type " << n.type; + if (t->factory == nullptr) + fail (ploc) << "abstract target type " << t->name << "{}"; + // Current dir collapses to an empty one. // if (!n.dir.empty ()) @@ -4328,6 +4341,13 @@ namespace build2 if (bt == nullptr) fail (t) << "unknown target type " << bn; + // The derive_target_type() call below does not produce a non-abstract + // type if passed an abstract base. So we ban this for now (it's unclear + // why would someone want to do this). + // + if (bt->factory == nullptr) + fail (t) << "abstract base target type " << bt->name << "{}"; + // Note that the group{foo}<...> syntax is only recognized for group- // based targets and ad hoc buildscript recipes/rules only match group. // (We may want to relax this for member_hint in the future since its @@ -7521,6 +7541,8 @@ namespace build2 if (ttp == nullptr) ppat = pinc = false; + else if (ttp->factory == nullptr) + fail (loc) << "abstract target type " << ttp->name << "{}"; } } @@ -7682,6 +7704,9 @@ namespace build2 ? scope_->find_target_type (*tp) : nullptr); + if (ttp != nullptr && ttp->factory == nullptr) + fail (loc) << "abstract target type " << ttp->name << "{}"; + if (tp == nullptr || ttp != nullptr) { if (pmode == pattern_mode::detect) diff --git a/libbuild2/target.hxx b/libbuild2/target.hxx index 79ec9fa..99383e7 100644 --- a/libbuild2/target.hxx +++ b/libbuild2/target.hxx @@ -2413,7 +2413,7 @@ namespace build2 // in the generic install rule. @@ This is still a TODO. // // Note that handling subsections with man1..9{} is easy, we - // simply specify the extension explicitly, e.g., man{foo.1p}. + // simply specify the extension explicitly, e.g., man1{foo.1p}. // class LIBBUILD2_SYMEXPORT man: public doc { |