From 020a16072923a66ae0985be618fd32310aa87242 Mon Sep 17 00:00:00 2001 From: Yong He Date: Wed, 16 Jul 2025 23:43:06 -0700 Subject: Improve lookup performance. (#7798) * Improve lookup performance. * Cleanup. * Improve autocompletion latency. --- source/slang/slang-parser.cpp | 54 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 6 deletions(-) (limited to 'source/slang/slang-parser.cpp') diff --git a/source/slang/slang-parser.cpp b/source/slang/slang-parser.cpp index 590954bd2..a12f216b1 100644 --- a/source/slang/slang-parser.cpp +++ b/source/slang/slang-parser.cpp @@ -4861,6 +4861,31 @@ static void addSpecialGLSLModifiersBasedOnType(Parser* parser, Decl* decl, Modif } } } + +static EnumDecl* isUnscopedEnum(Decl* decl) +{ + EnumDecl* enumDecl = as(decl); + if (!enumDecl) + return nullptr; + for (auto mod : enumDecl->modifiers) + { + if (as(mod)) + { + return enumDecl; + } + else if (auto uncheckedAttribute = as(mod)) + { + // We have to perform an ugly string comparison here, because the attributes + // haven't been checked during parsing. + if (getText(uncheckedAttribute->keywordName) == "UnscopedEnum") + { + return enumDecl; + } + } + } + return nullptr; +} + // Finish up work on a declaration that was parsed static void CompleteDecl( Parser* parser, @@ -4936,6 +4961,24 @@ static void CompleteDecl( { // Make sure the decl is properly nested inside its lexical parent AddMember(containerDecl, decl); + + // As a special case, if we are adding an unscoped enum to container, we should also + // create static const decls for each enum case and add them to the container. + if (auto enumDecl = isUnscopedEnum(decl)) + { + for (auto enumCase : enumDecl->getMembersOfType()) + { + auto staticConstDecl = parser->astBuilder->create(); + staticConstDecl->nameAndLoc = enumCase->nameAndLoc; + addModifier(staticConstDecl, parser->astBuilder->create()); + addModifier(staticConstDecl, parser->astBuilder->create()); + auto valueExpr = parser->astBuilder->create(); + valueExpr->declRef = DeclRef(enumCase); + staticConstDecl->initExpr = valueExpr; + staticConstDecl->loc = enumCase->loc; + AddMember(containerDecl, staticConstDecl); + } + } } } @@ -5556,17 +5599,16 @@ static Decl* parseEnumDecl(Parser* parser) decl->nameAndLoc = expectIdentifier(parser); } - // If the type needs to be unscoped, insert modifiers to make it so. - if (isUnscoped) - { - addModifier(decl, parser->astBuilder->create()); - addModifier(decl, parser->astBuilder->create()); - } return parseOptGenericDecl( parser, [&](GenericDecl* genericParent) { + // If the type needs to be unscoped, insert modifiers to make it so. + if (isUnscoped && !genericParent) + { + addModifier(decl, parser->astBuilder->create()); + } parseOptionalInheritanceClause(parser, decl); maybeParseGenericConstraints(parser, genericParent); parser->ReadToken(TokenType::LBrace); -- cgit v1.2.3