Ver código fonte

Update LLVM and switch to `std::optional`. (#2424)

LLVM's bazel build has changed a bit, so this updates the tree for that.

LLVM is also moving `llvm::Optional` to match the standard API, but it seemed simpler to just switch to `std::optional`.

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
Chandler Carruth 3 anos atrás
pai
commit
94cf343b05

+ 13 - 2
WORKSPACE

@@ -6,6 +6,17 @@ workspace(name = "carbon")
 
 load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
 
+skylib_version = "1.3.0"
+
+http_archive(
+    name = "bazel_skylib",
+    urls = [
+        "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/{0}/bazel-skylib-{0}.tar.gz".format(skylib_version),
+        "https://github.com/bazelbuild/bazel-skylib/releases/download/{0}/bazel-skylib-{0}.tar.gz".format(skylib_version),
+    ],
+    sha256 = "74d544d96f4a5bb630d465ca8bbcfe231e3594e5aae57e1edbf17a6eb3ca2506",
+)
+
 ###############################################################################
 # Python rules
 ###############################################################################
@@ -101,7 +112,7 @@ http_archive(
 
 # We pin to specific upstream commits and try to track top-of-tree reasonably
 # closely rather than pinning to a specific release.
-llvm_version = "6fa65f8a98967a5d2d2a6863e0f67a40d2961905"
+llvm_version = "ecfa2d3d9943a48411d04a4b3103c42b4653d9af"
 
 http_archive(
     name = "llvm-raw",
@@ -111,7 +122,7 @@ http_archive(
         "@carbon//bazel/llvm_patches:0001_Patch_for_mallinfo2_when_using_Bazel_build_system.patch",
         "@carbon//bazel/llvm_patches:0002_Added_Bazel_build_for_compiler_rt_fuzzer.patch",
     ],
-    sha256 = "0a3929c5f2fe756820277be7b10e95f7480e7cb7f297ec574d3e9ddeac9068d7",
+    sha256 = "8e9cbb937b1a40536cd809e09603a1810d86a8c314fee0cca36fc493e78289e5",
     strip_prefix = "llvm-project-{0}".format(llvm_version),
     urls = ["https://github.com/llvm/llvm-project/archive/{0}.tar.gz".format(llvm_version)],
 )

+ 2 - 2
explorer/interpreter/type_checker.cpp

@@ -1483,7 +1483,7 @@ class TypeChecker::ConstraintTypeBuilder {
             .drop_front(first_equal_to_add);
 
     // Add all of the new constraints.
-    impl_scope->Add(new_impl_constraints, llvm::None, llvm::None,
+    impl_scope->Add(new_impl_constraints, std::nullopt, std::nullopt,
                     GetSelfWitness(), type_checker);
     for (auto& equal : new_equality_constraints) {
       impl_scope->AddEqualityConstraint(arena_->New<EqualityConstraint>(equal));
@@ -3265,7 +3265,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
 
           CARBON_RETURN_IF_ERROR(DeduceCallBindings(
               call, &param_name.params().static_type(), generic_parameters,
-              /*deduced_bindings=*/llvm::None, impl_scope));
+              /*deduced_bindings=*/std::nullopt, impl_scope));
 
           // Currently the only kinds of parameterized entities we support are
           // types.

+ 1 - 1
scripts/forbid_llvm_googletest.py

@@ -38,7 +38,7 @@ def main() -> None:
     args = [
         scripts_utils.locate_bazel(),
         "query",
-        "somepath(//..., @llvm-project//llvm:gtest)",
+        "somepath(//..., @llvm-project//third-party/unittest:gtest)",
     ]
     p = subprocess.run(
         args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding="utf-8"

+ 2 - 2
toolchain/lexer/numeric_literal.cpp

@@ -32,11 +32,11 @@ static auto operator<<(llvm::raw_ostream& out, LexedNumericLiteral::Radix radix)
 }
 
 auto LexedNumericLiteral::Lex(llvm::StringRef source_text)
-    -> llvm::Optional<LexedNumericLiteral> {
+    -> std::optional<LexedNumericLiteral> {
   LexedNumericLiteral result;
 
   if (source_text.empty() || !IsDecimalDigit(source_text.front())) {
-    return llvm::None;
+    return std::nullopt;
   }
 
   bool seen_plus_minus = false;

+ 2 - 2
toolchain/lexer/numeric_literal.h

@@ -5,11 +5,11 @@
 #ifndef CARBON_TOOLCHAIN_LEXER_NUMERIC_LITERAL_H_
 #define CARBON_TOOLCHAIN_LEXER_NUMERIC_LITERAL_H_
 
+#include <optional>
 #include <utility>
 #include <variant>
 
 #include "llvm/ADT/APInt.h"
-#include "llvm/ADT/Optional.h"
 #include "llvm/ADT/StringRef.h"
 #include "toolchain/diagnostics/diagnostic_emitter.h"
 
@@ -44,7 +44,7 @@ class LexedNumericLiteral {
   //
   // The supplied `source_text` must outlive the return value.
   static auto Lex(llvm::StringRef source_text)
-      -> llvm::Optional<LexedNumericLiteral>;
+      -> std::optional<LexedNumericLiteral>;
 
   // Compute the value of the token, if possible. Emit diagnostics to the given
   // emitter if the token is not valid.

+ 1 - 1
toolchain/lexer/numeric_literal_test.cpp

@@ -31,7 +31,7 @@ class NumericLiteralTest : public ::testing::Test {
   NumericLiteralTest() : error_tracker(ConsoleDiagnosticConsumer()) {}
 
   auto Lex(llvm::StringRef text) -> LexedNumericLiteral {
-    llvm::Optional<LexedNumericLiteral> result = LexedNumericLiteral::Lex(text);
+    std::optional<LexedNumericLiteral> result = LexedNumericLiteral::Lex(text);
     CARBON_CHECK(result);
     EXPECT_EQ(result->text(), text);
     return *result;

+ 6 - 6
toolchain/lexer/string_literal.cpp

@@ -30,7 +30,7 @@ struct LexedStringLiteral::Introducer {
   int prefix_size;
 
   // Lex the introducer for a string literal, after any '#'s.
-  static auto Lex(llvm::StringRef source_text) -> llvm::Optional<Introducer>;
+  static auto Lex(llvm::StringRef source_text) -> std::optional<Introducer>;
 };
 
 // Lex the introducer for a string literal, after any '#'s.
@@ -38,7 +38,7 @@ struct LexedStringLiteral::Introducer {
 // We lex multi-line literals when spelled with either ''' or """ for error
 // recovery purposes, and reject """ literals after lexing.
 auto LexedStringLiteral::Introducer::Lex(llvm::StringRef source_text)
-    -> llvm::Optional<Introducer> {
+    -> std::optional<Introducer> {
   MultiLineKind kind = NotMultiLine;
   llvm::StringRef indicator;
   if (source_text.startswith(MultiLineIndicator)) {
@@ -67,7 +67,7 @@ auto LexedStringLiteral::Introducer::Lex(llvm::StringRef source_text)
         .kind = NotMultiLine, .terminator = "\"", .prefix_size = 1};
   }
 
-  return llvm::None;
+  return std::nullopt;
 }
 
 namespace {
@@ -88,7 +88,7 @@ struct alignas(8) CharSet {
 }  // namespace
 
 auto LexedStringLiteral::Lex(llvm::StringRef source_text)
-    -> llvm::Optional<LexedStringLiteral> {
+    -> std::optional<LexedStringLiteral> {
   int64_t cursor = 0;
   const int64_t source_text_size = source_text.size();
 
@@ -98,10 +98,10 @@ auto LexedStringLiteral::Lex(llvm::StringRef source_text)
   }
   const int hash_level = cursor;
 
-  const llvm::Optional<Introducer> introducer =
+  const std::optional<Introducer> introducer =
       Introducer::Lex(source_text.substr(hash_level));
   if (!introducer) {
-    return llvm::None;
+    return std::nullopt;
   }
 
   cursor += introducer->prefix_size;

+ 6 - 5
toolchain/lexer/string_literal.h

@@ -5,9 +5,9 @@
 #ifndef CARBON_TOOLCHAIN_LEXER_STRING_LITERAL_H_
 #define CARBON_TOOLCHAIN_LEXER_STRING_LITERAL_H_
 
+#include <optional>
 #include <string>
 
-#include "llvm/ADT/Optional.h"
 #include "llvm/ADT/StringRef.h"
 #include "toolchain/diagnostics/diagnostic_emitter.h"
 
@@ -16,11 +16,12 @@ namespace Carbon {
 class LexedStringLiteral {
  public:
   // Extract a string literal token from the given text, if it has a suitable
-  // form. Returning llvm::None indicates no string literal was found; returning
-  // an invalid literal indicates a string prefix was found, but it's malformed
-  // and is returning a partial string literal to assist error construction.
+  // form. Returning std::nullopt indicates no string literal was found;
+  // returning an invalid literal indicates a string prefix was found, but it's
+  // malformed and is returning a partial string literal to assist error
+  // construction.
   static auto Lex(llvm::StringRef source_text)
-      -> llvm::Optional<LexedStringLiteral>;
+      -> std::optional<LexedStringLiteral>;
 
   // Expand any escape sequences in the given string literal and compute the
   // resulting value. This handles error recovery internally and cannot fail.

+ 5 - 5
toolchain/lexer/string_literal_test.cpp

@@ -20,7 +20,7 @@ class StringLiteralTest : public ::testing::Test {
   StringLiteralTest() : error_tracker(ConsoleDiagnosticConsumer()) {}
 
   auto Lex(llvm::StringRef text) -> LexedStringLiteral {
-    llvm::Optional<LexedStringLiteral> result = LexedStringLiteral::Lex(text);
+    std::optional<LexedStringLiteral> result = LexedStringLiteral::Lex(text);
     CARBON_CHECK(result);
     EXPECT_EQ(result->text(), text);
     return *result;
@@ -92,8 +92,8 @@ TEST_F(StringLiteralTest, StringLiteralBounds) {
 
   for (llvm::StringLiteral test : valid) {
     SCOPED_TRACE(test);
-    llvm::Optional<LexedStringLiteral> result = LexedStringLiteral::Lex(test);
-    EXPECT_TRUE(result.hasValue());
+    std::optional<LexedStringLiteral> result = LexedStringLiteral::Lex(test);
+    EXPECT_TRUE(result.has_value());
     if (result) {
       EXPECT_EQ(result->text(), test);
     }
@@ -117,8 +117,8 @@ TEST_F(StringLiteralTest, StringLiteralBounds) {
 
   for (llvm::StringLiteral test : invalid) {
     SCOPED_TRACE(test);
-    llvm::Optional<LexedStringLiteral> result = LexedStringLiteral::Lex(test);
-    EXPECT_TRUE(result.hasValue());
+    std::optional<LexedStringLiteral> result = LexedStringLiteral::Lex(test);
+    EXPECT_TRUE(result.has_value());
     if (result) {
       EXPECT_FALSE(result->is_terminated());
     }

+ 5 - 5
toolchain/lexer/tokenized_buffer.cpp

@@ -184,7 +184,7 @@ class TokenizedBuffer::Lexer {
   }
 
   auto LexNumericLiteral(llvm::StringRef& source_text) -> LexResult {
-    llvm::Optional<LexedNumericLiteral> literal =
+    std::optional<LexedNumericLiteral> literal =
         LexedNumericLiteral::Lex(source_text);
     if (!literal) {
       return LexResult::NoMatch();
@@ -235,7 +235,7 @@ class TokenizedBuffer::Lexer {
   }
 
   auto LexStringLiteral(llvm::StringRef& source_text) -> LexResult {
-    llvm::Optional<LexedStringLiteral> literal =
+    std::optional<LexedStringLiteral> literal =
         LexedStringLiteral::Lex(source_text);
     if (!literal) {
       return LexResult::NoMatch();
@@ -360,7 +360,7 @@ class TokenizedBuffer::Lexer {
       return LexResult::NoMatch();
     }
 
-    llvm::Optional<TokenKind> kind;
+    std::optional<TokenKind> kind;
     switch (word.front()) {
       case 'i':
         kind = TokenKind::IntegerTypeLiteral();
@@ -621,7 +621,7 @@ auto TokenizedBuffer::GetTokenText(Token token) const -> llvm::StringRef {
       token_info.kind == TokenKind::RealLiteral()) {
     const auto& line_info = GetLineInfo(token_info.token_line);
     int64_t token_start = line_info.start + token_info.column;
-    llvm::Optional<LexedNumericLiteral> relexed_token =
+    std::optional<LexedNumericLiteral> relexed_token =
         LexedNumericLiteral::Lex(source_->text().substr(token_start));
     CARBON_CHECK(relexed_token) << "Could not reform numeric literal token.";
     return relexed_token->text();
@@ -632,7 +632,7 @@ auto TokenizedBuffer::GetTokenText(Token token) const -> llvm::StringRef {
   if (token_info.kind == TokenKind::StringLiteral()) {
     const auto& line_info = GetLineInfo(token_info.token_line);
     int64_t token_start = line_info.start + token_info.column;
-    llvm::Optional<LexedStringLiteral> relexed_token =
+    std::optional<LexedStringLiteral> relexed_token =
         LexedStringLiteral::Lex(source_->text().substr(token_start));
     CARBON_CHECK(relexed_token) << "Could not reform string literal token.";
     return relexed_token->text();

+ 1 - 1
toolchain/lexer/tokenized_buffer.h

@@ -7,11 +7,11 @@
 
 #include <cstdint>
 #include <iterator>
+#include <optional>
 
 #include "common/ostream.h"
 #include "llvm/ADT/APInt.h"
 #include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/Optional.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/iterator.h"

+ 1 - 1
toolchain/lexer/tokenized_buffer_test_helpers.h

@@ -58,7 +58,7 @@ struct ExpectedToken {
   int indent_column = -1;
   bool recovery = false;
   llvm::StringRef text = "";
-  llvm::Optional<llvm::StringRef> string_contents = llvm::None;
+  std::optional<llvm::StringRef> string_contents = std::nullopt;
 };
 
 // TODO: Consider rewriting this into a `TokenEq` matcher which is used inside

+ 3 - 3
toolchain/parser/parse_tree.cpp

@@ -5,10 +5,10 @@
 #include "toolchain/parser/parse_tree.h"
 
 #include <cstdlib>
+#include <optional>
 
 #include "common/check.h"
 #include "common/error.h"
-#include "llvm/ADT/Optional.h"
 #include "llvm/ADT/Sequence.h"
 #include "llvm/ADT/SmallVector.h"
 #include "toolchain/lexer/tokenized_buffer.h"
@@ -188,7 +188,7 @@ auto ParseTree::Print(llvm::raw_ostream& output, bool preorder) const -> void {
   output << "]\n";
 }
 
-auto ParseTree::Verify() const -> llvm::Optional<Error> {
+auto ParseTree::Verify() const -> std::optional<Error> {
   llvm::SmallVector<ParseTree::Node> nodes;
   // Traverse the tree in postorder.
   for (Node n : postorder()) {
@@ -259,7 +259,7 @@ auto ParseTree::Verify() const -> llvm::Optional<Error> {
                       "TokenizedBuffer has {1} tokens.",
                       node_impls_.size(), tokens_->size()));
   }
-  return llvm::None;
+  return std::nullopt;
 }
 
 auto ParseTree::Node::Print(llvm::raw_ostream& output) const -> void {

+ 1 - 1
toolchain/parser/parse_tree.h

@@ -146,7 +146,7 @@ class ParseTree {
   // This is primarily intended to be used as a
   // debugging aid. This routine doesn't directly CHECK so that it can be used
   // within a debugger.
-  [[nodiscard]] auto Verify() const -> llvm::Optional<Error>;
+  [[nodiscard]] auto Verify() const -> std::optional<Error>;
 
  private:
   friend class Parser;

+ 9 - 9
toolchain/parser/parser.cpp

@@ -6,9 +6,9 @@
 
 #include <cstdlib>
 #include <memory>
+#include <optional>
 
 #include "common/check.h"
-#include "llvm/ADT/Optional.h"
 #include "llvm/Support/PrettyStackTrace.h"
 #include "toolchain/lexer/token_kind.h"
 #include "toolchain/lexer/tokenized_buffer.h"
@@ -165,15 +165,15 @@ auto Parser::ConsumeChecked(TokenKind kind) -> TokenizedBuffer::Token {
 }
 
 auto Parser::ConsumeIf(TokenKind kind)
-    -> llvm::Optional<TokenizedBuffer::Token> {
+    -> std::optional<TokenizedBuffer::Token> {
   if (!PositionIs(kind)) {
-    return llvm::None;
+    return std::nullopt;
   }
   return Consume();
 }
 
 auto Parser::FindNextOf(std::initializer_list<TokenKind> desired_kinds)
-    -> llvm::Optional<TokenizedBuffer::Token> {
+    -> std::optional<TokenizedBuffer::Token> {
   auto new_position = position_;
   while (true) {
     TokenizedBuffer::Token token = *new_position;
@@ -185,7 +185,7 @@ auto Parser::FindNextOf(std::initializer_list<TokenKind> desired_kinds)
     // Step to the next token at the current bracketing level.
     if (kind.IsClosingSymbol() || kind == TokenKind::EndOfFile()) {
       // There are no more tokens at this level.
-      return llvm::None;
+      return std::nullopt;
     } else if (kind.IsOpeningSymbol()) {
       new_position = TokenizedBuffer::TokenIterator(
           tokens_->GetMatchedClosingToken(token));
@@ -208,9 +208,9 @@ auto Parser::SkipMatchingGroup() -> bool {
 }
 
 auto Parser::SkipPastLikelyEnd(TokenizedBuffer::Token skip_root)
-    -> llvm::Optional<TokenizedBuffer::Token> {
+    -> std::optional<TokenizedBuffer::Token> {
   if (position_ == end_) {
-    return llvm::None;
+    return std::nullopt;
   }
 
   TokenizedBuffer::Line root_line = tokens_->GetLine(skip_root);
@@ -232,7 +232,7 @@ auto Parser::SkipPastLikelyEnd(TokenizedBuffer::Token skip_root)
     if (PositionIs(TokenKind::CloseCurlyBrace())) {
       // Immediately bail out if we hit an unmatched close curly, this will
       // pop us up a level of the syntax grouping.
-      return llvm::None;
+      return std::nullopt;
     }
 
     // We assume that a semicolon is always intended to be the end of the
@@ -251,7 +251,7 @@ auto Parser::SkipPastLikelyEnd(TokenizedBuffer::Token skip_root)
   } while (position_ != end_ &&
            is_same_line_or_indent_greater_than_root(*position_));
 
-  return llvm::None;
+  return std::nullopt;
 }
 
 auto Parser::SkipTo(TokenizedBuffer::Token t) -> void {

+ 5 - 4
toolchain/parser/parser.h

@@ -5,9 +5,10 @@
 #ifndef CARBON_TOOLCHAIN_PARSER_PARSER_H_
 #define CARBON_TOOLCHAIN_PARSER_PARSER_H_
 
+#include <optional>
+
 #include "common/check.h"
 #include "common/vlog.h"
-#include "llvm/ADT/Optional.h"
 #include "toolchain/lexer/token_kind.h"
 #include "toolchain/lexer/tokenized_buffer.h"
 #include "toolchain/parser/parse_node_kind.h"
@@ -137,12 +138,12 @@ class Parser {
 
   // If the current position's token matches this `Kind`, returns it and
   // advances to the next position. Otherwise returns an empty optional.
-  auto ConsumeIf(TokenKind kind) -> llvm::Optional<TokenizedBuffer::Token>;
+  auto ConsumeIf(TokenKind kind) -> std::optional<TokenizedBuffer::Token>;
 
   // Find the next token of any of the given kinds at the current bracketing
   // level.
   auto FindNextOf(std::initializer_list<TokenKind> desired_kinds)
-      -> llvm::Optional<TokenizedBuffer::Token>;
+      -> std::optional<TokenizedBuffer::Token>;
 
   // If the token is an opening symbol for a matched group, skips to the matched
   // closing symbol and returns true. Otherwise, returns false.
@@ -165,7 +166,7 @@ class Parser {
   //
   // Returns a semicolon token if one is the likely end.
   auto SkipPastLikelyEnd(TokenizedBuffer::Token skip_root)
-      -> llvm::Optional<TokenizedBuffer::Token>;
+      -> std::optional<TokenizedBuffer::Token>;
 
   // Skip forward to the given token. Verifies that it is actually forward.
   auto SkipTo(TokenizedBuffer::Token t) -> void;

+ 4 - 4
toolchain/parser/precedence.cpp

@@ -194,7 +194,7 @@ auto PrecedenceGroup::ForType() -> PrecedenceGroup {
 }
 
 auto PrecedenceGroup::ForLeading(TokenKind kind)
-    -> llvm::Optional<PrecedenceGroup> {
+    -> std::optional<PrecedenceGroup> {
   switch (kind) {
     case TokenKind::Star():
       return PrecedenceGroup(TermPrefix);
@@ -211,12 +211,12 @@ auto PrecedenceGroup::ForLeading(TokenKind kind)
       return PrecedenceGroup(BitwisePrefix);
 
     default:
-      return llvm::None;
+      return std::nullopt;
   }
 }
 
 auto PrecedenceGroup::ForTrailing(TokenKind kind, bool infix)
-    -> llvm::Optional<Trailing> {
+    -> std::optional<Trailing> {
   switch (kind) {
     // Assignment operators.
     case TokenKind::Equal():
@@ -311,7 +311,7 @@ auto PrecedenceGroup::ForTrailing(TokenKind kind, bool infix)
       break;
   }
 
-  return llvm::None;
+  return std::nullopt;
 }
 
 auto PrecedenceGroup::GetPriority(PrecedenceGroup left, PrecedenceGroup right)

+ 6 - 5
toolchain/parser/precedence.h

@@ -5,7 +5,8 @@
 #ifndef CARBON_TOOLCHAIN_PARSER_PRECEDENCE_H_
 #define CARBON_TOOLCHAIN_PARSER_PRECEDENCE_H_
 
-#include "llvm/ADT/Optional.h"
+#include <optional>
+
 #include "toolchain/lexer/token_kind.h"
 
 namespace Carbon {
@@ -49,16 +50,16 @@ class PrecedenceGroup {
   static auto ForType() -> PrecedenceGroup;
 
   // Look up the operator information of the given prefix operator token, or
-  // return llvm::None if the given token is not a prefix operator.
-  static auto ForLeading(TokenKind kind) -> llvm::Optional<PrecedenceGroup>;
+  // return std::nullopt if the given token is not a prefix operator.
+  static auto ForLeading(TokenKind kind) -> std::optional<PrecedenceGroup>;
 
   // Look up the operator information of the given infix or postfix operator
-  // token, or return llvm::None if the given token is not an infix or postfix
+  // token, or return std::nullopt if the given token is not an infix or postfix
   // operator. `infix` indicates whether this is a valid infix operator, but is
   // only considered if the same operator symbol is available as both infix and
   // postfix.
   static auto ForTrailing(TokenKind kind, bool infix)
-      -> llvm::Optional<Trailing>;
+      -> std::optional<Trailing>;
 
   friend auto operator==(PrecedenceGroup lhs, PrecedenceGroup rhs) -> bool {
     return lhs.level_ == rhs.level_;

+ 9 - 8
toolchain/parser/precedence_test.cpp

@@ -15,19 +15,20 @@ namespace {
 using ::testing::Eq;
 
 TEST(PrecedenceTest, OperatorsAreRecognized) {
-  EXPECT_TRUE(PrecedenceGroup::ForLeading(TokenKind::Minus()).hasValue());
-  EXPECT_TRUE(PrecedenceGroup::ForLeading(TokenKind::Tilde()).hasValue());
-  EXPECT_FALSE(PrecedenceGroup::ForLeading(TokenKind::Slash()).hasValue());
-  EXPECT_FALSE(PrecedenceGroup::ForLeading(TokenKind::Identifier()).hasValue());
+  EXPECT_TRUE(PrecedenceGroup::ForLeading(TokenKind::Minus()).has_value());
+  EXPECT_TRUE(PrecedenceGroup::ForLeading(TokenKind::Tilde()).has_value());
+  EXPECT_FALSE(PrecedenceGroup::ForLeading(TokenKind::Slash()).has_value());
+  EXPECT_FALSE(
+      PrecedenceGroup::ForLeading(TokenKind::Identifier()).has_value());
 
   EXPECT_TRUE(
-      PrecedenceGroup::ForTrailing(TokenKind::Minus(), false).hasValue());
+      PrecedenceGroup::ForTrailing(TokenKind::Minus(), false).has_value());
   EXPECT_FALSE(
-      PrecedenceGroup::ForTrailing(TokenKind::Tilde(), false).hasValue());
+      PrecedenceGroup::ForTrailing(TokenKind::Tilde(), false).has_value());
   EXPECT_TRUE(
-      PrecedenceGroup::ForTrailing(TokenKind::Slash(), true).hasValue());
+      PrecedenceGroup::ForTrailing(TokenKind::Slash(), true).has_value());
   EXPECT_FALSE(
-      PrecedenceGroup::ForTrailing(TokenKind::Identifier(), false).hasValue());
+      PrecedenceGroup::ForTrailing(TokenKind::Identifier(), false).has_value());
 
   EXPECT_TRUE(
       PrecedenceGroup::ForTrailing(TokenKind::Minus(), true)->is_binary);

+ 1 - 1
toolchain/semantics/semantics_parse_tree_handler.cpp

@@ -132,7 +132,7 @@ auto SemanticsParseTreeHandler::Push(ParseTree::Node parse_node) -> void {
                 << parse_tree_->node_kind(parse_node) << "\n";
   CARBON_CHECK(node_stack_.size() < (1 << 20))
       << "Excessive stack size: likely infinite loop";
-  node_stack_.push_back({parse_node, llvm::None});
+  node_stack_.push_back({parse_node, std::nullopt});
 }
 
 auto SemanticsParseTreeHandler::Push(ParseTree::Node parse_node,

+ 1 - 1
toolchain/semantics/semantics_parse_tree_handler.h

@@ -37,7 +37,7 @@ class SemanticsParseTreeHandler {
 
   struct TraversalStackEntry {
     ParseTree::Node parse_node;
-    llvm::Optional<SemanticsNodeId> result_id;
+    std::optional<SemanticsNodeId> result_id;
   };
 
   // Adds an identifier for a DeclaredName node, returning its reference.

+ 1 - 1
toolchain/source/source_buffer.cpp

@@ -12,12 +12,12 @@
 #include <cerrno>
 #include <cstdint>
 #include <limits>
+#include <optional>
 #include <system_error>
 #include <utility>
 #include <variant>
 
 #include "common/check.h"
-#include "llvm/ADT/Optional.h"
 #include "llvm/ADT/ScopeExit.h"
 #include "llvm/Support/Error.h"