Update builtin methods.

This CL removes the import mechanism, the identifier paths and updates
all of the standard library methods to be builtins.

Bug: tint:242
Change-Id: If09b98a155ae49ced3986ba2c9b517a060693006
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/28720
Commit-Queue: dan sinclair <dsinclair@chromium.org>
Reviewed-by: Ryan Harrison <rharrison@chromium.org>
diff --git a/src/ast/identifier_expression.cc b/src/ast/identifier_expression.cc
index d14d5f4..375387e 100644
--- a/src/ast/identifier_expression.cc
+++ b/src/ast/identifier_expression.cc
@@ -18,62 +18,27 @@
 namespace ast {
 
 IdentifierExpression::IdentifierExpression(const std::string& name)
-    : Expression(), segments_({name}) {}
+    : Expression(), name_(name) {}
 
 IdentifierExpression::IdentifierExpression(const Source& source,
                                            const std::string& name)
-    : Expression(source), segments_({name}) {}
-
-IdentifierExpression::IdentifierExpression(std::vector<std::string> segments)
-    : Expression(), segments_(std::move(segments)) {}
-
-IdentifierExpression::IdentifierExpression(const Source& source,
-                                           std::vector<std::string> segments)
-    : Expression(source), segments_(std::move(segments)) {}
+    : Expression(source), name_(name) {}
 
 IdentifierExpression::IdentifierExpression(IdentifierExpression&&) = default;
 
 IdentifierExpression::~IdentifierExpression() = default;
 
-std::string IdentifierExpression::path() const {
-  if (segments_.size() < 2) {
-    return "";
-  }
-
-  std::string path = "";
-  // We skip the last segment as that's the name, not part of the path
-  for (size_t i = 0; i < segments_.size() - 1; ++i) {
-    if (i > 0) {
-      path += "::";
-    }
-    path += segments_[i];
-  }
-  return path;
-}
-
 bool IdentifierExpression::IsIdentifier() const {
   return true;
 }
 
 bool IdentifierExpression::IsValid() const {
-  if (segments_.size() == 0)
-    return false;
-
-  for (const auto& segment : segments_) {
-    if (segment.size() == 0)
-      return false;
-  }
-  return true;
+  return !name_.empty();
 }
 
 void IdentifierExpression::to_str(std::ostream& out, size_t indent) const {
   make_indent(out, indent);
-  out << "Identifier{";
-  if (has_path()) {
-    out << path() << "::";
-  }
-  out << name();
-  out << "}" << std::endl;
+  out << "Identifier{" << name_ << "}" << std::endl;
 }
 
 }  // namespace ast
diff --git a/src/ast/identifier_expression.h b/src/ast/identifier_expression.h
index e45cd8f..af08b69 100644
--- a/src/ast/identifier_expression.h
+++ b/src/ast/identifier_expression.h
@@ -16,10 +16,9 @@
 #define SRC_AST_IDENTIFIER_EXPRESSION_H_
 
 #include <string>
-#include <utility>
-#include <vector>
 
 #include "src/ast/expression.h"
+#include "src/ast/intrinsic.h"
 
 namespace tint {
 namespace ast {
@@ -34,31 +33,20 @@
   /// @param source the source
   /// @param name the name
   IdentifierExpression(const Source& source, const std::string& name);
-  /// Constructor
-  /// @param segments the name segments
-  explicit IdentifierExpression(std::vector<std::string> segments);
-  /// Constructor
-  /// @param source the identifier expression source
-  /// @param segments the name segments
-  IdentifierExpression(const Source& source, std::vector<std::string> segments);
   /// Move constructor
   IdentifierExpression(IdentifierExpression&&);
   ~IdentifierExpression() override;
 
-  /// Sets the name segments
-  /// @param segments the name segments
-  void set_segments(std::vector<std::string> segments) {
-    segments_ = std::move(segments);
-  }
-  /// @returns the name
-  std::vector<std::string> segments() const { return segments_; }
-
-  /// @returns true if this identifier has a path component
-  bool has_path() const { return segments_.size() > 1; }
-  /// @returns the path part of the identifier or blank if no path
-  std::string path() const;
   /// @returns the name part of the identifier
-  std::string name() const { return segments_.back(); }
+  std::string name() const { return name_; }
+
+  /// Sets the intrinsic for this identifier
+  /// @param i the intrinsic to set
+  void set_intrinsic(Intrinsic i) { intrinsic_ = i; }
+  /// @returns the intrinsic this identifier represents
+  Intrinsic intrinsic() const { return intrinsic_; }
+  /// @returns true if this identifier is for an intrinsic
+  bool IsIntrinsic() const { return intrinsic_ != Intrinsic::kNone; }
 
   /// @returns true if this is an identifier expression
   bool IsIdentifier() const override;
@@ -74,7 +62,8 @@
  private:
   IdentifierExpression(const IdentifierExpression&) = delete;
 
-  std::vector<std::string> segments_;
+  Intrinsic intrinsic_ = Intrinsic::kNone;
+  std::string name_;
 };
 
 }  // namespace ast
