summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2017-11-04 16:15:15 -0400
committerYong He <yonghe@outlook.com>2017-11-04 16:15:15 -0400
commit8d19b2b4443101040acaf7d9dce2a7a6affea712 (patch)
tree361c9cd72efd6c31b23360ed235d3f7bbba00177 /source
parent288841f66c808af70ad7687f9704c87075129b18 (diff)
parentcc98fd4606222ec1d18878d5e8278dc32910076b (diff)
Merge branch 'master' of https://github.com/shader-slang/slang
Diffstat (limited to 'source')
-rw-r--r--source/slang/check.cpp46
-rw-r--r--source/slang/diagnostic-defs.h1
-rw-r--r--source/slang/mangle.cpp7
3 files changed, 53 insertions, 1 deletions
diff --git a/source/slang/check.cpp b/source/slang/check.cpp
index b0cda278c..cbdf68bf2 100644
--- a/source/slang/check.cpp
+++ b/source/slang/check.cpp
@@ -3228,6 +3228,46 @@ namespace Slang
decl->SetCheckState(DeclCheckState::Checked);
}
+ // Figure out what type an initializer/constructor declaration
+ // is supposed to return. In most cases this is just the type
+ // declaration that its declaration is nested inside.
+ RefPtr<Type> findResultTypeForConstructorDecl(ConstructorDecl* decl)
+ {
+ // We want to look at the parent of the declaration,
+ // but if the declaration is generic, the parent will be
+ // the `GenericDecl` and we need to skip past that to
+ // the grandparent.
+ //
+ auto parent = decl->ParentDecl;
+ auto genericParent = dynamic_cast<GenericDecl*>(parent);
+ if (genericParent)
+ {
+ parent = genericParent->ParentDecl;
+ }
+
+ // Now look at the type of the parent (or grandparent).
+ if (auto aggTypeDecl = dynamic_cast<AggTypeDecl*>(parent))
+ {
+ // We are nested in an aggregate type declaration,
+ // so the result type of the initializer will just
+ // be the surrounding type.
+ return DeclRefType::Create(
+ getSession(),
+ makeDeclRef(aggTypeDecl));
+ }
+ else if (auto extDecl = dynamic_cast<ExtensionDecl*>(parent))
+ {
+ // We are nested inside an extension, so the result
+ // type needs to be the type being extended.
+ return extDecl->targetType.type;
+ }
+ else
+ {
+ getSink()->diagnose(decl, Diagnostics::initializerNotInsideType);
+ return nullptr;
+ }
+ }
+
void visitConstructorDecl(ConstructorDecl* decl)
{
if (decl->IsChecked(DeclCheckState::Checked)) return;
@@ -3237,6 +3277,12 @@ namespace Slang
{
paramDecl->type = CheckUsableType(paramDecl->type);
}
+
+ // We need to compute the result tyep for this declaration,
+ // since it wasn't filled in for us.
+ decl->ReturnType.type = findResultTypeForConstructorDecl(decl);
+
+
decl->SetCheckState(DeclCheckState::CheckedHeader);
// TODO(tfoley): check body
diff --git a/source/slang/diagnostic-defs.h b/source/slang/diagnostic-defs.h
index cca1c4869..cc7db7eb4 100644
--- a/source/slang/diagnostic-defs.h
+++ b/source/slang/diagnostic-defs.h
@@ -318,6 +318,7 @@ DIAGNOSTIC(38003, Error, entryPointSymbolNotAFunction, "entry point '$0' must be
DIAGNOSTIC(38100, Error, typeDoesntImplementInterfaceRequirement, "type '$0' does not provide required interface member '$1'")
DIAGNOSTIC(38101, Error, thisExpressionOutsideOfTypeDecl, "'this' expression can only be used in members of an aggregate type")
+DIAGNOSTIC(38102, Error, initializerNotInsideType, "an 'init' declaration is only allowed inside a type or 'extension' declaration")
//
// 4xxxx - IL code generation.
diff --git a/source/slang/mangle.cpp b/source/slang/mangle.cpp
index ed17a7ffa..a690e5b74 100644
--- a/source/slang/mangle.cpp
+++ b/source/slang/mangle.cpp
@@ -275,7 +275,12 @@ namespace Slang
emitType(context, GetType(paramDeclRef));
}
- emitType(context, GetResultType(callableDeclRef));
+ // Don't print result type for an initializer/constructor,
+ // since it is implicit in the qualified name.
+ if (!callableDeclRef.As<ConstructorDecl>())
+ {
+ emitType(context, GetResultType(callableDeclRef));
+ }
}
}