summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorTim Foley <tfoley@nvidia.com>2017-08-14 14:48:37 -0700
committerTim Foley <tfoley@nvidia.com>2017-08-14 14:48:37 -0700
commit9885c972a6bfa6f856e505cdd90d9b71fdbdadaf (patch)
tree7314b26e21ded966b6a4fe2430f0421c0c0970bd /source
parent7f57ea4ad86c2a3eb5a14fef458e711845c1f87e (diff)
Add an explicit `Name` type
Fixes #23 Up to this point, the compiler has used the ordinary `String` type to represent declaration names, which means a bunch of lookup structures throughout the compiler were string-to-whatever maps, which can reduce efficiency. It also means that things like the `Token` type end up carying a `String` by value and paying for things like reference-counting. This change adds a `Name` type that is used to represent names of variables, types, macros, etc. Names are cached and unique'd globally for a session, and the string-to-name mapping gets done during lexing. From that point on, most mapping is from pointers, which should make all the various table lookups faster. More importantly (possibly), this brings us one step closer to being able to pool-allocate the AST nodes.
Diffstat (limited to 'source')
-rw-r--r--source/slang/check.cpp75
-rw-r--r--source/slang/compiler.cpp2
-rw-r--r--source/slang/compiler.h28
-rw-r--r--source/slang/decl-defs.h24
-rw-r--r--source/slang/diagnostic-defs.h2
-rw-r--r--source/slang/diagnostics.cpp19
-rw-r--r--source/slang/diagnostics.h10
-rw-r--r--source/slang/emit.cpp107
-rw-r--r--source/slang/expr-defs.h2
-rw-r--r--source/slang/lexer.cpp61
-rw-r--r--source/slang/lexer.h12
-rw-r--r--source/slang/lookup.cpp32
-rw-r--r--source/slang/lookup.h4
-rw-r--r--source/slang/lower.cpp171
-rw-r--r--source/slang/modifier-defs.h3
-rw-r--r--source/slang/name.cpp24
-rw-r--r--source/slang/name.h81
-rw-r--r--source/slang/parameter-binding.cpp10
-rw-r--r--source/slang/parser.cpp252
-rw-r--r--source/slang/preprocessor.cpp109
-rw-r--r--source/slang/reflection.cpp6
-rw-r--r--source/slang/slang.cpp29
-rw-r--r--source/slang/slang.vcxproj2
-rw-r--r--source/slang/slang.vcxproj.filters2
-rw-r--r--source/slang/syntax-base-defs.h18
-rw-r--r--source/slang/syntax-visitors.h4
-rw-r--r--source/slang/syntax.cpp14
-rw-r--r--source/slang/syntax.h31
-rw-r--r--source/slang/token.cpp18
-rw-r--r--source/slang/token.h25
-rw-r--r--source/slang/type-layout.h2
31 files changed, 715 insertions, 464 deletions
diff --git a/source/slang/check.cpp b/source/slang/check.cpp
index 6b8617c66..cc2954fc4 100644
--- a/source/slang/check.cpp
+++ b/source/slang/check.cpp
@@ -147,7 +147,7 @@ namespace Slang
if (baseExpr)
{
auto expr = new MemberExpr();
- expr->Position = originalExpr->Position;
+ expr->loc = originalExpr->loc;
expr->BaseExpression = baseExpr;
expr->name = declRef.GetName();
expr->type = GetTypeForDeclRef(declRef);
@@ -157,7 +157,7 @@ namespace Slang
else
{
auto expr = new VarExpr();
- expr->Position = originalExpr->Position;
+ expr->loc = originalExpr->loc;
expr->name = declRef.GetName();
expr->type = GetTypeForDeclRef(declRef);
expr->declRef = declRef;
@@ -173,7 +173,7 @@ namespace Slang
SLANG_ASSERT(ptrLikeType);
auto derefExpr = new DerefExpr();
- derefExpr->Position = originalExpr->Position;
+ derefExpr->loc = originalExpr->loc;
derefExpr->base = base;
derefExpr->type = QualType(ptrLikeType->elementType);
@@ -217,7 +217,7 @@ namespace Slang
if (lookupResult.isOverloaded())
{
auto overloadedExpr = new OverloadedExpr();
- overloadedExpr->Position = originalExpr->Position;
+ overloadedExpr->loc = originalExpr->loc;
overloadedExpr->type = QualType(
getSession()->getOverloadedType());
overloadedExpr->base = baseExpr;
@@ -823,7 +823,7 @@ namespace Slang
if(outToExpr)
{
auto toInitializerListExpr = new InitializerListExpr();
- toInitializerListExpr->Position = fromInitializerListExpr->Position;
+ toInitializerListExpr->loc = fromInitializerListExpr->loc;
toInitializerListExpr->type = QualType(toType);
toInitializerListExpr->args = coercedArgs;
@@ -1007,7 +1007,7 @@ namespace Slang
castExpr = new ImplicitCastExpr();
}
- castExpr->Position = fromExpr->Position;
+ castExpr->loc = fromExpr->loc;
castExpr->TargetType.type = toType;
castExpr->type = QualType(toType);
castExpr->Expression = fromExpr;
@@ -1042,7 +1042,7 @@ namespace Slang
{
if(!isRewriteMode())
{
- getSink()->diagnose(fromExpr->Position, Diagnostics::typeMismatch, toType, fromExpr->type);
+ getSink()->diagnose(fromExpr->loc, Diagnostics::typeMismatch, toType, fromExpr->type);
}
// Note(tfoley): We don't call `CreateErrorExpr` here, because that would
@@ -1190,7 +1190,7 @@ namespace Slang
{
if (!isRewriteMode())
{
- getSink()->diagnose(expr->Position, Diagnostics::expectedIntegerConstantNotLiteral);
+ getSink()->diagnose(expr->loc, Diagnostics::expectedIntegerConstantNotLiteral);
}
return nullptr;
}
@@ -1234,7 +1234,7 @@ namespace Slang
// For now we will do this in a completely ad hoc fashion,
// but it would be nice to have some generic routine to
// do the needed type checking/coercion.
- if(hlslUncheckedAttribute->nameToken.Content == "numthreads")
+ if(getText(hlslUncheckedAttribute->getName()) == "numthreads")
{
if(hlslUncheckedAttribute->args.Count() != 3)
return m;
@@ -1249,8 +1249,8 @@ namespace Slang
auto hlslNumThreadsAttribute = new HLSLNumThreadsAttribute();
- hlslNumThreadsAttribute->Position = hlslUncheckedAttribute->Position;
- hlslNumThreadsAttribute->nameToken = hlslUncheckedAttribute->nameToken;
+ hlslNumThreadsAttribute->loc = hlslUncheckedAttribute->loc;
+ hlslNumThreadsAttribute->name = hlslUncheckedAttribute->getName();
hlslNumThreadsAttribute->args = hlslUncheckedAttribute->args;
hlslNumThreadsAttribute->x = (int32_t) xVal->value;
hlslNumThreadsAttribute->y = (int32_t) yVal->value;
@@ -1614,20 +1614,20 @@ namespace Slang
this->function = functionNode;
auto returnType = CheckProperType(functionNode->ReturnType);
functionNode->ReturnType = returnType;
- HashSet<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 a63df243b..f27ab9ba6 100644
--- a/source/slang/decl-defs.h
+++ b/source/slang/decl-defs.h
@@ -21,7 +21,7 @@ ABSTRACT_SYNTAX_CLASS(ContainerDecl, Decl)
// Dictionary for looking up members by name.
// This is built on demand before performing lookup.
- Dictionary<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 6f971ae76..45adf0ad8 100644
--- a/source/slang/diagnostics.cpp
+++ b/source/slang/diagnostics.cpp
@@ -2,6 +2,7 @@
#include "diagnostics.h"
#include "compiler.h"
+#include "name.h"
#include "syntax.h"
#include <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 fff79ae51..71ee31e5e 100644
--- a/source/slang/emit.cpp
+++ b/source/slang/emit.cpp
@@ -2,6 +2,7 @@
#include "emit.h"
#include "lower.h"
+#include "name.h"
#include "syntax.h"
#include "type-layout.h"
#include "visitor.h"
@@ -343,8 +344,8 @@ struct EDeclarator
EDeclarator* next = nullptr;
// Used for `Flavor::name`
- String name;
- SourceLoc loc;
+ Name* name;
+ SourceLoc loc;
// Used for `Flavor::Array`
IntVal* elementCount;
@@ -450,22 +451,31 @@ struct EmitVisitor
Emit(text.begin(), text.end());
}
- void emitName(
- String const& inName,
- SourceLoc const& loc)
+ void emit(Name* name)
{
- String name = inName;
+ emit(getText(name));
+ }
+
+ void emit(NameLoc const& nameAndLoc)
+ {
+ advanceToSourceLocation(nameAndLoc.loc);
+ emit(getText(nameAndLoc.name));
+ }
+ void emitName(
+ Name* name,
+ SourceLoc const& loc)
+ {
advanceToSourceLocation(loc);
emit(name);
}
- void emitName(Token const& nameToken)
+ void emitName(NameLoc const& nameAndLoc)
{
- emitName(nameToken.Content, nameToken.Position);
+ emitName(nameAndLoc.name, nameAndLoc.loc);
}
- void emitName(String const& name)
+ void emitName(Name* name)
{
emitName(name, SourceLoc());
}
@@ -720,7 +730,7 @@ struct EmitVisitor
return;
if ((mode == LineDirectiveMode::None)
- || !token.Position.isValid())
+ || !token.loc.isValid())
{
// If we don't have the original position info, or we are in the
// mode where the user didn't want line directives, we need to play
@@ -738,7 +748,7 @@ struct EmitVisitor
// If location information is available, and we are emitting
// such information, then just advance our tracking location
// to the right place.
- advanceToSourceLocation(token.Position);
+ advanceToSourceLocation(token.loc);
}
// Emit the raw textual content of the token
@@ -1197,10 +1207,10 @@ struct EmitVisitor
}
void EmitType(
- RefPtr<Type> type,
- SourceLoc const& typeLoc,
- String const& name,
- SourceLoc const& nameLoc)
+ RefPtr<Type> type,
+ SourceLoc const& typeLoc,
+ Name* name,
+ SourceLoc const& nameLoc)
{
advanceToSourceLocation(typeLoc);
@@ -1211,10 +1221,9 @@ struct EmitVisitor
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>())
{
@@ -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 30db9d75e..ccdbe8fbf 100644
--- a/source/slang/lookup.cpp
+++ b/source/slang/lookup.cpp
@@ -23,7 +23,7 @@ struct BreadcrumbInfo
void DoLocalLookupImpl(
Session* session,
- String const& name,
+ Name* name,
DeclRef<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 68f61f8a5..2c62a69a8 100644
--- a/source/slang/lower.cpp
+++ b/source/slang/lower.cpp
@@ -317,8 +317,8 @@ private:
class PseudoVarDecl : public RefObject
{
public:
- Token name;
- SourceLoc Position;
+ NameLoc nameAndLoc;
+ SourceLoc loc;
TypeExp type;
};
@@ -339,7 +339,7 @@ public:
class PseudoExpr : public RefObject
{
public:
- SourceLoc Position;
+ SourceLoc loc;
QualType type;
};
@@ -388,9 +388,9 @@ static SourceLoc getPosition(LoweredExpr const& expr)
{
switch (expr.getFlavor())
{
- case LoweredExpr::Flavor::Expr: return expr.getExpr() ->Position;
- case LoweredExpr::Flavor::Tuple: return expr.getTupleExpr() ->Position;
- case LoweredExpr::Flavor::VaryingTuple: return expr.getVaryingTupleExpr()->Position;
+ case LoweredExpr::Flavor::Expr: return expr.getExpr() ->loc;
+ case LoweredExpr::Flavor::Tuple: return expr.getTupleExpr() ->loc;
+ case LoweredExpr::Flavor::VaryingTuple: return expr.getVaryingTupleExpr()->loc;
default:
SLANG_UNREACHABLE("all cases handled");
return SourceLoc();
@@ -415,7 +415,7 @@ struct SharedLoweringContext
CodeGenTarget target;
// A set of words reserved by the target
- Dictionary<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);
@@ -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;
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 4a6eac472..877597640 100644
--- a/source/slang/parameter-binding.cpp
+++ b/source/slang/parameter-binding.cpp
@@ -226,7 +226,7 @@ struct ParameterBindingContext
LayoutRulesFamilyImpl* layoutRules;
// A dictionary to accellerate looking up parameters by name
- Dictionary<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 84935cb7f..7ea3fe864 100644
--- a/source/slang/parser.cpp
+++ b/source/slang/parser.cpp
@@ -55,7 +55,7 @@ namespace Slang
void FillPosition(SyntaxNode * node)
{
- node->Position = tokenReader.PeekLoc();
+ node->loc = tokenReader.PeekLoc();
}
void PushScope(ContainerDecl* containerDecl)
{
@@ -536,9 +536,9 @@ namespace Slang
auto type = parser->ParseTypeExp();
auto nameToken = parser->ReadToken(TokenType::Identifier);
- typeDefDecl->Position = nameToken.Position;
+ typeDefDecl->loc = nameToken.loc;
- typeDefDecl->name = nameToken;
+ typeDefDecl->nameAndLoc = NameLoc(nameToken);
typeDefDecl->type = type;
return typeDefDecl;
@@ -572,7 +572,8 @@ namespace Slang
{
auto nameToken = parser->ReadToken(TokenType::Identifier);
RefPtr<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
@@ -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);
@@ -1069,7 +1090,7 @@ namespace Slang
{
auto nameDeclarator = new NameDeclarator();
nameDeclarator->flavor = Declarator::Flavor::name;
- nameDeclarator->nameToken = ParseDeclName(parser);
+ nameDeclarator->nameAndLoc = ParseDeclName(parser);
declarator = nameDeclarator;
}
break;
@@ -1200,7 +1221,7 @@ namespace Slang
case Declarator::Flavor::name:
{
auto nameDeclarator = (NameDeclarator*) declarator.Ptr();
- ioInfo->nameToken = nameDeclarator->nameToken;
+ ioInfo->nameAndLoc = nameDeclarator->nameAndLoc;
return;
}
break;
@@ -1222,7 +1243,7 @@ namespace Slang
auto arrayDeclarator = (ArrayDeclarator*) declarator.Ptr();
auto arrayTypeExpr = new IndexExpr();
- arrayTypeExpr->Position = arrayDeclarator->openBracketLoc;
+ arrayTypeExpr->loc = arrayDeclarator->openBracketLoc;
arrayTypeExpr->BaseExpression = ioInfo->typeSpec;
arrayTypeExpr->IndexExpression = arrayDeclarator->elementCountExpr;
ioInfo->typeSpec = arrayTypeExpr;
@@ -1263,7 +1284,7 @@ namespace Slang
if( decl )
{
group = new DeclGroup();
- group->Position = startPosition;
+ group->loc = startPosition;
group->decls.Add(decl);
decl = nullptr;
}
@@ -1302,7 +1323,7 @@ namespace Slang
auto expr = new VarExpr();
expr->scope = parser->currentScope.Ptr();
- expr->Position = decl->getNameToken().Position;
+ expr->loc = decl->getNameLoc();
expr->name = decl->getName();
return expr;
}
@@ -1353,7 +1374,7 @@ namespace Slang
while (parser->LookAheadToken(TokenType::LBracket))
{
RefPtr<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 11e574064..fff3c0fd4 100644
--- a/source/slang/preprocessor.cpp
+++ b/source/slang/preprocessor.cpp
@@ -51,7 +51,7 @@ struct PreprocessorEnvironment
PreprocessorEnvironment* parent = NULL;
// Macros defined in this environment
- Dictionary<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);
}
}
@@ -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 d67acbe5c..e6f7cc55e 100644
--- a/source/slang/syntax-base-defs.h
+++ b/source/slang/syntax-base-defs.h
@@ -9,7 +9,7 @@
ABSTRACT_SYNTAX_CLASS(SyntaxNodeBase, RefObject)
// The primary source location associated with this AST node
- FIELD(SourceLoc, Position)
+ FIELD(SourceLoc, loc)
RAW(
// Allow dynamic casting with a convenient syntax
@@ -173,8 +173,13 @@ ABSTRACT_SYNTAX_CLASS(Modifier, SyntaxNodeBase)
// Next modifier in linked list of modifiers on same piece of syntax
SYNTAX_FIELD(RefPtr<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 a03783825..be1a429a6 100644
--- a/source/slang/syntax.cpp
+++ b/source/slang/syntax.cpp
@@ -260,7 +260,7 @@ void Type::accept(IValVisitor* visitor, void* extra)
return errorType;
}
- SyntaxClass<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;