diff --git a/clang-tools-extra/clang-doc/Generators.cpp b/clang-tools-extra/clang-doc/Generators.cpp index fafe41eebb77..aac9b18f351b 100644 --- a/clang-tools-extra/clang-doc/Generators.cpp +++ b/clang-tools-extra/clang-doc/Generators.cpp @@ -5,61 +5,61 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "Generators.h" #include "support/File.h" #include "llvm/Support/TimeProfiler.h" LLVM_INSTANTIATE_REGISTRY(clang::doc::GeneratorRegistry) using namespace llvm; using namespace llvm::json; using namespace llvm::mustache; namespace clang { namespace doc { llvm::Expected> findGeneratorByName(llvm::StringRef Format) { for (const auto &Generator : GeneratorRegistry::entries()) { if (Generator.getName() != Format) continue; return Generator.instantiate(); } return createStringError(llvm::inconvertibleErrorCode(), "can't find generator: " + Format); } // Enum conversion -std::string getTagType(TagTypeKind AS) { +std::string_view getTagType(TagTypeKind AS) { switch (AS) { case TagTypeKind::Class: return "class"; case TagTypeKind::Union: return "union"; case TagTypeKind::Interface: return "interface"; case TagTypeKind::Struct: return "struct"; case TagTypeKind::Enum: return "enum"; } llvm_unreachable("Unknown TagTypeKind"); } Error createFileOpenError(StringRef FileName, std::error_code EC) { return createFileError("cannot open file " + FileName, EC); } Error MustacheGenerator::setupTemplate( std::unique_ptr &Template, StringRef TemplatePath, std::vector> Partials) { auto T = MustacheTemplateFile::createMustacheFile(TemplatePath); if (Error Err = T.takeError()) return Err; Template = std::move(T.get()); for (const auto &[Name, FileName] : Partials) if (auto Err = Template->registerPartialFile(Name, FileName)) return Err; return Error::success(); diff --git a/clang-tools-extra/clang-doc/Generators.h b/clang-tools-extra/clang-doc/Generators.h index a50f1ac25eda..f7ec88816514 100644 --- a/clang-tools-extra/clang-doc/Generators.h +++ b/clang-tools-extra/clang-doc/Generators.h @@ -24,61 +24,61 @@ namespace doc { // Abstract base class for generators. // This is expected to be implemented and exposed via the GeneratorRegistry. class Generator { public: virtual ~Generator() = default; // Write out the decl info for the objects in the given map in the specified // format. virtual llvm::Error generateDocumentation( StringRef RootDir, llvm::StringMap> Infos, const ClangDocContext &CDCtx, std::string DirName = "") = 0; // This function writes a file with the index previously constructed. // It can be overwritten by any of the inherited generators. // If the override method wants to run this it should call // Generator::createResources(CDCtx); virtual llvm::Error createResources(ClangDocContext &CDCtx); // Write out one specific decl info to the destination stream. virtual llvm::Error generateDocForInfo(Info *I, llvm::raw_ostream &OS, const ClangDocContext &CDCtx) = 0; static void addInfoToIndex(Index &Idx, const doc::Info *Info); }; typedef llvm::Registry GeneratorRegistry; llvm::Expected> findGeneratorByName(llvm::StringRef Format); -std::string getTagType(TagTypeKind AS); +std::string_view getTagType(TagTypeKind AS); llvm::Error createFileOpenError(StringRef FileName, std::error_code EC); class MustacheTemplateFile { llvm::BumpPtrAllocator Allocator; llvm::StringSaver Saver; llvm::mustache::MustacheContext Ctx; llvm::mustache::Template T; std::unique_ptr Buffer; public: static Expected> createMustacheFile(StringRef FileName) { llvm::ErrorOr> BufferOrError = llvm::MemoryBuffer::getFile(FileName); if (auto EC = BufferOrError.getError()) return createFileOpenError(FileName, EC); return std::make_unique( std::move(BufferOrError.get())); } llvm::Error registerPartialFile(StringRef Name, StringRef FileName) { llvm::ErrorOr> BufferOrError = llvm::MemoryBuffer::getFile(FileName); if (auto EC = BufferOrError.getError()) return createFileOpenError(FileName, EC); std::unique_ptr Buffer = std::move(BufferOrError.get()); StringRef FileContent = Buffer->getBuffer(); T.registerPartial(Name.str(), FileContent.str()); diff --git a/clang-tools-extra/clang-doc/JSONGenerator.cpp b/clang-tools-extra/clang-doc/JSONGenerator.cpp index 9c384ed7eead..0fa58918a93d 100644 --- a/clang-tools-extra/clang-doc/JSONGenerator.cpp +++ b/clang-tools-extra/clang-doc/JSONGenerator.cpp @@ -22,61 +22,61 @@ public: }; const char *JSONGenerator::Format = "json"; static void serializeInfo(const ConstraintInfo &I, Object &Obj); static void serializeInfo(const RecordInfo &I, Object &Obj, const std::optional &RepositoryUrl); static void serializeReference(const Reference &Ref, Object &ReferenceObj); template static void serializeArray(const Container &Records, Object &Obj, const std::string &Key, SerializationFunc SerializeInfo); // Convenience lambda to pass to serializeArray. // If a serializeInfo needs a RepositoryUrl, create a local lambda that captures // the optional. static auto SerializeInfoLambda = [](const auto &Info, Object &Object) { serializeInfo(Info, Object); }; static auto SerializeReferenceLambda = [](const auto &Ref, Object &Object) { serializeReference(Ref, Object); }; static void insertNonEmpty(StringRef Key, StringRef Value, Object &Obj) { if (!Value.empty()) Obj[Key] = Value; } -static std::string infoTypeToString(InfoType IT) { +static std::string_view infoTypeToString(InfoType IT) { switch (IT) { case InfoType::IT_default: return "default"; case InfoType::IT_namespace: return "namespace"; case InfoType::IT_record: return "record"; case InfoType::IT_function: return "function"; case InfoType::IT_enum: return "enum"; case InfoType::IT_typedef: return "typedef"; case InfoType::IT_concept: return "concept"; case InfoType::IT_variable: return "variable"; case InfoType::IT_friend: return "friend"; } llvm_unreachable("Unknown InfoType encountered."); } static json::Object serializeLocation(const Location &Loc, const std::optional RepositoryUrl) { Object LocationObj = Object(); LocationObj["LineNumber"] = Loc.StartLineNumber; LocationObj["Filename"] = Loc.Filename; diff --git a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp index ee4c44971887..93bbb0895863 100644 --- a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp +++ b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp @@ -101,61 +101,61 @@ URL of repository that hosts code. Used for links to definition locations.)"), llvm::cl::cat(ClangDocCategory)); static llvm::cl::opt RepositoryCodeLinePrefix( "repository-line-prefix", llvm::cl::desc("Prefix of line code for repository."), llvm::cl::cat(ClangDocCategory)); static llvm::cl::opt FTimeTrace("ftime-trace", llvm::cl::desc(R"( Turn on time profiler. Generates clang-doc-tracing.json)"), llvm::cl::init(false), llvm::cl::cat(ClangDocCategory)); enum OutputFormatTy { md, yaml, html, json }; static llvm::cl::opt FormatEnum("format", llvm::cl::desc("Format for outputted docs."), llvm::cl::values(clEnumValN(OutputFormatTy::yaml, "yaml", "Documentation in YAML format."), clEnumValN(OutputFormatTy::md, "md", "Documentation in MD format."), clEnumValN(OutputFormatTy::html, "html", "Documentation in HTML format."), clEnumValN(OutputFormatTy::json, "json", "Documentation in JSON format")), llvm::cl::init(OutputFormatTy::yaml), llvm::cl::cat(ClangDocCategory)); static llvm::ExitOnError ExitOnErr; -static std::string getFormatString() { +static std::string_view getFormatString() { switch (FormatEnum) { case OutputFormatTy::yaml: return "yaml"; case OutputFormatTy::md: return "md"; case OutputFormatTy::html: return "html"; case OutputFormatTy::json: return "json"; } llvm_unreachable("Unknown OutputFormatTy"); } // This function isn't referenced outside its translation unit, but it // can't use the "static" keyword because its address is used for // GetMainExecutable (since some platforms don't support taking the // address of main, and some platforms can't implement GetMainExecutable // without being given the address of a function in the main executable). static std::string getExecutablePath(const char *Argv0, void *MainAddr) { return llvm::sys::fs::getMainExecutable(Argv0, MainAddr); } // TODO: Rename this, since it only gets custom CSS/JS static llvm::Error getAssetFiles(clang::doc::ClangDocContext &CDCtx) { using DirIt = llvm::sys::fs::directory_iterator; std::error_code FileErr; llvm::SmallString<128> FilePath(UserAssetPath); for (DirIt DirStart = DirIt(UserAssetPath, FileErr), DirEnd; !FileErr && DirStart != DirEnd; DirStart.increment(FileErr)) { FilePath = DirStart->path(); diff --git a/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp b/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp index 9aa679a9bf8d..15e1e4dd4e79 100644 --- a/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp +++ b/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp @@ -22,61 +22,61 @@ #include #define DEBUG_TYPE "clang-tidy-options" using clang::tidy::ClangTidyOptions; using clang::tidy::FileFilter; using OptionsSource = clang::tidy::ClangTidyOptionsProvider::OptionsSource; LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(FileFilter) LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(FileFilter::LineRange) namespace llvm::yaml { // Map std::pair to a JSON array of size 2. template <> struct SequenceTraits { static size_t size(IO &IO, FileFilter::LineRange &Range) { return Range.first == 0 ? 0 : Range.second == 0 ? 1 : 2; } static unsigned &element(IO &IO, FileFilter::LineRange &Range, size_t Index) { if (Index > 1) IO.setError("Too many elements in line range."); return Index == 0 ? Range.first : Range.second; } }; template <> struct MappingTraits { static void mapping(IO &IO, FileFilter &File) { IO.mapRequired("name", File.Name); IO.mapOptional("lines", File.LineRanges); } - static std::string validate(IO &Io, FileFilter &File) { + static std::string_view validate(IO &Io, FileFilter &File) { if (File.Name.empty()) return "No file name specified"; for (const FileFilter::LineRange &Range : File.LineRanges) if (Range.first <= 0 || Range.second <= 0) return "Invalid line range"; return ""; } }; template <> struct MappingTraits { static void mapping(IO &IO, ClangTidyOptions::StringPair &KeyValue) { IO.mapRequired("key", KeyValue.first); IO.mapRequired("value", KeyValue.second); } }; namespace { struct NOptionMap { NOptionMap(IO &) {} NOptionMap(IO &, const ClangTidyOptions::OptionMap &OptionMap) { Options.reserve(OptionMap.size()); for (const auto &KeyValue : OptionMap) Options.emplace_back(std::string(KeyValue.getKey()), KeyValue.getValue().Value); } ClangTidyOptions::OptionMap denormalize(IO &) { ClangTidyOptions::OptionMap Map; for (const auto &KeyValue : Options) Map[KeyValue.first] = ClangTidyOptions::ClangTidyValue(KeyValue.second); diff --git a/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py b/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py index 59523fd13118..1ce0b2cd77b6 100755 --- a/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py +++ b/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py @@ -411,61 +411,61 @@ async def run_tidy( invocation, process.returncode, stdout.decode("UTF-8"), stderr.decode("UTF-8"), end - start, ) async def main() -> None: parser = argparse.ArgumentParser( description="Runs clang-tidy over all files " "in a compilation database. Requires " "clang-tidy and clang-apply-replacements in " "$PATH or in your build directory." ) parser.add_argument( "-allow-enabling-alpha-checkers", action="store_true", help="Allow alpha checkers from clang-analyzer.", ) parser.add_argument( "-clang-tidy-binary", metavar="PATH", help="Path to clang-tidy binary." ) parser.add_argument( "-clang-apply-replacements-binary", metavar="PATH", help="Path to clang-apply-replacements binary.", ) parser.add_argument( "-checks", - default=None, + default="-*,modernize-use-string-view", help="Checks filter, when not specified, use clang-tidy default.", ) config_group = parser.add_mutually_exclusive_group() config_group.add_argument( "-config", default=None, help="Specifies a configuration in YAML/JSON format: " " -config=\"{Checks: '*', " ' CheckOptions: {x: y}}" ' "When the value is empty, clang-tidy will " "attempt to find a file named .clang-tidy for " "each source file in its parent directories.", ) config_group.add_argument( "-config-file", default=None, help="Specify the path of .clang-tidy or custom config " "file: e.g. -config-file=/some/path/myTidyConfigFile. " "This option internally works exactly the same way as " "-config option after reading specified config file. " "Use either -config-file or -config, not both.", ) parser.add_argument( "-exclude-header-filter", default=None, help="Regular expression matching the names of the " "headers to exclude diagnostics from. Diagnostics from " "the main file of each translation unit are always " "displayed.", ) diff --git a/clang-tools-extra/clangd/DumpAST.cpp b/clang-tools-extra/clangd/DumpAST.cpp index cd409a2b930e..d7d2f8ac2604 100644 --- a/clang-tools-extra/clangd/DumpAST.cpp +++ b/clang-tools-extra/clangd/DumpAST.cpp @@ -101,137 +101,137 @@ class DumpVisitor : public RecursiveASTVisitor { template ().getSourceRange())> SourceRange getSourceRange(const T &Node) { return Node.getSourceRange(); } template ()->getSourceRange())> SourceRange getSourceRange(const T *Node) { return Node->getSourceRange(); } // TemplateName doesn't have a real Loc node type. SourceRange getSourceRange(const TemplateName &Node) { return SourceRange(); } // Attr just uses a weird method name. Maybe we should fix it instead? SourceRange getSourceRange(const Attr *Node) { return Node->getRange(); } // Kind is usually the class name, without the suffix ("Type" etc). // Where there's a set of variants instead, we use the 'Kind' enum values. std::string getKind(const Decl *D) { return D->getDeclKindName(); } std::string getKind(const Stmt *S) { std::string Result = S->getStmtClassName(); if (llvm::StringRef(Result).ends_with("Stmt") || llvm::StringRef(Result).ends_with("Expr")) Result.resize(Result.size() - 4); return Result; } std::string getKind(const TypeLoc &TL) { if (TL.getTypeLocClass() == TypeLoc::Qualified) return "Qualified"; return TL.getType()->getTypeClassName(); } - std::string getKind(const TemplateArgumentLoc &TAL) { + std::string_view getKind(const TemplateArgumentLoc &TAL) { switch (TAL.getArgument().getKind()) { #define TEMPLATE_ARGUMENT_KIND(X) \ case TemplateArgument::X: \ return #X TEMPLATE_ARGUMENT_KIND(Null); TEMPLATE_ARGUMENT_KIND(NullPtr); TEMPLATE_ARGUMENT_KIND(Expression); TEMPLATE_ARGUMENT_KIND(Integral); TEMPLATE_ARGUMENT_KIND(Pack); TEMPLATE_ARGUMENT_KIND(Type); TEMPLATE_ARGUMENT_KIND(Declaration); TEMPLATE_ARGUMENT_KIND(Template); TEMPLATE_ARGUMENT_KIND(TemplateExpansion); TEMPLATE_ARGUMENT_KIND(StructuralValue); #undef TEMPLATE_ARGUMENT_KIND } llvm_unreachable("Unhandled ArgKind enum"); } - std::string getKind(NestedNameSpecifierLoc NNSL) { + std::string_view getKind(NestedNameSpecifierLoc NNSL) { switch (NNSL.getNestedNameSpecifier().getKind()) { case NestedNameSpecifier::Kind::Null: llvm_unreachable("unexpected null nested name specifier"); #define NNS_KIND(X) \ case NestedNameSpecifier::Kind::X: \ return #X NNS_KIND(Namespace); NNS_KIND(Type); NNS_KIND(Global); NNS_KIND(MicrosoftSuper); #undef NNS_KIND } llvm_unreachable("Unhandled SpecifierKind enum"); } - std::string getKind(const CXXCtorInitializer *CCI) { + std::string_view getKind(const CXXCtorInitializer *CCI) { if (CCI->isBaseInitializer()) return "BaseInitializer"; if (CCI->isDelegatingInitializer()) return "DelegatingInitializer"; if (CCI->isAnyMemberInitializer()) return "MemberInitializer"; llvm_unreachable("Unhandled CXXCtorInitializer type"); } - std::string getKind(const TemplateName &TN) { + std::string_view getKind(const TemplateName &TN) { switch (TN.getKind()) { #define TEMPLATE_KIND(X) \ case TemplateName::X: \ return #X; TEMPLATE_KIND(Template); TEMPLATE_KIND(OverloadedTemplate); TEMPLATE_KIND(AssumedTemplate); TEMPLATE_KIND(QualifiedTemplate); TEMPLATE_KIND(DependentTemplate); TEMPLATE_KIND(SubstTemplateTemplateParm); TEMPLATE_KIND(SubstTemplateTemplateParmPack); TEMPLATE_KIND(UsingTemplate); TEMPLATE_KIND(DeducedTemplate); #undef TEMPLATE_KIND } llvm_unreachable("Unhandled NameKind enum"); } - std::string getKind(const Attr *A) { + std::string_view getKind(const Attr *A) { switch (A->getKind()) { #define ATTR(X) \ case attr::X: \ return #X; #include "clang/Basic/AttrList.inc" #undef ATTR } llvm_unreachable("Unhandled attr::Kind enum"); } std::string getKind(const CXXBaseSpecifier &CBS) { // There aren't really any variants of CXXBaseSpecifier. // To avoid special cases in the API/UI, use public/private as the kind. return getAccessSpelling(CBS.getAccessSpecifier()).str(); } - std::string getKind(const ConceptReference *CR) { + std::string_view getKind(const ConceptReference *CR) { // Again there are no variants here. // Kind is "Concept", role is "reference" return "Concept"; } // Detail is the single most important fact about the node. // Often this is the name, sometimes a "kind" enum like operators or casts. // We should avoid unbounded text, like dumping parameter lists. std::string getDetail(const Decl *D) { const auto *ND = dyn_cast(D); if (!ND || llvm::isa_and_nonnull(ND->getAsFunction()) || isa(ND)) return ""; std::string Name = toString([&](raw_ostream &OS) { ND->printName(OS); }); if (Name.empty()) return "(anonymous)"; return Name; } std::string getDetail(const Stmt *S) { if (const auto *DRE = dyn_cast(S)) return DRE->getNameInfo().getAsString(); if (const auto *DSDRE = dyn_cast(S)) return DSDRE->getNameInfo().getAsString(); if (const auto *ME = dyn_cast(S)) return ME->getMemberNameInfo().getAsString(); if (const auto *CE = dyn_cast(S)) return CE->getCastKindName(); if (const auto *BO = dyn_cast(S)) return BO->getOpcodeStr().str(); @@ -290,63 +290,63 @@ class DumpVisitor : public RecursiveASTVisitor { if (TAL.getArgument().getKind() == TemplateArgument::Integral) return toString(TAL.getArgument().getAsIntegral(), 10); return ""; } std::string getDetail(const TemplateName &TN) { return toString([&](raw_ostream &OS) { TN.print(OS, Ctx.getPrintingPolicy(), TemplateName::Qualified::None); }); } std::string getDetail(const Attr *A) { return A->getAttrName() ? A->getNormalizedFullName() : A->getSpelling(); } std::string getDetail(const CXXBaseSpecifier &CBS) { return CBS.isVirtual() ? "virtual" : ""; } std::string getDetail(const ConceptReference *CR) { return CR->getNamedConcept()->getNameAsString(); } /// Arcana is produced by TextNodeDumper, for the types it supports. template std::string dump(const Dump &D) { return toString([&](raw_ostream &OS) { TextNodeDumper Dumper(OS, Ctx, /*ShowColors=*/false); D(Dumper); }); } template std::string getArcana(const T &N) { return dump([&](TextNodeDumper &D) { D.Visit(N); }); } - std::string getArcana(const NestedNameSpecifierLoc &NNS) { return ""; } - std::string getArcana(const TemplateName &NNS) { return ""; } - std::string getArcana(const CXXBaseSpecifier &CBS) { return ""; } + std::string_view getArcana(const NestedNameSpecifierLoc &NNS) { return ""; } + std::string_view getArcana(const TemplateName &NNS) { return ""; } + std::string_view getArcana(const CXXBaseSpecifier &CBS) { return ""; } std::string getArcana(const TemplateArgumentLoc &TAL) { return dump([&](TextNodeDumper &D) { D.Visit(TAL.getArgument(), TAL.getSourceRange()); }); } std::string getArcana(const TypeLoc &TL) { return dump([&](TextNodeDumper &D) { D.Visit(TL.getType()); }); } public: ASTNode Root; DumpVisitor(const syntax::TokenBuffer &Tokens, const ASTContext &Ctx) : Tokens(Tokens), Ctx(Ctx) {} // Override traversal to record the nodes we care about. // Generally, these are nodes with position information (TypeLoc, not Type). bool TraverseDecl(Decl *D) { return !D || isInjectedClassName(D) || traverseNode("declaration", D, [&] { Base::TraverseDecl(D); }); } bool TraverseTypeLoc(TypeLoc TL, bool TraverseQualifier = true) { return !TL || traverseNode("type", TL, [&] { Base::TraverseTypeLoc(TL, TraverseQualifier); }); } bool TraverseTemplateName(const TemplateName &TN) { return traverseNode("template name", TN, [&] { Base::TraverseTemplateName(TN); }); } diff --git a/clang-tools-extra/clangd/Feature.cpp b/clang-tools-extra/clangd/Feature.cpp index ec707a33f656..976b274de722 100644 --- a/clang-tools-extra/clangd/Feature.cpp +++ b/clang-tools-extra/clangd/Feature.cpp @@ -3,61 +3,61 @@ // 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 "Feature.h" #include "clang/Basic/Version.h" #include "llvm/Config/llvm-config.h" // for LLVM_ON_UNIX #include "llvm/Support/Compiler.h" #include "llvm/TargetParser/Host.h" namespace clang { namespace clangd { std::string versionString() { return clang::getClangToolFullVersion("clangd"); } std::string platformString() { static std::string PlatformString = []() { std::string Host = llvm::sys::getProcessTriple(); std::string Target = llvm::sys::getDefaultTargetTriple(); if (Host != Target) { Host += "; target="; Host += Target; } return Host; }(); return PlatformString; } -std::string featureString() { +std::string_view featureString() { return #if defined(_WIN32) "windows" #elif defined(__APPLE__) "mac" #elif defined(__linux__) "linux" #elif defined(LLVM_ON_UNIX) "unix" #else "unknown" #endif #ifndef NDEBUG "+debug" #endif #if LLVM_ADDRESS_SANITIZER_BUILD "+asan" #endif #if LLVM_THREAD_SANITIZER_BUILD "+tsan" #endif #if LLVM_MEMORY_SANITIZER_BUILD "+msan" #endif #if CLANGD_ENABLE_REMOTE "+grpc" #endif #if CLANGD_BUILD_XPC diff --git a/clang-tools-extra/clangd/Feature.h b/clang-tools-extra/clangd/Feature.h index ba958fc49c02..b8ce544d1dcd 100644 --- a/clang-tools-extra/clangd/Feature.h +++ b/clang-tools-extra/clangd/Feature.h @@ -1,36 +1,36 @@ //===--- Feature.h - Compile-time configuration ------------------*-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 // //===----------------------------------------------------------------------===// // This file is not named "Features.h" because of a conflict with libstdc++: // https://github.com/clangd/clangd/issues/835 //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_FEATURE_H #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_FEATURE_H #include // Export constants like CLANGD_BUILD_XPC #include "Features.inc" namespace clang { namespace clangd { // Returns a version string for clangd, e.g. "clangd 10.0.0" std::string versionString(); // Returns the platform triple for clangd, e.g. "x86_64-pc-linux-gnu" // May include both the host and target triple if they differ. std::string platformString(); // Returns a string describing the compile-time configuration. // e.g. mac+debug+asan+grpc -std::string featureString(); +std::string_view featureString(); } // namespace clangd } // namespace clang #endif diff --git a/clang-tools-extra/clangd/InlayHints.cpp b/clang-tools-extra/clangd/InlayHints.cpp index 23bd02304a4f..88c3912fc24d 100644 --- a/clang-tools-extra/clangd/InlayHints.cpp +++ b/clang-tools-extra/clangd/InlayHints.cpp @@ -126,61 +126,61 @@ std::string summarizeExpr(const Expr *E) { } std::string VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E) { return getSimpleName(E->getDeclName()).str(); } std::string VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *E) { return getSimpleName(E->getType()).str(); } std::string VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E) { return getSimpleName(E->getType()).str(); } // Step through implicit nodes that clang doesn't classify as such. std::string VisitCXXMemberCallExpr(const CXXMemberCallExpr *E) { // Call to operator bool() inside if (X): dispatch to X. if (E->getNumArgs() == 0 && E->getMethodDecl() && E->getMethodDecl()->getDeclName().getNameKind() == DeclarationName::CXXConversionFunctionName && E->getSourceRange() == E->getImplicitObjectArgument()->getSourceRange()) return Visit(E->getImplicitObjectArgument()); return ConstStmtVisitor::VisitCXXMemberCallExpr(E); } std::string VisitCXXConstructExpr(const CXXConstructExpr *E) { if (E->getNumArgs() == 1) return Visit(E->getArg(0)); return ""; } // Literals are just printed - std::string VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *E) { + std::string_view VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *E) { return "nullptr"; } std::string VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E) { return E->getValue() ? "true" : "false"; } std::string VisitIntegerLiteral(const IntegerLiteral *E) { return llvm::to_string(E->getValue()); } std::string VisitFloatingLiteral(const FloatingLiteral *E) { std::string Result; llvm::raw_string_ostream OS(Result); E->getValue().print(OS); // Printer adds newlines?! Result.resize(llvm::StringRef(Result).rtrim().size()); return Result; } std::string VisitStringLiteral(const StringLiteral *E) { std::string Result = "\""; if (E->containsNonAscii()) { Result += "..."; } else { llvm::raw_string_ostream OS(Result); if (E->getLength() > 10) { llvm::printEscapedString(E->getString().take_front(7), OS); Result += "..."; } else { llvm::printEscapedString(E->getString(), OS); } } Result.push_back('"'); diff --git a/clang-tools-extra/clangd/SymbolDocumentation.cpp b/clang-tools-extra/clangd/SymbolDocumentation.cpp index a50d7a565b1b..fbdc9c707292 100644 --- a/clang-tools-extra/clangd/SymbolDocumentation.cpp +++ b/clang-tools-extra/clangd/SymbolDocumentation.cpp @@ -1,53 +1,53 @@ //===--- SymbolDocumentation.cpp ==-------------------------------*- 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 // //===----------------------------------------------------------------------===// #include "SymbolDocumentation.h" #include "support/Markup.h" #include "clang/AST/Comment.h" #include "clang/AST/CommentCommandTraits.h" #include "clang/AST/CommentVisitor.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringRef.h" namespace clang { namespace clangd { namespace { -std::string commandMarkerAsString(comments::CommandMarkerKind CommandMarker) { +std::string_view commandMarkerAsString(comments::CommandMarkerKind CommandMarker) { switch (CommandMarker) { case comments::CommandMarkerKind::CMK_At: return "@"; case comments::CommandMarkerKind::CMK_Backslash: return "\\"; } llvm_unreachable("Unknown command marker kind"); } void commandToMarkup(markup::Paragraph &Out, StringRef Command, comments::CommandMarkerKind CommandMarker, StringRef Args) { Out.appendBoldText(commandMarkerAsString(CommandMarker) + Command.str()); Out.appendSpace(); if (!Args.empty()) Out.appendCode(Args.str()); } template std::string getArgText(const T *Command) { std::string ArgText; for (unsigned I = 0; I < Command->getNumArgs(); ++I) { if (!ArgText.empty()) ArgText += " "; ArgText += Command->getArgText(I); } return ArgText; } } // namespace diff --git a/clang-tools-extra/clangd/refactor/Rename.cpp b/clang-tools-extra/clangd/refactor/Rename.cpp index c56375b1a98d..ca6d54b6037e 100644 --- a/clang-tools-extra/clangd/refactor/Rename.cpp +++ b/clang-tools-extra/clangd/refactor/Rename.cpp @@ -454,61 +454,61 @@ const NamedDecl *lookupSiblingsWithinContext(ASTContext &Ctx, default: break; } // Lookup may contain the RenameDecl itself, exclude it. for (const auto *D : LookupResult) if (D->getCanonicalDecl() != RenamedDecl.getCanonicalDecl() && D->getIdentifierNamespace() & RenamedDecl.getIdentifierNamespace()) return D; return nullptr; } const NamedDecl *lookupSiblingWithName(ASTContext &Ctx, const NamedDecl &RenamedDecl, llvm::StringRef NewName) { trace::Span Tracer("LookupSiblingWithName"); if (const auto *Result = lookupSiblingsWithinContext(Ctx, RenamedDecl, NewName)) return Result; return lookupSiblingWithinEnclosingScope(Ctx, RenamedDecl, NewName); } struct InvalidName { enum Kind { Keywords, Conflict, BadIdentifier, }; Kind K; std::string Details; }; -std::string toString(InvalidName::Kind K) { +std::string_view toString(InvalidName::Kind K) { switch (K) { case InvalidName::Keywords: return "Keywords"; case InvalidName::Conflict: return "Conflict"; case InvalidName::BadIdentifier: return "BadIdentifier"; } llvm_unreachable("unhandled InvalidName kind"); } llvm::Error makeError(InvalidName Reason) { auto Message = [](const InvalidName &Reason) { switch (Reason.K) { case InvalidName::Keywords: return llvm::formatv("the chosen name \"{0}\" is a keyword", Reason.Details); case InvalidName::Conflict: return llvm::formatv("conflict with the symbol in {0}", Reason.Details); case InvalidName::BadIdentifier: return llvm::formatv("the chosen name \"{0}\" is not a valid identifier", Reason.Details); } llvm_unreachable("unhandled InvalidName kind"); }; return error("invalid name: {0}", Message(Reason)); } static bool mayBeValidIdentifier(llvm::StringRef Ident, bool AllowColon) { assert(llvm::json::isUTF8(Ident));