summaryrefslogtreecommitdiffstats
path: root/source/slang/emit.cpp
diff options
context:
space:
mode:
authorTim Foley <tfoley@nvidia.com>2017-08-14 14:48:37 -0700
committerTim Foley <tfoley@nvidia.com>2017-08-14 14:48:37 -0700
commit9885c972a6bfa6f856e505cdd90d9b71fdbdadaf (patch)
tree7314b26e21ded966b6a4fe2430f0421c0c0970bd /source/slang/emit.cpp
parent7f57ea4ad86c2a3eb5a14fef458e711845c1f87e (diff)
Add an explicit `Name` type
Fixes #23 Up to this point, the compiler has used the ordinary `String` type to represent declaration names, which means a bunch of lookup structures throughout the compiler were string-to-whatever maps, which can reduce efficiency. It also means that things like the `Token` type end up carying a `String` by value and paying for things like reference-counting. This change adds a `Name` type that is used to represent names of variables, types, macros, etc. Names are cached and unique'd globally for a session, and the string-to-name mapping gets done during lexing. From that point on, most mapping is from pointers, which should make all the various table lookups faster. More importantly (possibly), this brings us one step closer to being able to pool-allocate the AST nodes.
Diffstat (limited to 'source/slang/emit.cpp')
-rw-r--r--source/slang/emit.cpp107
1 files changed, 59 insertions, 48 deletions
diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp
index fff79ae51..71ee31e5e 100644
--- a/source/slang/emit.cpp
+++ b/source/slang/emit.cpp
@@ -2,6 +2,7 @@
#include "emit.h"
#include "lower.h"
+#include "name.h"
#include "syntax.h"
#include "type-layout.h"
#include "visitor.h"
@@ -343,8 +344,8 @@ struct EDeclarator
EDeclarator* next = nullptr;
// Used for `Flavor::name`
- String name;
- SourceLoc loc;
+ Name* name;
+ SourceLoc loc;
// Used for `Flavor::Array`
IntVal* elementCount;
@@ -450,22 +451,31 @@ struct EmitVisitor
Emit(text.begin(), text.end());
}
- void emitName(
- String const& inName,
- SourceLoc const& loc)
+ void emit(Name* name)
{
- String name = inName;
+ emit(getText(name));
+ }
+
+ void emit(NameLoc const& nameAndLoc)
+ {
+ advanceToSourceLocation(nameAndLoc.loc);
+ emit(getText(nameAndLoc.name));
+ }
+ void emitName(
+ Name* name,
+ SourceLoc const& loc)
+ {
advanceToSourceLocation(loc);
emit(name);
}
- void emitName(Token const& nameToken)
+ void emitName(NameLoc const& nameAndLoc)
{
- emitName(nameToken.Content, nameToken.Position);
+ emitName(nameAndLoc.name, nameAndLoc.loc);
}
- void emitName(String const& name)
+ void emitName(Name* name)
{
emitName(name, SourceLoc());
}
@@ -720,7 +730,7 @@ struct EmitVisitor
return;
if ((mode == LineDirectiveMode::None)
- || !token.Position.isValid())
+ || !token.loc.isValid())
{
// If we don't have the original position info, or we are in the
// mode where the user didn't want line directives, we need to play
@@ -738,7 +748,7 @@ struct EmitVisitor
// If location information is available, and we are emitting
// such information, then just advance our tracking location
// to the right place.
- advanceToSourceLocation(token.Position);
+ advanceToSourceLocation(token.loc);
}
// Emit the raw textual content of the token
@@ -1197,10 +1207,10 @@ struct EmitVisitor
}
void EmitType(
- RefPtr<Type> type,
- SourceLoc const& typeLoc,
- String const& name,
- SourceLoc const& nameLoc)
+ RefPtr<Type> type,
+ SourceLoc const& typeLoc,
+ Name* name,
+ SourceLoc const& nameLoc)
{
advanceToSourceLocation(typeLoc);
@@ -1211,10 +1221,9 @@ struct EmitVisitor
emitTypeImpl(type, &nameDeclarator);
}
-
- void EmitType(RefPtr<Type> type, Token const& nameToken)
+ void EmitType(RefPtr<Type> type, Name* name)
{
- EmitType(type, SourceLoc(), nameToken.Content, nameToken.Position);
+ EmitType(type, SourceLoc(), name, SourceLoc());
}
void EmitType(RefPtr<Type> type)
@@ -1243,7 +1252,7 @@ struct EmitVisitor
}
}
- void EmitType(TypeExp const& typeExp, String const& name, SourceLoc const& nameLoc)
+ void EmitType(TypeExp const& typeExp, Name* name, SourceLoc const& nameLoc)
{
if (!typeExp.type || typeExp.type->As<ErrorType>())
{
@@ -1262,17 +1271,17 @@ struct EmitVisitor
else
{
EmitType(typeExp.type,
- typeExp.exp ? typeExp.exp->Position : SourceLoc(),
+ typeExp.exp ? typeExp.exp->loc : SourceLoc(),
name, nameLoc);
}
}
- void EmitType(TypeExp const& typeExp, Token const& nameToken)
+ void EmitType(TypeExp const& typeExp, NameLoc const& nameAndLoc)
{
- EmitType(typeExp, nameToken.Content, nameToken.Position);
+ EmitType(typeExp, nameAndLoc.name, nameAndLoc.loc);
}
- void EmitType(TypeExp const& typeExp, String const& name)
+ void EmitType(TypeExp const& typeExp, Name* name)
{
EmitType(typeExp, name, SourceLoc());
}
@@ -1674,12 +1683,14 @@ struct EmitVisitor
void emitUncheckedCallExpr(
RefPtr<InvokeExpr> callExpr,
- String const& funcName,
- ExprEmitArg const& arg)
+ Name* funcName,
+ ExprEmitArg const& arg)
{
auto outerPrec = arg.outerPrec;
auto funcExpr = callExpr->FunctionExpr;
+ auto funcNameText = getText(funcName);
+
// This can occur when we are dealing with unchecked input syntax,
// because we are in "rewriter" mode. In this case we should go
// ahead and emit things in the form that they were written.
@@ -1688,7 +1699,7 @@ struct EmitVisitor
auto prec = kEOp_Comma;
for (auto opInfo : kInfixOpInfos)
{
- if (funcName == opInfo->op)
+ if (funcNameText == opInfo->op)
{
prec = *opInfo;
break;
@@ -1698,7 +1709,7 @@ struct EmitVisitor
EmitBinExpr(
outerPrec,
prec,
- funcName.Buffer(),
+ funcNameText.Buffer(),
callExpr);
}
else if( auto prefixExpr = callExpr.As<PrefixExpr>() )
@@ -1706,7 +1717,7 @@ struct EmitVisitor
EmitUnaryExpr(
outerPrec,
kEOp_Prefix,
- funcName.Buffer(),
+ funcNameText.Buffer(),
"",
callExpr);
}
@@ -1716,7 +1727,7 @@ struct EmitVisitor
outerPrec,
kEOp_Postfix,
"",
- funcName.Buffer(),
+ funcNameText.Buffer(),
callExpr);
}
else
@@ -2279,7 +2290,7 @@ struct EmitVisitor
// TODO: This won't be valid if we had to generate a qualified
// reference for some reason.
- advanceToSourceLocation(varExpr->Position);
+ advanceToSourceLocation(varExpr->loc);
// Because of the "rewriter" use case, it is possible that we will
// be trying to emit an expression that hasn't been wired up to
@@ -2456,11 +2467,11 @@ struct EmitVisitor
for(auto attr : decl->GetModifiersOfType<HLSLUncheckedAttribute>())
{
- if(attr->nameToken.Content == "loop")
+ if(getText(attr->getName()) == "loop")
{
Emit("[loop]");
}
- else if(attr->nameToken.Content == "unroll")
+ else if(getText(attr->getName()) == "unroll")
{
Emit("[unroll]");
}
@@ -2486,7 +2497,7 @@ struct EmitVisitor
return;
// Try to ensure that debugging can find the right location
- advanceToSourceLocation(stmt->Position);
+ advanceToSourceLocation(stmt->loc);
if (auto blockStmt = stmt.As<BlockStmt>())
{
@@ -2734,7 +2745,7 @@ struct EmitVisitor
return;
// Try to ensure that debugging can find the right location
- advanceToSourceLocation(decl->Position);
+ advanceToSourceLocation(decl->loc);
DeclEmitArg arg;
arg.layout = layout;
@@ -2789,7 +2800,7 @@ struct EmitVisitor
SLANG_RELEASE_ASSERT(context->shared->target != CodeGenTarget::GLSL);
Emit("typedef ");
- EmitType(decl->type, decl->name.Content);
+ EmitType(decl->type, decl->getNameAndLoc());
Emit(";\n");
}
@@ -2873,7 +2884,7 @@ struct EmitVisitor
Emit(", ");
}
- emit(mod->nameToken.Content);
+ emit(mod->getNameAndLoc());
if(mod->valToken.type != TokenType::Unknown)
{
Emit(" = ");
@@ -2890,7 +2901,7 @@ struct EmitVisitor
if (shouldSkipModifierForDecl(mod, decl))
continue;
- advanceToSourceLocation(mod->Position);
+ advanceToSourceLocation(mod->loc);
if (0) {}
@@ -2958,7 +2969,7 @@ struct EmitVisitor
else if (auto uncheckedAttr = mod.As<HLSLAttribute>())
{
Emit("[");
- emit(uncheckedAttr->nameToken.Content);
+ emit(uncheckedAttr->getNameAndLoc());
auto& args = uncheckedAttr->args;
auto argCount = args.Count();
if (argCount != 0)
@@ -2976,7 +2987,7 @@ struct EmitVisitor
else if(auto simpleModifier = mod.As<SimpleModifier>())
{
- emit(simpleModifier->nameToken.Content);
+ emit(simpleModifier->getNameAndLoc());
Emit(" ");
}
@@ -3038,7 +3049,7 @@ struct EmitVisitor
}
else
{
- SLANG_DIAGNOSE_UNEXPECTED(getSink(), semantic->Position, "unhandled kind of semantic");
+ SLANG_DIAGNOSE_UNEXPECTED(getSink(), semantic->loc, "unhandled kind of semantic");
}
}
@@ -3100,7 +3111,7 @@ struct EmitVisitor
return;
Emit("struct ");
- emitName(decl->name);
+ emitName(decl->getNameAndLoc());
Emit("\n{\n");
// TODO(tfoley): Need to hoist members functions, etc. out to global scope
@@ -3117,11 +3128,11 @@ struct EmitVisitor
auto type = GetType(declRef);
if (!type || type->As<ErrorType>())
{
- EmitType(declRef.getDecl()->type, declRef.getDecl()->getNameToken());
+ EmitType(declRef.getDecl()->type, declRef.getDecl()->getName());
}
else
{
- EmitType(GetType(declRef), declRef.getDecl()->getNameToken());
+ EmitType(GetType(declRef), declRef.getDecl()->getName());
}
EmitSemantics(declRef.getDecl());
@@ -3303,7 +3314,7 @@ struct EmitVisitor
if( auto reflectionNameModifier = varDecl->FindModifier<ParameterBlockReflectionName>() )
{
Emit(" ");
- emitName(reflectionNameModifier->nameToken);
+ emitName(reflectionNameModifier->nameAndLoc);
}
EmitSemantics(varDecl, kESemanticMask_None);
@@ -3490,7 +3501,7 @@ struct EmitVisitor
if( auto reflectionNameModifier = varDecl->FindModifier<ParameterBlockReflectionName>() )
{
Emit(" ");
- emitName(reflectionNameModifier->nameToken);
+ emitName(reflectionNameModifier->nameAndLoc);
}
Emit("\n{\n");
@@ -3516,10 +3527,10 @@ struct EmitVisitor
}
Emit("}");
- if( varDecl->name.type != TokenType::Unknown )
+ if( varDecl->getNameLoc().isValid() )
{
Emit(" ");
- emitName(varDecl->name);
+ emitName(varDecl->getName());
}
Emit(";\n");
@@ -3624,7 +3635,7 @@ struct EmitVisitor
// isn't allowed by declarator syntax and/or language rules, we could
// hypothetically wrap things in a `typedef` and work around it.
- EmitType(decl->ReturnType, decl->name);
+ EmitType(decl->ReturnType, decl->getNameAndLoc());
Emit("(");
bool first = true;