diff --git a/src/ast/identifier_expression_test.cc b/src/ast/identifier_expression_test.cc
index 0886953..ad0ff98 100644
--- a/src/ast/identifier_expression_test.cc
+++ b/src/ast/identifier_expression_test.cc
@@ -24,19 +24,11 @@
 
 TEST_F(IdentifierExpressionTest, Creation) {
   IdentifierExpression i("ident");
-  ASSERT_EQ(i.segments().size(), 1u);
-  EXPECT_EQ(i.segments()[0], "ident");
-  EXPECT_EQ(i.path(), "");
   EXPECT_EQ(i.name(), "ident");
 }
 
 TEST_F(IdentifierExpressionTest, Creation_WithSource) {
-  IdentifierExpression i(Source{20, 2}, {"ns1", "ns2", "ident"});
-  ASSERT_EQ(i.segments().size(), 3u);
-  EXPECT_EQ(i.segments()[0], "ns1");
-  EXPECT_EQ(i.segments()[1], "ns2");
-  EXPECT_EQ(i.segments()[2], "ident");
-  EXPECT_EQ(i.path(), "ns1::ns2");
+  IdentifierExpression i(Source{20, 2}, "ident");
   EXPECT_EQ(i.name(), "ident");
 
   auto src = i.source();
@@ -54,21 +46,11 @@
   EXPECT_TRUE(i.IsValid());
 }
 
-TEST_F(IdentifierExpressionTest, IsValid_WithNamespaces) {
-  IdentifierExpression i({"ns1", "n2", "ident"});
-  EXPECT_TRUE(i.IsValid());
-}
-
 TEST_F(IdentifierExpressionTest, IsValid_BlankName) {
   IdentifierExpression i("");
   EXPECT_FALSE(i.IsValid());
 }
 
-TEST_F(IdentifierExpressionTest, IsValid_BlankNamespace) {
-  IdentifierExpression i({"ns1", "", "ident"});
-  EXPECT_FALSE(i.IsValid());
-}
-
 TEST_F(IdentifierExpressionTest, ToStr) {
   IdentifierExpression i("ident");
   std::ostringstream out;
@@ -77,14 +59,6 @@
 )");
 }
 
-TEST_F(IdentifierExpressionTest, ToStr_WithNamespace) {
-  IdentifierExpression i({"ns1", "ns2", "ident"});
-  std::ostringstream out;
-  i.to_str(out, 2);
-  EXPECT_EQ(out.str(), R"(  Identifier{ns1::ns2::ident}
-)");
-}
-
 }  // namespace
 }  // namespace ast
 }  // namespace tint
