diff options
| author | Tim Foley <tim.foley.is@gmail.com> | 2017-08-14 18:50:46 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-08-14 18:50:46 -0700 |
| commit | aeb247cdf02e4dcfc0bb6839cfd291be5128f8ad (patch) | |
| tree | 7314b26e21ded966b6a4fe2430f0421c0c0970bd | |
| parent | bb66d6eddd649d8861cecefa2d6ccb7a28a827bc (diff) | |
| parent | 9885c972a6bfa6f856e505cdd90d9b71fdbdadaf (diff) | |
Merge pull request #159 from tfoleyNV/name-type
Name type
32 files changed, 728 insertions, 476 deletions
@@ -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 bb0b1b794..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<String> paraNames; + HashSet<Name*> 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<IntVal> 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<InvokeExpr> 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<GenericValueParamDecl>()) { @@ -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<VarExpr>()) funcName = baseVar->name; else if(auto baseMemberRef = funcExpr.As<MemberExpr>()) @@ -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<SwizzleExpr> 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<String, RefPtr<ModuleDecl>> mapPathToLoadedModule; // Map from the path of a module file to its definition - Dictionary<String, RefPtr<ModuleDecl>> mapNameToLoadedModules; + Dictionary<Name*, RefPtr<ModuleDecl>> mapNameToLoadedModules; CompileRequest(Session* session); @@ -277,7 +283,7 @@ namespace Slang Profile profile); RefPtr<ModuleDecl> 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<ModuleDecl> 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<RefObject> findSyntaxClass(String const& name); + SyntaxClass<RefObject> findSyntaxClass(Name* name); - Dictionary<String, SyntaxClass<RefObject> > mapNameToSyntaxClass; + Dictionary<Name*, SyntaxClass<RefObject> > mapNameToSyntaxClass; // diff --git a/source/slang/decl-defs.h b/source/slang/decl-defs.h index f30d4af82..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<String, Decl*> memberDictionary; + Dictionary<Name*, Decl*> 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>(); } - 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>, 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 eb6a818d3..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 <assert.h> @@ -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 5f6fca3c2..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" @@ -335,16 +336,16 @@ struct EDeclarator { enum class Flavor { - Name, + name, Array, UnsizedArray, }; Flavor flavor; EDeclarator* next = nullptr; - // Used for `Flavor::Name` - String name; - SourceLoc loc; + // Used for `Flavor::name` + 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 @@ -778,7 +788,7 @@ struct EmitVisitor switch (declarator->flavor) { - case EDeclarator::Flavor::Name: + case EDeclarator::Flavor::name: emitName(declarator->name, declarator->loc); break; @@ -1197,24 +1207,23 @@ struct EmitVisitor } void EmitType( - RefPtr<Type> type, - SourceLoc const& typeLoc, - String const& name, - SourceLoc const& nameLoc) + RefPtr<Type> type, + SourceLoc const& typeLoc, + Name* name, + SourceLoc const& nameLoc) { advanceToSourceLocation(typeLoc); EDeclarator nameDeclarator; - nameDeclarator.flavor = EDeclarator::Flavor::Name; + nameDeclarator.flavor = EDeclarator::Flavor::name; nameDeclarator.name = name; nameDeclarator.loc = nameLoc; emitTypeImpl(type, &nameDeclarator); } - - void EmitType(RefPtr<Type> type, Token const& nameToken) + void EmitType(RefPtr<Type> type, Name* name) { - EmitType(type, SourceLoc(), nameToken.Content, nameToken.Position); + EmitType(type, SourceLoc(), name, SourceLoc()); } void EmitType(RefPtr<Type> 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<ErrorType>()) { @@ -1253,7 +1262,7 @@ struct EmitVisitor } EDeclarator nameDeclarator; - nameDeclarator.flavor = EDeclarator::Flavor::Name; + nameDeclarator.flavor = EDeclarator::Flavor::name; nameDeclarator.name = name; nameDeclarator.loc = nameLoc; @@ -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<InvokeExpr> 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<PrefixExpr>() ) @@ -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<HLSLUncheckedAttribute>()) { - 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<BlockStmt>()) { @@ -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<HLSLAttribute>()) { 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<SimpleModifier>()) { - 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<ErrorType>()) { - 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<ParameterBlockReflectionName>() ) { Emit(" "); - emitName(reflectionNameModifier->nameToken); + emitName(reflectionNameModifier->nameAndLoc); } EmitSemantics(varDecl, kESemanticMask_None); @@ -3490,7 +3501,7 @@ struct EmitVisitor if( auto reflectionNameModifier = varDecl->FindModifier<ParameterBlockReflectionName>() ) { 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<Decl>, 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 3370b369b..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<ContainerDecl> 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<TransparentModifier>()) @@ -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<Type> baseType, + Name* name, + RefPtr<Type> 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<Decl> 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<ContainerDecl> 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> scope) { LookupRequest request; @@ -379,7 +379,7 @@ LookupResult LookUp( LookupResult LookUpLocal( Session* session, SemanticsVisitor* semantics, - String const& name, + Name* name, DeclRef<ContainerDecl> 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> 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<ContainerDecl> containerDeclRef); // TODO: this belongs somewhere else diff --git a/source/slang/lower.cpp b/source/slang/lower.cpp index 0f4eca53f..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<String, String> reservedWords; + HashSet<Name*> reservedWords; RefPtr<ModuleDecl> 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<Expr> createUncheckedVarRef( - char const* name) + Name* name) { RefPtr<VarExpr> result = new VarExpr(); result->name = name; return result; } + + RefPtr<Expr> createUncheckedVarRef( + char const* name) + { + return createUncheckedVarRef( + shared->compileRequest->getNamePool()->getName(name)); + } + RefPtr<Expr> createSimpleVarRef( SourceLoc const& loc, VarDeclBase* decl) { RefPtr<VarExpr> 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<TupleExpr> 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<VarExpr> 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<Expr> moveTemp(RefPtr<Expr> expr) { RefPtr<Variable> 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<TupleExpr> 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<VaryingTupleExpr> 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<AggTypeCtorExpr> 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> 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<Expr>* link = nullptr; }; - RefPtr<Expr> createSimpleVarExpr(char const* name) + RefPtr<Expr> createSimpleVarExpr(Name* name) { RefPtr<VarExpr> varExpr = new VarExpr(); varExpr->name = name; return varExpr; } + RefPtr<Expr> createSimpleVarExpr(char const* name) + { + return createSimpleVarExpr(getName(name)); + } + RefPtr<InvokeExpr> createSeqExpr( RefPtr<Expr> left, RefPtr<Expr> right) { RefPtr<InfixExpr> 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<IndexExpr> 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> 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<VaryingTupleExpr> 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<VaryingTupleExpr> 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<MemberExpr> 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<VaryingTupleExpr> 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<MemberExpr> 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<VarExpr>()) { - 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<VaryingTupleVarDecl> 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> expr) { RefPtr<ExplicitCastExpr> 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> 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); @@ -2948,7 +2973,7 @@ struct LoweringVisitor // Syntax class for declarations to create SyntaxClass<VarDeclBase> 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 @@ -3000,7 +3025,7 @@ struct LoweringVisitor SLANG_RELEASE_ASSERT(!info.initExpr); RefPtr<Expr> 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<VarDeclBase> 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<VarDeclBase> varDeclClass, RefPtr<VarDeclBase> originalVarDecl, String const& name, - RefPtr<Type> tupleType, + RefPtr<Type> tupleType, DeclRef<AggTypeDecl> tupleTypeDecl, TupleTypeModifier* tupleTypeMod, - RefPtr<Expr> initExpr, + RefPtr<Expr> initExpr, RefPtr<VarLayout> primaryVarLayout, RefPtr<StructTypeLayout> tupleTypeLayout) { @@ -3144,14 +3169,14 @@ struct LoweringVisitor // We'll need a placeholder declaration to wrap the whole thing up: RefPtr<TupleVarDecl> 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<VarDeclBase> 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> type) { RefPtr<VarExpr> 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<Variable> 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<VarExpr> 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<VaryingTupleVarDecl> 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<FunctionDeclBase>(); + auto mainName = getName("main"); + // Now we will generate a `void main() { ... }` function to call the lowered code. RefPtr<FuncDecl> 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<BlockStmt> bodyStmt = new BlockStmt(); bodyStmt->scopeDecl = new ScopeDecl(); @@ -4229,8 +4260,8 @@ struct LoweringVisitor SLANG_RELEASE_ASSERT(paramLayout); RefPtr<Variable> 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; @@ -4387,13 +4418,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/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<RefPtr<Expr>>, 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> 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<String, RefPtr<Name> > 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 eeaa04a3f..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<String, ParameterInfo*> mapNameToParameterInfo; + Dictionary<Name*, ParameterInfo*> 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<ParameterBlockReflectionName>()) - 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<Type> tryGetEffectiveTypeForGLSLVaryingInput( @@ -1688,7 +1688,7 @@ void generateParameterBindings( programLayout->bindingForHackSampler = (int)binding; RefPtr<Variable> 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 d85363bb6..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<HLSLUncheckedAttribute> 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<Modifier> parsedModifier; if (tryParseUsingSyntaxDecl<Modifier>(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<RefObject> 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 @@ -859,7 +881,7 @@ namespace Slang // Different cases of declarator appear as "flavors" here enum class Flavor { - Name, + name, Pointer, Array, }; @@ -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<Expr> typeSpec; - Token nameToken; - RefPtr<Modifier> semantics; - RefPtr<Expr> initializer; + RefPtr<Expr> typeSpec; + NameLoc nameAndLoc; + RefPtr<Modifier> semantics; + RefPtr<Expr> 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); @@ -1068,8 +1089,8 @@ namespace Slang case TokenType::Identifier: { auto nameDeclarator = new NameDeclarator(); - nameDeclarator->flavor = Declarator::Flavor::Name; - nameDeclarator->nameToken = ParseDeclName(parser); + nameDeclarator->flavor = Declarator::Flavor::name; + nameDeclarator->nameAndLoc = ParseDeclName(parser); declarator = nameDeclarator; } break; @@ -1197,10 +1218,10 @@ namespace Slang { switch(declarator->flavor) { - case Declarator::Flavor::Name: + 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<IndexExpr> 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<Expr> 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<Decl>(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<InterfaceDecl> 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<RefObject> parseSimpleSyntax(Parser* parser, void* userData) + static RefPtr<RefObject> 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<RefObject> 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> 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<ClassDecl> 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<Variable> 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<SeqStmt> 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<Expr> right) { RefPtr<InfixExpr> 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<SelectExpr> 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> 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> parenExpr = new ParenExpr(); - parenExpr->Position = openParen.Position; + parenExpr->loc = openParen.loc; parenExpr->base = base; return parenExpr; } @@ -3529,8 +3545,9 @@ namespace Slang RefPtr<VarExpr> 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<RefObject> syntaxClass) { - String name(nameText); + Name* name = session->getNamePool()->getName(nameText); RefPtr<SyntaxDecl> 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<GLSLLayoutModifier> 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 9c9a340ae..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<String, PreprocessorMacro*> macros; + Dictionary<Name*, PreprocessorMacro*> 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<Token> params; + List<NameLoc> 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); } } @@ -1885,7 +1906,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 @@ -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<ParameterBlockReflectionName>()) - 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<NAME>()); + #define SYNTAX_CLASS(NAME, BASE) \ + mapNameToSyntaxClass.Add(getNamePool()->getName(#NAME), getClass<NAME>()); #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<EntryPointRequest> 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<ModuleDecl> 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<ModuleDecl> 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<ModuleDecl> 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<ModuleDecl> CompileRequest::findOrImportModule( RefPtr<ModuleDecl> 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 @@ <ClInclude Include="lexer.h" /> <ClInclude Include="lookup.h" /> <ClInclude Include="modifier-defs.h" /> + <ClInclude Include="name.h" /> <ClInclude Include="object-meta-begin.h" /> <ClInclude Include="object-meta-end.h" /> <ClInclude Include="lower.h" /> @@ -205,6 +206,7 @@ <ClCompile Include="lexer.cpp" /> <ClCompile Include="lookup.cpp" /> <ClCompile Include="lower.cpp" /> + <ClCompile Include="name.cpp" /> <ClCompile Include="options.cpp" /> <ClCompile Include="parameter-binding.cpp" /> <ClCompile Include="parser.cpp" /> 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 @@ <ClInclude Include="val-defs.h" /> <ClInclude Include="visitor.h" /> <ClInclude Include="lower.h" /> + <ClInclude Include="name.h" /> </ItemGroup> <ItemGroup> <ClCompile Include="check.cpp" /> @@ -57,5 +58,6 @@ <ClCompile Include="options.cpp" /> <ClCompile Include="lower.cpp" /> <ClCompile Include="source-loc.cpp" /> + <ClCompile Include="name.cpp" /> </ItemGroup> </Project>
\ No newline at end of file diff --git a/source/slang/syntax-base-defs.h b/source/slang/syntax-base-defs.h index 711c4425b..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<Modifier>, 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<ModuleDecl> 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 2bd6c122c..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<RefObject> Session::findSyntaxClass(String const& name) + SyntaxClass<RefObject> Session::findSyntaxClass(Name* name) { SyntaxClass<RefObject> 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<VarDeclBase> 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> typeLayout; |
