@@ -506,8 +506,15 @@ struct ResolutionPass final
506
506
return allocator.allocate <AST::ProcessorInstanceRef> (qi.context , *p);
507
507
508
508
if (auto pa = cast<AST::ProcessorAliasDeclaration> (item))
509
+ {
509
510
if (pa->isResolved ())
510
- return allocator.allocate <AST::ProcessorRef> (qi.context , *pa->targetProcessor );
511
+ {
512
+ if (currentConnectionEndpoint != nullptr )
513
+ return getOrCreateImplicitProcessorInstance (qi.context , *pa->resolvedProcessor , {});
514
+
515
+ return allocator.allocate <AST::ProcessorRef> (qi.context , *pa->resolvedProcessor );
516
+ }
517
+ }
511
518
512
519
if (auto e = cast<AST::EndpointDeclaration> (item))
513
520
return ASTUtilities::createEndpointRef (allocator, qi.context , *e);
@@ -1638,6 +1645,68 @@ struct ResolutionPass final
1638
1645
using ArgList = decltype (AST::CommaSeparatedList::items);
1639
1646
using ParamList = decltype (AST::ModuleBase::specialisationParams);
1640
1647
1648
+ bool validateSpecialisationParam (AST::ASTObject& param) const
1649
+ {
1650
+ if (auto u = cast<AST::UsingDeclaration> (param))
1651
+ {
1652
+ if (u->targetType == nullptr )
1653
+ return true ;
1654
+
1655
+ if (AST::isResolvedAsType (*u->targetType ))
1656
+ return true ;
1657
+
1658
+ if (! ignoreErrors)
1659
+ u->targetType ->context .throwError (Errors::expectedType ());
1660
+
1661
+ return false ;
1662
+ }
1663
+ else if (auto pa = cast<AST::ProcessorAliasDeclaration> (param))
1664
+ {
1665
+ if (pa->targetProcessor == nullptr )
1666
+ return true ;
1667
+
1668
+ pa->resolvedProcessor = pa->targetProcessor ->getAsProcessor ();
1669
+
1670
+ if (pa->resolvedProcessor != nullptr )
1671
+ return true ;
1672
+
1673
+ if (! ignoreErrors)
1674
+ pa->targetProcessor ->context .throwError (Errors::expectedProcessorName ());
1675
+
1676
+ return false ;
1677
+ }
1678
+ else if (auto v = cast<AST::VariableDeclaration> (param))
1679
+ {
1680
+ if (v->initialValue == nullptr )
1681
+ return true ;
1682
+
1683
+ if (AST::isResolvedAsValue (*v->initialValue ))
1684
+ return true ;
1685
+
1686
+ if (! ignoreErrors)
1687
+ v->initialValue ->context .throwError (Errors::expectedValue ());
1688
+
1689
+ return false ;
1690
+ }
1691
+ else if (auto n = cast<AST::NamespaceAliasDeclaration> (param))
1692
+ {
1693
+ if (n->targetNamespace == nullptr )
1694
+ return true ;
1695
+
1696
+ n->resolvedNamespace = n->targetNamespace ->getAsNamespace ();
1697
+
1698
+ if (n->resolvedNamespace != nullptr )
1699
+ return true ;
1700
+
1701
+ if (! ignoreErrors)
1702
+ n->targetNamespace ->context .throwError (Errors::expectedNamespaceName ());
1703
+
1704
+ return false ;
1705
+ }
1706
+
1707
+ return false ;
1708
+ }
1709
+
1641
1710
bool canResolveSpecialisationArg (AST::Expression& arg, AST::ASTObject& param) const
1642
1711
{
1643
1712
if (auto u = cast<AST::UsingDeclaration> (param))
@@ -1650,8 +1719,7 @@ struct ResolutionPass final
1650
1719
1651
1720
return false ;
1652
1721
}
1653
-
1654
- if (auto pa = cast<AST::ProcessorAliasDeclaration> (param))
1722
+ else if (auto pa = cast<AST::ProcessorAliasDeclaration> (param))
1655
1723
{
1656
1724
if (auto prf = cast<AST::ProcessorInstanceRef> (arg))
1657
1725
return prf->processorInstance .specialisationArgs == nullptr
@@ -1665,8 +1733,7 @@ struct ResolutionPass final
1665
1733
1666
1734
return false ;
1667
1735
}
1668
-
1669
- if (auto v = cast<AST::VariableDeclaration> (param))
1736
+ else if (auto v = cast<AST::VariableDeclaration> (param))
1670
1737
{
1671
1738
if (AST::isResolvedAsValue (arg))
1672
1739
{
@@ -1679,8 +1746,7 @@ struct ResolutionPass final
1679
1746
1680
1747
return false ;
1681
1748
}
1682
-
1683
- if (auto n = cast<AST::NamespaceAliasDeclaration> (param))
1749
+ else if (auto n = cast<AST::NamespaceAliasDeclaration> (param))
1684
1750
{
1685
1751
if (arg.isResolved ())
1686
1752
{
@@ -1697,11 +1763,49 @@ struct ResolutionPass final
1697
1763
return false ;
1698
1764
}
1699
1765
1766
+ bool validateSpecialisationArgs (const ArgList& args, const ParamList& params) const
1767
+ {
1768
+ for (size_t i = 0 ; i < params.size (); ++i)
1769
+ if (! validateSpecialisationParam (params[i]))
1770
+ return false ;
1771
+
1772
+ if (args.size () == params.size ())
1773
+ return true ;
1774
+
1775
+ if (args.size () > params.size ())
1776
+ return false ;
1777
+
1778
+ for (auto i = args.size (); i < params.size (); i++)
1779
+ {
1780
+ if (auto x = cast<AST::UsingDeclaration> (params[i]))
1781
+ {
1782
+ if (x->targetType == nullptr )
1783
+ return false ;
1784
+ }
1785
+ else if (auto n = cast<AST::NamespaceAliasDeclaration> (params[i]))
1786
+ {
1787
+ if (n->resolvedNamespace == nullptr )
1788
+ return false ;
1789
+ }
1790
+ else if (auto p = cast<AST::ProcessorAliasDeclaration> (params[i]))
1791
+ {
1792
+ if (p->resolvedProcessor == nullptr )
1793
+ return false ;
1794
+ }
1795
+ else
1796
+ {
1797
+ return false ;
1798
+ }
1799
+ }
1800
+
1801
+ return true ;
1802
+ }
1803
+
1700
1804
bool canResolveAllSpecialisationArgs (const ArgList& args, const ParamList& params) const
1701
1805
{
1702
- SOUL_ASSERT (args.size () = = params.size ());
1806
+ SOUL_ASSERT (args.size () < = params.size ());
1703
1807
1704
- for (size_t i = 0 ; i < params .size (); ++i)
1808
+ for (size_t i = 0 ; i < args .size (); ++i)
1705
1809
if (! canResolveSpecialisationArg (args[i].get (), params[i]))
1706
1810
return false ;
1707
1811
@@ -1720,7 +1824,7 @@ struct ResolutionPass final
1720
1824
if (auto pa = cast<AST::ProcessorAliasDeclaration> (param))
1721
1825
{
1722
1826
auto pr = arg.getAsProcessor ();
1723
- pa->targetProcessor = *pr;
1827
+ pa->resolvedProcessor = *pr;
1724
1828
return ;
1725
1829
}
1726
1830
@@ -1746,10 +1850,10 @@ struct ResolutionPass final
1746
1850
1747
1851
static void resolveAllSpecialisationArgs (const ArgList& args, ParamList& params)
1748
1852
{
1749
- SOUL_ASSERT (args.size () = = params.size ());
1853
+ SOUL_ASSERT (args.size () < = params.size ());
1750
1854
1751
- for (size_t i = 0 ; i < params .size (); ++i)
1752
- resolveSpecialisationArg (args[i]. get () , params[i]);
1855
+ for (size_t i = 0 ; i < args .size (); ++i)
1856
+ resolveSpecialisationArg (args[i], params[i]);
1753
1857
1754
1858
params.clear ();
1755
1859
}
@@ -1778,8 +1882,8 @@ struct ResolutionPass final
1778
1882
auto numArgs = specialisationArgs.size ();
1779
1883
auto target = pool_ref<AST::ProcessorBase> (*p);
1780
1884
1781
- if (target->specialisationParams . size () != numArgs )
1782
- instance.context .throwError (Errors::wrongNumArgsForProcessor (target->getFullyQualifiedPath ()));
1885
+ if (! validateSpecialisationArgs (specialisationArgs, target->specialisationParams ) )
1886
+ instance.context .throwError (Errors::wrongNumArgsForNamespace (target->getFullyQualifiedPath ()));
1783
1887
1784
1888
auto & graph = *cast<AST::Graph> (instance.getParentScope ()->findProcessor ());
1785
1889
SanityCheckPass::RecursiveGraphDetector::check (graph);
@@ -1858,11 +1962,10 @@ struct ResolutionPass final
1858
1962
return instance;
1859
1963
1860
1964
auto specialisationArgs = AST::CommaSeparatedList::getAsExpressionList (instance.specialisationArgs );
1861
- auto numArgs = specialisationArgs.size ();
1862
1965
1863
1966
if (auto target = instance.targetNamespace ->getAsNamespace ())
1864
1967
{
1865
- if (target->specialisationParams . size () != numArgs )
1968
+ if (! validateSpecialisationArgs (specialisationArgs, target->specialisationParams ) )
1866
1969
instance.context .throwError (Errors::wrongNumArgsForNamespace (target->getFullyQualifiedPath ()));
1867
1970
1868
1971
if (canResolveAllSpecialisationArgs (specialisationArgs, target->specialisationParams ))
@@ -1884,10 +1987,10 @@ struct ResolutionPass final
1884
1987
1885
1988
AST::Namespace& getOrAddNamespaceSpecialisation (AST::Namespace& namespaceToClone, const ArgList& specialisationArgs)
1886
1989
{
1887
- SOUL_ASSERT (namespaceToClone. specialisationParams . size () == specialisationArgs .size ());
1990
+ SOUL_ASSERT (specialisationArgs. size () <= namespaceToClone. specialisationParams .size ());
1888
1991
1889
1992
// No parameters, just use the existing namespace
1890
- if (specialisationArgs .empty ())
1993
+ if (namespaceToClone. specialisationParams .empty ())
1891
1994
return namespaceToClone;
1892
1995
1893
1996
auto instanceKey = ASTUtilities::getSpecialisationSignature (namespaceToClone.specialisationParams , specialisationArgs);
0 commit comments