summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2024-06-12 09:45:26 -0700
committerGitHub <noreply@github.com>2024-06-12 09:45:26 -0700
commit318adcc27b8d89ec1d47c445a93239dd81be0b31 (patch)
tree939ae1ffe9a3e81a17d03e4c92c8ee13c6d822e8 /source
parentec35febb7f1dcc981e83c7ee3e52ab516b50be8a (diff)
Add compiler option to treat enum types as unscoped. (#4354)
Diffstat (limited to 'source')
-rw-r--r--source/slang/slang-lookup.cpp6
-rw-r--r--source/slang/slang-options.cpp4
-rw-r--r--source/slang/slang-parser.cpp28
3 files changed, 35 insertions, 3 deletions
diff --git a/source/slang/slang-lookup.cpp b/source/slang/slang-lookup.cpp
index 5e30e3ce9..c1895d754 100644
--- a/source/slang/slang-lookup.cpp
+++ b/source/slang/slang-lookup.cpp
@@ -224,6 +224,12 @@ static void _lookUpDirectAndTransparentMembers(
}
}
+ // Don't look up transparent members if we are looking for attributes, since
+ // they are always defined at global scope in the stdlib. Trying to lookup transparent
+ // members during attribute lookup can lead to infinite recursion on transparent types.
+ if ((int)request.mask & (int)LookupMask::Attribute)
+ return;
+
for(auto transparentInfo : containerDecl->getTransparentMembers())
{
// The reference to the transparent member should use the same
diff --git a/source/slang/slang-options.cpp b/source/slang/slang-options.cpp
index aefb14deb..04d48c85f 100644
--- a/source/slang/slang-options.cpp
+++ b/source/slang/slang-options.cpp
@@ -347,6 +347,7 @@ void initCommandOptions(CommandOptions& options)
{ OptionKind::SourceEmbedLanguage, "-source-embed-language", "-source-embed-language <language>",
"The language to be used for source embedding. Defaults to C/C++. Currently only C/C++ are supported"},
{ OptionKind::DisableShortCircuit, "-disable-short-circuit", nullptr, "Disable short-circuiting for \"&&\" and \"||\" operations" },
+ { OptionKind::UnscopedEnum, "-unscoped-enum", nullptr, "Treat enums types as unscoped by default."}
{ OptionKind::PreserveParameters, "-preserve-params", nullptr, "Preserve all resource parameters in the output code, even if they are not used by the shader."}
};
@@ -1705,8 +1706,9 @@ SlangResult OptionsParser::_parse(
case OptionKind::NoHLSLBinding:
case OptionKind::NoHLSLPackConstantBufferElements:
case OptionKind::LoopInversion:
+ case OptionKind::UnscopedEnum:
case OptionKind::PreserveParameters:
- linkage->m_optionSet.set(optionKind, true); break;
+ linkage->m_optionSet.set(optionKind, true);
break;
case OptionKind::MatrixLayoutRow:
case OptionKind::MatrixLayoutColumn:
diff --git a/source/slang/slang-parser.cpp b/source/slang/slang-parser.cpp
index f5a217354..3d9f1c199 100644
--- a/source/slang/slang-parser.cpp
+++ b/source/slang/slang-parser.cpp
@@ -4907,14 +4907,38 @@ namespace Slang
// TODO: diagnose this with a warning some day, and move
// toward deprecating it.
//
- AdvanceIf(parser, "class");
+ bool isEnumClass = AdvanceIf(parser, "class");
+ bool isUnscoped = false;
+
+ if (!isEnumClass)
+ {
+ if (parser->options.optionSet.getBoolOption(CompilerOptionName::UnscopedEnum))
+ {
+ isUnscoped = true;
+ }
+ }
AdvanceIf(parser, TokenType::CompletionRequest);
parser->FillPosition(decl);
- decl->nameAndLoc = expectIdentifier(parser);
+ if (parser->tokenReader.peekTokenType() != TokenType::Identifier)
+ {
+ decl->nameAndLoc.name = generateName(parser);
+ decl->nameAndLoc.loc = decl->loc;
+ isUnscoped = true;
+ }
+ else
+ {
+ decl->nameAndLoc = expectIdentifier(parser);
+ }
+ // If the type needs to be unscoped, insert modifiers to make it so.
+ if (isUnscoped)
+ {
+ addModifier(decl, parser->astBuilder->create<UnscopedEnumAttribute>());
+ addModifier(decl, parser->astBuilder->create<TransparentModifier>());
+ }
return parseOptGenericDecl(parser, [&](GenericDecl*)
{