[hlsl-writer] Add emission of identifiers

This CL adds identifier emission and an HLSL namer to guard against
names using reserved words.

Bug: tint:7
Change-Id: Id3d73ff683048c26ac99451d21c3dd7ef3c620a3
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/25001
Reviewed-by: David Neto <dneto@google.com>
diff --git a/BUILD.gn b/BUILD.gn
index e6c7e62..f6f1a9b 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -527,6 +527,8 @@
     "src/writer/hlsl/generator.h",
     "src/writer/hlsl/generator_impl.cc",
     "src/writer/hlsl/generator_impl.h",
+    "src/writer/hlsl/namer.cc",
+    "src/writer/hlsl/namer.h",
   ]
 
   configs += [ ":tint_common_config" ]
@@ -1014,7 +1016,11 @@
 }
 
 source_set("tint_unittests_hlsl_writer_src") {
-  sources = [ "src/writer/hlsl/generator_impl_test.cc" ]
+  sources = [
+    "src/writer/hlsl/generator_impl_identifier_test.cc",
+    "src/writer/hlsl/generator_impl_test.cc",
+    "src/writer/hlsl/namer_test.cc",
+  ]
 
   configs += [
     ":tint_common_config",
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 4c0c107..06b02eb 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -268,6 +268,8 @@
     writer/hlsl/generator.h
     writer/hlsl/generator_impl.cc
     writer/hlsl/generator_impl.h
+    writer/hlsl/namer.cc
+    writer/hlsl/namer.h
   )
 endif()
 
@@ -539,7 +541,9 @@
 
 if (${TINT_BUILD_HLSL_WRITER})
   list(APPEND TINT_TEST_SRCS
+    writer/hlsl/generator_impl_identifier_test.cc
     writer/hlsl/generator_impl_test.cc
+    writer/hlsl/namer_test.cc
   )
 endif()
 
diff --git a/src/writer/hlsl/generator.cc b/src/writer/hlsl/generator.cc
index b0f1566..03d68ac 100644
--- a/src/writer/hlsl/generator.cc
+++ b/src/writer/hlsl/generator.cc
@@ -20,12 +20,13 @@
 namespace writer {
 namespace hlsl {
 
-Generator::Generator(ast::Module module) : Text(std::move(module)) {}
+Generator::Generator(ast::Module module)
+    : Text(std::move(module)), impl_(&module_) {}
 
 Generator::~Generator() = default;
 
 bool Generator::Generate() {
-  auto ret = impl_.Generate(module_);
+  auto ret = impl_.Generate();
   if (!ret) {
     error_ = impl_.error();
   }
diff --git a/src/writer/hlsl/generator_impl.cc b/src/writer/hlsl/generator_impl.cc
index 7bcabcd..ad891da 100644
--- a/src/writer/hlsl/generator_impl.cc
+++ b/src/writer/hlsl/generator_impl.cc
@@ -14,15 +14,81 @@
 
 #include "src/writer/hlsl/generator_impl.h"
 
+#include "src/ast/identifier_expression.h"
+
 namespace tint {
 namespace writer {
 namespace hlsl {
 
-GeneratorImpl::GeneratorImpl() = default;
+GeneratorImpl::GeneratorImpl(ast::Module* module) : module_(module) {}
 
 GeneratorImpl::~GeneratorImpl() = default;
 
-bool GeneratorImpl::Generate(const ast::Module&) {
+bool GeneratorImpl::Generate() {
+  for (const auto& global : module_->global_variables()) {
+    global_variables_.set(global->name(), global.get());
+  }
+  return true;
+}
+
+std::string GeneratorImpl::current_ep_var_name(VarType type) {
+  std::string name = "";
+  switch (type) {
+    case VarType::kIn: {
+      auto in_it = ep_name_to_in_data_.find(current_ep_name_);
+      if (in_it != ep_name_to_in_data_.end()) {
+        name = in_it->second.var_name;
+      }
+      break;
+    }
+    case VarType::kOut: {
+      auto out_it = ep_name_to_out_data_.find(current_ep_name_);
+      if (out_it != ep_name_to_out_data_.end()) {
+        name = out_it->second.var_name;
+      }
+      break;
+    }
+  }
+  return name;
+}
+
+bool GeneratorImpl::EmitExpression(ast::Expression* expr) {
+  if (expr->IsIdentifier()) {
+    return EmitIdentifier(expr->AsIdentifier());
+  }
+
+  error_ = "unknown expression type: " + expr->str();
+  return false;
+}
+
+bool GeneratorImpl::global_is_in_struct(ast::Variable*) const {
+  return false;
+}
+
+bool GeneratorImpl::EmitIdentifier(ast::IdentifierExpression* expr) {
+  auto* ident = expr->AsIdentifier();
+  if (ident->has_path()) {
+    // TODO(dsinclair): Handle identifier with path
+    error_ = "Identifier paths not handled yet.";
+    return false;
+  }
+
+  ast::Variable* var = nullptr;
+  if (global_variables_.get(ident->name(), &var)) {
+    if (global_is_in_struct(var)) {
+      auto var_type = var->storage_class() == ast::StorageClass::kInput
+                          ? VarType::kIn
+                          : VarType::kOut;
+      auto name = current_ep_var_name(var_type);
+      if (name.empty()) {
+        error_ = "unable to find entry point data for variable";
+        return false;
+      }
+      out_ << name << ".";
+    }
+  }
+  out_ << namer_.NameFor(ident->name());
+
   return true;
 }
 
diff --git a/src/writer/hlsl/generator_impl.h b/src/writer/hlsl/generator_impl.h
index 2c78a01..e9e3028 100644
--- a/src/writer/hlsl/generator_impl.h
+++ b/src/writer/hlsl/generator_impl.h
@@ -16,6 +16,8 @@
 #define SRC_WRITER_HLSL_GENERATOR_IMPL_H_
 
 #include "src/ast/module.h"
+#include "src/scope_stack.h"
+#include "src/writer/hlsl/namer.h"
 #include "src/writer/text_generator.h"
 
 namespace tint {
@@ -26,13 +28,43 @@
 class GeneratorImpl : public TextGenerator {
  public:
   /// Constructor
-  GeneratorImpl();
+  /// @param module the module to generate
+  explicit GeneratorImpl(ast::Module* module);
   ~GeneratorImpl();
 
-  /// Generates the result data
-  /// @param module the module to generate
   /// @returns true on successful generation; false otherwise
-  bool Generate(const ast::Module& module);
+  bool Generate();
+
+  /// Handles generate an Expression
+  /// @param expr the expression
+  /// @returns true if the expression was emitted
+  bool EmitExpression(ast::Expression* expr);
+  /// Handles generating an identifier expression
+  /// @param expr the identifier expression
+  /// @returns true if the identifeir was emitted
+  bool EmitIdentifier(ast::IdentifierExpression* expr);
+
+  /// Checks if the global variable is in an input or output struct
+  /// @param var the variable to check
+  /// @returns true if the global is in an input or output struct
+  bool global_is_in_struct(ast::Variable* var) const;
+
+ private:
+  enum class VarType { kIn, kOut };
+
+  struct EntryPointData {
+    std::string struct_name;
+    std::string var_name;
+  };
+
+  std::string current_ep_var_name(VarType type);
+
+  Namer namer_;
+  ast::Module* module_ = nullptr;
+  std::string current_ep_name_;
+  ScopeStack<ast::Variable*> global_variables_;
+  std::unordered_map<std::string, EntryPointData> ep_name_to_in_data_;
+  std::unordered_map<std::string, EntryPointData> ep_name_to_out_data_;
 };
 
 }  // namespace hlsl
diff --git a/src/writer/hlsl/generator_impl_identifier_test.cc b/src/writer/hlsl/generator_impl_identifier_test.cc
new file mode 100644
index 0000000..7f45efd
--- /dev/null
+++ b/src/writer/hlsl/generator_impl_identifier_test.cc
@@ -0,0 +1,67 @@
+// Copyright 2020 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "gtest/gtest.h"
+#include "src/ast/identifier_expression.h"
+#include "src/ast/module.h"
+#include "src/writer/hlsl/generator_impl.h"
+
+namespace tint {
+namespace writer {
+namespace hlsl {
+namespace {
+
+using HlslGeneratorImplTest = testing::Test;
+
+TEST_F(HlslGeneratorImplTest, DISABLED_EmitExpression_Identifier) {
+  ast::IdentifierExpression i(std::vector<std::string>{"std", "glsl"});
+
+  ast::Module m;
+  GeneratorImpl g(&m);
+  ASSERT_TRUE(g.EmitExpression(&i)) << g.error();
+  EXPECT_EQ(g.result(), "std::glsl");
+}
+
+TEST_F(HlslGeneratorImplTest, EmitIdentifierExpression_Single) {
+  ast::IdentifierExpression i("foo");
+
+  ast::Module m;
+  GeneratorImpl g(&m);
+  ASSERT_TRUE(g.EmitExpression(&i)) << g.error();
+  EXPECT_EQ(g.result(), "foo");
+}
+
+TEST_F(HlslGeneratorImplTest, EmitIdentifierExpression_Single_WithCollision) {
+  ast::IdentifierExpression i("virtual");
+
+  ast::Module m;
+  GeneratorImpl g(&m);
+  ASSERT_TRUE(g.EmitExpression(&i)) << g.error();
+  EXPECT_EQ(g.result(), "virtual_tint_0");
+}
+
+// TODO(dsinclair): Handle import names
+TEST_F(HlslGeneratorImplTest, DISABLED_EmitIdentifierExpression_MultipleNames) {
+  ast::IdentifierExpression i({"std", "glsl", "init"});
+
+  ast::Module m;
+  GeneratorImpl g(&m);
+  ASSERT_TRUE(g.EmitExpression(&i)) << g.error();
+  EXPECT_EQ(g.result(), "std::glsl::init");
+}
+
+}  // namespace
+}  // namespace hlsl
+}  // namespace writer
+}  // namespace tint
diff --git a/src/writer/hlsl/generator_impl_test.cc b/src/writer/hlsl/generator_impl_test.cc
index 0b68755..df128ad 100644
--- a/src/writer/hlsl/generator_impl_test.cc
+++ b/src/writer/hlsl/generator_impl_test.cc
@@ -37,9 +37,8 @@
   m.AddEntryPoint(std::make_unique<ast::EntryPoint>(
       ast::PipelineStage::kFragment, "my_func", ""));
 
-  GeneratorImpl g;
-
-  ASSERT_TRUE(g.Generate(m)) << g.error();
+  GeneratorImpl g(&m);
+  ASSERT_TRUE(g.Generate()) << g.error();
   EXPECT_EQ(g.result(), R"(#import <metal_lib>
 
 void my_func() {
diff --git a/src/writer/hlsl/namer.cc b/src/writer/hlsl/namer.cc
new file mode 100644
index 0000000..8c04e91
--- /dev/null
+++ b/src/writer/hlsl/namer.cc
@@ -0,0 +1,692 @@
+// Copyright 2020 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "src/writer/hlsl/namer.h"
+
+#include <algorithm>
+
+namespace tint {
+namespace writer {
+namespace hlsl {
+namespace {
+
+// This list is used for a binary search and must be kept in sorted order.
+const char* kNames[] = {"AddressU",
+                        "AddressV",
+                        "AddressW",
+                        "AllMemoryBarrier",
+                        "AllMemoryBarrierWithGroupSync",
+                        "AppendStructuredBuffer",
+                        "BINORMAL",
+                        "BLENDINDICES",
+                        "BLENDWEIGHT",
+                        "BlendState",
+                        "BorderColor",
+                        "Buffer",
+                        "ByteAddressBuffer",
+                        "COLOR",
+                        "CheckAccessFullyMapped",
+                        "ComparisonFunc",
+                        "CompileShader",
+                        "ComputeShader",
+                        "ConsumeStructuredBuffer",
+                        "D3DCOLORtoUBYTE4",
+                        "DEPTH",
+                        "DepthStencilState",
+                        "DepthStencilView",
+                        "DeviceMemoryBarrier",
+                        "DeviceMemroyBarrierWithGroupSync",
+                        "DomainShader",
+                        "EvaluateAttributeAtCentroid",
+                        "EvaluateAttributeAtSample",
+                        "EvaluateAttributeSnapped",
+                        "FOG",
+                        "Filter",
+                        "GeometryShader",
+                        "GetRenderTargetSampleCount",
+                        "GetRenderTargetSamplePosition",
+                        "GroupMemoryBarrier",
+                        "GroupMemroyBarrierWithGroupSync",
+                        "Hullshader",
+                        "InputPatch",
+                        "InterlockedAdd",
+                        "InterlockedAnd",
+                        "InterlockedCompareExchange",
+                        "InterlockedCompareStore",
+                        "InterlockedExchange",
+                        "InterlockedMax",
+                        "InterlockedMin",
+                        "InterlockedOr",
+                        "InterlockedXor",
+                        "LineStream",
+                        "MaxAnisotropy",
+                        "MaxLOD",
+                        "MinLOD",
+                        "MipLODBias",
+                        "NORMAL",
+                        "NULL",
+                        "Normal",
+                        "OutputPatch",
+                        "POSITION",
+                        "POSITIONT",
+                        "PSIZE",
+                        "PixelShader",
+                        "PointStream",
+                        "Process2DQuadTessFactorsAvg",
+                        "Process2DQuadTessFactorsMax",
+                        "Process2DQuadTessFactorsMin",
+                        "ProcessIsolineTessFactors",
+                        "ProcessQuadTessFactorsAvg",
+                        "ProcessQuadTessFactorsMax",
+                        "ProcessQuadTessFactorsMin",
+                        "ProcessTriTessFactorsAvg",
+                        "ProcessTriTessFactorsMax",
+                        "ProcessTriTessFactorsMin",
+                        "RWBuffer",
+                        "RWByteAddressBuffer",
+                        "RWStructuredBuffer",
+                        "RWTexture1D",
+                        "RWTexture1DArray",
+                        "RWTexture2D",
+                        "RWTexture2DArray",
+                        "RWTexture3D",
+                        "RasterizerState",
+                        "RenderTargetView",
+                        "SV_ClipDistance",
+                        "SV_Coverage",
+                        "SV_CullDistance",
+                        "SV_Depth",
+                        "SV_DepthGreaterEqual",
+                        "SV_DepthLessEqual",
+                        "SV_DispatchThreadID",
+                        "SV_DomainLocation",
+                        "SV_GSInstanceID",
+                        "SV_GroupID",
+                        "SV_GroupIndex",
+                        "SV_GroupThreadID",
+                        "SV_InnerCoverage",
+                        "SV_InsideTessFactor",
+                        "SV_InstanceID",
+                        "SV_IsFrontFace",
+                        "SV_OutputControlPointID",
+                        "SV_Position",
+                        "SV_PrimitiveID",
+                        "SV_RenderTargetArrayIndex",
+                        "SV_SampleIndex",
+                        "SV_StencilRef",
+                        "SV_Target",
+                        "SV_TessFactor",
+                        "SV_VertexArrayIndex",
+                        "SV_VertexID",
+                        "Sampler",
+                        "Sampler1D",
+                        "Sampler2D",
+                        "Sampler3D",
+                        "SamplerCUBE",
+                        "StructuredBuffer",
+                        "TANGENT",
+                        "TESSFACTOR",
+                        "TEXCOORD",
+                        "Texcoord",
+                        "Texture",
+                        "Texture1D",
+                        "Texture1DArray",
+                        "Texture2D",
+                        "Texture2DArray",
+                        "Texture2DMS",
+                        "Texture2DMSArray",
+                        "Texture3D",
+                        "TextureCube",
+                        "TextureCubeArray",
+                        "TriangleStream",
+                        "VFACE",
+                        "VPOS",
+                        "VertexShader",
+                        "abort",
+                        "abs",
+                        "acos",
+                        "all",
+                        "allow_uav_condition",
+                        "any",
+                        "asdouble",
+                        "asfloat",
+                        "asin",
+                        "asint",
+                        "asm",
+                        "asm_fragment",
+                        "asuint",
+                        "atan",
+                        "atan2",
+                        "auto",
+                        "bool",
+                        "bool1",
+                        "bool1x1",
+                        "bool1x2",
+                        "bool1x3",
+                        "bool1x4",
+                        "bool2",
+                        "bool2x1",
+                        "bool2x2",
+                        "bool2x3",
+                        "bool2x4",
+                        "bool3",
+                        "bool3x1",
+                        "bool3x2",
+                        "bool3x3",
+                        "bool3x4",
+                        "bool4",
+                        "bool4x1",
+                        "bool4x2",
+                        "bool4x3",
+                        "bool4x4",
+                        "branch",
+                        "break",
+                        "call",
+                        "case",
+                        "catch",
+                        "cbuffer",
+                        "ceil",
+                        "centroid",
+                        "char",
+                        "clamp",
+                        "class",
+                        "clip",
+                        "column_major",
+                        "compile_fragment",
+                        "const",
+                        "const_cast",
+                        "continue",
+                        "cos",
+                        "cosh",
+                        "countbits",
+                        "cross",
+                        "ddx",
+                        "ddx_coarse",
+                        "ddx_fine",
+                        "ddy",
+                        "ddy_coarse",
+                        "ddy_fine",
+                        "degrees",
+                        "delete",
+                        "determinant",
+                        "discard",
+                        "distance",
+                        "do",
+                        "dot",
+                        "double",
+                        "double1",
+                        "double1x1",
+                        "double1x2",
+                        "double1x3",
+                        "double1x4",
+                        "double2",
+                        "double2x1",
+                        "double2x2",
+                        "double2x3",
+                        "double2x4",
+                        "double3",
+                        "double3x1",
+                        "double3x2",
+                        "double3x3",
+                        "double3x4",
+                        "double4",
+                        "double4x1",
+                        "double4x2",
+                        "double4x3",
+                        "double4x4",
+                        "dst",
+                        "dword",
+                        "dword1",
+                        "dword1x1",
+                        "dword1x2",
+                        "dword1x3",
+                        "dword1x4",
+                        "dword2",
+                        "dword2x1",
+                        "dword2x2",
+                        "dword2x3",
+                        "dword2x4",
+                        "dword3",
+                        "dword3x1",
+                        "dword3x2",
+                        "dword3x3",
+                        "dword3x4",
+                        "dword4",
+                        "dword4x1",
+                        "dword4x2",
+                        "dword4x3",
+                        "dword4x4",
+                        "dynamic_cast",
+                        "else",
+                        "enum",
+                        "errorf",
+                        "exp",
+                        "exp2",
+                        "explicit",
+                        "export",
+                        "extern",
+                        "f16to32",
+                        "f32tof16",
+                        "faceforward",
+                        "false",
+                        "fastopt",
+                        "firstbithigh",
+                        "firstbitlow",
+                        "flatten",
+                        "float",
+                        "float1",
+                        "float1x1",
+                        "float1x2",
+                        "float1x3",
+                        "float1x4",
+                        "float2",
+                        "float2x1",
+                        "float2x2",
+                        "float2x3",
+                        "float2x4",
+                        "float3",
+                        "float3x1",
+                        "float3x2",
+                        "float3x3",
+                        "float3x4",
+                        "float4",
+                        "float4x1",
+                        "float4x2",
+                        "float4x3",
+                        "float4x4",
+                        "floor",
+                        "fma",
+                        "fmod",
+                        "for",
+                        "forcecase",
+                        "frac",
+                        "frexp",
+                        "friend",
+                        "fwidth",
+                        "fxgroup",
+                        "goto",
+                        "groupshared",
+                        "half",
+                        "half1",
+                        "half1x1",
+                        "half1x2",
+                        "half1x3",
+                        "half1x4",
+                        "half2",
+                        "half2x1",
+                        "half2x2",
+                        "half2x3",
+                        "half2x4",
+                        "half3",
+                        "half3x1",
+                        "half3x2",
+                        "half3x3",
+                        "half3x4",
+                        "half4",
+                        "half4x1",
+                        "half4x2",
+                        "half4x3",
+                        "half4x4",
+                        "if",
+                        "in",
+                        "inline",
+                        "inout",
+                        "int",
+                        "int1",
+                        "int1x1",
+                        "int1x2",
+                        "int1x3",
+                        "int1x4",
+                        "int2",
+                        "int2x1",
+                        "int2x2",
+                        "int2x3",
+                        "int2x4",
+                        "int3",
+                        "int3x1",
+                        "int3x2",
+                        "int3x3",
+                        "int3x4",
+                        "int4",
+                        "int4x1",
+                        "int4x2",
+                        "int4x3",
+                        "int4x4",
+                        "interface",
+                        "isfinite",
+                        "isinf",
+                        "isnan",
+                        "ldexp",
+                        "length",
+                        "lerp",
+                        "lineadj",
+                        "linear",
+                        "lit",
+                        "log",
+                        "log10",
+                        "log2",
+                        "long",
+                        "loop",
+                        "mad",
+                        "matrix",
+                        "max",
+                        "min",
+                        "min10float",
+                        "min10float1",
+                        "min10float1x1",
+                        "min10float1x2",
+                        "min10float1x3",
+                        "min10float1x4",
+                        "min10float2",
+                        "min10float2x1",
+                        "min10float2x2",
+                        "min10float2x3",
+                        "min10float2x4",
+                        "min10float3",
+                        "min10float3x1",
+                        "min10float3x2",
+                        "min10float3x3",
+                        "min10float3x4",
+                        "min10float4",
+                        "min10float4x1",
+                        "min10float4x2",
+                        "min10float4x3",
+                        "min10float4x4",
+                        "min12int",
+                        "min12int1",
+                        "min12int1x1",
+                        "min12int1x2",
+                        "min12int1x3",
+                        "min12int1x4",
+                        "min12int2",
+                        "min12int2x1",
+                        "min12int2x2",
+                        "min12int2x3",
+                        "min12int2x4",
+                        "min12int3",
+                        "min12int3x1",
+                        "min12int3x2",
+                        "min12int3x3",
+                        "min12int3x4",
+                        "min12int4",
+                        "min12int4x1",
+                        "min12int4x2",
+                        "min12int4x3",
+                        "min12int4x4",
+                        "min16float",
+                        "min16float1",
+                        "min16float1x1",
+                        "min16float1x2",
+                        "min16float1x3",
+                        "min16float1x4",
+                        "min16float2",
+                        "min16float2x1",
+                        "min16float2x2",
+                        "min16float2x3",
+                        "min16float2x4",
+                        "min16float3",
+                        "min16float3x1",
+                        "min16float3x2",
+                        "min16float3x3",
+                        "min16float3x4",
+                        "min16float4",
+                        "min16float4x1",
+                        "min16float4x2",
+                        "min16float4x3",
+                        "min16float4x4",
+                        "min16int",
+                        "min16int1",
+                        "min16int1x1",
+                        "min16int1x2",
+                        "min16int1x3",
+                        "min16int1x4",
+                        "min16int2",
+                        "min16int2x1",
+                        "min16int2x2",
+                        "min16int2x3",
+                        "min16int2x4",
+                        "min16int3",
+                        "min16int3x1",
+                        "min16int3x2",
+                        "min16int3x3",
+                        "min16int3x4",
+                        "min16int4",
+                        "min16int4x1",
+                        "min16int4x2",
+                        "min16int4x3",
+                        "min16int4x4",
+                        "min16uint",
+                        "min16uint1",
+                        "min16uint1x1",
+                        "min16uint1x2",
+                        "min16uint1x3",
+                        "min16uint1x4",
+                        "min16uint2",
+                        "min16uint2x1",
+                        "min16uint2x2",
+                        "min16uint2x3",
+                        "min16uint2x4",
+                        "min16uint3",
+                        "min16uint3x1",
+                        "min16uint3x2",
+                        "min16uint3x3",
+                        "min16uint3x4",
+                        "min16uint4",
+                        "min16uint4x1",
+                        "min16uint4x2",
+                        "min16uint4x3",
+                        "min16uint4x4",
+                        "modf",
+                        "msad4",
+                        "mul",
+                        "mutable",
+                        "namespace",
+                        "new",
+                        "nointerpolation",
+                        "noise",
+                        "noperspective",
+                        "normalize",
+                        "numthreads",
+                        "operator",
+                        "out",
+                        "packoffset",
+                        "pass",
+                        "pixelfragment",
+                        "pixelshader",
+                        "point",
+                        "pow",
+                        "precise",
+                        "printf",
+                        "private",
+                        "protected",
+                        "public",
+                        "radians",
+                        "rcp",
+                        "reflect",
+                        "refract",
+                        "register",
+                        "reinterpret_cast",
+                        "return",
+                        "reversebits",
+                        "round",
+                        "row_major",
+                        "rsqrt",
+                        "sample",
+                        "sampler",
+                        "sampler1D",
+                        "sampler2D",
+                        "sampler3D",
+                        "samplerCUBE",
+                        "sampler_state",
+                        "saturate",
+                        "shared",
+                        "short",
+                        "sign",
+                        "signed",
+                        "sin",
+                        "sincos",
+                        "sinh",
+                        "sizeof",
+                        "smoothstep",
+                        "snorm",
+                        "sqrt",
+                        "stateblock",
+                        "stateblock_state",
+                        "static",
+                        "static_cast",
+                        "step",
+                        "string",
+                        "struct",
+                        "switch",
+                        "tan",
+                        "tanh",
+                        "tbuffer",
+                        "technique",
+                        "technique10",
+                        "technique11",
+                        "template",
+                        "tex1D",
+                        "tex1Dbias",
+                        "tex1Dgrad",
+                        "tex1Dlod",
+                        "tex1Dproj",
+                        "tex2D",
+                        "tex2Dbias",
+                        "tex2Dgrad",
+                        "tex2Dlod",
+                        "tex2Dproj",
+                        "tex3D",
+                        "tex3Dbias",
+                        "tex3Dgrad",
+                        "tex3Dlod",
+                        "tex3Dproj",
+                        "texCUBE",
+                        "texCUBEbias",
+                        "texCUBEgrad",
+                        "texCUBElod",
+                        "texCUBEproj",
+                        "texture",
+                        "texture1D",
+                        "texture1DArray",
+                        "texture2D",
+                        "texture2DArray",
+                        "texture2DMS",
+                        "texture2DMSArray",
+                        "texture3D",
+                        "textureCube",
+                        "textureCubeArray",
+                        "this",
+                        "throw",
+                        "transpose",
+                        "triangle",
+                        "triangleadj",
+                        "true",
+                        "trunc",
+                        "try",
+                        "typedef",
+                        "typename",
+                        "uint",
+                        "uint1",
+                        "uint1x1",
+                        "uint1x2",
+                        "uint1x3",
+                        "uint1x4",
+                        "uint2",
+                        "uint2x1",
+                        "uint2x2",
+                        "uint2x3",
+                        "uint2x4",
+                        "uint3",
+                        "uint3x1",
+                        "uint3x2",
+                        "uint3x3",
+                        "uint3x4",
+                        "uint4",
+                        "uint4x1",
+                        "uint4x2",
+                        "uint4x3",
+                        "uint4x4",
+                        "uniform",
+                        "union",
+                        "unorm",
+                        "unroll",
+                        "unsigned",
+                        "using",
+                        "vector",
+                        "vertexfragment",
+                        "vertexshader",
+                        "virtual",
+                        "void",
+                        "volatile",
+                        "while"};
+
+}  // namespace
+
+Namer::Namer() = default;
+
+Namer::~Namer() = default;
+
+std::string Namer::NameFor(const std::string& name) {
+  // If it's in the name map we can just return it. There are no shadow names
+  // in WGSL so this has to be unique in the WGSL names, and we've already
+  // checked the name collisions with HLSL.
+  auto it = name_map_.find(name);
+  if (it != name_map_.end()) {
+    return it->second;
+  }
+
+  std::string ret_name = name;
+  if (std::binary_search(std::begin(kNames), std::end(kNames), ret_name)) {
+    uint32_t i = 0;
+    // Make sure there wasn't already a tint variable with the new name we've
+    // now created.
+    while (true) {
+      ret_name = name + "_tint_" + std::to_string(i);
+      it = name_map_.find(ret_name);
+      if (it == name_map_.end()) {
+        break;
+      }
+      i++;
+    }
+    RegisterRemappedName(ret_name);
+  } else {
+    uint32_t i = 0;
+    // Make sure the ident name wasn't assigned by a remapping.
+    while (true) {
+      auto remap_it = remapped_names_.find(ret_name);
+      if (remap_it == remapped_names_.end()) {
+        break;
+      }
+      ret_name = name + "_" + std::to_string(i);
+      i++;
+    }
+    RegisterRemappedName(ret_name);
+  }
+
+  name_map_[name] = ret_name;
+  return ret_name;
+}
+
+bool Namer::IsMapped(const std::string& name) {
+  auto it = name_map_.find(name);
+  return it != name_map_.end();
+}
+
+void Namer::RegisterRemappedName(const std::string& name) {
+  remapped_names_.insert(name);
+}
+
+}  // namespace hlsl
+}  // namespace writer
+}  // namespace tint
diff --git a/src/writer/hlsl/namer.h b/src/writer/hlsl/namer.h
new file mode 100644
index 0000000..be3b521
--- /dev/null
+++ b/src/writer/hlsl/namer.h
@@ -0,0 +1,58 @@
+// Copyright 2020 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef SRC_WRITER_HLSL_NAMER_H_
+#define SRC_WRITER_HLSL_NAMER_H_
+
+#include <string>
+#include <unordered_map>
+#include <unordered_set>
+
+namespace tint {
+namespace writer {
+namespace hlsl {
+
+/// Remaps maps names to avoid reserved words and collisions for HLSL.
+class Namer {
+ public:
+  /// Constructor
+  Namer();
+  ~Namer();
+
+  /// Returns a sanitized version of |name|
+  /// @param name the name to sanitize
+  /// @returns the sanitized version of |name|
+  std::string NameFor(const std::string& name);
+
+  /// Registers a remapped name.
+  /// @param name the name to register
+  void RegisterRemappedName(const std::string& name);
+
+  /// Returns if the given name has been mapped alread
+  /// @param name the name to check
+  /// @returns true if the name has been mapped
+  bool IsMapped(const std::string& name);
+
+ private:
+  /// Map of original name to new name. The two names may be the same.
+  std::unordered_map<std::string, std::string> name_map_;
+  // The list of names taken by the remapper
+  std::unordered_set<std::string> remapped_names_;
+};
+
+}  // namespace hlsl
+}  // namespace writer
+}  // namespace tint
+
+#endif  // SRC_WRITER_HLSL_NAMER_H_
diff --git a/src/writer/hlsl/namer_test.cc b/src/writer/hlsl/namer_test.cc
new file mode 100644
index 0000000..cd5a1ce
--- /dev/null
+++ b/src/writer/hlsl/namer_test.cc
@@ -0,0 +1,666 @@
+// Copyright 2020 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "src/writer/hlsl/namer.h"
+#include "gtest/gtest.h"
+
+namespace tint {
+namespace writer {
+namespace hlsl {
+namespace {
+
+using HlslNamerTest = testing::Test;
+
+TEST_F(HlslNamerTest, ReturnsName) {
+  Namer n;
+  EXPECT_EQ("my_name", n.NameFor("my_name"));
+  EXPECT_EQ("my_name", n.NameFor("my_name"));
+}
+
+TEST_F(HlslNamerTest, HandlesConflictWithRenamedReservedWordAfterIdentSeen) {
+  Namer n;
+  EXPECT_EQ("float_tint_0", n.NameFor("float_tint_0"));
+  EXPECT_EQ("float_tint_1", n.NameFor("float"));
+  EXPECT_EQ("float_tint_0", n.NameFor("float_tint_0"));
+}
+
+TEST_F(HlslNamerTest, HandlesConflictWithRenamedReservedWordBeforeIdentSeen) {
+  Namer n;
+  EXPECT_EQ("float_tint_0", n.NameFor("float"));
+  EXPECT_EQ("float_tint_0_0", n.NameFor("float_tint_0"));
+  EXPECT_EQ("float_tint_0_0_0", n.NameFor("float_tint_0_0"));
+  EXPECT_EQ("float_tint_0_0", n.NameFor("float_tint_0"));
+}
+
+using HlslReservedNameTest = testing::TestWithParam<std::string>;
+TEST_P(HlslReservedNameTest, Emit) {
+  auto name = GetParam();
+
+  Namer n;
+  EXPECT_EQ(name + "_tint_0", n.NameFor(name));
+}
+INSTANTIATE_TEST_SUITE_P(HlslNamerTest,
+                         HlslReservedNameTest,
+                         testing::Values("AddressU",
+                                         "AddressV",
+                                         "AddressW",
+                                         "AllMemoryBarrier",
+                                         "AllMemoryBarrierWithGroupSync",
+                                         "AppendStructuredBuffer",
+                                         "BINORMAL",
+                                         "BLENDINDICES",
+                                         "BLENDWEIGHT",
+                                         "BlendState",
+                                         "BorderColor",
+                                         "Buffer",
+                                         "ByteAddressBuffer",
+                                         "COLOR",
+                                         "CheckAccessFullyMapped",
+                                         "ComparisonFunc",
+                                         "CompileShader",
+                                         "ComputeShader",
+                                         "ConsumeStructuredBuffer",
+                                         "D3DCOLORtoUBYTE4",
+                                         "DEPTH",
+                                         "DepthStencilState",
+                                         "DepthStencilView",
+                                         "DeviceMemoryBarrier",
+                                         "DeviceMemroyBarrierWithGroupSync",
+                                         "DomainShader",
+                                         "EvaluateAttributeAtCentroid",
+                                         "EvaluateAttributeAtSample",
+                                         "EvaluateAttributeSnapped",
+                                         "FOG",
+                                         "Filter",
+                                         "GeometryShader",
+                                         "GetRenderTargetSampleCount",
+                                         "GetRenderTargetSamplePosition",
+                                         "GroupMemoryBarrier",
+                                         "GroupMemroyBarrierWithGroupSync",
+                                         "Hullshader",
+                                         "InputPatch",
+                                         "InterlockedAdd",
+                                         "InterlockedAnd",
+                                         "InterlockedCompareExchange",
+                                         "InterlockedCompareStore",
+                                         "InterlockedExchange",
+                                         "InterlockedMax",
+                                         "InterlockedMin",
+                                         "InterlockedOr",
+                                         "InterlockedXor",
+                                         "LineStream",
+                                         "MaxAnisotropy",
+                                         "MaxLOD",
+                                         "MinLOD",
+                                         "MipLODBias",
+                                         "NORMAL",
+                                         "NULL",
+                                         "Normal",
+                                         "OutputPatch",
+                                         "POSITION",
+                                         "POSITIONT",
+                                         "PSIZE",
+                                         "PixelShader",
+                                         "PointStream",
+                                         "Process2DQuadTessFactorsAvg",
+                                         "Process2DQuadTessFactorsMax",
+                                         "Process2DQuadTessFactorsMin",
+                                         "ProcessIsolineTessFactors",
+                                         "ProcessQuadTessFactorsAvg",
+                                         "ProcessQuadTessFactorsMax",
+                                         "ProcessQuadTessFactorsMin",
+                                         "ProcessTriTessFactorsAvg",
+                                         "ProcessTriTessFactorsMax",
+                                         "ProcessTriTessFactorsMin",
+                                         "RWBuffer",
+                                         "RWByteAddressBuffer",
+                                         "RWStructuredBuffer",
+                                         "RWTexture1D",
+                                         "RWTexture1DArray",
+                                         "RWTexture2D",
+                                         "RWTexture2DArray",
+                                         "RWTexture3D",
+                                         "RasterizerState",
+                                         "RenderTargetView",
+                                         "SV_ClipDistance",
+                                         "SV_Coverage",
+                                         "SV_CullDistance",
+                                         "SV_Depth",
+                                         "SV_DepthGreaterEqual",
+                                         "SV_DepthLessEqual",
+                                         "SV_DispatchThreadID",
+                                         "SV_DomainLocation",
+                                         "SV_GSInstanceID",
+                                         "SV_GroupID",
+                                         "SV_GroupIndex",
+                                         "SV_GroupThreadID",
+                                         "SV_InnerCoverage",
+                                         "SV_InsideTessFactor",
+                                         "SV_InstanceID",
+                                         "SV_IsFrontFace",
+                                         "SV_OutputControlPointID",
+                                         "SV_Position",
+                                         "SV_PrimitiveID",
+                                         "SV_RenderTargetArrayIndex",
+                                         "SV_SampleIndex",
+                                         "SV_StencilRef",
+                                         "SV_Target",
+                                         "SV_TessFactor",
+                                         "SV_VertexArrayIndex",
+                                         "SV_VertexID",
+                                         "Sampler",
+                                         "Sampler1D",
+                                         "Sampler2D",
+                                         "Sampler3D",
+                                         "SamplerCUBE",
+                                         "StructuredBuffer",
+                                         "TANGENT",
+                                         "TESSFACTOR",
+                                         "TEXCOORD",
+                                         "Texcoord",
+                                         "Texture",
+                                         "Texture1D",
+                                         "Texture1DArray",
+                                         "Texture2D",
+                                         "Texture2DArray",
+                                         "Texture2DMS",
+                                         "Texture2DMSArray",
+                                         "Texture3D",
+                                         "TextureCube",
+                                         "TextureCubeArray",
+                                         "TriangleStream",
+                                         "VFACE",
+                                         "VPOS",
+                                         "VertexShader",
+                                         "abort",
+                                         "abs",
+                                         "acos",
+                                         "all",
+                                         "allow_uav_condition",
+                                         "any",
+                                         "asdouble",
+                                         "asfloat",
+                                         "asin",
+                                         "asint",
+                                         "asm",
+                                         "asm_fragment",
+                                         "asuint",
+                                         "atan",
+                                         "atan2",
+                                         "auto",
+                                         "bool",
+                                         "bool1",
+                                         "bool1x1",
+                                         "bool1x2",
+                                         "bool1x3",
+                                         "bool1x4",
+                                         "bool2",
+                                         "bool2x1",
+                                         "bool2x2",
+                                         "bool2x3",
+                                         "bool2x4",
+                                         "bool3",
+                                         "bool3x1",
+                                         "bool3x2",
+                                         "bool3x3",
+                                         "bool3x4",
+                                         "bool4",
+                                         "bool4x1",
+                                         "bool4x2",
+                                         "bool4x3",
+                                         "bool4x4",
+                                         "branch",
+                                         "break",
+                                         "call",
+                                         "case",
+                                         "catch",
+                                         "cbuffer",
+                                         "ceil",
+                                         "centroid",
+                                         "char",
+                                         "clamp",
+                                         "class",
+                                         "clip",
+                                         "column_major",
+                                         "compile_fragment",
+                                         "const",
+                                         "const_cast",
+                                         "continue",
+                                         "cos",
+                                         "cosh",
+                                         "countbits",
+                                         "cross",
+                                         "ddx",
+                                         "ddx_coarse",
+                                         "ddx_fine",
+                                         "ddy",
+                                         "ddy_coarse",
+                                         "ddy_fine",
+                                         "degrees",
+                                         "delete",
+                                         "determinant",
+                                         "discard",
+                                         "distance",
+                                         "do",
+                                         "dot",
+                                         "double",
+                                         "double1",
+                                         "double1x1",
+                                         "double1x2",
+                                         "double1x3",
+                                         "double1x4",
+                                         "double2",
+                                         "double2x1",
+                                         "double2x2",
+                                         "double2x3",
+                                         "double2x4",
+                                         "double3",
+                                         "double3x1",
+                                         "double3x2",
+                                         "double3x3",
+                                         "double3x4",
+                                         "double4",
+                                         "double4x1",
+                                         "double4x2",
+                                         "double4x3",
+                                         "double4x4",
+                                         "dst",
+                                         "dword",
+                                         "dword1",
+                                         "dword1x1",
+                                         "dword1x2",
+                                         "dword1x3",
+                                         "dword1x4",
+                                         "dword2",
+                                         "dword2x1",
+                                         "dword2x2",
+                                         "dword2x3",
+                                         "dword2x4",
+                                         "dword3",
+                                         "dword3x1",
+                                         "dword3x2",
+                                         "dword3x3",
+                                         "dword3x4",
+                                         "dword4",
+                                         "dword4x1",
+                                         "dword4x2",
+                                         "dword4x3",
+                                         "dword4x4",
+                                         "dynamic_cast",
+                                         "else",
+                                         "enum",
+                                         "errorf",
+                                         "exp",
+                                         "exp2",
+                                         "explicit",
+                                         "export",
+                                         "extern",
+                                         "f16to32",
+                                         "f32tof16",
+                                         "faceforward",
+                                         "false",
+                                         "fastopt",
+                                         "firstbithigh",
+                                         "firstbitlow",
+                                         "flatten",
+                                         "float",
+                                         "float1",
+                                         "float1x1",
+                                         "float1x2",
+                                         "float1x3",
+                                         "float1x4",
+                                         "float2",
+                                         "float2x1",
+                                         "float2x2",
+                                         "float2x3",
+                                         "float2x4",
+                                         "float3",
+                                         "float3x1",
+                                         "float3x2",
+                                         "float3x3",
+                                         "float3x4",
+                                         "float4",
+                                         "float4x1",
+                                         "float4x2",
+                                         "float4x3",
+                                         "float4x4",
+                                         "floor",
+                                         "fma",
+                                         "fmod",
+                                         "for",
+                                         "forcecase",
+                                         "frac",
+                                         "frexp",
+                                         "friend",
+                                         "fwidth",
+                                         "fxgroup",
+                                         "goto",
+                                         "groupshared",
+                                         "half",
+                                         "half1",
+                                         "half1x1",
+                                         "half1x2",
+                                         "half1x3",
+                                         "half1x4",
+                                         "half2",
+                                         "half2x1",
+                                         "half2x2",
+                                         "half2x3",
+                                         "half2x4",
+                                         "half3",
+                                         "half3x1",
+                                         "half3x2",
+                                         "half3x3",
+                                         "half3x4",
+                                         "half4",
+                                         "half4x1",
+                                         "half4x2",
+                                         "half4x3",
+                                         "half4x4",
+                                         "if",
+                                         "in",
+                                         "inline",
+                                         "inout",
+                                         "int",
+                                         "int1",
+                                         "int1x1",
+                                         "int1x2",
+                                         "int1x3",
+                                         "int1x4",
+                                         "int2",
+                                         "int2x1",
+                                         "int2x2",
+                                         "int2x3",
+                                         "int2x4",
+                                         "int3",
+                                         "int3x1",
+                                         "int3x2",
+                                         "int3x3",
+                                         "int3x4",
+                                         "int4",
+                                         "int4x1",
+                                         "int4x2",
+                                         "int4x3",
+                                         "int4x4",
+                                         "interface",
+                                         "isfinite",
+                                         "isinf",
+                                         "isnan",
+                                         "ldexp",
+                                         "length",
+                                         "lerp",
+                                         "lineadj",
+                                         "linear",
+                                         "lit",
+                                         "log",
+                                         "log10",
+                                         "log2",
+                                         "long",
+                                         "loop",
+                                         "mad",
+                                         "matrix",
+                                         "max",
+                                         "min",
+                                         "min10float",
+                                         "min10float1",
+                                         "min10float1x1",
+                                         "min10float1x2",
+                                         "min10float1x3",
+                                         "min10float1x4",
+                                         "min10float2",
+                                         "min10float2x1",
+                                         "min10float2x2",
+                                         "min10float2x3",
+                                         "min10float2x4",
+                                         "min10float3",
+                                         "min10float3x1",
+                                         "min10float3x2",
+                                         "min10float3x3",
+                                         "min10float3x4",
+                                         "min10float4",
+                                         "min10float4x1",
+                                         "min10float4x2",
+                                         "min10float4x3",
+                                         "min10float4x4",
+                                         "min12int",
+                                         "min12int1",
+                                         "min12int1x1",
+                                         "min12int1x2",
+                                         "min12int1x3",
+                                         "min12int1x4",
+                                         "min12int2",
+                                         "min12int2x1",
+                                         "min12int2x2",
+                                         "min12int2x3",
+                                         "min12int2x4",
+                                         "min12int3",
+                                         "min12int3x1",
+                                         "min12int3x2",
+                                         "min12int3x3",
+                                         "min12int3x4",
+                                         "min12int4",
+                                         "min12int4x1",
+                                         "min12int4x2",
+                                         "min12int4x3",
+                                         "min12int4x4",
+                                         "min16float",
+                                         "min16float1",
+                                         "min16float1x1",
+                                         "min16float1x2",
+                                         "min16float1x3",
+                                         "min16float1x4",
+                                         "min16float2",
+                                         "min16float2x1",
+                                         "min16float2x2",
+                                         "min16float2x3",
+                                         "min16float2x4",
+                                         "min16float3",
+                                         "min16float3x1",
+                                         "min16float3x2",
+                                         "min16float3x3",
+                                         "min16float3x4",
+                                         "min16float4",
+                                         "min16float4x1",
+                                         "min16float4x2",
+                                         "min16float4x3",
+                                         "min16float4x4",
+                                         "min16int",
+                                         "min16int1",
+                                         "min16int1x1",
+                                         "min16int1x2",
+                                         "min16int1x3",
+                                         "min16int1x4",
+                                         "min16int2",
+                                         "min16int2x1",
+                                         "min16int2x2",
+                                         "min16int2x3",
+                                         "min16int2x4",
+                                         "min16int3",
+                                         "min16int3x1",
+                                         "min16int3x2",
+                                         "min16int3x3",
+                                         "min16int3x4",
+                                         "min16int4",
+                                         "min16int4x1",
+                                         "min16int4x2",
+                                         "min16int4x3",
+                                         "min16int4x4",
+                                         "min16uint",
+                                         "min16uint1",
+                                         "min16uint1x1",
+                                         "min16uint1x2",
+                                         "min16uint1x3",
+                                         "min16uint1x4",
+                                         "min16uint2",
+                                         "min16uint2x1",
+                                         "min16uint2x2",
+                                         "min16uint2x3",
+                                         "min16uint2x4",
+                                         "min16uint3",
+                                         "min16uint3x1",
+                                         "min16uint3x2",
+                                         "min16uint3x3",
+                                         "min16uint3x4",
+                                         "min16uint4",
+                                         "min16uint4x1",
+                                         "min16uint4x2",
+                                         "min16uint4x3",
+                                         "min16uint4x4",
+                                         "modf",
+                                         "msad4",
+                                         "mul",
+                                         "mutable",
+                                         "namespace",
+                                         "new",
+                                         "nointerpolation",
+                                         "noise",
+                                         "noperspective",
+                                         "normalize",
+                                         "numthreads",
+                                         "operator",
+                                         "out",
+                                         "packoffset",
+                                         "pass",
+                                         "pixelfragment",
+                                         "pixelshader",
+                                         "point",
+                                         "pow",
+                                         "precise",
+                                         "printf",
+                                         "private",
+                                         "protected",
+                                         "public",
+                                         "radians",
+                                         "rcp",
+                                         "reflect",
+                                         "refract",
+                                         "register",
+                                         "reinterpret_cast",
+                                         "return",
+                                         "reversebits",
+                                         "round",
+                                         "row_major",
+                                         "rsqrt",
+                                         "sample",
+                                         "sampler1D",
+                                         "sampler2D",
+                                         "sampler3D",
+                                         "samplerCUBE",
+                                         "sampler_state",
+                                         "saturate",
+                                         "shared",
+                                         "short",
+                                         "sign",
+                                         "signed",
+                                         "sin",
+                                         "sincos",
+                                         "sinh",
+                                         "sizeof",
+                                         "smoothstep",
+                                         "snorm",
+                                         "sqrt",
+                                         "stateblock",
+                                         "stateblock_state",
+                                         "static",
+                                         "static_cast",
+                                         "step",
+                                         "string",
+                                         "struct",
+                                         "switch",
+                                         "tan",
+                                         "tanh",
+                                         "tbuffer",
+                                         "technique",
+                                         "technique10",
+                                         "technique11",
+                                         "template",
+                                         "tex1D",
+                                         "tex1Dbias",
+                                         "tex1Dgrad",
+                                         "tex1Dlod",
+                                         "tex1Dproj",
+                                         "tex2D",
+                                         "tex2Dbias",
+                                         "tex2Dgrad",
+                                         "tex2Dlod",
+                                         "tex2Dproj",
+                                         "tex3D",
+                                         "tex3Dbias",
+                                         "tex3Dgrad",
+                                         "tex3Dlod",
+                                         "tex3Dproj",
+                                         "texCUBE",
+                                         "texCUBEbias",
+                                         "texCUBEgrad",
+                                         "texCUBElod",
+                                         "texCUBEproj",
+                                         "texture",
+                                         "texture1D",
+                                         "texture1DArray",
+                                         "texture2D",
+                                         "texture2DArray",
+                                         "texture2DMS",
+                                         "texture2DMSArray",
+                                         "texture3D",
+                                         "textureCube",
+                                         "textureCubeArray",
+                                         "this",
+                                         "throw",
+                                         "transpose",
+                                         "triangle",
+                                         "triangleadj",
+                                         "true",
+                                         "trunc",
+                                         "try",
+                                         "typedef",
+                                         "typename",
+                                         "uint",
+                                         "uint1",
+                                         "uint1x1",
+                                         "uint1x2",
+                                         "uint1x3",
+                                         "uint1x4",
+                                         "uint2",
+                                         "uint2x1",
+                                         "uint2x2",
+                                         "uint2x3",
+                                         "uint2x4",
+                                         "uint3",
+                                         "uint3x1",
+                                         "uint3x2",
+                                         "uint3x3",
+                                         "uint3x4",
+                                         "uint4",
+                                         "uint4x1",
+                                         "uint4x2",
+                                         "uint4x3",
+                                         "uint4x4",
+                                         "uniform",
+                                         "union",
+                                         "unorm",
+                                         "unroll",
+                                         "unsigned",
+                                         "using",
+                                         "vector",
+                                         "vertexfragment",
+                                         "vertexshader",
+                                         "virtual",
+                                         "void",
+                                         "volatile",
+                                         "while"));
+
+}  // namespace
+}  // namespace hlsl
+}  // namespace writer
+}  // namespace tint