Pass std::string_view by value

As std::string_view is a relatively small structure it can be passed
by value. The code was using a mix of passing it either by value or
by const reference. Settle on passing by value.

Remove some unnecessary templated functions that was only overloaded
for `const std::string&` and `const std::string_view` as the latter
was enough.

Fix IWYU by adding `#include <string_view>` in all header files that
uses std::string_view.

Bug: none
Change-Id: If42ab28342e8d73f6f0543e77319fdf6380c41b5
Reviewed-on: https://gn-review.googlesource.com/c/gn/+/11400
Reviewed-by: Brett Wilson <brettw@chromium.org>
Commit-Queue: Sylvain Defresne <sdefresne@chromium.org>
diff --git a/src/base/command_line.cc b/src/base/command_line.cc
index ea4bbda..ba9a6b0 100644
--- a/src/base/command_line.cc
+++ b/src/base/command_line.cc
@@ -283,7 +283,7 @@
 #endif
 }
 
-bool CommandLine::HasSwitch(const std::string_view& switch_string) const {
+bool CommandLine::HasSwitch(std::string_view switch_string) const {
   DCHECK_EQ(ToLowerASCII(switch_string), switch_string);
   return ContainsKey(switches_, switch_string);
 }
@@ -293,7 +293,7 @@
 }
 
 std::string CommandLine::GetSwitchValueASCII(
-    const std::string_view& switch_string) const {
+    std::string_view switch_string) const {
   StringType value = GetSwitchValueNative(switch_string);
   if (!IsStringASCII(value)) {
     DLOG(WARNING) << "Value of switch (" << switch_string << ") must be ASCII.";
@@ -306,13 +306,12 @@
 #endif
 }
 
-FilePath CommandLine::GetSwitchValuePath(
-    const std::string_view& switch_string) const {
+FilePath CommandLine::GetSwitchValuePath(std::string_view switch_string) const {
   return FilePath(GetSwitchValueNative(switch_string));
 }
 
 CommandLine::StringType CommandLine::GetSwitchValueNative(
-    const std::string_view& switch_string) const {
+    std::string_view switch_string) const {
   DCHECK_EQ(ToLowerASCII(switch_string), switch_string);
   auto result = switches_.find(switch_string);
   return result == switches_.end() ? StringType() : result->second;
diff --git a/src/base/command_line.h b/src/base/command_line.h
index 46c1fcc..3a44346 100644
--- a/src/base/command_line.h
+++ b/src/base/command_line.h
@@ -164,15 +164,15 @@
   // The second override provides an optimized version to avoid inlining codegen
   // at every callsite to find the length of the constant and construct a
   // std::string_view.
-  bool HasSwitch(const std::string_view& switch_string) const;
+  bool HasSwitch(std::string_view switch_string) const;
   bool HasSwitch(const char switch_constant[]) const;
 
   // Returns the value associated with the given switch. If the switch has no
   // value or isn't present, this method returns the empty string.
   // Switch names must be lowercase.
-  std::string GetSwitchValueASCII(const std::string_view& switch_string) const;
-  FilePath GetSwitchValuePath(const std::string_view& switch_string) const;
-  StringType GetSwitchValueNative(const std::string_view& switch_string) const;
+  std::string GetSwitchValueASCII(std::string_view switch_string) const;
+  FilePath GetSwitchValuePath(std::string_view switch_string) const;
+  StringType GetSwitchValueNative(std::string_view switch_string) const;
 
   // Get a copy of all switches, along with their values.
   const SwitchMap& GetSwitches() const { return switches_; }
diff --git a/src/base/containers/span.h b/src/base/containers/span.h
index 29c9a97..4af83b4 100644
--- a/src/base/containers/span.h
+++ b/src/base/containers/span.h
@@ -10,6 +10,7 @@
 #include <algorithm>
 #include <array>
 #include <iterator>
+#include <string_view>
 #include <type_traits>
 #include <utility>
 
diff --git a/src/base/md5.cc b/src/base/md5.cc
index 4fcab55..54684e9 100644
--- a/src/base/md5.cc
+++ b/src/base/md5.cc
@@ -169,7 +169,7 @@
  * Update context to reflect the concatenation of another buffer full
  * of bytes.
  */
-void MD5Update(MD5Context* context, const std::string_view& data) {
+void MD5Update(MD5Context* context, std::string_view data) {
   struct Context* ctx = reinterpret_cast<struct Context*>(context);
   const uint8_t* buf = reinterpret_cast<const uint8_t*>(data.data());
   size_t len = data.size();
@@ -292,7 +292,7 @@
   MD5Final(digest, &ctx);
 }
 
-std::string MD5String(const std::string_view& str) {
+std::string MD5String(std::string_view str) {
   MD5Digest digest;
   MD5Sum(str.data(), str.length(), &digest);
   return MD5DigestToBase16(digest);
diff --git a/src/base/md5.h b/src/base/md5.h
index d25b2fc..b00165c 100644
--- a/src/base/md5.h
+++ b/src/base/md5.h
@@ -52,7 +52,7 @@
 // For the given buffer of |data| as a std::string_view, updates the given MD5
 // context with the sum of the data. You can call this any number of times
 // during the computation, except that MD5Init() must have been called first.
-void MD5Update(MD5Context* context, const std::string_view& data);
+void MD5Update(MD5Context* context, std::string_view data);
 
 // Finalizes the MD5 operation and fills the buffer with the digest.
 void MD5Final(MD5Digest* digest, MD5Context* context);
@@ -70,7 +70,7 @@
 void MD5Sum(const void* data, size_t length, MD5Digest* digest);
 
 // Returns the MD5 (in hexadecimal) of a string.
-std::string MD5String(const std::string_view& str);
+std::string MD5String(std::string_view str);
 
 }  // namespace base
 
diff --git a/src/base/strings/utf_offset_string_conversions.cc b/src/base/strings/utf_offset_string_conversions.cc
index ee55a24..6f2aaf4 100644
--- a/src/base/strings/utf_offset_string_conversions.cc
+++ b/src/base/strings/utf_offset_string_conversions.cc
@@ -228,7 +228,7 @@
 }
 
 std::u16string UTF8ToUTF16WithAdjustments(
-    const std::string_view& utf8,
+    std::string_view utf8,
     base::OffsetAdjuster::Adjustments* adjustments) {
   std::u16string result;
   UTF8ToUTF16WithAdjustments(utf8.data(), utf8.length(), &result, adjustments);
@@ -236,7 +236,7 @@
 }
 
 std::u16string UTF8ToUTF16AndAdjustOffsets(
-    const std::string_view& utf8,
+    std::string_view utf8,
     std::vector<size_t>* offsets_for_adjustment) {
   for (size_t& offset : *offsets_for_adjustment) {
     if (offset > utf8.length())
@@ -249,7 +249,7 @@
 }
 
 std::string UTF16ToUTF8AndAdjustOffsets(
-    const std::u16string_view& utf16,
+    std::u16string_view utf16,
     std::vector<size_t>* offsets_for_adjustment) {
   for (size_t& offset : *offsets_for_adjustment) {
     if (offset > utf16.length())
diff --git a/src/base/strings/utf_offset_string_conversions.h b/src/base/strings/utf_offset_string_conversions.h
index 8d6c5e8..0562e01 100644
--- a/src/base/strings/utf_offset_string_conversions.h
+++ b/src/base/strings/utf_offset_string_conversions.h
@@ -93,17 +93,17 @@
                                 std::u16string* output,
                                 base::OffsetAdjuster::Adjustments* adjustments);
 std::u16string UTF8ToUTF16WithAdjustments(
-    const std::string_view& utf8,
+    std::string_view utf8,
     base::OffsetAdjuster::Adjustments* adjustments);
 // As above, but instead internally examines the adjustments and applies them
 // to |offsets_for_adjustment|.  Input offsets greater than the length of the
 // input string will be set to std::u16string::npos.  See comments by
 // AdjustOffsets().
 std::u16string UTF8ToUTF16AndAdjustOffsets(
-    const std::string_view& utf8,
+    std::string_view utf8,
     std::vector<size_t>* offsets_for_adjustment);
 std::string UTF16ToUTF8AndAdjustOffsets(
-    const std::u16string_view& utf16,
+    std::u16string_view utf16,
     std::vector<size_t>* offsets_for_adjustment);
 
 }  // namespace base
diff --git a/src/gn/args.h b/src/gn/args.h
index 992d48f..24e8308 100644
--- a/src/gn/args.h
+++ b/src/gn/args.h
@@ -8,6 +8,7 @@
 #include <map>
 #include <mutex>
 #include <set>
+#include <string_view>
 #include <unordered_map>
 
 #include "base/macros.h"
diff --git a/src/gn/c_include_iterator.cc b/src/gn/c_include_iterator.cc
index f8626e1..9fcc6be 100644
--- a/src/gn/c_include_iterator.cc
+++ b/src/gn/c_include_iterator.cc
@@ -23,7 +23,7 @@
 // Returns a new string piece referencing the same buffer as the argument, but
 // with leading space trimmed. This only checks for space and tab characters
 // since we're dealing with lines in C source files.
-std::string_view TrimLeadingWhitespace(const std::string_view& str) {
+std::string_view TrimLeadingWhitespace(std::string_view str) {
   size_t new_begin = 0;
   while (new_begin < str.size() &&
          (str[new_begin] == ' ' || str[new_begin] == '\t'))
@@ -42,7 +42,7 @@
 //
 // We assume the line has leading whitespace trimmed. We also assume that empty
 // lines have already been filtered out.
-bool ShouldCountTowardNonIncludeLines(const std::string_view& line) {
+bool ShouldCountTowardNonIncludeLines(std::string_view line) {
   if (base::StartsWith(line, "//", base::CompareCase::SENSITIVE))
     return false;  // Don't count comments.
   if (base::StartsWith(line, "/*", base::CompareCase::SENSITIVE) ||
@@ -61,7 +61,7 @@
 //
 // The 1-based character number on the line that the include was found at
 // will be filled into *begin_char.
-IncludeType ExtractInclude(const std::string_view& line,
+IncludeType ExtractInclude(std::string_view line,
                            std::string_view* path,
                            int* begin_char) {
   static const char kInclude[] = "include";
@@ -113,7 +113,7 @@
 }
 
 // Returns true if this line has a "nogncheck" comment associated with it.
-bool HasNoCheckAnnotation(const std::string_view& line) {
+bool HasNoCheckAnnotation(std::string_view line) {
   return line.find("nogncheck") != std::string_view::npos;
 }
 
diff --git a/src/gn/command_args.cc b/src/gn/command_args.cc
index 14ca348..e74c598 100644
--- a/src/gn/command_args.cc
+++ b/src/gn/command_args.cc
@@ -40,7 +40,7 @@
 const char kSwitchOverridesOnly[] = "overrides-only";
 const char kSwitchJson[] = "json";
 
-bool DoesLineBeginWithComment(const std::string_view& line) {
+bool DoesLineBeginWithComment(std::string_view line) {
   // Skip whitespace.
   size_t i = 0;
   while (i < line.size() && base::IsAsciiWhitespace(line[i]))
@@ -67,7 +67,7 @@
 
 // Assumes DoesLineBeginWithComment(), this strips the # character from the
 // beginning and normalizes preceding whitespace.
-std::string StripHashFromLine(const std::string_view& line, bool pad) {
+std::string StripHashFromLine(std::string_view line, bool pad) {
   // Replace the # sign and everything before it with 3 spaces, so that a
   // normal comment that has a space after the # will be indented 4 spaces
   // (which makes our formatting come out nicely). If the comment is indented
@@ -137,8 +137,7 @@
 }
 
 // Override value is null if there is no override.
-void PrintArgHelp(const std::string_view& name,
-                  const Args::ValueWithOverride& val) {
+void PrintArgHelp(std::string_view name, const Args::ValueWithOverride& val) {
   OutputString(std::string(name), DECORATION_YELLOW);
   OutputString("\n");
 
@@ -163,7 +162,7 @@
 }
 
 void BuildArgJson(base::Value& dict,
-                  const std::string_view& name,
+                  std::string_view name,
                   const Args::ValueWithOverride& arg,
                   bool short_only) {
   assert(dict.is_dict());
diff --git a/src/gn/create_bundle_target_generator.cc b/src/gn/create_bundle_target_generator.cc
index b614a9c..0a3d7cf 100644
--- a/src/gn/create_bundle_target_generator.cc
+++ b/src/gn/create_bundle_target_generator.cc
@@ -76,7 +76,7 @@
 
 bool CreateBundleTargetGenerator::FillBundleDir(
     const SourceDir& bundle_root_dir,
-    const std::string_view& name,
+    std::string_view name,
     SourceDir* bundle_dir) {
   // All bundle_foo_dir properties are optional. They are only required if they
   // are used in an expansion. The check is performed there.
diff --git a/src/gn/create_bundle_target_generator.h b/src/gn/create_bundle_target_generator.h
index 6f13fb4..6a0971a 100644
--- a/src/gn/create_bundle_target_generator.h
+++ b/src/gn/create_bundle_target_generator.h
@@ -5,6 +5,8 @@
 #ifndef TOOLS_GN_CREATE_BUNDLE_TARGET_GENERATOR_H_
 #define TOOLS_GN_CREATE_BUNDLE_TARGET_GENERATOR_H_
 
+#include <string_view>
+
 #include "base/macros.h"
 #include "gn/target_generator.h"
 
@@ -24,7 +26,7 @@
 
  private:
   bool FillBundleDir(const SourceDir& bundle_root_dir,
-                     const std::string_view& name,
+                     std::string_view name,
                      SourceDir* bundle_dir);
 
   bool FillXcodeExtraAttributes();
diff --git a/src/gn/err.cc b/src/gn/err.cc
index 301ee8d..68cb046 100644
--- a/src/gn/err.cc
+++ b/src/gn/err.cc
@@ -17,7 +17,7 @@
 
 namespace {
 
-std::string GetNthLine(const std::string_view& data, int n) {
+std::string GetNthLine(std::string_view data, int n) {
   size_t line_off = Tokenizer::ByteOffsetOfNthLine(data, n);
   size_t end = line_off + 1;
   while (end < data.size() && !Tokenizer::IsNewline(data, end))
diff --git a/src/gn/escape.cc b/src/gn/escape.cc
index 3c8dc3f..687c92a 100644
--- a/src/gn/escape.cc
+++ b/src/gn/escape.cc
@@ -42,7 +42,7 @@
     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0};
 // clang-format on
 
-size_t EscapeStringToString_Space(const std::string_view& str,
+size_t EscapeStringToString_Space(std::string_view str,
                                   const EscapeOptions& options,
                                   char* dest,
                                   bool* needed_quoting) {
@@ -76,7 +76,7 @@
   return ch == '$' || ch == ' ' || ch == ':';
 }
 
-size_t EscapeStringToString_Ninja(const std::string_view& str,
+size_t EscapeStringToString_Ninja(std::string_view str,
                                   const EscapeOptions& options,
                                   char* dest,
                                   bool* needed_quoting) {
@@ -93,7 +93,7 @@
   return ch == '\\' || ch == '"';
 }
 
-size_t EscapeStringToString_CompilationDatabase(const std::string_view& str,
+size_t EscapeStringToString_CompilationDatabase(std::string_view str,
                                                 const EscapeOptions& options,
                                                 char* dest,
                                                 bool* needed_quoting) {
@@ -119,7 +119,7 @@
   return i;
 }
 
-size_t EscapeStringToString_Depfile(const std::string_view& str,
+size_t EscapeStringToString_Depfile(std::string_view str,
                                     const EscapeOptions& options,
                                     char* dest,
                                     bool* needed_quoting) {
@@ -137,7 +137,7 @@
   return i;
 }
 
-size_t EscapeStringToString_NinjaPreformatted(const std::string_view& str,
+size_t EscapeStringToString_NinjaPreformatted(std::string_view str,
                                               char* dest) {
   // Only Ninja-escape $.
   size_t i = 0;
@@ -157,7 +157,7 @@
 // See:
 //   http://blogs.msdn.com/b/twistylittlepassagesallalike/archive/2011/04/23/everyone-quotes-arguments-the-wrong-way.aspx
 //   http://blogs.msdn.com/b/oldnewthing/archive/2010/09/17/10063629.aspx
-size_t EscapeStringToString_WindowsNinjaFork(const std::string_view& str,
+size_t EscapeStringToString_WindowsNinjaFork(std::string_view str,
                                              const EscapeOptions& options,
                                              char* dest,
                                              bool* needed_quoting) {
@@ -209,7 +209,7 @@
   return i;
 }
 
-size_t EscapeStringToString_PosixNinjaFork(const std::string_view& str,
+size_t EscapeStringToString_PosixNinjaFork(std::string_view str,
                                            const EscapeOptions& options,
                                            char* dest,
                                            bool* needed_quoting) {
@@ -240,7 +240,7 @@
 }
 
 // Escapes |str| into |dest| and returns the number of characters written.
-size_t EscapeStringToString(const std::string_view& str,
+size_t EscapeStringToString(std::string_view str,
                             const EscapeOptions& options,
                             char* dest,
                             bool* needed_quoting) {
@@ -286,7 +286,7 @@
 
 }  // namespace
 
-std::string EscapeString(const std::string_view& str,
+std::string EscapeString(std::string_view str,
                          const EscapeOptions& options,
                          bool* needed_quoting) {
   StackOrHeapBuffer dest(str.size() * kMaxEscapedCharsPerChar);
@@ -295,14 +295,14 @@
 }
 
 void EscapeStringToStream(std::ostream& out,
-                          const std::string_view& str,
+                          std::string_view str,
                           const EscapeOptions& options) {
   StackOrHeapBuffer dest(str.size() * kMaxEscapedCharsPerChar);
   out.write(dest, EscapeStringToString(str, options, dest, nullptr));
 }
 
 void EscapeJSONStringToStream(std::ostream& out,
-                              const std::string_view& str,
+                              std::string_view str,
                               const EscapeOptions& options) {
   std::string dest;
   bool needed_quoting = !options.inhibit_quoting;
diff --git a/src/gn/escape.h b/src/gn/escape.h
index 31f972e..57a723f 100644
--- a/src/gn/escape.h
+++ b/src/gn/escape.h
@@ -71,20 +71,20 @@
 // (if inhibit_quoting was set) quoted will be written to it. This value should
 // be initialized to false by the caller and will be written to only if it's
 // true (the common use-case is for chaining calls).
-std::string EscapeString(const std::string_view& str,
+std::string EscapeString(std::string_view str,
                          const EscapeOptions& options,
                          bool* needed_quoting);
 
 // Same as EscapeString but writes the results to the given stream, saving a
 // copy.
 void EscapeStringToStream(std::ostream& out,
-                          const std::string_view& str,
+                          std::string_view str,
                           const EscapeOptions& options);
 
 // Same as EscapeString but escape JSON string and writes the results to the
 // given stream, saving a copy.
 void EscapeJSONStringToStream(std::ostream& out,
-                              const std::string_view& str,
+                              std::string_view str,
                               const EscapeOptions& options);
 
 #endif  // TOOLS_GN_ESCAPE_H_
diff --git a/src/gn/file_writer.h b/src/gn/file_writer.h
index 0ae5061..9b7a01f 100644
--- a/src/gn/file_writer.h
+++ b/src/gn/file_writer.h
@@ -5,6 +5,8 @@
 #ifndef TOOLS_GN_FILE_WRITER_H_
 #define TOOLS_GN_FILE_WRITER_H_
 
+#include <string_view>
+
 #include "util/build_config.h"
 
 #if defined(OS_WIN)
diff --git a/src/gn/filesystem_utils.cc b/src/gn/filesystem_utils.cc
index 9eb713b..4906d56 100644
--- a/src/gn/filesystem_utils.cc
+++ b/src/gn/filesystem_utils.cc
@@ -81,8 +81,7 @@
 
 // Attempts to do a case and slash-insensitive comparison of two 8-bit Windows
 // paths.
-bool AreAbsoluteWindowsPathsEqual(const std::string_view& a,
-                                  const std::string_view& b) {
+bool AreAbsoluteWindowsPathsEqual(std::string_view a, std::string_view b) {
   if (a.size() != b.size())
     return false;
 
@@ -95,7 +94,7 @@
   return true;
 }
 
-bool DoesBeginWindowsDriveLetter(const std::string_view& path) {
+bool DoesBeginWindowsDriveLetter(std::string_view path) {
   if (path.size() < 3)
     return false;
 
@@ -200,7 +199,7 @@
   }
 }
 
-size_t AbsPathLenWithNoTrailingSlash(const std::string_view& path) {
+size_t AbsPathLenWithNoTrailingSlash(std::string_view path) {
   size_t len = path.size();
 #if defined(OS_WIN)
   size_t min_len = 3;
@@ -222,7 +221,7 @@
 #endif
 }
 
-base::FilePath UTF8ToFilePath(const std::string_view& sp) {
+base::FilePath UTF8ToFilePath(std::string_view sp) {
 #if defined(OS_WIN)
   return base::FilePath(base::UTF8ToUTF16(sp));
 #else
@@ -283,7 +282,7 @@
   path->resize(FindFilenameOffset(*path));
 }
 
-bool EndsWithSlash(const std::string_view s) {
+bool EndsWithSlash(std::string_view s) {
   return !s.empty() && IsSlash(s[s.size() - 1]);
 }
 
@@ -334,7 +333,7 @@
   return false;
 }
 
-bool IsPathAbsolute(const std::string_view& path) {
+bool IsPathAbsolute(std::string_view path) {
   if (path.empty())
     return false;
 
@@ -355,12 +354,12 @@
   return true;
 }
 
-bool IsPathSourceAbsolute(const std::string_view& path) {
+bool IsPathSourceAbsolute(std::string_view path) {
   return (path.size() >= 2 && path[0] == '/' && path[1] == '/');
 }
 
-bool MakeAbsolutePathRelativeIfPossible(const std::string_view& source_root,
-                                        const std::string_view& path,
+bool MakeAbsolutePathRelativeIfPossible(std::string_view source_root,
+                                        std::string_view path,
                                         std::string* dest) {
   DCHECK(IsPathAbsolute(source_root));
   DCHECK(IsPathAbsolute(path));
@@ -504,7 +503,7 @@
   return base::FilePath(base::JoinString(relative_components, separator));
 }
 
-void NormalizePath(std::string* path, const std::string_view& source_root) {
+void NormalizePath(std::string* path, std::string_view source_root) {
   char* pathbuf = path->empty() ? nullptr : &(*path)[0];
 
   // top_index is the first character we can modify in the path. Anything
@@ -707,7 +706,7 @@
 
 std::string RebasePath(const std::string& input,
                        const SourceDir& dest_dir,
-                       const std::string_view& source_root) {
+                       std::string_view source_root) {
   std::string ret;
   DCHECK(source_root.empty() ||
          !base::EndsWith(source_root, "/", base::CompareCase::SENSITIVE));
@@ -785,11 +784,10 @@
       .NormalizePathSeparatorsTo('/');
 }
 
-template <typename StringType>
-std::string ResolveRelative(const StringType& input,
+std::string ResolveRelative(std::string_view input,
                             const std::string& value,
                             bool as_file,
-                            const std::string_view& source_root) {
+                            std::string_view source_root) {
   std::string result;
 
   if (input.size() >= 2 && input[0] == '/' && input[1] == '/') {
@@ -850,17 +848,6 @@
   return result;
 }
 
-// Explicit template instantiation
-template std::string ResolveRelative(const std::string_view& input,
-                                     const std::string& value,
-                                     bool as_file,
-                                     const std::string_view& source_root);
-
-template std::string ResolveRelative(const std::string& input,
-                                     const std::string& value,
-                                     bool as_file,
-                                     const std::string_view& source_root);
-
 std::string DirectoryWithNoLastSlash(const SourceDir& dir) {
   std::string ret;
 
diff --git a/src/gn/filesystem_utils.h b/src/gn/filesystem_utils.h
index 830478a..9f21cff 100644
--- a/src/gn/filesystem_utils.h
+++ b/src/gn/filesystem_utils.h
@@ -20,7 +20,7 @@
 inline std::string FilePathToUTF8(const base::FilePath& path) {
   return FilePathToUTF8(path.value());
 }
-base::FilePath UTF8ToFilePath(const std::string_view& sp);
+base::FilePath UTF8ToFilePath(std::string_view sp);
 
 // Extensions -----------------------------------------------------------------
 
@@ -60,7 +60,7 @@
 }
 
 // Returns true if the given path ends with a slash.
-bool EndsWithSlash(const std::string_view s);
+bool EndsWithSlash(std::string_view s);
 
 // Path parts -----------------------------------------------------------------
 
@@ -96,12 +96,12 @@
 // Returns true if the input string is absolute. Double-slashes at the
 // beginning are treated as source-relative paths. On Windows, this handles
 // paths of both the native format: "C:/foo" and ours "/C:/foo"
-bool IsPathAbsolute(const std::string_view& path);
+bool IsPathAbsolute(std::string_view path);
 
 // Returns true if the input string is source-absolute. Source-absolute
 // paths begin with two forward slashes and resolve as if they are
 // relative to the source root.
-bool IsPathSourceAbsolute(const std::string_view& path);
+bool IsPathSourceAbsolute(std::string_view path);
 
 // Given an absolute path, checks to see if is it is inside the source root.
 // If it is, fills a source-absolute path into the given output and returns
@@ -112,8 +112,8 @@
 // ("/C:/"). The source root can end with a slash or not.
 //
 // Note that this does not attempt to normalize slashes in the output.
-bool MakeAbsolutePathRelativeIfPossible(const std::string_view& source_root,
-                                        const std::string_view& path,
+bool MakeAbsolutePathRelativeIfPossible(std::string_view source_root,
+                                        std::string_view path,
                                         std::string* dest);
 
 // Given two absolute paths |base| and |target|, returns a relative path to
@@ -134,7 +134,7 @@
 // a leading slash. Otherwise, |path| will retain its relativity. |source_root|
 // must not end with a slash.
 void NormalizePath(std::string* path,
-                   const std::string_view& source_root = std::string_view());
+                   std::string_view source_root = std::string_view());
 
 // Converts slashes to backslashes for Windows. Keeps the string unchanged
 // for other systems.
@@ -147,10 +147,9 @@
 // If supplied, the |source_root| parameter is the absolute path to
 // the source root and not end in a slash. Unless you know that the
 // inputs are always source relative, this should be supplied.
-std::string RebasePath(
-    const std::string& input,
-    const SourceDir& dest_dir,
-    const std::string_view& source_root = std::string_view());
+std::string RebasePath(const std::string& input,
+                       const SourceDir& dest_dir,
+                       std::string_view source_root = std::string_view());
 
 // Resolves a file or dir name (parameter input) relative to
 // value directory. Will return an empty SourceDir/File on error
@@ -165,11 +164,10 @@
 // If source_root is supplied, these functions will additionally handle the
 // case where the input is a system-absolute but still inside the source
 // tree. This is the case for some external tools.
-template <typename StringType>
-std::string ResolveRelative(const StringType& input,
+std::string ResolveRelative(std::string_view input,
                             const std::string& value,
                             bool as_file,
-                            const std::string_view& source_root);
+                            std::string_view source_root);
 
 // Resolves source file or directory relative to some given source root. Returns
 // an empty file path on error.
diff --git a/src/gn/generated_file_target_generator.cc b/src/gn/generated_file_target_generator.cc
index 2506f19..0a92122 100644
--- a/src/gn/generated_file_target_generator.cc
+++ b/src/gn/generated_file_target_generator.cc
@@ -68,7 +68,7 @@
 }
 
 bool GeneratedFileTargetGenerator::IsMetadataCollectionTarget(
-    const std::string_view& variable,
+    std::string_view variable,
     const ParseNode* origin) {
   if (contents_defined_) {
     *err_ =
diff --git a/src/gn/generated_file_target_generator.h b/src/gn/generated_file_target_generator.h
index dcc4814..c10c600 100644
--- a/src/gn/generated_file_target_generator.h
+++ b/src/gn/generated_file_target_generator.h
@@ -5,6 +5,8 @@
 #ifndef TOOLS_GN_GENERATED_FILE_TARGET_GENERATOR_H_
 #define TOOLS_GN_GENERATED_FILE_TARGET_GENERATOR_H_
 
+#include <string_view>
+
 #include "base/macros.h"
 #include "gn/target.h"
 #include "gn/target_generator.h"
@@ -35,7 +37,7 @@
   // it is okay to set metadata collection variables on this target.
   //
   // Should be called before FillContents().
-  bool IsMetadataCollectionTarget(const std::string_view& variable,
+  bool IsMetadataCollectionTarget(std::string_view variable,
                                   const ParseNode* origin);
 
   bool contents_defined_ = false;
diff --git a/src/gn/input_conversion.cc b/src/gn/input_conversion.cc
index e82a939..73e8dcc 100644
--- a/src/gn/input_conversion.cc
+++ b/src/gn/input_conversion.cc
@@ -108,7 +108,7 @@
   return ret;
 }
 
-bool IsIdentifier(const std::string_view& buffer) {
+bool IsIdentifier(std::string_view buffer) {
   DCHECK(buffer.size() > 0);
   if (!Tokenizer::IsIdentifierFirstChar(buffer[0]))
     return false;
diff --git a/src/gn/label.cc b/src/gn/label.cc
index 173c3d5..c78b00e 100644
--- a/src/gn/label.cc
+++ b/src/gn/label.cc
@@ -29,8 +29,8 @@
 // used. The value is used only for generating error messages.
 bool ComputeBuildLocationFromDep(const Value& input_value,
                                  const SourceDir& current_dir,
-                                 const std::string_view& source_root,
-                                 const std::string_view& input,
+                                 std::string_view source_root,
+                                 std::string_view input,
                                  SourceDir* result,
                                  Err* err) {
   // No rule, use the current location.
@@ -50,7 +50,7 @@
 // error messages.
 bool ComputeTargetNameFromDep(const Value& input_value,
                               const SourceDir& computed_location,
-                              const std::string_view& input,
+                              std::string_view input,
                               StringAtom* result,
                               Err* err) {
   if (!input.empty()) {
@@ -88,10 +88,10 @@
 // Returns true on success. On failure, the out* variables might be written to
 // but shouldn't be used.
 bool Resolve(const SourceDir& current_dir,
-             const std::string_view& source_root,
+             std::string_view source_root,
              const Label& current_toolchain,
              const Value& original_value,
-             const std::string_view& input,
+             std::string_view input,
              SourceDir* out_dir,
              StringAtom* out_name,
              SourceDir* out_toolchain_dir,
@@ -256,22 +256,21 @@
 Label::Label() : hash_(ComputeHash()) {}
 
 Label::Label(const SourceDir& dir,
-             const std::string_view& name,
+             std::string_view name,
              const SourceDir& toolchain_dir,
-             const std::string_view& toolchain_name)
+             std::string_view toolchain_name)
     : dir_(dir),
       name_(StringAtom(name)),
       toolchain_dir_(toolchain_dir),
       toolchain_name_(StringAtom(toolchain_name)),
       hash_(ComputeHash()) {}
 
-Label::Label(const SourceDir& dir, const std::string_view& name)
-    : dir_(dir), name_(StringAtom(name)),
-      hash_(ComputeHash()) {}
+Label::Label(const SourceDir& dir, std::string_view name)
+    : dir_(dir), name_(StringAtom(name)), hash_(ComputeHash()) {}
 
 // static
 Label Label::Resolve(const SourceDir& current_dir,
-                     const std::string_view& source_root,
+                     std::string_view source_root,
                      const Label& current_toolchain,
                      const Value& input,
                      Err* err) {
diff --git a/src/gn/label.h b/src/gn/label.h
index dc9813b..1458fcc 100644
--- a/src/gn/label.h
+++ b/src/gn/label.h
@@ -5,6 +5,7 @@
 #ifndef TOOLS_GN_LABEL_H_
 #define TOOLS_GN_LABEL_H_
 
+#include <string_view>
 #include <tuple>
 
 #include <stddef.h>
@@ -25,18 +26,18 @@
   // Makes a label given an already-separated out path and name.
   // See also Resolve().
   Label(const SourceDir& dir,
-        const std::string_view& name,
+        std::string_view name,
         const SourceDir& toolchain_dir,
-        const std::string_view& toolchain_name);
+        std::string_view toolchain_name);
 
   // Makes a label with an empty toolchain.
-  Label(const SourceDir& dir, const std::string_view& name);
+  Label(const SourceDir& dir, std::string_view name);
 
   // Resolves a string from a build file that may be relative to the
   // current directory into a fully qualified label. On failure returns an
   // is_null() label and sets the error.
   static Label Resolve(const SourceDir& current_dir,
-                       const std::string_view& source_root,
+                       std::string_view source_root,
                        const Label& current_toolchain,
                        const Value& input,
                        Err* err);
diff --git a/src/gn/label_pattern.cc b/src/gn/label_pattern.cc
index 35235e5..9a21829 100644
--- a/src/gn/label_pattern.cc
+++ b/src/gn/label_pattern.cc
@@ -53,7 +53,7 @@
 
 LabelPattern::LabelPattern(Type type,
                            const SourceDir& dir,
-                           const std::string_view& name,
+                           std::string_view name,
                            const Label& toolchain_label)
     : toolchain_(toolchain_label), type_(type), dir_(dir), name_(name) {}
 
@@ -63,7 +63,7 @@
 
 // static
 LabelPattern LabelPattern::GetPattern(const SourceDir& current_dir,
-                                      const std::string_view& source_root,
+                                      std::string_view source_root,
                                       const Value& value,
                                       Err* err) {
   if (!value.VerifyTypeIs(Value::STRING, err))
diff --git a/src/gn/label_pattern.h b/src/gn/label_pattern.h
index f40750e..fbb11fa 100644
--- a/src/gn/label_pattern.h
+++ b/src/gn/label_pattern.h
@@ -30,7 +30,7 @@
   LabelPattern();
   LabelPattern(Type type,
                const SourceDir& dir,
-               const std::string_view& name,
+               std::string_view name,
                const Label& toolchain_label);
   LabelPattern(const LabelPattern& other);
   ~LabelPattern();
@@ -38,7 +38,7 @@
   // Converts the given input string to a pattern. This does special stuff
   // to treat the pattern as a label. Sets the error on failure.
   static LabelPattern GetPattern(const SourceDir& current_dir,
-                                 const std::string_view& source_root,
+                                 std::string_view source_root,
                                  const Value& value,
                                  Err* err);
 
diff --git a/src/gn/lib_file.cc b/src/gn/lib_file.cc
index cbb67f1..6723a18 100644
--- a/src/gn/lib_file.cc
+++ b/src/gn/lib_file.cc
@@ -8,7 +8,7 @@
 
 LibFile::LibFile(const SourceFile& source_file) : source_file_(source_file) {}
 
-LibFile::LibFile(const std::string_view& lib_name)
+LibFile::LibFile(std::string_view lib_name)
     : name_(lib_name.data(), lib_name.size()) {
   DCHECK(!lib_name.empty());
 }
diff --git a/src/gn/lib_file.h b/src/gn/lib_file.h
index 47952f8..575a9e9 100644
--- a/src/gn/lib_file.h
+++ b/src/gn/lib_file.h
@@ -19,7 +19,7 @@
  public:
   LibFile() = default;
 
-  explicit LibFile(const std::string_view& lib_name);
+  explicit LibFile(std::string_view lib_name);
   explicit LibFile(const SourceFile& source_file);
 
   bool is_source_file() const { return name_.empty(); }
diff --git a/src/gn/ninja_build_writer.cc b/src/gn/ninja_build_writer.cc
index e7852aa..28e2fa6 100644
--- a/src/gn/ninja_build_writer.cc
+++ b/src/gn/ninja_build_writer.cc
@@ -629,7 +629,7 @@
 }
 
 void NinjaBuildWriter::WritePhonyRule(const Target* target,
-                                      const std::string& phony_name) {
+                                      std::string_view phony_name) {
   EscapeOptions ninja_escape;
   ninja_escape.mode = ESCAPE_NINJA;
 
diff --git a/src/gn/ninja_build_writer.h b/src/gn/ninja_build_writer.h
index 9f41a38..b5e9e6a 100644
--- a/src/gn/ninja_build_writer.h
+++ b/src/gn/ninja_build_writer.h
@@ -7,6 +7,7 @@
 
 #include <iosfwd>
 #include <map>
+#include <string_view>
 #include <unordered_map>
 #include <vector>
 
@@ -56,7 +57,7 @@
   bool WriteSubninjas(Err* err);
   bool WritePhonyAndAllRules(Err* err);
 
-  void WritePhonyRule(const Target* target, const std::string& phony_name);
+  void WritePhonyRule(const Target* target, std::string_view phony_name);
 
   const BuildSettings* build_settings_;
 
diff --git a/src/gn/ninja_target_command_util.h b/src/gn/ninja_target_command_util.h
index d9d30bc..00f9a77 100644
--- a/src/gn/ninja_target_command_util.h
+++ b/src/gn/ninja_target_command_util.h
@@ -5,6 +5,8 @@
 #ifndef TOOLS_GN_NINJA_TARGET_COMMAND_WRITER_H_
 #define TOOLS_GN_NINJA_TARGET_COMMAND_WRITER_H_
 
+#include <string_view>
+
 #include "base/json/string_escape.h"
 #include "gn/config_values_extractors.h"
 #include "gn/escape.h"
diff --git a/src/gn/parse_tree.cc b/src/gn/parse_tree.cc
index 9ab28b5..83452d0 100644
--- a/src/gn/parse_tree.cc
+++ b/src/gn/parse_tree.cc
@@ -221,7 +221,7 @@
 }
 
 base::Value ParseNode::CreateJSONNode(const char* type,
-                                      const std::string_view& value,
+                                      std::string_view value,
                                       LocationRange location) const {
   base::Value dict(base::Value::Type::DICTIONARY);
   dict.SetKey(kJsonNodeType, base::Value(type));
diff --git a/src/gn/parse_tree.h b/src/gn/parse_tree.h
index 9ffacc2..57d82e3 100644
--- a/src/gn/parse_tree.h
+++ b/src/gn/parse_tree.h
@@ -8,6 +8,7 @@
 #include <stddef.h>
 
 #include <memory>
+#include <string_view>
 #include <utility>
 #include <vector>
 
@@ -115,7 +116,7 @@
   // given type (and value).
   base::Value CreateJSONNode(const char* type, LocationRange location) const;
   base::Value CreateJSONNode(const char* type,
-                             const std::string_view& value,
+                             std::string_view value,
                              LocationRange location) const;
 
  private:
diff --git a/src/gn/path_output.cc b/src/gn/path_output.cc
index c89e061..d2886d7 100644
--- a/src/gn/path_output.cc
+++ b/src/gn/path_output.cc
@@ -11,7 +11,7 @@
 #include "util/build_config.h"
 
 PathOutput::PathOutput(const SourceDir& current_dir,
-                       const std::string_view& source_root,
+                       std::string_view source_root,
                        EscapingMode escaping)
     : current_dir_(current_dir) {
   inverse_current_dir_ = RebasePath("//", current_dir, source_root);
@@ -129,7 +129,7 @@
 }
 
 void PathOutput::WriteSourceRelativeString(std::ostream& out,
-                                           const std::string_view& str) const {
+                                           std::string_view str) const {
   if (options_.mode == ESCAPE_NINJA_COMMAND) {
     // Shell escaping needs an intermediate string since it may end up
     // quoting the whole thing.
@@ -150,8 +150,7 @@
   }
 }
 
-void PathOutput::WritePathStr(std::ostream& out,
-                              const std::string_view& str) const {
+void PathOutput::WritePathStr(std::ostream& out, std::string_view str) const {
   DCHECK(str.size() > 0 && str[0] == '/');
 
   if (str.substr(0, current_dir_.value().size()) ==
diff --git a/src/gn/path_output.h b/src/gn/path_output.h
index 729ba98..e04d236 100644
--- a/src/gn/path_output.h
+++ b/src/gn/path_output.h
@@ -35,7 +35,7 @@
   };
 
   PathOutput(const SourceDir& current_dir,
-             const std::string_view& source_root,
+             std::string_view source_root,
              EscapingMode escaping);
   ~PathOutput();
 
@@ -72,13 +72,12 @@
 
   // Backend for WriteFile and WriteDir. This appends the given file or
   // directory string to the file.
-  void WritePathStr(std::ostream& out, const std::string_view& str) const;
+  void WritePathStr(std::ostream& out, std::string_view str) const;
 
  private:
   // Takes the given string and writes it out, appending to the inverse
   // current dir. This assumes leading slashes have been trimmed.
-  void WriteSourceRelativeString(std::ostream& out,
-                                 const std::string_view& str) const;
+  void WriteSourceRelativeString(std::ostream& out, std::string_view str) const;
 
   SourceDir current_dir_;
 
diff --git a/src/gn/rust_project_writer.cc b/src/gn/rust_project_writer.cc
index 117442f..ee62479 100644
--- a/src/gn/rust_project_writer.cc
+++ b/src/gn/rust_project_writer.cc
@@ -181,8 +181,8 @@
 
 // Add each of the crates a sysroot has, including their dependencies.
 void AddSysrootCrate(const BuildSettings* build_settings,
-                     const std::string_view crate,
-                     const std::string_view current_sysroot,
+                     std::string_view crate,
+                     std::string_view current_sysroot,
                      SysrootCrateIndexMap& sysroot_crate_lookup,
                      CrateList& crate_list) {
   if (sysroot_crate_lookup.find(crate) != sysroot_crate_lookup.end()) {
@@ -227,7 +227,7 @@
 
 // Add the given sysroot to the project, if it hasn't already been added.
 void AddSysroot(const BuildSettings* build_settings,
-                const std::string_view sysroot,
+                std::string_view sysroot,
                 SysrootIndexMap& sysroot_lookup,
                 CrateList& crate_list) {
   // If this sysroot is already in the lookup, we don't add it again.
@@ -244,7 +244,7 @@
 
 void AddSysrootDependencyToCrate(Crate* crate,
                                  const SysrootCrateIndexMap& sysroot,
-                                 const std::string_view crate_name) {
+                                 std::string_view crate_name) {
   if (const auto crate_idx = sysroot.find(crate_name);
       crate_idx != sysroot.end()) {
     crate->AddDependency(crate_idx->second, std::string(crate_name));
diff --git a/src/gn/rust_project_writer_helpers.h b/src/gn/rust_project_writer_helpers.h
index 0020e2c..a63ded1 100644
--- a/src/gn/rust_project_writer_helpers.h
+++ b/src/gn/rust_project_writer_helpers.h
@@ -9,6 +9,7 @@
 #include <optional>
 #include <sstream>
 #include <string>
+#include <string_view>
 #include <tuple>
 #include <unordered_map>
 #include <vector>
@@ -104,7 +105,7 @@
 // Add all of the crates for a sysroot (path) to the rust_project ostream.
 // Add the given sysroot to the project, if it hasn't already been added.
 void AddSysroot(const BuildSettings* build_settings,
-                const std::string_view sysroot,
+                std::string_view sysroot,
                 SysrootIndexMap& sysroot_lookup,
                 CrateList& crate_list);
 
diff --git a/src/gn/rust_tool.h b/src/gn/rust_tool.h
index 6a4fdf7..8eec377 100644
--- a/src/gn/rust_tool.h
+++ b/src/gn/rust_tool.h
@@ -6,6 +6,7 @@
 #define TOOLS_GN_RUST_TOOL_H_
 
 #include <string>
+#include <string_view>
 
 #include "base/logging.h"
 #include "base/macros.h"
diff --git a/src/gn/scope.cc b/src/gn/scope.cc
index 7e92766..05b0995 100644
--- a/src/gn/scope.cc
+++ b/src/gn/scope.cc
@@ -21,7 +21,7 @@
 // Returns true if this variable name should be considered private. Private
 // values start with an underscore, and are not imported from "gni" files
 // when processing an import.
-bool IsPrivateVar(const std::string_view& name) {
+bool IsPrivateVar(std::string_view name) {
   return name.empty() || name[0] == '_';
 }
 
@@ -74,13 +74,12 @@
   return !values_.empty();
 }
 
-const Value* Scope::GetValue(const std::string_view& ident,
-                             bool counts_as_used) {
+const Value* Scope::GetValue(std::string_view ident, bool counts_as_used) {
   const Scope* found_in_scope = nullptr;
   return GetValueWithScope(ident, counts_as_used, &found_in_scope);
 }
 
-const Value* Scope::GetValueWithScope(const std::string_view& ident,
+const Value* Scope::GetValueWithScope(std::string_view ident,
                                       bool counts_as_used,
                                       const Scope** found_in_scope) {
   // First check for programmatically-provided values.
@@ -110,7 +109,7 @@
   return nullptr;
 }
 
-Value* Scope::GetMutableValue(const std::string_view& ident,
+Value* Scope::GetMutableValue(std::string_view ident,
                               SearchNested search_mode,
                               bool counts_as_used) {
   // Don't do programmatic values, which are not mutable.
@@ -129,7 +128,7 @@
   return nullptr;
 }
 
-std::string_view Scope::GetStorageKey(const std::string_view& ident) const {
+std::string_view Scope::GetStorageKey(std::string_view ident) const {
   RecordMap::const_iterator found = values_.find(ident);
   if (found != values_.end())
     return found->first;
@@ -140,12 +139,12 @@
   return std::string_view();
 }
 
-const Value* Scope::GetValue(const std::string_view& ident) const {
+const Value* Scope::GetValue(std::string_view ident) const {
   const Scope* found_in_scope = nullptr;
   return GetValueWithScope(ident, &found_in_scope);
 }
 
-const Value* Scope::GetValueWithScope(const std::string_view& ident,
+const Value* Scope::GetValueWithScope(std::string_view ident,
                                       const Scope** found_in_scope) const {
   RecordMap::const_iterator found = values_.find(ident);
   if (found != values_.end()) {
@@ -157,7 +156,7 @@
   return nullptr;
 }
 
-Value* Scope::SetValue(const std::string_view& ident,
+Value* Scope::SetValue(std::string_view ident,
                        Value v,
                        const ParseNode* set_node) {
   Record& r = values_[ident];  // Clears any existing value.
@@ -166,7 +165,7 @@
   return &r.value;
 }
 
-void Scope::RemoveIdentifier(const std::string_view& ident) {
+void Scope::RemoveIdentifier(std::string_view ident) {
   RecordMap::iterator found = values_.find(ident);
   if (found != values_.end())
     values_.erase(found);
@@ -203,7 +202,7 @@
   return nullptr;
 }
 
-void Scope::MarkUsed(const std::string_view& ident) {
+void Scope::MarkUsed(std::string_view ident) {
   RecordMap::iterator found = values_.find(ident);
   if (found == values_.end()) {
     NOTREACHED();
@@ -227,7 +226,7 @@
   }
 }
 
-void Scope::MarkUnused(const std::string_view& ident) {
+void Scope::MarkUnused(std::string_view ident) {
   RecordMap::iterator found = values_.find(ident);
   if (found == values_.end()) {
     NOTREACHED();
@@ -236,7 +235,7 @@
   found->second.used = false;
 }
 
-bool Scope::IsSetButUnused(const std::string_view& ident) const {
+bool Scope::IsSetButUnused(std::string_view ident) const {
   RecordMap::const_iterator found = values_.find(ident);
   if (found != values_.end()) {
     if (!found->second.used) {
@@ -298,7 +297,7 @@
                                 Err* err) const {
   // Values.
   for (const auto& pair : values_) {
-    const std::string_view& current_name = pair.first;
+    const std::string_view current_name = pair.first;
     if (options.skip_private_vars && IsPrivateVar(current_name))
       continue;  // Skip this private var.
     if (!options.excluded_values.empty() &&
diff --git a/src/gn/scope.h b/src/gn/scope.h
index e6a2f5f..341cefa 100644
--- a/src/gn/scope.h
+++ b/src/gn/scope.h
@@ -8,6 +8,7 @@
 #include <map>
 #include <memory>
 #include <set>
+#include <string_view>
 #include <unordered_map>
 #include <utility>
 #include <vector>
@@ -58,8 +59,7 @@
 
     // Returns a non-null value if the given value can be programmatically
     // generated, or NULL if there is none.
-    virtual const Value* GetProgrammaticValue(
-        const std::string_view& ident) = 0;
+    virtual const Value* GetProgrammaticValue(std::string_view ident) = 0;
 
    protected:
     Scope* scope_;
@@ -135,11 +135,11 @@
   // found_in_scope is set to the scope that contains the definition of the
   // ident. If the value was provided programmatically (like host_cpu),
   // found_in_scope will be set to null.
-  const Value* GetValue(const std::string_view& ident, bool counts_as_used);
-  const Value* GetValue(const std::string_view& ident) const;
-  const Value* GetValueWithScope(const std::string_view& ident,
+  const Value* GetValue(std::string_view ident, bool counts_as_used);
+  const Value* GetValue(std::string_view ident) const;
+  const Value* GetValueWithScope(std::string_view ident,
                                  const Scope** found_in_scope) const;
-  const Value* GetValueWithScope(const std::string_view& ident,
+  const Value* GetValueWithScope(std::string_view ident,
                                  bool counts_as_used,
                                  const Scope** found_in_scope);
 
@@ -165,7 +165,7 @@
   //    }
   // The 6 should get set on the nested scope rather than modify the value
   // in the outer one.
-  Value* GetMutableValue(const std::string_view& ident,
+  Value* GetMutableValue(std::string_view ident,
                          SearchNested search_mode,
                          bool counts_as_used);
 
@@ -175,18 +175,16 @@
   // is static and won't be deleted for the life of the program, so it can be
   // used as keys in places that may outlive a temporary. It will return an
   // empty string for programmatic and nonexistent values.
-  std::string_view GetStorageKey(const std::string_view& ident) const;
+  std::string_view GetStorageKey(std::string_view ident) const;
 
   // The set_node indicates the statement that caused the set, for displaying
   // errors later. Returns a pointer to the value in the current scope (a copy
   // is made for storage).
-  Value* SetValue(const std::string_view& ident,
-                  Value v,
-                  const ParseNode* set_node);
+  Value* SetValue(std::string_view ident, Value v, const ParseNode* set_node);
 
   // Removes the value with the given identifier if it exists on the current
   // scope. This does not search recursive scopes. Does nothing if not found.
-  void RemoveIdentifier(const std::string_view& ident);
+  void RemoveIdentifier(std::string_view ident);
 
   // Removes from this scope all identifiers and templates that are considered
   // private.
@@ -200,17 +198,17 @@
   const Template* GetTemplate(const std::string& name) const;
 
   // Marks the given identifier as (un)used in the current scope.
-  void MarkUsed(const std::string_view& ident);
+  void MarkUsed(std::string_view ident);
   void MarkAllUsed();
   void MarkAllUsed(const std::set<std::string>& excluded_values);
-  void MarkUnused(const std::string_view& ident);
+  void MarkUnused(std::string_view ident);
 
   // Checks to see if the scope has a var set that hasn't been used. This is
   // called before replacing the var with a different one. It does not check
   // containing scopes.
   //
   // If the identifier is present but hasnn't been used, return true.
-  bool IsSetButUnused(const std::string_view& ident) const;
+  bool IsSetButUnused(std::string_view ident) const;
 
   // Checks the scope to see if any values were set but not used, and fills in
   // the error and returns false if they were.
diff --git a/src/gn/scope_per_file_provider.cc b/src/gn/scope_per_file_provider.cc
index 3110a8f..9332c40 100644
--- a/src/gn/scope_per_file_provider.cc
+++ b/src/gn/scope_per_file_provider.cc
@@ -20,7 +20,7 @@
 ScopePerFileProvider::~ScopePerFileProvider() = default;
 
 const Value* ScopePerFileProvider::GetProgrammaticValue(
-    const std::string_view& ident) {
+    std::string_view ident) {
   if (ident == variables::kCurrentToolchain)
     return GetCurrentToolchain();
   if (ident == variables::kDefaultToolchain)
diff --git a/src/gn/scope_per_file_provider.h b/src/gn/scope_per_file_provider.h
index 228bac3..3daa4fb 100644
--- a/src/gn/scope_per_file_provider.h
+++ b/src/gn/scope_per_file_provider.h
@@ -6,6 +6,7 @@
 #define TOOLS_GN_SCOPE_PER_FILE_PROVIDER_H_
 
 #include <memory>
+#include <string_view>
 
 #include "base/macros.h"
 #include "gn/scope.h"
@@ -21,7 +22,7 @@
   ~ScopePerFileProvider() override;
 
   // ProgrammaticProvider implementation.
-  const Value* GetProgrammaticValue(const std::string_view& ident) override;
+  const Value* GetProgrammaticValue(std::string_view ident) override;
 
  private:
   const Value* GetCurrentToolchain();
diff --git a/src/gn/source_dir.cc b/src/gn/source_dir.cc
index ce92cf2..f34a637 100644
--- a/src/gn/source_dir.cc
+++ b/src/gn/source_dir.cc
@@ -13,7 +13,7 @@
 
 namespace {
 
-void AssertValueSourceDirString(const std::string_view s) {
+void AssertValueSourceDirString(std::string_view s) {
   if (!s.empty()) {
 #if defined(OS_WIN)
     DCHECK(s[0] == '/' ||
@@ -27,10 +27,9 @@
 
 // Validates input value (input_value) and sets proper error message.
 // Note: Parameter blame_input is used only for generating error message.
-template <typename StringType>
 bool ValidateResolveInput(bool as_file,
                           const Value& blame_input_value,
-                          const StringType& input_value,
+                          std::string_view input_value,
                           Err* err) {
   if (as_file) {
     // It's an error to resolve an empty string or one that is a directory
@@ -57,7 +56,7 @@
   return true;
 }
 
-static StringAtom SourceDirStringAtom(const std::string_view s) {
+static StringAtom SourceDirStringAtom(std::string_view s) {
   if (EndsWithSlash(s)) {  // Avoid allocation when possible.
     AssertValueSourceDirString(s);
     return StringAtom(s);
@@ -73,44 +72,49 @@
 
 }  // namespace
 
-SourceDir::SourceDir(const std::string_view s)
-    : value_(SourceDirStringAtom(s)) {}
+SourceDir::SourceDir(std::string_view s) : value_(SourceDirStringAtom(s)) {}
 
-template <typename StringType>
-std::string SourceDir::ResolveRelativeAs(
-    bool as_file,
-    const Value& blame_input_value,
-    const StringType& input_value,
-    Err* err,
-    const std::string_view& source_root) const {
-  if (!ValidateResolveInput<StringType>(as_file, blame_input_value, input_value,
-                                        err)) {
+std::string SourceDir::ResolveRelativeAs(bool as_file,
+                                         const Value& blame_input_value,
+                                         std::string_view input_value,
+                                         Err* err,
+                                         std::string_view source_root) const {
+  if (!ValidateResolveInput(as_file, blame_input_value, input_value, err)) {
     return std::string();
   }
   return ResolveRelative(input_value, value_.str(), as_file, source_root);
 }
 
-SourceFile SourceDir::ResolveRelativeFile(
-    const Value& p,
-    Err* err,
-    const std::string_view& source_root) const {
+SourceFile SourceDir::ResolveRelativeFile(const Value& p,
+                                          Err* err,
+                                          std::string_view source_root) const {
   SourceFile ret;
 
   if (!p.VerifyTypeIs(Value::STRING, err))
     return ret;
 
   const std::string& input_string = p.string_value();
-  if (!ValidateResolveInput<std::string>(true, p, input_string, err))
+  if (!ValidateResolveInput(true, p, input_string, err))
     return ret;
 
   ret.SetValue(ResolveRelative(input_string, value_.str(), true, source_root));
   return ret;
 }
 
+SourceDir SourceDir::ResolveRelativeDir(const Value& blame_input_value,
+                                        std::string_view input_value,
+                                        Err* err,
+                                        std::string_view source_root) const {
+  SourceDir ret;
+  ret.value_ = StringAtom(ResolveRelativeAs(false, blame_input_value,
+                                            input_value, err, source_root));
+  return ret;
+}
+
 std::string SourceDir::ResolveRelativeAs(bool as_file,
                                          const Value& v,
                                          Err* err,
-                                         const std::string_view& source_root,
+                                         std::string_view source_root,
                                          const std::string* v_value) const {
   if (!v.VerifyTypeIs(Value::STRING, err))
     return std::string();
@@ -125,31 +129,15 @@
   return result;
 }
 
-SourceDir SourceDir::ResolveRelativeDir(
-    const Value& v,
-    Err* err,
-    const std::string_view& source_root) const {
+SourceDir SourceDir::ResolveRelativeDir(const Value& v,
+                                        Err* err,
+                                        std::string_view source_root) const {
   if (!v.VerifyTypeIs(Value::STRING, err))
     return SourceDir();
 
-  return ResolveRelativeDir<std::string>(v, v.string_value(), err, source_root);
+  return ResolveRelativeDir(v, v.string_value(), err, source_root);
 }
 
 base::FilePath SourceDir::Resolve(const base::FilePath& source_root) const {
   return ResolvePath(value_.str(), false, source_root);
 }
-
-// Explicit template instantiation
-template std::string SourceDir::ResolveRelativeAs(
-    bool as_file,
-    const Value& blame_input_value,
-    const std::string& input_value,
-    Err* err,
-    const std::string_view& source_root) const;
-
-template std::string SourceDir::ResolveRelativeAs(
-    bool as_file,
-    const Value& blame_input_value,
-    const std::string_view& input_value,
-    Err* err,
-    const std::string_view& source_root) const;
diff --git a/src/gn/source_dir.h b/src/gn/source_dir.h
index 5c436f4..d8b3c28 100644
--- a/src/gn/source_dir.h
+++ b/src/gn/source_dir.h
@@ -31,7 +31,7 @@
  public:
   SourceDir() = default;
 
-  SourceDir(const std::string_view s);
+  SourceDir(std::string_view s);
 
   // Resolves a file or dir name (based on as_file parameter) relative
   // to this source directory. Will return an empty string on error
@@ -48,44 +48,37 @@
       bool as_file,
       const Value& v,
       Err* err,
-      const std::string_view& source_root = std::string_view(),
+      std::string_view source_root = std::string_view(),
       const std::string* v_value = nullptr) const;
 
   // Like ResolveRelativeAs above, but allows one to produce result
   // without overhead for string conversion (on input value).
-  template <typename StringType>
   std::string ResolveRelativeAs(
       bool as_file,
       const Value& blame_input_value,
-      const StringType& input_value,
+      std::string_view input_value,
       Err* err,
-      const std::string_view& source_root = std::string_view()) const;
+      std::string_view source_root = std::string_view()) const;
 
   // Wrapper for ResolveRelativeAs.
   SourceFile ResolveRelativeFile(
       const Value& p,
       Err* err,
-      const std::string_view& source_root = std::string_view()) const;
+      std::string_view source_root = std::string_view()) const;
 
   // Wrapper for ResolveRelativeAs.
-  template <typename StringType>
   SourceDir ResolveRelativeDir(
       const Value& blame_input_value,
-      const StringType& input_value,
+      std::string_view input_value,
       Err* err,
-      const std::string_view& source_root = std::string_view()) const {
-    SourceDir ret;
-    ret.value_ = StringAtom(ResolveRelativeAs<StringType>(
-        false, blame_input_value, input_value, err, source_root));
-    return ret;
-  }
+      std::string_view source_root = std::string_view()) const;
 
   // Wrapper for ResolveRelativeDir where input_value equals to
   // v.string_value().
   SourceDir ResolveRelativeDir(
       const Value& v,
       Err* err,
-      const std::string_view& source_root = std::string_view()) const;
+      std::string_view source_root = std::string_view()) const;
 
   // Resolves this source file relative to some given source root. Returns
   // an empty file path on error.
diff --git a/src/gn/string_atom.cc b/src/gn/string_atom.cc
index fe1ef73..b4cd9f7 100644
--- a/src/gn/string_atom.cc
+++ b/src/gn/string_atom.cc
@@ -163,7 +163,7 @@
    public:
     // Init the n-th string in the slab with |str|.
     // Return its location as well.
-    std::string* init(size_t index, const std::string_view& str) {
+    std::string* init(size_t index, std::string_view str) {
       std::string* result = &items_[index].str;
       new (result) std::string(str);
       return result;
diff --git a/src/gn/string_atom.h b/src/gn/string_atom.h
index 29d4e41..541399e 100644
--- a/src/gn/string_atom.h
+++ b/src/gn/string_atom.h
@@ -7,6 +7,7 @@
 
 #include <functional>
 #include <string>
+#include <string_view>
 
 // A StringAtom models a pointer to a globally unique constant string.
 //
diff --git a/src/gn/string_output_buffer.h b/src/gn/string_output_buffer.h
index d2a42c9..5e89250 100644
--- a/src/gn/string_output_buffer.h
+++ b/src/gn/string_output_buffer.h
@@ -9,6 +9,7 @@
 #include <memory>
 #include <streambuf>
 #include <string>
+#include <string_view>
 #include <vector>
 
 namespace base {
diff --git a/src/gn/string_utils.cc b/src/gn/string_utils.cc
index b785e75..bff9e8f 100644
--- a/src/gn/string_utils.cc
+++ b/src/gn/string_utils.cc
@@ -287,8 +287,8 @@
   return true;
 }
 
-size_t EditDistance(const std::string_view& s1,
-                    const std::string_view& s2,
+size_t EditDistance(std::string_view s1,
+                    std::string_view s2,
                     size_t max_edit_distance) {
   // The algorithm implemented below is the "classic"
   // dynamic-programming algorithm for computing the Levenshtein
@@ -329,7 +329,7 @@
   return row[n];
 }
 
-std::string_view SpellcheckString(const std::string_view& text,
+std::string_view SpellcheckString(std::string_view text,
                                   const std::vector<std::string_view>& words) {
   const size_t kMaxValidEditDistance = 3u;
 
diff --git a/src/gn/string_utils.h b/src/gn/string_utils.h
index a98a485..4b3a69c 100644
--- a/src/gn/string_utils.h
+++ b/src/gn/string_utils.h
@@ -14,7 +14,7 @@
 class Token;
 class Value;
 
-inline std::string operator+(const std::string& a, const std::string_view& b) {
+inline std::string operator+(const std::string& a, std::string_view b) {
   std::string ret;
   ret.reserve(a.size() + b.size());
   ret.assign(a);
@@ -22,7 +22,7 @@
   return ret;
 }
 
-inline std::string operator+(const std::string_view& a, const std::string& b) {
+inline std::string operator+(std::string_view a, const std::string& b) {
   std::string ret;
   ret.reserve(a.size() + b.size());
   ret.assign(a.data(), a.size());
@@ -40,14 +40,14 @@
 // Returns the minimum number of inserts, deleted, and replacements of
 // characters needed to transform s1 to s2, or max_edit_distance + 1 if
 // transforming s1 into s2 isn't possible in at most max_edit_distance steps.
-size_t EditDistance(const std::string_view& s1,
-                    const std::string_view& s2,
+size_t EditDistance(std::string_view s1,
+                    std::string_view s2,
                     size_t max_edit_distance);
 
 // Given a string |text| and a vector of correctly-spelled strings |words|,
 // returns the first string in |words| closest to |text|, or an empty
 // std::string_view if none of the strings in |words| is close.
-std::string_view SpellcheckString(const std::string_view& text,
+std::string_view SpellcheckString(std::string_view text,
                                   const std::vector<std::string_view>& words);
 
 // Reads stdin until end-of-data and returns what it read.
diff --git a/src/gn/token.cc b/src/gn/token.cc
index 3af9c48..ea5139f 100644
--- a/src/gn/token.cc
+++ b/src/gn/token.cc
@@ -9,12 +9,11 @@
 
 Token::Token() : type_(INVALID), value_() {}
 
-Token::Token(const Location& location, Type t, const std::string_view& v)
+Token::Token(const Location& location, Type t, std::string_view v)
     : type_(t), value_(v), location_(location) {}
 
 // static
-Token Token::ClassifyAndMake(const Location& location,
-                             const std::string_view& v) {
+Token Token::ClassifyAndMake(const Location& location, std::string_view v) {
   char first = v.size() > 0 ? v[0] : '\0';
   char second = v.size() > 1 ? v[1] : '\0';
   return Token(location, Tokenizer::ClassifyToken(first, second), v);
diff --git a/src/gn/token.h b/src/gn/token.h
index a11807a..6a90872 100644
--- a/src/gn/token.h
+++ b/src/gn/token.h
@@ -58,13 +58,12 @@
   };
 
   Token();
-  Token(const Location& location, Type t, const std::string_view& v);
+  Token(const Location& location, Type t, std::string_view v);
 
-  static Token ClassifyAndMake(const Location& location,
-                               const std::string_view& v);
+  static Token ClassifyAndMake(const Location& location, std::string_view v);
 
   Type type() const { return type_; }
-  const std::string_view& value() const { return value_; }
+  std::string_view value() const { return value_; }
   const Location& location() const { return location_; }
   void set_location(Location location) { location_ = location; }
   LocationRange range() const {
diff --git a/src/gn/tokenizer.cc b/src/gn/tokenizer.cc
index 93a6425..a2f0034 100644
--- a/src/gn/tokenizer.cc
+++ b/src/gn/tokenizer.cc
@@ -156,7 +156,7 @@
 }
 
 // static
-size_t Tokenizer::ByteOffsetOfNthLine(const std::string_view& buf, int n) {
+size_t Tokenizer::ByteOffsetOfNthLine(std::string_view buf, int n) {
   DCHECK_GT(n, 0);
 
   if (n == 1)
@@ -176,7 +176,7 @@
 }
 
 // static
-bool Tokenizer::IsNewline(const std::string_view& buffer, size_t offset) {
+bool Tokenizer::IsNewline(std::string_view buffer, size_t offset) {
   DCHECK(offset < buffer.size());
   // We may need more logic here to handle different line ending styles.
   return buffer[offset] == '\n';
diff --git a/src/gn/tokenizer.h b/src/gn/tokenizer.h
index d4b347b..0af3a36 100644
--- a/src/gn/tokenizer.h
+++ b/src/gn/tokenizer.h
@@ -40,11 +40,11 @@
   //
   // This is a helper function for error output so that the tokenizer's
   // notion of lines can be used elsewhere.
-  static size_t ByteOffsetOfNthLine(const std::string_view& buf, int n);
+  static size_t ByteOffsetOfNthLine(std::string_view buf, int n);
 
   // Returns true if the given offset of the string piece counts as a newline.
   // The offset must be in the buffer.
-  static bool IsNewline(const std::string_view& buffer, size_t offset);
+  static bool IsNewline(std::string_view buffer, size_t offset);
 
   static bool IsIdentifierFirstChar(char c);
 
diff --git a/src/gn/visibility.cc b/src/gn/visibility.cc
index eb99a27..8fb5e7f 100644
--- a/src/gn/visibility.cc
+++ b/src/gn/visibility.cc
@@ -22,7 +22,7 @@
 Visibility::~Visibility() = default;
 
 bool Visibility::Set(const SourceDir& current_dir,
-                     const std::string_view& source_root,
+                     std::string_view source_root,
                      const Value& value,
                      Err* err) {
   patterns_.clear();
diff --git a/src/gn/visibility.h b/src/gn/visibility.h
index fc16731..f0ebcf5 100644
--- a/src/gn/visibility.h
+++ b/src/gn/visibility.h
@@ -32,7 +32,7 @@
   // Set the visibility to the thing specified by the given value. On failure,
   // returns false and sets the error.
   bool Set(const SourceDir& current_dir,
-           const std::string_view& source_root,
+           std::string_view source_root,
            const Value& value,
            Err* err);
 
diff --git a/src/gn/xcode_object.cc b/src/gn/xcode_object.cc
index 0761b4f..1d08f22 100644
--- a/src/gn/xcode_object.cc
+++ b/src/gn/xcode_object.cc
@@ -143,7 +143,7 @@
     {"y", "sourcecode.yacc"},
 };
 
-const char* GetSourceType(const std::string_view& ext) {
+const char* GetSourceType(std::string_view ext) {
   for (size_t i = 0; i < std::size(kSourceTypeForExt); ++i) {
     if (kSourceTypeForExt[i].ext == ext)
       return kSourceTypeForExt[i].source_type;
@@ -152,11 +152,11 @@
   return "text";
 }
 
-bool HasExplicitFileType(const std::string_view& ext) {
+bool HasExplicitFileType(std::string_view ext) {
   return ext == "dart";
 }
 
-bool IsSourceFileForIndexing(const std::string_view& ext) {
+bool IsSourceFileForIndexing(std::string_view ext) {
   return ext == "c" || ext == "cc" || ext == "cpp" || ext == "cxx" ||
          ext == "m" || ext == "mm";
 }
diff --git a/src/gn/xml_element_writer.cc b/src/gn/xml_element_writer.cc
index 8525057..f888915 100644
--- a/src/gn/xml_element_writer.cc
+++ b/src/gn/xml_element_writer.cc
@@ -8,13 +8,13 @@
 
 XmlAttributes::XmlAttributes() = default;
 
-XmlAttributes::XmlAttributes(const std::string_view& attr_key,
-                             const std::string_view& attr_value) {
+XmlAttributes::XmlAttributes(std::string_view attr_key,
+                             std::string_view attr_value) {
   add(attr_key, attr_value);
 }
 
-XmlAttributes& XmlAttributes::add(const std::string_view& attr_key,
-                                  const std::string_view& attr_value) {
+XmlAttributes& XmlAttributes::add(std::string_view attr_key,
+                                  std::string_view attr_value) {
   push_back(std::make_pair(attr_key, attr_value));
   return *this;
 }
@@ -50,7 +50,7 @@
   }
 }
 
-void XmlElementWriter::Text(const std::string_view& content) {
+void XmlElementWriter::Text(std::string_view content) {
   StartContent(false);
   out_ << content;
 }
diff --git a/src/gn/xml_element_writer.h b/src/gn/xml_element_writer.h
index 9040d16..6229f88 100644
--- a/src/gn/xml_element_writer.h
+++ b/src/gn/xml_element_writer.h
@@ -19,11 +19,9 @@
     : public std::vector<std::pair<std::string_view, std::string_view>> {
  public:
   XmlAttributes();
-  XmlAttributes(const std::string_view& attr_key,
-                const std::string_view& attr_value);
+  XmlAttributes(std::string_view attr_key, std::string_view attr_value);
 
-  XmlAttributes& add(const std::string_view& attr_key,
-                     const std::string_view& attr_value);
+  XmlAttributes& add(std::string_view attr_key, std::string_view attr_value);
 };
 
 // Helper class for writing XML elements. New XML element is started in
@@ -54,7 +52,7 @@
   ~XmlElementWriter();
 
   // Writes arbitrary XML element text.
-  void Text(const std::string_view& content);
+  void Text(std::string_view content);
 
   // Starts new XML sub-element. Caller must ensure that parent element outlives
   // its children.