diff --git a/clang-tools-extra/clang-move/Move.cpp b/clang-tools-extra/clang-move/Move.cpp --- a/clang-tools-extra/clang-move/Move.cpp +++ b/clang-tools-extra/clang-move/Move.cpp @@ -131,7 +131,7 @@ void InclusionDirective(SourceLocation HashLoc, const Token & /*IncludeTok*/, StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, - Optional /*File*/, StringRef SearchPath, + OptionalFileEntryRef /*File*/, StringRef SearchPath, StringRef /*RelativePath*/, const Module * /*Imported*/, SrcMgr::CharacteristicKind /*FileType*/) override { diff --git a/clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.h b/clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.h --- a/clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.h +++ b/clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.h @@ -69,7 +69,7 @@ void InclusionDirective(SourceLocation DirectiveLoc, const Token &IncludeToken, StringRef IncludedFilename, bool IsAngled, CharSourceRange FilenameRange, - Optional IncludedFile, + OptionalFileEntryRef IncludedFile, StringRef SearchPath, StringRef RelativePath, const Module *Imported, SrcMgr::CharacteristicKind FileType) override; @@ -91,7 +91,7 @@ void PragmaDiagnosticPop(SourceLocation Loc, StringRef) override; void PragmaDiagnostic(SourceLocation Loc, StringRef, diag::Severity, StringRef) override; - void HasInclude(SourceLocation Loc, StringRef, bool, Optional , + void HasInclude(SourceLocation Loc, StringRef, bool, OptionalFileEntryRef, SrcMgr::CharacteristicKind) override; void PragmaOpenCLExtension(SourceLocation NameLoc, const IdentifierInfo *, SourceLocation StateLoc, unsigned) override; diff --git a/clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.cpp b/clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.cpp --- a/clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.cpp +++ b/clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.cpp @@ -162,7 +162,7 @@ void ExpandModularHeadersPPCallbacks::InclusionDirective( SourceLocation DirectiveLoc, const Token &IncludeToken, StringRef IncludedFilename, bool IsAngled, CharSourceRange FilenameRange, - Optional IncludedFile, StringRef SearchPath, + OptionalFileEntryRef IncludedFile, StringRef SearchPath, StringRef RelativePath, const Module *Imported, SrcMgr::CharacteristicKind FileType) { if (Imported) { @@ -224,7 +224,7 @@ parseToLocation(Loc); } void ExpandModularHeadersPPCallbacks::HasInclude(SourceLocation Loc, StringRef, - bool, Optional, + bool, OptionalFileEntryRef, SrcMgr::CharacteristicKind) { parseToLocation(Loc); } diff --git a/clang-tools-extra/clang-tidy/altera/KernelNameRestrictionCheck.cpp b/clang-tools-extra/clang-tidy/altera/KernelNameRestrictionCheck.cpp --- a/clang-tools-extra/clang-tidy/altera/KernelNameRestrictionCheck.cpp +++ b/clang-tools-extra/clang-tidy/altera/KernelNameRestrictionCheck.cpp @@ -30,7 +30,7 @@ void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, bool IsAngled, CharSourceRange FileNameRange, - Optional File, StringRef SearchPath, + OptionalFileEntryRef File, StringRef SearchPath, StringRef RelativePath, const Module *Imported, SrcMgr::CharacteristicKind FileType) override; @@ -62,8 +62,8 @@ void KernelNameRestrictionPPCallbacks::InclusionDirective( SourceLocation HashLoc, const Token &, StringRef FileName, bool, - CharSourceRange, Optional, StringRef, StringRef, - const Module *, SrcMgr::CharacteristicKind) { + CharSourceRange, OptionalFileEntryRef, StringRef, StringRef, const Module *, + SrcMgr::CharacteristicKind) { IncludeDirective ID = {HashLoc, FileName}; IncludeDirectives.push_back(std::move(ID)); } diff --git a/clang-tools-extra/clang-tidy/bugprone/SuspiciousIncludeCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SuspiciousIncludeCheck.cpp --- a/clang-tools-extra/clang-tidy/bugprone/SuspiciousIncludeCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/SuspiciousIncludeCheck.cpp @@ -25,7 +25,7 @@ void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, - Optional File, StringRef SearchPath, + OptionalFileEntryRef File, StringRef SearchPath, StringRef RelativePath, const Module *Imported, SrcMgr::CharacteristicKind FileType) override; @@ -72,7 +72,7 @@ void SuspiciousIncludePPCallbacks::InclusionDirective( SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, - bool IsAngled, CharSourceRange FilenameRange, Optional File, + bool IsAngled, CharSourceRange FilenameRange, OptionalFileEntryRef File, StringRef SearchPath, StringRef RelativePath, const Module *Imported, SrcMgr::CharacteristicKind FileType) { if (IncludeTok.getIdentifierInfo()->getPPKeywordID() == tok::pp_import) @@ -93,7 +93,7 @@ llvm::sys::path::replace_extension(GuessedFileName, (HFE.size() ? "." : "") + HFE); - Optional File = + OptionalFileEntryRef File = PP->LookupFile(DiagLoc, GuessedFileName, IsAngled, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); if (File) { diff --git a/clang-tools-extra/clang-tidy/llvm/IncludeOrderCheck.cpp b/clang-tools-extra/clang-tidy/llvm/IncludeOrderCheck.cpp --- a/clang-tools-extra/clang-tidy/llvm/IncludeOrderCheck.cpp +++ b/clang-tools-extra/clang-tidy/llvm/IncludeOrderCheck.cpp @@ -28,7 +28,7 @@ void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, - Optional File, StringRef SearchPath, + OptionalFileEntryRef File, StringRef SearchPath, StringRef RelativePath, const Module *Imported, SrcMgr::CharacteristicKind FileType) override; void EndOfMainFile() override; @@ -82,7 +82,7 @@ void IncludeOrderPPCallbacks::InclusionDirective( SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, - bool IsAngled, CharSourceRange FilenameRange, Optional File, + bool IsAngled, CharSourceRange FilenameRange, OptionalFileEntryRef File, StringRef SearchPath, StringRef RelativePath, const Module *Imported, SrcMgr::CharacteristicKind FileType) { // We recognize the first include as a special main module header and want diff --git a/clang-tools-extra/clang-tidy/llvmlibc/RestrictSystemLibcHeadersCheck.cpp b/clang-tools-extra/clang-tidy/llvmlibc/RestrictSystemLibcHeadersCheck.cpp --- a/clang-tools-extra/clang-tidy/llvmlibc/RestrictSystemLibcHeadersCheck.cpp +++ b/clang-tools-extra/clang-tidy/llvmlibc/RestrictSystemLibcHeadersCheck.cpp @@ -34,7 +34,7 @@ void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, - Optional File, StringRef SearchPath, + OptionalFileEntryRef File, StringRef SearchPath, StringRef RelativePath, const Module *Imported, SrcMgr::CharacteristicKind FileType) override; @@ -46,7 +46,7 @@ void RestrictedIncludesPPCallbacks::InclusionDirective( SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, - bool IsAngled, CharSourceRange FilenameRange, Optional File, + bool IsAngled, CharSourceRange FilenameRange, OptionalFileEntryRef File, StringRef SearchPath, StringRef RelativePath, const Module *Imported, SrcMgr::CharacteristicKind FileType) { // Compiler provided headers are allowed (e.g stddef.h). diff --git a/clang-tools-extra/clang-tidy/modernize/DeprecatedHeadersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/DeprecatedHeadersCheck.cpp --- a/clang-tools-extra/clang-tidy/modernize/DeprecatedHeadersCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/DeprecatedHeadersCheck.cpp @@ -33,7 +33,7 @@ void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, - Optional File, StringRef SearchPath, + OptionalFileEntryRef File, StringRef SearchPath, StringRef RelativePath, const Module *Imported, SrcMgr::CharacteristicKind FileType) override; @@ -179,7 +179,7 @@ void IncludeModernizePPCallbacks::InclusionDirective( SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, - bool IsAngled, CharSourceRange FilenameRange, Optional File, + bool IsAngled, CharSourceRange FilenameRange, OptionalFileEntryRef File, StringRef SearchPath, StringRef RelativePath, const Module *Imported, SrcMgr::CharacteristicKind FileType) { diff --git a/clang-tools-extra/clang-tidy/modernize/MacroToEnumCheck.cpp b/clang-tools-extra/clang-tidy/modernize/MacroToEnumCheck.cpp --- a/clang-tools-extra/clang-tidy/modernize/MacroToEnumCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/MacroToEnumCheck.cpp @@ -119,7 +119,7 @@ void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, - Optional File, StringRef SearchPath, + OptionalFileEntryRef File, StringRef SearchPath, StringRef RelativePath, const Module *Imported, SrcMgr::CharacteristicKind FileType) override { clearCurrentEnum(HashLoc); diff --git a/clang-tools-extra/clang-tidy/portability/RestrictSystemIncludesCheck.h b/clang-tools-extra/clang-tidy/portability/RestrictSystemIncludesCheck.h --- a/clang-tools-extra/clang-tidy/portability/RestrictSystemIncludesCheck.h +++ b/clang-tools-extra/clang-tidy/portability/RestrictSystemIncludesCheck.h @@ -51,7 +51,7 @@ void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, - Optional File, StringRef SearchPath, + OptionalFileEntryRef File, StringRef SearchPath, StringRef RelativePath, const Module *Imported, SrcMgr::CharacteristicKind FileType) override; void EndOfMainFile() override; diff --git a/clang-tools-extra/clang-tidy/portability/RestrictSystemIncludesCheck.cpp b/clang-tools-extra/clang-tidy/portability/RestrictSystemIncludesCheck.cpp --- a/clang-tools-extra/clang-tidy/portability/RestrictSystemIncludesCheck.cpp +++ b/clang-tools-extra/clang-tidy/portability/RestrictSystemIncludesCheck.cpp @@ -22,7 +22,7 @@ void RestrictedIncludesPPCallbacks::InclusionDirective( SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, - bool IsAngled, CharSourceRange FilenameRange, Optional File, + bool IsAngled, CharSourceRange FilenameRange, OptionalFileEntryRef File, StringRef SearchPath, StringRef RelativePath, const Module *Imported, SrcMgr::CharacteristicKind FileType) { if (!Check.contains(FileName) && SrcMgr::isSystem(FileType)) { diff --git a/clang-tools-extra/clang-tidy/readability/DuplicateIncludeCheck.cpp b/clang-tools-extra/clang-tidy/readability/DuplicateIncludeCheck.cpp --- a/clang-tools-extra/clang-tidy/readability/DuplicateIncludeCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/DuplicateIncludeCheck.cpp @@ -48,7 +48,7 @@ void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, - Optional File, StringRef SearchPath, + OptionalFileEntryRef File, StringRef SearchPath, StringRef RelativePath, const Module *Imported, SrcMgr::CharacteristicKind FileType) override; @@ -77,7 +77,7 @@ void DuplicateIncludeCallbacks::InclusionDirective( SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, - bool IsAngled, CharSourceRange FilenameRange, Optional File, + bool IsAngled, CharSourceRange FilenameRange, OptionalFileEntryRef File, StringRef SearchPath, StringRef RelativePath, const Module *Imported, SrcMgr::CharacteristicKind FileType) { if (llvm::is_contained(Files.back(), FileName)) { diff --git a/clang-tools-extra/clang-tidy/utils/IncludeInserter.cpp b/clang-tools-extra/clang-tidy/utils/IncludeInserter.cpp --- a/clang-tools-extra/clang-tidy/utils/IncludeInserter.cpp +++ b/clang-tools-extra/clang-tidy/utils/IncludeInserter.cpp @@ -24,7 +24,7 @@ void InclusionDirective(SourceLocation HashLocation, const Token &IncludeToken, StringRef FileNameRef, bool IsAngled, CharSourceRange FileNameRange, - Optional /*IncludedFile*/, + OptionalFileEntryRef /*IncludedFile*/, StringRef /*SearchPath*/, StringRef /*RelativePath*/, const Module * /*ImportedModule*/, SrcMgr::CharacteristicKind /*FileType*/) override { diff --git a/clang-tools-extra/clangd/ConfigCompile.cpp b/clang-tools-extra/clangd/ConfigCompile.cpp --- a/clang-tools-extra/clangd/ConfigCompile.cpp +++ b/clang-tools-extra/clangd/ConfigCompile.cpp @@ -112,7 +112,7 @@ diag(Error, "Invalid regex " + Anchored + ": " + RegexError, Text.Range); return std::nullopt; } - return Result; + return std::move(Result); } std::optional makeAbsolute(Located Path, diff --git a/clang-tools-extra/clangd/Headers.cpp b/clang-tools-extra/clangd/Headers.cpp --- a/clang-tools-extra/clangd/Headers.cpp +++ b/clang-tools-extra/clangd/Headers.cpp @@ -35,7 +35,7 @@ void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, llvm::StringRef FileName, bool IsAngled, CharSourceRange /*FilenameRange*/, - Optional File, + OptionalFileEntryRef File, llvm::StringRef /*SearchPath*/, llvm::StringRef /*RelativePath*/, const clang::Module * /*Imported*/, diff --git a/clang-tools-extra/clangd/ParsedAST.cpp b/clang-tools-extra/clangd/ParsedAST.cpp --- a/clang-tools-extra/clangd/ParsedAST.cpp +++ b/clang-tools-extra/clangd/ParsedAST.cpp @@ -171,7 +171,7 @@ void replay() { for (const auto &Inc : Includes) { - llvm::Optional File; + OptionalFileEntryRef File; if (Inc.Resolved != "") File = expectedToOptional(SM.getFileManager().getFileRef(Inc.Resolved)); @@ -679,7 +679,7 @@ make_move_iterator(UnusedHeadersDiags.begin()), make_move_iterator(UnusedHeadersDiags.end())); } - return Result; + return std::move(Result); } ParsedAST::ParsedAST(ParsedAST &&Other) = default; diff --git a/clang-tools-extra/clangd/index/IndexAction.cpp b/clang-tools-extra/clangd/index/IndexAction.cpp --- a/clang-tools-extra/clangd/index/IndexAction.cpp +++ b/clang-tools-extra/clangd/index/IndexAction.cpp @@ -28,7 +28,7 @@ namespace clangd { namespace { -llvm::Optional toURI(Optional File) { +llvm::Optional toURI(OptionalFileEntryRef File) { if (!File) return std::nullopt; auto AbsolutePath = File->getFileEntry().tryGetRealPathName(); @@ -85,8 +85,7 @@ void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, llvm::StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, - Optional File, - llvm::StringRef SearchPath, + OptionalFileEntryRef File, llvm::StringRef SearchPath, llvm::StringRef RelativePath, const Module *Imported, SrcMgr::CharacteristicKind FileType) override { auto IncludeURI = toURI(File); diff --git a/clang-tools-extra/clangd/unittests/HoverTests.cpp b/clang-tools-extra/clangd/unittests/HoverTests.cpp --- a/clang-tools-extra/clangd/unittests/HoverTests.cpp +++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp @@ -898,9 +898,7 @@ HI.CalleeArgInfo.emplace(); HI.CalleeArgInfo->Name = "arg_b"; HI.CalleeArgInfo->Type = "int &"; - HI.CallPassType.emplace(); - HI.CallPassType->PassBy = PassMode::Ref; - HI.CallPassType->Converted = false; + HI.CallPassType = HoverInfo::PassType{PassMode::Ref, false}; }}, {// Extra info for method call. R"cpp( @@ -926,9 +924,7 @@ HI.CalleeArgInfo->Name = "arg_a"; HI.CalleeArgInfo->Type = "int"; HI.CalleeArgInfo->Default = "3"; - HI.CallPassType.emplace(); - HI.CallPassType->PassBy = PassMode::Value; - HI.CallPassType->Converted = false; + HI.CallPassType = HoverInfo::PassType{PassMode::Value, false}; }}, {// Dont crash on invalid decl R"cpp( @@ -3037,9 +3033,7 @@ HI.CalleeArgInfo->Name = "arg_a"; HI.CalleeArgInfo->Type = "int"; HI.CalleeArgInfo->Default = "7"; - HI.CallPassType.emplace(); - HI.CallPassType->PassBy = PassMode::Value; - HI.CallPassType->Converted = false; + HI.CallPassType = HoverInfo::PassType{PassMode::Value, false}; }, R"(variable foo @@ -3062,9 +3056,7 @@ HI.CalleeArgInfo->Name = "arg_a"; HI.CalleeArgInfo->Type = "int"; HI.CalleeArgInfo->Default = "7"; - HI.CallPassType.emplace(); - HI.CallPassType->PassBy = PassMode::Ref; - HI.CallPassType->Converted = false; + HI.CallPassType = HoverInfo::PassType{PassMode::Ref, false}; }, R"(variable foo @@ -3087,9 +3079,7 @@ HI.CalleeArgInfo->Name = "arg_a"; HI.CalleeArgInfo->Type = {"alias_int", "int"}; HI.CalleeArgInfo->Default = "7"; - HI.CallPassType.emplace(); - HI.CallPassType->PassBy = PassMode::Value; - HI.CallPassType->Converted = true; + HI.CallPassType = HoverInfo::PassType{PassMode::Value, true}; }, R"(variable foo @@ -3127,9 +3117,7 @@ HI.CalleeArgInfo->Name = "arg_a"; HI.CalleeArgInfo->Type = "int"; HI.CalleeArgInfo->Default = "7"; - HI.CallPassType.emplace(); - HI.CallPassType->PassBy = PassMode::ConstRef; - HI.CallPassType->Converted = true; + HI.CallPassType = HoverInfo::PassType{PassMode::ConstRef, true}; }, R"(variable foo diff --git a/clang-tools-extra/clangd/unittests/ParsedASTTests.cpp b/clang-tools-extra/clangd/unittests/ParsedASTTests.cpp --- a/clang-tools-extra/clangd/unittests/ParsedASTTests.cpp +++ b/clang-tools-extra/clangd/unittests/ParsedASTTests.cpp @@ -380,9 +380,8 @@ void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, bool IsAngled, - CharSourceRange FilenameRange, - Optional, StringRef, StringRef, - const clang::Module *, + CharSourceRange FilenameRange, OptionalFileEntryRef, + StringRef, StringRef, const clang::Module *, SrcMgr::CharacteristicKind) override { Includes.emplace_back(SM, HashLoc, IncludeTok, FileName, IsAngled, FilenameRange); diff --git a/clang-tools-extra/include-cleaner/lib/Record.cpp b/clang-tools-extra/include-cleaner/lib/Record.cpp --- a/clang-tools-extra/include-cleaner/lib/Record.cpp +++ b/clang-tools-extra/include-cleaner/lib/Record.cpp @@ -35,9 +35,9 @@ void InclusionDirective(SourceLocation Hash, const Token &IncludeTok, StringRef SpelledFilename, bool IsAngled, CharSourceRange FilenameRange, - llvm::Optional File, - StringRef SearchPath, StringRef RelativePath, - const Module *, SrcMgr::CharacteristicKind) override { + OptionalFileEntryRef File, StringRef SearchPath, + StringRef RelativePath, const Module *, + SrcMgr::CharacteristicKind) override { if (!Active) return; @@ -180,7 +180,7 @@ void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, llvm::StringRef FileName, bool IsAngled, CharSourceRange /*FilenameRange*/, - Optional File, + OptionalFileEntryRef File, llvm::StringRef /*SearchPath*/, llvm::StringRef /*RelativePath*/, const clang::Module * /*Imported*/, diff --git a/clang-tools-extra/modularize/CoverageChecker.cpp b/clang-tools-extra/modularize/CoverageChecker.cpp --- a/clang-tools-extra/modularize/CoverageChecker.cpp +++ b/clang-tools-extra/modularize/CoverageChecker.cpp @@ -89,7 +89,7 @@ void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, - Optional File, StringRef SearchPath, + OptionalFileEntryRef File, StringRef SearchPath, StringRef RelativePath, const Module *Imported, SrcMgr::CharacteristicKind FileType) override { Checker.collectUmbrellaHeaderHeader(File->getName()); diff --git a/clang-tools-extra/modularize/PreprocessorTracker.cpp b/clang-tools-extra/modularize/PreprocessorTracker.cpp --- a/clang-tools-extra/modularize/PreprocessorTracker.cpp +++ b/clang-tools-extra/modularize/PreprocessorTracker.cpp @@ -734,7 +734,7 @@ const clang::Token &IncludeTok, llvm::StringRef FileName, bool IsAngled, clang::CharSourceRange FilenameRange, - llvm::Optional File, + clang::OptionalFileEntryRef File, llvm::StringRef SearchPath, llvm::StringRef RelativePath, const clang::Module *Imported, @@ -1277,10 +1277,9 @@ void PreprocessorCallbacks::InclusionDirective( clang::SourceLocation HashLoc, const clang::Token &IncludeTok, llvm::StringRef FileName, bool IsAngled, - clang::CharSourceRange FilenameRange, - llvm::Optional File, llvm::StringRef SearchPath, - llvm::StringRef RelativePath, const clang::Module *Imported, - clang::SrcMgr::CharacteristicKind FileType) { + clang::CharSourceRange FilenameRange, clang::OptionalFileEntryRef File, + llvm::StringRef SearchPath, llvm::StringRef RelativePath, + const clang::Module *Imported, clang::SrcMgr::CharacteristicKind FileType) { int DirectiveLine, DirectiveColumn; std::string HeaderPath = getSourceLocationFile(PP, HashLoc); getSourceLocationLineAndColumn(PP, HashLoc, DirectiveLine, DirectiveColumn); diff --git a/clang-tools-extra/pp-trace/PPCallbacksTracker.h b/clang-tools-extra/pp-trace/PPCallbacksTracker.h --- a/clang-tools-extra/pp-trace/PPCallbacksTracker.h +++ b/clang-tools-extra/pp-trace/PPCallbacksTracker.h @@ -94,8 +94,7 @@ void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, llvm::StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, - Optional File, - llvm::StringRef SearchPath, + OptionalFileEntryRef File, llvm::StringRef SearchPath, llvm::StringRef RelativePath, const Module *Imported, SrcMgr::CharacteristicKind FileType) override; void moduleImport(SourceLocation ImportLoc, ModuleIdPath Path, @@ -179,7 +178,7 @@ void appendArgument(const char *Name, FileID Value); /// Append a FileEntryRef argument to the top trace item. - void appendArgument(const char *Name, Optional Value); + void appendArgument(const char *Name, OptionalFileEntryRef Value); void appendArgument(const char *Name, FileEntryRef Value); /// Append a SourceLocation argument to the top trace item. diff --git a/clang-tools-extra/pp-trace/PPCallbacksTracker.cpp b/clang-tools-extra/pp-trace/PPCallbacksTracker.cpp --- a/clang-tools-extra/pp-trace/PPCallbacksTracker.cpp +++ b/clang-tools-extra/pp-trace/PPCallbacksTracker.cpp @@ -133,7 +133,7 @@ // of whether the inclusion will actually result in an inclusion. void PPCallbacksTracker::InclusionDirective( SourceLocation HashLoc, const Token &IncludeTok, llvm::StringRef FileName, - bool IsAngled, CharSourceRange FilenameRange, Optional File, + bool IsAngled, CharSourceRange FilenameRange, OptionalFileEntryRef File, llvm::StringRef SearchPath, llvm::StringRef RelativePath, const Module *Imported, SrcMgr::CharacteristicKind FileType) { beginCallback("InclusionDirective"); @@ -486,7 +486,7 @@ // Append a FileEntry argument to the top trace item. void PPCallbacksTracker::appendArgument(const char *Name, - Optional Value) { + OptionalFileEntryRef Value) { if (!Value) { appendArgument(Name, "(null)"); return; diff --git a/clang/include/clang/Basic/CustomizableOptional.h b/clang/include/clang/Basic/CustomizableOptional.h new file mode 100644 --- /dev/null +++ b/clang/include/clang/Basic/CustomizableOptional.h @@ -0,0 +1,280 @@ +//===- CustomizableOptional.h - Optional with custom storage ----*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef CLANG_BASIC_CUSTOMIZABLEOPTIONAL_H +#define CLANG_BASIC_CUSTOMIZABLEOPTIONAL_H + +#include "llvm/ADT/Hashing.h" +#include "llvm/ADT/Optional.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Support/type_traits.h" +#include +#include +#include + +namespace clang { + +namespace optional_detail { +template class OptionalStorage; +} // namespace optional_detail + +// Optional type which internal storage can be specialized by providing +// OptionalStorage. The interface follows std::optional. +template class CustomizableOptional { + optional_detail::OptionalStorage Storage; + +public: + using value_type = T; + + constexpr CustomizableOptional() = default; + constexpr CustomizableOptional(std::nullopt_t) {} + + constexpr CustomizableOptional(const T &y) : Storage(std::in_place, y) {} + constexpr CustomizableOptional(const CustomizableOptional &O) = default; + + constexpr CustomizableOptional(T &&y) + : Storage(std::in_place, std::move(y)) {} + constexpr CustomizableOptional(CustomizableOptional &&O) = default; + + template + constexpr CustomizableOptional(std::in_place_t, ArgTypes &&...Args) + : Storage(std::in_place, std::forward(Args)...) {} + + // Allow conversion from Optional. + constexpr CustomizableOptional(const llvm::Optional &y) + : CustomizableOptional(y ? *y : CustomizableOptional()) {} + constexpr CustomizableOptional(llvm::Optional &&y) + : CustomizableOptional(y ? std::move(*y) : CustomizableOptional()) {} + + CustomizableOptional &operator=(T &&y) { + Storage = std::move(y); + return *this; + } + CustomizableOptional &operator=(CustomizableOptional &&O) = default; + + /// Create a new object by constructing it in place with the given arguments. + template void emplace(ArgTypes &&...Args) { + Storage.emplace(std::forward(Args)...); + } + + CustomizableOptional &operator=(const T &y) { + Storage = y; + return *this; + } + CustomizableOptional &operator=(const CustomizableOptional &O) = default; + + void reset() { Storage.reset(); } + + LLVM_DEPRECATED("Use &*X instead.", "&*X") + constexpr const T *getPointer() const { return &Storage.value(); } + LLVM_DEPRECATED("Use &*X instead.", "&*X") + T *getPointer() { return &Storage.value(); } + LLVM_DEPRECATED("std::optional::value is throwing. Use *X instead", "*X") + constexpr const T &value() const & { return Storage.value(); } + LLVM_DEPRECATED("std::optional::value is throwing. Use *X instead", "*X") + T &value() & { return Storage.value(); } + + constexpr explicit operator bool() const { return has_value(); } + constexpr bool has_value() const { return Storage.has_value(); } + constexpr const T *operator->() const { return &Storage.value(); } + T *operator->() { return &Storage.value(); } + constexpr const T &operator*() const & { return Storage.value(); } + T &operator*() & { return Storage.value(); } + + template constexpr T value_or(U &&alt) const & { + return has_value() ? operator*() : std::forward(alt); + } + + LLVM_DEPRECATED("std::optional::value is throwing. Use *X instead", "*X") + T &&value() && { return std::move(Storage.value()); } + T &&operator*() && { return std::move(Storage.value()); } + + template T value_or(U &&alt) && { + return has_value() ? std::move(operator*()) : std::forward(alt); + } + + // Allow conversion to Optional. + explicit operator llvm::Optional &() const & { + return *this ? **this : llvm::Optional(); + } + explicit operator llvm::Optional &&() const && { + return *this ? std::move(**this) : llvm::Optional(); + } +}; + +template +CustomizableOptional(const T &) -> CustomizableOptional; + +template +llvm::hash_code hash_value(const CustomizableOptional &O) { + return O ? llvm::hash_combine(true, *O) : llvm::hash_value(false); +} + +template +constexpr bool operator==(const CustomizableOptional &X, + const CustomizableOptional &Y) { + if (X && Y) + return *X == *Y; + return X.has_value() == Y.has_value(); +} + +template +constexpr bool operator!=(const CustomizableOptional &X, + const CustomizableOptional &Y) { + return !(X == Y); +} + +template +constexpr bool operator<(const CustomizableOptional &X, + const CustomizableOptional &Y) { + if (X && Y) + return *X < *Y; + return X.has_value() < Y.has_value(); +} + +template +constexpr bool operator<=(const CustomizableOptional &X, + const CustomizableOptional &Y) { + return !(Y < X); +} + +template +constexpr bool operator>(const CustomizableOptional &X, + const CustomizableOptional &Y) { + return Y < X; +} + +template +constexpr bool operator>=(const CustomizableOptional &X, + const CustomizableOptional &Y) { + return !(X < Y); +} + +template +constexpr bool operator==(const CustomizableOptional &X, std::nullopt_t) { + return !X; +} + +template +constexpr bool operator==(std::nullopt_t, const CustomizableOptional &X) { + return X == std::nullopt; +} + +template +constexpr bool operator!=(const CustomizableOptional &X, std::nullopt_t) { + return !(X == std::nullopt); +} + +template +constexpr bool operator!=(std::nullopt_t, const CustomizableOptional &X) { + return X != std::nullopt; +} + +template +constexpr bool operator<(const CustomizableOptional &, std::nullopt_t) { + return false; +} + +template +constexpr bool operator<(std::nullopt_t, const CustomizableOptional &X) { + return X.has_value(); +} + +template +constexpr bool operator<=(const CustomizableOptional &X, std::nullopt_t) { + return !(std::nullopt < X); +} + +template +constexpr bool operator<=(std::nullopt_t, const CustomizableOptional &X) { + return !(X < std::nullopt); +} + +template +constexpr bool operator>(const CustomizableOptional &X, std::nullopt_t) { + return std::nullopt < X; +} + +template +constexpr bool operator>(std::nullopt_t, const CustomizableOptional &X) { + return X < std::nullopt; +} + +template +constexpr bool operator>=(const CustomizableOptional &X, std::nullopt_t) { + return std::nullopt <= X; +} + +template +constexpr bool operator>=(std::nullopt_t, const CustomizableOptional &X) { + return X <= std::nullopt; +} + +template +constexpr bool operator==(const CustomizableOptional &X, const T &Y) { + return X && *X == Y; +} + +template +constexpr bool operator==(const T &X, const CustomizableOptional &Y) { + return Y && X == *Y; +} + +template +constexpr bool operator!=(const CustomizableOptional &X, const T &Y) { + return !(X == Y); +} + +template +constexpr bool operator!=(const T &X, const CustomizableOptional &Y) { + return !(X == Y); +} + +template +constexpr bool operator<(const CustomizableOptional &X, const T &Y) { + return !X || *X < Y; +} + +template +constexpr bool operator<(const T &X, const CustomizableOptional &Y) { + return Y && X < *Y; +} + +template +constexpr bool operator<=(const CustomizableOptional &X, const T &Y) { + return !(Y < X); +} + +template +constexpr bool operator<=(const T &X, const CustomizableOptional &Y) { + return !(Y < X); +} + +template +constexpr bool operator>(const CustomizableOptional &X, const T &Y) { + return Y < X; +} + +template +constexpr bool operator>(const T &X, const CustomizableOptional &Y) { + return Y < X; +} + +template +constexpr bool operator>=(const CustomizableOptional &X, const T &Y) { + return !(X < Y); +} + +template +constexpr bool operator>=(const T &X, const CustomizableOptional &Y) { + return !(X < Y); +} + +} // namespace clang + +#endif // CLANG_BASIC_CUSTOMIZABLEOPTIONAL_H diff --git a/clang/include/clang/Basic/Diagnostic.h b/clang/include/clang/Basic/Diagnostic.h --- a/clang/include/clang/Basic/Diagnostic.h +++ b/clang/include/clang/Basic/Diagnostic.h @@ -1471,6 +1471,12 @@ return DB; } +inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB, + SourceLocation L) { + DB.AddSourceRange(CharSourceRange::getTokenRange(L)); + return DB; +} + inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB, SourceRange R) { DB.AddSourceRange(CharSourceRange::getTokenRange(R)); diff --git a/clang/include/clang/Basic/DirectoryEntry.h b/clang/include/clang/Basic/DirectoryEntry.h --- a/clang/include/clang/Basic/DirectoryEntry.h +++ b/clang/include/clang/Basic/DirectoryEntry.h @@ -14,12 +14,13 @@ #ifndef LLVM_CLANG_BASIC_DIRECTORYENTRY_H #define LLVM_CLANG_BASIC_DIRECTORYENTRY_H +#include "clang/Basic/CustomizableOptional.h" #include "clang/Basic/LLVM.h" #include "llvm/ADT/DenseMapInfo.h" #include "llvm/ADT/Hashing.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" -#include "llvm/ADT/STLExtras.h" #include "llvm/Support/ErrorOr.h" #include @@ -115,6 +116,8 @@ const MapEntry *ME; }; +using OptionalDirectoryEntryRef = CustomizableOptional; + namespace FileMgr { /// Customized storage for refs derived from map entires in FileManager, using @@ -158,9 +161,7 @@ }; } // end namespace FileMgr -} // end namespace clang -namespace llvm { namespace optional_detail { /// Customize OptionalStorage to use DirectoryEntryRef and @@ -184,16 +185,16 @@ } }; -static_assert(sizeof(Optional) == - sizeof(clang::DirectoryEntryRef), - "Optional must avoid size overhead"); +static_assert(sizeof(OptionalDirectoryEntryRef) == sizeof(DirectoryEntryRef), + "OptionalDirectoryEntryRef must avoid size overhead"); -static_assert( - std::is_trivially_copyable>::value, - "Optional should be trivially copyable"); +static_assert(std::is_trivially_copyable::value, + "OptionalDirectoryEntryRef should be trivially copyable"); } // end namespace optional_detail +} // namespace clang +namespace llvm { /// Specialisation of DenseMapInfo for DirectoryEntryRef. template <> struct DenseMapInfo { static inline clang::DirectoryEntryRef getEmptyKey() { @@ -229,19 +230,19 @@ namespace clang { -/// Wrapper around Optional that degrades to 'const +/// Wrapper around OptionalDirectoryEntryRef that degrades to 'const /// DirectoryEntry*', facilitating incremental patches to propagate /// DirectoryEntryRef. /// /// This class can be used as return value or field where it's convenient for -/// an Optional to degrade to a 'const DirectoryEntry*'. The +/// an OptionalDirectoryEntryRef to degrade to a 'const DirectoryEntry*'. The /// purpose is to avoid code churn due to dances like the following: /// \code /// // Old code. /// lvalue = rvalue; /// /// // Temporary code from an incremental patch. -/// Optional MaybeF = rvalue; +/// OptionalDirectoryEntryRef MaybeF = rvalue; /// lvalue = MaybeF ? &MaybeF.getDirectoryEntry() : nullptr; /// /// // Final code. @@ -250,9 +251,9 @@ /// /// FIXME: Once DirectoryEntryRef is "everywhere" and DirectoryEntry::LastRef /// and DirectoryEntry::getName have been deleted, delete this class and -/// replace instances with Optional. +/// replace instances with OptionalDirectoryEntryRef. class OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr - : public Optional { + : public OptionalDirectoryEntryRef { public: OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr() = default; OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr( @@ -266,28 +267,29 @@ OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr(std::nullopt_t) {} OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr(DirectoryEntryRef Ref) - : Optional(Ref) {} - OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr(Optional MaybeRef) - : Optional(MaybeRef) {} + : OptionalDirectoryEntryRef(Ref) {} + OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr( + OptionalDirectoryEntryRef MaybeRef) + : OptionalDirectoryEntryRef(MaybeRef) {} OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr & operator=(std::nullopt_t) { - Optional::operator=(std::nullopt); + OptionalDirectoryEntryRef::operator=(std::nullopt); return *this; } OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr &operator=(DirectoryEntryRef Ref) { - Optional::operator=(Ref); + OptionalDirectoryEntryRef::operator=(Ref); return *this; } OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr & - operator=(Optional MaybeRef) { - Optional::operator=(MaybeRef); + operator=(OptionalDirectoryEntryRef MaybeRef) { + OptionalDirectoryEntryRef::operator=(MaybeRef); return *this; } /// Degrade to 'const DirectoryEntry *' to allow DirectoryEntry::LastRef and /// DirectoryEntry::getName have been deleted, delete this class and replace - /// instances with Optional + /// instances with OptionalDirectoryEntryRef operator const DirectoryEntry *() const { return has_value() ? &(*this)->getDirEntry() : nullptr; } diff --git a/clang/include/clang/Basic/FileEntry.h b/clang/include/clang/Basic/FileEntry.h --- a/clang/include/clang/Basic/FileEntry.h +++ b/clang/include/clang/Basic/FileEntry.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_BASIC_FILEENTRY_H #define LLVM_CLANG_BASIC_FILEENTRY_H +#include "clang/Basic/CustomizableOptional.h" #include "clang/Basic/DirectoryEntry.h" #include "clang/Basic/LLVM.h" #include "llvm/ADT/DenseMapInfo.h" @@ -41,19 +42,12 @@ class FileEntryRef; -} // namespace clang - -namespace llvm { namespace optional_detail { /// Forward declare a template specialization for OptionalStorage. -template <> -class OptionalStorage; +template <> class OptionalStorage; } // namespace optional_detail -} // namespace llvm - -namespace clang { class FileEntry; @@ -129,7 +123,7 @@ llvm::PointerUnion V; /// Directory the file was found in. Set if and only if V is a FileEntry. - Optional Dir; + OptionalDirectoryEntryRef Dir; MapValue() = delete; MapValue(FileEntry &FE, DirectoryEntryRef Dir) : V(&FE), Dir(Dir) {} @@ -207,9 +201,8 @@ static_assert(std::is_trivially_copyable::value, "FileEntryRef must be trivially copyable"); -} // end namespace clang +using OptionalFileEntryRef = CustomizableOptional; -namespace llvm { namespace optional_detail { /// Customize OptionalStorage to use FileEntryRef and its @@ -233,15 +226,16 @@ } }; -static_assert(sizeof(Optional) == - sizeof(clang::FileEntryRef), - "Optional must avoid size overhead"); +static_assert(sizeof(OptionalFileEntryRef) == sizeof(FileEntryRef), + "OptionalFileEntryRef must avoid size overhead"); -static_assert(std::is_trivially_copyable>::value, - "Optional should be trivially copyable"); +static_assert(std::is_trivially_copyable::value, + "OptionalFileEntryRef should be trivially copyable"); } // end namespace optional_detail +} // namespace clang +namespace llvm { /// Specialisation of DenseMapInfo for FileEntryRef. template <> struct DenseMapInfo { static inline clang::FileEntryRef getEmptyKey() { @@ -274,18 +268,18 @@ namespace clang { -/// Wrapper around Optional that degrades to 'const FileEntry*', +/// Wrapper around OptionalFileEntryRef that degrades to 'const FileEntry*', /// facilitating incremental patches to propagate FileEntryRef. /// /// This class can be used as return value or field where it's convenient for -/// an Optional to degrade to a 'const FileEntry*'. The purpose +/// an OptionalFileEntryRef to degrade to a 'const FileEntry*'. The purpose /// is to avoid code churn due to dances like the following: /// \code /// // Old code. /// lvalue = rvalue; /// /// // Temporary code from an incremental patch. -/// Optional MaybeF = rvalue; +/// OptionalFileEntryRef MaybeF = rvalue; /// lvalue = MaybeF ? &MaybeF.getFileEntry() : nullptr; /// /// // Final code. @@ -294,9 +288,8 @@ /// /// FIXME: Once FileEntryRef is "everywhere" and FileEntry::LastRef and /// FileEntry::getName have been deleted, delete this class and replace -/// instances with Optional. -class OptionalFileEntryRefDegradesToFileEntryPtr - : public Optional { +/// instances with OptionalFileEntryRef. +class OptionalFileEntryRefDegradesToFileEntryPtr : public OptionalFileEntryRef { public: OptionalFileEntryRefDegradesToFileEntryPtr() = default; OptionalFileEntryRefDegradesToFileEntryPtr( @@ -310,27 +303,27 @@ OptionalFileEntryRefDegradesToFileEntryPtr(std::nullopt_t) {} OptionalFileEntryRefDegradesToFileEntryPtr(FileEntryRef Ref) - : Optional(Ref) {} - OptionalFileEntryRefDegradesToFileEntryPtr(Optional MaybeRef) - : Optional(MaybeRef) {} + : OptionalFileEntryRef(Ref) {} + OptionalFileEntryRefDegradesToFileEntryPtr(OptionalFileEntryRef MaybeRef) + : OptionalFileEntryRef(MaybeRef) {} OptionalFileEntryRefDegradesToFileEntryPtr &operator=(std::nullopt_t) { - Optional::operator=(std::nullopt); + OptionalFileEntryRef::operator=(std::nullopt); return *this; } OptionalFileEntryRefDegradesToFileEntryPtr &operator=(FileEntryRef Ref) { - Optional::operator=(Ref); + OptionalFileEntryRef::operator=(Ref); return *this; } OptionalFileEntryRefDegradesToFileEntryPtr & - operator=(Optional MaybeRef) { - Optional::operator=(MaybeRef); + operator=(OptionalFileEntryRef MaybeRef) { + OptionalFileEntryRef::operator=(MaybeRef); return *this; } /// Degrade to 'const FileEntry *' to allow FileEntry::LastRef and /// FileEntry::getName have been deleted, delete this class and replace - /// instances with Optional + /// instances with OptionalFileEntryRef operator const FileEntry *() const { return has_value() ? &(*this)->getFileEntry() : nullptr; } @@ -341,20 +334,16 @@ OptionalFileEntryRefDegradesToFileEntryPtr>::value, "OptionalFileEntryRefDegradesToFileEntryPtr should be trivially copyable"); -inline bool operator==(const FileEntry *LHS, - const Optional &RHS) { +inline bool operator==(const FileEntry *LHS, const OptionalFileEntryRef &RHS) { return LHS == (RHS ? &RHS->getFileEntry() : nullptr); } -inline bool operator==(const Optional &LHS, - const FileEntry *RHS) { +inline bool operator==(const OptionalFileEntryRef &LHS, const FileEntry *RHS) { return (LHS ? &LHS->getFileEntry() : nullptr) == RHS; } -inline bool operator!=(const FileEntry *LHS, - const Optional &RHS) { +inline bool operator!=(const FileEntry *LHS, const OptionalFileEntryRef &RHS) { return !(LHS == RHS); } -inline bool operator!=(const Optional &LHS, - const FileEntry *RHS) { +inline bool operator!=(const OptionalFileEntryRef &LHS, const FileEntry *RHS) { return !(LHS == RHS); } @@ -390,7 +379,7 @@ // default constructor). It should always have a value in practice. // // TODO: remove this once everyone that needs a name uses FileEntryRef. - Optional LastRef; + OptionalFileEntryRef LastRef; public: ~FileEntry(); diff --git a/clang/include/clang/Basic/FileManager.h b/clang/include/clang/Basic/FileManager.h --- a/clang/include/clang/Basic/FileManager.h +++ b/clang/include/clang/Basic/FileManager.h @@ -102,7 +102,7 @@ SeenBypassFileEntries; /// The file entry for stdin, if it has been accessed through the FileManager. - Optional STDIN; + OptionalFileEntryRef STDIN; /// The canonical names of files and directories . llvm::DenseMap CanonicalNames; @@ -166,8 +166,8 @@ bool CacheFailure = true); /// Get a \c DirectoryEntryRef if it exists, without doing anything on error. - llvm::Optional - getOptionalDirectoryRef(StringRef DirName, bool CacheFailure = true) { + OptionalDirectoryEntryRef getOptionalDirectoryRef(StringRef DirName, + bool CacheFailure = true) { return llvm::expectedToOptional(getDirectoryRef(DirName, CacheFailure)); } @@ -231,9 +231,9 @@ llvm::Expected getSTDIN(); /// Get a FileEntryRef if it exists, without doing anything on error. - llvm::Optional getOptionalFileRef(StringRef Filename, - bool OpenFile = false, - bool CacheFailure = true) { + OptionalFileEntryRef getOptionalFileRef(StringRef Filename, + bool OpenFile = false, + bool CacheFailure = true) { return llvm::expectedToOptional( getFileRef(Filename, OpenFile, CacheFailure)); } @@ -270,7 +270,7 @@ /// bypasses all mapping and uniquing, blindly creating a new FileEntry. /// There is no attempt to deduplicate these; if you bypass the same file /// twice, you get two new file entries. - llvm::Optional getBypassFile(FileEntryRef VFE); + OptionalFileEntryRef getBypassFile(FileEntryRef VFE); /// Open the specified file as a MemoryBuffer, returning a new /// MemoryBuffer if successful, otherwise returning null. diff --git a/clang/include/clang/Basic/LLVM.h b/clang/include/clang/Basic/LLVM.h --- a/clang/include/clang/Basic/LLVM.h +++ b/clang/include/clang/Basic/LLVM.h @@ -37,7 +37,7 @@ template class SmallString; template class SmallVector; template class SmallVectorImpl; - template class Optional; + template using Optional = std::optional; template class Expected; template diff --git a/clang/include/clang/Basic/Module.h b/clang/include/clang/Basic/Module.h --- a/clang/include/clang/Basic/Module.h +++ b/clang/include/clang/Basic/Module.h @@ -185,7 +185,7 @@ /// The AST file if this is a top-level module which has a /// corresponding serialized AST file, or null otherwise. - Optional ASTFile; + OptionalFileEntryRef ASTFile; /// The top-level headers associated with this module. llvm::SmallSetVector TopHeaders; @@ -610,7 +610,7 @@ } /// Set the serialized AST file for the top-level module of this module. - void setASTFile(Optional File) { + void setASTFile(OptionalFileEntryRef File) { assert((!getASTFile() || getASTFile() == File) && "file path changed"); getTopLevelModule()->ASTFile = File; } diff --git a/clang/include/clang/Basic/SourceManager.h b/clang/include/clang/Basic/SourceManager.h --- a/clang/include/clang/Basic/SourceManager.h +++ b/clang/include/clang/Basic/SourceManager.h @@ -1003,7 +1003,7 @@ /// is no such file in the filesystem. /// /// This should be called before parsing has begun. - Optional bypassFileContentsOverride(FileEntryRef File); + OptionalFileEntryRef bypassFileContentsOverride(FileEntryRef File); /// Specify that a file is transient. void setFileIsTransient(const FileEntry *SourceFile); @@ -1049,7 +1049,7 @@ } /// Returns the FileEntryRef for the provided FileID. - Optional getFileEntryRefForID(FileID FID) const { + OptionalFileEntryRef getFileEntryRefForID(FileID FID) const { if (auto *Entry = getSLocEntryForFile(FID)) return Entry->getFile().getContentCache().OrigEntry; return std::nullopt; diff --git a/clang/include/clang/Lex/DirectoryLookup.h b/clang/include/clang/Lex/DirectoryLookup.h --- a/clang/include/clang/Lex/DirectoryLookup.h +++ b/clang/include/clang/Lex/DirectoryLookup.h @@ -91,8 +91,8 @@ return isNormalDir() ? &u.Dir.getDirEntry() : nullptr; } - Optional getDirRef() const { - return isNormalDir() ? Optional(u.Dir) : std::nullopt; + OptionalDirectoryEntryRef getDirRef() const { + return isNormalDir() ? OptionalDirectoryEntryRef(u.Dir) : std::nullopt; } /// getFrameworkDir - Return the directory that this framework refers to. @@ -101,8 +101,8 @@ return isFramework() ? &u.Dir.getDirEntry() : nullptr; } - Optional getFrameworkDirRef() const { - return isFramework() ? Optional(u.Dir) : std::nullopt; + OptionalDirectoryEntryRef getFrameworkDirRef() const { + return isFramework() ? OptionalDirectoryEntryRef(u.Dir) : std::nullopt; } /// getHeaderMap - Return the directory that this entry refers to. @@ -180,7 +180,7 @@ /// \param [out] MappedName if this is a headermap which maps the filename to /// a framework include ("Foo.h" -> "Foo/Foo.h"), set the new name to this /// vector and point Filename to it. - Optional + OptionalFileEntryRef LookupFile(StringRef &Filename, HeaderSearch &HS, SourceLocation IncludeLoc, SmallVectorImpl *SearchPath, SmallVectorImpl *RelativePath, Module *RequestingModule, @@ -190,7 +190,7 @@ bool OpenFile = true) const; private: - Optional DoFrameworkLookup( + OptionalFileEntryRef DoFrameworkLookup( StringRef Filename, HeaderSearch &HS, SmallVectorImpl *SearchPath, SmallVectorImpl *RelativePath, Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule, diff --git a/clang/include/clang/Lex/HeaderSearch.h b/clang/include/clang/Lex/HeaderSearch.h --- a/clang/include/clang/Lex/HeaderSearch.h +++ b/clang/include/clang/Lex/HeaderSearch.h @@ -145,7 +145,7 @@ /// This structure is used to record entries in our framework cache. struct FrameworkCacheEntry { /// The directory entry which should be used for the cached framework. - Optional Directory; + OptionalDirectoryEntryRef Directory; /// Whether this framework has been "user-specified" to be treated as if it /// were a system framework (even if it was found outside a system framework @@ -479,7 +479,7 @@ /// found in any of searched SearchDirs. Will be set to false if a framework /// is found only through header maps. Doesn't guarantee the requested file is /// found. - Optional LookupFile( + OptionalFileEntryRef LookupFile( StringRef Filename, SourceLocation IncludeLoc, bool isAngled, ConstSearchDirIterator FromDir, ConstSearchDirIterator *CurDir, ArrayRef> Includers, @@ -495,7 +495,7 @@ /// within ".../Carbon.framework/Headers/Carbon.h", check to see if /// HIToolbox is a subframework within Carbon.framework. If so, return /// the FileEntry for the designated file, otherwise return null. - Optional LookupSubframeworkHeader( + OptionalFileEntryRef LookupSubframeworkHeader( StringRef Filename, const FileEntry *ContextFileEnt, SmallVectorImpl *SearchPath, SmallVectorImpl *RelativePath, Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule); @@ -769,7 +769,7 @@ /// Look up the file with the specified name and determine its owning /// module. - Optional + OptionalFileEntryRef getFileAndSuggestModule(StringRef FileName, SourceLocation IncludeLoc, const DirectoryEntry *Dir, bool IsSystemHeaderDir, Module *RequestingModule, diff --git a/clang/include/clang/Lex/ModuleMap.h b/clang/include/clang/Lex/ModuleMap.h --- a/clang/include/clang/Lex/ModuleMap.h +++ b/clang/include/clang/Lex/ModuleMap.h @@ -333,7 +333,7 @@ /// \param NeedsFramework If M is not a framework but a missing header would /// be found in case M was, set it to true. False otherwise. /// \return The resolved file, if any. - Optional + OptionalFileEntryRef findHeader(Module *M, const Module::UnresolvedHeaderDirective &Header, SmallVectorImpl &RelativePathName, bool &NeedsFramework); @@ -606,7 +606,7 @@ /// /// \returns The file entry for the module map file containing the given /// module, or nullptr if the module definition was inferred. - Optional getContainingModuleMapFile(const Module *Module) const; + OptionalFileEntryRef getContainingModuleMapFile(const Module *Module) const; /// Get the module map file that (along with the module name) uniquely /// identifies this module. @@ -617,7 +617,7 @@ /// of inferred modules, returns the module map that allowed the inference /// (e.g. contained 'module *'). Otherwise, returns /// getContainingModuleMapFile(). - Optional getModuleMapFileForUniquing(const Module *M) const; + OptionalFileEntryRef getModuleMapFileForUniquing(const Module *M) const; void setInferredModuleAllowedBy(Module *M, const FileEntry *ModMap); diff --git a/clang/include/clang/Lex/PPCallbacks.h b/clang/include/clang/Lex/PPCallbacks.h --- a/clang/include/clang/Lex/PPCallbacks.h +++ b/clang/include/clang/Lex/PPCallbacks.h @@ -125,16 +125,12 @@ /// implicitly 'extern "C"' in C++ mode. /// virtual void InclusionDirective(SourceLocation HashLoc, - const Token &IncludeTok, - StringRef FileName, - bool IsAngled, - CharSourceRange FilenameRange, - Optional File, - StringRef SearchPath, - StringRef RelativePath, + const Token &IncludeTok, StringRef FileName, + bool IsAngled, CharSourceRange FilenameRange, + OptionalFileEntryRef File, + StringRef SearchPath, StringRef RelativePath, const Module *Imported, - SrcMgr::CharacteristicKind FileType) { - } + SrcMgr::CharacteristicKind FileType) {} /// Callback invoked whenever a submodule was entered. /// @@ -327,7 +323,7 @@ /// Hook called when a '__has_include' or '__has_include_next' directive is /// read. virtual void HasInclude(SourceLocation Loc, StringRef FileName, bool IsAngled, - Optional File, + OptionalFileEntryRef File, SrcMgr::CharacteristicKind FileType); /// Hook called when a source range is skipped. @@ -458,7 +454,7 @@ void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, - Optional File, StringRef SearchPath, + OptionalFileEntryRef File, StringRef SearchPath, StringRef RelativePath, const Module *Imported, SrcMgr::CharacteristicKind FileType) override { First->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled, @@ -548,7 +544,7 @@ } void HasInclude(SourceLocation Loc, StringRef FileName, bool IsAngled, - Optional File, + OptionalFileEntryRef File, SrcMgr::CharacteristicKind FileType) override; void PragmaOpenCLExtension(SourceLocation NameLoc, const IdentifierInfo *Name, diff --git a/clang/include/clang/Lex/PreprocessingRecord.h b/clang/include/clang/Lex/PreprocessingRecord.h --- a/clang/include/clang/Lex/PreprocessingRecord.h +++ b/clang/include/clang/Lex/PreprocessingRecord.h @@ -240,12 +240,12 @@ unsigned ImportedModule : 1; /// The file that was included. - Optional File; + OptionalFileEntryRef File; public: InclusionDirective(PreprocessingRecord &PPRec, InclusionKind Kind, StringRef FileName, bool InQuotes, bool ImportedModule, - Optional File, SourceRange Range); + OptionalFileEntryRef File, SourceRange Range); /// Determine what kind of inclusion directive this is. InclusionKind getKind() const { return static_cast(Kind); } @@ -263,7 +263,7 @@ /// Retrieve the file entry for the actual file that was included /// by this directive. - Optional getFile() const { return File; } + OptionalFileEntryRef getFile() const { return File; } // Implement isa/cast/dyncast/etc. static bool classof(const PreprocessedEntity *PE) { @@ -528,7 +528,7 @@ void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, - Optional File, StringRef SearchPath, + OptionalFileEntryRef File, StringRef SearchPath, StringRef RelativePath, const Module *Imported, SrcMgr::CharacteristicKind FileType) override; void Ifdef(SourceLocation Loc, const Token &MacroNameTok, diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h --- a/clang/include/clang/Lex/Preprocessor.h +++ b/clang/include/clang/Lex/Preprocessor.h @@ -2243,7 +2243,7 @@ /// /// Returns std::nullopt on failure. \p isAngled indicates whether the file /// reference is for system \#include's or not (i.e. using <> instead of ""). - Optional + OptionalFileEntryRef LookupFile(SourceLocation FilenameLoc, StringRef Filename, bool isAngled, ConstSearchDirIterator FromDir, const FileEntry *FromFile, ConstSearchDirIterator *CurDir, SmallVectorImpl *SearchPath, @@ -2510,7 +2510,7 @@ } }; - Optional LookupHeaderIncludeOrImport( + OptionalFileEntryRef LookupHeaderIncludeOrImport( ConstSearchDirIterator *CurDir, StringRef &Filename, SourceLocation FilenameLoc, CharSourceRange FilenameRange, const Token &FilenameTok, bool &IsFrameworkFound, bool IsImportDecl, diff --git a/clang/include/clang/Serialization/ModuleManager.h b/clang/include/clang/Serialization/ModuleManager.h --- a/clang/include/clang/Serialization/ModuleManager.h +++ b/clang/include/clang/Serialization/ModuleManager.h @@ -302,7 +302,7 @@ /// modification time criteria, false if the file is either available and /// suitable, or is missing. bool lookupModuleFile(StringRef FileName, off_t ExpectedSize, - time_t ExpectedModTime, Optional &File); + time_t ExpectedModTime, OptionalFileEntryRef &File); /// View the graphviz representation of the module graph. void viewGraph(); diff --git a/clang/include/clang/Tooling/Core/Replacement.h b/clang/include/clang/Tooling/Core/Replacement.h --- a/clang/include/clang/Tooling/Core/Replacement.h +++ b/clang/include/clang/Tooling/Core/Replacement.h @@ -202,6 +202,9 @@ /// Equal-to operator between two Replacements. bool operator==(const Replacement &LHS, const Replacement &RHS); +inline bool operator!=(const Replacement &LHS, const Replacement &RHS) { + return !(LHS == RHS); +} /// Maintains a set of replacements that are conflict-free. /// Two replacements are considered conflicts if they overlap or have the same diff --git a/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h b/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h --- a/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h +++ b/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h @@ -134,7 +134,7 @@ void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, - Optional File, StringRef SearchPath, + OptionalFileEntryRef File, StringRef SearchPath, StringRef RelativePath, const Module *Imported, SrcMgr::CharacteristicKind FileType) override; void moduleImport(SourceLocation ImportLoc, ModuleIdPath Path, diff --git a/clang/include/clang/Tooling/Inclusions/StandardLibrary.h b/clang/include/clang/Tooling/Inclusions/StandardLibrary.h --- a/clang/include/clang/Tooling/Inclusions/StandardLibrary.h +++ b/clang/include/clang/Tooling/Inclusions/StandardLibrary.h @@ -16,6 +16,7 @@ #define LLVM_CLANG_TOOLING_INCLUSIONS_STANDARDLIBRARY_H #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/Hashing.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/raw_ostream.h" #include diff --git a/clang/lib/ARCMigrate/ObjCMT.cpp b/clang/lib/ARCMigrate/ObjCMT.cpp --- a/clang/lib/ARCMigrate/ObjCMT.cpp +++ b/clang/lib/ARCMigrate/ObjCMT.cpp @@ -156,7 +156,7 @@ return AllowListFilenames.find(llvm::sys::path::filename(Path)) != AllowListFilenames.end(); } - bool canModifyFile(Optional FE) { + bool canModifyFile(OptionalFileEntryRef FE) { if (!FE) return false; return canModifyFile(FE->getName()); @@ -1958,7 +1958,8 @@ I = rewriter.buffer_begin(), E = rewriter.buffer_end(); I != E; ++I) { FileID FID = I->first; RewriteBuffer &buf = I->second; - Optional file = Ctx.getSourceManager().getFileEntryRefForID(FID); + OptionalFileEntryRef file = + Ctx.getSourceManager().getFileEntryRefForID(FID); assert(file); SmallString<512> newText; llvm::raw_svector_ostream vecOS(newText); @@ -2028,7 +2029,7 @@ namespace { struct EditEntry { - Optional File; + OptionalFileEntryRef File; unsigned Offset = 0; unsigned RemoveLen = 0; std::string Text; diff --git a/clang/lib/Basic/FileManager.cpp b/clang/lib/Basic/FileManager.cpp --- a/clang/lib/Basic/FileManager.cpp +++ b/clang/lib/Basic/FileManager.cpp @@ -471,7 +471,7 @@ return FileEntryRef(NamedFileEnt); } -llvm::Optional FileManager::getBypassFile(FileEntryRef VF) { +OptionalFileEntryRef FileManager::getBypassFile(FileEntryRef VF) { // Stat of the file and return nullptr if it doesn't exist. llvm::vfs::Status Status; if (getStatValue(VF.getName(), Status, /*isFile=*/true, /*F=*/nullptr)) diff --git a/clang/lib/Basic/SourceManager.cpp b/clang/lib/Basic/SourceManager.cpp --- a/clang/lib/Basic/SourceManager.cpp +++ b/clang/lib/Basic/SourceManager.cpp @@ -712,10 +712,10 @@ Pair.first->second = NewFile; } -Optional +OptionalFileEntryRef SourceManager::bypassFileContentsOverride(FileEntryRef File) { assert(isFileOverridden(&File.getFileEntry())); - llvm::Optional BypassFile = FileMgr.getBypassFile(File); + OptionalFileEntryRef BypassFile = FileMgr.getBypassFile(File); // If the file can't be found in the FS, give up. if (!BypassFile) diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp --- a/clang/lib/Basic/TargetInfo.cpp +++ b/clang/lib/Basic/TargetInfo.cpp @@ -510,7 +510,7 @@ } if (Opts.MaxBitIntWidth) - MaxBitIntWidth = Opts.MaxBitIntWidth; + MaxBitIntWidth = (unsigned)Opts.MaxBitIntWidth; if (Opts.FakeAddressSpaceMap) AddrSpaceMap = &FakeAddrSpaceMap; diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -536,7 +536,7 @@ // a relative path, so we look into the actual file entry for the main // file to determine the real absolute path for the file. std::string MainFileDir; - if (Optional MainFile = + if (OptionalFileEntryRef MainFile = SM.getFileEntryRefForID(SM.getMainFileID())) { MainFileDir = std::string(MainFile->getDir().getName()); if (!llvm::sys::path::is_absolute(MainFileName)) { diff --git a/clang/lib/CodeGen/CGObjCGNU.cpp b/clang/lib/CodeGen/CGObjCGNU.cpp --- a/clang/lib/CodeGen/CGObjCGNU.cpp +++ b/clang/lib/CodeGen/CGObjCGNU.cpp @@ -3864,8 +3864,7 @@ // The path to the source file where this module was declared SourceManager &SM = CGM.getContext().getSourceManager(); - Optional mainFile = - SM.getFileEntryRefForID(SM.getMainFileID()); + OptionalFileEntryRef mainFile = SM.getFileEntryRefForID(SM.getMainFileID()); std::string path = (mainFile->getDir().getName() + "/" + mainFile->getName()).str(); module.add(MakeConstantString(path, ".objc_source_file_name")); diff --git a/clang/lib/CodeGen/MacroPPCallbacks.h b/clang/lib/CodeGen/MacroPPCallbacks.h --- a/clang/lib/CodeGen/MacroPPCallbacks.h +++ b/clang/lib/CodeGen/MacroPPCallbacks.h @@ -101,7 +101,7 @@ void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, - Optional File, StringRef SearchPath, + OptionalFileEntryRef File, StringRef SearchPath, StringRef RelativePath, const Module *Imported, SrcMgr::CharacteristicKind FileType) override; diff --git a/clang/lib/CodeGen/MacroPPCallbacks.cpp b/clang/lib/CodeGen/MacroPPCallbacks.cpp --- a/clang/lib/CodeGen/MacroPPCallbacks.cpp +++ b/clang/lib/CodeGen/MacroPPCallbacks.cpp @@ -167,7 +167,7 @@ void MacroPPCallbacks::InclusionDirective( SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, - bool IsAngled, CharSourceRange FilenameRange, Optional File, + bool IsAngled, CharSourceRange FilenameRange, OptionalFileEntryRef File, StringRef SearchPath, StringRef RelativePath, const Module *Imported, SrcMgr::CharacteristicKind FileType) { diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp --- a/clang/lib/Frontend/CompilerInstance.cpp +++ b/clang/lib/Frontend/CompilerInstance.cpp @@ -426,7 +426,7 @@ // Remap files in the source manager (with other files). for (const auto &RF : InitOpts.RemappedFiles) { // Find the file that we're mapping to. - Optional ToFile = FileMgr.getOptionalFileRef(RF.second); + OptionalFileEntryRef ToFile = FileMgr.getOptionalFileRef(RF.second); if (!ToFile) { Diags.Report(diag::err_fe_remap_missing_to_file) << RF.first << RF.second; continue; @@ -1281,8 +1281,8 @@ Instance.getFrontendOpts().AllowPCMWithCompilerErrors; } -static Optional getPublicModuleMap(FileEntryRef File, - FileManager &FileMgr) { +static OptionalFileEntryRef getPublicModuleMap(FileEntryRef File, + FileManager &FileMgr) { StringRef Filename = llvm::sys::path::filename(File.getName()); SmallString<128> PublicFilename(File.getDir().getName()); if (Filename == "module_private.map") @@ -1307,12 +1307,12 @@ ModuleMap &ModMap = ImportingInstance.getPreprocessor().getHeaderSearchInfo().getModuleMap(); bool Result; - if (Optional ModuleMapFile = + if (OptionalFileEntryRef ModuleMapFile = ModMap.getContainingModuleMapFile(Module)) { // Canonicalize compilation to start with the public module map. This is // vital for submodules declarations in the private module maps to be // correctly parsed when depending on a top level module in the public one. - if (Optional PublicMMFile = getPublicModuleMap( + if (OptionalFileEntryRef PublicMMFile = getPublicModuleMap( *ModuleMapFile, ImportingInstance.getFileManager())) ModuleMapFile = PublicMMFile; diff --git a/clang/lib/Frontend/DependencyFile.cpp b/clang/lib/Frontend/DependencyFile.cpp --- a/clang/lib/Frontend/DependencyFile.cpp +++ b/clang/lib/Frontend/DependencyFile.cpp @@ -64,7 +64,7 @@ void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, - Optional File, StringRef SearchPath, + OptionalFileEntryRef File, StringRef SearchPath, StringRef RelativePath, const Module *Imported, SrcMgr::CharacteristicKind FileType) override { if (!File) @@ -75,7 +75,7 @@ } void HasInclude(SourceLocation Loc, StringRef SpelledFilename, bool IsAngled, - Optional File, + OptionalFileEntryRef File, SrcMgr::CharacteristicKind FileType) override { if (!File) return; diff --git a/clang/lib/Frontend/DependencyGraph.cpp b/clang/lib/Frontend/DependencyGraph.cpp --- a/clang/lib/Frontend/DependencyGraph.cpp +++ b/clang/lib/Frontend/DependencyGraph.cpp @@ -48,7 +48,7 @@ void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, - Optional File, StringRef SearchPath, + OptionalFileEntryRef File, StringRef SearchPath, StringRef RelativePath, const Module *Imported, SrcMgr::CharacteristicKind FileType) override; @@ -66,21 +66,15 @@ } void DependencyGraphCallback::InclusionDirective( - SourceLocation HashLoc, - const Token &IncludeTok, - StringRef FileName, - bool IsAngled, - CharSourceRange FilenameRange, - Optional File, - StringRef SearchPath, - StringRef RelativePath, - const Module *Imported, + SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, + bool IsAngled, CharSourceRange FilenameRange, OptionalFileEntryRef File, + StringRef SearchPath, StringRef RelativePath, const Module *Imported, SrcMgr::CharacteristicKind FileType) { if (!File) return; SourceManager &SM = PP->getSourceManager(); - Optional FromFile = + OptionalFileEntryRef FromFile = SM.getFileEntryRefForID(SM.getFileID(SM.getExpansionLoc(HashLoc))); if (!FromFile) return; diff --git a/clang/lib/Frontend/FrontendAction.cpp b/clang/lib/Frontend/FrontendAction.cpp --- a/clang/lib/Frontend/FrontendAction.cpp +++ b/clang/lib/Frontend/FrontendAction.cpp @@ -823,7 +823,7 @@ Dir = *DirOrErr; SmallVector, 1> CWD; CWD.push_back({nullptr, Dir}); - Optional FE = + OptionalFileEntryRef FE = HS.LookupFile(FileName, SourceLocation(), /*Angled*/ Input.getKind().getHeaderUnitKind() == InputKind::HeaderUnit_System, diff --git a/clang/lib/Frontend/ModuleDependencyCollector.cpp b/clang/lib/Frontend/ModuleDependencyCollector.cpp --- a/clang/lib/Frontend/ModuleDependencyCollector.cpp +++ b/clang/lib/Frontend/ModuleDependencyCollector.cpp @@ -48,7 +48,7 @@ void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, - Optional File, StringRef SearchPath, + OptionalFileEntryRef File, StringRef SearchPath, StringRef RelativePath, const Module *Imported, SrcMgr::CharacteristicKind FileType) override { if (!File) diff --git a/clang/lib/Frontend/PrecompiledPreamble.cpp b/clang/lib/Frontend/PrecompiledPreamble.cpp --- a/clang/lib/Frontend/PrecompiledPreamble.cpp +++ b/clang/lib/Frontend/PrecompiledPreamble.cpp @@ -97,7 +97,7 @@ void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, - Optional File, StringRef SearchPath, + OptionalFileEntryRef File, StringRef SearchPath, StringRef RelativePath, const Module *Imported, SrcMgr::CharacteristicKind FileType) override { // File is None if it wasn't found. diff --git a/clang/lib/Frontend/PrintPreprocessedOutput.cpp b/clang/lib/Frontend/PrintPreprocessedOutput.cpp --- a/clang/lib/Frontend/PrintPreprocessedOutput.cpp +++ b/clang/lib/Frontend/PrintPreprocessedOutput.cpp @@ -146,7 +146,7 @@ void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, - Optional File, StringRef SearchPath, + OptionalFileEntryRef File, StringRef SearchPath, StringRef RelativePath, const Module *Imported, SrcMgr::CharacteristicKind FileType) override; void Ident(SourceLocation Loc, StringRef str) override; @@ -389,15 +389,9 @@ } void PrintPPOutputPPCallbacks::InclusionDirective( - SourceLocation HashLoc, - const Token &IncludeTok, - StringRef FileName, - bool IsAngled, - CharSourceRange FilenameRange, - Optional File, - StringRef SearchPath, - StringRef RelativePath, - const Module *Imported, + SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, + bool IsAngled, CharSourceRange FilenameRange, OptionalFileEntryRef File, + StringRef SearchPath, StringRef RelativePath, const Module *Imported, SrcMgr::CharacteristicKind FileType) { // In -dI mode, dump #include directives prior to dumping their content or // interpretation. diff --git a/clang/lib/Frontend/Rewrite/InclusionRewriter.cpp b/clang/lib/Frontend/Rewrite/InclusionRewriter.cpp --- a/clang/lib/Frontend/Rewrite/InclusionRewriter.cpp +++ b/clang/lib/Frontend/Rewrite/InclusionRewriter.cpp @@ -74,7 +74,7 @@ void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, - Optional File, StringRef SearchPath, + OptionalFileEntryRef File, StringRef SearchPath, StringRef RelativePath, const Module *Imported, SrcMgr::CharacteristicKind FileType) override; void If(SourceLocation Loc, SourceRange ConditionRange, @@ -182,16 +182,12 @@ /// FileChanged() or FileSkipped() is called after this (or neither is /// called if this #include results in an error or does not textually include /// anything). -void InclusionRewriter::InclusionDirective(SourceLocation HashLoc, - const Token &/*IncludeTok*/, - StringRef /*FileName*/, - bool /*IsAngled*/, - CharSourceRange /*FilenameRange*/, - Optional /*File*/, - StringRef /*SearchPath*/, - StringRef /*RelativePath*/, - const Module *Imported, - SrcMgr::CharacteristicKind FileType){ +void InclusionRewriter::InclusionDirective( + SourceLocation HashLoc, const Token & /*IncludeTok*/, + StringRef /*FileName*/, bool /*IsAngled*/, + CharSourceRange /*FilenameRange*/, OptionalFileEntryRef /*File*/, + StringRef /*SearchPath*/, StringRef /*RelativePath*/, + const Module *Imported, SrcMgr::CharacteristicKind FileType) { if (Imported) { auto P = ModuleIncludes.insert(std::make_pair(HashLoc, Imported)); (void)P; diff --git a/clang/lib/Frontend/VerifyDiagnosticConsumer.cpp b/clang/lib/Frontend/VerifyDiagnosticConsumer.cpp --- a/clang/lib/Frontend/VerifyDiagnosticConsumer.cpp +++ b/clang/lib/Frontend/VerifyDiagnosticConsumer.cpp @@ -541,7 +541,7 @@ ExpectedLoc = SourceLocation(); } else { // Lookup file via Preprocessor, like a #include. - Optional File = + OptionalFileEntryRef File = PP->LookupFile(Pos, Filename, false, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); if (!File) { diff --git a/clang/lib/Lex/HeaderSearch.cpp b/clang/lib/Lex/HeaderSearch.cpp --- a/clang/lib/Lex/HeaderSearch.cpp +++ b/clang/lib/Lex/HeaderSearch.cpp @@ -171,7 +171,7 @@ } std::string HeaderSearch::getCachedModuleFileName(Module *Module) { - Optional ModuleMap = + OptionalFileEntryRef ModuleMap = getModuleMap().getModuleMapFileForUniquing(Module); // The ModuleMap maybe a nullptr, when we load a cached C++ module without // *.modulemap file. In this case, just return an empty string. @@ -212,7 +212,7 @@ } std::string HeaderSearch::getPrebuiltImplicitModuleFileName(Module *Module) { - Optional ModuleMap = + OptionalFileEntryRef ModuleMap = getModuleMap().getModuleMapFileForUniquing(Module); StringRef ModuleName = Module->Name; StringRef ModuleMapPath = ModuleMap->getName(); @@ -415,7 +415,7 @@ return getHeaderMap()->getFileName(); } -Optional HeaderSearch::getFileAndSuggestModule( +OptionalFileEntryRef HeaderSearch::getFileAndSuggestModule( StringRef FileName, SourceLocation IncludeLoc, const DirectoryEntry *Dir, bool IsSystemHeaderDir, Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule, bool OpenFile /*=true*/, @@ -447,7 +447,7 @@ /// LookupFile - Lookup the specified file in this search path, returning it /// if it exists or returning null if not. -Optional DirectoryLookup::LookupFile( +OptionalFileEntryRef DirectoryLookup::LookupFile( StringRef &Filename, HeaderSearch &HS, SourceLocation IncludeLoc, SmallVectorImpl *SearchPath, SmallVectorImpl *RelativePath, Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule, @@ -532,7 +532,7 @@ /// \param DirName The name of the framework directory. /// \param SubmodulePath Will be populated with the submodule path from the /// returned top-level module to the originally named framework. -static Optional +static OptionalDirectoryEntryRef getTopFrameworkDir(FileManager &FileMgr, StringRef DirName, SmallVectorImpl &SubmodulePath) { assert(llvm::sys::path::extension(DirName) == ".framework" && @@ -586,7 +586,7 @@ /// DoFrameworkLookup - Do a lookup of the specified file in the current /// DirectoryLookup, which is a framework directory. -Optional DirectoryLookup::DoFrameworkLookup( +OptionalFileEntryRef DirectoryLookup::DoFrameworkLookup( StringRef Filename, HeaderSearch &HS, SmallVectorImpl *SearchPath, SmallVectorImpl *RelativePath, Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule, @@ -855,7 +855,7 @@ /// for system \#include's or not (i.e. using <> instead of ""). Includers, if /// non-empty, indicates where the \#including file(s) are, in case a relative /// search is needed. Microsoft mode will pass all \#including files. -Optional HeaderSearch::LookupFile( +OptionalFileEntryRef HeaderSearch::LookupFile( StringRef Filename, SourceLocation IncludeLoc, bool isAngled, ConstSearchDirIterator FromDir, ConstSearchDirIterator *CurDirArg, ArrayRef> Includers, @@ -898,7 +898,7 @@ // This is the header that MSVC's header search would have found. ModuleMap::KnownHeader MSSuggestedModule; - Optional MSFE; + OptionalFileEntryRef MSFE; // Unless disabled, check to see if the file is in the #includer's // directory. This cannot be based on CurDir, because each includer could be @@ -927,7 +927,7 @@ bool IncluderIsSystemHeader = Includer ? getFileInfo(Includer).DirInfo != SrcMgr::C_User : BuildSystemModule; - if (Optional FE = getFileAndSuggestModule( + if (OptionalFileEntryRef FE = getFileAndSuggestModule( TmpDir, IncludeLoc, IncluderAndDir.second, IncluderIsSystemHeader, RequestingModule, SuggestedModule)) { if (!Includer) { @@ -1043,7 +1043,7 @@ bool InUserSpecifiedSystemFramework = false; bool IsInHeaderMap = false; bool IsFrameworkFoundInDir = false; - Optional File = It->LookupFile( + OptionalFileEntryRef File = It->LookupFile( Filename, *this, IncludeLoc, SearchPath, RelativePath, RequestingModule, SuggestedModule, InUserSpecifiedSystemFramework, IsFrameworkFoundInDir, IsInHeaderMap, MappedName, OpenFile); @@ -1138,7 +1138,7 @@ ScratchFilename += '/'; ScratchFilename += Filename; - Optional File = LookupFile( + OptionalFileEntryRef File = LookupFile( ScratchFilename, IncludeLoc, /*isAngled=*/true, FromDir, &CurDir, Includers.front(), SearchPath, RelativePath, RequestingModule, SuggestedModule, IsMapped, /*IsFrameworkFound=*/nullptr); @@ -1175,7 +1175,7 @@ /// within ".../Carbon.framework/Headers/Carbon.h", check to see if HIToolbox /// is a subframework within Carbon.framework. If so, return the FileEntry /// for the designated file, otherwise return null. -Optional HeaderSearch::LookupSubframeworkHeader( +OptionalFileEntryRef HeaderSearch::LookupSubframeworkHeader( StringRef Filename, const FileEntry *ContextFileEnt, SmallVectorImpl *SearchPath, SmallVectorImpl *RelativePath, Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule) { @@ -1628,7 +1628,7 @@ if (needModuleLookup(RequestingModule, SuggestedModule)) { // Find the top-level framework based on this framework. SmallVector SubmodulePath; - Optional TopFrameworkDir = + OptionalDirectoryEntryRef TopFrameworkDir = ::getTopFrameworkDir(FileMgr, FrameworkName, SubmodulePath); assert(TopFrameworkDir && "Could not find the top-most framework dir"); @@ -1668,7 +1668,7 @@ StringRef OriginalModuleMapFile) { // Find the directory for the module. For frameworks, that may require going // up from the 'Modules' directory. - Optional Dir; + OptionalDirectoryEntryRef Dir; if (getHeaderSearchOpts().ModuleMapFileHomeIsCwd) { Dir = FileMgr.getOptionalDirectoryRef("."); } else { diff --git a/clang/lib/Lex/ModuleMap.cpp b/clang/lib/Lex/ModuleMap.cpp --- a/clang/lib/Lex/ModuleMap.cpp +++ b/clang/lib/Lex/ModuleMap.cpp @@ -176,14 +176,14 @@ llvm::sys::path::append(Path, "Frameworks", Framework + ".framework"); } -Optional ModuleMap::findHeader( +OptionalFileEntryRef ModuleMap::findHeader( Module *M, const Module::UnresolvedHeaderDirective &Header, SmallVectorImpl &RelativePathName, bool &NeedsFramework) { // Search for the header file within the module's home directory. auto *Directory = M->Directory; SmallString<128> FullPathName(Directory->getName()); - auto GetFile = [&](StringRef Filename) -> Optional { + auto GetFile = [&](StringRef Filename) -> OptionalFileEntryRef { auto File = expectedToOptional(SourceMgr.getFileManager().getFileRef(Filename)); if (!File || (Header.Size && File->getSize() != *Header.Size) || @@ -192,7 +192,7 @@ return *File; }; - auto GetFrameworkFile = [&]() -> Optional { + auto GetFrameworkFile = [&]() -> OptionalFileEntryRef { unsigned FullPathLength = FullPathName.size(); appendSubframeworkPaths(M, RelativePathName); unsigned RelativePathLength = RelativePathName.size(); @@ -256,7 +256,7 @@ const Module::UnresolvedHeaderDirective &Header, bool &NeedsFramework) { SmallString<128> RelativePathName; - if (Optional File = + if (OptionalFileEntryRef File = findHeader(Mod, Header, RelativePathName, NeedsFramework)) { if (Header.IsUmbrella) { const DirectoryEntry *UmbrellaDir = &File->getDir().getDirEntry(); @@ -1258,7 +1258,7 @@ Cb->moduleMapAddHeader(Header.Entry->getName()); } -Optional +OptionalFileEntryRef ModuleMap::getContainingModuleMapFile(const Module *Module) const { if (Module->DefinitionLoc.isInvalid()) return std::nullopt; @@ -1267,7 +1267,7 @@ SourceMgr.getFileID(Module->DefinitionLoc)); } -Optional +OptionalFileEntryRef ModuleMap::getModuleMapFileForUniquing(const Module *M) const { if (M->IsInferred) { assert(InferredModuleAllowedBy.count(M) && "missing inferred module map"); diff --git a/clang/lib/Lex/PPCallbacks.cpp b/clang/lib/Lex/PPCallbacks.cpp --- a/clang/lib/Lex/PPCallbacks.cpp +++ b/clang/lib/Lex/PPCallbacks.cpp @@ -15,16 +15,15 @@ PPCallbacks::~PPCallbacks() = default; void PPCallbacks::HasInclude(SourceLocation Loc, StringRef FileName, - bool IsAngled, Optional File, + bool IsAngled, OptionalFileEntryRef File, SrcMgr::CharacteristicKind FileType) {} // Out of line key method. PPChainedCallbacks::~PPChainedCallbacks() = default; void PPChainedCallbacks::HasInclude(SourceLocation Loc, StringRef FileName, - bool IsAngled, Optional File, + bool IsAngled, OptionalFileEntryRef File, SrcMgr::CharacteristicKind FileType) { First->HasInclude(Loc, FileName, IsAngled, File, FileType); Second->HasInclude(Loc, FileName, IsAngled, File, FileType); } - diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp --- a/clang/lib/Lex/PPDirectives.cpp +++ b/clang/lib/Lex/PPDirectives.cpp @@ -947,7 +947,7 @@ return nullptr; } -Optional Preprocessor::LookupFile( +OptionalFileEntryRef Preprocessor::LookupFile( SourceLocation FilenameLoc, StringRef Filename, bool isAngled, ConstSearchDirIterator FromDir, const FileEntry *FromFile, ConstSearchDirIterator *CurDirArg, SmallVectorImpl *SearchPath, @@ -1012,7 +1012,7 @@ // the include path until we find that file or run out of files. ConstSearchDirIterator TmpCurDir = CurDir; ConstSearchDirIterator TmpFromDir = nullptr; - while (Optional FE = HeaderInfo.LookupFile( + while (OptionalFileEntryRef FE = HeaderInfo.LookupFile( Filename, FilenameLoc, isAngled, TmpFromDir, &TmpCurDir, Includers, SearchPath, RelativePath, RequestingModule, SuggestedModule, /*IsMapped=*/nullptr, @@ -1030,7 +1030,7 @@ } // Do a standard file entry lookup. - Optional FE = HeaderInfo.LookupFile( + OptionalFileEntryRef FE = HeaderInfo.LookupFile( Filename, FilenameLoc, isAngled, FromDir, &CurDir, Includers, SearchPath, RelativePath, RequestingModule, SuggestedModule, IsMapped, IsFrameworkFound, SkipCache, BuildSystemModule, OpenFile, CacheFailures); @@ -1048,7 +1048,7 @@ // headers on the #include stack and pass them to HeaderInfo. if (IsFileLexer()) { if ((CurFileEnt = CurPPLexer->getFileEntry())) { - if (Optional FE = HeaderInfo.LookupSubframeworkHeader( + if (OptionalFileEntryRef FE = HeaderInfo.LookupSubframeworkHeader( Filename, CurFileEnt, SearchPath, RelativePath, RequestingModule, SuggestedModule)) { if (SuggestedModule && !LangOpts.AsmPreprocessor) @@ -1063,7 +1063,7 @@ for (IncludeStackInfo &ISEntry : llvm::reverse(IncludeMacroStack)) { if (IsFileLexer(ISEntry)) { if ((CurFileEnt = ISEntry.ThePPLexer->getFileEntry())) { - if (Optional FE = HeaderInfo.LookupSubframeworkHeader( + if (OptionalFileEntryRef FE = HeaderInfo.LookupSubframeworkHeader( Filename, CurFileEnt, SearchPath, RelativePath, RequestingModule, SuggestedModule)) { if (SuggestedModule && !LangOpts.AsmPreprocessor) @@ -2003,7 +2003,7 @@ } } -Optional Preprocessor::LookupHeaderIncludeOrImport( +OptionalFileEntryRef Preprocessor::LookupHeaderIncludeOrImport( ConstSearchDirIterator *CurDir, StringRef &Filename, SourceLocation FilenameLoc, CharSourceRange FilenameRange, const Token &FilenameTok, bool &IsFrameworkFound, bool IsImportDecl, @@ -2011,9 +2011,8 @@ const FileEntry *LookupFromFile, StringRef &LookupFilename, SmallVectorImpl &RelativePath, SmallVectorImpl &SearchPath, ModuleMap::KnownHeader &SuggestedModule, bool isAngled) { - Optional File = LookupFile( - FilenameLoc, LookupFilename, - isAngled, LookupFrom, LookupFromFile, CurDir, + OptionalFileEntryRef File = LookupFile( + FilenameLoc, LookupFilename, isAngled, LookupFrom, LookupFromFile, CurDir, Callbacks ? &SearchPath : nullptr, Callbacks ? &RelativePath : nullptr, &SuggestedModule, &IsMapped, &IsFrameworkFound); if (File) @@ -2026,9 +2025,8 @@ // brackets, we can attempt a lookup as though it were a quoted path to // provide the user with a possible fixit. if (isAngled) { - Optional File = LookupFile( - FilenameLoc, LookupFilename, - false, LookupFrom, LookupFromFile, CurDir, + OptionalFileEntryRef File = LookupFile( + FilenameLoc, LookupFilename, false, LookupFrom, LookupFromFile, CurDir, Callbacks ? &SearchPath : nullptr, Callbacks ? &RelativePath : nullptr, &SuggestedModule, &IsMapped, /*IsFrameworkFound=*/nullptr); @@ -2057,9 +2055,9 @@ StringRef TypoCorrectionName = CorrectTypoFilename(Filename); StringRef TypoCorrectionLookupName = CorrectTypoFilename(LookupFilename); - Optional File = LookupFile( - FilenameLoc, TypoCorrectionLookupName, isAngled, LookupFrom, LookupFromFile, - CurDir, Callbacks ? &SearchPath : nullptr, + OptionalFileEntryRef File = LookupFile( + FilenameLoc, TypoCorrectionLookupName, isAngled, LookupFrom, + LookupFromFile, CurDir, Callbacks ? &SearchPath : nullptr, Callbacks ? &RelativePath : nullptr, &SuggestedModule, &IsMapped, /*IsFrameworkFound=*/nullptr); if (File) { @@ -2182,7 +2180,7 @@ BackslashStyle = llvm::sys::path::Style::windows; } - Optional File = LookupHeaderIncludeOrImport( + OptionalFileEntryRef File = LookupHeaderIncludeOrImport( &CurDir, Filename, FilenameLoc, FilenameRange, FilenameTok, IsFrameworkFound, IsImportDecl, IsMapped, LookupFrom, LookupFromFile, LookupFilename, RelativePath, SearchPath, SuggestedModule, isAngled); diff --git a/clang/lib/Lex/PPLexerChange.cpp b/clang/lib/Lex/PPLexerChange.cpp --- a/clang/lib/Lex/PPLexerChange.cpp +++ b/clang/lib/Lex/PPLexerChange.cpp @@ -94,7 +94,7 @@ Lexer *TheLexer = new Lexer(FID, *InputFile, *this, IsFirstIncludeOfFile); if (getPreprocessorOpts().DependencyDirectivesForFile && FID != PredefinesFileID) { - if (Optional File = SourceMgr.getFileEntryRefForID(FID)) { + if (OptionalFileEntryRef File = SourceMgr.getFileEntryRefForID(FID)) { if (Optional> DepDirectives = getPreprocessorOpts().DependencyDirectivesForFile(*File)) { diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp --- a/clang/lib/Lex/PPMacroExpansion.cpp +++ b/clang/lib/Lex/PPMacroExpansion.cpp @@ -1249,7 +1249,7 @@ return false; // Search include directories. - Optional File = + OptionalFileEntryRef File = PP.LookupFile(FilenameLoc, Filename, isAngled, LookupFrom, LookupFromFile, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); diff --git a/clang/lib/Lex/Pragma.cpp b/clang/lib/Lex/Pragma.cpp --- a/clang/lib/Lex/Pragma.cpp +++ b/clang/lib/Lex/Pragma.cpp @@ -527,7 +527,7 @@ return; // Search include directories for this file. - Optional File = + OptionalFileEntryRef File = LookupFile(FilenameTok.getLocation(), Filename, isAngled, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); if (!File) { diff --git a/clang/lib/Lex/PreprocessingRecord.cpp b/clang/lib/Lex/PreprocessingRecord.cpp --- a/clang/lib/Lex/PreprocessingRecord.cpp +++ b/clang/lib/Lex/PreprocessingRecord.cpp @@ -42,7 +42,7 @@ InclusionDirective::InclusionDirective(PreprocessingRecord &PPRec, InclusionKind Kind, StringRef FileName, bool InQuotes, bool ImportedModule, - Optional File, + OptionalFileEntryRef File, SourceRange Range) : PreprocessingDirective(InclusionDirectiveKind, Range), InQuotes(InQuotes), Kind(Kind), ImportedModule(ImportedModule), File(File) { @@ -475,15 +475,9 @@ } void PreprocessingRecord::InclusionDirective( - SourceLocation HashLoc, - const Token &IncludeTok, - StringRef FileName, - bool IsAngled, - CharSourceRange FilenameRange, - Optional File, - StringRef SearchPath, - StringRef RelativePath, - const Module *Imported, + SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, + bool IsAngled, CharSourceRange FilenameRange, OptionalFileEntryRef File, + StringRef SearchPath, StringRef RelativePath, const Module *Imported, SrcMgr::CharacteristicKind FileType) { InclusionDirective::InclusionKind Kind = InclusionDirective::Include; diff --git a/clang/lib/Lex/Preprocessor.cpp b/clang/lib/Lex/Preprocessor.cpp --- a/clang/lib/Lex/Preprocessor.cpp +++ b/clang/lib/Lex/Preprocessor.cpp @@ -580,7 +580,7 @@ if (!PPOpts->PCHThroughHeader.empty()) { // Lookup and save the FileID for the through header. If it isn't found // in the search path, it's a fatal error. - Optional File = LookupFile( + OptionalFileEntryRef File = LookupFile( SourceLocation(), PPOpts->PCHThroughHeader, /*isAngled=*/false, /*FromDir=*/nullptr, /*FromFile=*/nullptr, /*CurDir=*/nullptr, /*SearchPath=*/nullptr, /*RelativePath=*/nullptr, diff --git a/clang/lib/Sema/SemaModule.cpp b/clang/lib/Sema/SemaModule.cpp --- a/clang/lib/Sema/SemaModule.cpp +++ b/clang/lib/Sema/SemaModule.cpp @@ -320,7 +320,7 @@ Diag(Path[0].second, diag::err_module_redefinition) << ModuleName; if (M->DefinitionLoc.isValid()) Diag(M->DefinitionLoc, diag::note_prev_module_definition); - else if (Optional FE = M->getASTFile()) + else if (OptionalFileEntryRef FE = M->getASTFile()) Diag(M->DefinitionLoc, diag::note_prev_module_definition_from_ast_file) << FE->getName(); Mod = M; diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -1520,7 +1520,7 @@ // we will also try to fail gracefully by setting up the SLocEntry. unsigned InputID = Record[4]; InputFile IF = getInputFile(*F, InputID); - Optional File = IF.getFile(); + OptionalFileEntryRef File = IF.getFile(); bool OverriddenBuffer = IF.isOverridden(); // Note that we only check if a File was returned. If it was out-of-date @@ -2361,8 +2361,8 @@ StringRef Filename = FI.Filename; uint64_t StoredContentHash = FI.ContentHash; - OptionalFileEntryRefDegradesToFileEntryPtr File = - expectedToOptional(FileMgr.getFileRef(Filename, /*OpenFile=*/false)); + OptionalFileEntryRefDegradesToFileEntryPtr File = OptionalFileEntryRef( + expectedToOptional(FileMgr.getFileRef(Filename, /*OpenFile=*/false))); // For an overridden file, create a virtual file with the stored // size/timestamp. @@ -3964,7 +3964,7 @@ Module *M = PP.getHeaderSearchInfo().lookupModule(F.ModuleName, F.ImportLoc); auto &Map = PP.getHeaderSearchInfo().getModuleMap(); - Optional ModMap = + OptionalFileEntryRef ModMap = M ? Map.getModuleMapFileForUniquing(M) : std::nullopt; // Don't emit module relocation error if we have -fno-validate-pch if (!bool(PP.getPreprocessorOpts().DisablePCHOrModuleValidation & @@ -6126,7 +6126,7 @@ case PPD_INCLUSION_DIRECTIVE: { const char *FullFileNameStart = Blob.data() + Record[0]; StringRef FullFileName(FullFileNameStart, Blob.size() - Record[0]); - Optional File; + OptionalFileEntryRef File; if (!FullFileName.empty()) File = PP.getFileManager().getOptionalFileRef(FullFileName); diff --git a/clang/lib/Serialization/ModuleManager.cpp b/clang/lib/Serialization/ModuleManager.cpp --- a/clang/lib/Serialization/ModuleManager.cpp +++ b/clang/lib/Serialization/ModuleManager.cpp @@ -444,14 +444,14 @@ bool ModuleManager::lookupModuleFile(StringRef FileName, off_t ExpectedSize, time_t ExpectedModTime, - Optional &File) { + OptionalFileEntryRef &File) { File = std::nullopt; if (FileName == "-") return false; // Open the file immediately to ensure there is no race between stat'ing and // opening the file. - Optional FileOrErr = + OptionalFileEntryRef FileOrErr = expectedToOptional(FileMgr.getFileRef(FileName, /*OpenFile=*/true, /*CacheFailure=*/false)); if (!FileOrErr) diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -481,7 +481,7 @@ const CXXConstructExpr *E, const LocationContext *LCtx) { const unsigned *V = State->get({E, LCtx->getStackFrame()}); - return V ? Optional(*V) : std::nullopt; + return V ? std::make_optional(*V) : std::nullopt; } ProgramStateRef ExprEngine::removePendingInitLoop(ProgramStateRef State, @@ -510,7 +510,7 @@ const LocationContext *LCtx) { const unsigned *V = State->get({E, LCtx->getStackFrame()}); - return V ? Optional(*V) : std::nullopt; + return V ? std::make_optional(*V) : std::nullopt; } ProgramStateRef @@ -530,7 +530,7 @@ const unsigned *V = State->get(LCtx->getStackFrame()); - return V ? Optional(*V) : std::nullopt; + return V ? std::make_optional(*V) : std::nullopt; } ProgramStateRef ExprEngine::setPendingArrayDestruction( @@ -600,7 +600,7 @@ const LocationContext *LC) { ConstructedObjectKey Key(Item, LC->getStackFrame()); const SVal *V = State->get(Key); - return V ? Optional(*V) : std::nullopt; + return V ? std::make_optional(*V) : std::nullopt; } ProgramStateRef diff --git a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp --- a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp +++ b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp @@ -237,7 +237,7 @@ if (llvm::any_of(CI.getFrontendOpts().Inputs, needsModules)) { Preprocessor &PP = ScanInstance.getPreprocessor(); if (Module *CurrentModule = PP.getCurrentModuleImplementation()) - if (Optional CurrentModuleMap = + if (OptionalFileEntryRef CurrentModuleMap = PP.getHeaderSearchInfo() .getModuleMap() .getModuleMapFileForUniquing(CurrentModule)) @@ -334,7 +334,7 @@ void ModuleDepCollectorPP::InclusionDirective( SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, - bool IsAngled, CharSourceRange FilenameRange, Optional File, + bool IsAngled, CharSourceRange FilenameRange, OptionalFileEntryRef File, StringRef SearchPath, StringRef RelativePath, const Module *Imported, SrcMgr::CharacteristicKind FileType) { if (!File && !Imported) { @@ -419,7 +419,7 @@ ModuleMap &ModMapInfo = MDC.ScanInstance.getPreprocessor().getHeaderSearchInfo().getModuleMap(); - Optional ModuleMap = ModMapInfo.getModuleMapFileForUniquing(M); + OptionalFileEntryRef ModuleMap = ModMapInfo.getModuleMapFileForUniquing(M); if (ModuleMap) { SmallString<128> Path = ModuleMap->getNameAsRequested(); diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -8531,7 +8531,7 @@ return nullptr; const InclusionDirective *ID = getCursorInclusionDirective(cursor); - Optional File = ID->getFile(); + OptionalFileEntryRef File = ID->getFile(); return const_cast(File ? &File->getFileEntry() : nullptr); } diff --git a/clang/tools/libclang/CXIndexDataConsumer.h b/clang/tools/libclang/CXIndexDataConsumer.h --- a/clang/tools/libclang/CXIndexDataConsumer.h +++ b/clang/tools/libclang/CXIndexDataConsumer.h @@ -363,7 +363,7 @@ void enteredMainFile(const FileEntry *File); void ppIncludedFile(SourceLocation hashLoc, StringRef filename, - Optional File, bool isImport, bool isAngled, + OptionalFileEntryRef File, bool isImport, bool isAngled, bool isModuleImport); void importedModule(const ImportDecl *ImportD); diff --git a/clang/tools/libclang/CXIndexDataConsumer.cpp b/clang/tools/libclang/CXIndexDataConsumer.cpp --- a/clang/tools/libclang/CXIndexDataConsumer.cpp +++ b/clang/tools/libclang/CXIndexDataConsumer.cpp @@ -463,10 +463,10 @@ } void CXIndexDataConsumer::ppIncludedFile(SourceLocation hashLoc, - StringRef filename, - Optional File, - bool isImport, bool isAngled, - bool isModuleImport) { + StringRef filename, + OptionalFileEntryRef File, + bool isImport, bool isAngled, + bool isModuleImport) { if (!CB.ppIncludedFile) return; diff --git a/clang/tools/libclang/Indexing.cpp b/clang/tools/libclang/Indexing.cpp --- a/clang/tools/libclang/Indexing.cpp +++ b/clang/tools/libclang/Indexing.cpp @@ -262,7 +262,7 @@ void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, - Optional File, StringRef SearchPath, + OptionalFileEntryRef File, StringRef SearchPath, StringRef RelativePath, const Module *Imported, SrcMgr::CharacteristicKind FileType) override { bool isImport = (IncludeTok.is(tok::identifier) && diff --git a/clang/unittests/Analysis/FlowSensitive/TransferBranchTest.cpp b/clang/unittests/Analysis/FlowSensitive/TransferBranchTest.cpp --- a/clang/unittests/Analysis/FlowSensitive/TransferBranchTest.cpp +++ b/clang/unittests/Analysis/FlowSensitive/TransferBranchTest.cpp @@ -102,10 +102,10 @@ ASSERT_THAT(Results.keys(), UnorderedElementsAre("p", "q")); const TestLattice &LP = getLatticeAtAnnotation(Results, "p"); - EXPECT_THAT(LP.Branch, Optional(true)); + EXPECT_THAT(LP.Branch, std::make_optional(true)); const TestLattice &LQ = getLatticeAtAnnotation(Results, "q"); - EXPECT_THAT(LQ.Branch, Optional(false)); + EXPECT_THAT(LQ.Branch, std::make_optional(false)); }, LangStandard::lang_cxx17); } diff --git a/clang/unittests/Basic/FileManagerTest.cpp b/clang/unittests/Basic/FileManagerTest.cpp --- a/clang/unittests/Basic/FileManagerTest.cpp +++ b/clang/unittests/Basic/FileManagerTest.cpp @@ -534,7 +534,7 @@ // Calling a second time should not affect the UID or size. unsigned VirtualUID = FE.getUID(); - llvm::Optional SearchRef; + OptionalFileEntryRef SearchRef; ASSERT_THAT_ERROR(Manager.getFileRef("/tmp/test").moveInto(SearchRef), Succeeded()); EXPECT_EQ(&FE, &SearchRef->getFileEntry()); @@ -542,8 +542,7 @@ EXPECT_EQ(FE.getSize(), 10); // Bypass the file. - llvm::Optional BypassRef = - Manager.getBypassFile(File->getLastRef()); + OptionalFileEntryRef BypassRef = Manager.getBypassFile(File->getLastRef()); ASSERT_TRUE(BypassRef); EXPECT_EQ("/tmp/test", BypassRef->getName()); diff --git a/clang/unittests/Lex/PPCallbacksTest.cpp b/clang/unittests/Lex/PPCallbacksTest.cpp --- a/clang/unittests/Lex/PPCallbacksTest.cpp +++ b/clang/unittests/Lex/PPCallbacksTest.cpp @@ -36,7 +36,7 @@ void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, - Optional File, StringRef SearchPath, + OptionalFileEntryRef File, StringRef SearchPath, StringRef RelativePath, const Module *Imported, SrcMgr::CharacteristicKind FileType) override { this->HashLoc = HashLoc; @@ -56,7 +56,7 @@ SmallString<16> FileName; bool IsAngled; CharSourceRange FilenameRange; - Optional File; + OptionalFileEntryRef File; SmallString<16> SearchPath; SmallString<16> RelativePath; const Module* Imported; diff --git a/clang/unittests/Lex/PPDependencyDirectivesTest.cpp b/clang/unittests/Lex/PPDependencyDirectivesTest.cpp --- a/clang/unittests/Lex/PPDependencyDirectivesTest.cpp +++ b/clang/unittests/Lex/PPDependencyDirectivesTest.cpp @@ -92,7 +92,7 @@ "#include \"head3.h\"\n#include \"head3.h\"\n")); FileMgr.setVirtualFileSystem(VFS); - Optional FE; + OptionalFileEntryRef FE; ASSERT_THAT_ERROR(FileMgr.getFileRef("main.c").moveInto(FE), llvm::Succeeded()); SourceMgr.setMainFileID( diff --git a/flang/include/flang/Lower/Runtime.h b/flang/include/flang/Lower/Runtime.h --- a/flang/include/flang/Lower/Runtime.h +++ b/flang/include/flang/Lower/Runtime.h @@ -16,9 +16,10 @@ #ifndef FORTRAN_LOWER_RUNTIME_H #define FORTRAN_LOWER_RUNTIME_H +#include + namespace llvm { -template -class Optional; +template using Optional = std::optional; } namespace mlir { diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp @@ -190,7 +190,7 @@ llvm::Optional DWARFFormValue::GetFixedSize(dw_form_t form, const DWARFUnit *u) { if (form <= DW_FORM_ref_sig8 && g_form_sizes[form].valid) - return g_form_sizes[form].size; + return (uint8_t)g_form_sizes[form].size; if (form == DW_FORM_addr && u) return u->GetAddressByteSize(); return std::nullopt; diff --git a/lldb/source/Symbol/Type.cpp b/lldb/source/Symbol/Type.cpp --- a/lldb/source/Symbol/Type.cpp +++ b/lldb/source/Symbol/Type.cpp @@ -343,7 +343,7 @@ llvm::Optional Type::GetByteSize(ExecutionContextScope *exe_scope) { if (m_byte_size_has_value) - return m_byte_size; + return (uint64_t)m_byte_size; switch (m_encoding_uid_type) { case eEncodingInvalid: @@ -360,14 +360,14 @@ if (llvm::Optional size = encoding_type->GetByteSize(exe_scope)) { m_byte_size = *size; m_byte_size_has_value = true; - return m_byte_size; + return (uint64_t)m_byte_size; } if (llvm::Optional size = GetLayoutCompilerType().GetByteSize(exe_scope)) { m_byte_size = *size; m_byte_size_has_value = true; - return m_byte_size; + return (uint64_t)m_byte_size; } } break; @@ -378,7 +378,7 @@ if (ArchSpec arch = m_symbol_file->GetObjectFile()->GetArchitecture()) { m_byte_size = arch.GetAddressByteSize(); m_byte_size_has_value = true; - return m_byte_size; + return (uint64_t)m_byte_size; } } break; } diff --git a/llvm/include/llvm/ADT/Optional.h b/llvm/include/llvm/ADT/Optional.h --- a/llvm/include/llvm/ADT/Optional.h +++ b/llvm/include/llvm/ADT/Optional.h @@ -16,446 +16,12 @@ #ifndef LLVM_ADT_OPTIONAL_H #define LLVM_ADT_OPTIONAL_H -#include "llvm/ADT/Hashing.h" -#include "llvm/Support/Compiler.h" -#include "llvm/Support/type_traits.h" -#include -#include -#include +#include namespace llvm { - -namespace optional_detail { - -/// Storage for any type. -// -// The specialization condition intentionally uses -// llvm::is_trivially_{copy/move}_constructible instead of -// std::is_trivially_{copy/move}_constructible. GCC versions prior to 7.4 may -// instantiate the copy/move constructor of `T` when -// std::is_trivially_{copy/move}_constructible is instantiated. This causes -// compilation to fail if we query the trivially copy/move constructible -// property of a class which is not copy/move constructible. -// -// The current implementation of OptionalStorage insists that in order to use -// the trivial specialization, the value_type must be trivially copy -// constructible and trivially copy assignable due to =default implementations -// of the copy/move constructor/assignment. It does not follow that this is -// necessarily the case std::is_trivially_copyable is true (hence the expanded -// specialization condition). -// -// The move constructible / assignable conditions emulate the remaining behavior -// of std::is_trivially_copyable. -template ::value && - std::is_trivially_copy_assignable::value && - (llvm::is_trivially_move_constructible::value || - !std::is_move_constructible::value) && - (std::is_trivially_move_assignable::value || - !std::is_move_assignable::value))> -class OptionalStorage { - union { - char empty; - T val; - }; - bool hasVal = false; - -public: - ~OptionalStorage() { reset(); } - - constexpr OptionalStorage() noexcept : empty() {} - - constexpr OptionalStorage(OptionalStorage const &other) : OptionalStorage() { - if (other.has_value()) { - emplace(other.val); - } - } - constexpr OptionalStorage(OptionalStorage &&other) : OptionalStorage() { - if (other.has_value()) { - emplace(std::move(other.val)); - } - } - - template - constexpr explicit OptionalStorage(std::in_place_t, Args &&...args) - : val(std::forward(args)...), hasVal(true) {} - - void reset() noexcept { - if (hasVal) { - val.~T(); - hasVal = false; - } - } - - constexpr bool has_value() const noexcept { return hasVal; } - - T &value() &noexcept { - assert(hasVal); - return val; - } - constexpr T const &value() const &noexcept { - assert(hasVal); - return val; - } - T &&value() &&noexcept { - assert(hasVal); - return std::move(val); - } - - template void emplace(Args &&...args) { - reset(); - ::new ((void *)std::addressof(val)) T(std::forward(args)...); - hasVal = true; - } - - OptionalStorage &operator=(T const &y) { - if (has_value()) { - val = y; - } else { - ::new ((void *)std::addressof(val)) T(y); - hasVal = true; - } - return *this; - } - OptionalStorage &operator=(T &&y) { - if (has_value()) { - val = std::move(y); - } else { - ::new ((void *)std::addressof(val)) T(std::move(y)); - hasVal = true; - } - return *this; - } - - OptionalStorage &operator=(OptionalStorage const &other) { - if (other.has_value()) { - if (has_value()) { - val = other.val; - } else { - ::new ((void *)std::addressof(val)) T(other.val); - hasVal = true; - } - } else { - reset(); - } - return *this; - } - - OptionalStorage &operator=(OptionalStorage &&other) { - if (other.has_value()) { - if (has_value()) { - val = std::move(other.val); - } else { - ::new ((void *)std::addressof(val)) T(std::move(other.val)); - hasVal = true; - } - } else { - reset(); - } - return *this; - } -}; - -template class OptionalStorage { - union { - char empty; - T val; - }; - bool hasVal = false; - -public: - ~OptionalStorage() = default; - - constexpr OptionalStorage() noexcept : empty{} {} - - constexpr OptionalStorage(OptionalStorage const &other) = default; - constexpr OptionalStorage(OptionalStorage &&other) = default; - - OptionalStorage &operator=(OptionalStorage const &other) = default; - OptionalStorage &operator=(OptionalStorage &&other) = default; - - template - constexpr explicit OptionalStorage(std::in_place_t, Args &&...args) - : val(std::forward(args)...), hasVal(true) {} - - void reset() noexcept { - if (hasVal) { - val.~T(); - hasVal = false; - } - } - - constexpr bool has_value() const noexcept { return hasVal; } - - T &value() &noexcept { - assert(hasVal); - return val; - } - constexpr T const &value() const &noexcept { - assert(hasVal); - return val; - } - T &&value() &&noexcept { - assert(hasVal); - return std::move(val); - } - - template void emplace(Args &&...args) { - reset(); - ::new ((void *)std::addressof(val)) T(std::forward(args)...); - hasVal = true; - } - - OptionalStorage &operator=(T const &y) { - if (has_value()) { - val = y; - } else { - ::new ((void *)std::addressof(val)) T(y); - hasVal = true; - } - return *this; - } - OptionalStorage &operator=(T &&y) { - if (has_value()) { - val = std::move(y); - } else { - ::new ((void *)std::addressof(val)) T(std::move(y)); - hasVal = true; - } - return *this; - } -}; - -} // namespace optional_detail - -template class Optional { - optional_detail::OptionalStorage Storage; - -public: - using value_type = T; - - constexpr Optional() = default; - constexpr Optional(std::nullopt_t) {} - - constexpr Optional(const T &y) : Storage(std::in_place, y) {} - constexpr Optional(const Optional &O) = default; - - constexpr Optional(T &&y) : Storage(std::in_place, std::move(y)) {} - constexpr Optional(Optional &&O) = default; - - template - constexpr Optional(std::in_place_t, ArgTypes &&...Args) - : Storage(std::in_place, std::forward(Args)...) {} - - Optional &operator=(T &&y) { - Storage = std::move(y); - return *this; - } - Optional &operator=(Optional &&O) = default; - - /// Create a new object by constructing it in place with the given arguments. - template void emplace(ArgTypes &&... Args) { - Storage.emplace(std::forward(Args)...); - } - - Optional &operator=(const T &y) { - Storage = y; - return *this; - } - Optional &operator=(const Optional &O) = default; - - void reset() { Storage.reset(); } - - LLVM_DEPRECATED("Use &*X instead.", "&*X") - constexpr const T *getPointer() const { return &Storage.value(); } - LLVM_DEPRECATED("Use &*X instead.", "&*X") - T *getPointer() { return &Storage.value(); } - LLVM_DEPRECATED("std::optional::value is throwing. Use *X instead", "*X") - constexpr const T &value() const & { return Storage.value(); } - LLVM_DEPRECATED("std::optional::value is throwing. Use *X instead", "*X") - T &value() & { return Storage.value(); } - - constexpr explicit operator bool() const { return has_value(); } - constexpr bool has_value() const { return Storage.has_value(); } - constexpr const T *operator->() const { return &Storage.value(); } - T *operator->() { return &Storage.value(); } - constexpr const T &operator*() const & { return Storage.value(); } - T &operator*() & { return Storage.value(); } - - template constexpr T value_or(U &&alt) const & { - return has_value() ? operator*() : std::forward(alt); - } - - LLVM_DEPRECATED("std::optional::value is throwing. Use *X instead", "*X") - T &&value() && { return std::move(Storage.value()); } - T &&operator*() && { return std::move(Storage.value()); } - - template T value_or(U &&alt) && { - return has_value() ? std::move(operator*()) : std::forward(alt); - } -}; - -template -Optional(const T&) -> Optional; - -template llvm::hash_code hash_value(const Optional &O) { - return O ? hash_combine(true, *O) : hash_value(false); -} - -template -constexpr bool operator==(const Optional &X, const Optional &Y) { - if (X && Y) - return *X == *Y; - return X.has_value() == Y.has_value(); -} - -template -constexpr bool operator!=(const Optional &X, const Optional &Y) { - return !(X == Y); -} - -template -constexpr bool operator<(const Optional &X, const Optional &Y) { - if (X && Y) - return *X < *Y; - return X.has_value() < Y.has_value(); -} - -template -constexpr bool operator<=(const Optional &X, const Optional &Y) { - return !(Y < X); -} - -template -constexpr bool operator>(const Optional &X, const Optional &Y) { - return Y < X; -} - -template -constexpr bool operator>=(const Optional &X, const Optional &Y) { - return !(X < Y); -} - -template -constexpr bool operator==(const Optional &X, std::nullopt_t) { - return !X; -} - -template -constexpr bool operator==(std::nullopt_t, const Optional &X) { - return X == std::nullopt; -} - -template -constexpr bool operator!=(const Optional &X, std::nullopt_t) { - return !(X == std::nullopt); -} - -template -constexpr bool operator!=(std::nullopt_t, const Optional &X) { - return X != std::nullopt; -} - -template -constexpr bool operator<(const Optional &, std::nullopt_t) { - return false; -} - -template -constexpr bool operator<(std::nullopt_t, const Optional &X) { - return X.has_value(); -} - -template -constexpr bool operator<=(const Optional &X, std::nullopt_t) { - return !(std::nullopt < X); -} - -template -constexpr bool operator<=(std::nullopt_t, const Optional &X) { - return !(X < std::nullopt); -} - -template -constexpr bool operator>(const Optional &X, std::nullopt_t) { - return std::nullopt < X; -} - -template -constexpr bool operator>(std::nullopt_t, const Optional &X) { - return X < std::nullopt; -} - -template -constexpr bool operator>=(const Optional &X, std::nullopt_t) { - return std::nullopt <= X; -} - -template -constexpr bool operator>=(std::nullopt_t, const Optional &X) { - return X <= std::nullopt; -} - -template -constexpr bool operator==(const Optional &X, const T &Y) { - return X && *X == Y; -} - -template -constexpr bool operator==(const T &X, const Optional &Y) { - return Y && X == *Y; -} - -template -constexpr bool operator!=(const Optional &X, const T &Y) { - return !(X == Y); -} - -template -constexpr bool operator!=(const T &X, const Optional &Y) { - return !(X == Y); -} - -template -constexpr bool operator<(const Optional &X, const T &Y) { - return !X || *X < Y; -} - -template -constexpr bool operator<(const T &X, const Optional &Y) { - return Y && X < *Y; -} - -template -constexpr bool operator<=(const Optional &X, const T &Y) { - return !(Y < X); -} - -template -constexpr bool operator<=(const T &X, const Optional &Y) { - return !(Y < X); -} - -template -constexpr bool operator>(const Optional &X, const T &Y) { - return Y < X; -} - -template -constexpr bool operator>(const T &X, const Optional &Y) { - return Y < X; -} - -template -constexpr bool operator>=(const Optional &X, const T &Y) { - return !(X < Y); -} - -template -constexpr bool operator>=(const T &X, const Optional &Y) { - return !(X < Y); -} - -} // end namespace llvm +// Legacy alias of llvm::Optional to std::optional. +// FIXME: Remove this after LLVM 16. +template using Optional = std::optional; +} // namespace llvm #endif // LLVM_ADT_OPTIONAL_H diff --git a/llvm/include/llvm/ADT/STLForwardCompat.h b/llvm/include/llvm/ADT/STLForwardCompat.h --- a/llvm/include/llvm/ADT/STLForwardCompat.h +++ b/llvm/include/llvm/ADT/STLForwardCompat.h @@ -61,26 +61,6 @@ return std::nullopt; } -// TODO: Remove this once the migration from llvm::Optional to std::optional is -// complete. -template -auto transformOptional(const Optional &O, const Function &F) - -> Optional { - if (O) - return F(*O); - return std::nullopt; -} - -// TODO: Remove this once the migration from llvm::Optional to std::optional is -// complete. -template -auto transformOptional(Optional &&O, const Function &F) - -> Optional { - if (O) - return F(*std::move(O)); - return std::nullopt; -} - } // namespace llvm #endif // LLVM_ADT_STLFORWARDCOMPAT_H diff --git a/llvm/include/llvm/Analysis/TargetTransformInfo.h b/llvm/include/llvm/Analysis/TargetTransformInfo.h --- a/llvm/include/llvm/Analysis/TargetTransformInfo.h +++ b/llvm/include/llvm/Analysis/TargetTransformInfo.h @@ -66,7 +66,6 @@ class Value; class VPIntrinsic; struct KnownBits; -template class Optional; /// Information about a load/store intrinsic defined by the target. struct MemIntrinsicInfo { diff --git a/llvm/include/llvm/AsmParser/LLParser.h b/llvm/include/llvm/AsmParser/LLParser.h --- a/llvm/include/llvm/AsmParser/LLParser.h +++ b/llvm/include/llvm/AsmParser/LLParser.h @@ -33,7 +33,6 @@ class SourceMgr; class Type; struct MaybeAlign; - template class Optional; class Function; class Value; class BasicBlock; diff --git a/llvm/include/llvm/BinaryFormat/Dwarf.h b/llvm/include/llvm/BinaryFormat/Dwarf.h --- a/llvm/include/llvm/BinaryFormat/Dwarf.h +++ b/llvm/include/llvm/BinaryFormat/Dwarf.h @@ -30,7 +30,6 @@ namespace llvm { class StringRef; -template class Optional; namespace dwarf { diff --git a/llvm/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h b/llvm/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h --- a/llvm/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h +++ b/llvm/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h @@ -14,7 +14,6 @@ #include "llvm/Support/Error.h" namespace llvm { -template class Optional; template class SmallVectorImpl; namespace codeview { diff --git a/llvm/include/llvm/IR/Function.h b/llvm/include/llvm/IR/Function.h --- a/llvm/include/llvm/IR/Function.h +++ b/llvm/include/llvm/IR/Function.h @@ -50,7 +50,6 @@ class DISubprogram; class LLVMContext; class Module; -template class Optional; class raw_ostream; class Type; class User; diff --git a/llvm/include/llvm/Object/Archive.h b/llvm/include/llvm/Object/Archive.h --- a/llvm/include/llvm/Object/Archive.h +++ b/llvm/include/llvm/Object/Archive.h @@ -28,9 +28,6 @@ #include namespace llvm { - -template class Optional; - namespace object { const char ArchiveMagic[] = "!\n"; diff --git a/llvm/include/llvm/Support/raw_ostream.h b/llvm/include/llvm/Support/raw_ostream.h --- a/llvm/include/llvm/Support/raw_ostream.h +++ b/llvm/include/llvm/Support/raw_ostream.h @@ -743,16 +743,6 @@ raw_ostream &operator<<(raw_ostream &OS, std::nullopt_t); -template () - << std::declval())> -raw_ostream &operator<<(raw_ostream &OS, const Optional &O) { - if (O) - OS << *O; - else - OS << std::nullopt; - return OS; -} - template () << std::declval())> raw_ostream &operator<<(raw_ostream &OS, const std::optional &O) { diff --git a/llvm/include/llvm/Testing/Support/SupportHelpers.h b/llvm/include/llvm/Testing/Support/SupportHelpers.h --- a/llvm/include/llvm/Testing/Support/SupportHelpers.h +++ b/llvm/include/llvm/Testing/Support/SupportHelpers.h @@ -69,12 +69,6 @@ new Impl(::testing::SafeMatcherCast(ValueMatcher))); } - template - operator ::testing::Matcher &>() const { - return ::testing::MakeMatcher( - new Impl>(::testing::SafeMatcherCast(ValueMatcher))); - } - template > class Impl : public ::testing::MatcherInterface { public: diff --git a/llvm/include/llvm/Transforms/Scalar/Float2Int.h b/llvm/include/llvm/Transforms/Scalar/Float2Int.h --- a/llvm/include/llvm/Transforms/Scalar/Float2Int.h +++ b/llvm/include/llvm/Transforms/Scalar/Float2Int.h @@ -25,7 +25,6 @@ class Function; class Instruction; class LLVMContext; -template class Optional; class Type; class Value; diff --git a/llvm/include/llvm/Transforms/Utils/LoopUtils.h b/llvm/include/llvm/Transforms/Utils/LoopUtils.h --- a/llvm/include/llvm/Transforms/Utils/LoopUtils.h +++ b/llvm/include/llvm/Transforms/Utils/LoopUtils.h @@ -47,7 +47,6 @@ const RuntimeCheckingPtrGroup *> RuntimePointerCheck; -template class Optional; template class SmallSetVector; template class SmallPriorityWorklist; diff --git a/llvm/lib/CodeGen/RegAllocGreedy.h b/llvm/lib/CodeGen/RegAllocGreedy.h --- a/llvm/lib/CodeGen/RegAllocGreedy.h +++ b/llvm/lib/CodeGen/RegAllocGreedy.h @@ -80,7 +80,7 @@ unsigned NextCascade = 1; public: - ExtraRegInfo() = default; + ExtraRegInfo() {} ExtraRegInfo(const ExtraRegInfo &) = delete; LiveRangeStage getStage(Register Reg) const { return Info[Reg].Stage; } diff --git a/llvm/unittests/ADT/CMakeLists.txt b/llvm/unittests/ADT/CMakeLists.txt --- a/llvm/unittests/ADT/CMakeLists.txt +++ b/llvm/unittests/ADT/CMakeLists.txt @@ -49,7 +49,6 @@ MappedIteratorTest.cpp MapVectorTest.cpp MoveOnly.cpp - OptionalTest.cpp PackedVectorTest.cpp PointerEmbeddedIntTest.cpp PointerIntPairTest.cpp diff --git a/llvm/unittests/ADT/OptionalTest.cpp b/llvm/unittests/ADT/OptionalTest.cpp deleted file mode 100644 --- a/llvm/unittests/ADT/OptionalTest.cpp +++ /dev/null @@ -1,803 +0,0 @@ -//===- llvm/unittest/ADT/OptionalTest.cpp - Optional unit tests -----------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "llvm/ADT/Optional.h" -#include "llvm/ADT/SmallString.h" -#include "llvm/ADT/StringMap.h" -#include "llvm/Support/raw_ostream.h" -#include "MoveOnly.h" -#include "gtest/gtest-spi.h" -#include "gtest/gtest.h" - -#include -#include - -using namespace llvm; - -static_assert(std::is_trivially_copyable_v>, - "trivially copyable"); - -static_assert(std::is_trivially_copyable_v>>, - "trivially copyable"); - -void OptionalWorksInConstexpr() { - constexpr auto x1 = Optional(); - constexpr Optional x2{}; - static_assert(!x1.has_value() && !x2.has_value(), - "Default construction and hasValue() are contexpr"); - static_assert(!x1.has_value() && !x2.has_value(), - "Default construction and hasValue() are contexpr"); - constexpr auto y1 = Optional(3); - constexpr Optional y2{3}; - static_assert(*y1 == *y2 && *y1 == 3, - "Construction with value and getValue() are constexpr"); - static_assert(*y1 == *y2 && *y1 == 3, - "Construction with value and getValue() are constexpr"); - static_assert(Optional{3} >= 2 && Optional{1} < Optional{2}, - "Comparisons work in constexpr"); -} - -namespace { - -struct NonDefaultConstructible { - static unsigned CopyConstructions; - static unsigned Destructions; - static unsigned CopyAssignments; - explicit NonDefaultConstructible(int) { - } - NonDefaultConstructible(const NonDefaultConstructible&) { - ++CopyConstructions; - } - NonDefaultConstructible &operator=(const NonDefaultConstructible&) { - ++CopyAssignments; - return *this; - } - ~NonDefaultConstructible() { - ++Destructions; - } - static void ResetCounts() { - CopyConstructions = 0; - Destructions = 0; - CopyAssignments = 0; - } -}; - -unsigned NonDefaultConstructible::CopyConstructions = 0; -unsigned NonDefaultConstructible::Destructions = 0; -unsigned NonDefaultConstructible::CopyAssignments = 0; - -static_assert(!std::is_trivially_copyable_v>, - "not trivially copyable"); - -TEST(OptionalTest, NonDefaultConstructibleTest) { - Optional O; - EXPECT_FALSE(O); -} - -TEST(OptionalTest, ResetTest) { - NonDefaultConstructible::ResetCounts(); - Optional O(NonDefaultConstructible(3)); - EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions); - EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); - EXPECT_EQ(1u, NonDefaultConstructible::Destructions); - NonDefaultConstructible::ResetCounts(); - O.reset(); - EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions); - EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); - EXPECT_EQ(1u, NonDefaultConstructible::Destructions); -} - -TEST(OptionalTest, InitializationLeakTest) { - NonDefaultConstructible::ResetCounts(); - Optional(NonDefaultConstructible(3)); - EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions); - EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); - EXPECT_EQ(2u, NonDefaultConstructible::Destructions); -} - -TEST(OptionalTest, CopyConstructionTest) { - NonDefaultConstructible::ResetCounts(); - { - Optional A(NonDefaultConstructible(3)); - EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions); - EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); - EXPECT_EQ(1u, NonDefaultConstructible::Destructions); - NonDefaultConstructible::ResetCounts(); - Optional B(A); - EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions); - EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); - EXPECT_EQ(0u, NonDefaultConstructible::Destructions); - NonDefaultConstructible::ResetCounts(); - } - EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions); - EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); - EXPECT_EQ(2u, NonDefaultConstructible::Destructions); -} - -TEST(OptionalTest, ConstructingCopyAssignmentTest) { - NonDefaultConstructible::ResetCounts(); - { - Optional A(NonDefaultConstructible(3)); - Optional B; - EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions); - EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); - EXPECT_EQ(1u, NonDefaultConstructible::Destructions); - NonDefaultConstructible::ResetCounts(); - B = A; - EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions); - EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); - EXPECT_EQ(0u, NonDefaultConstructible::Destructions); - NonDefaultConstructible::ResetCounts(); - } - EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions); - EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); - EXPECT_EQ(2u, NonDefaultConstructible::Destructions); -} - -TEST(OptionalTest, CopyingCopyAssignmentTest) { - NonDefaultConstructible::ResetCounts(); - { - Optional A(NonDefaultConstructible(3)); - Optional B(NonDefaultConstructible(4)); - EXPECT_EQ(2u, NonDefaultConstructible::CopyConstructions); - EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); - EXPECT_EQ(2u, NonDefaultConstructible::Destructions); - NonDefaultConstructible::ResetCounts(); - B = A; - EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions); - EXPECT_EQ(1u, NonDefaultConstructible::CopyAssignments); - EXPECT_EQ(0u, NonDefaultConstructible::Destructions); - NonDefaultConstructible::ResetCounts(); - } - EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions); - EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); - EXPECT_EQ(2u, NonDefaultConstructible::Destructions); -} - -TEST(OptionalTest, DeletingCopyAssignmentTest) { - NonDefaultConstructible::ResetCounts(); - { - Optional A; - Optional B(NonDefaultConstructible(3)); - EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions); - EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); - EXPECT_EQ(1u, NonDefaultConstructible::Destructions); - NonDefaultConstructible::ResetCounts(); - B = A; - EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions); - EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); - EXPECT_EQ(1u, NonDefaultConstructible::Destructions); - NonDefaultConstructible::ResetCounts(); - } - EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions); - EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); - EXPECT_EQ(0u, NonDefaultConstructible::Destructions); -} - -TEST(OptionalTest, NullCopyConstructionTest) { - NonDefaultConstructible::ResetCounts(); - { - Optional A; - Optional B; - EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions); - EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); - EXPECT_EQ(0u, NonDefaultConstructible::Destructions); - NonDefaultConstructible::ResetCounts(); - B = A; - EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions); - EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); - EXPECT_EQ(0u, NonDefaultConstructible::Destructions); - NonDefaultConstructible::ResetCounts(); - } - EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions); - EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); - EXPECT_EQ(0u, NonDefaultConstructible::Destructions); -} - -TEST(OptionalTest, InPlaceConstructionNonDefaultConstructibleTest) { - NonDefaultConstructible::ResetCounts(); - { Optional A{std::in_place, 1}; } - EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions); - EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); - EXPECT_EQ(1u, NonDefaultConstructible::Destructions); -} - -TEST(OptionalTest, GetValueOr) { - Optional A; - EXPECT_EQ(42, A.value_or(42)); - - A = 5; - EXPECT_EQ(5, A.value_or(42)); -} - -struct MultiArgConstructor { - int x, y; - MultiArgConstructor(int x, int y) : x(x), y(y) {} - explicit MultiArgConstructor(int x, bool positive) - : x(x), y(positive ? x : -x) {} - - MultiArgConstructor(const MultiArgConstructor &) = delete; - MultiArgConstructor(MultiArgConstructor &&) = delete; - MultiArgConstructor &operator=(const MultiArgConstructor &) = delete; - MultiArgConstructor &operator=(MultiArgConstructor &&) = delete; - - friend bool operator==(const MultiArgConstructor &LHS, - const MultiArgConstructor &RHS) { - return LHS.x == RHS.x && LHS.y == RHS.y; - } - - static unsigned Destructions; - ~MultiArgConstructor() { - ++Destructions; - } - static void ResetCounts() { - Destructions = 0; - } -}; -unsigned MultiArgConstructor::Destructions = 0; - -static_assert(!std::is_trivially_copyable_v>, - "not trivially copyable"); - -TEST(OptionalTest, Emplace) { - MultiArgConstructor::ResetCounts(); - Optional A; - - A.emplace(1, 2); - EXPECT_TRUE(A.has_value()); - EXPECT_TRUE(A.has_value()); - EXPECT_EQ(1, A->x); - EXPECT_EQ(2, A->y); - EXPECT_EQ(0u, MultiArgConstructor::Destructions); - - A.emplace(5, false); - EXPECT_TRUE(A.has_value()); - EXPECT_TRUE(A.has_value()); - EXPECT_EQ(5, A->x); - EXPECT_EQ(-5, A->y); - EXPECT_EQ(1u, MultiArgConstructor::Destructions); -} - -TEST(OptionalTest, InPlaceConstructionMultiArgConstructorTest) { - MultiArgConstructor::ResetCounts(); - { - Optional A{std::in_place, 1, 2}; - EXPECT_TRUE(A.has_value()); - EXPECT_TRUE(A.has_value()); - EXPECT_EQ(1, A->x); - EXPECT_EQ(2, A->y); - Optional B{std::in_place, 5, false}; - EXPECT_TRUE(B.has_value()); - EXPECT_TRUE(B.has_value()); - EXPECT_EQ(5, B->x); - EXPECT_EQ(-5, B->y); - EXPECT_EQ(0u, MultiArgConstructor::Destructions); - } - EXPECT_EQ(2u, MultiArgConstructor::Destructions); -} - -TEST(OptionalTest, InPlaceConstructionAndEmplaceEquivalentTest) { - MultiArgConstructor::ResetCounts(); - { - Optional A{std::in_place, 1, 2}; - Optional B; - B.emplace(1, 2); - EXPECT_EQ(0u, MultiArgConstructor::Destructions); - ASSERT_EQ(A, B); - } - EXPECT_EQ(2u, MultiArgConstructor::Destructions); -} - -static_assert(!std::is_trivially_copyable_v>, - "not trivially copyable"); - -TEST(OptionalTest, MoveOnlyNull) { - MoveOnly::ResetCounts(); - Optional O; - EXPECT_EQ(0u, MoveOnly::MoveConstructions); - EXPECT_EQ(0u, MoveOnly::MoveAssignments); - EXPECT_EQ(0u, MoveOnly::Destructions); -} - -TEST(OptionalTest, MoveOnlyConstruction) { - MoveOnly::ResetCounts(); - Optional O(MoveOnly(3)); - EXPECT_TRUE((bool)O); - EXPECT_EQ(3, O->val); - EXPECT_EQ(1u, MoveOnly::MoveConstructions); - EXPECT_EQ(0u, MoveOnly::MoveAssignments); - EXPECT_EQ(1u, MoveOnly::Destructions); -} - -TEST(OptionalTest, MoveOnlyMoveConstruction) { - Optional A(MoveOnly(3)); - MoveOnly::ResetCounts(); - Optional B(std::move(A)); - EXPECT_TRUE((bool)A); - EXPECT_TRUE((bool)B); - EXPECT_EQ(3, B->val); - EXPECT_EQ(1u, MoveOnly::MoveConstructions); - EXPECT_EQ(0u, MoveOnly::MoveAssignments); - EXPECT_EQ(0u, MoveOnly::Destructions); -} - -TEST(OptionalTest, MoveOnlyAssignment) { - MoveOnly::ResetCounts(); - Optional O; - O = MoveOnly(3); - EXPECT_TRUE((bool)O); - EXPECT_EQ(3, O->val); - EXPECT_EQ(1u, MoveOnly::MoveConstructions); - EXPECT_EQ(0u, MoveOnly::MoveAssignments); - EXPECT_EQ(1u, MoveOnly::Destructions); -} - -TEST(OptionalTest, MoveOnlyInitializingAssignment) { - Optional A(MoveOnly(3)); - Optional B; - MoveOnly::ResetCounts(); - B = std::move(A); - EXPECT_TRUE((bool)A); - EXPECT_TRUE((bool)B); - EXPECT_EQ(3, B->val); - EXPECT_EQ(1u, MoveOnly::MoveConstructions); - EXPECT_EQ(0u, MoveOnly::MoveAssignments); - EXPECT_EQ(0u, MoveOnly::Destructions); -} - -TEST(OptionalTest, MoveOnlyNullingAssignment) { - Optional A; - Optional B(MoveOnly(3)); - MoveOnly::ResetCounts(); - B = std::move(A); - EXPECT_FALSE((bool)A); - EXPECT_FALSE((bool)B); - EXPECT_EQ(0u, MoveOnly::MoveConstructions); - EXPECT_EQ(0u, MoveOnly::MoveAssignments); - EXPECT_EQ(1u, MoveOnly::Destructions); -} - -TEST(OptionalTest, MoveOnlyAssigningAssignment) { - Optional A(MoveOnly(3)); - Optional B(MoveOnly(4)); - MoveOnly::ResetCounts(); - B = std::move(A); - EXPECT_TRUE((bool)A); - EXPECT_TRUE((bool)B); - EXPECT_EQ(3, B->val); - EXPECT_EQ(0u, MoveOnly::MoveConstructions); - EXPECT_EQ(1u, MoveOnly::MoveAssignments); - EXPECT_EQ(0u, MoveOnly::Destructions); -} - -struct Immovable { - static unsigned Constructions; - static unsigned Destructions; - int val; - explicit Immovable(int val) : val(val) { - ++Constructions; - } - ~Immovable() { - ++Destructions; - } - static void ResetCounts() { - Constructions = 0; - Destructions = 0; - } -private: - // This should disable all move/copy operations. - Immovable(Immovable&& other) = delete; -}; - -unsigned Immovable::Constructions = 0; -unsigned Immovable::Destructions = 0; - -static_assert(!std::is_trivially_copyable_v>, - "not trivially copyable"); - -TEST(OptionalTest, ImmovableEmplace) { - Optional A; - Immovable::ResetCounts(); - A.emplace(4); - EXPECT_TRUE((bool)A); - EXPECT_EQ(4, A->val); - EXPECT_EQ(1u, Immovable::Constructions); - EXPECT_EQ(0u, Immovable::Destructions); -} - -TEST(OptionalTest, ImmovableInPlaceConstruction) { - Immovable::ResetCounts(); - Optional A{std::in_place, 4}; - EXPECT_TRUE((bool)A); - EXPECT_EQ(4, A->val); - EXPECT_EQ(1u, Immovable::Constructions); - EXPECT_EQ(0u, Immovable::Destructions); -} - -// Craft a class which is_trivially_copyable, but not -// is_trivially_copy_constructible. -struct NonTCopy { - NonTCopy() = default; - - // Delete the volatile copy constructor to engage the "rule of 3" and delete - // any unspecified copy assignment or constructor. - NonTCopy(volatile NonTCopy const &) = delete; - - // Leave the non-volatile default copy constructor unspecified (deleted by - // rule of 3) - - // This template can serve as the copy constructor, but isn't chosen - // by =default in a class with a 'NonTCopy' member. - template - NonTCopy(Self const &Other) : Val(Other.Val) {} - - NonTCopy &operator=(NonTCopy const &) = default; - - int Val{0}; -}; - -#if defined(_MSC_VER) && _MSC_VER >= 1927 && !defined(__clang__) -// Currently only true on recent MSVC releases. -static_assert(std::is_trivially_copyable::value, - "Expect NonTCopy to be trivially copyable"); - -static_assert(!std::is_trivially_copy_constructible::value, - "Expect NonTCopy not to be trivially copy constructible."); -#endif // defined(_MSC_VER) && _MSC_VER >= 1927 - -TEST(OptionalTest, DeletedCopyConstructor) { - - // Expect compile to fail if 'trivial' version of - // optional_detail::OptionalStorage is chosen. - using NonTCopyOptT = Optional; - NonTCopyOptT NonTCopy1; - - // Check that the Optional can be copy constructed. - NonTCopyOptT NonTCopy2{NonTCopy1}; - - // Check that the Optional can be copy assigned. - NonTCopy1 = NonTCopy2; -} - -// Craft a class which is_trivially_copyable, but not -// is_trivially_copy_assignable. -class NonTAssign { -public: - NonTAssign() = default; - NonTAssign(NonTAssign const &) = default; - - // Delete the volatile copy assignment to engage the "rule of 3" and delete - // any unspecified copy assignment or constructor. - NonTAssign &operator=(volatile NonTAssign const &) = delete; - - // Leave the non-volatile default copy assignment unspecified (deleted by rule - // of 3). - - // This template can serve as the copy assignment, but isn't chosen - // by =default in a class with a 'NonTAssign' member. - template - NonTAssign &operator=(Self const &Other) { - A = Other.A; - return *this; - } - - int A{0}; -}; - -#if defined(_MSC_VER) && _MSC_VER >= 1927 && !defined(__clang__) -// Currently only true on recent MSVC releases. -static_assert(std::is_trivially_copyable::value, - "Expect NonTAssign to be trivially copyable"); - -static_assert(!std::is_trivially_copy_assignable::value, - "Expect NonTAssign not to be trivially assignable."); -#endif // defined(_MSC_VER) && _MSC_VER >= 1927 - -TEST(OptionalTest, DeletedCopyAssignment) { - - // Expect compile to fail if 'trivial' version of - // optional_detail::OptionalStorage is chosen. - using NonTAssignOptT = Optional; - NonTAssignOptT NonTAssign1; - - // Check that the Optional can be copy constructed. - NonTAssignOptT NonTAssign2{NonTAssign1}; - - // Check that the Optional can be copy assigned. - NonTAssign1 = NonTAssign2; -} - -struct NoTMove { - NoTMove() = default; - NoTMove(NoTMove const &) = default; - NoTMove &operator=(NoTMove const &) = default; - - // Delete move constructor / assignment. Compiler should fall-back to the - // trivial copy constructor / assignment in the trivial OptionalStorage - // specialization. - NoTMove(NoTMove &&) = delete; - NoTMove &operator=(NoTMove &&) = delete; - - int Val{0}; -}; - -TEST(OptionalTest, DeletedMoveConstructor) { - using NoTMoveOptT = Optional; - - NoTMoveOptT NonTMove1; - NoTMoveOptT NonTMove2{std::move(NonTMove1)}; - - NonTMove1 = std::move(NonTMove2); - - static_assert( - std::is_trivially_copyable_v, - "Expect Optional to still use the trivial specialization " - "of OptionalStorage despite the deleted move constructor / assignment."); -} - -class NoCopyStringMap { -public: - NoCopyStringMap() = default; - -private: - llvm::StringMap> Map; -}; - -TEST(OptionalTest, DeletedCopyStringMap) { - // Old versions of gcc (7.3 and prior) instantiate the copy constructor when - // std::is_trivially_copyable is instantiated. This test will fail - // compilation if std::is_trivially_copyable is used in the OptionalStorage - // specialization condition by gcc <= 7.3. - Optional TestInstantiation; -} - -TEST(OptionalTest, MoveValueOr) { - Optional A; - - MoveOnly::ResetCounts(); - EXPECT_EQ(42, std::move(A).value_or(MoveOnly(42)).val); - EXPECT_EQ(1u, MoveOnly::MoveConstructions); - EXPECT_EQ(0u, MoveOnly::MoveAssignments); - EXPECT_EQ(2u, MoveOnly::Destructions); - - A = MoveOnly(5); - MoveOnly::ResetCounts(); - EXPECT_EQ(5, std::move(A).value_or(MoveOnly(42)).val); - EXPECT_EQ(1u, MoveOnly::MoveConstructions); - EXPECT_EQ(0u, MoveOnly::MoveAssignments); - EXPECT_EQ(2u, MoveOnly::Destructions); -} - -struct EqualTo { - template static bool apply(const T &X, const U &Y) { - return X == Y; - } -}; - -struct NotEqualTo { - template static bool apply(const T &X, const U &Y) { - return X != Y; - } -}; - -struct Less { - template static bool apply(const T &X, const U &Y) { - return X < Y; - } -}; - -struct Greater { - template static bool apply(const T &X, const U &Y) { - return X > Y; - } -}; - -struct LessEqual { - template static bool apply(const T &X, const U &Y) { - return X <= Y; - } -}; - -struct GreaterEqual { - template static bool apply(const T &X, const U &Y) { - return X >= Y; - } -}; - -template -void CheckRelation(const Optional &Lhs, const Optional &Rhs, - bool Expected) { - EXPECT_EQ(Expected, OperatorT::apply(Lhs, Rhs)); - - if (Lhs) - EXPECT_EQ(Expected, OperatorT::apply(*Lhs, Rhs)); - else - EXPECT_EQ(Expected, OperatorT::apply(std::nullopt, Rhs)); - - if (Rhs) - EXPECT_EQ(Expected, OperatorT::apply(Lhs, *Rhs)); - else - EXPECT_EQ(Expected, OperatorT::apply(Lhs, std::nullopt)); -} - -struct EqualityMock {}; -const Optional NoneEq, EqualityLhs((EqualityMock())), - EqualityRhs((EqualityMock())); -bool IsEqual; - -bool operator==(const EqualityMock &Lhs, const EqualityMock &Rhs) { - EXPECT_EQ(&*EqualityLhs, &Lhs); - EXPECT_EQ(&*EqualityRhs, &Rhs); - return IsEqual; -} - -TEST(OptionalTest, OperatorEqual) { - CheckRelation(NoneEq, NoneEq, true); - CheckRelation(NoneEq, EqualityRhs, false); - CheckRelation(EqualityLhs, NoneEq, false); - - IsEqual = false; - CheckRelation(EqualityLhs, EqualityRhs, IsEqual); - IsEqual = true; - CheckRelation(EqualityLhs, EqualityRhs, IsEqual); -} - -TEST(OptionalTest, OperatorNotEqual) { - CheckRelation(NoneEq, NoneEq, false); - CheckRelation(NoneEq, EqualityRhs, true); - CheckRelation(EqualityLhs, NoneEq, true); - - IsEqual = false; - CheckRelation(EqualityLhs, EqualityRhs, !IsEqual); - IsEqual = true; - CheckRelation(EqualityLhs, EqualityRhs, !IsEqual); -} - -struct InequalityMock {}; -const Optional NoneIneq, InequalityLhs((InequalityMock())), - InequalityRhs((InequalityMock())); -bool IsLess; - -bool operator<(const InequalityMock &Lhs, const InequalityMock &Rhs) { - EXPECT_EQ(&*InequalityLhs, &Lhs); - EXPECT_EQ(&*InequalityRhs, &Rhs); - return IsLess; -} - -TEST(OptionalTest, OperatorLess) { - CheckRelation(NoneIneq, NoneIneq, false); - CheckRelation(NoneIneq, InequalityRhs, true); - CheckRelation(InequalityLhs, NoneIneq, false); - - IsLess = false; - CheckRelation(InequalityLhs, InequalityRhs, IsLess); - IsLess = true; - CheckRelation(InequalityLhs, InequalityRhs, IsLess); -} - -TEST(OptionalTest, OperatorGreater) { - CheckRelation(NoneIneq, NoneIneq, false); - CheckRelation(NoneIneq, InequalityRhs, false); - CheckRelation(InequalityLhs, NoneIneq, true); - - IsLess = false; - CheckRelation(InequalityRhs, InequalityLhs, IsLess); - IsLess = true; - CheckRelation(InequalityRhs, InequalityLhs, IsLess); -} - -TEST(OptionalTest, OperatorLessEqual) { - CheckRelation(NoneIneq, NoneIneq, true); - CheckRelation(NoneIneq, InequalityRhs, true); - CheckRelation(InequalityLhs, NoneIneq, false); - - IsLess = false; - CheckRelation(InequalityRhs, InequalityLhs, !IsLess); - IsLess = true; - CheckRelation(InequalityRhs, InequalityLhs, !IsLess); -} - -TEST(OptionalTest, OperatorGreaterEqual) { - CheckRelation(NoneIneq, NoneIneq, true); - CheckRelation(NoneIneq, InequalityRhs, false); - CheckRelation(InequalityLhs, NoneIneq, true); - - IsLess = false; - CheckRelation(InequalityLhs, InequalityRhs, !IsLess); - IsLess = true; - CheckRelation(InequalityLhs, InequalityRhs, !IsLess); -} - -struct ComparableAndStreamable { - friend bool operator==(ComparableAndStreamable, - ComparableAndStreamable) LLVM_ATTRIBUTE_USED { - return true; - } - - friend raw_ostream &operator<<(raw_ostream &OS, ComparableAndStreamable) { - return OS << "ComparableAndStreamable"; - } - - static Optional get() { - return ComparableAndStreamable(); - } -}; - -TEST(OptionalTest, StreamOperator) { - auto to_string = [](Optional O) { - SmallString<16> S; - raw_svector_ostream OS(S); - OS << O; - return S; - }; - EXPECT_EQ("ComparableAndStreamable", - to_string(ComparableAndStreamable::get())); - EXPECT_EQ("None", to_string(std::nullopt)); -} - -struct Comparable { - friend bool operator==(Comparable, Comparable) LLVM_ATTRIBUTE_USED { - return true; - } - static Optional get() { return Comparable(); } -}; - -TEST(OptionalTest, UseInUnitTests) { - // Test that we invoke the streaming operators when pretty-printing values in - // EXPECT macros. - EXPECT_NONFATAL_FAILURE( - EXPECT_EQ(std::nullopt, ComparableAndStreamable::get()), - "Expected equality of these values:\n" - " std::nullopt\n" - " Which is: None\n" - " ComparableAndStreamable::get()\n" - " Which is: ComparableAndStreamable"); - - // Test that it is still possible to compare objects which do not have a - // custom streaming operator. - EXPECT_NONFATAL_FAILURE(EXPECT_EQ(std::nullopt, Comparable::get()), "object"); -} - -TEST(OptionalTest, HashValue) { - // Check that None, false, and true all hash differently. - Optional B, B0 = false, B1 = true; - EXPECT_NE(hash_value(B0), hash_value(B)); - EXPECT_NE(hash_value(B1), hash_value(B)); - EXPECT_NE(hash_value(B1), hash_value(B0)); - - // Check that None, 0, and 1 all hash differently. - Optional I, I0 = 0, I1 = 1; - EXPECT_NE(hash_value(I0), hash_value(I)); - EXPECT_NE(hash_value(I1), hash_value(I)); - EXPECT_NE(hash_value(I1), hash_value(I0)); - - // Check None hash the same way regardless of type. - EXPECT_EQ(hash_value(B), hash_value(I)); -} - -struct NotTriviallyCopyable { - NotTriviallyCopyable(); // Constructor out-of-line. - virtual ~NotTriviallyCopyable() = default; - Optional MO; -}; - -TEST(OptionalTest, GCCIsTriviallyMoveConstructibleCompat) { - Optional V; - EXPECT_FALSE(V); -} - -TEST(OptionalTest, DeductionGuide) { - Optional V = MoveOnly(1); - EXPECT_TRUE(V); - EXPECT_EQ(V->val, 1); -} - -static_assert( - std::is_same_v, decltype(Optional(MoveOnly(1)))>); - -} // end anonymous namespace diff --git a/llvm/unittests/Support/TypeTraitsTest.cpp b/llvm/unittests/Support/TypeTraitsTest.cpp --- a/llvm/unittests/Support/TypeTraitsTest.cpp +++ b/llvm/unittests/Support/TypeTraitsTest.cpp @@ -118,7 +118,10 @@ TrivialityTester(); TrivialityTester, true, true>(); TrivialityTester, true, true>(); +#if defined(_LIBCPP_VERSION) || \ + (defined(_GLIBCXX_RELEASE) && _GLIBCXX_RELEASE >= 8) TrivialityTester, true, true>(); +#endif } } // namespace triviality diff --git a/mlir/include/mlir/Bindings/Python/PybindAdaptors.h b/mlir/include/mlir/Bindings/Python/PybindAdaptors.h --- a/mlir/include/mlir/Bindings/Python/PybindAdaptors.h +++ b/mlir/include/mlir/Bindings/Python/PybindAdaptors.h @@ -35,9 +35,6 @@ namespace pybind11 { namespace detail { -template -struct type_caster> : optional_caster> {}; - /// Helper to convert a presumed MLIR API object to a capsule, accepting either /// an explicit Capsule (which can happen when two C APIs are communicating /// directly via Python) or indirectly by querying the MLIR_PYTHON_CAPI_PTR_ATTR diff --git a/mlir/include/mlir/IR/Visitors.h b/mlir/include/mlir/IR/Visitors.h --- a/mlir/include/mlir/IR/Visitors.h +++ b/mlir/include/mlir/IR/Visitors.h @@ -46,6 +46,7 @@ WalkResult(InFlightDiagnostic &&) : result(Interrupt) {} bool operator==(const WalkResult &rhs) const { return result == rhs.result; } + bool operator!=(const WalkResult &rhs) const { return result != rhs.result; } static WalkResult interrupt() { return {Interrupt}; } static WalkResult advance() { return {Advance}; } diff --git a/mlir/include/mlir/Support/LLVM.h b/mlir/include/mlir/Support/LLVM.h --- a/mlir/include/mlir/Support/LLVM.h +++ b/mlir/include/mlir/Support/LLVM.h @@ -58,8 +58,7 @@ class MallocAllocator; template class MutableArrayRef; -template -class Optional; +template using Optional = std::optional; template class PointerUnion; template diff --git a/mlir/lib/Bindings/Python/PybindUtils.h b/mlir/lib/Bindings/Python/PybindUtils.h --- a/mlir/lib/Bindings/Python/PybindUtils.h +++ b/mlir/lib/Bindings/Python/PybindUtils.h @@ -94,9 +94,6 @@ return pybind11::cast(src, policy); } }; - -template -struct type_caster> : optional_caster> {}; } // namespace detail } // namespace pybind11 diff --git a/mlir/lib/Dialect/GPU/Transforms/SerializeToHsaco.cpp b/mlir/lib/Dialect/GPU/Transforms/SerializeToHsaco.cpp --- a/mlir/lib/Dialect/GPU/Transforms/SerializeToHsaco.cpp +++ b/mlir/lib/Dialect/GPU/Transforms/SerializeToHsaco.cpp @@ -179,7 +179,7 @@ ret.push_back(std::move(library)); } - return ret; + return std::move(ret); } std::unique_ptr