summaryrefslogtreecommitdiff
path: root/source/slang/slang-check-decl.cpp
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2024-02-20 15:37:11 -0800
committerGitHub <noreply@github.com>2024-02-20 15:37:11 -0800
commita62be597990966b9516995650baf750ee6a0146b (patch)
tree1741b3d5b5859319f278aa6ab821a2f801fd8e08 /source/slang/slang-check-decl.cpp
parent4d20fd329956ac89408b1628a8291fea01bc9a6d (diff)
Support link time type specialization. (#3604)
Diffstat (limited to 'source/slang/slang-check-decl.cpp')
-rw-r--r--source/slang/slang-check-decl.cpp40
1 files changed, 40 insertions, 0 deletions
diff --git a/source/slang/slang-check-decl.cpp b/source/slang/slang-check-decl.cpp
index 3fb2725e2..dc888ccda 100644
--- a/source/slang/slang-check-decl.cpp
+++ b/source/slang/slang-check-decl.cpp
@@ -302,6 +302,8 @@ namespace Slang
void visitFunctionDeclBase(FunctionDeclBase* funcDecl);
void visitParamDecl(ParamDecl* paramDecl);
+
+ void visitAggTypeDecl(AggTypeDecl* aggTypeDecl);
};
template<typename VisitorType>
@@ -1705,6 +1707,15 @@ namespace Slang
}
}
+ // Propagate type tags.
+ if (auto parentAggTypeDecl = as<AggTypeDecl>(getParentDecl(varDecl)))
+ {
+ if (auto varDeclRefType = as<DeclRefType>(varDecl->type.type))
+ {
+ parentAggTypeDecl->unionTagsWith(getTypeTags(varDecl->type.type));
+ }
+ }
+
checkVisibility(varDecl);
}
@@ -1722,11 +1733,20 @@ namespace Slang
{
addModifier(structDecl, m_astBuilder->create<NVAPIMagicModifier>());
}
+
+ if (structDecl->hasModifier<ExternModifier>())
+ {
+ structDecl->addTag(TypeTag::Incomplete);
+ }
checkVisibility(structDecl);
}
void SemanticsDeclHeaderVisitor::visitClassDecl(ClassDecl* classDecl)
{
+ if (classDecl->hasModifier<ExternModifier>())
+ {
+ classDecl->addTag(TypeTag::Incomplete);
+ }
checkVisibility(classDecl);
}
@@ -1812,6 +1832,13 @@ namespace Slang
varDecl->initExpr = CompleteOverloadCandidate(overloadContext, *overloadContext.bestCandidate);
}
}
+ if (auto elementType = getBufferElementType(varDecl->getType()))
+ {
+ if (doesTypeHaveTag(elementType, TypeTag::Incomplete))
+ {
+ getSink()->diagnose(varDecl->type.exp->loc, Diagnostics::incompleteTypeCannotBeUsedInBuffer, elementType);
+ }
+ }
maybeRegisterDifferentiableType(getASTBuilder(), varDecl->getType());
}
@@ -4784,6 +4811,9 @@ namespace Slang
SubtypeWitness* subIsSuperWitness,
WitnessTable* witnessTable)
{
+ if (witnessTable->isExtern)
+ return true;
+
if (auto supereclRefType = as<DeclRefType>(superType))
{
auto superTypeDeclRef = supereclRefType->getDeclRef();
@@ -4896,6 +4926,7 @@ namespace Slang
witnessTable = new WitnessTable();
witnessTable->baseType = superType;
witnessTable->witnessedType = subType;
+ witnessTable->isExtern = parentDecl->hasModifier<ExternModifier>();
inheritanceDecl->witnessTable = witnessTable;
}
@@ -5179,6 +5210,7 @@ namespace Slang
// order) is allowed to declare a base `class` type.
//
SLANG_OUTER_SCOPE_CONTEXT_DECL_RAII(this, decl);
+
Index inheritanceClauseCounter = 0;
for (auto inheritanceDecl : decl->getMembersOfType<InheritanceDecl>())
{
@@ -6544,6 +6576,14 @@ namespace Slang
}
}
+ void SemanticsDeclBodyVisitor::visitAggTypeDecl(AggTypeDecl* aggTypeDecl)
+ {
+ if (aggTypeDecl->hasTag(TypeTag::Incomplete) && aggTypeDecl->hasModifier<HLSLExportModifier>())
+ {
+ getSink()->diagnose(aggTypeDecl->loc, Diagnostics::cannotExportIncompleteType, aggTypeDecl);
+ }
+ }
+
void SemanticsDeclHeaderVisitor::cloneModifiers(Decl* dest, Decl* src)
{
dest->modifiers = src->modifiers;