diff options
Diffstat (limited to 'source')
| -rw-r--r-- | source/slang/emit.cpp | 195 | ||||
| -rw-r--r-- | source/slang/lower.cpp | 217 |
2 files changed, 217 insertions, 195 deletions
diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp index 20b9856c5..c135090c1 100644 --- a/source/slang/emit.cpp +++ b/source/slang/emit.cpp @@ -21,9 +21,6 @@ struct SharedEmitContext // The target language we want to generate code for CodeGenTarget target; - // A set of words reserved by the target - Dictionary<String, String> reservedWords; - // The string of code we've built so far StringBuilder sb; @@ -385,48 +382,12 @@ struct EmitVisitor Emit(text.begin(), text.end()); } - bool isReservedWord(String const& name) - { - return context->shared->reservedWords.TryGetValue(name) != nullptr; - } - void emitName( String const& inName, CodePosition const& loc) { String name = inName; - // By default, we would like to emit a name in the generated - // code exactly as it appeared in the soriginal program. - // When that isn't possible, we'd like to emit a name as - // close to the original as possible (to ensure that existing - // debugging tools still work reasonably well). - // - // One reason why a name might not be allowed as-is is that - // it could collide with a reserved word in the target language. - // Another reason is that it might not follow a naming convention - // imposed by the target (e.g., in GLSL names starting with - // `gl_` or containing `__` are reserved). - // - // Given a name that should not be allowed, we want to - // change it to a name that *is* allowed. e.g., by adding - // `_` to the end of a reserved word. - // - // The next problem this creates is that the modified name - // could not collide with an existing use of the same - // (valid) name. - // - // For now we are going to solve this problem in a simple - // and ad hoc fashion, but longer term we'll want to do - // something sytematic. - - if (isReservedWord(name)) - { - // TODO(tfoley): Need to put this back in, as part of lowering. - -// name = name + "_"; - } - advanceToSourceLocation(loc); emit(name); } @@ -3261,159 +3222,6 @@ struct EmitVisitor throw "unimplemented"; } } - - void registerReservedWord( - String const& name) - { - context->shared->reservedWords.Add(name, name); - } - - void registerReservedWords() - { - #define WORD(NAME) registerReservedWord(#NAME) - - switch (context->shared->target) - { - case CodeGenTarget::GLSL: - WORD(attribute); - WORD(const); - WORD(uniform); - WORD(varying); - WORD(buffer); - - WORD(shared); - WORD(coherent); - WORD(volatile); - WORD(restrict); - WORD(readonly); - WORD(writeonly); - WORD(atomic_unit); - WORD(layout); - WORD(centroid); - WORD(flat); - WORD(smooth); - WORD(noperspective); - WORD(patch); - WORD(sample); - WORD(break); - WORD(continue); - WORD(do); - WORD(for); - WORD(while); - WORD(switch); - WORD(case); - WORD(default); - WORD(if); - WORD(else); - WORD(subroutine); - WORD(in); - WORD(out); - WORD(inout); - WORD(float); - WORD(double); - WORD(int); - WORD(void); - WORD(bool); - WORD(true); - WORD(false); - WORD(invariant); - WORD(precise); - WORD(discard); - WORD(return); - - WORD(lowp); - WORD(mediump); - WORD(highp); - WORD(precision); - WORD(struct); - WORD(uint); - - WORD(common); - WORD(partition); - WORD(active); - WORD(asm); - WORD(class); - WORD(union); - WORD(enum); - WORD(typedef); - WORD(template); - WORD(this); - WORD(resource); - - WORD(goto); - WORD(inline); - WORD(noinline); - WORD(public); - WORD(static); - WORD(extern); - WORD(external); - WORD(interface); - WORD(long); - WORD(short); - WORD(half); - WORD(fixed); - WORD(unsigned); - WORD(superp); - WORD(input); - WORD(output); - WORD(filter); - WORD(sizeof); - WORD(cast); - WORD(namespace); - WORD(using); - - #define CASE(NAME) \ - WORD(NAME ## 2); WORD(NAME ## 3); WORD(NAME ## 4) - - CASE(mat); - CASE(dmat); - CASE(mat2x); - CASE(mat3x); - CASE(mat4x); - CASE(dmat2x); - CASE(dmat3x); - CASE(dmat4x); - CASE(vec); - CASE(ivec); - CASE(bvec); - CASE(dvec); - CASE(uvec); - CASE(hvec); - CASE(fvec); - - #undef CASE - - #define CASE(NAME) \ - WORD(NAME ## 1D); \ - WORD(NAME ## 2D); \ - WORD(NAME ## 3D); \ - WORD(NAME ## Cube); \ - WORD(NAME ## 1DArray); \ - WORD(NAME ## 2DArray); \ - WORD(NAME ## 3DArray); \ - WORD(NAME ## CubeArray);\ - WORD(NAME ## 2DMS); \ - WORD(NAME ## 2DMSArray) \ - /* end */ - - #define CASE2(NAME) \ - CASE(NAME); \ - CASE(i ## NAME); \ - CASE(u ## NAME) \ - /* end */ - - CASE2(sampler); - CASE2(image); - CASE2(texture); - - #undef CASE2 - #undef CASE - break; - - default: - break; - } - } }; String emitEntryPoint( @@ -3474,9 +3282,6 @@ String emitEntryPoint( EmitVisitor visitor(&context); - // TODO: this should only need to take the shared context - visitor.registerReservedWords(); - auto translationUnitSyntax = translationUnit->SyntaxNode.Ptr(); diff --git a/source/slang/lower.cpp b/source/slang/lower.cpp index 0d54faf0b..0bb047791 100644 --- a/source/slang/lower.cpp +++ b/source/slang/lower.cpp @@ -194,8 +194,17 @@ public: struct SharedLoweringContext { ProgramLayout* programLayout; + + // The target we are going to generate code for. + // + // We may need to specialize how constructs get lowered based + // on the capabilities of the target language. CodeGenTarget target; + // A set of words reserved by the target + Dictionary<String, String> reservedWords; + + RefPtr<ProgramSyntaxNode> loweredProgram; Dictionary<Decl*, RefPtr<Decl>> loweredDecls; @@ -238,6 +247,165 @@ struct LoweringVisitor CodeGenTarget getTarget() { return shared->target; } + bool isReservedWord(String const& name) + { + return shared->reservedWords.TryGetValue(name) != nullptr; + } + + void registerReservedWord( + String const& name) + { + shared->reservedWords.Add(name, name); + } + + void registerReservedWords() + { + #define WORD(NAME) registerReservedWord(#NAME) + + switch (shared->target) + { + case CodeGenTarget::GLSL: + WORD(attribute); + WORD(const); + WORD(uniform); + WORD(varying); + WORD(buffer); + + WORD(shared); + WORD(coherent); + WORD(volatile); + WORD(restrict); + WORD(readonly); + WORD(writeonly); + WORD(atomic_unit); + WORD(layout); + WORD(centroid); + WORD(flat); + WORD(smooth); + WORD(noperspective); + WORD(patch); + WORD(sample); + WORD(break); + WORD(continue); + WORD(do); + WORD(for); + WORD(while); + WORD(switch); + WORD(case); + WORD(default); + WORD(if); + WORD(else); + WORD(subroutine); + WORD(in); + WORD(out); + WORD(inout); + WORD(float); + WORD(double); + WORD(int); + WORD(void); + WORD(bool); + WORD(true); + WORD(false); + WORD(invariant); + WORD(precise); + WORD(discard); + WORD(return); + + WORD(lowp); + WORD(mediump); + WORD(highp); + WORD(precision); + WORD(struct); + WORD(uint); + + WORD(common); + WORD(partition); + WORD(active); + WORD(asm); + WORD(class); + WORD(union); + WORD(enum); + WORD(typedef); + WORD(template); + WORD(this); + WORD(resource); + + WORD(goto); + WORD(inline); + WORD(noinline); + WORD(public); + WORD(static); + WORD(extern); + WORD(external); + WORD(interface); + WORD(long); + WORD(short); + WORD(half); + WORD(fixed); + WORD(unsigned); + WORD(superp); + WORD(input); + WORD(output); + WORD(filter); + WORD(sizeof); + WORD(cast); + WORD(namespace); + WORD(using); + + #define CASE(NAME) \ + WORD(NAME ## 2); WORD(NAME ## 3); WORD(NAME ## 4) + + CASE(mat); + CASE(dmat); + CASE(mat2x); + CASE(mat3x); + CASE(mat4x); + CASE(dmat2x); + CASE(dmat3x); + CASE(dmat4x); + CASE(vec); + CASE(ivec); + CASE(bvec); + CASE(dvec); + CASE(uvec); + CASE(hvec); + CASE(fvec); + + #undef CASE + + #define CASE(NAME) \ + WORD(NAME ## 1D); \ + WORD(NAME ## 2D); \ + WORD(NAME ## 3D); \ + WORD(NAME ## Cube); \ + WORD(NAME ## 1DArray); \ + WORD(NAME ## 2DArray); \ + WORD(NAME ## 3DArray); \ + WORD(NAME ## CubeArray);\ + WORD(NAME ## 2DMS); \ + WORD(NAME ## 2DMSArray) \ + /* end */ + + #define CASE2(NAME) \ + CASE(NAME); \ + CASE(i ## NAME); \ + CASE(u ## NAME) \ + /* end */ + + CASE2(sampler); + CASE2(image); + CASE2(texture); + + #undef CASE2 + #undef CASE + break; + + default: + break; + } + } + + // // Values // @@ -975,6 +1143,43 @@ struct LoweringVisitor shared->mapLoweredDeclToOriginal.Add(loweredDecl, decl); } + // If the name of the declarations collides with a reserved word + // for the code generation target, then rename it to avoid the conflict + // + // Note that this does *not* implement any kind of comprehensive renaming + // to, e.g., avoid conflicts between user-defined and library functions. + void ensureDeclHasAValidName(Decl* decl) + { + // By default, we would like to emit a name in the generated + // code exactly as it appeared in the original program. + // When that isn't possible, we'd like to emit a name as + // close to the original as possible (to ensure that existing + // debugging tools still work reasonably well). + // + // One reason why a name might not be allowed as-is is that + // it could collide with a reserved word in the target language. + // Another reason is that it might not follow a naming convention + // imposed by the target (e.g., in GLSL names starting with + // `gl_` or containing `__` are reserved). + // + // Given a name that should not be allowed, we want to + // change it to a name that *is* allowed. e.g., by adding + // `_` to the end of a reserved word. + // + // The next problem this creates is that the modified name + // could not collide with an existing use of the same + // (valid) name. + // + // For now we are going to solve this problem in a simple + // and ad hoc fashion, but longer term we'll want to do + // something sytematic. + + if (isReservedWord(decl->getName())) + { + decl->Name.Content.append("_"); + } + } + void lowerDeclCommon( Decl* loweredDecl, Decl* decl) @@ -984,6 +1189,9 @@ struct LoweringVisitor loweredDecl->Position = decl->Position; loweredDecl->Name = decl->getNameToken(); + // Deal with renaming - we shouldn't allow decls with names that are reserved words + ensureDeclHasAValidName(loweredDecl); + // Lower modifiers as needed // HACK: just doing a shallow copy of modifiers, which will @@ -1325,6 +1533,8 @@ struct LoweringVisitor globalVarDecl->Name.Content = info.name; globalVarDecl->Type.type = type; + ensureDeclHasAValidName(globalVarDecl); + addMember(shared->loweredProgram, globalVarDecl); // Add the layout information @@ -1526,6 +1736,8 @@ struct LoweringVisitor localVarDecl->Name.Content = paramDecl->getName(); localVarDecl->Type = lowerType(paramDecl->Type); + ensureDeclHasAValidName(localVarDecl); + subVisitor.addDecl(localVarDecl); EntryPointParamPair paramPair; @@ -1560,6 +1772,8 @@ struct LoweringVisitor resultVarDecl->Name.Content = "_main_result"; resultVarDecl->Type = TypeExp(loweredEntryPointFunc->ReturnType); + ensureDeclHasAValidName(resultVarDecl); + subVisitor.addDecl(resultVarDecl); } @@ -1804,6 +2018,9 @@ LoweredEntryPoint lowerEntryPoint( visitor.shared = &sharedContext; visitor.parentDecl = loweredProgram; + // TODO: this should only need to take the shared context + visitor.registerReservedWords(); + // We need to register the lowered program as the lowered version // of the existing translation unit declaration. |
