aboutsummaryrefslogtreecommitdiff
path: root/libbuild2
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2023-08-02 09:58:28 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2023-08-02 09:58:28 +0200
commit54a0c41081f2bfd11054c3e7456b6ab4a915f28f (patch)
tree794e167b84f6659fd273c039a5ecdc6274fe3aba /libbuild2
parent934b4f4bdaca78bf8b0fc42331dcf7403b1d8086 (diff)
Diagnose declarations of targets/prerequisites with abstract target types
Diffstat (limited to 'libbuild2')
-rw-r--r--libbuild2/parser.cxx25
-rw-r--r--libbuild2/target.hxx2
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
{