From 7f57ea4ad86c2a3eb5a14fef458e711845c1f87e Mon Sep 17 00:00:00 2001 From: Tim Foley Date: Mon, 14 Aug 2017 08:02:03 -0700 Subject: Rename `Name` fields to `name` This is in preparation for using `Name` as a type name. --- source/slang/check.cpp | 8 +++---- source/slang/decl-defs.h | 4 ++-- source/slang/diagnostics.cpp | 2 +- source/slang/emit.cpp | 20 ++++++++-------- source/slang/lookup.cpp | 2 +- source/slang/lower.cpp | 32 ++++++++++++------------- source/slang/parameter-binding.cpp | 2 +- source/slang/parser.cpp | 48 +++++++++++++++++++------------------- source/slang/preprocessor.cpp | 2 +- source/slang/syntax-base-defs.h | 6 ++--- source/slang/syntax.cpp | 2 +- 11 files changed, 64 insertions(+), 64 deletions(-) diff --git a/source/slang/check.cpp b/source/slang/check.cpp index bb0b1b794..6b8617c66 100644 --- a/source/slang/check.cpp +++ b/source/slang/check.cpp @@ -1619,15 +1619,15 @@ namespace Slang { checkDecl(para); - if (paraNames.Contains(para->Name.Content)) + if (paraNames.Contains(para->name.Content)) { if (!isRewriteMode()) { - getSink()->diagnose(para, Diagnostics::parameterAlreadyDefined, para->Name); + getSink()->diagnose(para, Diagnostics::parameterAlreadyDefined, para->name); } } else - paraNames.Add(para->Name.Content); + paraNames.Add(para->name.Content); } this->function = NULL; functionNode->SetCheckState(DeclCheckState::CheckedHeader); @@ -4559,7 +4559,7 @@ namespace Slang { if (!isRewriteMode()) { - getSink()->diagnose(expr->Arguments[i], Diagnostics::argumentExpectedLValue, (*params)[i]->Name); + getSink()->diagnose(expr->Arguments[i], Diagnostics::argumentExpectedLValue, (*params)[i]->name); } } } diff --git a/source/slang/decl-defs.h b/source/slang/decl-defs.h index f30d4af82..a63df243b 100644 --- a/source/slang/decl-defs.h +++ b/source/slang/decl-defs.h @@ -84,7 +84,7 @@ RAW( { for (auto field : GetFields()) { - if (field->Name.Content == name) + if (field->name.Content == name) return field.Ptr(); } return nullptr; @@ -94,7 +94,7 @@ RAW( int index = 0; for (auto field : GetFields()) { - if (field->Name.Content == name) + if (field->name.Content == name) return index; index++; } diff --git a/source/slang/diagnostics.cpp b/source/slang/diagnostics.cpp index eb6a818d3..6f971ae76 100644 --- a/source/slang/diagnostics.cpp +++ b/source/slang/diagnostics.cpp @@ -40,7 +40,7 @@ void printDiagnosticArg(StringBuilder& sb, Slang::String const& str) void printDiagnosticArg(StringBuilder& sb, Decl* decl) { - sb << decl->Name.Content; + sb << decl->name.Content; } void printDiagnosticArg(StringBuilder& sb, Type* type) diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp index 5f6fca3c2..fff79ae51 100644 --- a/source/slang/emit.cpp +++ b/source/slang/emit.cpp @@ -335,14 +335,14 @@ struct EDeclarator { enum class Flavor { - Name, + name, Array, UnsizedArray, }; Flavor flavor; EDeclarator* next = nullptr; - // Used for `Flavor::Name` + // Used for `Flavor::name` String name; SourceLoc loc; @@ -778,7 +778,7 @@ struct EmitVisitor switch (declarator->flavor) { - case EDeclarator::Flavor::Name: + case EDeclarator::Flavor::name: emitName(declarator->name, declarator->loc); break; @@ -1205,7 +1205,7 @@ struct EmitVisitor advanceToSourceLocation(typeLoc); EDeclarator nameDeclarator; - nameDeclarator.flavor = EDeclarator::Flavor::Name; + nameDeclarator.flavor = EDeclarator::Flavor::name; nameDeclarator.name = name; nameDeclarator.loc = nameLoc; emitTypeImpl(type, &nameDeclarator); @@ -1253,7 +1253,7 @@ struct EmitVisitor } EDeclarator nameDeclarator; - nameDeclarator.flavor = EDeclarator::Flavor::Name; + nameDeclarator.flavor = EDeclarator::Flavor::name; nameDeclarator.name = name; nameDeclarator.loc = nameLoc; @@ -2789,7 +2789,7 @@ struct EmitVisitor SLANG_RELEASE_ASSERT(context->shared->target != CodeGenTarget::GLSL); Emit("typedef "); - EmitType(decl->type, decl->Name.Content); + EmitType(decl->type, decl->name.Content); Emit(";\n"); } @@ -3100,7 +3100,7 @@ struct EmitVisitor return; Emit("struct "); - emitName(decl->Name); + emitName(decl->name); Emit("\n{\n"); // TODO(tfoley): Need to hoist members functions, etc. out to global scope @@ -3516,10 +3516,10 @@ struct EmitVisitor } Emit("}"); - if( varDecl->Name.type != TokenType::Unknown ) + if( varDecl->name.type != TokenType::Unknown ) { Emit(" "); - emitName(varDecl->Name); + emitName(varDecl->name); } Emit(";\n"); @@ -3624,7 +3624,7 @@ struct EmitVisitor // isn't allowed by declarator syntax and/or language rules, we could // hypothetically wrap things in a `typedef` and work around it. - EmitType(decl->ReturnType, decl->Name); + EmitType(decl->ReturnType, decl->name); Emit("("); bool first = true; diff --git a/source/slang/lookup.cpp b/source/slang/lookup.cpp index 3370b369b..30db9d75e 100644 --- a/source/slang/lookup.cpp +++ b/source/slang/lookup.cpp @@ -42,7 +42,7 @@ void buildMemberDictionary(ContainerDecl* decl) for (auto m : decl->Members) { - auto name = m->Name.Content; + auto name = m->name.Content; // Add any transparent members to a separate list for lookup if (m->HasModifier()) diff --git a/source/slang/lower.cpp b/source/slang/lower.cpp index 0f4eca53f..68f61f8a5 100644 --- a/source/slang/lower.cpp +++ b/source/slang/lower.cpp @@ -317,7 +317,7 @@ private: class PseudoVarDecl : public RefObject { public: - Token Name; + Token name; SourceLoc Position; TypeExp type; }; @@ -918,7 +918,7 @@ struct LoweringVisitor RefPtr moveTemp(RefPtr expr) { RefPtr varDecl = new Variable(); - varDecl->Name.Content = generateName(); + varDecl->name.Content = generateName(); varDecl->type.type = expr->type.type; varDecl->initExpr = expr; @@ -2575,7 +2575,7 @@ struct LoweringVisitor if (isReservedWord(decl->getName())) { - decl->Name.Content.append("_"); + decl->name.Content.append("_"); } } @@ -2611,7 +2611,7 @@ struct LoweringVisitor registerLoweredDecl(loweredDecl, decl); loweredDecl->Position = decl->Position; - loweredDecl->Name = decl->getNameToken(); + loweredDecl->name = decl->getNameToken(); // Deal with renaming - we shouldn't allow decls with names that are reserved words ensureDeclHasAValidName(loweredDecl); @@ -2948,7 +2948,7 @@ struct LoweringVisitor // Syntax class for declarations to create SyntaxClass varDeclClass; - // Name "stem" to use for any actual variables we create + // name "stem" to use for any actual variables we create String name; // The parent tuple type (or array thereof) we are scalarizing @@ -3102,7 +3102,7 @@ struct LoweringVisitor } RefPtr fieldVarDecl = info.varDeclClass.createInstance(); - fieldVarDecl->Name.Content = fieldName; + fieldVarDecl->name.Content = fieldName; fieldVarDecl->type.type = fieldVarType; addDecl(fieldVarDecl); @@ -3144,14 +3144,14 @@ struct LoweringVisitor // We'll need a placeholder declaration to wrap the whole thing up: RefPtr tupleDecl = new TupleVarDecl(); - tupleDecl->Name.Content = name; + tupleDecl->name.Content = name; // First, if the tuple type had any "ordinary" data, // then we go ahead and create a declaration for that stuff if (tupleTypeMod->hasAnyNonTupleFields) { RefPtr primaryVarDecl = varDeclClass.createInstance(); - primaryVarDecl->Name.Content = name; + primaryVarDecl->name.Content = name; primaryVarDecl->type.type = tupleType; primaryVarDecl->modifiers = originalVarDecl->modifiers; @@ -3939,7 +3939,7 @@ struct LoweringVisitor if (!globalVarExpr) { RefPtr globalVarDecl = new Variable(); - globalVarDecl->Name.Content = info.name; + globalVarDecl->name.Content = info.name; globalVarDecl->type.type = type; ensureDeclHasAValidName(globalVarDecl); @@ -4168,7 +4168,7 @@ struct LoweringVisitor LoweredExpr loweredExpr) { RefPtr loweredDecl = new VaryingTupleVarDecl(); - loweredDecl->Name = originalVarDecl->Name; + loweredDecl->name = originalVarDecl->name; loweredDecl->type = loweredType; loweredDecl->expr = loweredExpr; @@ -4200,11 +4200,11 @@ struct LoweringVisitor // Now we will generate a `void main() { ... }` function to call the lowered code. RefPtr mainDecl = new FuncDecl(); mainDecl->ReturnType.type = getSession()->getVoidType(); - mainDecl->Name.Content = "main"; + mainDecl->name.Content = "main"; // If the user's entry point was called `main` then rename it here if (loweredEntryPointFunc->getName() == "main") - loweredEntryPointFunc->Name.Content = "main_"; + loweredEntryPointFunc->name.Content = "main_"; RefPtr bodyStmt = new BlockStmt(); bodyStmt->scopeDecl = new ScopeDecl(); @@ -4230,7 +4230,7 @@ struct LoweringVisitor RefPtr localVarDecl = new Variable(); localVarDecl->Position = paramDecl->Position; - localVarDecl->Name.Content = paramDecl->getName(); + localVarDecl->name.Content = paramDecl->getName(); localVarDecl->type = lowerType(paramDecl->type); ensureDeclHasAValidName(localVarDecl); @@ -4268,7 +4268,7 @@ struct LoweringVisitor { resultVarDecl = new Variable(); resultVarDecl->Position = loweredEntryPointFunc->Position; - resultVarDecl->Name.Content = "main_result"; + resultVarDecl->name.Content = "main_result"; resultVarDecl->type = TypeExp(loweredEntryPointFunc->ReturnType); ensureDeclHasAValidName(resultVarDecl); @@ -4387,13 +4387,13 @@ struct LoweringVisitor { resultGlobal = new Variable(); // TODO: need a scheme for generating unique names - resultGlobal->Name.Content = "_main_result"; + resultGlobal->name.Content = "_main_result"; resultGlobal->type = loweredReturnType; addMember(shared->loweredProgram, resultGlobal); } - loweredDecl->Name.Content = "main"; + loweredDecl->name.Content = "main"; loweredDecl->ReturnType.type = getSession()->getVoidType(); // We will emit the body statement in a context where diff --git a/source/slang/parameter-binding.cpp b/source/slang/parameter-binding.cpp index eeaa04a3f..4a6eac472 100644 --- a/source/slang/parameter-binding.cpp +++ b/source/slang/parameter-binding.cpp @@ -1688,7 +1688,7 @@ void generateParameterBindings( programLayout->bindingForHackSampler = (int)binding; RefPtr var = new Variable(); - var->Name.Content = "SLANG_hack_samplerForTexelFetch"; + var->name.Content = "SLANG_hack_samplerForTexelFetch"; var->type.type = getSamplerStateType(request->mSession); auto typeLayout = new TypeLayout(); diff --git a/source/slang/parser.cpp b/source/slang/parser.cpp index d85363bb6..84935cb7f 100644 --- a/source/slang/parser.cpp +++ b/source/slang/parser.cpp @@ -538,7 +538,7 @@ namespace Slang auto nameToken = parser->ReadToken(TokenType::Identifier); typeDefDecl->Position = nameToken.Position; - typeDefDecl->Name = nameToken; + typeDefDecl->name = nameToken; typeDefDecl->type = type; return typeDefDecl; @@ -859,7 +859,7 @@ namespace Slang // Different cases of declarator appear as "flavors" here enum class Flavor { - Name, + name, Pointer, Array, }; @@ -961,7 +961,7 @@ namespace Slang parser->FillPosition(decl.Ptr()); decl->Position = declaratorInfo.nameToken.Position; - decl->Name = declaratorInfo.nameToken; + decl->name = declaratorInfo.nameToken; decl->ReturnType = TypeExp(declaratorInfo.typeSpec); parseParameterList(parser, decl); ParseOptSemantics(parser, decl.Ptr()); @@ -1043,12 +1043,12 @@ namespace Slang if( declaratorInfo.nameToken.type == TokenType::Unknown ) { // HACK(tfoley): we always give a name, even if the declarator didn't include one... :( - decl->Name.Content = generateName(parser); + decl->name.Content = generateName(parser); } else { decl->Position = declaratorInfo.nameToken.Position; - decl->Name = declaratorInfo.nameToken; + decl->name = declaratorInfo.nameToken; } decl->type = TypeExp(declaratorInfo.typeSpec); @@ -1068,7 +1068,7 @@ namespace Slang case TokenType::Identifier: { auto nameDeclarator = new NameDeclarator(); - nameDeclarator->flavor = Declarator::Flavor::Name; + nameDeclarator->flavor = Declarator::Flavor::name; nameDeclarator->nameToken = ParseDeclName(parser); declarator = nameDeclarator; } @@ -1197,7 +1197,7 @@ namespace Slang { switch(declarator->flavor) { - case Declarator::Flavor::Name: + case Declarator::Flavor::name: { auto nameDeclarator = (NameDeclarator*) declarator.Ptr(); ioInfo->nameToken = nameDeclarator->nameToken; @@ -1671,8 +1671,8 @@ namespace Slang addModifier(bufferVarDecl, reflectionNameModifier); // Both the buffer variable and its type need to have names generated - bufferVarDecl->Name.Content = generateName(parser, "parameterBlock_" + reflectionNameToken.Content); - bufferDataTypeDecl->Name.Content = generateName(parser, "ParameterBlock_" + reflectionNameToken.Content); + bufferVarDecl->name.Content = generateName(parser, "parameterBlock_" + reflectionNameToken.Content); + bufferDataTypeDecl->name.Content = generateName(parser, "ParameterBlock_" + reflectionNameToken.Content); addModifier(bufferDataTypeDecl, new ImplicitParameterBlockElementTypeModifier()); addModifier(bufferVarDecl, new ImplicitParameterBlockVariableModifier()); @@ -1685,7 +1685,7 @@ namespace Slang // Construct a type expression to reference the buffer data type auto bufferDataTypeExpr = new VarExpr(); bufferDataTypeExpr->Position = bufferDataTypeDecl->Position; - bufferDataTypeExpr->name = bufferDataTypeDecl->Name.Content; + bufferDataTypeExpr->name = bufferDataTypeDecl->name.Content; bufferDataTypeExpr->scope = parser->currentScope.Ptr(); // Construct a type exrpession to reference the type constructor @@ -1840,7 +1840,7 @@ namespace Slang parser->FillPosition(blockVarDecl.Ptr()); // Generate a unique name for the data type - blockDataTypeDecl->Name.Content = generateName(parser, "ParameterBlock_" + reflectionNameToken.Content); + blockDataTypeDecl->name.Content = generateName(parser, "ParameterBlock_" + reflectionNameToken.Content); // TODO(tfoley): We end up constructing unchecked syntax here that // is expected to type check into the right form, but it might be @@ -1850,7 +1850,7 @@ namespace Slang // Construct a type expression to reference the buffer data type auto blockDataTypeExpr = new VarExpr(); blockDataTypeExpr->Position = blockDataTypeDecl->Position; - blockDataTypeExpr->name = blockDataTypeDecl->Name.Content; + blockDataTypeExpr->name = blockDataTypeDecl->name.Content; blockDataTypeExpr->scope = parser->currentScope.Ptr(); // Construct a type exrpession to reference the type constructor @@ -1877,7 +1877,7 @@ namespace Slang { // The user gave an explicit name to the block, // so we need to use that as our variable name - blockVarDecl->Name = parser->ReadToken(TokenType::Identifier); + blockVarDecl->name = parser->ReadToken(TokenType::Identifier); // TODO: in this case we make actually have a more complex // declarator, including `[]` brackets. @@ -1885,7 +1885,7 @@ namespace Slang else { // synthesize a dummy name - blockVarDecl->Name.Content = generateName(parser, "parameterBlock_" + reflectionNameToken.Content); + blockVarDecl->name.Content = generateName(parser, "parameterBlock_" + reflectionNameToken.Content); // Otherwise we have a transparent declaration, similar // to an HLSL `cbuffer` @@ -1924,7 +1924,7 @@ namespace Slang { // default case is a type parameter auto paramDecl = new GenericValueParamDecl(); - paramDecl->Name = parser->ReadToken(TokenType::Identifier); + paramDecl->name = parser->ReadToken(TokenType::Identifier); if (AdvanceIf(parser, TokenType::Colon)) { paramDecl->type = parser->ParseTypeExp(); @@ -1940,7 +1940,7 @@ namespace Slang // default case is a type parameter auto paramDecl = new GenericTypeParamDecl(); parser->FillPosition(paramDecl); - paramDecl->Name = parser->ReadToken(TokenType::Identifier); + paramDecl->name = parser->ReadToken(TokenType::Identifier); if (AdvanceIf(parser, TokenType::Colon)) { // The user is apply a constraint to this type parameter... @@ -1999,7 +1999,7 @@ namespace Slang // it wraps, so that lookup can find it. if (decl->inner) { - decl->Name = decl->inner->Name; + decl->name = decl->inner->name; decl->Position = decl->inner->Position; } @@ -2040,7 +2040,7 @@ namespace Slang { RefPtr decl = new InterfaceDecl(); parser->FillPosition(decl.Ptr()); - decl->Name = parser->ReadToken(TokenType::Identifier); + decl->name = parser->ReadToken(TokenType::Identifier); parseOptionalInheritanceClause(parser, decl.Ptr()); @@ -2102,7 +2102,7 @@ namespace Slang parser->FillPosition(decl.Ptr()); // TODO: the use of this name here is a bit magical... - decl->Name.Content = "operator[]"; + decl->name.Content = "operator[]"; parseParameterList(parser, decl); @@ -2224,7 +2224,7 @@ namespace Slang // up for downstream code? RefPtr syntaxDecl = new SyntaxDecl(); - syntaxDecl->Name = nameToken; + syntaxDecl->name = nameToken; syntaxDecl->Position = nameToken.Position; syntaxDecl->syntaxClass = syntaxClass; syntaxDecl->parseCallback = parseCallback; @@ -2453,7 +2453,7 @@ namespace Slang ReadToken("struct"); // TODO: support `struct` declaration without tag - rs->Name = ReadToken(TokenType::Identifier); + rs->name = ReadToken(TokenType::Identifier); // We allow for an inheritance clause on a `struct` // so that it can conform to interfaces. @@ -2469,7 +2469,7 @@ namespace Slang RefPtr rs = new ClassDecl(); FillPosition(rs.Ptr()); ReadToken("class"); - rs->Name = ReadToken(TokenType::Identifier); + rs->name = ReadToken(TokenType::Identifier); ReadToken(TokenType::LBrace); parseOptionalInheritanceClause(this, rs.Ptr()); parseAggTypeDeclBody(this, rs.Ptr()); @@ -2576,7 +2576,7 @@ namespace Slang Token varNameToken = parser->ReadToken(TokenType::Identifier); RefPtr varDecl = new Variable(); - varDecl->Name = varNameToken; + varDecl->name = varNameToken; varDecl->Position = varNameToken.Position; stmt->varDecl = varDecl; @@ -3682,7 +3682,7 @@ namespace Slang String name(nameText); RefPtr syntaxDecl = new SyntaxDecl(); - syntaxDecl->Name.Content = name; + syntaxDecl->name.Content = name; syntaxDecl->syntaxClass = syntaxClass; syntaxDecl->parseCallback = callback; syntaxDecl->parseUserData = userData; diff --git a/source/slang/preprocessor.cpp b/source/slang/preprocessor.cpp index 9c9a340ae..11e574064 100644 --- a/source/slang/preprocessor.cpp +++ b/source/slang/preprocessor.cpp @@ -1885,7 +1885,7 @@ enum PreprocessorDirectiveFlag : unsigned int // Information about a specific directive struct PreprocessorDirective { - // Name of the directive + // name of the directive char const* name; // Callback to handle the directive diff --git a/source/slang/syntax-base-defs.h b/source/slang/syntax-base-defs.h index 711c4425b..d67acbe5c 100644 --- a/source/slang/syntax-base-defs.h +++ b/source/slang/syntax-base-defs.h @@ -211,11 +211,11 @@ END_SYNTAX_CLASS() ABSTRACT_SYNTAX_CLASS(Decl, DeclBase) DECL_FIELD(ContainerDecl*, ParentDecl RAW(=nullptr)) - FIELD(Token, Name) + FIELD(Token, name) RAW( - String const& getName() { return Name.Content; } - Token const& getNameToken() { return Name; } + String const& getName() { return name.Content; } + Token const& getNameToken() { return name; } ) diff --git a/source/slang/syntax.cpp b/source/slang/syntax.cpp index 2bd6c122c..a03783825 100644 --- a/source/slang/syntax.cpp +++ b/source/slang/syntax.cpp @@ -949,7 +949,7 @@ void Type::accept(IValVisitor* visitor, void* extra) // Convenience accessors for common properties of declarations String const& DeclRefBase::GetName() const { - return decl->Name.Content; + return decl->name.Content; } DeclRefBase DeclRefBase::GetParent() const -- cgit v1.2.3 From 9885c972a6bfa6f856e505cdd90d9b71fdbdadaf Mon Sep 17 00:00:00 2001 From: Tim Foley Date: Mon, 14 Aug 2017 14:48:37 -0700 Subject: Add an explicit `Name` type Fixes #23 Up to this point, the compiler has used the ordinary `String` type to represent declaration names, which means a bunch of lookup structures throughout the compiler were string-to-whatever maps, which can reduce efficiency. It also means that things like the `Token` type end up carying a `String` by value and paying for things like reference-counting. This change adds a `Name` type that is used to represent names of variables, types, macros, etc. Names are cached and unique'd globally for a session, and the string-to-name mapping gets done during lexing. From that point on, most mapping is from pointers, which should make all the various table lookups faster. More importantly (possibly), this brings us one step closer to being able to pool-allocate the AST nodes. --- slang.h | 1 + source/slang/check.cpp | 75 ++++++----- source/slang/compiler.cpp | 2 +- source/slang/compiler.h | 28 +++-- source/slang/decl-defs.h | 24 +--- source/slang/diagnostic-defs.h | 2 +- source/slang/diagnostics.cpp | 19 ++- source/slang/diagnostics.h | 10 +- source/slang/emit.cpp | 107 +++++++++------- source/slang/expr-defs.h | 2 +- source/slang/lexer.cpp | 61 +++------ source/slang/lexer.h | 12 +- source/slang/lookup.cpp | 32 ++--- source/slang/lookup.h | 4 +- source/slang/lower.cpp | 171 ++++++++++++++----------- source/slang/modifier-defs.h | 3 +- source/slang/name.cpp | 24 ++++ source/slang/name.h | 81 ++++++++++++ source/slang/parameter-binding.cpp | 10 +- source/slang/parser.cpp | 252 ++++++++++++++++++++----------------- source/slang/preprocessor.cpp | 109 +++++++++------- source/slang/reflection.cpp | 6 +- source/slang/slang.cpp | 29 +++-- source/slang/slang.vcxproj | 2 + source/slang/slang.vcxproj.filters | 2 + source/slang/syntax-base-defs.h | 18 ++- source/slang/syntax-visitors.h | 4 +- source/slang/syntax.cpp | 14 +-- source/slang/syntax.h | 31 ++++- source/slang/token.cpp | 18 +++ source/slang/token.h | 25 +++- source/slang/type-layout.h | 2 +- 32 files changed, 716 insertions(+), 464 deletions(-) create mode 100644 source/slang/name.cpp create mode 100644 source/slang/name.h diff --git a/slang.h b/slang.h index 1c34f3033..eefee9a07 100644 --- a/slang.h +++ b/slang.h @@ -974,6 +974,7 @@ namespace slang #include "source/slang/diagnostics.cpp" #include "source/slang/emit.cpp" #include "source/slang/lexer.cpp" +#include "source/slang/name.cpp" #include "source/slang/options.cpp" #include "source/slang/parameter-binding.cpp" #include "source/slang/parser.cpp" diff --git a/source/slang/check.cpp b/source/slang/check.cpp index 6b8617c66..cc2954fc4 100644 --- a/source/slang/check.cpp +++ b/source/slang/check.cpp @@ -147,7 +147,7 @@ namespace Slang if (baseExpr) { auto expr = new MemberExpr(); - expr->Position = originalExpr->Position; + expr->loc = originalExpr->loc; expr->BaseExpression = baseExpr; expr->name = declRef.GetName(); expr->type = GetTypeForDeclRef(declRef); @@ -157,7 +157,7 @@ namespace Slang else { auto expr = new VarExpr(); - expr->Position = originalExpr->Position; + expr->loc = originalExpr->loc; expr->name = declRef.GetName(); expr->type = GetTypeForDeclRef(declRef); expr->declRef = declRef; @@ -173,7 +173,7 @@ namespace Slang SLANG_ASSERT(ptrLikeType); auto derefExpr = new DerefExpr(); - derefExpr->Position = originalExpr->Position; + derefExpr->loc = originalExpr->loc; derefExpr->base = base; derefExpr->type = QualType(ptrLikeType->elementType); @@ -217,7 +217,7 @@ namespace Slang if (lookupResult.isOverloaded()) { auto overloadedExpr = new OverloadedExpr(); - overloadedExpr->Position = originalExpr->Position; + overloadedExpr->loc = originalExpr->loc; overloadedExpr->type = QualType( getSession()->getOverloadedType()); overloadedExpr->base = baseExpr; @@ -823,7 +823,7 @@ namespace Slang if(outToExpr) { auto toInitializerListExpr = new InitializerListExpr(); - toInitializerListExpr->Position = fromInitializerListExpr->Position; + toInitializerListExpr->loc = fromInitializerListExpr->loc; toInitializerListExpr->type = QualType(toType); toInitializerListExpr->args = coercedArgs; @@ -1007,7 +1007,7 @@ namespace Slang castExpr = new ImplicitCastExpr(); } - castExpr->Position = fromExpr->Position; + castExpr->loc = fromExpr->loc; castExpr->TargetType.type = toType; castExpr->type = QualType(toType); castExpr->Expression = fromExpr; @@ -1042,7 +1042,7 @@ namespace Slang { if(!isRewriteMode()) { - getSink()->diagnose(fromExpr->Position, Diagnostics::typeMismatch, toType, fromExpr->type); + getSink()->diagnose(fromExpr->loc, Diagnostics::typeMismatch, toType, fromExpr->type); } // Note(tfoley): We don't call `CreateErrorExpr` here, because that would @@ -1190,7 +1190,7 @@ namespace Slang { if (!isRewriteMode()) { - getSink()->diagnose(expr->Position, Diagnostics::expectedIntegerConstantNotLiteral); + getSink()->diagnose(expr->loc, Diagnostics::expectedIntegerConstantNotLiteral); } return nullptr; } @@ -1234,7 +1234,7 @@ namespace Slang // For now we will do this in a completely ad hoc fashion, // but it would be nice to have some generic routine to // do the needed type checking/coercion. - if(hlslUncheckedAttribute->nameToken.Content == "numthreads") + if(getText(hlslUncheckedAttribute->getName()) == "numthreads") { if(hlslUncheckedAttribute->args.Count() != 3) return m; @@ -1249,8 +1249,8 @@ namespace Slang auto hlslNumThreadsAttribute = new HLSLNumThreadsAttribute(); - hlslNumThreadsAttribute->Position = hlslUncheckedAttribute->Position; - hlslNumThreadsAttribute->nameToken = hlslUncheckedAttribute->nameToken; + hlslNumThreadsAttribute->loc = hlslUncheckedAttribute->loc; + hlslNumThreadsAttribute->name = hlslUncheckedAttribute->getName(); hlslNumThreadsAttribute->args = hlslUncheckedAttribute->args; hlslNumThreadsAttribute->x = (int32_t) xVal->value; hlslNumThreadsAttribute->y = (int32_t) yVal->value; @@ -1614,20 +1614,20 @@ namespace Slang this->function = functionNode; auto returnType = CheckProperType(functionNode->ReturnType); functionNode->ReturnType = returnType; - HashSet paraNames; + HashSet paraNames; for (auto & para : functionNode->GetParameters()) { checkDecl(para); - if (paraNames.Contains(para->name.Content)) + if (paraNames.Contains(para->getName())) { if (!isRewriteMode()) { - getSink()->diagnose(para, Diagnostics::parameterAlreadyDefined, para->name); + getSink()->diagnose(para, Diagnostics::parameterAlreadyDefined, para->getName()); } } else - paraNames.Add(para->name.Content); + paraNames.Add(para->getName()); } this->function = NULL; functionNode->SetCheckState(DeclCheckState::CheckedHeader); @@ -2062,6 +2062,11 @@ namespace Slang return new ConstantIntVal(expr->integerValue); } + Name* getName(String const& text) + { + return getCompileRequest()->getNamePool()->getName(text); + } + RefPtr TryConstantFoldExpr( InvokeExpr* invokeExpr) { @@ -2127,7 +2132,7 @@ namespace Slang auto opName = funcDeclRef.GetName(); // handle binary operators - if (opName == "-") + if (opName == getName("-")) { if (argCount == 1) { @@ -2140,8 +2145,8 @@ namespace Slang } // simple binary operators -#define CASE(OP) \ - else if(opName == #OP) do { \ +#define CASE(OP) \ + else if(opName == getName(#OP)) do { \ if(argCount != 2) return nullptr; \ resultValue = constArgVals[0] OP constArgVals[1]; \ } while(0) @@ -2152,8 +2157,8 @@ namespace Slang // binary operators with chance of divide-by-zero // TODO: issue a suitable error in that case -#define CASE(OP) \ - else if(opName == #OP) do { \ +#define CASE(OP) \ + else if(opName == getName(#OP)) do { \ if(argCount != 2) return nullptr; \ if(!constArgVals[1]) return nullptr; \ resultValue = constArgVals[0] OP constArgVals[1]; \ @@ -2445,7 +2450,7 @@ namespace Slang // it must match what the parser installed in subscript declarations. LookupResult lookupResult = LookUpLocal( getSession(), - this, "operator[]", aggTypeDeclRef); + this, getName("operator[]"), aggTypeDeclRef); if (!lookupResult.isValid()) { goto fail; @@ -2458,7 +2463,7 @@ namespace Slang // we will construct a reference to it and try to call it RefPtr subscriptCallExpr = new InvokeExpr(); - subscriptCallExpr->Position = subscriptExpr->Position; + subscriptCallExpr->loc = subscriptExpr->loc; subscriptCallExpr->FunctionExpr = subscriptFuncExpr; // TODO(tfoley): This path can support multiple arguments easily @@ -4126,7 +4131,7 @@ namespace Slang sb << "."; } - sb << declRef.GetName(); + sb << getText(declRef.GetName()); // If the parent declaration is a generic, then we need to print out its // signature @@ -4179,7 +4184,7 @@ namespace Slang if (!first) sb << ", "; first = false; - sb << genericTypeParam.GetName(); + sb << getText(genericTypeParam.GetName()); } else if(auto genericValParam = paramDeclRef.As()) { @@ -4188,7 +4193,7 @@ namespace Slang formatType(sb, GetType(genericValParam)); sb << " "; - sb << genericValParam.GetName(); + sb << getText(genericValParam.GetName()); } else {} @@ -4286,7 +4291,7 @@ namespace Slang } } - String funcName; + Name* funcName = nullptr; if (auto baseVar = funcExpr.As()) funcName = baseVar->name; else if(auto baseMemberRef = funcExpr.As()) @@ -4298,7 +4303,7 @@ namespace Slang { // There were multple equally-good candidates, but none actually usable. // We will construct a diagnostic message to help out. - if (funcName.Length() != 0) + if (funcName) { if (!isRewriteMode()) { @@ -4317,7 +4322,7 @@ namespace Slang { // There were multiple applicable candidates, so we need to report them. - if (funcName.Length() != 0) + if (funcName) { if (!isRewriteMode()) { @@ -4559,7 +4564,7 @@ namespace Slang { if (!isRewriteMode()) { - getSink()->diagnose(expr->Arguments[i], Diagnostics::argumentExpectedLValue, (*params)[i]->name); + getSink()->diagnose(expr->Arguments[i], Diagnostics::argumentExpectedLValue, (*params)[i]->getName()); } } } @@ -4732,7 +4737,7 @@ namespace Slang IntegerLiteralValue baseElementCount) { RefPtr swizExpr = new SwizzleExpr(); - swizExpr->Position = memberRefExpr->Position; + swizExpr->loc = memberRefExpr->loc; swizExpr->base = memberRefExpr->BaseExpression; IntegerLiteralValue limitElement = baseElementCount; @@ -4744,9 +4749,11 @@ namespace Slang bool anyDuplicates = false; bool anyError = false; - for (UInt i = 0; i < memberRefExpr->name.Length(); i++) + auto swizzleText = getText(memberRefExpr->name); + + for (UInt i = 0; i < swizzleText.Length(); i++) { - auto ch = memberRefExpr->name[i]; + auto ch = swizzleText[i]; int elementIndex = -1; switch (ch) { @@ -5014,11 +5021,11 @@ namespace Slang // be loaded), and then put its declarations into // the current scope. - auto name = decl->nameToken.Content; + auto name = decl->moduleNameAndLoc.name; auto scope = decl->scope; // Try to load a module matching the name - auto importedModuleDecl = findOrImportModule(request, name, decl->nameToken.Position); + auto importedModuleDecl = findOrImportModule(request, name, decl->moduleNameAndLoc.loc); // If we didn't find a matching module, then bail out if (!importedModuleDecl) diff --git a/source/slang/compiler.cpp b/source/slang/compiler.cpp index 55b79c00e..9ca1d247f 100644 --- a/source/slang/compiler.cpp +++ b/source/slang/compiler.cpp @@ -234,7 +234,7 @@ namespace Slang "slang", nullptr, nullptr, - entryPoint->name.begin(), + getText(entryPoint->name).begin(), GetHLSLProfileName(entryPoint->profile), 0, 0, diff --git a/source/slang/compiler.h b/source/slang/compiler.h index a2d29f445..b6eca1b36 100644 --- a/source/slang/compiler.h +++ b/source/slang/compiler.h @@ -4,6 +4,7 @@ #include "../core/basic.h" #include "diagnostics.h" +#include "name.h" #include "profile.h" #include "syntax.h" @@ -90,7 +91,7 @@ namespace Slang CompileRequest* compileRequest = nullptr; // The name of the entry point function (e.g., `main`) - String name; + Name* name; // The profile that the entry point will be compiled for // (this is a combination of the target state, and also @@ -222,6 +223,11 @@ namespace Slang SourceManager sourceManagerStorage; SourceManager* sourceManager; + // Name pool for looking up names + NamePool namePool; + + NamePool* getNamePool() { return &namePool; } + // Output stuff DiagnosticSink mSink; String mDiagnosticOutput; @@ -241,7 +247,7 @@ namespace Slang Dictionary> mapPathToLoadedModule; // Map from the path of a module file to its definition - Dictionary> mapNameToLoadedModules; + Dictionary> mapNameToLoadedModules; CompileRequest(Session* session); @@ -277,7 +283,7 @@ namespace Slang Profile profile); RefPtr loadModule( - String const& name, + Name* name, String const& path, String const& source, SourceLoc const& loc); @@ -287,8 +293,8 @@ namespace Slang TokenList const& tokens); RefPtr findOrImportModule( - String const& name, - SourceLoc const& loc); + Name* name, + SourceLoc const& loc); SourceManager* getSourceManager() { @@ -335,6 +341,14 @@ namespace Slang SourceManager* getBuiltinSourceManager() { return &builtinSourceManager; } + // Name pool stuff for unique-ing identifiers + + RootNamePool rootNamePool; + NamePool namePool; + + RootNamePool* getRootNamePool() { return &rootNamePool; } + NamePool* getNamePool() { return &namePool; } + // // Generated code for stdlib, etc. @@ -372,9 +386,9 @@ namespace Slang Type* getOverloadedType(); Type* getErrorType(); - SyntaxClass findSyntaxClass(String const& name); + SyntaxClass findSyntaxClass(Name* name); - Dictionary > mapNameToSyntaxClass; + Dictionary > mapNameToSyntaxClass; // diff --git a/source/slang/decl-defs.h b/source/slang/decl-defs.h index a63df243b..f27ab9ba6 100644 --- a/source/slang/decl-defs.h +++ b/source/slang/decl-defs.h @@ -21,7 +21,7 @@ ABSTRACT_SYNTAX_CLASS(ContainerDecl, Decl) // Dictionary for looking up members by name. // This is built on demand before performing lookup. - Dictionary memberDictionary; + Dictionary memberDictionary; // Whether the `memberDictionary` is valid. // Should be set to `false` if any members get added/remoed. @@ -80,26 +80,6 @@ RAW( { return getMembersOfType(); } - StructField* FindField(String name) - { - for (auto field : GetFields()) - { - if (field->name.Content == name) - return field.Ptr(); - } - return nullptr; - } - int FindFieldIndex(String name) - { - int index = 0; - for (auto field : GetFields()) - { - if (field->name.Content == name) - return index; - index++; - } - return -1; - } ) END_SYNTAX_CLASS() @@ -176,7 +156,7 @@ SIMPLE_SYNTAX_CLASS(ModuleDecl, ContainerDecl) SYNTAX_CLASS(ImportDecl, Decl) // The name of the module we are trying to import - FIELD(Token, nameToken) + FIELD(NameLoc, moduleNameAndLoc) // The scope that we want to import into FIELD(RefPtr, scope) diff --git a/source/slang/diagnostic-defs.h b/source/slang/diagnostic-defs.h index f0033b65b..17af6cbbb 100644 --- a/source/slang/diagnostic-defs.h +++ b/source/slang/diagnostic-defs.h @@ -329,7 +329,7 @@ DIAGNOSTIC(50020, Error, invalidPrimitiveIdType, "PrimitiveId must have i DIAGNOSTIC(50020, Error, invalidPatchVertexCountType, "PatchVertexCount must have int type.") DIAGNOSTIC(50022, Error, worldIsNotDefined, "world '$0' is not defined."); DIAGNOSTIC(50023, Error, stageShouldProvideWorldAttribute, "'$0' should provide 'World' attribute."); -DIAGNOSTIC(50040, Error, componentHasInvalidTypeForPositionOutput, "'$0': component used as 'Position' output must be of vec4 type.") +DIAGNOSTIC(50040, Error, componentHasInvalidTypeForPositionOutput, "'$0': component used as 'loc' output must be of vec4 type.") DIAGNOSTIC(50041, Error, componentNotDefined, "'$0': component not defined.") DIAGNOSTIC(50052, Error, domainShaderRequiresControlPointCount, "'DomainShader' requires attribute 'ControlPointCount'."); diff --git a/source/slang/diagnostics.cpp b/source/slang/diagnostics.cpp index 6f971ae76..45adf0ad8 100644 --- a/source/slang/diagnostics.cpp +++ b/source/slang/diagnostics.cpp @@ -2,6 +2,7 @@ #include "diagnostics.h" #include "compiler.h" +#include "name.h" #include "syntax.h" #include @@ -38,9 +39,15 @@ void printDiagnosticArg(StringBuilder& sb, Slang::String const& str) sb << str; } +void printDiagnosticArg(StringBuilder& sb, Name* name) +{ + sb << getText(name); +} + + void printDiagnosticArg(StringBuilder& sb, Decl* decl) { - sb << decl->name.Content; + sb << getText(decl->getName()); } void printDiagnosticArg(StringBuilder& sb, Type* type) @@ -70,17 +77,17 @@ void printDiagnosticArg(StringBuilder& sb, Token const& token) SourceLoc const& getDiagnosticPos(SyntaxNode const* syntax) { - return syntax->Position; + return syntax->loc; } SourceLoc const& getDiagnosticPos(Token const& token) { - return token.Position; + return token.loc; } SourceLoc const& getDiagnosticPos(TypeExp const& typeExp) { - return typeExp.exp->Position; + return typeExp.exp->loc; } // Take the format string for a diagnostic message, along with its arguments, and turn it into a @@ -147,7 +154,7 @@ static void formatDiagnostic( { auto sourceManager = sink->sourceManager; - auto expandedLoc = sourceManager->expandSourceLoc(diagnostic.Position); + auto expandedLoc = sourceManager->expandSourceLoc(diagnostic.loc); auto humaneLoc = sourceManager->getHumaneLoc(expandedLoc); sb << humaneLoc.getPath(); @@ -170,7 +177,7 @@ void DiagnosticSink::diagnoseImpl(SourceLoc const& pos, DiagnosticInfo const& in Diagnostic diagnostic; diagnostic.ErrorID = info.id; diagnostic.Message = sb.ProduceString(); - diagnostic.Position = pos; + diagnostic.loc = pos; diagnostic.severity = info.severity; if (diagnostic.severity >= Severity::Error) diff --git a/source/slang/diagnostics.h b/source/slang/diagnostics.h index e22320d3d..f92df030b 100644 --- a/source/slang/diagnostics.h +++ b/source/slang/diagnostics.h @@ -46,7 +46,7 @@ namespace Slang { public: String Message; - SourceLoc Position; + SourceLoc loc; int ErrorID; Severity severity; @@ -63,15 +63,13 @@ namespace Slang { Message = msg; ErrorID = id; - Position = pos; + loc = pos; } }; + class Name; class Decl; - class type; class Type; - class ILType; - class StageAttribute; struct TypeExp; struct QualType; @@ -79,8 +77,8 @@ namespace Slang void printDiagnosticArg(StringBuilder& sb, int val); void printDiagnosticArg(StringBuilder& sb, UInt val); void printDiagnosticArg(StringBuilder& sb, Slang::String const& str); + void printDiagnosticArg(StringBuilder& sb, Name* name); void printDiagnosticArg(StringBuilder& sb, Decl* decl); - void printDiagnosticArg(StringBuilder& sb, type* type); void printDiagnosticArg(StringBuilder& sb, Type* type); void printDiagnosticArg(StringBuilder& sb, TypeExp const& type); void printDiagnosticArg(StringBuilder& sb, QualType const& type); diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp index fff79ae51..71ee31e5e 100644 --- a/source/slang/emit.cpp +++ b/source/slang/emit.cpp @@ -2,6 +2,7 @@ #include "emit.h" #include "lower.h" +#include "name.h" #include "syntax.h" #include "type-layout.h" #include "visitor.h" @@ -343,8 +344,8 @@ struct EDeclarator EDeclarator* next = nullptr; // Used for `Flavor::name` - String name; - SourceLoc loc; + Name* name; + SourceLoc loc; // Used for `Flavor::Array` IntVal* elementCount; @@ -450,22 +451,31 @@ struct EmitVisitor Emit(text.begin(), text.end()); } - void emitName( - String const& inName, - SourceLoc const& loc) + void emit(Name* name) { - String name = inName; + emit(getText(name)); + } + + void emit(NameLoc const& nameAndLoc) + { + advanceToSourceLocation(nameAndLoc.loc); + emit(getText(nameAndLoc.name)); + } + void emitName( + Name* name, + SourceLoc const& loc) + { advanceToSourceLocation(loc); emit(name); } - void emitName(Token const& nameToken) + void emitName(NameLoc const& nameAndLoc) { - emitName(nameToken.Content, nameToken.Position); + emitName(nameAndLoc.name, nameAndLoc.loc); } - void emitName(String const& name) + void emitName(Name* name) { emitName(name, SourceLoc()); } @@ -720,7 +730,7 @@ struct EmitVisitor return; if ((mode == LineDirectiveMode::None) - || !token.Position.isValid()) + || !token.loc.isValid()) { // If we don't have the original position info, or we are in the // mode where the user didn't want line directives, we need to play @@ -738,7 +748,7 @@ struct EmitVisitor // If location information is available, and we are emitting // such information, then just advance our tracking location // to the right place. - advanceToSourceLocation(token.Position); + advanceToSourceLocation(token.loc); } // Emit the raw textual content of the token @@ -1197,10 +1207,10 @@ struct EmitVisitor } void EmitType( - RefPtr type, - SourceLoc const& typeLoc, - String const& name, - SourceLoc const& nameLoc) + RefPtr type, + SourceLoc const& typeLoc, + Name* name, + SourceLoc const& nameLoc) { advanceToSourceLocation(typeLoc); @@ -1211,10 +1221,9 @@ struct EmitVisitor emitTypeImpl(type, &nameDeclarator); } - - void EmitType(RefPtr type, Token const& nameToken) + void EmitType(RefPtr type, Name* name) { - EmitType(type, SourceLoc(), nameToken.Content, nameToken.Position); + EmitType(type, SourceLoc(), name, SourceLoc()); } void EmitType(RefPtr type) @@ -1243,7 +1252,7 @@ struct EmitVisitor } } - void EmitType(TypeExp const& typeExp, String const& name, SourceLoc const& nameLoc) + void EmitType(TypeExp const& typeExp, Name* name, SourceLoc const& nameLoc) { if (!typeExp.type || typeExp.type->As()) { @@ -1262,17 +1271,17 @@ struct EmitVisitor else { EmitType(typeExp.type, - typeExp.exp ? typeExp.exp->Position : SourceLoc(), + typeExp.exp ? typeExp.exp->loc : SourceLoc(), name, nameLoc); } } - void EmitType(TypeExp const& typeExp, Token const& nameToken) + void EmitType(TypeExp const& typeExp, NameLoc const& nameAndLoc) { - EmitType(typeExp, nameToken.Content, nameToken.Position); + EmitType(typeExp, nameAndLoc.name, nameAndLoc.loc); } - void EmitType(TypeExp const& typeExp, String const& name) + void EmitType(TypeExp const& typeExp, Name* name) { EmitType(typeExp, name, SourceLoc()); } @@ -1674,12 +1683,14 @@ struct EmitVisitor void emitUncheckedCallExpr( RefPtr callExpr, - String const& funcName, - ExprEmitArg const& arg) + Name* funcName, + ExprEmitArg const& arg) { auto outerPrec = arg.outerPrec; auto funcExpr = callExpr->FunctionExpr; + auto funcNameText = getText(funcName); + // This can occur when we are dealing with unchecked input syntax, // because we are in "rewriter" mode. In this case we should go // ahead and emit things in the form that they were written. @@ -1688,7 +1699,7 @@ struct EmitVisitor auto prec = kEOp_Comma; for (auto opInfo : kInfixOpInfos) { - if (funcName == opInfo->op) + if (funcNameText == opInfo->op) { prec = *opInfo; break; @@ -1698,7 +1709,7 @@ struct EmitVisitor EmitBinExpr( outerPrec, prec, - funcName.Buffer(), + funcNameText.Buffer(), callExpr); } else if( auto prefixExpr = callExpr.As() ) @@ -1706,7 +1717,7 @@ struct EmitVisitor EmitUnaryExpr( outerPrec, kEOp_Prefix, - funcName.Buffer(), + funcNameText.Buffer(), "", callExpr); } @@ -1716,7 +1727,7 @@ struct EmitVisitor outerPrec, kEOp_Postfix, "", - funcName.Buffer(), + funcNameText.Buffer(), callExpr); } else @@ -2279,7 +2290,7 @@ struct EmitVisitor // TODO: This won't be valid if we had to generate a qualified // reference for some reason. - advanceToSourceLocation(varExpr->Position); + advanceToSourceLocation(varExpr->loc); // Because of the "rewriter" use case, it is possible that we will // be trying to emit an expression that hasn't been wired up to @@ -2456,11 +2467,11 @@ struct EmitVisitor for(auto attr : decl->GetModifiersOfType()) { - if(attr->nameToken.Content == "loop") + if(getText(attr->getName()) == "loop") { Emit("[loop]"); } - else if(attr->nameToken.Content == "unroll") + else if(getText(attr->getName()) == "unroll") { Emit("[unroll]"); } @@ -2486,7 +2497,7 @@ struct EmitVisitor return; // Try to ensure that debugging can find the right location - advanceToSourceLocation(stmt->Position); + advanceToSourceLocation(stmt->loc); if (auto blockStmt = stmt.As()) { @@ -2734,7 +2745,7 @@ struct EmitVisitor return; // Try to ensure that debugging can find the right location - advanceToSourceLocation(decl->Position); + advanceToSourceLocation(decl->loc); DeclEmitArg arg; arg.layout = layout; @@ -2789,7 +2800,7 @@ struct EmitVisitor SLANG_RELEASE_ASSERT(context->shared->target != CodeGenTarget::GLSL); Emit("typedef "); - EmitType(decl->type, decl->name.Content); + EmitType(decl->type, decl->getNameAndLoc()); Emit(";\n"); } @@ -2873,7 +2884,7 @@ struct EmitVisitor Emit(", "); } - emit(mod->nameToken.Content); + emit(mod->getNameAndLoc()); if(mod->valToken.type != TokenType::Unknown) { Emit(" = "); @@ -2890,7 +2901,7 @@ struct EmitVisitor if (shouldSkipModifierForDecl(mod, decl)) continue; - advanceToSourceLocation(mod->Position); + advanceToSourceLocation(mod->loc); if (0) {} @@ -2958,7 +2969,7 @@ struct EmitVisitor else if (auto uncheckedAttr = mod.As()) { Emit("["); - emit(uncheckedAttr->nameToken.Content); + emit(uncheckedAttr->getNameAndLoc()); auto& args = uncheckedAttr->args; auto argCount = args.Count(); if (argCount != 0) @@ -2976,7 +2987,7 @@ struct EmitVisitor else if(auto simpleModifier = mod.As()) { - emit(simpleModifier->nameToken.Content); + emit(simpleModifier->getNameAndLoc()); Emit(" "); } @@ -3038,7 +3049,7 @@ struct EmitVisitor } else { - SLANG_DIAGNOSE_UNEXPECTED(getSink(), semantic->Position, "unhandled kind of semantic"); + SLANG_DIAGNOSE_UNEXPECTED(getSink(), semantic->loc, "unhandled kind of semantic"); } } @@ -3100,7 +3111,7 @@ struct EmitVisitor return; Emit("struct "); - emitName(decl->name); + emitName(decl->getNameAndLoc()); Emit("\n{\n"); // TODO(tfoley): Need to hoist members functions, etc. out to global scope @@ -3117,11 +3128,11 @@ struct EmitVisitor auto type = GetType(declRef); if (!type || type->As()) { - EmitType(declRef.getDecl()->type, declRef.getDecl()->getNameToken()); + EmitType(declRef.getDecl()->type, declRef.getDecl()->getName()); } else { - EmitType(GetType(declRef), declRef.getDecl()->getNameToken()); + EmitType(GetType(declRef), declRef.getDecl()->getName()); } EmitSemantics(declRef.getDecl()); @@ -3303,7 +3314,7 @@ struct EmitVisitor if( auto reflectionNameModifier = varDecl->FindModifier() ) { Emit(" "); - emitName(reflectionNameModifier->nameToken); + emitName(reflectionNameModifier->nameAndLoc); } EmitSemantics(varDecl, kESemanticMask_None); @@ -3490,7 +3501,7 @@ struct EmitVisitor if( auto reflectionNameModifier = varDecl->FindModifier() ) { Emit(" "); - emitName(reflectionNameModifier->nameToken); + emitName(reflectionNameModifier->nameAndLoc); } Emit("\n{\n"); @@ -3516,10 +3527,10 @@ struct EmitVisitor } Emit("}"); - if( varDecl->name.type != TokenType::Unknown ) + if( varDecl->getNameLoc().isValid() ) { Emit(" "); - emitName(varDecl->name); + emitName(varDecl->getName()); } Emit(";\n"); @@ -3624,7 +3635,7 @@ struct EmitVisitor // isn't allowed by declarator syntax and/or language rules, we could // hypothetically wrap things in a `typedef` and work around it. - EmitType(decl->ReturnType, decl->name); + EmitType(decl->ReturnType, decl->getNameAndLoc()); Emit("("); bool first = true; diff --git a/source/slang/expr-defs.h b/source/slang/expr-defs.h index 1860f8a72..5e3d23a02 100644 --- a/source/slang/expr-defs.h +++ b/source/slang/expr-defs.h @@ -13,7 +13,7 @@ ABSTRACT_SYNTAX_CLASS(DeclRefExpr, Expr) DECL_FIELD(DeclRef, declRef) // The name of the symbol being referenced - FIELD(String, name) + FIELD(Name*, name) END_SYNTAX_CLASS() SIMPLE_SYNTAX_CLASS(VarExpr, DeclRefExpr) diff --git a/source/slang/lexer.cpp b/source/slang/lexer.cpp index 351e3f664..11c70d1f5 100644 --- a/source/slang/lexer.cpp +++ b/source/slang/lexer.cpp @@ -65,7 +65,7 @@ namespace Slang if (!mCursor) return SourceLoc(); SLANG_ASSERT(mCursor); - return mCursor->Position; + return mCursor->loc; } Token TokenReader::AdvanceToken() @@ -85,10 +85,12 @@ namespace Slang void Lexer::initialize( SourceFile* inSourceFile, - DiagnosticSink* inSink) + DiagnosticSink* inSink, + NamePool* inNamePool) { - sourceFile = inSourceFile; - sink = inSink; + sourceFile = inSourceFile; + sink = inSink; + namePool = inNamePool; auto content = inSourceFile->content; @@ -222,6 +224,8 @@ namespace Slang lexer->cursor++; handleNewLineInner(lexer, d); + lexer->tokenFlags |= TokenFlag::ScrubbingNeeded; + // Now try again, looking at the character after the // escaped nmewline. continue; @@ -1215,11 +1219,11 @@ namespace Slang Token Lexer::lexToken() { - auto flags = this->tokenFlags; + auto& flags = this->tokenFlags; for(;;) { Token token; - token.Position = getSourceLoc(this); + token.loc = getSourceLoc(this); char const* textBegin = cursor; @@ -1246,7 +1250,7 @@ namespace Slang // We don't want to skip the end-of-file token, but we *do* // want to make sure it has appropriate flags to make our life easier case TokenType::EndOfFile: - flags = TokenFlag::AtStartOfLine | TokenFlag::AfterWhitespace; + flags |= TokenFlag::AtStartOfLine | TokenFlag::AfterWhitespace; break; // We will also do some book-keeping around preprocessor directives here: @@ -1316,6 +1320,11 @@ namespace Slang this->tokenFlags = 0; + if (tokenType == TokenType::Identifier) + { + token.ptrValue = this->namePool->getName(token.Content); + } + return token; } } @@ -1332,42 +1341,4 @@ namespace Slang return tokenList; } } - - - -#if 0 - TokenList Lexer::Parse(const String & fileName, const String & str, DiagnosticSink * sink) - { - TokenList tokenList; - tokenList.mTokens = TokenizeText(fileName, str, [&](TokenizeErrorType errType, SourceLoc pos) - { - auto curChar = str[pos.Pos]; - switch (errType) - { - case TokenizeErrorType::InvalidCharacter: - // Check if inside the ASCII "printable" range - if(curChar >= 0x20 && curChar <= 0x7E) - { - char buffer[] = { curChar, 0 }; - sink->diagnose(pos, Diagnostics::illegalCharacterPrint, buffer); - } - else - { - // Fallback: print as hexadecimal - sink->diagnose(pos, Diagnostics::illegalCharacterHex, String((unsigned char)curChar, 16)); - } - break; - case TokenizeErrorType::InvalidEscapeSequence: - sink->diagnose(pos, Diagnostics::illegalCharacterLiteral); - break; - default: - break; - } - }); - - // Add an end-of-file token so that we can reference it in diagnostic messages - tokenList.mTokens.Add(Token(TokenType::EndOfFile, "", 0, 0, 0, fileName, TokenFlag::AtStartOfLine | TokenFlag::AfterWhitespace)); - return tokenList; - } -#endif } \ No newline at end of file diff --git a/source/slang/lexer.h b/source/slang/lexer.h index 9bb4d34aa..9ea793d73 100644 --- a/source/slang/lexer.h +++ b/source/slang/lexer.h @@ -6,6 +6,10 @@ namespace Slang { + struct NamePool; + + // + struct TokenList { Token* begin() const; @@ -60,15 +64,16 @@ namespace Slang typedef unsigned int LexerFlags; enum { - kLexerFlag_InDirective = 1 << 0, - kLexerFlag_ExpectFileName = 2 << 0, + kLexerFlag_InDirective = 1 << 0, + kLexerFlag_ExpectFileName = 1 << 1, }; struct Lexer { void initialize( SourceFile* sourceFile, - DiagnosticSink* sink); + DiagnosticSink* sink, + NamePool* namePool); ~Lexer(); @@ -86,6 +91,7 @@ namespace Slang SourceFile* sourceFile; DiagnosticSink* sink; + NamePool* namePool; char const* cursor; diff --git a/source/slang/lookup.cpp b/source/slang/lookup.cpp index 30db9d75e..ccdbe8fbf 100644 --- a/source/slang/lookup.cpp +++ b/source/slang/lookup.cpp @@ -23,7 +23,7 @@ struct BreadcrumbInfo void DoLocalLookupImpl( Session* session, - String const& name, + Name* name, DeclRef containerDeclRef, LookupRequest const& request, LookupResult& result, @@ -42,7 +42,7 @@ void buildMemberDictionary(ContainerDecl* decl) for (auto m : decl->Members) { - auto name = m->name.Content; + auto name = m->getName(); // Add any transparent members to a separate list for lookup if (m->HasModifier()) @@ -52,8 +52,8 @@ void buildMemberDictionary(ContainerDecl* decl) decl->transparentMembers.Add(info); } - // Ignore members with an empty name - if (name.Length() == 0) + // Ignore members with no name + if (!name) continue; m->nextInContainerWithSameName = nullptr; @@ -153,11 +153,11 @@ LookupResultItem CreateLookupResultItem( void DoMemberLookupImpl( Session* session, - String const& name, - RefPtr baseType, + Name* name, + RefPtr baseType, LookupRequest const& request, - LookupResult& ioResult, - BreadcrumbInfo* breadcrumbs) + LookupResult& ioResult, + BreadcrumbInfo* breadcrumbs) { // If the type was pointer-like, then dereference it // automatically here. @@ -192,7 +192,7 @@ void DoMemberLookupImpl( void DoMemberLookupImpl( Session* session, - String const& name, + Name* name, DeclRef baseDeclRef, LookupRequest const& request, LookupResult& ioResult, @@ -209,7 +209,7 @@ void DoMemberLookupImpl( // Look for members of the given name in the given container for declarations void DoLocalLookupImpl( Session* session, - String const& name, + Name* name, DeclRef containerDeclRef, LookupRequest const& request, LookupResult& result, @@ -293,7 +293,7 @@ void DoLocalLookupImpl( void DoLookupImpl( Session* session, - String const& name, + Name* name, LookupRequest const& request, LookupResult& result) { @@ -353,9 +353,9 @@ void DoLookupImpl( } LookupResult DoLookup( - Session* session, - String const& name, - LookupRequest const& request) + Session* session, + Name* name, + LookupRequest const& request) { LookupResult result; DoLookupImpl(session, name, request, result); @@ -365,7 +365,7 @@ LookupResult DoLookup( LookupResult LookUp( Session* session, SemanticsVisitor* semantics, - String const& name, + Name* name, RefPtr scope) { LookupRequest request; @@ -379,7 +379,7 @@ LookupResult LookUp( LookupResult LookUpLocal( Session* session, SemanticsVisitor* semantics, - String const& name, + Name* name, DeclRef containerDeclRef) { LookupRequest request; diff --git a/source/slang/lookup.h b/source/slang/lookup.h index 8710ac54f..b8223caa6 100644 --- a/source/slang/lookup.h +++ b/source/slang/lookup.h @@ -20,7 +20,7 @@ void buildMemberDictionary(ContainerDecl* decl); LookupResult LookUp( Session* session, SemanticsVisitor* semantics, - String const& name, + Name* name, RefPtr scope); // perform lookup within the context of a particular container declaration, @@ -28,7 +28,7 @@ LookupResult LookUp( LookupResult LookUpLocal( Session* session, SemanticsVisitor* semantics, - String const& name, + Name* name, DeclRef containerDeclRef); // TODO: this belongs somewhere else diff --git a/source/slang/lower.cpp b/source/slang/lower.cpp index 68f61f8a5..2c62a69a8 100644 --- a/source/slang/lower.cpp +++ b/source/slang/lower.cpp @@ -317,8 +317,8 @@ private: class PseudoVarDecl : public RefObject { public: - Token name; - SourceLoc Position; + NameLoc nameAndLoc; + SourceLoc loc; TypeExp type; }; @@ -339,7 +339,7 @@ public: class PseudoExpr : public RefObject { public: - SourceLoc Position; + SourceLoc loc; QualType type; }; @@ -388,9 +388,9 @@ static SourceLoc getPosition(LoweredExpr const& expr) { switch (expr.getFlavor()) { - case LoweredExpr::Flavor::Expr: return expr.getExpr() ->Position; - case LoweredExpr::Flavor::Tuple: return expr.getTupleExpr() ->Position; - case LoweredExpr::Flavor::VaryingTuple: return expr.getVaryingTupleExpr()->Position; + case LoweredExpr::Flavor::Expr: return expr.getExpr() ->loc; + case LoweredExpr::Flavor::Tuple: return expr.getTupleExpr() ->loc; + case LoweredExpr::Flavor::VaryingTuple: return expr.getVaryingTupleExpr()->loc; default: SLANG_UNREACHABLE("all cases handled"); return SourceLoc(); @@ -415,7 +415,7 @@ struct SharedLoweringContext CodeGenTarget target; // A set of words reserved by the target - Dictionary reservedWords; + HashSet reservedWords; RefPtr loweredProgram; @@ -477,15 +477,16 @@ struct LoweringVisitor CodeGenTarget getTarget() { return shared->target; } - bool isReservedWord(String const& name) + bool isReservedWord(Name* name) { - return shared->reservedWords.TryGetValue(name) != nullptr; + return shared->reservedWords.Contains(name); } void registerReservedWord( - String const& name) + String const& text) { - shared->reservedWords.Add(name, name); + Name* name = shared->compileRequest->getNamePool()->getName(text); + shared->reservedWords.Add(name); } void registerReservedWords() @@ -781,7 +782,7 @@ struct LoweringVisitor Expr* loweredExpr, Expr* expr) { - loweredExpr->Position = expr->Position; + loweredExpr->loc = expr->loc; loweredExpr->type.type = lowerType(expr->type.type); } @@ -796,19 +797,27 @@ struct LoweringVisitor } RefPtr createUncheckedVarRef( - char const* name) + Name* name) { RefPtr result = new VarExpr(); result->name = name; return result; } + + RefPtr createUncheckedVarRef( + char const* name) + { + return createUncheckedVarRef( + shared->compileRequest->getNamePool()->getName(name)); + } + RefPtr createSimpleVarRef( SourceLoc const& loc, VarDeclBase* decl) { RefPtr result = new VarExpr(); - result->Position = loc; + result->loc = loc; result->type.type = decl->type.type; result->declRef = makeDeclRef(decl); result->name = decl->getName(); @@ -842,7 +851,7 @@ struct LoweringVisitor TupleVarDecl* decl) { RefPtr result = new TupleExpr(); - result->Position = loc; + result->loc = loc; result->type.type = decl->type.type; if (auto primaryDecl = decl->primaryDecl) @@ -891,11 +900,11 @@ struct LoweringVisitor // If we are referencing a declaration that got tuple-ified, // then we need to produce a tuple expression as well. - return createTupleRef(expr->Position, tupleVarDecl); + return createTupleRef(expr->loc, tupleVarDecl); } else if (auto varyingTupleVarDecl = loweredDecl.asVaryingTupleDecl()) { - return createVaryingTupleRef(expr->Position, varyingTupleVarDecl); + return createVaryingTupleRef(expr->loc, varyingTupleVarDecl); } RefPtr loweredExpr = new VarExpr(); @@ -905,26 +914,31 @@ struct LoweringVisitor return LoweredExpr(loweredExpr); } - String generateName() + Name* getName(String const& text) + { + return shared->compileRequest->getNamePool()->getName(text); + } + + Name* generateName() { int id = shared->nameCounter++; String result; result.append("SLANG_tmp_"); result.append(id); - return result; + return getName(result); } RefPtr moveTemp(RefPtr expr) { RefPtr varDecl = new Variable(); - varDecl->name.Content = generateName(); + varDecl->nameAndLoc.name = generateName(); varDecl->type.type = expr->type.type; varDecl->initExpr = expr; addDecl(varDecl); - return createSimpleVarRef(expr->Position, varDecl); + return createSimpleVarRef(expr->loc, varDecl); } // The idea of this function is to take an expression that we plan to @@ -953,7 +967,7 @@ struct LoweringVisitor if (auto tupleExpr = expr.asTuple()) { RefPtr resultExpr = new TupleExpr(); - resultExpr->Position = tupleExpr->Position; + resultExpr->loc = tupleExpr->loc; resultExpr->type = tupleExpr->type; if (tupleExpr->primaryExpr) { @@ -973,7 +987,7 @@ struct LoweringVisitor else if (auto varyingTupleExpr = expr.asVaryingTuple()) { RefPtr resultExpr = new VaryingTupleExpr(); - resultExpr->Position = varyingTupleExpr->Position; + resultExpr->loc = varyingTupleExpr->loc; resultExpr->type = varyingTupleExpr->type; for (auto ee : varyingTupleExpr->elements) { @@ -1057,7 +1071,7 @@ struct LoweringVisitor rightExpr = maybeMoveTemp(rightExpr); RefPtr ctorExpr = new AggTypeCtorExpr(); - ctorExpr->Position = rightExpr->Position; + ctorExpr->loc = rightExpr->loc; ctorExpr->type.type = leftType; ctorExpr->base.type = leftType; @@ -1065,7 +1079,7 @@ struct LoweringVisitor for (int ee = 0; ee < elementCount; ++ee) { RefPtr swizzleExpr = new SwizzleExpr(); - swizzleExpr->Position = rightExpr->Position; + swizzleExpr->loc = rightExpr->loc; swizzleExpr->type.type = rightVecType->elementType; swizzleExpr->base = rightExpr; swizzleExpr->elementCount = 1; @@ -1104,19 +1118,24 @@ struct LoweringVisitor RefPtr* link = nullptr; }; - RefPtr createSimpleVarExpr(char const* name) + RefPtr createSimpleVarExpr(Name* name) { RefPtr varExpr = new VarExpr(); varExpr->name = name; return varExpr; } + RefPtr createSimpleVarExpr(char const* name) + { + return createSimpleVarExpr(getName(name)); + } + RefPtr createSeqExpr( RefPtr left, RefPtr right) { RefPtr seqExpr = new InfixExpr(); - seqExpr->Position = left->Position; + seqExpr->loc = left->loc; seqExpr->type = right->type; seqExpr->FunctionExpr = createSimpleVarExpr(","); seqExpr->Arguments.Add(left); @@ -1207,14 +1226,14 @@ struct LoweringVisitor { // LHS array element RefPtr arrayElemExpr = new IndexExpr(); - arrayElemExpr->Position = leftExpr->Position; + arrayElemExpr->loc = leftExpr->loc; arrayElemExpr->type.type = leftArrayType->BaseType; arrayElemExpr->BaseExpression = leftExpr; arrayElemExpr->IndexExpression = createConstIntExpr(ee); // RHS swizzle RefPtr swizzleExpr = new SwizzleExpr(); - swizzleExpr->Position = rightExpr->Position; + swizzleExpr->loc = rightExpr->loc; swizzleExpr->type.type = rightVecType->elementType; swizzleExpr->base = rightExpr; swizzleExpr->elementCount = 1; @@ -1315,7 +1334,7 @@ struct LoweringVisitor { RefPtr resultTuple = new VaryingTupleExpr(); resultTuple->type.type = leftVaryingTuple->type.type; - resultTuple->Position = leftVaryingTuple->Position; + resultTuple->loc = leftVaryingTuple->loc; SLANG_RELEASE_ASSERT(resultTuple->type.type); @@ -1344,7 +1363,7 @@ struct LoweringVisitor RefPtr resultTuple = new VaryingTupleExpr(); resultTuple->type.type = leftVaryingTuple->type.type; - resultTuple->Position = leftVaryingTuple->Position; + resultTuple->loc = leftVaryingTuple->loc; SLANG_RELEASE_ASSERT(resultTuple->type.type); @@ -1366,7 +1385,7 @@ struct LoweringVisitor RefPtr rightElemExpr = new MemberExpr(); - rightElemExpr->Position = rightSimpleExpr->Position; + rightElemExpr->loc = rightSimpleExpr->loc; rightElemExpr->type.type = GetType(leftElem.originalFieldDeclRef); rightElemExpr->declRef = leftElem.originalFieldDeclRef; rightElemExpr->name = leftElem.originalFieldDeclRef.GetName(); @@ -1392,7 +1411,7 @@ struct LoweringVisitor RefPtr resultTuple = new VaryingTupleExpr(); resultTuple->type.type = leftSimpleExpr->type.type; - resultTuple->Position = leftSimpleExpr->Position; + resultTuple->loc = leftSimpleExpr->loc; SLANG_RELEASE_ASSERT(resultTuple->type.type); @@ -1413,7 +1432,7 @@ struct LoweringVisitor RefPtr leftElemExpr = new MemberExpr(); - leftElemExpr->Position = leftSimpleExpr->Position; + leftElemExpr->loc = leftSimpleExpr->loc; leftElemExpr->type.type = GetType(rightElem.originalFieldDeclRef); leftElemExpr->declRef = rightElem.originalFieldDeclRef; leftElemExpr->name = rightElem.originalFieldDeclRef.GetName(); @@ -2038,7 +2057,7 @@ struct LoweringVisitor { if (auto varExpr = infixExpr->FunctionExpr.As()) { - if (varExpr->name == ",") + if (getText(varExpr->name) == ",") { // Call to "operator comma" for (auto aa : infixExpr->Arguments) @@ -2124,7 +2143,7 @@ struct LoweringVisitor Stmt* loweredStmt, Stmt* originalStmt) { - loweredStmt->Position = originalStmt->Position; + loweredStmt->loc = originalStmt->loc; loweredStmt->modifiers = originalStmt->modifiers; } @@ -2190,7 +2209,9 @@ struct LoweringVisitor for (auto token : stmt->tokens) { if (token.type == TokenType::Identifier) - doSampleRateInputCheck(token.Content); + { + doSampleRateInputCheck(token.getName()); + } } loweredStmt->tokens = stmt->tokens; @@ -2284,7 +2305,7 @@ struct LoweringVisitor constExpr->integerValue = ii; RefPtr loweredVarDecl = new VaryingTupleVarDecl(); - loweredVarDecl->Position = varDecl->Position; + loweredVarDecl->loc = varDecl->loc; loweredVarDecl->type = varType; loweredVarDecl->expr = LoweredExpr(constExpr); @@ -2354,7 +2375,7 @@ struct LoweringVisitor RefPtr expr) { RefPtr castExpr = new ExplicitCastExpr(); - castExpr->Position = expr->Position; + castExpr->loc = expr->loc; castExpr->type.type = type; castExpr->TargetType.type = type; castExpr->Expression = expr; @@ -2521,7 +2542,7 @@ struct LoweringVisitor if (isBuildingStmt) { RefPtr declStmt = new DeclStmt(); - declStmt->Position = decl->Position; + declStmt->loc = decl->loc; declStmt->decl = decl; addStmt(declStmt); } @@ -2573,9 +2594,13 @@ struct LoweringVisitor // and ad hoc fashion, but longer term we'll want to do // something sytematic. - if (isReservedWord(decl->getName())) + auto name = decl->getName(); + if (isReservedWord(name)) { - decl->name.Content.append("_"); + auto nameText = getText(name); + nameText.append("_"); + + decl->nameAndLoc.name = getName(nameText); } } @@ -2610,8 +2635,8 @@ struct LoweringVisitor { registerLoweredDecl(loweredDecl, decl); - loweredDecl->Position = decl->Position; - loweredDecl->name = decl->getNameToken(); + loweredDecl->loc = decl->loc; + loweredDecl->nameAndLoc = decl->nameAndLoc; // Deal with renaming - we shouldn't allow decls with names that are reserved words ensureDeclHasAValidName(loweredDecl); @@ -3000,7 +3025,7 @@ struct LoweringVisitor SLANG_RELEASE_ASSERT(!info.initExpr); RefPtr fieldInitExpr; - String fieldName = info.name + "_" + dd.GetName(); + String fieldName = info.name + "_" + getText(dd.GetName()); auto fieldType = GetType(dd); @@ -3102,7 +3127,7 @@ struct LoweringVisitor } RefPtr fieldVarDecl = info.varDeclClass.createInstance(); - fieldVarDecl->name.Content = fieldName; + fieldVarDecl->nameAndLoc = NameLoc(getName(fieldName)); fieldVarDecl->type.type = fieldVarType; addDecl(fieldVarDecl); @@ -3132,10 +3157,10 @@ struct LoweringVisitor SyntaxClass varDeclClass, RefPtr originalVarDecl, String const& name, - RefPtr tupleType, + RefPtr tupleType, DeclRef tupleTypeDecl, TupleTypeModifier* tupleTypeMod, - RefPtr initExpr, + RefPtr initExpr, RefPtr primaryVarLayout, RefPtr tupleTypeLayout) { @@ -3144,14 +3169,14 @@ struct LoweringVisitor // We'll need a placeholder declaration to wrap the whole thing up: RefPtr tupleDecl = new TupleVarDecl(); - tupleDecl->name.Content = name; + tupleDecl->nameAndLoc = NameLoc(getName(name)); // First, if the tuple type had any "ordinary" data, // then we go ahead and create a declaration for that stuff if (tupleTypeMod->hasAnyNonTupleFields) { RefPtr primaryVarDecl = varDeclClass.createInstance(); - primaryVarDecl->name.Content = name; + primaryVarDecl->nameAndLoc.name = getName(name); primaryVarDecl->type.type = tupleType; primaryVarDecl->modifiers = originalVarDecl->modifiers; @@ -3257,7 +3282,7 @@ struct LoweringVisitor auto tupleDecl = createTupleTypeVarDecls( loweredDeclClass, decl, - decl->getName(), + getText(decl->getName()), loweredType.type, tupleTypeMod, loweredInit, @@ -3276,7 +3301,7 @@ struct LoweringVisitor auto tupleDecl = createTupleTypeVarDecls( loweredDeclClass, decl, - decl->getName(), + getText(decl->getName()), loweredType.type, elementTupleTypeMod, nullptr, @@ -3357,9 +3382,10 @@ struct LoweringVisitor } } - void doSampleRateInputCheck(String const& name) + void doSampleRateInputCheck(Name* name) { - if (name == "gl_SampleIndex") + auto text = getText(name); + if (text == "gl_SampleIndex") { setSampleRateFlag(); } @@ -3616,7 +3642,7 @@ struct LoweringVisitor RefPtr type) { RefPtr globalVarRef = new VarExpr(); - globalVarRef->name = name; + globalVarRef->name = getName(name); globalVarRef->type.type = type; return globalVarRef; } @@ -3939,7 +3965,7 @@ struct LoweringVisitor if (!globalVarExpr) { RefPtr globalVarDecl = new Variable(); - globalVarDecl->name.Content = info.name; + globalVarDecl->nameAndLoc.name = getName(info.name); globalVarDecl->type.type = type; ensureDeclHasAValidName(globalVarDecl); @@ -3998,7 +4024,7 @@ struct LoweringVisitor RefPtr globalVarRef = new VarExpr(); - globalVarRef->Position = globalVarDecl->Position; + globalVarRef->loc = globalVarDecl->loc; globalVarRef->type.type = globalVarDecl->type.type; globalVarRef->declRef = makeDeclRef(globalVarDecl.Ptr()); globalVarRef->name = globalVarDecl->getName(); @@ -4077,7 +4103,7 @@ struct LoweringVisitor fieldVarChain.varDecl = fieldDeclRef.getDecl(); VaryingParameterInfo fieldInfo = info; - fieldInfo.name = info.name + "_" + fieldDeclRef.GetName(); + fieldInfo.name = info.name + "_" + getText(fieldDeclRef.GetName()); fieldInfo.varChain = &fieldVarChain; // Need to find the layout for the given field... @@ -4119,6 +4145,7 @@ struct LoweringVisitor VaryingParameterDirection direction) { auto name = originalVarDecl->getName(); + auto nameText = getText(name); auto declRef = makeDeclRef(originalVarDecl.Ptr()); VaryingParameterVarChain varChain; @@ -4126,7 +4153,7 @@ struct LoweringVisitor varChain.varDecl = originalVarDecl; VaryingParameterInfo info; - info.name = name; + info.name = nameText; info.direction = direction; info.varChain = &varChain; @@ -4134,11 +4161,11 @@ struct LoweringVisitor switch (direction) { case VaryingParameterDirection::Input: - info.name = "SLANG_in_" + name; + info.name = "SLANG_in_" + nameText; break; case VaryingParameterDirection::Output: - info.name = "SLANG_out_" + name; + info.name = "SLANG_out_" + nameText; break; } @@ -4168,7 +4195,7 @@ struct LoweringVisitor LoweredExpr loweredExpr) { RefPtr loweredDecl = new VaryingTupleVarDecl(); - loweredDecl->name = originalVarDecl->name; + loweredDecl->nameAndLoc = originalVarDecl->nameAndLoc; loweredDecl->type = loweredType; loweredDecl->expr = loweredExpr; @@ -4197,14 +4224,18 @@ struct LoweringVisitor // First, loer the entry-point function as an ordinary function: auto loweredEntryPointFunc = visitFunctionDeclBase(entryPointDecl).getDecl()->As(); + auto mainName = getName("main"); + // Now we will generate a `void main() { ... }` function to call the lowered code. RefPtr mainDecl = new FuncDecl(); mainDecl->ReturnType.type = getSession()->getVoidType(); - mainDecl->name.Content = "main"; + + + mainDecl->nameAndLoc = NameLoc(mainName); // If the user's entry point was called `main` then rename it here - if (loweredEntryPointFunc->getName() == "main") - loweredEntryPointFunc->name.Content = "main_"; + if (loweredEntryPointFunc->getName() == mainName) + loweredEntryPointFunc->nameAndLoc = NameLoc(getName("main_")); RefPtr bodyStmt = new BlockStmt(); bodyStmt->scopeDecl = new ScopeDecl(); @@ -4229,8 +4260,8 @@ struct LoweringVisitor SLANG_RELEASE_ASSERT(paramLayout); RefPtr localVarDecl = new Variable(); - localVarDecl->Position = paramDecl->Position; - localVarDecl->name.Content = paramDecl->getName(); + localVarDecl->loc = paramDecl->loc; + localVarDecl->nameAndLoc = paramDecl->getNameAndLoc(); localVarDecl->type = lowerType(paramDecl->type); ensureDeclHasAValidName(localVarDecl); @@ -4267,8 +4298,8 @@ struct LoweringVisitor if (!loweredEntryPointFunc->ReturnType->Equals(getSession()->getVoidType())) { resultVarDecl = new Variable(); - resultVarDecl->Position = loweredEntryPointFunc->Position; - resultVarDecl->name.Content = "main_result"; + resultVarDecl->loc = loweredEntryPointFunc->loc; + resultVarDecl->nameAndLoc = NameLoc(getName("main_result")); resultVarDecl->type = TypeExp(loweredEntryPointFunc->ReturnType); ensureDeclHasAValidName(resultVarDecl); @@ -4335,7 +4366,7 @@ struct LoweringVisitor if (resultVarDecl) { VaryingParameterInfo info; - info.name = "SLANG_out_" + resultVarDecl->getName(); + info.name = "SLANG_out_" + getText(resultVarDecl->getName()); info.direction = VaryingParameterDirection::Output; info.varChain = nullptr; diff --git a/source/slang/modifier-defs.h b/source/slang/modifier-defs.h index b007b3296..ddfb9c410 100644 --- a/source/slang/modifier-defs.h +++ b/source/slang/modifier-defs.h @@ -193,7 +193,7 @@ SYNTAX_CLASS(GLSLExtensionDirective, GLSLPreprocessorDirective) END_SYNTAX_CLASS() SYNTAX_CLASS(ParameterBlockReflectionName, Modifier) - FIELD(Token, nameToken) + FIELD(NameLoc, nameAndLoc) END_SYNTAX_CLASS() // A modifier that indicates a built-in base type (e.g., `float`) @@ -270,7 +270,6 @@ SIMPLE_SYNTAX_CLASS(HLSLVolatileModifier, Modifier) // An HLSL `[name(arg0, ...)]` style attribute. SYNTAX_CLASS(HLSLAttribute, Modifier) - FIELD(Token, nameToken) SYNTAX_FIELD(List>, args) END_SYNTAX_CLASS() diff --git a/source/slang/name.cpp b/source/slang/name.cpp new file mode 100644 index 000000000..995bce19f --- /dev/null +++ b/source/slang/name.cpp @@ -0,0 +1,24 @@ +// name.cpp +#include "name.h" + +namespace Slang { + +String getText(Name* name) +{ + if (!name) return String(); + return name->text; +} + +Name* NamePool::getName(String const& text) +{ + RefPtr name; + if (rootPool->names.TryGetValue(text, name)) + return name; + + name = new Name(); + name->text = text; + rootPool->names.Add(text, name); + return name; +} + +} // namespace Slang diff --git a/source/slang/name.h b/source/slang/name.h new file mode 100644 index 000000000..e492c4507 --- /dev/null +++ b/source/slang/name.h @@ -0,0 +1,81 @@ +// name.h +#ifndef SLANG_NAME_H_INCLUDED +#define SLANG_NAME_H_INCLUDED + +// This file defines the `Name` type, used to represent +// the name of types, variables, etc. in the AST. + +#include "../core/basic.h" + +namespace Slang { + +// The `Name` type is used to represent the name of a type, variable, etc. +// +// The key benefit of using `Name`s instead of raw strings is that `Name`s +// can be compared for equality just by testing pointer equality. Names +// also don't require any memory management; you can just retain an ordinary +// pointer to one and not deal with reference-counting overhead. +// +// In order to provide these benefits, a `Name` can only be created using +// a `NamePool` that owns the allocations for all the names (so they get +// cleaned up when the pool is deleted), and which is responsible for +// ensuring the uniqueness of name objects. +// +class Name : public RefObject +{ +public: + // The raw text of the name. + // + // Note that at some point in the future we might have other categories + // of name than "simple" names, and so this might change to a structured + // ADT instead of a simple string. + String text; +}; + +// Get the textual string representation of a name +// (e.g., so that it can be printed). +String getText(Name* name); + +// A `RootNamePool` is used to store and look up names. +// If two systems need to work together with names, and be sure that they +// get equivalent names for a string like `"Foo"`, then they need to use +// the same root name pool (directly or indirectly). +// +struct RootNamePool +{ + // The mapping from text strings to the corresponding name. + Dictionary > names; +}; + +// A `NamePool` is effectively a way of storing a subset of the +// names that have been created through a `RootNamePool`. +// +// The intention is that eventually we will add the ability to clean +// up a `NamePool`, and remove the names it created from the corresponding +// `RootNamePool` *if* those names are no longer in use. +// +// The goal of such an approach would be to ensure that the memory +// usage of a `Session` can't bloat over time just because of multiple +// `CompileRequest`s being created, used, and then destroyed (each time +// adding just a few more strings to the name mapping). +// +struct NamePool +{ + // Find or create the `Name` that represents the given `text`. + Name* getName(String const& text); + + // Set the parent name pool to use for lookup + void setRootNamePool(RootNamePool* rootNamePool) + { + this->rootPool = rootNamePool; + } + + // + + // The root name pool to use for storage/lookup + RootNamePool* rootPool = nullptr; +}; + +} // namespace Slang + +#endif diff --git a/source/slang/parameter-binding.cpp b/source/slang/parameter-binding.cpp index 4a6eac472..877597640 100644 --- a/source/slang/parameter-binding.cpp +++ b/source/slang/parameter-binding.cpp @@ -226,7 +226,7 @@ struct ParameterBindingContext LayoutRulesFamilyImpl* layoutRules; // A dictionary to accellerate looking up parameters by name - Dictionary mapNameToParameterInfo; + Dictionary mapNameToParameterInfo; // What stage (if any) are we compiling for? Stage stage; @@ -377,17 +377,17 @@ static bool findLayoutArg( // -static String getReflectionName(VarDeclBase* varDecl) +static Name* getReflectionName(VarDeclBase* varDecl) { if (auto reflectionNameModifier = varDecl->FindModifier()) - return reflectionNameModifier->nameToken.Content; + return reflectionNameModifier->nameAndLoc.name; return varDecl->getName(); } static bool isGLSLBuiltinName(VarDeclBase* varDecl) { - return getReflectionName(varDecl).StartsWith("gl_"); + return getText(getReflectionName(varDecl)).StartsWith("gl_"); } RefPtr tryGetEffectiveTypeForGLSLVaryingInput( @@ -1688,7 +1688,7 @@ void generateParameterBindings( programLayout->bindingForHackSampler = (int)binding; RefPtr var = new Variable(); - var->name.Content = "SLANG_hack_samplerForTexelFetch"; + var->nameAndLoc.name = request->getNamePool()->getName("SLANG_hack_samplerForTexelFetch"); var->type.type = getSamplerStateType(request->mSession); auto typeLayout = new TypeLayout(); diff --git a/source/slang/parser.cpp b/source/slang/parser.cpp index 84935cb7f..7ea3fe864 100644 --- a/source/slang/parser.cpp +++ b/source/slang/parser.cpp @@ -55,7 +55,7 @@ namespace Slang void FillPosition(SyntaxNode * node) { - node->Position = tokenReader.PeekLoc(); + node->loc = tokenReader.PeekLoc(); } void PushScope(ContainerDecl* containerDecl) { @@ -536,9 +536,9 @@ namespace Slang auto type = parser->ParseTypeExp(); auto nameToken = parser->ReadToken(TokenType::Identifier); - typeDefDecl->Position = nameToken.Position; + typeDefDecl->loc = nameToken.loc; - typeDefDecl->name = nameToken; + typeDefDecl->nameAndLoc = NameLoc(nameToken); typeDefDecl->type = type; return typeDefDecl; @@ -572,7 +572,8 @@ namespace Slang { auto nameToken = parser->ReadToken(TokenType::Identifier); RefPtr modifier = new HLSLUncheckedAttribute(); - modifier->nameToken = nameToken; + modifier->name = nameToken.getName(); + modifier->loc = nameToken.getLoc(); if (AdvanceIf(parser, TokenType::LParent)) { @@ -618,8 +619,8 @@ namespace Slang } static SyntaxDecl* tryLookUpSyntaxDecl( - Parser* parser, - String const& name) + Parser* parser, + Name* name) { // Let's look up the name and see what we find. @@ -665,9 +666,9 @@ namespace Slang if (syntax) { - if (!syntax->Position.isValid()) + if (!syntax->loc.isValid()) { - syntax->Position = keywordToken.Position; + syntax->loc = keywordToken.loc; } } else if (parsedObject) @@ -689,7 +690,7 @@ namespace Slang return false; auto nameToken = peekToken(parser); - auto name = nameToken.Content; + auto name = nameToken.getName(); auto syntaxDecl = tryLookUpSyntaxDecl(parser, name); @@ -724,10 +725,10 @@ namespace Slang RefPtr parsedModifier; if (tryParseUsingSyntaxDecl(parser, &parsedModifier)) { - parsedModifier->nameToken = nameToken; - if (!parsedModifier->Position.isValid()) + parsedModifier->name = nameToken.getName(); + if (!parsedModifier->loc.isValid()) { - parsedModifier->Position = nameToken.Position; + parsedModifier->loc = nameToken.loc; } AddModifier(&modifierLink, parsedModifier); @@ -749,6 +750,17 @@ namespace Slang } } + static Name* getName(Parser* parser, String const& text) + { + return parser->translationUnit->compileRequest->getNamePool()->getName(text); + } + + static NameLoc expectIdentifier(Parser* parser) + { + return NameLoc(parser->ReadToken(TokenType::Identifier)); + } + + static RefPtr parseImportDecl( Parser* parser, void* /*userData*/) { @@ -760,28 +772,30 @@ namespace Slang if (peekTokenType(parser) == TokenType::StringLiteral) { auto nameToken = parser->ReadToken(TokenType::StringLiteral); - nameToken.Content = getStringLiteralTokenValue(nameToken); - decl->nameToken = nameToken; + auto nameString = getStringLiteralTokenValue(nameToken); + auto moduleName = getName(parser, nameString); + + decl->moduleNameAndLoc = NameLoc(moduleName, nameToken.loc); } else { - auto nameToken = parser->ReadToken(TokenType::Identifier); + auto moduleNameAndLoc = expectIdentifier(parser); // We allow a dotted format for the name, as sugar if (peekTokenType(parser) == TokenType::Dot) { StringBuilder sb; - sb << nameToken.Content; + sb << getText(moduleNameAndLoc.name); while (AdvanceIf(parser, TokenType::Dot)) { sb << "/"; sb << parser->ReadToken(TokenType::Identifier).Content; } - nameToken.Content = sb.ProduceString(); + moduleNameAndLoc.name = getName(parser, sb.ProduceString()); } - decl->nameToken = nameToken; + decl->moduleNameAndLoc = moduleNameAndLoc; } parser->ReadToken(TokenType::Semicolon); @@ -796,21 +810,25 @@ namespace Slang Token importToken = parser->ReadToken(TokenType::PoundImport); + NameLoc nameAndLoc; + nameAndLoc.name = getName(parser, importToken.Content); + nameAndLoc.loc = importToken.loc; + auto decl = new ImportDecl(); - decl->nameToken = importToken; + decl->moduleNameAndLoc = nameAndLoc; decl->scope = parser->currentScope; return decl; } - static Token ParseDeclName( + static NameLoc ParseDeclName( Parser* parser) { - Token name; + Token nameToken; if (AdvanceIf(parser, "operator")) { - name = parser->ReadToken(); - switch (name.type) + nameToken = parser->ReadToken(); + switch (nameToken.type) { case TokenType::OpAdd: case TokenType::OpSub: case TokenType::OpMul: case TokenType::OpDiv: case TokenType::OpMod: case TokenType::OpNot: case TokenType::OpBitNot: case TokenType::OpLsh: case TokenType::OpRsh: @@ -837,20 +855,24 @@ namespace Slang case TokenType::QuestionMark: if (AdvanceIf(parser, TokenType::Colon)) { - name.Content = name.Content + ":"; + nameToken.Content = nameToken.Content + ":"; break; } default: - parser->sink->diagnose(name.Position, Diagnostics::invalidOperator, name.Content); + parser->sink->diagnose(nameToken.loc, Diagnostics::invalidOperator, nameToken); break; } + + return NameLoc( + getName(parser, nameToken.Content), + nameToken.loc); } else { - name = parser->ReadToken(TokenType::Identifier); + nameToken = parser->ReadToken(TokenType::Identifier); + return NameLoc(nameToken); } - return name; } // A "declarator" as used in C-style languages @@ -869,7 +891,7 @@ namespace Slang // The most common case of declarator uses a simple name struct NameDeclarator : Declarator { - Token nameToken; + NameLoc nameAndLoc; }; // A declarator that declares a pointer type @@ -896,10 +918,10 @@ namespace Slang // "Unwrapped" information about a declarator struct DeclaratorInfo { - RefPtr typeSpec; - Token nameToken; - RefPtr semantics; - RefPtr initializer; + RefPtr typeSpec; + NameLoc nameAndLoc; + RefPtr semantics; + RefPtr initializer; }; // Add a member declaration to its container, and ensure that its @@ -959,9 +981,9 @@ namespace Slang parser->PushScope(decl.Ptr()); parser->FillPosition(decl.Ptr()); - decl->Position = declaratorInfo.nameToken.Position; + decl->loc = declaratorInfo.nameAndLoc.loc; - decl->name = declaratorInfo.nameToken; + decl->nameAndLoc = declaratorInfo.nameAndLoc; decl->ReturnType = TypeExp(declaratorInfo.typeSpec); parseParameterList(parser, decl); ParseOptSemantics(parser, decl.Ptr()); @@ -1019,14 +1041,13 @@ namespace Slang *link = modifiers; } - - static String generateName(Parser* /*parser*/, String const& base) + static Name* generateName(Parser* parser, String const& base) { // TODO: somehow mangle the name to avoid clashes - return "SLANG_" + base; + return getName(parser, "SLANG_" + base); } - static String generateName(Parser* parser) + static Name* generateName(Parser* parser) { return generateName(parser, "anonymous_" + String(parser->anonymousCounter++)); } @@ -1040,15 +1061,15 @@ namespace Slang { parser->FillPosition(decl.Ptr()); - if( declaratorInfo.nameToken.type == TokenType::Unknown ) + if( !declaratorInfo.nameAndLoc.name ) { // HACK(tfoley): we always give a name, even if the declarator didn't include one... :( - decl->name.Content = generateName(parser); + decl->nameAndLoc = NameLoc(generateName(parser)); } else { - decl->Position = declaratorInfo.nameToken.Position; - decl->name = declaratorInfo.nameToken; + decl->loc = declaratorInfo.nameAndLoc.loc; + decl->nameAndLoc = declaratorInfo.nameAndLoc; } decl->type = TypeExp(declaratorInfo.typeSpec); @@ -1069,7 +1090,7 @@ namespace Slang { auto nameDeclarator = new NameDeclarator(); nameDeclarator->flavor = Declarator::Flavor::name; - nameDeclarator->nameToken = ParseDeclName(parser); + nameDeclarator->nameAndLoc = ParseDeclName(parser); declarator = nameDeclarator; } break; @@ -1200,7 +1221,7 @@ namespace Slang case Declarator::Flavor::name: { auto nameDeclarator = (NameDeclarator*) declarator.Ptr(); - ioInfo->nameToken = nameDeclarator->nameToken; + ioInfo->nameAndLoc = nameDeclarator->nameAndLoc; return; } break; @@ -1222,7 +1243,7 @@ namespace Slang auto arrayDeclarator = (ArrayDeclarator*) declarator.Ptr(); auto arrayTypeExpr = new IndexExpr(); - arrayTypeExpr->Position = arrayDeclarator->openBracketLoc; + arrayTypeExpr->loc = arrayDeclarator->openBracketLoc; arrayTypeExpr->BaseExpression = ioInfo->typeSpec; arrayTypeExpr->IndexExpression = arrayDeclarator->elementCountExpr; ioInfo->typeSpec = arrayTypeExpr; @@ -1263,7 +1284,7 @@ namespace Slang if( decl ) { group = new DeclGroup(); - group->Position = startPosition; + group->loc = startPosition; group->decls.Add(decl); decl = nullptr; } @@ -1302,7 +1323,7 @@ namespace Slang auto expr = new VarExpr(); expr->scope = parser->currentScope.Ptr(); - expr->Position = decl->getNameToken().Position; + expr->loc = decl->getNameLoc(); expr->name = decl->getName(); return expr; } @@ -1353,7 +1374,7 @@ namespace Slang while (parser->LookAheadToken(TokenType::LBracket)) { RefPtr arrType = new IndexExpr(); - arrType->Position = typeExpr->Position; + arrType->loc = typeExpr->loc; arrType->BaseExpression = typeExpr; parser->ReadToken(TokenType::LBracket); if (!parser->LookAheadToken(TokenType::RBracket)) @@ -1395,8 +1416,8 @@ namespace Slang auto basicType = new VarExpr(); basicType->scope = parser->currentScope.Ptr(); - basicType->Position = typeName.Position; - basicType->name = typeName.Content; + basicType->loc = typeName.loc; + basicType->name = typeName.getNameOrNull(); RefPtr typeExpr = basicType; @@ -1492,7 +1513,7 @@ namespace Slang // clone syntax. auto sharedTypeSpec = new SharedTypeExpr(); - sharedTypeSpec->Position = typeSpec.expr->Position; + sharedTypeSpec->loc = typeSpec.expr->loc; sharedTypeSpec->base = TypeExp(typeSpec.expr); for(;;) @@ -1667,12 +1688,12 @@ namespace Slang // Attach the reflection name to the block so we can use it auto reflectionNameModifier = new ParameterBlockReflectionName(); - reflectionNameModifier->nameToken = reflectionNameToken; + reflectionNameModifier->nameAndLoc = NameLoc(reflectionNameToken); addModifier(bufferVarDecl, reflectionNameModifier); // Both the buffer variable and its type need to have names generated - bufferVarDecl->name.Content = generateName(parser, "parameterBlock_" + reflectionNameToken.Content); - bufferDataTypeDecl->name.Content = generateName(parser, "ParameterBlock_" + reflectionNameToken.Content); + bufferVarDecl->nameAndLoc.name = generateName(parser, "parameterBlock_" + reflectionNameToken.Content); + bufferDataTypeDecl->nameAndLoc.name = generateName(parser, "ParameterBlock_" + reflectionNameToken.Content); addModifier(bufferDataTypeDecl, new ImplicitParameterBlockElementTypeModifier()); addModifier(bufferVarDecl, new ImplicitParameterBlockVariableModifier()); @@ -1684,14 +1705,14 @@ namespace Slang // Construct a type expression to reference the buffer data type auto bufferDataTypeExpr = new VarExpr(); - bufferDataTypeExpr->Position = bufferDataTypeDecl->Position; - bufferDataTypeExpr->name = bufferDataTypeDecl->name.Content; + bufferDataTypeExpr->loc = bufferDataTypeDecl->loc; + bufferDataTypeExpr->name = bufferDataTypeDecl->nameAndLoc.name; bufferDataTypeExpr->scope = parser->currentScope.Ptr(); // Construct a type exrpession to reference the type constructor auto bufferWrapperTypeExpr = new VarExpr(); - bufferWrapperTypeExpr->Position = bufferWrapperTypeNamePos; - bufferWrapperTypeExpr->name = bufferWrapperTypeName; + bufferWrapperTypeExpr->loc = bufferWrapperTypeNamePos; + bufferWrapperTypeExpr->name = getName(parser, bufferWrapperTypeName); // Always need to look this up in the outer scope, // so that it won't collide with, e.g., a local variable called `ConstantBuffer` @@ -1700,7 +1721,7 @@ namespace Slang // Construct a type expression that represents the type for the variable, // which is the wrapper type applied to the data type auto bufferVarTypeExpr = new GenericAppExpr(); - bufferVarTypeExpr->Position = bufferVarDecl->Position; + bufferVarTypeExpr->loc = bufferVarDecl->loc; bufferVarTypeExpr->FunctionExpr = bufferWrapperTypeExpr; bufferVarTypeExpr->Arguments.Add(bufferDataTypeExpr); @@ -1832,7 +1853,7 @@ namespace Slang // Attach the reflection name to the block so we can use it auto reflectionNameModifier = new ParameterBlockReflectionName(); - reflectionNameModifier->nameToken = reflectionNameToken; + reflectionNameModifier->nameAndLoc = NameLoc(reflectionNameToken); addModifier(blockVarDecl, reflectionNameModifier); // Both declarations will have a location that points to the name @@ -1840,7 +1861,7 @@ namespace Slang parser->FillPosition(blockVarDecl.Ptr()); // Generate a unique name for the data type - blockDataTypeDecl->name.Content = generateName(parser, "ParameterBlock_" + reflectionNameToken.Content); + blockDataTypeDecl->nameAndLoc.name = generateName(parser, "ParameterBlock_" + reflectionNameToken.Content); // TODO(tfoley): We end up constructing unchecked syntax here that // is expected to type check into the right form, but it might be @@ -1849,14 +1870,14 @@ namespace Slang // Construct a type expression to reference the buffer data type auto blockDataTypeExpr = new VarExpr(); - blockDataTypeExpr->Position = blockDataTypeDecl->Position; - blockDataTypeExpr->name = blockDataTypeDecl->name.Content; + blockDataTypeExpr->loc = blockDataTypeDecl->loc; + blockDataTypeExpr->name = blockDataTypeDecl->getName(); blockDataTypeExpr->scope = parser->currentScope.Ptr(); // Construct a type exrpession to reference the type constructor auto blockWrapperTypeExpr = new VarExpr(); - blockWrapperTypeExpr->Position = pos; - blockWrapperTypeExpr->name = blockWrapperTypeName; + blockWrapperTypeExpr->loc = pos; + blockWrapperTypeExpr->name = getName(parser, blockWrapperTypeName); // Always need to look this up in the outer scope, // so that it won't collide with, e.g., a local variable called `ConstantBuffer` blockWrapperTypeExpr->scope = parser->outerScope; @@ -1864,7 +1885,7 @@ namespace Slang // Construct a type expression that represents the type for the variable, // which is the wrapper type applied to the data type auto blockVarTypeExpr = new GenericAppExpr(); - blockVarTypeExpr->Position = blockVarDecl->Position; + blockVarTypeExpr->loc = blockVarDecl->loc; blockVarTypeExpr->FunctionExpr = blockWrapperTypeExpr; blockVarTypeExpr->Arguments.Add(blockDataTypeExpr); @@ -1877,7 +1898,7 @@ namespace Slang { // The user gave an explicit name to the block, // so we need to use that as our variable name - blockVarDecl->name = parser->ReadToken(TokenType::Identifier); + blockVarDecl->nameAndLoc = NameLoc(parser->ReadToken(TokenType::Identifier)); // TODO: in this case we make actually have a more complex // declarator, including `[]` brackets. @@ -1885,12 +1906,12 @@ namespace Slang else { // synthesize a dummy name - blockVarDecl->name.Content = generateName(parser, "parameterBlock_" + reflectionNameToken.Content); + blockVarDecl->nameAndLoc.name = generateName(parser, "parameterBlock_" + reflectionNameToken.Content); // Otherwise we have a transparent declaration, similar // to an HLSL `cbuffer` auto transparentModifier = new TransparentModifier(); - transparentModifier->Position = pos; + transparentModifier->loc = pos; addModifier(blockVarDecl, transparentModifier); } @@ -1924,7 +1945,7 @@ namespace Slang { // default case is a type parameter auto paramDecl = new GenericValueParamDecl(); - paramDecl->name = parser->ReadToken(TokenType::Identifier); + paramDecl->nameAndLoc = NameLoc(parser->ReadToken(TokenType::Identifier)); if (AdvanceIf(parser, TokenType::Colon)) { paramDecl->type = parser->ParseTypeExp(); @@ -1940,7 +1961,7 @@ namespace Slang // default case is a type parameter auto paramDecl = new GenericTypeParamDecl(); parser->FillPosition(paramDecl); - paramDecl->name = parser->ReadToken(TokenType::Identifier); + paramDecl->nameAndLoc = NameLoc(parser->ReadToken(TokenType::Identifier)); if (AdvanceIf(parser, TokenType::Colon)) { // The user is apply a constraint to this type parameter... @@ -1953,7 +1974,7 @@ namespace Slang DeclRef(paramDecl, nullptr)); auto paramTypeExpr = new SharedTypeExpr(); - paramTypeExpr->Position = paramDecl->Position; + paramTypeExpr->loc = paramDecl->loc; paramTypeExpr->base.type = paramType; paramTypeExpr->type = QualType(getTypeType(paramType)); @@ -1999,8 +2020,8 @@ namespace Slang // it wraps, so that lookup can find it. if (decl->inner) { - decl->name = decl->inner->name; - decl->Position = decl->inner->Position; + decl->nameAndLoc = decl->inner->nameAndLoc; + decl->loc = decl->inner->loc; } parser->PopScope(); @@ -2027,7 +2048,7 @@ namespace Slang auto base = parser->ParseTypeExp(); auto inheritanceDecl = new InheritanceDecl(); - inheritanceDecl->Position = base.exp->Position; + inheritanceDecl->loc = base.exp->loc; inheritanceDecl->base = base; AddMember(decl, inheritanceDecl); @@ -2040,7 +2061,7 @@ namespace Slang { RefPtr decl = new InterfaceDecl(); parser->FillPosition(decl.Ptr()); - decl->name = parser->ReadToken(TokenType::Identifier); + decl->nameAndLoc = NameLoc(parser->ReadToken(TokenType::Identifier)); parseOptionalInheritanceClause(parser, decl.Ptr()); @@ -2102,7 +2123,7 @@ namespace Slang parser->FillPosition(decl.Ptr()); // TODO: the use of this name here is a bit magical... - decl->name.Content = "operator[]"; + decl->nameAndLoc.name = getName(parser, "operator[]"); parseParameterList(parser, decl); @@ -2135,15 +2156,10 @@ namespace Slang return parser->ReadToken(tokenType); } - static Token expectIdentifier(Parser* parser) - { - return parser->ReadToken(TokenType::Identifier); - } - // This is a catch-all syntax-construction callback to handle cases where // a piece of syntax is fully defined by the keyword to use, along with // the class of AST node to construct. - static RefPtr parseSimpleSyntax(Parser* parser, void* userData) + static RefPtr parseSimpleSyntax(Parser* /*parser*/, void* userData) { SyntaxClassBase syntaxClass((SyntaxClassBase::ClassInfo*) userData); return (RefObject*) syntaxClass.createInstanceImpl(); @@ -2163,16 +2179,16 @@ namespace Slang // the new syntax should be an alias for. // First we parse the keyword name. - auto nameToken = expectIdentifier(parser); + auto nameAndLoc = expectIdentifier(parser); // Next we look for a clause that specified the AST node class. SyntaxClass syntaxClass; if (AdvanceIf(parser, TokenType::Colon)) { // User is specifying the class that should be construted - auto classNameToken = expectIdentifier(parser); + auto classNameAndLoc = expectIdentifier(parser); - syntaxClass = parser->getSession()->findSyntaxClass(classNameToken.Content); + syntaxClass = parser->getSession()->findSyntaxClass(classNameAndLoc.name); } // If the user specified a syntax class, then we will default @@ -2185,9 +2201,9 @@ namespace Slang // an alias for some existing keyword. if (AdvanceIf(parser, TokenType::OpAssign)) { - auto existingKeywordToken = expectIdentifier(parser); + auto existingKeywordNameAndLoc = expectIdentifier(parser); - auto existingSyntax = tryLookUpSyntaxDecl(parser, existingKeywordToken.Content); + auto existingSyntax = tryLookUpSyntaxDecl(parser, existingKeywordNameAndLoc.name); if (!existingSyntax) { // TODO: diagnose: keyword did not name syntax @@ -2224,8 +2240,8 @@ namespace Slang // up for downstream code? RefPtr syntaxDecl = new SyntaxDecl(); - syntaxDecl->name = nameToken; - syntaxDecl->Position = nameToken.Position; + syntaxDecl->nameAndLoc = nameAndLoc; + syntaxDecl->loc = nameAndLoc.loc; syntaxDecl->syntaxClass = syntaxClass; syntaxDecl->parseCallback = parseCallback; syntaxDecl->parseUserData = parseUserData; @@ -2314,7 +2330,7 @@ namespace Slang advanceToken(parser); decl = new EmptyDecl(); - decl->Position = loc; + decl->loc = loc; } break; @@ -2383,7 +2399,7 @@ namespace Slang } } - parser->sink->diagnose(declBase->Position, Diagnostics::unimplemented, "didn't expect multiple declarations here"); + parser->sink->diagnose(declBase->loc, Diagnostics::unimplemented, "didn't expect multiple declarations here"); return nullptr; } @@ -2429,7 +2445,7 @@ namespace Slang } PushScope(program); - program->Position = tokenReader.PeekLoc(); + program->loc = tokenReader.PeekLoc(); ParseDeclBody(this, program, TokenType::EndOfFile); PopScope(); @@ -2453,7 +2469,7 @@ namespace Slang ReadToken("struct"); // TODO: support `struct` declaration without tag - rs->name = ReadToken(TokenType::Identifier); + rs->nameAndLoc = expectIdentifier(this); // We allow for an inheritance clause on a `struct` // so that it can conform to interfaces. @@ -2469,7 +2485,7 @@ namespace Slang RefPtr rs = new ClassDecl(); FillPosition(rs.Ptr()); ReadToken("class"); - rs->name = ReadToken(TokenType::Identifier); + rs->nameAndLoc = expectIdentifier(this); ReadToken(TokenType::LBrace); parseOptionalInheritanceClause(this, rs.Ptr()); parseAggTypeDeclBody(this, rs.Ptr()); @@ -2507,7 +2523,7 @@ namespace Slang return stmt; } - static bool isGenericName(Parser* parser, String const& name) + static bool isGenericName(Parser* parser, Name* name) { auto lookupResult = LookUp( parser->getSession(), @@ -2529,7 +2545,7 @@ namespace Slang } - static bool isTypeName(Parser* parser, String const& name) + static bool isTypeName(Parser* parser, Name* name) { auto lookupResult = LookUp( parser->getSession(), @@ -2559,7 +2575,7 @@ namespace Slang if(!parser->LookAheadToken(TokenType::Identifier)) return false; - auto name = parser->tokenReader.PeekToken().Content; + auto name = parser->tokenReader.PeekToken().getName(); return isTypeName(parser, name); } @@ -2574,10 +2590,10 @@ namespace Slang parser->ReadToken("for"); parser->ReadToken(TokenType::LParent); - Token varNameToken = parser->ReadToken(TokenType::Identifier); + NameLoc varNameAndLoc = expectIdentifier(parser); RefPtr varDecl = new Variable(); - varDecl->name = varNameToken; - varDecl->Position = varNameToken.Position; + varDecl->nameAndLoc = varNameAndLoc; + varDecl->loc = varNameAndLoc.loc; stmt->varDecl = varDecl; @@ -2804,7 +2820,7 @@ namespace Slang else { RefPtr newBody = new SeqStmt(); - newBody->Position = blockStatement->Position; + newBody->loc = blockStatement->loc; newBody->stmts.Add(body); newBody->stmts.Add(stmt); @@ -3102,9 +3118,9 @@ namespace Slang } auto opExpr = new VarExpr(); - opExpr->name = opToken.Content; + opExpr->name = getName(parser, opToken.Content); opExpr->scope = parser->currentScope; - opExpr->Position = opToken.Position; + opExpr->loc = opToken.loc; return opExpr; @@ -3117,7 +3133,7 @@ namespace Slang RefPtr right) { RefPtr expr = new InfixExpr(); - expr->Position = op->Position; + expr->loc = op->loc; expr->FunctionExpr = op; expr->Arguments.Add(left); expr->Arguments.Add(right); @@ -3144,7 +3160,7 @@ namespace Slang if(opTokenType == TokenType::QuestionMark) { RefPtr select = new SelectExpr(); - select->Position = op->Position; + select->loc = op->loc; select->FunctionExpr = op; select->Arguments.Add(expr); @@ -3172,7 +3188,7 @@ namespace Slang if (opTokenType == TokenType::OpAssign) { RefPtr assignExpr = new AssignExpr(); - assignExpr->Position = op->Position; + assignExpr->loc = op->loc; assignExpr->left = expr; assignExpr->right = right; @@ -3305,7 +3321,7 @@ namespace Slang parser->ReadToken(TokenType::RParent); RefPtr parenExpr = new ParenExpr(); - parenExpr->Position = openParen.Position; + parenExpr->loc = openParen.loc; parenExpr->base = base; return parenExpr; } @@ -3529,8 +3545,9 @@ namespace Slang RefPtr varExpr = new VarExpr(); varExpr->scope = parser->currentScope.Ptr(); parser->FillPosition(varExpr.Ptr()); - auto token = parser->ReadToken(TokenType::Identifier); - varExpr->name = token.Content; + + auto nameAndLoc = expectIdentifier(parser); + varExpr->name = nameAndLoc.name; if(peekTokenType(parser) == TokenType::OpLess) { @@ -3619,7 +3636,7 @@ namespace Slang parser->FillPosition(memberExpr.Ptr()); memberExpr->BaseExpression = expr; parser->ReadToken(TokenType::Dot); - memberExpr->name = parser->ReadToken(TokenType::Identifier).Content; + memberExpr->name = expectIdentifier(parser).name; expr = memberExpr; } @@ -3672,17 +3689,17 @@ namespace Slang } static void addBuiltinSyntaxImpl( - Session* /*session*/, + Session* session, Scope* scope, char const* nameText, SyntaxParseCallback callback, void* userData, SyntaxClass syntaxClass) { - String name(nameText); + Name* name = session->getNamePool()->getName(nameText); RefPtr syntaxDecl = new SyntaxDecl(); - syntaxDecl->name.Content = name; + syntaxDecl->nameAndLoc = NameLoc(name); syntaxDecl->syntaxClass = syntaxClass; syntaxDecl->parseCallback = callback; syntaxDecl->parseUserData = userData; @@ -3796,14 +3813,14 @@ namespace Slang parser->ReadToken(TokenType::LParent); while (!AdvanceIfMatch(parser, TokenType::RParent)) { - auto nameToken = parser->ReadToken(TokenType::Identifier); + auto nameAndLoc = expectIdentifier(parser); RefPtr modifier; // TODO: better handling of this choise (e.g., lookup in scope) if(0) {} #define CASE(KEYWORD, CLASS) \ - else if(nameToken.Content == #KEYWORD) modifier = new CLASS() + else if(getText(nameAndLoc.name) == #KEYWORD) modifier = new CLASS() CASE(constant_id, GLSLConstantIDLayoutModifier); CASE(binding, GLSLBindingLayoutModifier); @@ -3820,7 +3837,8 @@ namespace Slang modifier = new GLSLUnparsedLayoutModifier(); } - modifier->nameToken = nameToken; + modifier->name = nameAndLoc.name; + modifier->loc = nameAndLoc.loc; if(AdvanceIf(parser, TokenType::OpAssign)) { diff --git a/source/slang/preprocessor.cpp b/source/slang/preprocessor.cpp index 11e574064..fff3c0fd4 100644 --- a/source/slang/preprocessor.cpp +++ b/source/slang/preprocessor.cpp @@ -51,7 +51,7 @@ struct PreprocessorEnvironment PreprocessorEnvironment* parent = NULL; // Macros defined in this environment - Dictionary macros; + Dictionary macros; ~PreprocessorEnvironment(); }; @@ -145,10 +145,10 @@ enum class PreprocessorMacroFlavor struct PreprocessorMacro { // The name under which the macro was `#define`d - Token nameToken; + NameLoc nameAndLoc; // Parameters of the macro, in case of a function-like macro - List params; + List params; // The tokens that make up the macro body TokenList tokens; @@ -161,6 +161,17 @@ struct PreprocessorMacro // while for function-like macro arguments, it will be // the environment of the macro invocation. PreprocessorEnvironment* environment; + + // + Name* getName() + { + return nameAndLoc.name; + } + + SourceLoc getLoc() + { + return nameAndLoc.loc; + } }; // State of the preprocessor @@ -239,6 +250,11 @@ static void destroyInputStream(Preprocessor* /*preprocessor*/, PreprocessorInput delete inputStream; } +static NamePool* getNamePool(Preprocessor* preprocessor) +{ + return preprocessor->translationUnit->compileRequest->getNamePool(); +} + // Create an input stream to represent a pre-tokenized input file. // TODO(tfoley): pre-tokenizing files isn't going to work in the long run. static PreprocessorInputStream* CreateInputStreamForSource( @@ -249,7 +265,7 @@ static PreprocessorInputStream* CreateInputStreamForSource( initializePrimaryInputStream(preprocessor, inputStream); // initialize the embedded lexer so that it can generate a token stream - inputStream->lexer.initialize(sourceFile, GetSink(preprocessor)); + inputStream->lexer.initialize(sourceFile, GetSink(preprocessor), getNamePool(preprocessor)); inputStream->token = inputStream->lexer.lexToken(); return inputStream; @@ -283,7 +299,7 @@ static void EndInputStream(Preprocessor* preprocessor, PreprocessorInputStream* { PreprocessorConditional* conditional = primaryStream->conditional; - GetSink(preprocessor)->diagnose(conditional->ifToken.Position, Diagnostics::endOfFileInPreprocessorConditional); + GetSink(preprocessor)->diagnose(conditional->ifToken.loc, Diagnostics::endOfFileInPreprocessorConditional); while (conditional) { @@ -407,7 +423,7 @@ static Token PeekRawToken(Preprocessor* preprocessor) // Get the location of the current (raw) token static SourceLoc PeekLoc(Preprocessor* preprocessor) { - return PeekRawToken(preprocessor).Position; + return PeekRawToken(preprocessor).loc; } // Get the `TokenType` of the current (raw) token @@ -440,7 +456,7 @@ static void DestroyMacro(Preprocessor* /*preprocessor*/, PreprocessorMacro* macr // Find the currently-defined macro of the given name, or return NULL -static PreprocessorMacro* LookupMacro(PreprocessorEnvironment* environment, String const& name) +static PreprocessorMacro* LookupMacro(PreprocessorEnvironment* environment, Name* name) { for(PreprocessorEnvironment* e = environment; e; e = e->parent) { @@ -485,7 +501,7 @@ static PreprocessorEnvironment* GetCurrentEnvironment(Preprocessor* preprocessor } } -static PreprocessorMacro* LookupMacro(Preprocessor* preprocessor, String const& name) +static PreprocessorMacro* LookupMacro(Preprocessor* preprocessor, Name* name) { return LookupMacro(GetCurrentEnvironment(preprocessor), name); } @@ -567,7 +583,7 @@ static SimpleTokenInputStream* createSimpleInputStream( Token eofToken; eofToken.type = TokenType::EndOfFile; - eofToken.Position = token.Position; + eofToken.loc = token.loc; eofToken.flags = TokenFlag::AfterWhitespace | TokenFlag::AtStartOfLine; inputStream->lexedTokens.mTokens.Add(eofToken); @@ -594,7 +610,7 @@ static void MaybeBeginMacroExpansion( return; // Look for a macro with the given name. - String name = token.Content; + Name* name = token.getName(); PreprocessorMacro* macro = LookupMacro(preprocessor, name); // Not a macro? Can't be an invocation. @@ -606,6 +622,11 @@ static void MaybeBeginMacroExpansion( if (IsMacroBusy(macro)) return; + // We might already have looked at this token, + // and need to suppress expansion + if (token.flags & TokenFlag::SuppressMacroExpansion) + return; + // A function-style macro invocation should only match // if the token *after* the identifier is `(`. This // requires more lookahead than we usually have/need @@ -665,9 +686,9 @@ static void MaybeBeginMacroExpansion( arg->environment = GetCurrentEnvironment(preprocessor); // Associate the new macro with its parameter name - Token paramToken = macro->params[argIndex]; - String const& paramName = paramToken.Content; - arg->nameToken = paramToken; + NameLoc paramNameAndLoc = macro->params[argIndex]; + Name* paramName = paramNameAndLoc.name; + arg->nameAndLoc = paramNameAndLoc; expansion->argumentEnvironment.macros[paramName] = arg; argIndex++; @@ -810,7 +831,7 @@ top: SourceFile* sourceFile = preprocessor->getCompileRequest()->getSourceManager()->allocateSourceFile("token paste", sb.ProduceString()); Lexer lexer; - lexer.initialize(sourceFile, GetSink(preprocessor)); + lexer.initialize(sourceFile, GetSink(preprocessor), getNamePool(preprocessor)); SimpleTokenInputStream* inputStream = new SimpleTokenInputStream(); initializeInputStream(preprocessor, inputStream); @@ -898,7 +919,7 @@ inline String const& GetDirectiveName(PreprocessorDirectiveContext* context) // Get the location of the directive being parsed. inline SourceLoc const& GetDirectiveLoc(PreprocessorDirectiveContext* context) { - return context->directiveToken.Position; + return context->directiveToken.loc; } // Wrapper to get the diagnostic sink in the context of a directive. @@ -914,7 +935,7 @@ static SourceLoc PeekLoc(PreprocessorDirectiveContext* context) } // Wrapper to look up a macro in the context of a directive. -static PreprocessorMacro* LookupMacro(PreprocessorDirectiveContext* context, String const& name) +static PreprocessorMacro* LookupMacro(PreprocessorDirectiveContext* context, Name* name) { return LookupMacro(context->preprocessor, name); } @@ -1138,7 +1159,7 @@ static PreprocessorExpressionValue ParseAndEvaluateUnaryExpression(PreprocessorD PreprocessorExpressionValue value = ParseAndEvaluateExpression(context); if (!Expect(context, TokenType::RParent, Diagnostics::expectedTokenInPreprocessorExpression)) { - GetSink(context)->diagnose(leftParen.Position, Diagnostics::seeOpeningToken, leftParen); + GetSink(context)->diagnose(leftParen.loc, Diagnostics::seeOpeningToken, leftParen); } return value; } @@ -1166,14 +1187,14 @@ static PreprocessorExpressionValue ParseAndEvaluateUnaryExpression(PreprocessorD { return 0; } - String name = nameToken.Content; + Name* name = nameToken.getName(); // If we saw an opening `(`, then expect one to close if (leftParen.type != TokenType::Unknown) { if(!ExpectRaw(context, TokenType::RParent, Diagnostics::expectedTokenInDefinedExpression)) { - GetSink(context)->diagnose(leftParen.Position, Diagnostics::seeOpeningToken, leftParen); + GetSink(context)->diagnose(leftParen.loc, Diagnostics::seeOpeningToken, leftParen); return 0; } } @@ -1259,7 +1280,7 @@ static PreprocessorExpressionValue EvaluateInfixOp( { if (!context->parseError) { - GetSink(context)->diagnose(opToken.Position, Diagnostics::divideByZeroInPreprocessorExpression); + GetSink(context)->diagnose(opToken.loc, Diagnostics::divideByZeroInPreprocessorExpression); } return 0; } @@ -1271,7 +1292,7 @@ static PreprocessorExpressionValue EvaluateInfixOp( { if (!context->parseError) { - GetSink(context)->diagnose(opToken.Position, Diagnostics::divideByZeroInPreprocessorExpression); + GetSink(context)->diagnose(opToken.loc, Diagnostics::divideByZeroInPreprocessorExpression); } return 0; } @@ -1383,7 +1404,7 @@ static void HandleIfDefDirective(PreprocessorDirectiveContext* context) Token nameToken; if(!ExpectRaw(context, TokenType::Identifier, Diagnostics::expectedTokenInPreprocessorDirective, &nameToken)) return; - String name = nameToken.Content; + Name* name = nameToken.getName(); // Check if the name is defined. beginConditional(context, LookupMacro(context, name) != NULL); @@ -1396,7 +1417,7 @@ static void HandleIfNDefDirective(PreprocessorDirectiveContext* context) Token nameToken; if(!ExpectRaw(context, TokenType::Identifier, Diagnostics::expectedTokenInPreprocessorDirective, &nameToken)) return; - String name = nameToken.Content; + Name* name = nameToken.getName(); // Check if the name is defined. beginConditional(context, LookupMacro(context, name) == NULL); @@ -1420,7 +1441,7 @@ static void HandleElseDirective(PreprocessorDirectiveContext* context) if (conditional->elseToken.type != TokenType::Unknown) { GetSink(context)->diagnose(GetDirectiveLoc(context), Diagnostics::directiveAfterElse, GetDirectiveName(context)); - GetSink(context)->diagnose(conditional->elseToken.Position, Diagnostics::seeDirective); + GetSink(context)->diagnose(conditional->elseToken.loc, Diagnostics::seeDirective); return; } conditional->elseToken = context->directiveToken; @@ -1474,7 +1495,7 @@ static void HandleElifDirective(PreprocessorDirectiveContext* context) if (conditional->elseToken.type != TokenType::Unknown) { GetSink(context)->diagnose(GetDirectiveLoc(context), Diagnostics::directiveAfterElse, GetDirectiveName(context)); - GetSink(context)->diagnose(conditional->elseToken.Position, Diagnostics::seeDirective); + GetSink(context)->diagnose(conditional->elseToken.loc, Diagnostics::seeDirective); return; } @@ -1562,8 +1583,8 @@ static void HandleIncludeDirective(PreprocessorDirectiveContext* context) IncludeHandler* includeHandler = context->preprocessor->includeHandler; if (!includeHandler) { - GetSink(context)->diagnose(pathToken.Position, Diagnostics::includeFailed, path); - GetSink(context)->diagnose(pathToken.Position, Diagnostics::noIncludeHandlerSpecified); + GetSink(context)->diagnose(pathToken.loc, Diagnostics::includeFailed, path); + GetSink(context)->diagnose(pathToken.loc, Diagnostics::noIncludeHandlerSpecified); return; } auto includeResult = includeHandler->TryToFindIncludeFile(path, pathIncludedFrom, &foundPath, &foundSource); @@ -1572,7 +1593,7 @@ static void HandleIncludeDirective(PreprocessorDirectiveContext* context) { case IncludeResult::NotFound: case IncludeResult::Error: - GetSink(context)->diagnose(pathToken.Position, Diagnostics::includeFailed, path); + GetSink(context)->diagnose(pathToken.loc, Diagnostics::includeFailed, path); return; case IncludeResult::Found: @@ -1600,16 +1621,16 @@ static void HandleDefineDirective(PreprocessorDirectiveContext* context) Token nameToken; if (!Expect(context, TokenType::Identifier, Diagnostics::expectedTokenInPreprocessorDirective, &nameToken)) return; - String name = nameToken.Content; + Name* name = nameToken.getName(); PreprocessorMacro* macro = CreateMacro(context->preprocessor); - macro->nameToken = nameToken; + macro->nameAndLoc = NameLoc(nameToken); PreprocessorMacro* oldMacro = LookupMacro(&context->preprocessor->globalEnv, name); if (oldMacro) { - GetSink(context)->diagnose(nameToken.Position, Diagnostics::macroRedefinition, name); - GetSink(context)->diagnose(oldMacro->nameToken.Position, Diagnostics::seePreviousDefinitionOf, name); + GetSink(context)->diagnose(nameToken.loc, Diagnostics::macroRedefinition, name); + GetSink(context)->diagnose(oldMacro->getLoc(), Diagnostics::seePreviousDefinitionOf, name); DestroyMacro(context->preprocessor, oldMacro); } @@ -1682,7 +1703,7 @@ static void HandleUndefDirective(PreprocessorDirectiveContext* context) Token nameToken; if (!Expect(context, TokenType::Identifier, Diagnostics::expectedTokenInPreprocessorDirective, &nameToken)) return; - String name = nameToken.Content; + Name* name = nameToken.getName(); PreprocessorEnvironment* env = &context->preprocessor->globalEnv; PreprocessorMacro* macro = LookupMacro(env, name); @@ -1696,7 +1717,7 @@ static void HandleUndefDirective(PreprocessorDirectiveContext* context) else { // name wasn't defined - GetSink(context)->diagnose(nameToken.Position, Diagnostics::macroNotDefined, name); + GetSink(context)->diagnose(nameToken.loc, Diagnostics::macroNotDefined, name); } } @@ -2084,17 +2105,21 @@ static void DefineMacro( // Use existing `Lexer` to generate a token stream. Lexer lexer; - lexer.initialize(valueFile, GetSink(preprocessor)); + lexer.initialize(valueFile, GetSink(preprocessor), getNamePool(preprocessor)); macro->tokens = lexer.lexAllTokens(); - macro->nameToken = Token(TokenType::Identifier, key, keyFile->sourceRange.begin); + + Name* keyName = preprocessor->translationUnit->compileRequest->getNamePool()->getName(key); + + macro->nameAndLoc.name = keyName; + macro->nameAndLoc.loc = keyFile->sourceRange.begin; PreprocessorMacro* oldMacro = NULL; - if (preprocessor->globalEnv.macros.TryGetValue(key, oldMacro)) + if (preprocessor->globalEnv.macros.TryGetValue(keyName, oldMacro)) { DestroyMacro(preprocessor, oldMacro); } - preprocessor->globalEnv.macros[key] = macro; + preprocessor->globalEnv.macros[keyName] = macro; } // read the entire input into tokens @@ -2183,8 +2208,8 @@ static void HandleImportDirective(PreprocessorDirectiveContext* context) IncludeHandler* includeHandler = context->preprocessor->includeHandler; if (!includeHandler) { - GetSink(context)->diagnose(pathToken.Position, Diagnostics::importFailed, path); - GetSink(context)->diagnose(pathToken.Position, Diagnostics::noIncludeHandlerSpecified); + GetSink(context)->diagnose(pathToken.loc, Diagnostics::importFailed, path); + GetSink(context)->diagnose(pathToken.loc, Diagnostics::noIncludeHandlerSpecified); return; } auto includeResult = includeHandler->TryToFindIncludeFile(path, pathIncludedFrom, &foundPath, &foundSource); @@ -2193,7 +2218,7 @@ static void HandleImportDirective(PreprocessorDirectiveContext* context) { case IncludeResult::NotFound: case IncludeResult::Error: - GetSink(context)->diagnose(pathToken.Position, Diagnostics::importFailed, path); + GetSink(context)->diagnose(pathToken.loc, Diagnostics::importFailed, path); return; case IncludeResult::Found: @@ -2262,7 +2287,7 @@ static void HandleImportDirective(PreprocessorDirectiveContext* context) Token token; token.type = TokenType::PoundImport; - token.Position = GetDirectiveLoc(context); + token.loc = GetDirectiveLoc(context); token.flags = 0; token.Content = foundPath; diff --git a/source/slang/reflection.cpp b/source/slang/reflection.cpp index 13c306d56..b63240506 100644 --- a/source/slang/reflection.cpp +++ b/source/slang/reflection.cpp @@ -570,9 +570,9 @@ SLANG_API char const* spReflectionVariable_GetName(SlangReflectionVariable* inVa // If the variable is one that has an "external" name that is supposed // to be exposed for reflection, then report it here if(auto reflectionNameMod = var->FindModifier()) - return reflectionNameMod->nameToken.Content.Buffer(); + return getText(reflectionNameMod->nameAndLoc.name).Buffer(); - return var->getName().Buffer(); + return getText(var->getName()).Buffer(); } SLANG_API SlangReflectionType* spReflectionVariable_GetType(SlangReflectionVariable* inVar) @@ -695,7 +695,7 @@ SLANG_API char const* spReflectionEntryPoint_getName( auto entryPointLayout = convert(inEntryPoint); if(!entryPointLayout) return 0; - return entryPointLayout->entryPoint->getName().begin(); + return getText(entryPointLayout->entryPoint->getName()).begin(); } SLANG_API unsigned spReflectionEntryPoint_getParameterCount( diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp index 2bacb28ca..f6e9bd70b 100644 --- a/source/slang/slang.cpp +++ b/source/slang/slang.cpp @@ -20,9 +20,13 @@ namespace Slang { Session::Session() { + // Initialize name pool + getNamePool()->setRootNamePool(getRootNamePool()); + // Initialize the lookup table of syntax classes: - #define SYNTAX_CLASS(NAME, BASE) mapNameToSyntaxClass.Add(#NAME, getClass()); + #define SYNTAX_CLASS(NAME, BASE) \ + mapNameToSyntaxClass.Add(getNamePool()->getName(#NAME), getClass()); #include "object-meta-begin.h" #include "syntax-base-defs.h" @@ -110,6 +114,8 @@ struct IncludeHandlerImpl : IncludeHandler CompileRequest::CompileRequest(Session* session) : mSession(session) { + getNamePool()->setRootNamePool(session->getRootNamePool()); + setSourceManager(&sourceManagerStorage); sourceManager->initialize(session->getBuiltinSourceManager()); @@ -378,7 +384,7 @@ int CompileRequest::addEntryPoint( { RefPtr entryPoint = new EntryPointRequest(); entryPoint->compileRequest = this; - entryPoint->name = name; + entryPoint->name = getNamePool()->getName(name); entryPoint->profile = entryPointProfile; entryPoint->translationUnitIndex = translationUnitIndex; @@ -391,7 +397,7 @@ int CompileRequest::addEntryPoint( } RefPtr CompileRequest::loadModule( - String const& name, + Name* name, String const& path, String const& source, SourceLoc const&) @@ -462,15 +468,20 @@ void CompileRequest::handlePoundImport( // as the "name" when registering things, but this saves // us the trouble of trying to special-case things when // checking an `import` down the road. - mapNameToLoadedModules.Add(path, moduleDecl); + // + // Ideally we'd construct a suitable name by effectively + // running the name->path logic in reverse (e.g., replacing + // `-` with `_` and `/` with `.`). + Name* name = getNamePool()->getName(path); + mapNameToLoadedModules.Add(name, moduleDecl); mapPathToLoadedModule.Add(path, moduleDecl); loadedModulesList.Add(moduleDecl); } RefPtr CompileRequest::findOrImportModule( - String const& name, - SourceLoc const& loc) + Name* name, + SourceLoc const& loc) { // Have we already loaded a module matching this name? // If so, return it. @@ -485,7 +496,7 @@ RefPtr CompileRequest::findOrImportModule( // For example, `foo_bar` becomes `foo-bar.slang`. StringBuilder sb; - for (auto c : name) + for (auto c : getText(name)) { if (c == '_') c = '-'; @@ -541,8 +552,8 @@ RefPtr CompileRequest::findOrImportModule( RefPtr findOrImportModule( CompileRequest* request, - String const& name, - SourceLoc const& loc) + Name* name, + SourceLoc const& loc) { return request->findOrImportModule(name, loc); } diff --git a/source/slang/slang.vcxproj b/source/slang/slang.vcxproj index 7da5c39d6..a212d96ec 100644 --- a/source/slang/slang.vcxproj +++ b/source/slang/slang.vcxproj @@ -175,6 +175,7 @@ + @@ -205,6 +206,7 @@ + diff --git a/source/slang/slang.vcxproj.filters b/source/slang/slang.vcxproj.filters index 2241dc67c..2efbc8e30 100644 --- a/source/slang/slang.vcxproj.filters +++ b/source/slang/slang.vcxproj.filters @@ -36,6 +36,7 @@ + @@ -57,5 +58,6 @@ + \ No newline at end of file diff --git a/source/slang/syntax-base-defs.h b/source/slang/syntax-base-defs.h index d67acbe5c..e6f7cc55e 100644 --- a/source/slang/syntax-base-defs.h +++ b/source/slang/syntax-base-defs.h @@ -9,7 +9,7 @@ ABSTRACT_SYNTAX_CLASS(SyntaxNodeBase, RefObject) // The primary source location associated with this AST node - FIELD(SourceLoc, Position) + FIELD(SourceLoc, loc) RAW( // Allow dynamic casting with a convenient syntax @@ -173,8 +173,13 @@ ABSTRACT_SYNTAX_CLASS(Modifier, SyntaxNodeBase) // Next modifier in linked list of modifiers on same piece of syntax SYNTAX_FIELD(RefPtr, next) - // The token that was used to name this modifier. - FIELD(Token, nameToken) + // The keyword that was used to introduce t that was used to name this modifier. + FIELD(Name*, name) + + RAW( + Name* getName() { return name; } + NameLoc getNameAndLoc() { return NameLoc(name, loc); } + ) END_SYNTAX_CLASS() // A syntax node which can have modifiers appled @@ -211,11 +216,12 @@ END_SYNTAX_CLASS() ABSTRACT_SYNTAX_CLASS(Decl, DeclBase) DECL_FIELD(ContainerDecl*, ParentDecl RAW(=nullptr)) - FIELD(Token, name) + FIELD(NameLoc, nameAndLoc) RAW( - String const& getName() { return name.Content; } - Token const& getNameToken() { return name; } + Name* getName() { return nameAndLoc.name; } + SourceLoc getNameLoc() { return nameAndLoc.loc ; } + NameLoc getNameAndLoc() { return nameAndLoc ; } ) diff --git a/source/slang/syntax-visitors.h b/source/slang/syntax-visitors.h index 0780bab2a..5c32c4a36 100644 --- a/source/slang/syntax-visitors.h +++ b/source/slang/syntax-visitors.h @@ -25,8 +25,8 @@ namespace Slang // TODO: need a better location to declare this. RefPtr findOrImportModule( CompileRequest* request, - String const& name, - SourceLoc const& loc); + Name* name, + SourceLoc const& loc); } #endif \ No newline at end of file diff --git a/source/slang/syntax.cpp b/source/slang/syntax.cpp index a03783825..be1a429a6 100644 --- a/source/slang/syntax.cpp +++ b/source/slang/syntax.cpp @@ -260,7 +260,7 @@ void Type::accept(IValVisitor* visitor, void* extra) return errorType; } - SyntaxClass Session::findSyntaxClass(String const& name) + SyntaxClass Session::findSyntaxClass(Name* name) { SyntaxClass syntaxClass; if (mapNameToSyntaxClass.TryGetValue(name, syntaxClass)) @@ -306,7 +306,7 @@ void Type::accept(IValVisitor* visitor, void* extra) String DeclRefType::ToString() { - return declRef.GetName(); + return getText(declRef.GetName()); } int DeclRefType::GetHashCode() @@ -620,7 +620,7 @@ void Type::accept(IValVisitor* visitor, void* extra) String NamedExpressionType::ToString() { - return declRef.GetName(); + return getText(declRef.GetName()); } bool NamedExpressionType::EqualsImpl(Type * /*type*/) @@ -646,7 +646,7 @@ void Type::accept(IValVisitor* visitor, void* extra) { // TODO: a better approach than this if (declRef) - return declRef.GetName(); + return getText(declRef.GetName()); else return "/* unknown FuncType */"; } @@ -786,7 +786,7 @@ void Type::accept(IValVisitor* visitor, void* extra) String GenericParamIntVal::ToString() { - return declRef.GetName(); + return getText(declRef.GetName()); } int GenericParamIntVal::GetHashCode() @@ -947,9 +947,9 @@ void Type::accept(IValVisitor* visitor, void* extra) } // Convenience accessors for common properties of declarations - String const& DeclRefBase::GetName() const + Name* DeclRefBase::GetName() const { - return decl->name.Content; + return decl->nameAndLoc.name; } DeclRefBase DeclRefBase::GetParent() const diff --git a/source/slang/syntax.h b/source/slang/syntax.h index 6f3c32d18..e25f096ff 100644 --- a/source/slang/syntax.h +++ b/source/slang/syntax.h @@ -11,6 +11,7 @@ namespace Slang { + class Name; class Session; class Substitutions; class SyntaxVisitor; @@ -44,6 +45,32 @@ namespace Slang IntrinsicOp findIntrinsicOp(char const* name); + // Helper type for pairing up a name and the location where it appeared + struct NameLoc + { + Name* name; + SourceLoc loc; + + NameLoc() + : name(nullptr) + {} + + explicit NameLoc(Name* name) + : name(name) + {} + + + NameLoc(Name* name, SourceLoc loc) + : name(name) + , loc(loc) + {} + + NameLoc(Token const& token) + : name(token.getNameOrNull()) + , loc(token.getLoc()) + {} + }; + // Helper class for iterating over a list of heap-allocated modifiers struct ModifierList { @@ -371,7 +398,7 @@ namespace Slang } // Convenience accessors for common properties of declarations - String const& GetName() const; + Name* GetName() const; DeclRefBase GetParent() const; int GetHashCode() const; @@ -772,7 +799,7 @@ namespace Slang bool isOverloaded() const { return items.Count() > 1; } - String const& getName() const + Name* getName() const { return items.Count() > 1 ? items[0].declRef.GetName() : item.declRef.GetName(); } diff --git a/source/slang/token.cpp b/source/slang/token.cpp index 69baf5e70..42f7ab55f 100644 --- a/source/slang/token.cpp +++ b/source/slang/token.cpp @@ -5,6 +5,24 @@ namespace Slang { + +Name* Token::getName() const +{ + return getNameOrNull(); +} + +Name* Token::getNameOrNull() const +{ + switch (type) + { + default: + return nullptr; + + case TokenType::Identifier: + return (Name*) ptrValue; + } +} + char const* TokenTypeToString(TokenType type) { switch( type ) diff --git a/source/slang/token.h b/source/slang/token.h index 306d4a2f2..5967ac49a 100644 --- a/source/slang/token.h +++ b/source/slang/token.h @@ -8,6 +8,8 @@ namespace Slang { +class Name; + enum class TokenType { #define TOKEN(NAME, DESC) NAME, @@ -21,18 +23,22 @@ enum TokenFlag : unsigned int AtStartOfLine = 1 << 0, AfterWhitespace = 1 << 1, SuppressMacroExpansion = 1 << 2, + ScrubbingNeeded = 1 << 3, }; typedef unsigned int TokenFlags; class Token { public: - TokenType type = TokenType::Unknown; - String Content; - SourceLoc Position; - TokenFlags flags = 0; + TokenType type = TokenType::Unknown; + TokenFlags flags = 0; + + SourceLoc loc; + void* ptrValue; + + String Content; - Token() = default; + Token() = default; Token( TokenType type, @@ -43,8 +49,15 @@ public: { type = type; Content = content; - Position = loc; + loc = loc; + ptrValue = nullptr; } + + Name* getName() const; + + Name* getNameOrNull() const; + + SourceLoc getLoc() const { return loc; } }; diff --git a/source/slang/type-layout.h b/source/slang/type-layout.h index 7d037b2e7..8a034b5a6 100644 --- a/source/slang/type-layout.h +++ b/source/slang/type-layout.h @@ -228,7 +228,7 @@ public: DeclRef varDecl; VarDeclBase* getVariable() { return varDecl.getDecl(); } - String const& getName() { return getVariable()->getName(); } + Name* getName() { return getVariable()->getName(); } // The result of laying out the variable's type RefPtr typeLayout; -- cgit v1.2.3