diff --git a/src/ast/import.cc b/src/ast/import.cc
deleted file mode 100644
index b86c6b1..0000000
--- a/src/ast/import.cc
+++ /dev/null
@@ -1,60 +0,0 @@
-// 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/ast/import.h"
-
-#include <cctype>
-
-namespace tint {
-namespace ast {
-
-Import::Import() = default;
-
-Import::Import(const std::string& path, const std::string& name)
-    : Node(), path_(path), name_(name) {}
-
-Import::Import(const Source& source,
-               const std::string& path,
-               const std::string& name)
-    : Node(source), path_(path), name_(name) {}
-
-Import::Import(Import&&) = default;
-
-Import::~Import() = default;
-
-bool Import::IsValid() const {
-  if (path_.length() == 0) {
-    return false;
-  }
-
-  auto len = name_.length();
-  if (len == 0) {
-    return false;
-  }
-
-  // Verify the import name ends in a character, number or _
-  if (len > 2 && !std::isalnum(name_[len - 1]) && name_[len] != '_') {
-    return false;
-  }
-
-  return true;
-}
-
-void Import::to_str(std::ostream& out, size_t indent) const {
-  make_indent(out, indent);
-  out << R"(Import{")" + path_ + R"(" as )" + name_ + "}" << std::endl;
-}
-
-}  // namespace ast
-}  // namespace tint
diff --git a/src/ast/import.h b/src/ast/import.h
deleted file mode 100644
index 5f40188..0000000
--- a/src/ast/import.h
+++ /dev/null
@@ -1,101 +0,0 @@
-// 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_AST_IMPORT_H_
-#define SRC_AST_IMPORT_H_
-
-#include <memory>
-#include <ostream>
-#include <string>
-#include <unordered_map>
-#include <vector>
-
-#include "src/ast/node.h"
-
-namespace tint {
-namespace ast {
-
-/// An import statement.
-class Import : public Node {
- public:
-  /// Create a new empty import statement
-  Import();
-  /// Create a new import statement
-  /// @param path The import path e.g. GLSL.std.450
-  /// @param name The import reference name e.g. std
-  Import(const std::string& path, const std::string& name);
-  /// Create a new import statement
-  /// @param source The input source for the import statement
-  /// @param path The import path e.g. GLSL.std.430
-  /// @param name The import reference name e.g. std
-  Import(const Source& source,
-         const std::string& path,
-         const std::string& name);
-  /// Move constructor
-  Import(Import&&);
-
-  ~Import() override;
-
-  /// Sets the import path
-  /// @param path the path to set
-  void set_path(const std::string& path) { path_ = path; }
-  /// @returns the import path
-  const std::string& path() const { return path_; }
-  /// Sets the import name
-  /// @param name the name to set
-  void set_name(const std::string& name) { name_ = name; }
-  /// @returns the import name
-  const std::string& name() const { return name_; }
-
-  /// Add the given |name| to map to the given |id|
-  /// @param name the name to map
-  /// @param id the id to map too
-  void AddMethodId(const std::string& name, uint32_t id) {
-    method_to_id_map_[name] = id;
-  }
-
-  /// Retrieves the id for a given name
-  /// @param name the name to lookup
-  /// @returns the id for the given name or 0 on failure
-  uint32_t GetIdForMethod(const std::string& name) const {
-    auto val = method_to_id_map_.find(name);
-    if (val == method_to_id_map_.end()) {
-      return 0;
-    }
-    return val->second;
-  }
-
-  /// @returns true if the name and path are both present
-  bool IsValid() const override;
-
-  /// Writes a representation of the node to the output stream
-  /// @param out the stream to write to
-  /// @param indent number of spaces to indent the node when writing
-  void to_str(std::ostream& out, size_t indent) const override;
-
- private:
-  Import(const Import&) = delete;
-
-  std::string path_;
-  std::string name_;
-  std::unordered_map<std::string, uint32_t> method_to_id_map_;
-};
-
-/// A list of unique imports
-using ImportList = std::vector<std::unique_ptr<Import>>;
-
-}  // namespace ast
-}  // namespace tint
-
-#endif  // SRC_AST_IMPORT_H_
diff --git a/src/ast/import_test.cc b/src/ast/import_test.cc
deleted file mode 100644
index af77bab..0000000
--- a/src/ast/import_test.cc
+++ /dev/null
@@ -1,93 +0,0 @@
-// 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/ast/import.h"
-
-#include <sstream>
-
-#include "gtest/gtest.h"
-
-namespace tint {
-namespace ast {
-namespace {
-
-using ImportTest = testing::Test;
-
-TEST_F(ImportTest, Creation) {
-  Import i("GLSL.std.430", "std::glsl");
-
-  EXPECT_EQ(i.path(), "GLSL.std.430");
-  EXPECT_EQ(i.name(), "std::glsl");
-  EXPECT_EQ(i.line(), 0u);
-  EXPECT_EQ(i.column(), 0u);
-}
-
-TEST_F(ImportTest, CreationWithSource) {
-  Source s{27, 4};
-  Import i(s, "GLSL.std.430", "std::glsl");
-
-  EXPECT_EQ(i.path(), "GLSL.std.430");
-  EXPECT_EQ(i.name(), "std::glsl");
-  EXPECT_EQ(i.line(), 27u);
-  EXPECT_EQ(i.column(), 4u);
-}
-
-TEST_F(ImportTest, CreationEmpty) {
-  Source s{27, 4};
-  Import i;
-  i.set_source(s);
-  i.set_path("GLSL.std.430");
-  i.set_name("std::glsl");
-
-  EXPECT_EQ(i.path(), "GLSL.std.430");
-  EXPECT_EQ(i.name(), "std::glsl");
-  EXPECT_EQ(i.line(), 27u);
-  EXPECT_EQ(i.column(), 4u);
-}
-
-TEST_F(ImportTest, to_str) {
-  Import i{"GLSL.std.430", "std::glsl"};
-  std::ostringstream out;
-  i.to_str(out, 2);
-  EXPECT_EQ(out.str(), "  Import{\"GLSL.std.430\" as std::glsl}\n");
-}
-
-TEST_F(ImportTest, IsValid) {
-  Import i{"GLSL.std.430", "std::glsl"};
-  EXPECT_TRUE(i.IsValid());
-}
-
-TEST_F(ImportTest, IsValid_MissingPath) {
-  Import i{"", "std::glsl"};
-  EXPECT_FALSE(i.IsValid());
-}
-
-TEST_F(ImportTest, IsValid_MissingName) {
-  Import i{"GLSL.std.430", ""};
-  EXPECT_FALSE(i.IsValid());
-}
-
-TEST_F(ImportTest, IsValid_MissingBoth) {
-  Import i;
-  EXPECT_FALSE(i.IsValid());
-}
-
-TEST_F(ImportTest, IsValid_InvalidEndingCharacter) {
-  Import i{"GLSL.std.430", "std::glsl::"};
-  EXPECT_FALSE(i.IsValid());
-}
-
-}  // namespace
-}  // namespace ast
-}  // namespace tint
diff --git a/src/ast/intrinsic.cc b/src/ast/intrinsic.cc
index da5a855..6006bcb 100644
--- a/src/ast/intrinsic.cc
+++ b/src/ast/intrinsic.cc
@@ -16,37 +16,242 @@
 
 namespace tint {
 namespace ast {
+
+std::ostream& operator<<(std::ostream& out, Intrinsic i) {
+  switch (i) {
+    case Intrinsic::kAbs:
+      out << "abs";
+      break;
+    case Intrinsic::kAcos:
+      out << "acos";
+      break;
+    case Intrinsic::kAll:
+      out << "all";
+      break;
+    case Intrinsic::kAny:
+      out << "any";
+      break;
+    case Intrinsic::kAsin:
+      out << "asin";
+      break;
+    case Intrinsic::kAtan:
+      out << "atan";
+      break;
+    case Intrinsic::kAtan2:
+      out << "atan2";
+      break;
+    case Intrinsic::kCeil:
+      out << "ceil";
+      break;
+    case Intrinsic::kClamp:
+      out << "clamp";
+      break;
+    case Intrinsic::kCos:
+      out << "cos";
+      break;
+    case Intrinsic::kCosh:
+      out << "cosh";
+      break;
+    case Intrinsic::kCountOneBits:
+      out << "countOneBits";
+      break;
+    case Intrinsic::kCross:
+      out << "cross";
+      break;
+    case Intrinsic::kDeterminant:
+      out << "determinant";
+      break;
+    case Intrinsic::kDistance:
+      out << "distance";
+      break;
+    case Intrinsic::kDot:
+      out << "dot";
+      break;
+    case Intrinsic::kDpdx:
+      out << "dpdx";
+      break;
+    case Intrinsic::kDpdxCoarse:
+      out << "dpdxCoarse";
+      break;
+    case Intrinsic::kDpdxFine:
+      out << "dpdxFine";
+      break;
+    case Intrinsic::kDpdy:
+      out << "dpdy";
+      break;
+    case Intrinsic::kDpdyCoarse:
+      out << "dpdyCoarse";
+      break;
+    case Intrinsic::kDpdyFine:
+      out << "dpdyFine";
+      break;
+    case Intrinsic::kExp:
+      out << "exp";
+      break;
+    case Intrinsic::kExp2:
+      out << "exp2";
+      break;
+    case Intrinsic::kFaceForward:
+      out << "faceForward";
+      break;
+    case Intrinsic::kFloor:
+      out << "floor";
+      break;
+    case Intrinsic::kFma:
+      out << "fma";
+      break;
+    case Intrinsic::kFract:
+      out << "fract";
+      break;
+    case Intrinsic::kFrexp:
+      out << "frexp";
+      break;
+    case Intrinsic::kFwidth:
+      out << "fwidth";
+      break;
+    case Intrinsic::kFwidthCoarse:
+      out << "fwidthCoarse";
+      break;
+    case Intrinsic::kFwidthFine:
+      out << "fwidthFine";
+      break;
+    case Intrinsic::kInverseSqrt:
+      out << "inverseSqrt";
+      break;
+    case Intrinsic::kIsFinite:
+      out << "isFinite";
+      break;
+    case Intrinsic::kIsInf:
+      out << "isInf";
+      break;
+    case Intrinsic::kIsNan:
+      out << "isNan";
+      break;
+    case Intrinsic::kIsNormal:
+      out << "isNormal";
+      break;
+    case Intrinsic::kLdexp:
+      out << "ldexp";
+      break;
+    case Intrinsic::kLength:
+      out << "length";
+      break;
+    case Intrinsic::kLog:
+      out << "log";
+      break;
+    case Intrinsic::kLog2:
+      out << "log2";
+      break;
+    case Intrinsic::kMax:
+      out << "max";
+      break;
+    case Intrinsic::kMin:
+      out << "min";
+      break;
+    case Intrinsic::kMix:
+      out << "mix";
+      break;
+    case Intrinsic::kModf:
+      out << "modf";
+      break;
+    case Intrinsic::kNormalize:
+      out << "normalize";
+      break;
+    case Intrinsic::kOuterProduct:
+      out << "outerProduct";
+      break;
+    case Intrinsic::kPow:
+      out << "pow";
+      break;
+    case Intrinsic::kReflect:
+      out << "reflect";
+      break;
+    case Intrinsic::kReverseBits:
+      out << "reverseBits";
+      break;
+    case Intrinsic::kRound:
+      out << "round";
+      break;
+    case Intrinsic::kSelect:
+      out << "select";
+      break;
+    case Intrinsic::kSign:
+      out << "sign";
+      break;
+    case Intrinsic::kSin:
+      out << "sin";
+      break;
+    case Intrinsic::kSinh:
+      out << "sinh";
+      break;
+    case Intrinsic::kSmoothStep:
+      out << "smoothStep";
+      break;
+    case Intrinsic::kSqrt:
+      out << "sqrt";
+      break;
+    case Intrinsic::kStep:
+      out << "step";
+      break;
+    case Intrinsic::kTan:
+      out << "tan";
+      break;
+    case Intrinsic::kTanh:
+      out << "tanh";
+      break;
+    case Intrinsic::kTextureLoad:
+      out << "textureLoad";
+      break;
+    case Intrinsic::kTextureSample:
+      out << "textureSample";
+      break;
+    case Intrinsic::kTextureSampleBias:
+      out << "textureSampleBias";
+      break;
+    case Intrinsic::kTextureSampleCompare:
+      out << "textureSampleCompare";
+      break;
+    case Intrinsic::kTextureSampleLevel:
+      out << "textureSampleLevel";
+      break;
+    case Intrinsic::kTrunc:
+      out << "trunc";
+      break;
+    default:
+      out << "Unknown";
+      break;
+  }
+  return out;
+}
+
 namespace intrinsic {
 
-bool IsCoarseDerivative(const std::string& name) {
-  return name == "dpdxCoarse" || name == "dpdyCoarse" || name == "fwidthCoarse";
+bool IsCoarseDerivative(ast::Intrinsic i) {
+  return i == Intrinsic::kDpdxCoarse ||
+         i == Intrinsic::kDpdyCoarse | i == Intrinsic::kFwidthCoarse;
 }
 
-bool IsFineDerivative(const std::string& name) {
-  return name == "dpdxFine" || name == "dpdyFine" || name == "fwidthFine";
+bool IsFineDerivative(ast::Intrinsic i) {
+  return i == Intrinsic::kDpdxFine || i == Intrinsic::kDpdyFine ||
+         i == Intrinsic::kFwidthFine;
 }
 
-bool IsDerivative(const std::string& name) {
-  return name == "dpdx" || name == "dpdy" || name == "fwidth" ||
-         IsCoarseDerivative(name) || IsFineDerivative(name);
+bool IsDerivative(ast::Intrinsic i) {
+  return i == Intrinsic::kDpdx || i == Intrinsic::kDpdy ||
+         i == Intrinsic::kFwidth || IsCoarseDerivative(i) ||
+         IsFineDerivative(i);
 }
 
-bool IsFloatClassificationIntrinsic(const std::string& name) {
-  return name == "isFinite" || name == "isInf" || name == "isNan" ||
-         name == "isNormal";
+bool IsFloatClassificationIntrinsic(ast::Intrinsic i) {
+  return i == Intrinsic::kIsFinite || i == Intrinsic::kIsInf ||
+         i == Intrinsic::kIsNan || i == Intrinsic::kIsNormal;
 }
 
-bool IsTextureOperationIntrinsic(const std::string& name) {
-  return name == "textureLoad" || name == "textureSample" ||
-         name == "textureSampleLevel" || name == "textureSampleBias" ||
-         name == "textureSampleCompare";
-}
-
-bool IsIntrinsic(const std::string& name) {
-  return IsDerivative(name) || name == "all" || name == "any" ||
-         IsFloatClassificationIntrinsic(name) ||
-         IsTextureOperationIntrinsic(name) || name == "dot" ||
-         name == "outerProduct" || name == "select";
+bool IsTextureIntrinsic(ast::Intrinsic i) {
+  return i == Intrinsic::kTextureLoad || i == Intrinsic::kTextureSample ||
+         i == Intrinsic::kTextureSampleLevel ||
+         i == Intrinsic::kTextureSampleBias ||
+         i == Intrinsic::kTextureSampleCompare;
 }
 
 }  // namespace intrinsic
diff --git a/src/ast/intrinsic.h b/src/ast/intrinsic.h
index 1196db9..c66f749 100644
--- a/src/ast/intrinsic.h
+++ b/src/ast/intrinsic.h
@@ -15,41 +15,111 @@
 #ifndef SRC_AST_INTRINSIC_H_
 #define SRC_AST_INTRINSIC_H_
 
+#include <ostream>
 #include <string>
 
 namespace tint {
 namespace ast {
+
+enum class Intrinsic {
+  kNone = -1,
+
+  kAbs,
+  kAcos,
+  kAll,
+  kAny,
+  kAsin,
+  kAtan,
+  kAtan2,
+  kCeil,
+  kClamp,
+  kCos,
+  kCosh,
+  kCountOneBits,
+  kCross,
+  kDeterminant,
+  kDistance,
+  kDot,
+  kDpdx,
+  kDpdxCoarse,
+  kDpdxFine,
+  kDpdy,
+  kDpdyCoarse,
+  kDpdyFine,
+  kExp,
+  kExp2,
+  kFaceForward,
+  kFloor,
+  kFma,
+  kFract,
+  kFrexp,
+  kFwidth,
+  kFwidthCoarse,
+  kFwidthFine,
+  kInverseSqrt,
+  kIsFinite,
+  kIsInf,
+  kIsNan,
+  kIsNormal,
+  kLdexp,
+  kLength,
+  kLog,
+  kLog2,
+  kMax,
+  kMin,
+  kMix,
+  kModf,
+  kNormalize,
+  kOuterProduct,
+  kPow,
+  kReflect,
+  kReverseBits,
+  kRound,
+  kSelect,
+  kSign,
+  kSin,
+  kSinh,
+  kSmoothStep,
+  kSqrt,
+  kStep,
+  kTan,
+  kTanh,
+  kTextureLoad,
+  kTextureSample,
+  kTextureSampleBias,
+  kTextureSampleCompare,
+  kTextureSampleLevel,
+  kTrunc
+};
+
+std::ostream& operator<<(std::ostream& out, Intrinsic i);
+
 namespace intrinsic {
 
 /// Determines if the given |name| is a coarse derivative
-/// @param name the name to check
+/// @param i the intrinsic
 /// @returns true if the given derivative is coarse.
-bool IsCoarseDerivative(const std::string& name);
+bool IsCoarseDerivative(ast::Intrinsic i);
 
 /// Determines if the given |name| is a fine derivative
-/// @param name the name to check
+/// @param i the intrinsic
 /// @returns true if the given derivative is fine.
-bool IsFineDerivative(const std::string& name);
+bool IsFineDerivative(ast::Intrinsic i);
 
 /// Determine if the given |name| is a derivative intrinsic
-/// @param name the name to check
+/// @param i the intrinsic
 /// @returns true if the given |name| is a derivative intrinsic
-bool IsDerivative(const std::string& name);
+bool IsDerivative(ast::Intrinsic i);
 
 /// Determines if the given |name| is a float classification intrinsic
-/// @param name the name to check
+/// @param i the intrinsic
 /// @returns true if the given |name| is a float intrinsic
-bool IsFloatClassificationIntrinsic(const std::string& name);
+bool IsFloatClassificationIntrinsic(ast::Intrinsic i);
 
 /// Determines if the given |name| is a texture operation intrinsic
-/// @param name the name to check
+/// @param i the intrinsic
 /// @returns true if the given |name| is a texture operation intrinsic
-bool IsTextureOperationIntrinsic(const std::string& name);
-
-/// Determines if the given |name| is an intrinsic
-/// @param name the name to check
-/// @returns true if the given |name| is an intrinsic
-bool IsIntrinsic(const std::string& name);
+bool IsTextureIntrinsic(ast::Intrinsic i);
 
 }  // namespace intrinsic
 }  // namespace ast
diff --git a/src/ast/module.cc b/src/ast/module.cc
index b650a78..b595aa7 100644
--- a/src/ast/module.cc
+++ b/src/ast/module.cc
@@ -27,15 +27,6 @@
 
 Module::~Module() = default;
 
-Import* Module::FindImportByName(const std::string& name) const {
-  for (const auto& import : imports_) {
-    if (import->name() == name) {
-      return import.get();
-    }
-  }
-  return nullptr;
-}
-
 Function* Module::FindFunctionByName(const std::string& name) const {
   for (const auto& func : functions_) {
     if (func->name() == name) {
@@ -56,11 +47,6 @@
 }
 
 bool Module::IsValid() const {
-  for (const auto& import : imports_) {
-    if (import == nullptr || !import->IsValid()) {
-      return false;
-    }
-  }
   for (const auto& var : global_variables_) {
     if (var == nullptr || !var->IsValid()) {
       return false;
@@ -84,9 +70,6 @@
 
   out << "Module{" << std::endl;
   const auto indent = 2;
-  for (const auto& import : imports_) {
-    import->to_str(out, indent);
-  }
   for (const auto& var : global_variables_) {
     var->to_str(out, indent);
   }
diff --git a/src/ast/module.h b/src/ast/module.h
index cb8f13a..134e762 100644
--- a/src/ast/module.h
+++ b/src/ast/module.h
@@ -21,7 +21,6 @@
 #include <vector>
 
 #include "src/ast/function.h"
-#include "src/ast/import.h"
 #include "src/ast/type/alias_type.h"
 #include "src/ast/variable.h"
 
@@ -36,18 +35,6 @@
   Module(Module&&);
   ~Module();
 
-  /// Add the given import to the module
-  /// @param import The import to add.
-  void AddImport(std::unique_ptr<Import> import) {
-    imports_.push_back(std::move(import));
-  }
-  /// @returns the imports for this module
-  const ImportList& imports() const { return imports_; }
-  /// Find the import of the given name
-  /// @param name The import name to search for
-  /// @returns the import with the given name if found, nullptr otherwise.
-  Import* FindImportByName(const std::string& name) const;
-
   /// Add a global variable to the module
   /// @param var the variable to add
   void AddGlobalVariable(std::unique_ptr<Variable> var) {
@@ -94,7 +81,6 @@
  private:
   Module(const Module&) = delete;
 
-  ImportList imports_;
   VariableList global_variables_;
   // The alias types are owned by the type manager
   std::vector<type::AliasType*> alias_types_;
diff --git a/src/ast/module_test.cc b/src/ast/module_test.cc
index e1cec96..50c3982 100644
--- a/src/ast/module_test.cc
+++ b/src/ast/module_test.cc
@@ -19,7 +19,6 @@
 
 #include "gmock/gmock.h"
 #include "src/ast/function.h"
-#include "src/ast/import.h"
 #include "src/ast/type/f32_type.h"
 #include "src/ast/variable.h"
 
@@ -32,7 +31,7 @@
 TEST_F(ModuleTest, Creation) {
   Module m;
 
-  EXPECT_EQ(m.imports().size(), 0u);
+  EXPECT_EQ(m.functions().size(), 0u);
 }
 
 TEST_F(ModuleTest, ToStrEmitsPreambleAndPostamble) {
@@ -42,44 +41,6 @@
   EXPECT_EQ(str, expected);
 }
 
-TEST_F(ModuleTest, Imports) {
-  Module m;
-
-  m.AddImport(std::make_unique<Import>("GLSL.std.430", "std::glsl"));
-  m.AddImport(std::make_unique<Import>("OpenCL.debug.100", "std::debug"));
-
-  EXPECT_EQ(2u, m.imports().size());
-  EXPECT_EQ("std::glsl", m.imports()[0]->name());
-}
-
-TEST_F(ModuleTest, ToStrWithImport) {
-  Module m;
-  m.AddImport(std::make_unique<Import>("GLSL.std.430", "std::glsl"));
-  const auto str = m.to_str();
-  EXPECT_EQ(str, R"(Module{
-  Import{"GLSL.std.430" as std::glsl}
-}
-)");
-}
-
-TEST_F(ModuleTest, LookupImport) {
-  Module m;
-
-  auto i = std::make_unique<Import>("GLSL.std.430", "std::glsl");
-  m.AddImport(std::move(i));
-  m.AddImport(std::make_unique<Import>("OpenCL.debug.100", "std::debug"));
-
-  auto* import = m.FindImportByName("std::glsl");
-  ASSERT_NE(nullptr, import);
-  EXPECT_EQ(import->path(), "GLSL.std.430");
-  EXPECT_EQ(import->name(), "std::glsl");
-}
-
-TEST_F(ModuleTest, LookupImportMissing) {
-  Module m;
-  EXPECT_EQ(nullptr, m.FindImportByName("Missing"));
-}
-
 TEST_F(ModuleTest, LookupFunction) {
   type::F32Type f32;
   Module m;
@@ -100,24 +61,6 @@
   EXPECT_TRUE(m.IsValid());
 }
 
-TEST_F(ModuleTest, IsValid_Import) {
-  Module m;
-  m.AddImport(std::make_unique<Import>("GLSL.std.430", "std::glsl"));
-  EXPECT_TRUE(m.IsValid());
-}
-
-TEST_F(ModuleTest, IsValid_Null_Import) {
-  Module m;
-  m.AddImport(nullptr);
-  EXPECT_FALSE(m.IsValid());
-}
-
-TEST_F(ModuleTest, IsValid_Invalid_Import) {
-  Module m;
-  m.AddImport(std::make_unique<Import>());
-  EXPECT_FALSE(m.IsValid());
-}
-
 TEST_F(ModuleTest, IsValid_GlobalVariable) {
   type::F32Type f32;
   auto var = std::make_unique<Variable>("var", StorageClass::kInput, &f32);