[clang-tools-extra] Use std::optional instead of llvm::Optional (NFC)

This patch replaces (llvm::|)Optional< with std::optional<.  I'll post
a separate patch to clean up the "using" declarations, #include
"llvm/ADT/Optional.h", etc.

This is part of an effort to migrate from llvm::Optional to
std::optional:

https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
diff --git a/clang-tools-extra/clangd/AST.cpp b/clang-tools-extra/clangd/AST.cpp
index d33960a..9576d74 100644
--- a/clang-tools-extra/clangd/AST.cpp
+++ b/clang-tools-extra/clangd/AST.cpp
@@ -45,7 +45,7 @@
 namespace clangd {
 
 namespace {
-llvm::Optional<llvm::ArrayRef<TemplateArgumentLoc>>
+std::optional<llvm::ArrayRef<TemplateArgumentLoc>>
 getTemplateSpecializationArgLocs(const NamedDecl &ND) {
   if (auto *Func = llvm::dyn_cast<FunctionDecl>(&ND)) {
     if (const ASTTemplateArgumentListInfo *Args =
@@ -267,7 +267,7 @@
   std::string TemplateArgs;
   llvm::raw_string_ostream OS(TemplateArgs);
   PrintingPolicy Policy(ND.getASTContext().getLangOpts());
-  if (llvm::Optional<llvm::ArrayRef<TemplateArgumentLoc>> Args =
+  if (std::optional<llvm::ArrayRef<TemplateArgumentLoc>> Args =
           getTemplateSpecializationArgLocs(ND)) {
     printTemplateArgumentList(OS, *Args, Policy);
   } else if (auto *Cls = llvm::dyn_cast<ClassTemplateSpecializationDecl>(&ND)) {
@@ -564,8 +564,7 @@
 };
 } // namespace
 
-llvm::Optional<QualType> getDeducedType(ASTContext &ASTCtx,
-                                        SourceLocation Loc) {
+std::optional<QualType> getDeducedType(ASTContext &ASTCtx, SourceLocation Loc) {
   if (!Loc.isValid())
     return {};
   DeducedTypeVisitor V(Loc);
@@ -798,11 +797,11 @@
     ArrayRef<const ParmVarDecl *> Tail;
     // If the parameters were resolved to another forwarding FunctionDecl, this
     // is it.
-    Optional<FunctionDecl *> PackTarget;
+    std::optional<FunctionDecl *> PackTarget;
   };
 
   // The output of this visitor
-  Optional<ForwardingInfo> Info;
+  std::optional<ForwardingInfo> Info;
 
 private:
   // inspects the given callee with the given args to check whether it
@@ -844,7 +843,7 @@
 
   // Returns the beginning of the expanded pack represented by Parameters
   // in the given arguments, if it is there.
-  llvm::Optional<size_t> findPack(typename CallExpr::arg_range Args) {
+  std::optional<size_t> findPack(typename CallExpr::arg_range Args) {
     // find the argument directly referring to the first parameter
     assert(Parameters.size() <= static_cast<size_t>(llvm::size(Args)));
     for (auto Begin = Args.begin(), End = Args.end() - Parameters.size() + 1;
diff --git a/clang-tools-extra/clangd/AST.h b/clang-tools-extra/clangd/AST.h
index fbbee89..bdc0862 100644
--- a/clang-tools-extra/clangd/AST.h
+++ b/clang-tools-extra/clangd/AST.h
@@ -152,7 +152,7 @@
 /// Retrieves the deduced type at a given location (auto, decltype).
 /// It will return the underlying type.
 /// If the type is an undeduced auto, returns the type itself.
-llvm::Optional<QualType> getDeducedType(ASTContext &, SourceLocation Loc);
+std::optional<QualType> getDeducedType(ASTContext &, SourceLocation Loc);
 
 // Find the abbreviated-function-template `auto` within a type, or returns null.
 // Similar to getContainedAutoTypeLoc, but these `auto`s are
diff --git a/clang-tools-extra/clangd/ClangdLSPServer.cpp b/clang-tools-extra/clangd/ClangdLSPServer.cpp
index 7d75176..53d5a78 100644
--- a/clang-tools-extra/clangd/ClangdLSPServer.cpp
+++ b/clang-tools-extra/clangd/ClangdLSPServer.cpp
@@ -245,7 +245,7 @@
   // clangd receives the reply from the LSP client.
   // Return a call id of the request.
   llvm::json::Value bindReply(Callback<llvm::json::Value> Reply) {
-    llvm::Optional<std::pair<int, Callback<llvm::json::Value>>> OldestCB;
+    std::optional<std::pair<int, Callback<llvm::json::Value>>> OldestCB;
     int ID;
     {
       std::lock_guard<std::mutex> Mutex(CallMutex);
@@ -516,7 +516,7 @@
     // rather want to propagate information from LSPServer's context into the
     // Server, CDB, etc.
     WithContext MainContext(BackgroundContext.clone());
-    llvm::Optional<WithContextValue> WithOffsetEncoding;
+    std::optional<WithContextValue> WithOffsetEncoding;
     if (Opts.Encoding)
       WithOffsetEncoding.emplace(kCurrentOffsetEncoding, *Opts.Encoding);
     Server.emplace(*CDB, TFS, Opts,
@@ -908,7 +908,7 @@
                        const URIForFile &FileURI) {
   std::vector<SymbolInformation> Results;
   std::function<void(const DocumentSymbol &, llvm::StringRef)> Process =
-      [&](const DocumentSymbol &S, llvm::Optional<llvm::StringRef> ParentName) {
+      [&](const DocumentSymbol &S, std::optional<llvm::StringRef> ParentName) {
         SymbolInformation SI;
         SI.containerName = std::string(ParentName ? "" : *ParentName);
         SI.name = S.name;
@@ -949,7 +949,7 @@
   Server->foldingRanges(Params.textDocument.uri.file(), std::move(Reply));
 }
 
-static llvm::Optional<Command> asCommand(const CodeAction &Action) {
+static std::optional<Command> asCommand(const CodeAction &Action) {
   Command Cmd;
   if (Action.command && Action.edit)
     return std::nullopt; // Not representable. (We never emit these anyway).
@@ -1149,7 +1149,7 @@
   Server->switchSourceHeader(
       Params.uri.file(),
       [Reply = std::move(Reply),
-       Params](llvm::Expected<llvm::Optional<clangd::Path>> Path) mutable {
+       Params](llvm::Expected<std::optional<clangd::Path>> Path) mutable {
         if (!Path)
           return Reply(Path.takeError());
         if (*Path)
diff --git a/clang-tools-extra/clangd/ClangdLSPServer.h b/clang-tools-extra/clangd/ClangdLSPServer.h
index 1b1f4ad..3659fd8 100644
--- a/clang-tools-extra/clangd/ClangdLSPServer.h
+++ b/clang-tools-extra/clangd/ClangdLSPServer.h
@@ -44,7 +44,7 @@
     /// set via LSP (extensions) only.
     bool UseDirBasedCDB = true;
     /// The offset-encoding to use, or std::nullopt to negotiate it over LSP.
-    llvm::Optional<OffsetEncoding> Encoding;
+    std::optional<OffsetEncoding> Encoding;
     /// If set, periodically called to release memory.
     /// Consider malloc_trim(3)
     std::function<void()> MemoryCleanup = nullptr;
@@ -292,9 +292,9 @@
   // The CDB is created by the "initialize" LSP method.
   std::unique_ptr<GlobalCompilationDatabase> BaseCDB;
   // CDB is BaseCDB plus any commands overridden via LSP extensions.
-  llvm::Optional<OverlayCDB> CDB;
+  std::optional<OverlayCDB> CDB;
   // The ClangdServer is created by the "initialize" LSP method.
-  llvm::Optional<ClangdServer> Server;
+  std::optional<ClangdServer> Server;
 };
 } // namespace clangd
 } // namespace clang
diff --git a/clang-tools-extra/clangd/ClangdServer.cpp b/clang-tools-extra/clangd/ClangdServer.cpp
index 5a9b2ed..74ad3c9 100644
--- a/clang-tools-extra/clangd/ClangdServer.cpp
+++ b/clang-tools-extra/clangd/ClangdServer.cpp
@@ -393,7 +393,7 @@
     if (auto Reason = isCancelled())
       return CB(llvm::make_error<CancelledError>(Reason));
 
-    llvm::Optional<SpeculativeFuzzyFind> SpecFuzzyFind;
+    std::optional<SpeculativeFuzzyFind> SpecFuzzyFind;
     if (!IP->Preamble) {
       // No speculation in Fallback mode, as it's supposed to be much faster
       // without compiling.
@@ -471,7 +471,7 @@
                                  std::move(Action));
 }
 
-void ClangdServer::formatFile(PathRef File, llvm::Optional<Range> Rng,
+void ClangdServer::formatFile(PathRef File, std::optional<Range> Rng,
                               Callback<tooling::Replacements> CB) {
   auto Code = getDraft(File);
   if (!Code)
@@ -538,7 +538,7 @@
 }
 
 void ClangdServer::prepareRename(PathRef File, Position Pos,
-                                 llvm::Optional<std::string> NewName,
+                                 std::optional<std::string> NewName,
                                  const RenameOptions &RenameOpts,
                                  Callback<RenameResult> CB) {
   auto Action = [Pos, File = File.str(), CB = std::move(CB),
@@ -672,7 +672,7 @@
     auto Selections = tweakSelection(Sel, *InpAST, FS.get());
     if (!Selections)
       return CB(Selections.takeError());
-    llvm::Optional<llvm::Expected<Tweak::Effect>> Effect;
+    std::optional<llvm::Expected<Tweak::Effect>> Effect;
     // Try each selection, take the first one that prepare()s.
     // If they all fail, Effect will hold get the last error.
     for (const auto &Selection : *Selections) {
@@ -714,7 +714,7 @@
 }
 
 void ClangdServer::switchSourceHeader(
-    PathRef Path, Callback<llvm::Optional<clangd::Path>> CB) {
+    PathRef Path, Callback<std::optional<clangd::Path>> CB) {
   // We want to return the result as fast as possible, strategy is:
   //  1) use the file-only heuristic, it requires some IO but it is much
   //     faster than building AST, but it only works when .h/.cc files are in
@@ -1029,7 +1029,7 @@
 }
 
 [[nodiscard]] bool
-ClangdServer::blockUntilIdleForTest(llvm::Optional<double> TimeoutSeconds) {
+ClangdServer::blockUntilIdleForTest(std::optional<double> TimeoutSeconds) {
   // Order is important here: we don't want to block on A and then B,
   // if B might schedule work on A.
 
@@ -1056,8 +1056,8 @@
   // Then on the last iteration, verify they're idle without waiting.
   //
   // There's a small chance they're juggling work and we didn't catch them :-(
-  for (llvm::Optional<double> Timeout :
-       {TimeoutSeconds, TimeoutSeconds, llvm::Optional<double>(0)}) {
+  for (std::optional<double> Timeout :
+       {TimeoutSeconds, TimeoutSeconds, std::optional<double>(0)}) {
     if (!CDB.blockUntilIdle(timeoutSeconds(Timeout)))
       return false;
     if (BackgroundIdx && !BackgroundIdx->blockUntilIdleForTest(Timeout))
diff --git a/clang-tools-extra/clangd/ClangdServer.h b/clang-tools-extra/clangd/ClangdServer.h
index 097fed1..40b9183 100644
--- a/clang-tools-extra/clangd/ClangdServer.h
+++ b/clang-tools-extra/clangd/ClangdServer.h
@@ -137,13 +137,13 @@
     /// Clangd's workspace root. Relevant for "workspace" operations not bound
     /// to a particular file.
     /// FIXME: If not set, should use the current working directory.
-    llvm::Optional<std::string> WorkspaceRoot;
+    std::optional<std::string> WorkspaceRoot;
 
     /// The resource directory is used to find internal headers, overriding
     /// defaults and -resource-dir compiler flag).
     /// If None, ClangdServer calls CompilerInvocation::GetResourcePath() to
     /// obtain the standard resource directory.
-    llvm::Optional<std::string> ResourceDir = std::nullopt;
+    std::optional<std::string> ResourceDir = std::nullopt;
 
     /// Time to wait after a new file version before computing diagnostics.
     DebouncePolicy UpdateDebounce = DebouncePolicy{
@@ -241,7 +241,7 @@
   /// Switch to a corresponding source file when given a header file, and vice
   /// versa.
   void switchSourceHeader(PathRef Path,
-                          Callback<llvm::Optional<clangd::Path>> CB);
+                          Callback<std::optional<clangd::Path>> CB);
 
   /// Get document highlights for a given position.
   void findDocumentHighlights(PathRef File, Position Pos,
@@ -304,7 +304,7 @@
 
   /// Run formatting for the \p File with content \p Code.
   /// If \p Rng is non-null, formats only that region.
-  void formatFile(PathRef File, llvm::Optional<Range> Rng,
+  void formatFile(PathRef File, std::optional<Range> Rng,
                   Callback<tooling::Replacements> CB);
 
   /// Run formatting after \p TriggerText was typed at \p Pos in \p File with
@@ -316,7 +316,7 @@
   ///
   /// If NewName is provided, it performs a name validation.
   void prepareRename(PathRef File, Position Pos,
-                     llvm::Optional<std::string> NewName,
+                     std::optional<std::string> NewName,
                      const RenameOptions &RenameOpts,
                      Callback<RenameResult> CB);
 
@@ -398,7 +398,7 @@
   // FIXME: various subcomponents each get the full timeout, so it's more of
   // an order of magnitude than a hard deadline.
   [[nodiscard]] bool
-  blockUntilIdleForTest(llvm::Optional<double> TimeoutSeconds = 10);
+  blockUntilIdleForTest(std::optional<double> TimeoutSeconds = 10);
 
   /// Builds a nested representation of memory used by components.
   void profile(MemoryTree &MT) const;
@@ -436,13 +436,13 @@
   bool PreambleParseForwardingFunctions = false;
 
   // GUARDED_BY(CachedCompletionFuzzyFindRequestMutex)
-  llvm::StringMap<llvm::Optional<FuzzyFindRequest>>
+  llvm::StringMap<std::optional<FuzzyFindRequest>>
       CachedCompletionFuzzyFindRequestByFile;
   mutable std::mutex CachedCompletionFuzzyFindRequestMutex;
 
-  llvm::Optional<std::string> WorkspaceRoot;
-  llvm::Optional<AsyncTaskRunner> IndexTasks; // for stdlib indexing.
-  llvm::Optional<TUScheduler> WorkScheduler;
+  std::optional<std::string> WorkspaceRoot;
+  std::optional<AsyncTaskRunner> IndexTasks; // for stdlib indexing.
+  std::optional<TUScheduler> WorkScheduler;
   // Invalidation policy used for actions that we assume are "transient".
   TUScheduler::ASTActionInvalidation Transient;
 
diff --git a/clang-tools-extra/clangd/CodeComplete.cpp b/clang-tools-extra/clangd/CodeComplete.cpp
index 42e6ef2..b6d7da1 100644
--- a/clang-tools-extra/clangd/CodeComplete.cpp
+++ b/clang-tools-extra/clangd/CodeComplete.cpp
@@ -265,7 +265,7 @@
   }
 
   // The best header to include if include insertion is allowed.
-  llvm::Optional<llvm::StringRef>
+  std::optional<llvm::StringRef>
   headerToInsertIfAllowed(const CodeCompleteOptions &Opts) const {
     if (Opts.InsertIncludes == CodeCompleteOptions::NeverInsert ||
         RankedIncludeHeaders.empty())
@@ -647,7 +647,7 @@
   std::vector<std::string> AccessibleScopes;
   // The full scope qualifier as typed by the user (without the leading "::").
   // Set if the qualifier is not fully resolved by Sema.
-  llvm::Optional<std::string> UnresolvedQualifier;
+  std::optional<std::string> UnresolvedQualifier;
 
   // Construct scopes being queried in indexes. The results are deduplicated.
   // This method format the scopes to match the index request representation.
@@ -1232,7 +1232,7 @@
   PathRef FileName;
   size_t Offset;
   const PreambleData &Preamble;
-  const llvm::Optional<PreamblePatch> Patch;
+  const std::optional<PreamblePatch> Patch;
   const ParseInputs &ParseInput;
 };
 
@@ -1454,24 +1454,24 @@
   int NSema = 0, NIndex = 0, NSemaAndIndex = 0, NIdent = 0;
   bool Incomplete = false; // Would more be available with a higher limit?
   CompletionPrefix HeuristicPrefix;
-  llvm::Optional<FuzzyMatcher> Filter; // Initialized once Sema runs.
+  std::optional<FuzzyMatcher> Filter; // Initialized once Sema runs.
   Range ReplacedRange;
   std::vector<std::string> QueryScopes; // Initialized once Sema runs.
   // Initialized once QueryScopes is initialized, if there are scopes.
-  llvm::Optional<ScopeDistance> ScopeProximity;
-  llvm::Optional<OpaqueType> PreferredType; // Initialized once Sema runs.
+  std::optional<ScopeDistance> ScopeProximity;
+  std::optional<OpaqueType> PreferredType; // Initialized once Sema runs.
   // Whether to query symbols from any scope. Initialized once Sema runs.
   bool AllScopes = false;
   llvm::StringSet<> ContextWords;
   // Include-insertion and proximity scoring rely on the include structure.
   // This is available after Sema has run.
-  llvm::Optional<IncludeInserter> Inserter;  // Available during runWithSema.
-  llvm::Optional<URIDistance> FileProximity; // Initialized once Sema runs.
+  std::optional<IncludeInserter> Inserter;  // Available during runWithSema.
+  std::optional<URIDistance> FileProximity; // Initialized once Sema runs.
   /// Speculative request based on the cached request and the filter text before
   /// the cursor.
   /// Initialized right before sema run. This is only set if `SpecFuzzyFind` is
   /// set and contains a cached request.
-  llvm::Optional<FuzzyFindRequest> SpecReq;
+  std::optional<FuzzyFindRequest> SpecReq;
 
 public:
   // A CodeCompleteFlow object is only useful for calling run() exactly once.
@@ -1834,7 +1834,7 @@
     return std::move(Top).items();
   }
 
-  llvm::Optional<float> fuzzyScore(const CompletionCandidate &C) {
+  std::optional<float> fuzzyScore(const CompletionCandidate &C) {
     // Macros can be very spammy, so we only support prefix completion.
     if (((C.SemaResult &&
           C.SemaResult->Kind == CodeCompletionResult::RK_Macro) ||
@@ -1949,7 +1949,7 @@
   }
 
   CodeCompletion toCodeCompletion(const CompletionCandidate::Bundle &Bundle) {
-    llvm::Optional<CodeCompletionBuilder> Builder;
+    std::optional<CodeCompletionBuilder> Builder;
     for (const auto &Item : Bundle) {
       CodeCompletionString *SemaCCS =
           Item.SemaResult ? Recorder->codeCompletionString(*Item.SemaResult)
@@ -2062,7 +2062,7 @@
 // If Offset is inside what looks like argument comment (e.g.
 // "/*^" or "/* foo^"), returns new offset pointing to the start of the /*
 // (place where semaCodeComplete should run).
-llvm::Optional<unsigned>
+std::optional<unsigned>
 maybeFunctionArgumentCommentStart(llvm::StringRef Content) {
   while (!Content.empty() && isAsciiIdentifierContinue(Content.back()))
     Content = Content.drop_back();
diff --git a/clang-tools-extra/clangd/CodeComplete.h b/clang-tools-extra/clangd/CodeComplete.h
index e88e9b3..4f7fcd7 100644
--- a/clang-tools-extra/clangd/CodeComplete.h
+++ b/clang-tools-extra/clangd/CodeComplete.h
@@ -57,7 +57,7 @@
   /// If none, the implementation may choose an appropriate behavior.
   /// (In practice, ClangdLSPServer enables bundling if the client claims
   /// to supports signature help).
-  llvm::Optional<bool> BundleOverloads;
+  std::optional<bool> BundleOverloads;
 
   /// Limit the number of results returned (0 means no limit).
   /// If more results are available, we set CompletionList.isIncomplete.
@@ -175,7 +175,7 @@
   // Type to be displayed for this completion.
   std::string ReturnType;
   // The parsed documentation comment.
-  llvm::Optional<markup::Document> Documentation;
+  std::optional<markup::Document> Documentation;
   CompletionItemKind Kind = CompletionItemKind::Missing;
   // This completion item may represent several symbols that can be inserted in
   // the same way, such as function overloads. In this case BundleSize > 1, and
@@ -194,7 +194,7 @@
     // Empty for non-symbol completions, or when not known.
     std::string Header;
     // Present if Header should be inserted to use this item.
-    llvm::Optional<TextEdit> Insertion;
+    std::optional<TextEdit> Insertion;
   };
   // All possible include headers ranked by preference. By default, the first
   // include is used.
@@ -247,7 +247,7 @@
   // Example: foo.pb^ -> foo.push_back()
   //              ~~
   // Typically matches the textEdit.range of Completions, but not guaranteed to.
-  llvm::Optional<Range> CompletionRange;
+  std::optional<Range> CompletionRange;
   // Usually the source will be parsed with a real C++ parser.
   // But heuristics may be used instead if e.g. the preamble is not ready.
   bool RanParser = true;
@@ -260,10 +260,10 @@
 struct SpeculativeFuzzyFind {
   /// A cached request from past code completions.
   /// Set by caller of `codeComplete()`.
-  llvm::Optional<FuzzyFindRequest> CachedReq;
+  std::optional<FuzzyFindRequest> CachedReq;
   /// The actual request used by `codeComplete()`.
   /// Set by `codeComplete()`. This can be used by callers to update cache.
-  llvm::Optional<FuzzyFindRequest> NewReq;
+  std::optional<FuzzyFindRequest> NewReq;
   /// The result is consumed by `codeComplete()` if speculation succeeded.
   /// NOTE: the destructor will wait for the async call to finish.
   std::future<std::pair<bool /*Incomplete*/, SymbolSlab>> Result;
diff --git a/clang-tools-extra/clangd/CompileCommands.cpp b/clang-tools-extra/clangd/CompileCommands.cpp
index 6669103..3b7e257 100644
--- a/clang-tools-extra/clangd/CompileCommands.cpp
+++ b/clang-tools-extra/clangd/CompileCommands.cpp
@@ -38,7 +38,7 @@
 
 // Query apple's `xcrun` launcher, which is the source of truth for "how should"
 // clang be invoked on this system.
-llvm::Optional<std::string> queryXcrun(llvm::ArrayRef<llvm::StringRef> Argv) {
+std::optional<std::string> queryXcrun(llvm::ArrayRef<llvm::StringRef> Argv) {
   auto Xcrun = llvm::sys::findProgramByName("xcrun");
   if (!Xcrun) {
     log("Couldn't find xcrun. Hopefully you have a non-apple toolchain...");
@@ -118,7 +118,7 @@
 
 // On mac, /usr/bin/clang sets SDKROOT and then invokes the real clang.
 // The effect of this is to set -isysroot correctly. We do the same.
-llvm::Optional<std::string> detectSysroot() {
+std::optional<std::string> detectSysroot() {
 #ifndef __APPLE__
   return std::nullopt;
 #endif
@@ -141,7 +141,7 @@
 // Where possible it should be an absolute path with sensible directory, but
 // with the original basename.
 static std::string resolveDriver(llvm::StringRef Driver, bool FollowSymlink,
-                                 llvm::Optional<std::string> ClangPath) {
+                                 std::optional<std::string> ClangPath) {
   auto SiblingOf = [&](llvm::StringRef AbsPath) {
     llvm::SmallString<128> Result = llvm::sys::path::parent_path(AbsPath);
     llvm::sys::path::append(Result, llvm::sys::path::filename(Driver));
@@ -256,7 +256,7 @@
   // In practice only the extension of the file matters, so do this only when
   // it differs.
   llvm::StringRef FileExtension = llvm::sys::path::extension(File);
-  llvm::Optional<std::string> TransferFrom;
+  std::optional<std::string> TransferFrom;
   auto SawInput = [&](llvm::StringRef Input) {
     if (llvm::sys::path::extension(Input) != FileExtension)
       TransferFrom.emplace(Input);
diff --git a/clang-tools-extra/clangd/CompileCommands.h b/clang-tools-extra/clangd/CompileCommands.h
index 561d9ea..eb318d1 100644
--- a/clang-tools-extra/clangd/CompileCommands.h
+++ b/clang-tools-extra/clangd/CompileCommands.h
@@ -28,11 +28,11 @@
 //  - injecting -isysroot flags on mac as the system clang does
 struct CommandMangler {
   // Absolute path to clang.
-  llvm::Optional<std::string> ClangPath;
+  std::optional<std::string> ClangPath;
   // Directory containing builtin headers.
-  llvm::Optional<std::string> ResourceDir;
+  std::optional<std::string> ResourceDir;
   // Root for searching for standard library (passed to -isysroot).
-  llvm::Optional<std::string> Sysroot;
+  std::optional<std::string> Sysroot;
   SystemIncludeExtractorFn SystemIncludeExtractor;
 
   // A command-mangler that doesn't know anything about the system.
diff --git a/clang-tools-extra/clangd/ConfigCompile.cpp b/clang-tools-extra/clangd/ConfigCompile.cpp
index e1a511d..f0cf937 100644
--- a/clang-tools-extra/clangd/ConfigCompile.cpp
+++ b/clang-tools-extra/clangd/ConfigCompile.cpp
@@ -103,7 +103,7 @@
   std::string FragmentDirectory;
   bool Trusted = false;
 
-  llvm::Optional<llvm::Regex>
+  std::optional<llvm::Regex>
   compileRegex(const Located<std::string> &Text,
                llvm::Regex::RegexFlags Flags = llvm::Regex::NoFlags) {
     std::string Anchored = "^(" + *Text + ")$";
@@ -142,7 +142,7 @@
     FragmentCompiler &Outer;
     llvm::StringRef EnumName;
     const Located<std::string> &Input;
-    llvm::Optional<T> Result;
+    std::optional<T> Result;
     llvm::SmallVector<llvm::StringLiteral> ValidValues;
 
   public:
@@ -158,7 +158,7 @@
       return *this;
     }
 
-    llvm::Optional<T> value() {
+    std::optional<T> value() {
       if (!Result)
         Outer.diag(
             Warning,
@@ -173,7 +173,7 @@
   // Attempt to parse a specified string into an enum.
   // Yields std::nullopt and produces a diagnostic on failure.
   //
-  // Optional<T> Value = compileEnum<En>("Foo", Frag.Foo)
+  // std::optional<T> Value = compileEnum<En>("Foo", Frag.Foo)
   //    .map("Foo", Enum::Foo)
   //    .map("Bar", Enum::Bar)
   //    .value();
@@ -291,7 +291,7 @@
     }
 
     if (F.CompilationDatabase) {
-      llvm::Optional<Config::CDBSearchSpec> Spec;
+      std::optional<Config::CDBSearchSpec> Spec;
       if (**F.CompilationDatabase == "Ancestors") {
         Spec.emplace();
         Spec->Policy = Config::CDBSearchSpec::Ancestors;
diff --git a/clang-tools-extra/clangd/Diagnostics.cpp b/clang-tools-extra/clangd/Diagnostics.cpp
index 6c8cf5c..326df0a 100644
--- a/clang-tools-extra/clangd/Diagnostics.cpp
+++ b/clang-tools-extra/clangd/Diagnostics.cpp
@@ -907,9 +907,9 @@
   return Code;
 }
 
-llvm::Optional<std::string> getDiagnosticDocURI(Diag::DiagSource Source,
-                                                unsigned ID,
-                                                llvm::StringRef Name) {
+std::optional<std::string> getDiagnosticDocURI(Diag::DiagSource Source,
+                                               unsigned ID,
+                                               llvm::StringRef Name) {
   switch (Source) {
   case Diag::Unknown:
     break;
diff --git a/clang-tools-extra/clangd/Diagnostics.h b/clang-tools-extra/clangd/Diagnostics.h
index b1a1f01..ca6b92f 100644
--- a/clang-tools-extra/clangd/Diagnostics.h
+++ b/clang-tools-extra/clangd/Diagnostics.h
@@ -62,7 +62,7 @@
   // May be relative, absolute or even artificially constructed.
   std::string File;
   // Absolute path to containing file, if available.
-  llvm::Optional<std::string> AbsFile;
+  std::optional<std::string> AbsFile;
 
   clangd::Range Range;
   DiagnosticsEngine::Level Severity = DiagnosticsEngine::Note;
@@ -128,8 +128,8 @@
 int getSeverity(DiagnosticsEngine::Level L);
 
 /// Returns a URI providing more information about a particular diagnostic.
-llvm::Optional<std::string> getDiagnosticDocURI(Diag::DiagSource, unsigned ID,
-                                                llvm::StringRef Name);
+std::optional<std::string> getDiagnosticDocURI(Diag::DiagSource, unsigned ID,
+                                               llvm::StringRef Name);
 
 /// StoreDiags collects the diagnostics that can later be reported by
 /// clangd. It groups all notes for a diagnostic into a single Diag
@@ -171,9 +171,9 @@
   LevelAdjuster Adjuster = nullptr;
   DiagCallback DiagCB = nullptr;
   std::vector<Diag> Output;
-  llvm::Optional<LangOptions> LangOpts;
-  llvm::Optional<Diag> LastDiag;
-  llvm::Optional<FullSourceLoc> LastDiagLoc; // Valid only when LastDiag is set.
+  std::optional<LangOptions> LangOpts;
+  std::optional<Diag> LastDiag;
+  std::optional<FullSourceLoc> LastDiagLoc;  // Valid only when LastDiag is set.
   bool LastDiagOriginallyError = false;      // Valid only when LastDiag is set.
   SourceManager *OrigSrcMgr = nullptr;
 
diff --git a/clang-tools-extra/clangd/DraftStore.cpp b/clang-tools-extra/clangd/DraftStore.cpp
index 7df70e6..66e45b0 100644
--- a/clang-tools-extra/clangd/DraftStore.cpp
+++ b/clang-tools-extra/clangd/DraftStore.cpp
@@ -16,7 +16,7 @@
 namespace clang {
 namespace clangd {
 
-llvm::Optional<DraftStore::Draft> DraftStore::getDraft(PathRef File) const {
+std::optional<DraftStore::Draft> DraftStore::getDraft(PathRef File) const {
   std::lock_guard<std::mutex> Lock(Mutex);
 
   auto It = Drafts.find(File);
diff --git a/clang-tools-extra/clangd/DraftStore.h b/clang-tools-extra/clangd/DraftStore.h
index a19fe55..0d52042 100644
--- a/clang-tools-extra/clangd/DraftStore.h
+++ b/clang-tools-extra/clangd/DraftStore.h
@@ -34,7 +34,7 @@
 
   /// \return Contents of the stored document.
   /// For untracked files, a std::nullopt is returned.
-  llvm::Optional<Draft> getDraft(PathRef File) const;
+  std::optional<Draft> getDraft(PathRef File) const;
 
   /// \return List of names of the drafts in this store.
   std::vector<Path> getActiveFiles() const;
diff --git a/clang-tools-extra/clangd/DumpAST.cpp b/clang-tools-extra/clangd/DumpAST.cpp
index 438733d..2bf75e6 100644
--- a/clang-tools-extra/clangd/DumpAST.cpp
+++ b/clang-tools-extra/clangd/DumpAST.cpp
@@ -88,7 +88,7 @@
   // Range: most nodes have getSourceRange(), with a couple of exceptions.
   // We only return it if it's valid at both ends and there are no macros.
 
-  template <typename T> llvm::Optional<Range> getRange(const T &Node) {
+  template <typename T> std::optional<Range> getRange(const T &Node) {
     SourceRange SR = getSourceRange(Node);
     auto Spelled = Tokens.spelledForExpanded(Tokens.expandedTokens(SR));
     if (!Spelled)
diff --git a/clang-tools-extra/clangd/ExpectedTypes.cpp b/clang-tools-extra/clangd/ExpectedTypes.cpp
index 563612a..deea8a5 100644
--- a/clang-tools-extra/clangd/ExpectedTypes.cpp
+++ b/clang-tools-extra/clangd/ExpectedTypes.cpp
@@ -40,8 +40,7 @@
   return T.getTypePtr();
 }
 
-static llvm::Optional<QualType>
-typeOfCompletion(const CodeCompletionResult &R) {
+static std::optional<QualType> typeOfCompletion(const CodeCompletionResult &R) {
   const NamedDecl *D = R.Declaration;
   // Templates do not have a type on their own, look at the templated decl.
   if (auto *Template = dyn_cast_or_null<TemplateDecl>(D))
@@ -63,7 +62,7 @@
 }
 } // namespace
 
-llvm::Optional<OpaqueType> OpaqueType::encode(ASTContext &Ctx, QualType T) {
+std::optional<OpaqueType> OpaqueType::encode(ASTContext &Ctx, QualType T) {
   if (T.isNull())
     return std::nullopt;
   const Type *C = toEquivClass(Ctx, T);
@@ -77,12 +76,11 @@
 
 OpaqueType::OpaqueType(std::string Data) : Data(std::move(Data)) {}
 
-llvm::Optional<OpaqueType> OpaqueType::fromType(ASTContext &Ctx,
-                                                QualType Type) {
+std::optional<OpaqueType> OpaqueType::fromType(ASTContext &Ctx, QualType Type) {
   return encode(Ctx, Type);
 }
 
-llvm::Optional<OpaqueType>
+std::optional<OpaqueType>
 OpaqueType::fromCompletionResult(ASTContext &Ctx,
                                  const CodeCompletionResult &R) {
   auto T = typeOfCompletion(R);
diff --git a/clang-tools-extra/clangd/ExpectedTypes.h b/clang-tools-extra/clangd/ExpectedTypes.h
index 6cfd093..8182e76 100644
--- a/clang-tools-extra/clangd/ExpectedTypes.h
+++ b/clang-tools-extra/clangd/ExpectedTypes.h
@@ -35,11 +35,11 @@
 class OpaqueType {
 public:
   /// Create a type from a code completion result.
-  static llvm::Optional<OpaqueType>
+  static std::optional<OpaqueType>
   fromCompletionResult(ASTContext &Ctx, const CodeCompletionResult &R);
   /// Construct an instance from a clang::QualType. This is usually a
   /// PreferredType from a clang's completion context.
-  static llvm::Optional<OpaqueType> fromType(ASTContext &Ctx, QualType Type);
+  static std::optional<OpaqueType> fromType(ASTContext &Ctx, QualType Type);
 
   /// Get the raw byte representation of the type. You can only rely on the
   /// types being equal iff their raw representation is the same. The particular
@@ -55,7 +55,7 @@
   }
 
 private:
-  static llvm::Optional<OpaqueType> encode(ASTContext &Ctx, QualType Type);
+  static std::optional<OpaqueType> encode(ASTContext &Ctx, QualType Type);
   explicit OpaqueType(std::string Data);
 
   std::string Data;
diff --git a/clang-tools-extra/clangd/FS.cpp b/clang-tools-extra/clangd/FS.cpp
index 587b921..3622d35 100644
--- a/clang-tools-extra/clangd/FS.cpp
+++ b/clang-tools-extra/clangd/FS.cpp
@@ -36,7 +36,7 @@
   StatCache.insert({PathStore, std::move(S)});
 }
 
-llvm::Optional<llvm::vfs::Status>
+std::optional<llvm::vfs::Status>
 PreambleFileStatusCache::lookup(llvm::StringRef File) const {
   // Canonicalize to match the cached form.
   // Lookup tends to be first by absolute path, so no need to make absolute.
diff --git a/clang-tools-extra/clangd/FS.h b/clang-tools-extra/clangd/FS.h
index 96b04dc..16a0a49 100644
--- a/clang-tools-extra/clangd/FS.h
+++ b/clang-tools-extra/clangd/FS.h
@@ -45,7 +45,7 @@
   void update(const llvm::vfs::FileSystem &FS, llvm::vfs::Status S);
 
   /// \p Path is a path stored in preamble.
-  llvm::Optional<llvm::vfs::Status> lookup(llvm::StringRef Path) const;
+  std::optional<llvm::vfs::Status> lookup(llvm::StringRef Path) const;
 
   /// Returns a VFS that collects file status.
   /// Only cache stats for files that exist because
diff --git a/clang-tools-extra/clangd/FeatureModule.h b/clang-tools-extra/clangd/FeatureModule.h
index eb4232f..7b68835 100644
--- a/clang-tools-extra/clangd/FeatureModule.h
+++ b/clang-tools-extra/clangd/FeatureModule.h
@@ -138,7 +138,7 @@
   using OutgoingMethod = llvm::unique_function<void(const P &, Callback<R>)>;
 
 private:
-  llvm::Optional<Facilities> Fac;
+  std::optional<Facilities> Fac;
 };
 
 /// A FeatureModuleSet is a collection of feature modules installed in clangd.
diff --git a/clang-tools-extra/clangd/FindSymbols.cpp b/clang-tools-extra/clangd/FindSymbols.cpp
index 682ca79..6e6dbb2 100644
--- a/clang-tools-extra/clangd/FindSymbols.cpp
+++ b/clang-tools-extra/clangd/FindSymbols.cpp
@@ -220,7 +220,7 @@
   return std::move(OS.str());
 }
 
-llvm::Optional<DocumentSymbol> declToSym(ASTContext &Ctx, const NamedDecl &ND) {
+std::optional<DocumentSymbol> declToSym(ASTContext &Ctx, const NamedDecl &ND) {
   auto &SM = Ctx.getSourceManager();
 
   SourceLocation BeginLoc = SM.getSpellingLoc(SM.getFileLoc(ND.getBeginLoc()));
diff --git a/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp b/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
index 37f6173..9e32fce 100644
--- a/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
+++ b/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
@@ -354,7 +354,7 @@
 DirectoryBasedGlobalCompilationDatabase::
     ~DirectoryBasedGlobalCompilationDatabase() = default;
 
-llvm::Optional<tooling::CompileCommand>
+std::optional<tooling::CompileCommand>
 DirectoryBasedGlobalCompilationDatabase::getCompileCommand(PathRef File) const {
   CDBLookupRequest Req;
   Req.FileName = File;
@@ -398,7 +398,7 @@
   return Ret;
 }
 
-llvm::Optional<DirectoryBasedGlobalCompilationDatabase::CDBLookupResult>
+std::optional<DirectoryBasedGlobalCompilationDatabase::CDBLookupResult>
 DirectoryBasedGlobalCompilationDatabase::lookupCDB(
     CDBLookupRequest Request) const {
   assert(llvm::sys::path::is_absolute(Request.FileName) &&
@@ -476,7 +476,7 @@
     Context Ctx;
   };
   std::deque<Task> Queue;
-  llvm::Optional<Task> ActiveTask;
+  std::optional<Task> ActiveTask;
   std::thread Thread; // Must be last member.
 
   // Thread body: this is just the basic queue procesing boilerplate.
@@ -725,7 +725,7 @@
   return Broadcaster->blockUntilIdle(Timeout);
 }
 
-llvm::Optional<ProjectInfo>
+std::optional<ProjectInfo>
 DirectoryBasedGlobalCompilationDatabase::getProjectInfo(PathRef File) const {
   CDBLookupRequest Req;
   Req.FileName = File;
@@ -744,9 +744,9 @@
     : DelegatingCDB(Base), Mangler(std::move(Mangler)),
       FallbackFlags(std::move(FallbackFlags)) {}
 
-llvm::Optional<tooling::CompileCommand>
+std::optional<tooling::CompileCommand>
 OverlayCDB::getCompileCommand(PathRef File) const {
-  llvm::Optional<tooling::CompileCommand> Cmd;
+  std::optional<tooling::CompileCommand> Cmd;
   {
     std::lock_guard<std::mutex> Lock(Mutex);
     auto It = Commands.find(removeDots(File));
@@ -772,8 +772,8 @@
   return Cmd;
 }
 
-void OverlayCDB::setCompileCommand(
-    PathRef File, llvm::Optional<tooling::CompileCommand> Cmd) {
+void OverlayCDB::setCompileCommand(PathRef File,
+                                   std::optional<tooling::CompileCommand> Cmd) {
   // We store a canonical version internally to prevent mismatches between set
   // and get compile commands. Also it assures clients listening to broadcasts
   // doesn't receive different names for the same file.
@@ -801,14 +801,14 @@
   BaseOwner = std::move(Base);
 }
 
-llvm::Optional<tooling::CompileCommand>
+std::optional<tooling::CompileCommand>
 DelegatingCDB::getCompileCommand(PathRef File) const {
   if (!Base)
     return std::nullopt;
   return Base->getCompileCommand(File);
 }
 
-llvm::Optional<ProjectInfo> DelegatingCDB::getProjectInfo(PathRef File) const {
+std::optional<ProjectInfo> DelegatingCDB::getProjectInfo(PathRef File) const {
   if (!Base)
     return std::nullopt;
   return Base->getProjectInfo(File);
diff --git a/clang-tools-extra/clangd/GlobalCompilationDatabase.h b/clang-tools-extra/clangd/GlobalCompilationDatabase.h
index 04481fa..12cf280 100644
--- a/clang-tools-extra/clangd/GlobalCompilationDatabase.h
+++ b/clang-tools-extra/clangd/GlobalCompilationDatabase.h
@@ -38,11 +38,11 @@
   virtual ~GlobalCompilationDatabase() = default;
 
   /// If there are any known-good commands for building this file, returns one.
-  virtual llvm::Optional<tooling::CompileCommand>
+  virtual std::optional<tooling::CompileCommand>
   getCompileCommand(PathRef File) const = 0;
 
   /// Finds the closest project to \p File.
-  virtual llvm::Optional<ProjectInfo> getProjectInfo(PathRef File) const {
+  virtual std::optional<ProjectInfo> getProjectInfo(PathRef File) const {
     return std::nullopt;
   }
 
@@ -72,10 +72,10 @@
   DelegatingCDB(const GlobalCompilationDatabase *Base);
   DelegatingCDB(std::unique_ptr<GlobalCompilationDatabase> Base);
 
-  llvm::Optional<tooling::CompileCommand>
+  std::optional<tooling::CompileCommand>
   getCompileCommand(PathRef File) const override;
 
-  llvm::Optional<ProjectInfo> getProjectInfo(PathRef File) const override;
+  std::optional<ProjectInfo> getProjectInfo(PathRef File) const override;
 
   tooling::CompileCommand getFallbackCommand(PathRef File) const override;
 
@@ -116,12 +116,12 @@
   /// Scans File's parents looking for compilation databases.
   /// Any extra flags will be added.
   /// Might trigger OnCommandChanged, if CDB wasn't broadcasted yet.
-  llvm::Optional<tooling::CompileCommand>
+  std::optional<tooling::CompileCommand>
   getCompileCommand(PathRef File) const override;
 
   /// Returns the path to first directory containing a compilation database in
   /// \p File's parents.
-  llvm::Optional<ProjectInfo> getProjectInfo(PathRef File) const override;
+  std::optional<ProjectInfo> getProjectInfo(PathRef File) const override;
 
   bool blockUntilIdle(Deadline Timeout) const override;
 
@@ -150,7 +150,7 @@
     std::shared_ptr<const tooling::CompilationDatabase> CDB;
     ProjectInfo PI;
   };
-  llvm::Optional<CDBLookupResult> lookupCDB(CDBLookupRequest Request) const;
+  std::optional<CDBLookupResult> lookupCDB(CDBLookupRequest Request) const;
 
   class BroadcastThread;
   std::unique_ptr<BroadcastThread> Broadcaster;
@@ -186,14 +186,14 @@
              std::vector<std::string> FallbackFlags = {},
              CommandMangler Mangler = nullptr);
 
-  llvm::Optional<tooling::CompileCommand>
+  std::optional<tooling::CompileCommand>
   getCompileCommand(PathRef File) const override;
   tooling::CompileCommand getFallbackCommand(PathRef File) const override;
 
   /// Sets or clears the compilation command for a particular file.
   void
   setCompileCommand(PathRef File,
-                    llvm::Optional<tooling::CompileCommand> CompilationCommand);
+                    std::optional<tooling::CompileCommand> CompilationCommand);
 
 private:
   mutable std::mutex Mutex;
diff --git a/clang-tools-extra/clangd/HeaderSourceSwitch.cpp b/clang-tools-extra/clangd/HeaderSourceSwitch.cpp
index ded7a43..2351858 100644
--- a/clang-tools-extra/clangd/HeaderSourceSwitch.cpp
+++ b/clang-tools-extra/clangd/HeaderSourceSwitch.cpp
@@ -18,7 +18,7 @@
 namespace clang {
 namespace clangd {
 
-llvm::Optional<Path> getCorrespondingHeaderOrSource(
+std::optional<Path> getCorrespondingHeaderOrSource(
     PathRef OriginalFile, llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) {
   llvm::StringRef SourceExtensions[] = {".cpp", ".c", ".cc", ".cxx",
                                         ".c++", ".m", ".mm"};
@@ -64,9 +64,9 @@
   return std::nullopt;
 }
 
-llvm::Optional<Path> getCorrespondingHeaderOrSource(PathRef OriginalFile,
-                                                    ParsedAST &AST,
-                                                    const SymbolIndex *Index) {
+std::optional<Path> getCorrespondingHeaderOrSource(PathRef OriginalFile,
+                                                   ParsedAST &AST,
+                                                   const SymbolIndex *Index) {
   if (!Index) {
     // FIXME: use the AST to do the inference.
     return std::nullopt;
diff --git a/clang-tools-extra/clangd/HeaderSourceSwitch.h b/clang-tools-extra/clangd/HeaderSourceSwitch.h
index 1cf9da9..aa1d73e 100644
--- a/clang-tools-extra/clangd/HeaderSourceSwitch.h
+++ b/clang-tools-extra/clangd/HeaderSourceSwitch.h
@@ -18,14 +18,14 @@
 
 /// Given a header file, returns the best matching source file, and vice visa.
 /// It only uses the filename heuristics to do the inference.
-llvm::Optional<Path> getCorrespondingHeaderOrSource(
+std::optional<Path> getCorrespondingHeaderOrSource(
     PathRef OriginalFile, llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS);
 
 /// Given a header file, returns the best matching source file, and vice visa.
 /// The heuristics incorporate with the AST and the index (if provided).
-llvm::Optional<Path> getCorrespondingHeaderOrSource(PathRef OriginalFile,
-                                                    ParsedAST &AST,
-                                                    const SymbolIndex *Index);
+std::optional<Path> getCorrespondingHeaderOrSource(PathRef OriginalFile,
+                                                   ParsedAST &AST,
+                                                   const SymbolIndex *Index);
 
 /// Returns all indexable decls that are present in the main file of the AST.
 /// Exposed for unittests.
diff --git a/clang-tools-extra/clangd/Headers.cpp b/clang-tools-extra/clangd/Headers.cpp
index fd058e8..3e5fefb 100644
--- a/clang-tools-extra/clangd/Headers.cpp
+++ b/clang-tools-extra/clangd/Headers.cpp
@@ -235,7 +235,7 @@
   CI.getPreprocessor().addPPCallbacks(std::move(Collector));
 }
 
-llvm::Optional<IncludeStructure::HeaderID>
+std::optional<IncludeStructure::HeaderID>
 IncludeStructure::getID(const FileEntry *Entry) const {
   // HeaderID of the main file is always 0;
   if (Entry == MainFileEntry) {
@@ -315,7 +315,7 @@
   return !Included(DeclaringHeader) && !Included(InsertedHeader.File);
 }
 
-llvm::Optional<std::string>
+std::optional<std::string>
 IncludeInserter::calculateIncludePath(const HeaderFile &InsertedHeader,
                                       llvm::StringRef IncludingFile) const {
   assert(InsertedHeader.valid());
@@ -345,10 +345,10 @@
   return Suggested;
 }
 
-llvm::Optional<TextEdit>
+std::optional<TextEdit>
 IncludeInserter::insert(llvm::StringRef VerbatimHeader,
                         tooling::IncludeDirective Directive) const {
-  llvm::Optional<TextEdit> Edit;
+  std::optional<TextEdit> Edit;
   if (auto Insertion =
           Inserter.insert(VerbatimHeader.trim("\"<>"),
                           VerbatimHeader.startswith("<"), Directive))
diff --git a/clang-tools-extra/clangd/Headers.h b/clang-tools-extra/clangd/Headers.h
index 68ccf93..8a5b885 100644
--- a/clang-tools-extra/clangd/Headers.h
+++ b/clang-tools-extra/clangd/Headers.h
@@ -72,7 +72,7 @@
   unsigned HashOffset = 0; // Byte offset from start of file to #.
   int HashLine = 0;        // Line number containing the directive, 0-indexed.
   SrcMgr::CharacteristicKind FileKind = SrcMgr::C_User;
-  llvm::Optional<unsigned> HeaderID;
+  std::optional<unsigned> HeaderID;
   bool BehindPragmaKeep = false; // Has IWYU pragma: keep right after.
 };
 llvm::raw_ostream &operator<<(llvm::raw_ostream &, const Inclusion &);
@@ -143,7 +143,7 @@
   // file builds.
   enum class HeaderID : unsigned {};
 
-  llvm::Optional<HeaderID> getID(const FileEntry *Entry) const;
+  std::optional<HeaderID> getID(const FileEntry *Entry) const;
   HeaderID getOrCreateID(FileEntryRef Entry);
 
   StringRef getRealPath(HeaderID ID) const {
@@ -243,14 +243,14 @@
   ///
   /// \return A quoted "path" or <path> to be included, or std::nullopt if it
   /// couldn't be shortened.
-  llvm::Optional<std::string>
+  std::optional<std::string>
   calculateIncludePath(const HeaderFile &InsertedHeader,
                        llvm::StringRef IncludingFile) const;
 
   /// Calculates an edit that inserts \p VerbatimHeader into code. If the header
   /// is already included, this returns std::nullopt.
-  llvm::Optional<TextEdit> insert(llvm::StringRef VerbatimHeader,
-                                  tooling::IncludeDirective Directive) const;
+  std::optional<TextEdit> insert(llvm::StringRef VerbatimHeader,
+                                 tooling::IncludeDirective Directive) const;
 
 private:
   StringRef FileName;
diff --git a/clang-tools-extra/clangd/Hover.cpp b/clang-tools-extra/clangd/Hover.cpp
index ca63019..456b544 100644
--- a/clang-tools-extra/clangd/Hover.cpp
+++ b/clang-tools-extra/clangd/Hover.cpp
@@ -402,8 +402,8 @@
   return llvm::format_hex(Bits, 0);
 }
 
-llvm::Optional<std::string> printExprValue(const Expr *E,
-                                           const ASTContext &Ctx) {
+std::optional<std::string> printExprValue(const Expr *E,
+                                          const ASTContext &Ctx) {
   // InitListExpr has two forms, syntactic and semantic. They are the same thing
   // (refer to a same AST node) in most cases.
   // When they are different, RAV returns the syntactic form, and we should feed
@@ -451,8 +451,8 @@
   return Constant.Val.getAsString(Ctx, T);
 }
 
-llvm::Optional<std::string> printExprValue(const SelectionTree::Node *N,
-                                           const ASTContext &Ctx) {
+std::optional<std::string> printExprValue(const SelectionTree::Node *N,
+                                          const ASTContext &Ctx) {
   for (; N; N = N->Parent) {
     // Try to evaluate the first evaluatable enclosing expression.
     if (const Expr *E = N->ASTNode.get<Expr>()) {
@@ -471,7 +471,7 @@
   return std::nullopt;
 }
 
-llvm::Optional<StringRef> fieldName(const Expr *E) {
+std::optional<StringRef> fieldName(const Expr *E) {
   const auto *ME = llvm::dyn_cast<MemberExpr>(E->IgnoreCasts());
   if (!ME || !llvm::isa<CXXThisExpr>(ME->getBase()->IgnoreCasts()))
     return std::nullopt;
@@ -482,7 +482,7 @@
 }
 
 // If CMD is of the form T foo() { return FieldName; } then returns "FieldName".
-llvm::Optional<StringRef> getterVariableName(const CXXMethodDecl *CMD) {
+std::optional<StringRef> getterVariableName(const CXXMethodDecl *CMD) {
   assert(CMD->hasBody());
   if (CMD->getNumParams() != 0 || CMD->isVariadic())
     return std::nullopt;
@@ -501,7 +501,7 @@
 //   void foo(T arg) { FieldName = std::move(arg); }
 //   R foo(T arg) { FieldName = std::move(arg); return *this; }
 // then returns "FieldName"
-llvm::Optional<StringRef> setterVariableName(const CXXMethodDecl *CMD) {
+std::optional<StringRef> setterVariableName(const CXXMethodDecl *CMD) {
   assert(CMD->hasBody());
   if (CMD->isConst() || CMD->getNumParams() != 1 || CMD->isVariadic())
     return std::nullopt;
@@ -1283,8 +1283,8 @@
 
 // If the backtick at `Offset` starts a probable quoted range, return the range
 // (including the quotes).
-llvm::Optional<llvm::StringRef> getBacktickQuoteRange(llvm::StringRef Line,
-                                                      unsigned Offset) {
+std::optional<llvm::StringRef> getBacktickQuoteRange(llvm::StringRef Line,
+                                                     unsigned Offset) {
   assert(Line[Offset] == '`');
 
   // The open-quote is usually preceded by whitespace.
diff --git a/clang-tools-extra/clangd/Hover.h b/clang-tools-extra/clangd/Hover.h
index a2c4e60..e63ff95 100644
--- a/clang-tools-extra/clangd/Hover.h
+++ b/clang-tools-extra/clangd/Hover.h
@@ -33,7 +33,7 @@
     /// Pretty-printed type
     std::string Type;
     /// Desugared type
-    llvm::Optional<std::string> AKA;
+    std::optional<std::string> AKA;
   };
 
   /// Represents parameters of a function, a template or a macro.
@@ -44,11 +44,11 @@
   struct Param {
     /// The printable parameter type, e.g. "int", or "typename" (in
     /// TemplateParameters), might be std::nullopt for macro parameters.
-    llvm::Optional<PrintedType> Type;
+    std::optional<PrintedType> Type;
     /// std::nullopt for unnamed parameters.
     std::optional<std::string> Name;
     /// std::nullopt if no default is provided.
-    llvm::Optional<std::string> Default;
+    std::optional<std::string> Default;
   };
 
   /// For a variable named Bar, declared in clang::clangd::Foo::getFoo the
@@ -61,13 +61,13 @@
   /// auto/decltype.
   /// Contains all of the enclosing namespaces, empty string means global
   /// namespace.
-  llvm::Optional<std::string> NamespaceScope;
+  std::optional<std::string> NamespaceScope;
   /// Remaining named contexts in symbol's qualified name, empty string means
   /// symbol is not local.
   std::string LocalScope;
   /// Name of the symbol, does not contain any "::".
   std::string Name;
-  llvm::Optional<Range> SymRange;
+  std::optional<Range> SymRange;
   index::SymbolKind Kind = index::SymbolKind::Unknown;
   std::string Documentation;
   /// Source code containing the definition of the symbol.
@@ -78,24 +78,24 @@
   std::string AccessSpecifier;
   /// Printable variable type.
   /// Set only for variables.
-  llvm::Optional<PrintedType> Type;
+  std::optional<PrintedType> Type;
   /// Set for functions and lambdas.
-  llvm::Optional<PrintedType> ReturnType;
+  std::optional<PrintedType> ReturnType;
   /// Set for functions, lambdas and macros with parameters.
-  llvm::Optional<std::vector<Param>> Parameters;
+  std::optional<std::vector<Param>> Parameters;
   /// Set for all templates(function, class, variable).
-  llvm::Optional<std::vector<Param>> TemplateParameters;
+  std::optional<std::vector<Param>> TemplateParameters;
   /// Contains the evaluated value of the symbol if available.
-  llvm::Optional<std::string> Value;
+  std::optional<std::string> Value;
   /// Contains the byte-size of fields and types where it's interesting.
-  llvm::Optional<uint64_t> Size;
+  std::optional<uint64_t> Size;
   /// Contains the offset of fields within the enclosing class.
-  llvm::Optional<uint64_t> Offset;
+  std::optional<uint64_t> Offset;
   /// Contains the padding following a field within the enclosing class.
-  llvm::Optional<uint64_t> Padding;
+  std::optional<uint64_t> Padding;
   // Set when symbol is inside function call. Contains information extracted
   // from the callee definition about the argument this is passed as.
-  llvm::Optional<Param> CalleeArgInfo;
+  std::optional<Param> CalleeArgInfo;
   struct PassType {
     // How the variable is passed to callee.
     enum PassMode { Ref, ConstRef, Value };
@@ -106,7 +106,7 @@
     bool Converted = false;
   };
   // Set only if CalleeArgInfo is set.
-  llvm::Optional<PassType> CallPassType;
+  std::optional<PassType> CallPassType;
 
   /// Produce a user-readable information.
   markup::Document present() const;
diff --git a/clang-tools-extra/clangd/IncludeCleaner.cpp b/clang-tools-extra/clangd/IncludeCleaner.cpp
index daac976..dbed805 100644
--- a/clang-tools-extra/clangd/IncludeCleaner.cpp
+++ b/clang-tools-extra/clangd/IncludeCleaner.cpp
@@ -345,7 +345,7 @@
 ReferencedFiles findReferencedFiles(
     const ReferencedLocations &Locs, const SourceManager &SM,
     llvm::function_ref<FileID(FileID)> HeaderResponsible,
-    llvm::function_ref<Optional<StringRef>(FileID)> UmbrellaHeader) {
+    llvm::function_ref<std::optional<StringRef>(FileID)> UmbrellaHeader) {
   std::vector<SourceLocation> Sorted{Locs.User.begin(), Locs.User.end()};
   llvm::sort(Sorted); // Group by FileID.
   ReferencedFilesBuilder Builder(SM);
@@ -390,7 +390,7 @@
       [&SM, &Includes](FileID ID) {
         return headerResponsible(ID, SM, Includes);
       },
-      [&SM, &CanonIncludes](FileID ID) -> Optional<StringRef> {
+      [&SM, &CanonIncludes](FileID ID) -> std::optional<StringRef> {
         auto Entry = SM.getFileEntryRefForID(ID);
         if (!Entry)
           return std::nullopt;
diff --git a/clang-tools-extra/clangd/IncludeCleaner.h b/clang-tools-extra/clangd/IncludeCleaner.h
index fc3d04d..8d8a5f7 100644
--- a/clang-tools-extra/clangd/IncludeCleaner.h
+++ b/clang-tools-extra/clangd/IncludeCleaner.h
@@ -77,7 +77,7 @@
 ReferencedFiles findReferencedFiles(
     const ReferencedLocations &Locs, const SourceManager &SM,
     llvm::function_ref<FileID(FileID)> HeaderResponsible,
-    llvm::function_ref<Optional<StringRef>(FileID)> UmbrellaHeader);
+    llvm::function_ref<std::optional<StringRef>(FileID)> UmbrellaHeader);
 ReferencedFiles findReferencedFiles(const ReferencedLocations &Locs,
                                     const IncludeStructure &Includes,
                                     const CanonicalIncludes &CanonIncludes,
diff --git a/clang-tools-extra/clangd/IncludeFixer.cpp b/clang-tools-extra/clangd/IncludeFixer.cpp
index 5ab9932..f6b3977 100644
--- a/clang-tools-extra/clangd/IncludeFixer.cpp
+++ b/clang-tools-extra/clangd/IncludeFixer.cpp
@@ -50,8 +50,8 @@
 namespace clangd {
 namespace {
 
-llvm::Optional<llvm::StringRef> getArgStr(const clang::Diagnostic &Info,
-                                          unsigned Index) {
+std::optional<llvm::StringRef> getArgStr(const clang::Diagnostic &Info,
+                                         unsigned Index) {
   switch (Info.getArgKind(Index)) {
   case DiagnosticsEngine::ak_c_string:
     return llvm::StringRef(Info.getArgCStr(Index));
@@ -62,7 +62,7 @@
   }
 }
 
-std::vector<Fix> only(llvm::Optional<Fix> F) {
+std::vector<Fix> only(std::optional<Fix> F) {
   if (F)
     return {std::move(*F)};
   return {};
@@ -248,7 +248,7 @@
   return {};
 }
 
-llvm::Optional<Fix> IncludeFixer::insertHeader(llvm::StringRef Spelled,
+std::optional<Fix> IncludeFixer::insertHeader(llvm::StringRef Spelled,
                                                llvm::StringRef Symbol,
                                                tooling::IncludeDirective Directive) const {
   Fix F;
@@ -282,7 +282,7 @@
   auto ID = getSymbolID(TD);
   if (!ID)
     return {};
-  llvm::Optional<const SymbolSlab *> Symbols = lookupCached(ID);
+  std::optional<const SymbolSlab *> Symbols = lookupCached(ID);
   if (!Symbols)
     return {};
   const SymbolSlab &Syms = **Symbols;
@@ -347,7 +347,7 @@
 // "::X::Y" that is qualified by unresolved name "clangd":
 //     clang::clangd::X::Y
 //            ~
-llvm::Optional<std::string> qualifiedByUnresolved(const SourceManager &SM,
+std::optional<std::string> qualifiedByUnresolved(const SourceManager &SM,
                                                   SourceLocation Loc,
                                                   const LangOptions &LangOpts) {
   std::string Result;
@@ -373,15 +373,15 @@
   // This is the part of what was typed that was resolved, and it's in its
   // resolved form not its typed form (think `namespace clang { clangd::x }` -->
   // `clang::clangd::`).
-  llvm::Optional<std::string> ResolvedScope;
+  std::optional<std::string> ResolvedScope;
 
   // Unresolved part of the scope. When the unresolved name is a specifier, we
   // use the name that comes after it as the alternative name to resolve and use
   // the specifier as the extra scope in the accessible scopes.
-  llvm::Optional<std::string> UnresolvedScope;
+  std::optional<std::string> UnresolvedScope;
 };
 
-llvm::Optional<std::string> getSpelledSpecifier(const CXXScopeSpec &SS,
+std::optional<std::string> getSpelledSpecifier(const CXXScopeSpec &SS,
     const SourceManager &SM) {
   // Support specifiers written within a single macro argument.
   if (!SM.isWrittenInSameFile(SS.getBeginLoc(), SS.getEndLoc()))
@@ -395,7 +395,7 @@
 
 // Extracts unresolved name and scope information around \p Unresolved.
 // FIXME: try to merge this with the scope-wrangling code in CodeComplete.
-llvm::Optional<CheapUnresolvedName> extractUnresolvedNameCheaply(
+std::optional<CheapUnresolvedName> extractUnresolvedNameCheaply(
     const SourceManager &SM, const DeclarationNameInfo &Unresolved,
     CXXScopeSpec *SS, const LangOptions &LangOpts, bool UnresolvedIsSpecifier) {
   CheapUnresolvedName Result;
@@ -406,7 +406,7 @@
         Result.ResolvedScope = "";
       } else if (const auto *NS = Nested->getAsNamespace()) {
         std::string SpecifiedNS = printNamespaceScope(*NS);
-        llvm::Optional<std::string> Spelling = getSpelledSpecifier(*SS, SM);
+        std::optional<std::string> Spelling = getSpelledSpecifier(*SS, SM);
 
         // Check the specifier spelled in the source.
         // If the resolved scope doesn't end with the spelled scope, the
@@ -491,7 +491,7 @@
 
 class IncludeFixer::UnresolvedNameRecorder : public ExternalSemaSource {
 public:
-  UnresolvedNameRecorder(llvm::Optional<UnresolvedName> &LastUnresolvedName)
+  UnresolvedNameRecorder(std::optional<UnresolvedName> &LastUnresolvedName)
       : LastUnresolvedName(LastUnresolvedName) {}
 
   void InitializeSema(Sema &S) override { this->SemaPtr = &S; }
@@ -544,7 +544,7 @@
 private:
   Sema *SemaPtr = nullptr;
 
-  llvm::Optional<UnresolvedName> &LastUnresolvedName;
+  std::optional<UnresolvedName> &LastUnresolvedName;
 };
 
 llvm::IntrusiveRefCntPtr<ExternalSemaSource>
@@ -565,13 +565,13 @@
   Req.RestrictForCodeCompletion = true;
   Req.Limit = 100;
 
-  if (llvm::Optional<const SymbolSlab *> Syms = fuzzyFindCached(Req))
+  if (std::optional<const SymbolSlab *> Syms = fuzzyFindCached(Req))
     return fixesForSymbols(**Syms);
 
   return {};
 }
 
-llvm::Optional<const SymbolSlab *>
+std::optional<const SymbolSlab *>
 IncludeFixer::fuzzyFindCached(const FuzzyFindRequest &Req) const {
   auto ReqStr = llvm::formatv("{0}", toJSON(Req)).str();
   auto I = FuzzyFindCache.find(ReqStr);
@@ -594,7 +594,7 @@
   return &E.first->second;
 }
 
-llvm::Optional<const SymbolSlab *>
+std::optional<const SymbolSlab *>
 IncludeFixer::lookupCached(const SymbolID &ID) const {
   LookupRequest Req;
   Req.IDs.insert(ID);
diff --git a/clang-tools-extra/clangd/IncludeFixer.h b/clang-tools-extra/clangd/IncludeFixer.h
index 2a74c23..0c51ad9 100644
--- a/clang-tools-extra/clangd/IncludeFixer.h
+++ b/clang-tools-extra/clangd/IncludeFixer.h
@@ -56,10 +56,10 @@
   /// Generates header insertion fixes for all symbols. Fixes are deduplicated.
   std::vector<Fix> fixesForSymbols(const SymbolSlab &Syms) const;
 
-  llvm::Optional<Fix>
-  insertHeader(llvm::StringRef Name, llvm::StringRef Symbol = "",
-               tooling::IncludeDirective Directive =
-                   tooling::IncludeDirective::Include) const;
+  std::optional<Fix> insertHeader(llvm::StringRef Name,
+                                  llvm::StringRef Symbol = "",
+                                  tooling::IncludeDirective Directive =
+                                      tooling::IncludeDirective::Include) const;
 
   struct UnresolvedName {
     std::string Name;   // E.g. "X" in foo::X.
@@ -84,7 +84,7 @@
 
   // These collect the last unresolved name so that we can associate it with the
   // diagnostic.
-  llvm::Optional<UnresolvedName> LastUnresolvedName;
+  std::optional<UnresolvedName> LastUnresolvedName;
 
   // There can be multiple diagnostics that are caused by the same unresolved
   // name or incomplete type in one parse, especially when code is
@@ -93,9 +93,9 @@
   mutable llvm::StringMap<SymbolSlab> FuzzyFindCache;
   mutable llvm::DenseMap<SymbolID, SymbolSlab> LookupCache;
   // Returns std::nullopt if the number of index requests has reached the limit.
-  llvm::Optional<const SymbolSlab *>
+  std::optional<const SymbolSlab *>
   fuzzyFindCached(const FuzzyFindRequest &Req) const;
-  llvm::Optional<const SymbolSlab *> lookupCached(const SymbolID &ID) const;
+  std::optional<const SymbolSlab *> lookupCached(const SymbolID &ID) const;
 };
 
 } // namespace clangd
diff --git a/clang-tools-extra/clangd/InlayHints.cpp b/clang-tools-extra/clangd/InlayHints.cpp
index 20a8adc..30c7c05 100644
--- a/clang-tools-extra/clangd/InlayHints.cpp
+++ b/clang-tools-extra/clangd/InlayHints.cpp
@@ -648,7 +648,7 @@
   }
 
   // Get the range of the main file that *exactly* corresponds to R.
-  llvm::Optional<Range> getHintRange(SourceRange R) {
+  std::optional<Range> getHintRange(SourceRange R) {
     const auto &SM = AST.getSourceManager();
     auto Spelled = Tokens.spelledForExpanded(Tokens.expandedTokens(R));
     // TokenBuffer will return null if e.g. R corresponds to only part of a
diff --git a/clang-tools-extra/clangd/JSONTransport.cpp b/clang-tools-extra/clangd/JSONTransport.cpp
index 50b1833..9dc0df8 100644
--- a/clang-tools-extra/clangd/JSONTransport.cpp
+++ b/clang-tools-extra/clangd/JSONTransport.cpp
@@ -164,12 +164,12 @@
   // Message must be an object with "jsonrpc":"2.0".
   auto *Object = Message.getAsObject();
   if (!Object ||
-      Object->getString("jsonrpc") != llvm::Optional<llvm::StringRef>("2.0")) {
+      Object->getString("jsonrpc") != std::optional<llvm::StringRef>("2.0")) {
     elog("Not a JSON-RPC 2.0 message: {0:2}", Message);
     return false;
   }
   // ID may be any JSON value. If absent, this is a notification.
-  llvm::Optional<llvm::json::Value> ID;
+  std::optional<llvm::json::Value> ID;
   if (auto *I = Object->get("id"))
     ID = std::move(*I);
   auto Method = Object->getString("method");
diff --git a/clang-tools-extra/clangd/ParsedAST.cpp b/clang-tools-extra/clangd/ParsedAST.cpp
index c2846749..cd814c8 100644
--- a/clang-tools-extra/clangd/ParsedAST.cpp
+++ b/clang-tools-extra/clangd/ParsedAST.cpp
@@ -339,7 +339,7 @@
 
 } // namespace
 
-llvm::Optional<ParsedAST>
+std::optional<ParsedAST>
 ParsedAST::build(llvm::StringRef Filename, const ParseInputs &Inputs,
                  std::unique_ptr<clang::CompilerInvocation> CI,
                  llvm::ArrayRef<Diag> CompilerInvocationDiags,
@@ -376,7 +376,7 @@
                        [&](const auto &L) { L->sawDiagnostic(D, Diag); });
       });
 
-  llvm::Optional<PreamblePatch> Patch;
+  std::optional<PreamblePatch> Patch;
   bool PreserveDiags = true;
   // We might use an ignoring diagnostic consumer if they are going to be
   // dropped later on to not pay for extra latency by processing them.
@@ -465,10 +465,10 @@
   // In practice almost all checks work well without modifications.
   std::vector<std::unique_ptr<tidy::ClangTidyCheck>> CTChecks;
   ast_matchers::MatchFinder CTFinder;
-  llvm::Optional<tidy::ClangTidyContext> CTContext;
+  std::optional<tidy::ClangTidyContext> CTContext;
   // Must outlive FixIncludes.
   auto BuildDir = VFS->getCurrentWorkingDirectory();
-  llvm::Optional<IncludeFixer> FixIncludes;
+  std::optional<IncludeFixer> FixIncludes;
   llvm::DenseMap<diag::kind, DiagnosticsEngine::Level> OverriddenSeverity;
   // No need to run clang-tidy or IncludeFixerif we are not going to surface
   // diagnostics.
@@ -653,7 +653,7 @@
   // CompilerInstance won't run this callback, do it directly.
   ASTDiags.EndSourceFile();
 
-  llvm::Optional<std::vector<Diag>> Diags;
+  std::optional<std::vector<Diag>> Diags;
   // FIXME: Also skip generation of diagnostics alltogether to speed up ast
   // builds when we are patching a stale preamble.
   if (PreserveDiags) {
@@ -770,7 +770,7 @@
                      syntax::TokenBuffer Tokens, MainFileMacros Macros,
                      std::vector<PragmaMark> Marks,
                      std::vector<Decl *> LocalTopLevelDecls,
-                     llvm::Optional<std::vector<Diag>> Diags,
+                     std::optional<std::vector<Diag>> Diags,
                      IncludeStructure Includes, CanonicalIncludes CanonIncludes)
     : TUPath(TUPath), Version(Version), Preamble(std::move(Preamble)),
       Clang(std::move(Clang)), Action(std::move(Action)),
@@ -783,7 +783,7 @@
   assert(this->Action);
 }
 
-llvm::Optional<llvm::StringRef> ParsedAST::preambleVersion() const {
+std::optional<llvm::StringRef> ParsedAST::preambleVersion() const {
   if (!Preamble)
     return std::nullopt;
   return llvm::StringRef(Preamble->Version);
diff --git a/clang-tools-extra/clangd/ParsedAST.h b/clang-tools-extra/clangd/ParsedAST.h
index 8f74c17..f0085d7 100644
--- a/clang-tools-extra/clangd/ParsedAST.h
+++ b/clang-tools-extra/clangd/ParsedAST.h
@@ -49,7 +49,7 @@
   /// Attempts to run Clang and store the parsed AST.
   /// If \p Preamble is non-null it is reused during parsing.
   /// This function does not check if preamble is valid to reuse.
-  static llvm::Optional<ParsedAST>
+  static std::optional<ParsedAST>
   build(llvm::StringRef Filename, const ParseInputs &Inputs,
         std::unique_ptr<clang::CompilerInvocation> CI,
         llvm::ArrayRef<Diag> CompilerInvocationDiags,
@@ -88,7 +88,7 @@
   /// (These should be const, but RecursiveASTVisitor requires Decl*).
   ArrayRef<Decl *> getLocalTopLevelDecls();
 
-  const llvm::Optional<std::vector<Diag>> &getDiagnostics() const {
+  const std::optional<std::vector<Diag>> &getDiagnostics() const {
     return Diags;
   }
 
@@ -115,7 +115,7 @@
 
   /// Returns the version of the ParseInputs used to build Preamble part of this
   /// AST. Might be std::nullopt if no Preamble is used.
-  llvm::Optional<llvm::StringRef> preambleVersion() const;
+  std::optional<llvm::StringRef> preambleVersion() const;
 
   const HeuristicResolver *getHeuristicResolver() const {
     return Resolver.get();
@@ -128,7 +128,7 @@
             std::unique_ptr<FrontendAction> Action, syntax::TokenBuffer Tokens,
             MainFileMacros Macros, std::vector<PragmaMark> Marks,
             std::vector<Decl *> LocalTopLevelDecls,
-            llvm::Optional<std::vector<Diag>> Diags, IncludeStructure Includes,
+            std::optional<std::vector<Diag>> Diags, IncludeStructure Includes,
             CanonicalIncludes CanonIncludes);
 
   Path TUPath;
@@ -155,7 +155,7 @@
   std::vector<PragmaMark> Marks;
   // Data, stored after parsing. std::nullopt if AST was built with a stale
   // preamble.
-  llvm::Optional<std::vector<Diag>> Diags;
+  std::optional<std::vector<Diag>> Diags;
   // Top-level decls inside the current file. Not that this does not include
   // top-level decls from the preamble.
   std::vector<Decl *> LocalTopLevelDecls;
diff --git a/clang-tools-extra/clangd/Protocol.h b/clang-tools-extra/clangd/Protocol.h
index 9cd1955..9056ae6 100644
--- a/clang-tools-extra/clangd/Protocol.h
+++ b/clang-tools-extra/clangd/Protocol.h
@@ -416,7 +416,7 @@
 struct ClientCapabilities {
   /// The supported set of SymbolKinds for workspace/symbol.
   /// workspace.symbol.symbolKind.valueSet
-  llvm::Optional<SymbolKindBitset> WorkspaceSymbolKinds;
+  std::optional<SymbolKindBitset> WorkspaceSymbolKinds;
 
   /// Whether the client accepts diagnostics with codeActions attached inline.
   /// textDocument.publishDiagnostics.codeActionsInline.
@@ -469,7 +469,7 @@
 
   /// The supported set of CompletionItemKinds for textDocument/completion.
   /// textDocument.completion.completionItemKind.valueSet
-  llvm::Optional<CompletionItemKindBitset> CompletionItemKinds;
+  std::optional<CompletionItemKindBitset> CompletionItemKinds;
 
   /// The documentation format that should be used for textDocument/completion.
   /// textDocument.completion.completionItem.documentationFormat
@@ -490,7 +490,7 @@
   bool TheiaSemanticHighlighting = false;
 
   /// Supported encodings for LSP character offsets. (clangd extension).
-  llvm::Optional<std::vector<OffsetEncoding>> offsetEncoding;
+  std::optional<std::vector<OffsetEncoding>> offsetEncoding;
 
   /// The content format that should be used for Hover requests.
   /// textDocument.hover.contentEncoding
@@ -651,14 +651,14 @@
   ///
   /// Clients that don't support cancellation or don't support control
   /// the button's enablement state are allowed to ignore the setting.
-  llvm::Optional<bool> cancellable;
+  std::optional<bool> cancellable;
 
   /// Optional, more detailed associated progress message. Contains
   /// complementary information to the `title`.
   ///
   /// Examples: "3/25 files", "project/src/module2", "node_modules/some_dep".
   /// If unset, the previous progress message (if any) is still valid.
-  llvm::Optional<std::string> message;
+  std::optional<std::string> message;
 
   /// Optional progress percentage to display (value 100 is considered 100%).
   /// If not provided infinite progress is assumed and clients are allowed
@@ -666,7 +666,7 @@
   ///
   /// The value should be steadily rising. Clients are free to ignore values
   /// that are not following this rule.
-  llvm::Optional<unsigned> percentage;
+  std::optional<unsigned> percentage;
 };
 llvm::json::Value toJSON(const WorkDoneProgressReport &);
 //
@@ -674,7 +674,7 @@
 struct WorkDoneProgressEnd {
   /// Optional, a final message indicating to for example indicate the outcome
   /// of the operation.
-  llvm::Optional<std::string> message;
+  std::optional<std::string> message;
 };
 llvm::json::Value toJSON(const WorkDoneProgressEnd &);
 
@@ -879,7 +879,7 @@
   std::string code;
 
   /// An optional property to describe the error code.
-  llvm::Optional<CodeDescription> codeDescription;
+  std::optional<CodeDescription> codeDescription;
 
   /// A human-readable string describing the source of this
   /// diagnostic, e.g. 'typescript' or 'super lint'.
@@ -1019,13 +1019,13 @@
 
   /// The kind of the code action.
   /// Used to filter code actions.
-  llvm::Optional<std::string> kind;
+  std::optional<std::string> kind;
   const static llvm::StringLiteral QUICKFIX_KIND;
   const static llvm::StringLiteral REFACTOR_KIND;
   const static llvm::StringLiteral INFO_KIND;
 
   /// The diagnostics that this code action resolves.
-  llvm::Optional<std::vector<Diagnostic>> diagnostics;
+  std::optional<std::vector<Diagnostic>> diagnostics;
 
   /// Marks this as a preferred action. Preferred actions are used by the
   /// `auto fix` command and can be targeted by keybindings.
@@ -1035,11 +1035,11 @@
   bool isPreferred = false;
 
   /// The workspace edit this code action performs.
-  llvm::Optional<WorkspaceEdit> edit;
+  std::optional<WorkspaceEdit> edit;
 
   /// A command this code action executes. If a code action provides an edit
   /// and a command, first the edit is executed and then the command.
-  llvm::Optional<Command> command;
+  std::optional<Command> command;
 };
 llvm::json::Value toJSON(const CodeAction &);
 
@@ -1097,7 +1097,7 @@
   /// This can be used to re-rank results as the user types, using client-side
   /// fuzzy-matching (that score should be multiplied with this one).
   /// This is a clangd extension, set only for workspace/symbol responses.
-  llvm::Optional<float> score;
+  std::optional<float> score;
 };
 llvm::json::Value toJSON(const SymbolInformation &);
 llvm::raw_ostream &operator<<(llvm::raw_ostream &, const SymbolInformation &);
@@ -1118,9 +1118,9 @@
 
   SymbolID ID;
 
-  llvm::Optional<Location> declarationRange;
+  std::optional<Location> declarationRange;
 
-  llvm::Optional<Location> definitionRange;
+  std::optional<Location> definitionRange;
 };
 llvm::json::Value toJSON(const SymbolDetails &);
 llvm::raw_ostream &operator<<(llvm::raw_ostream &, const SymbolDetails &);
@@ -1202,7 +1202,7 @@
 
   /// An optional range is a range inside a text document
   /// that is used to visualize a hover, e.g. by changing the background color.
-  llvm::Optional<Range> range;
+  std::optional<Range> range;
 };
 llvm::json::Value toJSON(const Hover &H);
 
@@ -1261,7 +1261,7 @@
   ///
   /// Note: The range of the edit must be a single line range and it must
   /// contain the position at which completion has been requested.
-  llvm::Optional<TextEdit> textEdit;
+  std::optional<TextEdit> textEdit;
 
   /// An optional array of additional text edits that are applied when selecting
   /// this completion. Edits must not overlap with the main edit nor with
@@ -1312,7 +1312,7 @@
   /// label.
   /// Offsets are computed by lspLength(), which counts UTF-16 code units by
   /// default but that can be overriden, see its documentation for details.
-  llvm::Optional<std::pair<unsigned, unsigned>> labelOffsets;
+  std::optional<std::pair<unsigned, unsigned>> labelOffsets;
 
   /// The documentation of this parameter. Optional.
   std::string documentation;
@@ -1731,9 +1731,9 @@
 struct SemanticTokensOrDelta {
   std::string resultId;
   /// Set if we computed edits relative to a previous set of tokens.
-  llvm::Optional<std::vector<SemanticTokensEdit>> edits;
+  std::optional<std::vector<SemanticTokensEdit>> edits;
   /// Set if we computed a fresh set of tokens.
-  llvm::Optional<std::vector<SemanticToken>> tokens; // encoded as integer array
+  std::optional<std::vector<SemanticToken>> tokens; // encoded as integer array
 };
 llvm::json::Value toJSON(const SemanticTokensOrDelta &);
 
@@ -1870,7 +1870,7 @@
   std::string arcana;
   /// The range of the original source file covered by this node.
   /// May be missing for implicit nodes, or those created by macro expansion.
-  llvm::Optional<Range> range;
+  std::optional<Range> range;
   /// Nodes nested within this one, such as the operands of a BinaryOperator.
   std::vector<ASTNode> children;
 };
diff --git a/clang-tools-extra/clangd/Quality.cpp b/clang-tools-extra/clangd/Quality.cpp
index 72e3154..318488f 100644
--- a/clang-tools-extra/clangd/Quality.cpp
+++ b/clang-tools-extra/clangd/Quality.cpp
@@ -368,7 +368,7 @@
   return std::max(0.65, 2.0 * std::pow(0.6, ScopeDistance / 2.0));
 }
 
-static llvm::Optional<llvm::StringRef>
+static std::optional<llvm::StringRef>
 wordMatching(llvm::StringRef Name, const llvm::StringSet<> *ContextWords) {
   if (ContextWords)
     for (const auto &Word : ContextWords->keys())
diff --git a/clang-tools-extra/clangd/Quality.h b/clang-tools-extra/clangd/Quality.h
index 2a4efe9..5fe7045 100644
--- a/clang-tools-extra/clangd/Quality.h
+++ b/clang-tools-extra/clangd/Quality.h
@@ -106,7 +106,7 @@
 
   // Scope proximity is only considered (both index and sema) when this is set.
   ScopeDistance *ScopeProximityMatch = nullptr;
-  llvm::Optional<llvm::StringRef> SymbolScope;
+  std::optional<llvm::StringRef> SymbolScope;
   // A symbol from sema should be accessible from the current scope.
   bool SemaSaysInScope = false;
 
diff --git a/clang-tools-extra/clangd/Selection.cpp b/clang-tools-extra/clangd/Selection.cpp
index 56836fd..f46da8e 100644
--- a/clang-tools-extra/clangd/Selection.cpp
+++ b/clang-tools-extra/clangd/Selection.cpp
@@ -513,7 +513,7 @@
   }
 
   // Decomposes Loc and returns the offset if the file ID is SelFile.
-  llvm::Optional<unsigned> offsetInSelFile(SourceLocation Loc) const {
+  std::optional<unsigned> offsetInSelFile(SourceLocation Loc) const {
     // Decoding Loc with SM.getDecomposedLoc is relatively expensive.
     // But SourceLocations for a file are numerically contiguous, so we
     // can use cheap integer operations instead.
@@ -1060,7 +1060,7 @@
 SelectionTree SelectionTree::createRight(ASTContext &AST,
                                          const syntax::TokenBuffer &Tokens,
                                          unsigned int Begin, unsigned int End) {
-  llvm::Optional<SelectionTree> Result;
+  std::optional<SelectionTree> Result;
   createEach(AST, Tokens, Begin, End, [&](SelectionTree T) {
     Result = std::move(T);
     return true;
diff --git a/clang-tools-extra/clangd/SemanticHighlighting.cpp b/clang-tools-extra/clangd/SemanticHighlighting.cpp
index eaed887..db346ef 100644
--- a/clang-tools-extra/clangd/SemanticHighlighting.cpp
+++ b/clang-tools-extra/clangd/SemanticHighlighting.cpp
@@ -83,10 +83,10 @@
          isa<ObjCImplDecl>(Decl);
 }
 
-llvm::Optional<HighlightingKind> kindForType(const Type *TP,
-                                             const HeuristicResolver *Resolver);
-llvm::Optional<HighlightingKind>
-kindForDecl(const NamedDecl *D, const HeuristicResolver *Resolver) {
+std::optional<HighlightingKind> kindForType(const Type *TP,
+                                            const HeuristicResolver *Resolver);
+std::optional<HighlightingKind> kindForDecl(const NamedDecl *D,
+                                            const HeuristicResolver *Resolver) {
   if (auto *USD = dyn_cast<UsingShadowDecl>(D)) {
     if (auto *Target = USD->getTargetDecl())
       D = Target;
@@ -164,8 +164,8 @@
   }
   return std::nullopt;
 }
-llvm::Optional<HighlightingKind>
-kindForType(const Type *TP, const HeuristicResolver *Resolver) {
+std::optional<HighlightingKind> kindForType(const Type *TP,
+                                            const HeuristicResolver *Resolver) {
   if (!TP)
     return std::nullopt;
   if (TP->isBuiltinType()) // Builtins are special, they do not have decls.
@@ -332,8 +332,8 @@
 //
 // In particular, heuristically resolved dependent names get their heuristic
 // kind, plus the dependent modifier.
-llvm::Optional<HighlightingToken> resolveConflict(const HighlightingToken &A,
-                                                  const HighlightingToken &B) {
+std::optional<HighlightingToken> resolveConflict(const HighlightingToken &A,
+                                                 const HighlightingToken &B) {
   unsigned Priority1 = evaluateHighlightPriority(A);
   unsigned Priority2 = evaluateHighlightPriority(B);
   if (Priority1 == Priority2 && A.Kind != B.Kind)
@@ -342,13 +342,14 @@
   Result.Modifiers = A.Modifiers | B.Modifiers;
   return Result;
 }
-llvm::Optional<HighlightingToken>
+std::optional<HighlightingToken>
 resolveConflict(ArrayRef<HighlightingToken> Tokens) {
   if (Tokens.size() == 1)
     return Tokens[0];
 
   assert(Tokens.size() >= 2);
-  Optional<HighlightingToken> Winner = resolveConflict(Tokens[0], Tokens[1]);
+  std::optional<HighlightingToken> Winner =
+      resolveConflict(Tokens[0], Tokens[1]);
   for (size_t I = 2; Winner && I < Tokens.size(); ++I)
     Winner = resolveConflict(*Winner, Tokens[I]);
   return Winner;
@@ -474,7 +475,7 @@
   const HeuristicResolver *getResolver() const { return Resolver; }
 
 private:
-  llvm::Optional<Range> getRangeForSourceLocation(SourceLocation Loc) {
+  std::optional<Range> getRangeForSourceLocation(SourceLocation Loc) {
     Loc = getHighlightableSpellingToken(Loc, SourceMgr);
     if (Loc.isInvalid())
       return std::nullopt;
@@ -496,7 +497,7 @@
   HighlightingToken InvalidHighlightingToken;
 };
 
-llvm::Optional<HighlightingModifier> scopeModifier(const NamedDecl *D) {
+std::optional<HighlightingModifier> scopeModifier(const NamedDecl *D) {
   const DeclContext *DC = D->getDeclContext();
   // Injected "Foo" within the class "Foo" has file scope, not class scope.
   if (auto *R = dyn_cast_or_null<RecordDecl>(D))
@@ -524,7 +525,7 @@
   return HighlightingModifier::GlobalScope;
 }
 
-llvm::Optional<HighlightingModifier> scopeModifier(const Type *T) {
+std::optional<HighlightingModifier> scopeModifier(const Type *T) {
   if (!T)
     return std::nullopt;
   if (T->isBuiltinType())
@@ -672,7 +673,7 @@
       return;
     }
 
-    llvm::Optional<SourceLocation> Location;
+    std::optional<SourceLocation> Location;
 
     // FIXME Add "unwrapping" for ArraySubscriptExpr,
     //  e.g. highlight `a` in `a[i]`
diff --git a/clang-tools-extra/clangd/SemanticSelection.cpp b/clang-tools-extra/clangd/SemanticSelection.cpp
index fe01c15..b3f3d28 100644
--- a/clang-tools-extra/clangd/SemanticSelection.cpp
+++ b/clang-tools-extra/clangd/SemanticSelection.cpp
@@ -41,8 +41,8 @@
   }
 }
 
-llvm::Optional<FoldingRange> toFoldingRange(SourceRange SR,
-                                            const SourceManager &SM) {
+std::optional<FoldingRange> toFoldingRange(SourceRange SR,
+                                           const SourceManager &SM) {
   const auto Begin = SM.getDecomposedLoc(SR.getBegin()),
              End = SM.getDecomposedLoc(SR.getEnd());
   // Do not produce folding ranges if either range ends is not within the main
@@ -58,7 +58,7 @@
   return Range;
 }
 
-llvm::Optional<FoldingRange>
+std::optional<FoldingRange>
 extractFoldingRange(const syntax::Node *Node,
                     const syntax::TokenBufferTokenManager &TM) {
   if (const auto *Stmt = dyn_cast<syntax::CompoundStatement>(Node)) {
diff --git a/clang-tools-extra/clangd/SourceCode.cpp b/clang-tools-extra/clangd/SourceCode.cpp
index 90dd37f..b53e9ad 100644
--- a/clang-tools-extra/clangd/SourceCode.cpp
+++ b/clang-tools-extra/clangd/SourceCode.cpp
@@ -422,9 +422,9 @@
   return FID == SM.getMainFileID() || FID == SM.getPreambleFileID();
 }
 
-llvm::Optional<SourceRange> toHalfOpenFileRange(const SourceManager &SM,
-                                                const LangOptions &LangOpts,
-                                                SourceRange R) {
+std::optional<SourceRange> toHalfOpenFileRange(const SourceManager &SM,
+                                               const LangOptions &LangOpts,
+                                               SourceRange R) {
   SourceRange R1 = getTokenFileRange(R.getBegin(), SM, LangOpts);
   if (!isValidFileRange(SM, R1))
     return std::nullopt;
@@ -512,8 +512,8 @@
   return Edits;
 }
 
-llvm::Optional<std::string> getCanonicalPath(const FileEntry *F,
-                                             const SourceManager &SourceMgr) {
+std::optional<std::string> getCanonicalPath(const FileEntry *F,
+                                            const SourceManager &SourceMgr) {
   if (!F)
     return std::nullopt;
 
@@ -570,7 +570,7 @@
   return Result;
 }
 
-llvm::Optional<FileDigest> digestFile(const SourceManager &SM, FileID FID) {
+std::optional<FileDigest> digestFile(const SourceManager &SM, FileID FID) {
   bool Invalid = false;
   llvm::StringRef Content = SM.getBufferData(FID, &Invalid);
   if (Invalid)
@@ -924,9 +924,9 @@
   return false;
 }
 
-llvm::Optional<SpelledWord> SpelledWord::touching(SourceLocation SpelledLoc,
-                                                  const syntax::TokenBuffer &TB,
-                                                  const LangOptions &LangOpts) {
+std::optional<SpelledWord> SpelledWord::touching(SourceLocation SpelledLoc,
+                                                 const syntax::TokenBuffer &TB,
+                                                 const LangOptions &LangOpts) {
   const auto &SM = TB.sourceManager();
   auto Touching = syntax::spelledTokensTouching(SpelledLoc, TB);
   for (const auto &T : Touching) {
@@ -974,8 +974,8 @@
   return Result;
 }
 
-llvm::Optional<DefinedMacro> locateMacroAt(const syntax::Token &SpelledTok,
-                                           Preprocessor &PP) {
+std::optional<DefinedMacro> locateMacroAt(const syntax::Token &SpelledTok,
+                                          Preprocessor &PP) {
   if (SpelledTok.kind() != tok::identifier)
     return std::nullopt;
   SourceLocation Loc = SpelledTok.location();
@@ -1196,7 +1196,7 @@
 }
 
 bool isHeaderFile(llvm::StringRef FileName,
-                  llvm::Optional<LangOptions> LangOpts) {
+                  std::optional<LangOptions> LangOpts) {
   // Respect the langOpts, for non-file-extension cases, e.g. standard library
   // files.
   if (LangOpts && LangOpts->IsHeaderFile)
diff --git a/clang-tools-extra/clangd/SourceCode.h b/clang-tools-extra/clangd/SourceCode.h
index 69626c2..7527fd9 100644
--- a/clang-tools-extra/clangd/SourceCode.h
+++ b/clang-tools-extra/clangd/SourceCode.h
@@ -41,7 +41,7 @@
 // of hashing function at every place that needs to store this information.
 using FileDigest = std::array<uint8_t, 8>;
 FileDigest digest(StringRef Content);
-Optional<FileDigest> digestFile(const SourceManager &SM, FileID FID);
+std::optional<FileDigest> digestFile(const SourceManager &SM, FileID FID);
 
 // This context variable controls the behavior of functions in this file
 // that convert between LSP offsets and native clang byte offsets.
@@ -111,9 +111,9 @@
 /// User input (e.g. cursor position) is expressed as a file location, so this
 /// function can be viewed as a way to normalize the ranges used in the clang
 /// AST so that they are comparable with ranges coming from the user input.
-llvm::Optional<SourceRange> toHalfOpenFileRange(const SourceManager &Mgr,
-                                                const LangOptions &LangOpts,
-                                                SourceRange R);
+std::optional<SourceRange> toHalfOpenFileRange(const SourceManager &Mgr,
+                                               const LangOptions &LangOpts,
+                                               SourceRange R);
 
 /// Returns true iff all of the following conditions hold:
 ///   - start and end locations are valid,
@@ -163,8 +163,8 @@
 /// This function should be used when paths needs to be used outside the
 /// component that generate it, so that paths are normalized as much as
 /// possible.
-llvm::Optional<std::string> getCanonicalPath(const FileEntry *F,
-                                             const SourceManager &SourceMgr);
+std::optional<std::string> getCanonicalPath(const FileEntry *F,
+                                            const SourceManager &SourceMgr);
 
 /// Choose the clang-format style we should apply to a certain file.
 /// This will usually use FS to look for .clang-format directories.
@@ -252,9 +252,9 @@
   const syntax::Token *ExpandedToken = nullptr;
 
   // Find the unique word that contains SpelledLoc or starts/ends there.
-  static llvm::Optional<SpelledWord> touching(SourceLocation SpelledLoc,
-                                              const syntax::TokenBuffer &TB,
-                                              const LangOptions &LangOpts);
+  static std::optional<SpelledWord> touching(SourceLocation SpelledLoc,
+                                             const syntax::TokenBuffer &TB,
+                                             const LangOptions &LangOpts);
 };
 
 /// Return true if the \p TokenName is in the list of reversed keywords of the
@@ -315,13 +315,13 @@
 };
 /// Gets the macro referenced by \p SpelledTok. It must be a spelled token
 /// aligned to the beginning of an identifier.
-llvm::Optional<DefinedMacro> locateMacroAt(const syntax::Token &SpelledTok,
-                                           Preprocessor &PP);
+std::optional<DefinedMacro> locateMacroAt(const syntax::Token &SpelledTok,
+                                          Preprocessor &PP);
 
 /// Infers whether this is a header from the FileName and LangOpts (if
 /// presents).
 bool isHeaderFile(llvm::StringRef FileName,
-                  llvm::Optional<LangOptions> LangOpts = std::nullopt);
+                  std::optional<LangOptions> LangOpts = std::nullopt);
 
 /// Returns true if the given location is in a generated protobuf file.
 bool isProtoFile(SourceLocation Loc, const SourceManager &SourceMgr);
diff --git a/clang-tools-extra/clangd/SystemIncludeExtractor.cpp b/clang-tools-extra/clangd/SystemIncludeExtractor.cpp
index d78d56e..c334697 100644
--- a/clang-tools-extra/clangd/SystemIncludeExtractor.cpp
+++ b/clang-tools-extra/clangd/SystemIncludeExtractor.cpp
@@ -75,7 +75,7 @@
   return bool(Target);
 }
 
-llvm::Optional<DriverInfo> parseDriverOutput(llvm::StringRef Output) {
+std::optional<DriverInfo> parseDriverOutput(llvm::StringRef Output) {
   DriverInfo Info;
   const char SIS[] = "#include <...> search starts here:";
   const char SIE[] = "End of search list.";
@@ -136,7 +136,7 @@
   return std::move(Info);
 }
 
-llvm::Optional<DriverInfo>
+std::optional<DriverInfo>
 extractSystemIncludesAndTarget(llvm::SmallString<128> Driver,
                                llvm::StringRef Lang,
                                llvm::ArrayRef<std::string> CommandLine,
@@ -226,7 +226,7 @@
     return std::nullopt;
   }
 
-  llvm::Optional<DriverInfo> Info =
+  std::optional<DriverInfo> Info =
       parseDriverOutput(BufOrError->get()->getBuffer());
   if (!Info)
     return std::nullopt;
@@ -361,7 +361,7 @@
 
 private:
   // Caches includes extracted from a driver. Key is driver:lang.
-  Memoize<llvm::StringMap<llvm::Optional<DriverInfo>>> QueriedDrivers;
+  Memoize<llvm::StringMap<std::optional<DriverInfo>>> QueriedDrivers;
   llvm::Regex QueryDriverRegex;
 };
 } // namespace
diff --git a/clang-tools-extra/clangd/TUScheduler.cpp b/clang-tools-extra/clangd/TUScheduler.cpp
index 50802d2..b50d47a 100644
--- a/clang-tools-extra/clangd/TUScheduler.cpp
+++ b/clang-tools-extra/clangd/TUScheduler.cpp
@@ -137,7 +137,7 @@
 
 static clang::clangd::Key<std::string> FileBeingProcessed;
 
-llvm::Optional<llvm::StringRef> TUScheduler::getFileBeingProcessedInContext() {
+std::optional<llvm::StringRef> TUScheduler::getFileBeingProcessedInContext() {
   if (auto *File = Context::current().get(FileBeingProcessed))
     return llvm::StringRef(*File);
   return std::nullopt;
@@ -184,7 +184,7 @@
   /// the cache anymore. If nullptr was cached for \p K, this function will
   /// return a null unique_ptr wrapped into an optional.
   /// If \p AccessMetric is set records whether there was a hit or miss.
-  llvm::Optional<std::unique_ptr<ParsedAST>>
+  std::optional<std::unique_ptr<ParsedAST>>
   take(Key K, const trace::Metric *AccessMetric = nullptr) {
     // Record metric after unlocking the mutex.
     std::unique_lock<std::mutex> Lock(Mut);
@@ -201,7 +201,7 @@
     // GCC 4.8 fails to compile `return V;`, as it tries to call the copy
     // constructor of unique_ptr, so we call the move ctor explicitly to avoid
     // this miscompile.
-    return llvm::Optional<std::unique_ptr<ParsedAST>>(std::move(V));
+    return std::optional<std::unique_ptr<ParsedAST>>(std::move(V));
   }
 
 private:
@@ -465,7 +465,7 @@
 
   void run() {
     while (true) {
-      llvm::Optional<PreambleThrottlerRequest> Throttle;
+      std::optional<PreambleThrottlerRequest> Throttle;
       {
         std::unique_lock<std::mutex> Lock(Mutex);
         assert(!CurrentReq && "Already processing a request?");
@@ -476,7 +476,7 @@
 
         {
           Throttle.emplace(FileName, Throttler, ReqCV);
-          llvm::Optional<trace::Span> Tracer;
+          std::optional<trace::Span> Tracer;
           // If acquire succeeded synchronously, avoid status jitter.
           if (!Throttle->satisfied()) {
             Tracer.emplace("PreambleThrottle");
@@ -564,8 +564,8 @@
 
   mutable std::mutex Mutex;
   bool Done = false;                  /* GUARDED_BY(Mutex) */
-  llvm::Optional<Request> NextReq;    /* GUARDED_BY(Mutex) */
-  llvm::Optional<Request> CurrentReq; /* GUARDED_BY(Mutex) */
+  std::optional<Request> NextReq;     /* GUARDED_BY(Mutex) */
+  std::optional<Request> CurrentReq;  /* GUARDED_BY(Mutex) */
   // Signaled whenever a thread populates NextReq or worker thread builds a
   // Preamble.
   mutable std::condition_variable ReqCV; /* GUARDED_BY(Mutex) */
@@ -681,7 +681,7 @@
 
   /// Adds a new task to the end of the request queue.
   void startTask(llvm::StringRef Name, llvm::unique_function<void()> Task,
-                 llvm::Optional<UpdateType> Update,
+                 std::optional<UpdateType> Update,
                  TUScheduler::ASTActionInvalidation);
   /// Runs a task synchronously.
   void runTask(llvm::StringRef Name, llvm::function_ref<void()> Task);
@@ -699,8 +699,8 @@
     std::string Name;
     steady_clock::time_point AddTime;
     Context Ctx;
-    llvm::Optional<Context> QueueCtx;
-    llvm::Optional<UpdateType> Update;
+    std::optional<Context> QueueCtx;
+    std::optional<UpdateType> Update;
     TUScheduler::ASTActionInvalidation InvalidationPolicy;
     Canceler Invalidate;
   };
@@ -734,7 +734,7 @@
   /// Set to true to signal run() to finish processing.
   bool Done;                              /* GUARDED_BY(Mutex) */
   std::deque<Request> Requests;           /* GUARDED_BY(Mutex) */
-  llvm::Optional<Request> CurrentRequest; /* GUARDED_BY(Mutex) */
+  std::optional<Request> CurrentRequest;  /* GUARDED_BY(Mutex) */
   /// Signalled whenever a new request has been scheduled or processing of a
   /// request has completed.
   mutable std::condition_variable RequestsCV;
@@ -742,7 +742,7 @@
   /// Latest build preamble for current TU.
   /// None means no builds yet, null means there was an error while building.
   /// Only written by ASTWorker's thread.
-  llvm::Optional<std::shared_ptr<const PreambleData>> LatestPreamble;
+  std::optional<std::shared_ptr<const PreambleData>> LatestPreamble;
   std::deque<Request> PreambleRequests; /* GUARDED_BY(Mutex) */
   /// Signaled whenever LatestPreamble changes state or there's a new
   /// PreambleRequest.
@@ -965,7 +965,7 @@
   auto Task = [=, Action = std::move(Action)]() mutable {
     if (auto Reason = isCancelled())
       return Action(llvm::make_error<CancelledError>(Reason));
-    llvm::Optional<std::unique_ptr<ParsedAST>> AST =
+    std::optional<std::unique_ptr<ParsedAST>> AST =
         IdleASTs.take(this, &ASTAccessForRead);
     if (!AST) {
       StoreDiags CompilerInvocationDiagConsumer;
@@ -977,7 +977,7 @@
       // FIXME: We might need to build a patched ast once preamble thread starts
       // running async. Currently getPossiblyStalePreamble below will always
       // return a compatible preamble as ASTWorker::update blocks.
-      llvm::Optional<ParsedAST> NewAST;
+      std::optional<ParsedAST> NewAST;
       if (Invocation) {
         NewAST = ParsedAST::build(FileName, FileInputs, std::move(Invocation),
                                   CompilerInvocationDiagConsumer.take(),
@@ -1184,11 +1184,11 @@
   // We might be able to reuse the last we've built for a read request.
   // FIXME: It might be better to not reuse this AST. That way queued AST builds
   // won't be required for diags.
-  llvm::Optional<std::unique_ptr<ParsedAST>> AST =
+  std::optional<std::unique_ptr<ParsedAST>> AST =
       IdleASTs.take(this, &ASTAccessForDiag);
   if (!AST || !InputsAreLatest) {
     auto RebuildStartTime = DebouncePolicy::clock::now();
-    llvm::Optional<ParsedAST> NewAST = ParsedAST::build(
+    std::optional<ParsedAST> NewAST = ParsedAST::build(
         FileName, Inputs, std::move(Invocation), CIDiags, *LatestPreamble);
     auto RebuildDuration = DebouncePolicy::clock::now() - RebuildStartTime;
     ++ASTBuildCount;
@@ -1307,7 +1307,7 @@
 
 void ASTWorker::startTask(llvm::StringRef Name,
                           llvm::unique_function<void()> Task,
-                          llvm::Optional<UpdateType> Update,
+                          std::optional<UpdateType> Update,
                           TUScheduler::ASTActionInvalidation Invalidation) {
   if (RunSync) {
     assert(!Done && "running a task after stop()");
@@ -1338,7 +1338,7 @@
     }
     // Trace the time the request spends in the queue, and the requests that
     // it's going to wait for.
-    llvm::Optional<Context> QueueCtx;
+    std::optional<Context> QueueCtx;
     if (trace::enabled()) {
       // Tracers that follow threads and need strict nesting will see a tiny
       // instantaneous event "we're enqueueing", and sometime later it runs.
@@ -1385,8 +1385,8 @@
         }
 
         // Tracing: we have a next request, attribute this sleep to it.
-        llvm::Optional<WithContext> Ctx;
-        llvm::Optional<trace::Span> Tracer;
+        std::optional<WithContext> Ctx;
+        std::optional<trace::Span> Tracer;
         if (!Requests.empty()) {
           Ctx.emplace(Requests.front().Ctx.clone());
           Tracer.emplace("Debounce");
diff --git a/clang-tools-extra/clangd/TUScheduler.h b/clang-tools-extra/clangd/TUScheduler.h
index f9582a6..7e2343c 100644
--- a/clang-tools-extra/clangd/TUScheduler.h
+++ b/clang-tools-extra/clangd/TUScheduler.h
@@ -353,7 +353,7 @@
   // FIXME: remove this when there is proper index support via build system
   // integration.
   // FIXME: move to ClangdServer via createProcessingContext.
-  static llvm::Optional<llvm::StringRef> getFileBeingProcessedInContext();
+  static std::optional<llvm::StringRef> getFileBeingProcessedInContext();
 
   void profile(MemoryTree &MT) const;
 
@@ -371,8 +371,8 @@
   std::unique_ptr<HeaderIncluderCache> HeaderIncluders;
   // None when running tasks synchronously and non-None when running tasks
   // asynchronously.
-  llvm::Optional<AsyncTaskRunner> PreambleTasks;
-  llvm::Optional<AsyncTaskRunner> WorkerThreads;
+  std::optional<AsyncTaskRunner> PreambleTasks;
+  std::optional<AsyncTaskRunner> WorkerThreads;
   // Used to create contexts for operations that are not bound to a particular
   // file (e.g. index queries).
   std::string LastActiveFile;
diff --git a/clang-tools-extra/clangd/XRefs.cpp b/clang-tools-extra/clangd/XRefs.cpp
index da33b72..ee677fe 100644
--- a/clang-tools-extra/clangd/XRefs.cpp
+++ b/clang-tools-extra/clangd/XRefs.cpp
@@ -117,8 +117,8 @@
 // TUPath is used to resolve the path of URI.
 // FIXME: figure out a good home for it, and share the implementation with
 // FindSymbols.
-llvm::Optional<Location> toLSPLocation(const SymbolLocation &Loc,
-                                       llvm::StringRef TUPath) {
+std::optional<Location> toLSPLocation(const SymbolLocation &Loc,
+                                      llvm::StringRef TUPath) {
   if (!Loc)
     return std::nullopt;
   auto Uri = URI::parse(Loc.FileURI);
@@ -206,8 +206,8 @@
 
 // Expects Loc to be a SpellingLocation, will bail out otherwise as it can't
 // figure out a filename.
-llvm::Optional<Location> makeLocation(const ASTContext &AST, SourceLocation Loc,
-                                      llvm::StringRef TUPath) {
+std::optional<Location> makeLocation(const ASTContext &AST, SourceLocation Loc,
+                                     llvm::StringRef TUPath) {
   const auto &SM = AST.getSourceManager();
   const FileEntry *F = SM.getFileEntryForID(SM.getFileID(Loc));
   if (!F)
@@ -228,9 +228,9 @@
 }
 
 // Treat #included files as symbols, to enable go-to-definition on them.
-llvm::Optional<LocatedSymbol> locateFileReferent(const Position &Pos,
-                                                 ParsedAST &AST,
-                                                 llvm::StringRef MainFilePath) {
+std::optional<LocatedSymbol> locateFileReferent(const Position &Pos,
+                                                ParsedAST &AST,
+                                                llvm::StringRef MainFilePath) {
   for (auto &Inc : AST.getIncludeStructure().MainFileIncludes) {
     if (!Inc.Resolved.empty() && Inc.HashLine == Pos.line) {
       LocatedSymbol File;
@@ -247,7 +247,7 @@
 
 // Macros are simple: there's no declaration/definition distinction.
 // As a consequence, there's no need to look them up in the index either.
-llvm::Optional<LocatedSymbol>
+std::optional<LocatedSymbol>
 locateMacroReferent(const syntax::Token &TouchedIdentifier, ParsedAST &AST,
                     llvm::StringRef MainFilePath) {
   if (auto M = locateMacroAt(TouchedIdentifier, AST.getPreprocessor())) {
@@ -1201,8 +1201,8 @@
   return DH;
 }
 
-llvm::Optional<DocumentHighlight> toHighlight(SourceLocation Loc,
-                                              const syntax::TokenBuffer &TB) {
+std::optional<DocumentHighlight> toHighlight(SourceLocation Loc,
+                                             const syntax::TokenBuffer &TB) {
   Loc = TB.sourceManager().getFileLoc(Loc);
   if (const auto *Tok = TB.spelledTokenAt(Loc)) {
     DocumentHighlight Result;
@@ -1303,7 +1303,7 @@
   }
 }
 
-llvm::Optional<std::string>
+std::optional<std::string>
 stringifyContainerForMainFileRef(const Decl *Container) {
   // FIXME We might also want to display the signature here
   // When doing so, remember to also add the Signature to index results!
@@ -1329,7 +1329,7 @@
 
   const auto *IdentifierAtCursor =
       syntax::spelledIdentifierTouching(*CurLoc, AST.getTokens());
-  llvm::Optional<DefinedMacro> Macro;
+  std::optional<DefinedMacro> Macro;
   if (IdentifierAtCursor)
     Macro = locateMacroAt(*IdentifierAtCursor, AST.getPreprocessor());
   if (Macro) {
@@ -1607,7 +1607,7 @@
 }
 
 template <typename HierarchyItem>
-static llvm::Optional<HierarchyItem>
+static std::optional<HierarchyItem>
 declToHierarchyItem(const NamedDecl &ND, llvm::StringRef TUPath) {
   ASTContext &Ctx = ND.getASTContext();
   auto &SM = Ctx.getSourceManager();
@@ -1649,7 +1649,7 @@
   return HI;
 }
 
-static llvm::Optional<TypeHierarchyItem>
+static std::optional<TypeHierarchyItem>
 declToTypeHierarchyItem(const NamedDecl &ND, llvm::StringRef TUPath) {
   auto Result = declToHierarchyItem<TypeHierarchyItem>(ND, TUPath);
   if (Result) {
@@ -1663,7 +1663,7 @@
   return Result;
 }
 
-static llvm::Optional<CallHierarchyItem>
+static std::optional<CallHierarchyItem>
 declToCallHierarchyItem(const NamedDecl &ND, llvm::StringRef TUPath) {
   auto Result = declToHierarchyItem<CallHierarchyItem>(ND, TUPath);
   if (!Result)
@@ -1676,8 +1676,8 @@
 }
 
 template <typename HierarchyItem>
-static llvm::Optional<HierarchyItem> symbolToHierarchyItem(const Symbol &S,
-                                                           PathRef TUPath) {
+static std::optional<HierarchyItem> symbolToHierarchyItem(const Symbol &S,
+                                                          PathRef TUPath) {
   auto Loc = symbolToLocation(S, TUPath);
   if (!Loc) {
     elog("Failed to convert symbol to hierarchy item: {0}", Loc.takeError());
@@ -1695,7 +1695,7 @@
   return HI;
 }
 
-static llvm::Optional<TypeHierarchyItem>
+static std::optional<TypeHierarchyItem>
 symbolToTypeHierarchyItem(const Symbol &S, PathRef TUPath) {
   auto Result = symbolToHierarchyItem<TypeHierarchyItem>(S, TUPath);
   if (Result) {
@@ -1705,7 +1705,7 @@
   return Result;
 }
 
-static llvm::Optional<CallHierarchyItem>
+static std::optional<CallHierarchyItem>
 symbolToCallHierarchyItem(const Symbol &S, PathRef TUPath) {
   auto Result = symbolToHierarchyItem<CallHierarchyItem>(S, TUPath);
   if (!Result)
@@ -1723,7 +1723,7 @@
   Req.Subjects.insert(ID);
   Req.Predicate = RelationKind::BaseOf;
   Index->relations(Req, [&](const SymbolID &Subject, const Symbol &Object) {
-    if (Optional<TypeHierarchyItem> ChildSym =
+    if (std::optional<TypeHierarchyItem> ChildSym =
             symbolToTypeHierarchyItem(Object, TUPath)) {
       if (Levels > 1) {
         ChildSym->children.emplace();
@@ -1755,7 +1755,7 @@
   }
 
   for (const CXXRecordDecl *ParentDecl : typeParents(&CXXRD)) {
-    if (Optional<TypeHierarchyItem> ParentSym =
+    if (std::optional<TypeHierarchyItem> ParentSym =
             declToTypeHierarchyItem(*ParentDecl, TUPath)) {
       fillSuperTypes(*ParentDecl, TUPath, *ParentSym, RPSet);
       Item.data.parents->emplace_back(ParentSym->data);
@@ -2087,7 +2087,7 @@
         CXXRD = CTSD->getTemplateInstantiationPattern();
     }
 
-    Optional<TypeHierarchyItem> Result =
+    std::optional<TypeHierarchyItem> Result =
         declToTypeHierarchyItem(*CXXRD, AST.tuPath());
     if (!Result)
       continue;
diff --git a/clang-tools-extra/clangd/XRefs.h b/clang-tools-extra/clangd/XRefs.h
index 8af5106..c4f7952 100644
--- a/clang-tools-extra/clangd/XRefs.h
+++ b/clang-tools-extra/clangd/XRefs.h
@@ -45,7 +45,7 @@
   // The canonical or best declaration: where most users find its interface.
   Location PreferredDeclaration;
   // Where the symbol is defined, if known. May equal PreferredDeclaration.
-  llvm::Optional<Location> Definition;
+  std::optional<Location> Definition;
   // SymbolID of the located symbol if available.
   SymbolID ID;
 };
diff --git a/clang-tools-extra/clangd/index/Background.cpp b/clang-tools-extra/clangd/index/Background.cpp
index f09fb5d..117c766 100644
--- a/clang-tools-extra/clangd/index/Background.cpp
+++ b/clang-tools-extra/clangd/index/Background.cpp
@@ -124,7 +124,7 @@
   BackgroundQueue::Task T([this, ChangedFiles] {
     trace::Span Tracer("BackgroundIndexEnqueue");
 
-    llvm::Optional<WithContext> WithProvidedContext;
+    std::optional<WithContext> WithProvidedContext;
     if (ContextProvider)
       WithProvidedContext.emplace(ContextProvider(/*Path=*/""));
 
@@ -157,7 +157,7 @@
   std::string Tag = filenameWithoutExtension(Path).str();
   uint64_t Key = llvm::xxHash64(Path);
   BackgroundQueue::Task T([this, Path(std::move(Path))] {
-    llvm::Optional<WithContext> WithProvidedContext;
+    std::optional<WithContext> WithProvidedContext;
     if (ContextProvider)
       WithProvidedContext.emplace(ContextProvider(Path));
     auto Cmd = CDB.getCompileCommand(Path);
diff --git a/clang-tools-extra/clangd/index/Background.h b/clang-tools-extra/clangd/index/Background.h
index 45f679a..0d719ff 100644
--- a/clang-tools-extra/clangd/index/Background.h
+++ b/clang-tools-extra/clangd/index/Background.h
@@ -62,7 +62,7 @@
   // CDBDirectory is the first directory containing a CDB in parent directories
   // of a file, or user cache directory if none was found, e.g. stdlib headers.
   static Factory createDiskBackedStorageFactory(
-      std::function<llvm::Optional<ProjectInfo>(PathRef)> GetProjectInfo);
+      std::function<std::optional<ProjectInfo>(PathRef)> GetProjectInfo);
 };
 
 // A priority queue of tasks which can be run on (external) worker threads.
@@ -112,7 +112,7 @@
   // Only affects tasks that run after the call.
   static void preventThreadStarvationInTests();
   [[nodiscard]] bool
-  blockUntilIdleForTest(llvm::Optional<double> TimeoutSeconds);
+  blockUntilIdleForTest(std::optional<double> TimeoutSeconds);
 
 private:
   void notifyProgress() const; // Requires lock Mu
@@ -174,7 +174,7 @@
 
   // Wait until the queue is empty, to allow deterministic testing.
   [[nodiscard]] bool
-  blockUntilIdleForTest(llvm::Optional<double> TimeoutSeconds = 10) {
+  blockUntilIdleForTest(std::optional<double> TimeoutSeconds = 10) {
     return Queue.blockUntilIdleForTest(TimeoutSeconds);
   }
 
diff --git a/clang-tools-extra/clangd/index/BackgroundIndexStorage.cpp b/clang-tools-extra/clangd/index/BackgroundIndexStorage.cpp
index c7bbd98..27c9c91 100644
--- a/clang-tools-extra/clangd/index/BackgroundIndexStorage.cpp
+++ b/clang-tools-extra/clangd/index/BackgroundIndexStorage.cpp
@@ -99,7 +99,7 @@
 class DiskBackedIndexStorageManager {
 public:
   DiskBackedIndexStorageManager(
-      std::function<llvm::Optional<ProjectInfo>(PathRef)> GetProjectInfo)
+      std::function<std::optional<ProjectInfo>(PathRef)> GetProjectInfo)
       : IndexStorageMapMu(std::make_unique<std::mutex>()),
         GetProjectInfo(std::move(GetProjectInfo)) {
     llvm::SmallString<128> FallbackDir;
@@ -136,14 +136,14 @@
   llvm::StringMap<std::unique_ptr<BackgroundIndexStorage>> IndexStorageMap;
   std::unique_ptr<std::mutex> IndexStorageMapMu;
 
-  std::function<llvm::Optional<ProjectInfo>(PathRef)> GetProjectInfo;
+  std::function<std::optional<ProjectInfo>(PathRef)> GetProjectInfo;
 };
 
 } // namespace
 
 BackgroundIndexStorage::Factory
 BackgroundIndexStorage::createDiskBackedStorageFactory(
-    std::function<llvm::Optional<ProjectInfo>(PathRef)> GetProjectInfo) {
+    std::function<std::optional<ProjectInfo>(PathRef)> GetProjectInfo) {
   return DiskBackedIndexStorageManager(std::move(GetProjectInfo));
 }
 
diff --git a/clang-tools-extra/clangd/index/BackgroundQueue.cpp b/clang-tools-extra/clangd/index/BackgroundQueue.cpp
index 5fb1511..6023f48 100644
--- a/clang-tools-extra/clangd/index/BackgroundQueue.cpp
+++ b/clang-tools-extra/clangd/index/BackgroundQueue.cpp
@@ -21,7 +21,7 @@
 
 void BackgroundQueue::work(std::function<void()> OnIdle) {
   while (true) {
-    llvm::Optional<Task> Task;
+    std::optional<Task> Task;
     {
       std::unique_lock<std::mutex> Lock(Mu);
       CV.wait(Lock, [&] { return ShouldStop || !Queue.empty(); });
@@ -134,7 +134,7 @@
 }
 
 bool BackgroundQueue::blockUntilIdleForTest(
-    llvm::Optional<double> TimeoutSeconds) {
+    std::optional<double> TimeoutSeconds) {
   std::unique_lock<std::mutex> Lock(Mu);
   return wait(Lock, CV, timeoutSeconds(TimeoutSeconds),
               [&] { return Queue.empty() && Stat.Active == 0; });
diff --git a/clang-tools-extra/clangd/index/FileIndex.cpp b/clang-tools-extra/clangd/index/FileIndex.cpp
index 95bda42..348f15e 100644
--- a/clang-tools-extra/clangd/index/FileIndex.cpp
+++ b/clang-tools-extra/clangd/index/FileIndex.cpp
@@ -189,7 +189,7 @@
   return Result;
 }
 
-llvm::Optional<IndexFileIn>
+std::optional<IndexFileIn>
 FileShardedIndex::getShard(llvm::StringRef Uri) const {
   auto It = Shards.find(Uri);
   if (It == Shards.end())
diff --git a/clang-tools-extra/clangd/index/FileIndex.h b/clang-tools-extra/clangd/index/FileIndex.h
index 31757d1..34ecbf4 100644
--- a/clang-tools-extra/clangd/index/FileIndex.h
+++ b/clang-tools-extra/clangd/index/FileIndex.h
@@ -179,7 +179,7 @@
   /// a copy of all the relevant data.
   /// Returned index will always have Symbol/Refs/Relation Slabs set, even if
   /// they are empty.
-  llvm::Optional<IndexFileIn> getShard(llvm::StringRef Uri) const;
+  std::optional<IndexFileIn> getShard(llvm::StringRef Uri) const;
 
 private:
   // Contains all the information that belongs to a single file.
diff --git a/clang-tools-extra/clangd/index/Index.h b/clang-tools-extra/clangd/index/Index.h
index e836d45..db5c967 100644
--- a/clang-tools-extra/clangd/index/Index.h
+++ b/clang-tools-extra/clangd/index/Index.h
@@ -72,7 +72,7 @@
   /// If set, limit the number of refers returned from the index. The index may
   /// choose to return less than this, e.g. it tries to avoid returning stale
   /// results.
-  llvm::Optional<uint32_t> Limit;
+  std::optional<uint32_t> Limit;
   /// If set, populates the container of the reference.
   /// Index implementations may chose to populate containers no matter what.
   bool WantContainer = false;
@@ -82,7 +82,7 @@
   llvm::DenseSet<SymbolID> Subjects;
   RelationKind Predicate;
   /// If set, limit the number of relations returned from the index.
-  llvm::Optional<uint32_t> Limit;
+  std::optional<uint32_t> Limit;
 };
 
 /// Describes what data is covered by an index.
diff --git a/clang-tools-extra/clangd/index/IndexAction.cpp b/clang-tools-extra/clangd/index/IndexAction.cpp
index d97dc40..6588f4d 100644
--- a/clang-tools-extra/clangd/index/IndexAction.cpp
+++ b/clang-tools-extra/clangd/index/IndexAction.cpp
@@ -29,7 +29,7 @@
 namespace clangd {
 namespace {
 
-llvm::Optional<std::string> toURI(OptionalFileEntryRef File) {
+std::optional<std::string> toURI(OptionalFileEntryRef File) {
   if (!File)
     return std::nullopt;
   auto AbsolutePath = File->getFileEntry().tryGetRealPathName();
diff --git a/clang-tools-extra/clangd/index/Serialization.h b/clang-tools-extra/clangd/index/Serialization.h
index fceaefe..b6890d63 100644
--- a/clang-tools-extra/clangd/index/Serialization.h
+++ b/clang-tools-extra/clangd/index/Serialization.h
@@ -41,13 +41,13 @@
 
 // Holds the contents of an index file that was read.
 struct IndexFileIn {
-  llvm::Optional<SymbolSlab> Symbols;
-  llvm::Optional<RefSlab> Refs;
-  llvm::Optional<RelationSlab> Relations;
+  std::optional<SymbolSlab> Symbols;
+  std::optional<RefSlab> Refs;
+  std::optional<RelationSlab> Relations;
   // Keys are URIs of the source files.
-  llvm::Optional<IncludeGraph> Sources;
+  std::optional<IncludeGraph> Sources;
   // This contains only the Directory and CommandLine.
-  llvm::Optional<tooling::CompileCommand> Cmd;
+  std::optional<tooling::CompileCommand> Cmd;
 };
 // Parse an index file. The input must be a RIFF or YAML file.
 llvm::Expected<IndexFileIn> readIndexFile(llvm::StringRef, SymbolOrigin);
diff --git a/clang-tools-extra/clangd/index/StdLib.cpp b/clang-tools-extra/clangd/index/StdLib.cpp
index ab9a8ed..399bd2f 100644
--- a/clang-tools-extra/clangd/index/StdLib.cpp
+++ b/clang-tools-extra/clangd/index/StdLib.cpp
@@ -286,8 +286,8 @@
          Best[langFromOpts(LO)].load(std::memory_order_acquire);
 }
 
-llvm::Optional<StdLibLocation> StdLibSet::add(const LangOptions &LO,
-                                              const HeaderSearch &HS) {
+std::optional<StdLibLocation> StdLibSet::add(const LangOptions &LO,
+                                             const HeaderSearch &HS) {
   Lang L = langFromOpts(LO);
   int OldVersion = Best[L].load(std::memory_order_acquire);
   int NewVersion = standardFromOpts(LO);
diff --git a/clang-tools-extra/clangd/index/StdLib.h b/clang-tools-extra/clangd/index/StdLib.h
index 6c170dc..2ed5eae 100644
--- a/clang-tools-extra/clangd/index/StdLib.h
+++ b/clang-tools-extra/clangd/index/StdLib.h
@@ -67,7 +67,7 @@
   // Returns the location where the standard library was found.
   //
   // This function is threadsafe.
-  llvm::Optional<StdLibLocation> add(const LangOptions &, const HeaderSearch &);
+  std::optional<StdLibLocation> add(const LangOptions &, const HeaderSearch &);
 
   // Indicates whether a built index should be used.
   // It should not be used if a newer version has subsequently been added.
diff --git a/clang-tools-extra/clangd/index/SymbolCollector.cpp b/clang-tools-extra/clangd/index/SymbolCollector.cpp
index 5f9c8bb..822f3cb 100644
--- a/clang-tools-extra/clangd/index/SymbolCollector.cpp
+++ b/clang-tools-extra/clangd/index/SymbolCollector.cpp
@@ -146,7 +146,7 @@
   return Result;
 }
 
-llvm::Optional<RelationKind> indexableRelation(const index::SymbolRelation &R) {
+std::optional<RelationKind> indexableRelation(const index::SymbolRelation &R) {
   if (R.Roles & static_cast<unsigned>(index::SymbolRole::RelationBaseOf))
     return RelationKind::BaseOf;
   if (R.Roles & static_cast<unsigned>(index::SymbolRole::RelationOverrideOf))
@@ -178,10 +178,10 @@
 class SymbolCollector::HeaderFileURICache {
   struct FrameworkUmbrellaSpelling {
     // Spelling for the public umbrella header, e.g. <Foundation/Foundation.h>
-    llvm::Optional<std::string> PublicHeader;
+    std::optional<std::string> PublicHeader;
     // Spelling for the private umbrella header, e.g.
     // <Foundation/Foundation_Private.h>
-    llvm::Optional<std::string> PrivateHeader;
+    std::optional<std::string> PrivateHeader;
   };
   // Weird double-indirect access to PP, which might not be ready yet when
   // HeaderFiles is created but will be by the time it's used.
@@ -263,7 +263,7 @@
     bool IsPrivateHeader;
   };
 
-  llvm::Optional<FrameworkHeaderPath>
+  std::optional<FrameworkHeaderPath>
   splitFrameworkHeaderPath(llvm::StringRef Path) {
     using namespace llvm::sys;
     path::reverse_iterator I = path::rbegin(Path);
@@ -296,7 +296,7 @@
   // <Foundation/Foundation_Private.h> instead of
   // <Foundation/NSObject_Private.h> which should be used instead of directly
   // importing the header.
-  llvm::Optional<std::string> getFrameworkUmbrellaSpelling(
+  std::optional<std::string> getFrameworkUmbrellaSpelling(
       llvm::StringRef Framework, SrcMgr::CharacteristicKind HeadersDirKind,
       HeaderSearch &HS, FrameworkHeaderPath &HeaderPath) {
     auto Res = CacheFrameworkToUmbrellaHeaderSpelling.try_emplace(Framework);
@@ -340,7 +340,7 @@
   // named `Framework`, e.g. `NSObject.h` in framework `Foundation` would
   // give <Foundation/Foundation.h> if the umbrella header exists, otherwise
   // <Foundation/NSObject.h>.
-  llvm::Optional<llvm::StringRef> getFrameworkHeaderIncludeSpelling(
+  std::optional<llvm::StringRef> getFrameworkHeaderIncludeSpelling(
       const FileEntry *FE, llvm::StringRef Framework, HeaderSearch &HS) {
     auto Res = CachePathToFrameworkSpelling.try_emplace(FE->getName());
     auto *CachedHeaderSpelling = &Res.first->second;
@@ -414,7 +414,7 @@
 };
 
 // Return the symbol location of the token at \p TokLoc.
-llvm::Optional<SymbolLocation>
+std::optional<SymbolLocation>
 SymbolCollector::getTokenLocation(SourceLocation TokLoc) {
   const auto &SM = ASTCtx->getSourceManager();
   auto *FE = SM.getFileEntryForID(SM.getFileID(TokLoc));
@@ -941,7 +941,7 @@
   std::string ReturnType = getReturnType(*CCS);
   S.ReturnType = ReturnType;
 
-  llvm::Optional<OpaqueType> TypeStorage;
+  std::optional<OpaqueType> TypeStorage;
   if (S.Flags & Symbol::IndexedForCodeCompletion) {
     TypeStorage = OpaqueType::fromCompletionResult(*ASTCtx, SymbolCompletion);
     if (TypeStorage)
diff --git a/clang-tools-extra/clangd/index/SymbolCollector.h b/clang-tools-extra/clangd/index/SymbolCollector.h
index 6acce1f..2655544 100644
--- a/clang-tools-extra/clangd/index/SymbolCollector.h
+++ b/clang-tools-extra/clangd/index/SymbolCollector.h
@@ -156,9 +156,9 @@
   void processRelations(const NamedDecl &ND, const SymbolID &ID,
                         ArrayRef<index::SymbolRelation> Relations);
 
-  llvm::Optional<SymbolLocation> getTokenLocation(SourceLocation TokLoc);
+  std::optional<SymbolLocation> getTokenLocation(SourceLocation TokLoc);
 
-  llvm::Optional<std::string> getIncludeHeader(const Symbol &S, FileID);
+  std::optional<std::string> getIncludeHeader(const Symbol &S, FileID);
 
   SymbolID getSymbolIDCached(const Decl *D);
   SymbolID getSymbolIDCached(const llvm::StringRef MacroName,
diff --git a/clang-tools-extra/clangd/index/YAMLSerialization.cpp b/clang-tools-extra/clangd/index/YAMLSerialization.cpp
index c51489f..2892d8c 100644
--- a/clang-tools-extra/clangd/index/YAMLSerialization.cpp
+++ b/clang-tools-extra/clangd/index/YAMLSerialization.cpp
@@ -42,11 +42,11 @@
     std::pair<clang::clangd::SymbolID, std::vector<clang::clangd::Ref>>;
 // This is a pale imitation of std::variant<Symbol, RefBundle, Relation>
 struct VariantEntry {
-  llvm::Optional<clang::clangd::Symbol> Symbol;
-  llvm::Optional<RefBundle> Refs;
-  llvm::Optional<clang::clangd::Relation> Relation;
-  llvm::Optional<clang::clangd::IncludeGraphNode> Source;
-  llvm::Optional<clang::tooling::CompileCommand> Cmd;
+  std::optional<clang::clangd::Symbol> Symbol;
+  std::optional<RefBundle> Refs;
+  std::optional<clang::clangd::Relation> Relation;
+  std::optional<clang::clangd::IncludeGraphNode> Source;
+  std::optional<clang::tooling::CompileCommand> Cmd;
 };
 // A class helps YAML to serialize the 32-bit encoded position (Line&Column),
 // as YAMLIO can't directly map bitfields.
@@ -480,7 +480,7 @@
   llvm::UniqueStringSaver Strings(Arena);
   llvm::yaml::Input Yin(Data, &Strings);
   IncludeGraph Sources;
-  llvm::Optional<tooling::CompileCommand> Cmd;
+  std::optional<tooling::CompileCommand> Cmd;
   while (Yin.setCurrentDocument()) {
     llvm::yaml::EmptyContext Ctx;
     VariantEntry Variant;
diff --git a/clang-tools-extra/clangd/index/dex/Dex.cpp b/clang-tools-extra/clangd/index/dex/Dex.cpp
index 0e94f59..8f504fb 100644
--- a/clang-tools-extra/clangd/index/dex/Dex.cpp
+++ b/clang-tools-extra/clangd/index/dex/Dex.cpp
@@ -268,7 +268,7 @@
   for (const auto &IDAndScore : IDAndScores) {
     const DocID SymbolDocID = IDAndScore.first;
     const auto *Sym = Symbols[SymbolDocID];
-    const llvm::Optional<float> Score = Filter.match(Sym->Name);
+    const std::optional<float> Score = Filter.match(Sym->Name);
     if (!Score)
       continue;
     // Combine Fuzzy Matching score, precomputed symbol quality and boosting
diff --git a/clang-tools-extra/clangd/index/dex/dexp/Dexp.cpp b/clang-tools-extra/clangd/index/dex/dexp/Dexp.cpp
index 7633822..392960d 100644
--- a/clang-tools-extra/clangd/index/dex/dexp/Dexp.cpp
+++ b/clang-tools-extra/clangd/index/dex/dexp/Dexp.cpp
@@ -443,6 +443,6 @@
     return runCommand(ExecCommand, *Index) ? 0 : 1;
 
   llvm::LineEditor LE("dexp");
-  while (llvm::Optional<std::string> Request = LE.readLine())
+  while (std::optional<std::string> Request = LE.readLine())
     runCommand(std::move(*Request), *Index);
 }
diff --git a/clang-tools-extra/clangd/index/remote/server/Server.cpp b/clang-tools-extra/clangd/index/remote/server/Server.cpp
index 5d2c82e2..e108d4d 100644
--- a/clang-tools-extra/clangd/index/remote/server/Server.cpp
+++ b/clang-tools-extra/clangd/index/remote/server/Server.cpp
@@ -504,7 +504,7 @@
   auto Logger = makeLogger(LogPrefix.getValue(), llvm::errs());
   clang::clangd::LoggingSession LoggingSession(*Logger);
 
-  llvm::Optional<llvm::raw_fd_ostream> TracerStream;
+  std::optional<llvm::raw_fd_ostream> TracerStream;
   std::unique_ptr<clang::clangd::trace::EventTracer> Tracer;
   if (!TraceFile.empty()) {
     std::error_code EC;
@@ -522,7 +522,7 @@
     }
   }
 
-  llvm::Optional<clang::clangd::trace::Session> TracingSession;
+  std::optional<clang::clangd::trace::Session> TracingSession;
   if (Tracer)
     TracingSession.emplace(*Tracer);
 
diff --git a/clang-tools-extra/clangd/refactor/InsertionPoint.cpp b/clang-tools-extra/clangd/refactor/InsertionPoint.cpp
index ff17ddd..7f042c0 100644
--- a/clang-tools-extra/clangd/refactor/InsertionPoint.cpp
+++ b/clang-tools-extra/clangd/refactor/InsertionPoint.cpp
@@ -22,8 +22,8 @@
 // Choose the decl to insert before, according to an anchor.
 // Nullptr means insert at end of DC.
 // None means no valid place to insert.
-llvm::Optional<const Decl *> insertionDecl(const DeclContext &DC,
-                                           const Anchor &A) {
+std::optional<const Decl *> insertionDecl(const DeclContext &DC,
+                                          const Anchor &A) {
   bool LastMatched = false;
   bool ReturnNext = false;
   for (const auto *D : DC.decls()) {
diff --git a/clang-tools-extra/clangd/refactor/Rename.cpp b/clang-tools-extra/clangd/refactor/Rename.cpp
index afddab0..6362768 100644
--- a/clang-tools-extra/clangd/refactor/Rename.cpp
+++ b/clang-tools-extra/clangd/refactor/Rename.cpp
@@ -39,8 +39,8 @@
 namespace clangd {
 namespace {
 
-llvm::Optional<std::string> filePath(const SymbolLocation &Loc,
-                                     llvm::StringRef HintFilePath) {
+std::optional<std::string> filePath(const SymbolLocation &Loc,
+                                    llvm::StringRef HintFilePath) {
   if (!Loc)
     return std::nullopt;
   auto Path = URI::resolve(Loc.FileURI, HintFilePath);
@@ -197,10 +197,10 @@
   SameName,
 };
 
-llvm::Optional<ReasonToReject> renameable(const NamedDecl &RenameDecl,
-                                          StringRef MainFilePath,
-                                          const SymbolIndex *Index,
-                                          const RenameOptions& Opts) {
+std::optional<ReasonToReject> renameable(const NamedDecl &RenameDecl,
+                                         StringRef MainFilePath,
+                                         const SymbolIndex *Index,
+                                         const RenameOptions &Opts) {
   trace::Span Tracer("Renameable");
   if (!Opts.RenameVirtual) {
     if (const auto *S = llvm::dyn_cast<CXXMethodDecl>(&RenameDecl)) {
@@ -501,13 +501,13 @@
 
 // Check if we can rename the given RenameDecl into NewName.
 // Return details if the rename would produce a conflict.
-llvm::Optional<InvalidName> checkName(const NamedDecl &RenameDecl,
-                                      llvm::StringRef NewName) {
+std::optional<InvalidName> checkName(const NamedDecl &RenameDecl,
+                                     llvm::StringRef NewName) {
   trace::Span Tracer("CheckName");
   static constexpr trace::Metric InvalidNameMetric(
       "rename_name_invalid", trace::Metric::Counter, "invalid_kind");
   auto &ASTCtx = RenameDecl.getASTContext();
-  llvm::Optional<InvalidName> Result;
+  std::optional<InvalidName> Result;
   if (isKeyword(NewName, ASTCtx.getLangOpts()))
     Result = InvalidName{InvalidName::Keywords, NewName.str()};
   else if (!mayBeValidIdentifier(NewName))
@@ -911,7 +911,7 @@
 //          ranges onto candidates in a plausible way (e.g. guess that lines
 //          were inserted). If such a "near miss" is found, the rename is still
 //          possible
-llvm::Optional<std::vector<Range>>
+std::optional<std::vector<Range>>
 adjustRenameRanges(llvm::StringRef DraftCode, llvm::StringRef Identifier,
                    std::vector<Range> Indexed, const LangOptions &LangOpts) {
   trace::Span Tracer("AdjustRenameRanges");
@@ -923,8 +923,8 @@
   return getMappedRanges(Indexed, Lexed);
 }
 
-llvm::Optional<std::vector<Range>> getMappedRanges(ArrayRef<Range> Indexed,
-                                                   ArrayRef<Range> Lexed) {
+std::optional<std::vector<Range>> getMappedRanges(ArrayRef<Range> Indexed,
+                                                  ArrayRef<Range> Lexed) {
   trace::Span Tracer("GetMappedRanges");
   assert(!Indexed.empty());
   assert(llvm::is_sorted(Indexed));
diff --git a/clang-tools-extra/clangd/refactor/Rename.h b/clang-tools-extra/clangd/refactor/Rename.h
index 6b917d5..91728ba 100644
--- a/clang-tools-extra/clangd/refactor/Rename.h
+++ b/clang-tools-extra/clangd/refactor/Rename.h
@@ -84,7 +84,7 @@
 /// The API assumes that Indexed contains only named occurrences (each
 /// occurrence has the same length).
 /// REQUIRED: Indexed is sorted.
-llvm::Optional<std::vector<Range>>
+std::optional<std::vector<Range>>
 adjustRenameRanges(llvm::StringRef DraftCode, llvm::StringRef Identifier,
                    std::vector<Range> Indexed, const LangOptions &LangOpts);
 
@@ -94,8 +94,8 @@
 /// Exposed for testing only.
 ///
 /// REQUIRED: Indexed and Lexed are sorted.
-llvm::Optional<std::vector<Range>> getMappedRanges(ArrayRef<Range> Indexed,
-                                                   ArrayRef<Range> Lexed);
+std::optional<std::vector<Range>> getMappedRanges(ArrayRef<Range> Indexed,
+                                                  ArrayRef<Range> Lexed);
 /// Evaluates how good the mapped result is. 0 indicates a perfect match.
 ///
 /// Exposed for testing only.
diff --git a/clang-tools-extra/clangd/refactor/Tweak.h b/clang-tools-extra/clangd/refactor/Tweak.h
index f91faf2..e35d34a 100644
--- a/clang-tools-extra/clangd/refactor/Tweak.h
+++ b/clang-tools-extra/clangd/refactor/Tweak.h
@@ -74,7 +74,7 @@
 
   struct Effect {
     /// A message to be displayed to the user.
-    llvm::Optional<std::string> ShowMessage;
+    std::optional<std::string> ShowMessage;
     FileEdits ApplyEdits;
     /// Whether the edits should be formatted before presenting to the client.
     /// Note that it applies to all files.
diff --git a/clang-tools-extra/clangd/refactor/tweaks/DefineInline.cpp b/clang-tools-extra/clangd/refactor/tweaks/DefineInline.cpp
index 410dec0..4e97b13 100644
--- a/clang-tools-extra/clangd/refactor/tweaks/DefineInline.cpp
+++ b/clang-tools-extra/clangd/refactor/tweaks/DefineInline.cpp
@@ -53,7 +53,7 @@
 // Returns semicolon location for the given FD. Since AST doesn't contain that
 // information, searches for a semicolon by lexing from end of function decl
 // while skipping comments.
-llvm::Optional<SourceLocation> getSemicolonForDecl(const FunctionDecl *FD) {
+std::optional<SourceLocation> getSemicolonForDecl(const FunctionDecl *FD) {
   const SourceManager &SM = FD->getASTContext().getSourceManager();
   const LangOptions &LangOpts = FD->getASTContext().getLangOpts();
 
@@ -349,7 +349,7 @@
   return FD->getBeginLoc();
 }
 
-llvm::Optional<tooling::Replacement>
+std::optional<tooling::Replacement>
 addInlineIfInHeader(const FunctionDecl *FD) {
   // This includes inline functions and constexpr functions.
   if (FD->isInlined() || llvm::isa<CXXMethodDecl>(FD))
diff --git a/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp b/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
index 1e09da9..782d14e 100644
--- a/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
+++ b/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
@@ -59,8 +59,8 @@
   return nullptr;
 }
 
-llvm::Optional<Path> getSourceFile(llvm::StringRef FileName,
-                                   const Tweak::Selection &Sel) {
+std::optional<Path> getSourceFile(llvm::StringRef FileName,
+                                  const Tweak::Selection &Sel) {
   assert(Sel.FS);
   if (auto Source = getCorrespondingHeaderOrSource(FileName, Sel.FS))
     return *Source;
@@ -70,7 +70,7 @@
 // Synthesize a DeclContext for TargetNS from CurContext. TargetNS must be empty
 // for global namespace, and endwith "::" otherwise.
 // Returns std::nullopt if TargetNS is not a prefix of CurContext.
-llvm::Optional<const DeclContext *>
+std::optional<const DeclContext *>
 findContextForNS(llvm::StringRef TargetNS, const DeclContext *CurContext) {
   assert(TargetNS.empty() || TargetNS.endswith("::"));
   // Skip any non-namespace contexts, e.g. TagDecls, functions/methods.
diff --git a/clang-tools-extra/clangd/refactor/tweaks/DumpAST.cpp b/clang-tools-extra/clangd/refactor/tweaks/DumpAST.cpp
index 7a89ce7..e126e72 100644
--- a/clang-tools-extra/clangd/refactor/tweaks/DumpAST.cpp
+++ b/clang-tools-extra/clangd/refactor/tweaks/DumpAST.cpp
@@ -56,7 +56,7 @@
     return N.get<Decl>() || N.get<Stmt>() || N.get<Type>();
   }
 
-  llvm::Optional<DynTypedNode> Node;
+  std::optional<DynTypedNode> Node;
 };
 REGISTER_TWEAK(DumpAST)
 
diff --git a/clang-tools-extra/clangd/refactor/tweaks/ExpandAutoType.cpp b/clang-tools-extra/clangd/refactor/tweaks/ExpandAutoType.cpp
index aabaed0..b877521 100644
--- a/clang-tools-extra/clangd/refactor/tweaks/ExpandAutoType.cpp
+++ b/clang-tools-extra/clangd/refactor/tweaks/ExpandAutoType.cpp
@@ -114,7 +114,7 @@
 Expected<Tweak::Effect> ExpandAutoType::apply(const Selection& Inputs) {
   auto &SrcMgr = Inputs.AST->getSourceManager();
 
-  llvm::Optional<clang::QualType> DeducedType =
+  std::optional<clang::QualType> DeducedType =
       getDeducedType(Inputs.AST->getASTContext(), AutoRange.getBegin());
 
   // if we can't resolve the type, return an error message
diff --git a/clang-tools-extra/clangd/refactor/tweaks/ExtractFunction.cpp b/clang-tools-extra/clangd/refactor/tweaks/ExtractFunction.cpp
index a259deb..b47d083 100644
--- a/clang-tools-extra/clangd/refactor/tweaks/ExtractFunction.cpp
+++ b/clang-tools-extra/clangd/refactor/tweaks/ExtractFunction.cpp
@@ -265,9 +265,9 @@
 
 // Zone Range is the union of SourceRanges of all child Nodes in Parent since
 // all child Nodes are RootStmts
-llvm::Optional<SourceRange> findZoneRange(const Node *Parent,
-                                          const SourceManager &SM,
-                                          const LangOptions &LangOpts) {
+std::optional<SourceRange> findZoneRange(const Node *Parent,
+                                         const SourceManager &SM,
+                                         const LangOptions &LangOpts) {
   SourceRange SR;
   if (auto BeginFileRange = toHalfOpenFileRange(
           SM, LangOpts, Parent->Children.front()->ASTNode.getSourceRange()))
@@ -286,7 +286,7 @@
 // FIXME: check if EnclosingFunction has any attributes as the AST doesn't
 // always store the source range of the attributes and thus we end up extracting
 // between the attributes and the EnclosingFunction.
-llvm::Optional<SourceRange>
+std::optional<SourceRange>
 computeEnclosingFuncRange(const FunctionDecl *EnclosingFunction,
                           const SourceManager &SM,
                           const LangOptions &LangOpts) {
@@ -311,9 +311,9 @@
 
 // FIXME: Check we're not extracting from the initializer/condition of a control
 // flow structure.
-llvm::Optional<ExtractionZone> findExtractionZone(const Node *CommonAnc,
-                                                  const SourceManager &SM,
-                                                  const LangOptions &LangOpts) {
+std::optional<ExtractionZone> findExtractionZone(const Node *CommonAnc,
+                                                 const SourceManager &SM,
+                                                 const LangOptions &LangOpts) {
   ExtractionZone ExtZone;
   ExtZone.Parent = getParentOfRootStmts(CommonAnc);
   if (!ExtZone.Parent || ExtZone.Parent->Children.empty())
@@ -358,7 +358,7 @@
   std::vector<Parameter> Parameters;
   SourceRange BodyRange;
   SourceLocation DefinitionPoint;
-  llvm::Optional<SourceLocation> ForwardDeclarationPoint;
+  std::optional<SourceLocation> ForwardDeclarationPoint;
   const CXXRecordDecl *EnclosingClass = nullptr;
   const NestedNameSpecifier *DefinitionQualifier = nullptr;
   const DeclContext *SemanticDC = nullptr;
diff --git a/clang-tools-extra/clangd/refactor/tweaks/ObjCMemberwiseInitializer.cpp b/clang-tools-extra/clangd/refactor/tweaks/ObjCMemberwiseInitializer.cpp
index dbaf2a5..c3f5321 100644
--- a/clang-tools-extra/clangd/refactor/tweaks/ObjCMemberwiseInitializer.cpp
+++ b/clang-tools-extra/clangd/refactor/tweaks/ObjCMemberwiseInitializer.cpp
@@ -90,7 +90,7 @@
     else // Could be a dynamic property or a property in a header.
       Assignee = ("self." + Name).str();
   }
-  static llvm::Optional<MethodParameter> parameterFor(const Decl &D) {
+  static std::optional<MethodParameter> parameterFor(const Decl &D) {
     if (const auto *ID = dyn_cast<ObjCIvarDecl>(&D))
       return MethodParameter(*ID);
     if (const auto *PD = dyn_cast<ObjCPropertyDecl>(&D))
diff --git a/clang-tools-extra/clangd/refactor/tweaks/RemoveUsingNamespace.cpp b/clang-tools-extra/clangd/refactor/tweaks/RemoveUsingNamespace.cpp
index 51d299e..da32e00a 100644
--- a/clang-tools-extra/clangd/refactor/tweaks/RemoveUsingNamespace.cpp
+++ b/clang-tools-extra/clangd/refactor/tweaks/RemoveUsingNamespace.cpp
@@ -73,7 +73,7 @@
 llvm::Expected<tooling::Replacement>
 removeUsingDirective(ASTContext &Ctx, const UsingDirectiveDecl *D) {
   auto &SM = Ctx.getSourceManager();
-  llvm::Optional<Token> NextTok =
+  std::optional<Token> NextTok =
       Lexer::findNextToken(D->getEndLoc(), SM, Ctx.getLangOpts());
   if (!NextTok || NextTok->isNot(tok::semi))
     return error("no semicolon after using-directive");
diff --git a/clang-tools-extra/clangd/tool/Check.cpp b/clang-tools-extra/clangd/tool/Check.cpp
index 3250571..b0af900 100644
--- a/clang-tools-extra/clangd/tool/Check.cpp
+++ b/clang-tools-extra/clangd/tool/Check.cpp
@@ -126,7 +126,7 @@
   format::FormatStyle Style;
   // from buildAST
   std::shared_ptr<const PreambleData> Preamble;
-  llvm::Optional<ParsedAST> AST;
+  std::optional<ParsedAST> AST;
   FileIndex Index;
 
 public:
@@ -167,7 +167,7 @@
 
   // Prepare inputs and build CompilerInvocation (parsed compile command).
   bool buildInvocation(const ThreadsafeFS &TFS,
-                       llvm::Optional<std::string> Contents) {
+                       std::optional<std::string> Contents) {
     StoreDiags CaptureInvocationDiags;
     std::vector<std::string> CC1Args;
     Inputs.CompileCommand = Cmd;
@@ -438,7 +438,7 @@
   }
 
   llvm::SmallString<0> FakeFile;
-  llvm::Optional<std::string> Contents;
+  std::optional<std::string> Contents;
   if (File.empty()) {
     llvm::sys::path::system_temp_directory(false, FakeFile);
     llvm::sys::path::append(FakeFile, "test.cc");
diff --git a/clang-tools-extra/clangd/tool/ClangdMain.cpp b/clang-tools-extra/clangd/tool/ClangdMain.cpp
index fa6bda1..e0682f1 100644
--- a/clang-tools-extra/clangd/tool/ClangdMain.cpp
+++ b/clang-tools-extra/clangd/tool/ClangdMain.cpp
@@ -639,9 +639,9 @@
 
 public:
   FlagsConfigProvider() {
-    llvm::Optional<Config::CDBSearchSpec> CDBSearch;
-    llvm::Optional<Config::ExternalIndexSpec> IndexSpec;
-    llvm::Optional<Config::BackgroundPolicy> BGPolicy;
+    std::optional<Config::CDBSearchSpec> CDBSearch;
+    std::optional<Config::ExternalIndexSpec> IndexSpec;
+    std::optional<Config::BackgroundPolicy> BGPolicy;
 
     // If --compile-commands-dir arg was invoked, check value and override
     // default path.
@@ -784,7 +784,7 @@
     clang::format::DefaultFallbackStyle = FallbackStyle.c_str();
 
   // Validate command line arguments.
-  llvm::Optional<llvm::raw_fd_ostream> InputMirrorStream;
+  std::optional<llvm::raw_fd_ostream> InputMirrorStream;
   if (!InputMirrorFile.empty()) {
     std::error_code EC;
     InputMirrorStream.emplace(InputMirrorFile, /*ref*/ EC,
@@ -808,7 +808,7 @@
   // Setup tracing facilities if CLANGD_TRACE is set. In practice enabling a
   // trace flag in your editor's config is annoying, launching with
   // `CLANGD_TRACE=trace.json vim` is easier.
-  llvm::Optional<llvm::raw_fd_ostream> TracerStream;
+  std::optional<llvm::raw_fd_ostream> TracerStream;
   std::unique_ptr<trace::EventTracer> Tracer;
   const char *JSONTraceFile = getenv("CLANGD_TRACE");
   const char *MetricsCSVFile = getenv("CLANGD_METRICS");
@@ -828,7 +828,7 @@
     }
   }
 
-  llvm::Optional<trace::Session> TracingSession;
+  std::optional<trace::Session> TracingSession;
   if (Tracer)
     TracingSession.emplace(*Tracer);
 
diff --git a/clang-tools-extra/clangd/unittests/ClangdLSPServerTests.cpp b/clang-tools-extra/clangd/unittests/ClangdLSPServerTests.cpp
index a9a30ea..4c6a238 100644
--- a/clang-tools-extra/clangd/unittests/ClangdLSPServerTests.cpp
+++ b/clang-tools-extra/clangd/unittests/ClangdLSPServerTests.cpp
@@ -98,8 +98,8 @@
 
   Logger L;
   LoggingSession LogSession;
-  llvm::Optional<ClangdLSPServer> Server;
-  llvm::Optional<std::thread> ServerThread;
+  std::optional<ClangdLSPServer> Server;
+  std::optional<std::thread> ServerThread;
   LSPClient Client;
 };
 
@@ -262,10 +262,11 @@
               ElementsAre(llvm::json::Value(2), llvm::json::Value(10)));
 }
 
-// Creates a Callback that writes its received value into an Optional<Expected>.
+// Creates a Callback that writes its received value into an
+// std::optional<Expected>.
 template <typename T>
 llvm::unique_function<void(llvm::Expected<T>)>
-capture(llvm::Optional<llvm::Expected<T>> &Out) {
+capture(std::optional<llvm::Expected<T>> &Out) {
   Out.reset();
   return [&Out](llvm::Expected<T> V) { Out.emplace(std::move(V)); };
 }
diff --git a/clang-tools-extra/clangd/unittests/ClangdTests.cpp b/clang-tools-extra/clangd/unittests/ClangdTests.cpp
index 0563062..6e6036e 100644
--- a/clang-tools-extra/clangd/unittests/ClangdTests.cpp
+++ b/clang-tools-extra/clangd/unittests/ClangdTests.cpp
@@ -1111,7 +1111,7 @@
     DelayedCompilationDatabase(Notification &CanReturnCommand)
         : CanReturnCommand(CanReturnCommand) {}
 
-    llvm::Optional<tooling::CompileCommand>
+    std::optional<tooling::CompileCommand>
     getCompileCommand(PathRef File) const override {
       // FIXME: make this timeout and fail instead of waiting forever in case
       // something goes wrong.
diff --git a/clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp b/clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp
index 8d434a2..16dd81a 100644
--- a/clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp
+++ b/clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp
@@ -436,7 +436,7 @@
 
 TEST_F(ConfigCompileTests, ExternalBlockMountPoint) {
   auto GetFrag = [](llvm::StringRef Directory,
-                    llvm::Optional<const char *> MountPoint) {
+                    std::optional<const char *> MountPoint) {
     Fragment Frag;
     Frag.Source.Directory = Directory.str();
     Fragment::IndexBlock::ExternalBlock External;
diff --git a/clang-tools-extra/clangd/unittests/ConfigTesting.h b/clang-tools-extra/clangd/unittests/ConfigTesting.h
index c06a061..dc92e13 100644
--- a/clang-tools-extra/clangd/unittests/ConfigTesting.h
+++ b/clang-tools-extra/clangd/unittests/ConfigTesting.h
@@ -50,7 +50,7 @@
     std::string Message;
     llvm::SourceMgr::DiagKind Kind;
     Position Pos;
-    llvm::Optional<Range> Rng;
+    std::optional<Range> Rng;
 
     friend void PrintTo(const Diag &D, std::ostream *OS) {
       *OS << (D.Kind == llvm::SourceMgr::DK_Error ? "error: " : "warning: ")
diff --git a/clang-tools-extra/clangd/unittests/ExpectedTypeTest.cpp b/clang-tools-extra/clangd/unittests/ExpectedTypeTest.cpp
index 839f4c8..afefa24 100644
--- a/clang-tools-extra/clangd/unittests/ExpectedTypeTest.cpp
+++ b/clang-tools-extra/clangd/unittests/ExpectedTypeTest.cpp
@@ -39,7 +39,7 @@
   }
 
   /// An overload for convenience.
-  llvm::Optional<OpaqueType> fromCompletionResult(const NamedDecl *D) {
+  std::optional<OpaqueType> fromCompletionResult(const NamedDecl *D) {
     return OpaqueType::fromCompletionResult(
         astCtx(), CodeCompletionResult(D, CCP_Declaration));
   }
@@ -75,7 +75,7 @@
 
 private:
   // Set after calling build().
-  llvm::Optional<ParsedAST> AST;
+  std::optional<ParsedAST> AST;
 };
 
 TEST_F(ExpectedTypeConversionTest, BasicTypes) {
diff --git a/clang-tools-extra/clangd/unittests/GlobalCompilationDatabaseTests.cpp b/clang-tools-extra/clangd/unittests/GlobalCompilationDatabaseTests.cpp
index 71bcb12..a2fc52a 100644
--- a/clang-tools-extra/clangd/unittests/GlobalCompilationDatabaseTests.cpp
+++ b/clang-tools-extra/clangd/unittests/GlobalCompilationDatabaseTests.cpp
@@ -64,7 +64,7 @@
 class OverlayCDBTest : public ::testing::Test {
   class BaseCDB : public GlobalCompilationDatabase {
   public:
-    llvm::Optional<tooling::CompileCommand>
+    std::optional<tooling::CompileCommand>
     getCompileCommand(llvm::StringRef File) const override {
       if (File == testPath("foo.cc"))
         return cmd(File, "-DA=1");
@@ -76,7 +76,7 @@
       return cmd(File, "-DA=2");
     }
 
-    llvm::Optional<ProjectInfo> getProjectInfo(PathRef File) const override {
+    std::optional<ProjectInfo> getProjectInfo(PathRef File) const override {
       return ProjectInfo{testRoot()};
     }
   };
diff --git a/clang-tools-extra/clangd/unittests/HeaderSourceSwitchTests.cpp b/clang-tools-extra/clangd/unittests/HeaderSourceSwitchTests.cpp
index f6bc9a6..6e280f5 100644
--- a/clang-tools-extra/clangd/unittests/HeaderSourceSwitchTests.cpp
+++ b/clang-tools-extra/clangd/unittests/HeaderSourceSwitchTests.cpp
@@ -31,7 +31,7 @@
   FS.Files[FooCpp];
   FS.Files[FooH];
   FS.Files[Invalid];
-  Optional<Path> PathResult =
+  std::optional<Path> PathResult =
       getCorrespondingHeaderOrSource(FooCpp, FS.view(std::nullopt));
   EXPECT_TRUE(PathResult.has_value());
   ASSERT_EQ(*PathResult, FooH);
@@ -142,7 +142,7 @@
   // Test for switch from .h header to .cc source
   struct {
     llvm::StringRef HeaderCode;
-    llvm::Optional<std::string> ExpectedSource;
+    std::optional<std::string> ExpectedSource;
   } TestCases[] = {
       {"// empty, no header found", std::nullopt},
       {R"cpp(
@@ -211,7 +211,7 @@
   // Test for switching from .cc source file to .h header.
   struct {
     llvm::StringRef SourceCode;
-    llvm::Optional<std::string> ExpectedResult;
+    std::optional<std::string> ExpectedResult;
   } TestCases[] = {
       {"// empty, no header found", std::nullopt},
       {R"cpp(
diff --git a/clang-tools-extra/clangd/unittests/HeadersTests.cpp b/clang-tools-extra/clangd/unittests/HeadersTests.cpp
index b14a14f0..4fadb7c 100644
--- a/clang-tools-extra/clangd/unittests/HeadersTests.cpp
+++ b/clang-tools-extra/clangd/unittests/HeadersTests.cpp
@@ -119,8 +119,8 @@
     return Path.value_or("");
   }
 
-  llvm::Optional<TextEdit> insert(llvm::StringRef VerbatimHeader,
-                                  tooling::IncludeDirective Directive) {
+  std::optional<TextEdit> insert(llvm::StringRef VerbatimHeader,
+                                 tooling::IncludeDirective Directive) {
     Clang = setupClang();
     PreprocessOnlyAction Action;
     EXPECT_TRUE(
diff --git a/clang-tools-extra/clangd/unittests/LSPBinderTests.cpp b/clang-tools-extra/clangd/unittests/LSPBinderTests.cpp
index b23c00e..03f7870 100644
--- a/clang-tools-extra/clangd/unittests/LSPBinderTests.cpp
+++ b/clang-tools-extra/clangd/unittests/LSPBinderTests.cpp
@@ -31,10 +31,11 @@
 }
 llvm::json::Value toJSON(const Foo &F) { return F.X; }
 
-// Creates a Callback that writes its received value into an Optional<Expected>.
+// Creates a Callback that writes its received value into an
+// std::optional<Expected>.
 template <typename T>
 llvm::unique_function<void(llvm::Expected<T>)>
-capture(llvm::Optional<llvm::Expected<T>> &Out) {
+capture(std::optional<llvm::Expected<T>> &Out) {
   Out.reset();
   return [&Out](llvm::Expected<T> V) { Out.emplace(std::move(V)); };
 }
@@ -90,7 +91,7 @@
               UnorderedElementsAre("notify"));
   ASSERT_THAT(RawHandlers.CommandHandlers.keys(),
               UnorderedElementsAre("cmdPlusOne"));
-  llvm::Optional<llvm::Expected<llvm::json::Value>> Reply;
+  std::optional<llvm::Expected<llvm::json::Value>> Reply;
 
   auto &RawPlusOne = RawHandlers.MethodHandlers["plusOne"];
   RawPlusOne(1, capture(Reply));
@@ -136,14 +137,14 @@
   LSPBinder::OutgoingMethod<Foo, Foo> Fail;
   Fail = Binder.outgoingMethod("fail");
 
-  llvm::Optional<llvm::Expected<Foo>> Reply;
+  std::optional<llvm::Expected<Foo>> Reply;
   Echo(Foo{2}, capture(Reply));
   EXPECT_THAT(RawOutgoing.take("echo"), ElementsAre(llvm::json::Value(2)));
   ASSERT_TRUE(Reply.has_value());
   EXPECT_THAT_EXPECTED(*Reply, llvm::HasValue(Foo{2}));
 
   // JSON response is integer, can't be parsed as string.
-  llvm::Optional<llvm::Expected<std::string>> WrongTypeReply;
+  std::optional<llvm::Expected<std::string>> WrongTypeReply;
   WrongSignature(Foo{2}, capture(WrongTypeReply));
   EXPECT_THAT(RawOutgoing.take("wrongSignature"),
               ElementsAre(llvm::json::Value(2)));
diff --git a/clang-tools-extra/clangd/unittests/LSPClient.cpp b/clang-tools-extra/clangd/unittests/LSPClient.cpp
index 027bf57..9361c0e 100644
--- a/clang-tools-extra/clangd/unittests/LSPClient.cpp
+++ b/clang-tools-extra/clangd/unittests/LSPClient.cpp
@@ -199,7 +199,7 @@
 
 void LSPClient::sync() { call("sync", nullptr).takeValue(); }
 
-llvm::Optional<std::vector<llvm::json::Value>>
+std::optional<std::vector<llvm::json::Value>>
 LSPClient::diagnostics(llvm::StringRef Path) {
   sync();
   auto Notifications = takeNotifications("textDocument/publishDiagnostics");
diff --git a/clang-tools-extra/clangd/unittests/PreambleTests.cpp b/clang-tools-extra/clangd/unittests/PreambleTests.cpp
index eb071e3..1e95b62 100644
--- a/clang-tools-extra/clangd/unittests/PreambleTests.cpp
+++ b/clang-tools-extra/clangd/unittests/PreambleTests.cpp
@@ -190,8 +190,8 @@
                                 Field(&Inclusion::Resolved, testPath("a.h")))));
 }
 
-llvm::Optional<ParsedAST> createPatchedAST(llvm::StringRef Baseline,
-                                           llvm::StringRef Modified) {
+std::optional<ParsedAST> createPatchedAST(llvm::StringRef Baseline,
+                                          llvm::StringRef Modified) {
   auto BaselinePreamble = TestTU::withCode(Baseline).preamble();
   if (!BaselinePreamble) {
     ADD_FAILURE() << "Failed to build baseline preamble";
diff --git a/clang-tools-extra/clangd/unittests/SourceCodeTests.cpp b/clang-tools-extra/clangd/unittests/SourceCodeTests.cpp
index eb5f60c..9d40702 100644
--- a/clang-tools-extra/clangd/unittests/SourceCodeTests.cpp
+++ b/clang-tools-extra/clangd/unittests/SourceCodeTests.cpp
@@ -356,9 +356,9 @@
 }
 
 class SpelledWordsTest : public ::testing::Test {
-  llvm::Optional<ParsedAST> AST;
+  std::optional<ParsedAST> AST;
 
-  llvm::Optional<SpelledWord> tryWord(const char *Text) {
+  std::optional<SpelledWord> tryWord(const char *Text) {
     llvm::Annotations A(Text);
     auto TU = TestTU::withCode(A.code());
     AST = TU.build();
@@ -663,7 +663,7 @@
   const auto &Func = cast<FunctionDecl>(findDecl(AST, "test"));
   const auto &Body = cast<CompoundStmt>(Func.getBody());
   const auto &Loop = cast<WhileStmt>(*Body->child_begin());
-  llvm::Optional<SourceRange> Range = toHalfOpenFileRange(
+  std::optional<SourceRange> Range = toHalfOpenFileRange(
       AST.getSourceManager(), AST.getLangOpts(), Loop->getSourceRange());
   ASSERT_TRUE(Range) << "Failed to get file range";
   EXPECT_EQ(AST.getSourceManager().getFileOffset(Range->getBegin()),
diff --git a/clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp b/clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp
index 08523ed..a2bf1c0 100644
--- a/clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp
+++ b/clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp
@@ -132,7 +132,7 @@
   std::string HeaderName = "f.h";
   std::string FileName = "f.cpp";
   TestTU File;
-  llvm::Optional<ParsedAST> AST; // Initialized after build.
+  std::optional<ParsedAST> AST; // Initialized after build.
 };
 
 TEST_F(ShouldCollectSymbolTest, ShouldCollectSymbol) {
@@ -870,7 +870,7 @@
   CollectorOpts.RefFilter = RefKind::All;
   CollectorOpts.CollectMainFileRefs = true;
   runSymbolCollector("", Code.code());
-  auto FindRefWithRange = [&](Range R) -> Optional<Ref> {
+  auto FindRefWithRange = [&](Range R) -> std::optional<Ref> {
     for (auto &Entry : Refs) {
       for (auto &Ref : Entry.second) {
         if (rangesMatch(Ref.Location, R))
diff --git a/clang-tools-extra/clangd/unittests/SymbolInfoTests.cpp b/clang-tools-extra/clangd/unittests/SymbolInfoTests.cpp
index ad76d7d..6c91f37 100644
--- a/clang-tools-extra/clangd/unittests/SymbolInfoTests.cpp
+++ b/clang-tools-extra/clangd/unittests/SymbolInfoTests.cpp
@@ -377,7 +377,7 @@
 
     std::vector<SymbolDetails> Expected;
     for (const auto &Sym : T.second) {
-      llvm::Optional<Location> Decl, Def;
+      std::optional<Location> Decl, Def;
       if (Sym.DeclMarker)
         Decl = Location{URIForFile::canonicalize(testPath(TU.Filename), ""),
                         TestInput.range(Sym.DeclMarker)};
diff --git a/clang-tools-extra/clangd/unittests/SyncAPI.cpp b/clang-tools-extra/clangd/unittests/SyncAPI.cpp
index 2c4fde7..d48622eb 100644
--- a/clang-tools-extra/clangd/unittests/SyncAPI.cpp
+++ b/clang-tools-extra/clangd/unittests/SyncAPI.cpp
@@ -28,7 +28,7 @@
 ///    T Result;
 ///    someAsyncFunc(Param1, Param2, /*Callback=*/capture(Result));
 template <typename T> struct CaptureProxy {
-  CaptureProxy(llvm::Optional<T> &Target) : Target(&Target) { assert(!Target); }
+  CaptureProxy(std::optional<T> &Target) : Target(&Target) { assert(!Target); }
 
   CaptureProxy(const CaptureProxy &) = delete;
   CaptureProxy &operator=(const CaptureProxy &) = delete;
@@ -55,7 +55,7 @@
   }
 
 private:
-  llvm::Optional<T> *Target;
+  std::optional<T> *Target;
   // Using shared_ptr to workaround compilation errors with MSVC.
   // MSVC only allows default-constructible and copyable objects as future<>
   // arguments.
@@ -63,7 +63,7 @@
   std::future<std::shared_ptr<T>> Future;
 };
 
-template <typename T> CaptureProxy<T> capture(llvm::Optional<T> &Target) {
+template <typename T> CaptureProxy<T> capture(std::optional<T> &Target) {
   return CaptureProxy<T>(Target);
 }
 } // namespace
@@ -71,7 +71,7 @@
 llvm::Expected<CodeCompleteResult>
 runCodeComplete(ClangdServer &Server, PathRef File, Position Pos,
                 clangd::CodeCompleteOptions Opts) {
-  llvm::Optional<llvm::Expected<CodeCompleteResult>> Result;
+  std::optional<llvm::Expected<CodeCompleteResult>> Result;
   Server.codeComplete(File, Pos, Opts, capture(Result));
   return std::move(*Result);
 }
@@ -79,21 +79,21 @@
 llvm::Expected<SignatureHelp> runSignatureHelp(ClangdServer &Server,
                                                PathRef File, Position Pos,
                                                MarkupKind DocumentationFormat) {
-  llvm::Optional<llvm::Expected<SignatureHelp>> Result;
+  std::optional<llvm::Expected<SignatureHelp>> Result;
   Server.signatureHelp(File, Pos, DocumentationFormat, capture(Result));
   return std::move(*Result);
 }
 
 llvm::Expected<std::vector<LocatedSymbol>>
 runLocateSymbolAt(ClangdServer &Server, PathRef File, Position Pos) {
-  llvm::Optional<llvm::Expected<std::vector<LocatedSymbol>>> Result;
+  std::optional<llvm::Expected<std::vector<LocatedSymbol>>> Result;
   Server.locateSymbolAt(File, Pos, capture(Result));
   return std::move(*Result);
 }
 
 llvm::Expected<std::vector<DocumentHighlight>>
 runFindDocumentHighlights(ClangdServer &Server, PathRef File, Position Pos) {
-  llvm::Optional<llvm::Expected<std::vector<DocumentHighlight>>> Result;
+  std::optional<llvm::Expected<std::vector<DocumentHighlight>>> Result;
   Server.findDocumentHighlights(File, Pos, capture(Result));
   return std::move(*Result);
 }
@@ -101,23 +101,23 @@
 llvm::Expected<RenameResult> runRename(ClangdServer &Server, PathRef File,
                                        Position Pos, llvm::StringRef NewName,
                                        const RenameOptions &RenameOpts) {
-  llvm::Optional<llvm::Expected<RenameResult>> Result;
+  std::optional<llvm::Expected<RenameResult>> Result;
   Server.rename(File, Pos, NewName, RenameOpts, capture(Result));
   return std::move(*Result);
 }
 
 llvm::Expected<RenameResult>
 runPrepareRename(ClangdServer &Server, PathRef File, Position Pos,
-                 llvm::Optional<std::string> NewName,
+                 std::optional<std::string> NewName,
                  const RenameOptions &RenameOpts) {
-  llvm::Optional<llvm::Expected<RenameResult>> Result;
+  std::optional<llvm::Expected<RenameResult>> Result;
   Server.prepareRename(File, Pos, NewName, RenameOpts, capture(Result));
   return std::move(*Result);
 }
 
 llvm::Expected<tooling::Replacements>
-runFormatFile(ClangdServer &Server, PathRef File, llvm::Optional<Range> Rng) {
-  llvm::Optional<llvm::Expected<tooling::Replacements>> Result;
+runFormatFile(ClangdServer &Server, PathRef File, std::optional<Range> Rng) {
+  std::optional<llvm::Expected<tooling::Replacements>> Result;
   Server.formatFile(File, Rng, capture(Result));
   return std::move(*Result);
 }
@@ -146,14 +146,14 @@
 llvm::Expected<std::vector<SelectionRange>>
 runSemanticRanges(ClangdServer &Server, PathRef File,
                   const std::vector<Position> &Pos) {
-  llvm::Optional<llvm::Expected<std::vector<SelectionRange>>> Result;
+  std::optional<llvm::Expected<std::vector<SelectionRange>>> Result;
   Server.semanticRanges(File, Pos, capture(Result));
   return std::move(*Result);
 }
 
-llvm::Expected<llvm::Optional<clangd::Path>>
+llvm::Expected<std::optional<clangd::Path>>
 runSwitchHeaderSource(ClangdServer &Server, PathRef File) {
-  llvm::Optional<llvm::Expected<llvm::Optional<clangd::Path>>> Result;
+  std::optional<llvm::Expected<std::optional<clangd::Path>>> Result;
   Server.switchSourceHeader(File, capture(Result));
   return std::move(*Result);
 }
diff --git a/clang-tools-extra/clangd/unittests/SyncAPI.h b/clang-tools-extra/clangd/unittests/SyncAPI.h
index 6b4e3fc..cf3de4f 100644
--- a/clang-tools-extra/clangd/unittests/SyncAPI.h
+++ b/clang-tools-extra/clangd/unittests/SyncAPI.h
@@ -49,11 +49,11 @@
 
 llvm::Expected<RenameResult>
 runPrepareRename(ClangdServer &Server, PathRef File, Position Pos,
-                 llvm::Optional<std::string> NewName,
+                 std::optional<std::string> NewName,
                  const clangd::RenameOptions &RenameOpts);
 
 llvm::Expected<tooling::Replacements>
-runFormatFile(ClangdServer &Server, PathRef File, llvm::Optional<Range>);
+runFormatFile(ClangdServer &Server, PathRef File, std::optional<Range>);
 
 SymbolSlab runFuzzyFind(const SymbolIndex &Index, StringRef Query);
 SymbolSlab runFuzzyFind(const SymbolIndex &Index, const FuzzyFindRequest &Req);
@@ -63,7 +63,7 @@
 runSemanticRanges(ClangdServer &Server, PathRef File,
                   const std::vector<Position> &Pos);
 
-llvm::Expected<llvm::Optional<clangd::Path>>
+llvm::Expected<std::optional<clangd::Path>>
 runSwitchHeaderSource(ClangdServer &Server, PathRef File);
 
 llvm::Error runCustomAction(ClangdServer &Server, PathRef File,
diff --git a/clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp b/clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp
index c7e28a0..5b3cab1 100644
--- a/clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp
+++ b/clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp
@@ -1204,7 +1204,7 @@
                      OK = testPath("ok.h"),
                      NotIncluded = testPath("not_included.h");
   struct NoHeadersCDB : public GlobalCompilationDatabase {
-    llvm::Optional<tooling::CompileCommand>
+    std::optional<tooling::CompileCommand>
     getCompileCommand(PathRef File) const override {
       if (File == NoCmd || File == NotIncluded || FailAll)
         return std::nullopt;
@@ -1387,7 +1387,7 @@
     std::vector<RequestID> Releases;
     llvm::DenseMap<RequestID, Callback> Callbacks;
     // If set, the notification is signalled after acquiring the specified ID.
-    llvm::Optional<std::pair<RequestID, Notification *>> Notify;
+    std::optional<std::pair<RequestID, Notification *>> Notify;
 
     RequestID acquire(llvm::StringRef Filename, Callback CB) override {
       RequestID ID;
diff --git a/clang-tools-extra/clangd/unittests/TestFS.cpp b/clang-tools-extra/clangd/unittests/TestFS.cpp
index be26a6c..1b313f7 100644
--- a/clang-tools-extra/clangd/unittests/TestFS.cpp
+++ b/clang-tools-extra/clangd/unittests/TestFS.cpp
@@ -52,12 +52,12 @@
   // -ffreestanding avoids implicit stdc-predef.h.
 }
 
-llvm::Optional<ProjectInfo>
+std::optional<ProjectInfo>
 MockCompilationDatabase::getProjectInfo(PathRef File) const {
   return ProjectInfo{std::string(Directory)};
 }
 
-llvm::Optional<tooling::CompileCommand>
+std::optional<tooling::CompileCommand>
 MockCompilationDatabase::getCompileCommand(PathRef File) const {
   if (ExtraClangFlags.empty())
     return std::nullopt;
diff --git a/clang-tools-extra/clangd/unittests/TestFS.h b/clang-tools-extra/clangd/unittests/TestFS.h
index 3e4ac3b..a7a521c 100644
--- a/clang-tools-extra/clangd/unittests/TestFS.h
+++ b/clang-tools-extra/clangd/unittests/TestFS.h
@@ -61,10 +61,10 @@
   MockCompilationDatabase(StringRef Directory = StringRef(),
                           StringRef RelPathPrefix = StringRef());
 
-  llvm::Optional<tooling::CompileCommand>
+  std::optional<tooling::CompileCommand>
   getCompileCommand(PathRef File) const override;
 
-  llvm::Optional<ProjectInfo> getProjectInfo(PathRef File) const override;
+  std::optional<ProjectInfo> getProjectInfo(PathRef File) const override;
 
   std::vector<std::string> ExtraClangFlags;
 
diff --git a/clang-tools-extra/clangd/unittests/TestWorkspace.cpp b/clang-tools-extra/clangd/unittests/TestWorkspace.cpp
index 662eef6..40c08fc 100644
--- a/clang-tools-extra/clangd/unittests/TestWorkspace.cpp
+++ b/clang-tools-extra/clangd/unittests/TestWorkspace.cpp
@@ -32,7 +32,7 @@
   return Index;
 }
 
-Optional<ParsedAST> TestWorkspace::openFile(llvm::StringRef Filename) {
+std::optional<ParsedAST> TestWorkspace::openFile(llvm::StringRef Filename) {
   auto It = Inputs.find(Filename);
   if (It == Inputs.end()) {
     ADD_FAILURE() << "Accessing non-existing file: " << Filename;
diff --git a/clang-tools-extra/clangd/unittests/TestWorkspace.h b/clang-tools-extra/clangd/unittests/TestWorkspace.h
index bc6aee1..a5e688d 100644
--- a/clang-tools-extra/clangd/unittests/TestWorkspace.h
+++ b/clang-tools-extra/clangd/unittests/TestWorkspace.h
@@ -39,7 +39,7 @@
 
   std::unique_ptr<SymbolIndex> index();
 
-  Optional<ParsedAST> openFile(llvm::StringRef Filename);
+  std::optional<ParsedAST> openFile(llvm::StringRef Filename);
 
 private:
   struct SourceFile {
diff --git a/clang-tools-extra/clangd/unittests/XRefsTests.cpp b/clang-tools-extra/clangd/unittests/XRefsTests.cpp
index ae19656..3bbcde2 100644
--- a/clang-tools-extra/clangd/unittests/XRefsTests.cpp
+++ b/clang-tools-extra/clangd/unittests/XRefsTests.cpp
@@ -272,7 +272,7 @@
 }
 
 MATCHER_P3(sym, Name, Decl, DefOrNone, "") {
-  llvm::Optional<Range> Def = DefOrNone;
+  std::optional<Range> Def = DefOrNone;
   if (Name != arg.Name) {
     *result_listener << "Name is " << arg.Name;
     return false;
@@ -1003,8 +1003,8 @@
       )objc"};
   for (const char *Test : Tests) {
     Annotations T(Test);
-    llvm::Optional<Range> WantDecl;
-    llvm::Optional<Range> WantDef;
+    std::optional<Range> WantDecl;
+    std::optional<Range> WantDef;
     if (!T.ranges().empty())
       WantDecl = WantDef = T.range();
     if (!T.ranges("decl").empty())
@@ -1026,7 +1026,7 @@
       ASSERT_THAT(Results, ::testing::SizeIs(1)) << Test;
       EXPECT_EQ(Results[0].PreferredDeclaration.range, *WantDecl) << Test;
       EXPECT_TRUE(Results[0].ID) << Test;
-      llvm::Optional<Range> GotDef;
+      std::optional<Range> GotDef;
       if (Results[0].Definition)
         GotDef = Results[0].Definition->range;
       EXPECT_EQ(WantDef, GotDef) << Test;
@@ -1061,7 +1061,7 @@
   //   N starts at 0.
   struct ExpectedRanges {
     Range WantDecl;
-    llvm::Optional<Range> WantDef;
+    std::optional<Range> WantDef;
   };
   const char *Tests[] = {
       R"objc(
@@ -1128,7 +1128,7 @@
     for (size_t Idx = 0; Idx < Ranges.size(); Idx++) {
       EXPECT_EQ(Results[Idx].PreferredDeclaration.range, Ranges[Idx].WantDecl)
           << "($decl" << Idx << ")" << Test;
-      llvm::Optional<Range> GotDef;
+      std::optional<Range> GotDef;
       if (Results[Idx].Definition)
         GotDef = Results[Idx].Definition->range;
       EXPECT_EQ(GotDef, Ranges[Idx].WantDef) << "($def" << Idx << ")" << Test;
@@ -1159,8 +1159,8 @@
 
   for (const char *Test : Tests) {
     Annotations T(Test);
-    llvm::Optional<Range> WantDecl;
-    llvm::Optional<Range> WantDef;
+    std::optional<Range> WantDecl;
+    std::optional<Range> WantDef;
     if (!T.ranges().empty())
       WantDecl = WantDef = T.range();
     if (!T.ranges("decl").empty())
@@ -1179,7 +1179,7 @@
     } else {
       ASSERT_THAT(Results, ::testing::SizeIs(1)) << Test;
       EXPECT_EQ(Results[0].PreferredDeclaration.range, *WantDecl) << Test;
-      llvm::Optional<Range> GotDef;
+      std::optional<Range> GotDef;
       if (Results[0].Definition)
         GotDef = Results[0].Definition->range;
       EXPECT_EQ(WantDef, GotDef) << Test;
@@ -1233,7 +1233,7 @@
 
   for (const char *Test : Tests) {
     Annotations T(Test);
-    llvm::Optional<Range> WantDecl;
+    std::optional<Range> WantDecl;
     if (!T.ranges().empty())
       WantDecl = T.range();
 
@@ -1731,7 +1731,7 @@
     Annotations T(Test);
     auto AST = TestTU::withCode(T.code()).build();
     const auto &SM = AST.getSourceManager();
-    llvm::Optional<Range> Nearby;
+    std::optional<Range> Nearby;
     auto Word =
         SpelledWord::touching(cantFail(sourceLocationInMainFile(SM, T.point())),
                               AST.getTokens(), AST.getLangOpts());
@@ -2379,7 +2379,7 @@
 
 TEST(FindReferences, NoQueryForLocalSymbols) {
   struct RecordingIndex : public MemIndex {
-    mutable Optional<llvm::DenseSet<SymbolID>> RefIDs;
+    mutable std::optional<llvm::DenseSet<SymbolID>> RefIDs;
     bool refs(const RefsRequest &Req,
               llvm::function_ref<void(const Ref &)>) const override {
       RefIDs = Req.IDs;
diff --git a/clang-tools-extra/clangd/unittests/support/FileCacheTests.cpp b/clang-tools-extra/clangd/unittests/support/FileCacheTests.cpp
index 133b83b..840cad6 100644
--- a/clang-tools-extra/clangd/unittests/support/FileCacheTests.cpp
+++ b/clang-tools-extra/clangd/unittests/support/FileCacheTests.cpp
@@ -41,7 +41,7 @@
     std::string Result;
     read(
         FS, FreshTime,
-        [&](llvm::Optional<llvm::StringRef> Data) {
+        [&](std::optional<llvm::StringRef> Data) {
           GotParse = true;
           Value = Data.value_or("").str();
         },
diff --git a/clang-tools-extra/clangd/unittests/tweaks/TweakTesting.cpp b/clang-tools-extra/clangd/unittests/tweaks/TweakTesting.cpp
index 12836d0..ee93436 100644
--- a/clang-tools-extra/clangd/unittests/tweaks/TweakTesting.cpp
+++ b/clang-tools-extra/clangd/unittests/tweaks/TweakTesting.cpp
@@ -61,10 +61,10 @@
 
 // Prepare and apply the specified tweak based on the selection in Input.
 // Returns std::nullopt if and only if prepare() failed.
-llvm::Optional<llvm::Expected<Tweak::Effect>>
+std::optional<llvm::Expected<Tweak::Effect>>
 applyTweak(ParsedAST &AST, llvm::Annotations::Range Range, StringRef TweakID,
            const SymbolIndex *Index, llvm::vfs::FileSystem *FS) {
-  llvm::Optional<llvm::Expected<Tweak::Effect>> Result;
+  std::optional<llvm::Expected<Tweak::Effect>> Result;
   SelectionTree::createEach(AST.getASTContext(), AST.getTokens(), Range.Begin,
                             Range.End, [&](SelectionTree ST) {
                               Tweak::Selection S(Index, AST, Range.Begin,
diff --git a/clang-tools-extra/clangd/xpc/XPCTransport.cpp b/clang-tools-extra/clangd/xpc/XPCTransport.cpp
index dac8e29..8f5b787 100644
--- a/clang-tools-extra/clangd/xpc/XPCTransport.cpp
+++ b/clang-tools-extra/clangd/xpc/XPCTransport.cpp
@@ -107,12 +107,13 @@
 bool XPCTransport::handleMessage(json::Value Message, MessageHandler &Handler) {
   // Message must be an object with "jsonrpc":"2.0".
   auto *Object = Message.getAsObject();
-  if (!Object || Object->getString("jsonrpc") != Optional<StringRef>("2.0")) {
+  if (!Object ||
+      Object->getString("jsonrpc") != std::optional<StringRef>("2.0")) {
     elog("Not a JSON-RPC 2.0 message: {0:2}", Message);
     return false;
   }
   // ID may be any JSON value. If absent, this is a notification.
-  Optional<json::Value> ID;
+  std::optional<json::Value> ID;
   if (auto *I = Object->get("id"))
     ID = std::move(*I);
   auto Method = Object->getString("method");