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