brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.3 KiB · 2ed5eae Raw
112 lines · c
1//===--- StdLib.h - Index the C and C++ standard library ---------*- C++-*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8// Eagerly indexing the standard library gives a much friendlier "warm start"9// with working code completion in a standalone file or small project.10//11// We act as if we saw a file which included the whole standard library:12//   #include <array>13//   #include <bitset>14//   #include <chrono>15//   ...16// We index this TU and feed the result into the dynamic index.17//18// This happens within the context of some particular open file, and we reuse19// its CompilerInvocation. Matching its include path, LangOpts etc ensures that20// we see the standard library and configuration that matches the project.21//===----------------------------------------------------------------------===//22 23#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_STDLIB_H24#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_STDLIB_H25 26#include "index/Symbol.h"27#include "support/ThreadsafeFS.h"28#include "llvm/ADT/StringRef.h"29#include <optional>30#include <string>31 32namespace clang {33class CompilerInvocation;34class LangOptions;35class HeaderSearch;36namespace clangd {37 38// The filesystem location where a standard library was found.39//40// This is the directory containing <vector> or <stdio.h>.41// It's used to ensure we only index files that are in the standard library.42//43// The paths are canonicalized (FS "real path" with symlinks resolved).44// This allows them to be easily compared against paths the indexer returns.45struct StdLibLocation {46  llvm::SmallVector<std::string> Paths;47};48 49// Tracks the state of standard library indexing within a particular index.50//51// In general, we don't want to index the standard library multiple times.52// In most cases, this class just acts as a flag to ensure we only do it once.53//54// However, if we first open a C++11 file, and then a C++20 file, we *do*55// want the index to be upgraded to include the extra symbols.56// Similarly, the C and C++ standard library can coexist.57class StdLibSet {58  std::atomic<int> Best[2] = {{-1}, {-1}};59 60public:61  // Determines if we should index the standard library in a configuration.62  //63  // This is true if:64  //  - standard library indexing is enabled for the file65  //  - the language version is higher than any previous add() for the language66  //  - the standard library headers exist on the search path67  // Returns the location where the standard library was found.68  //69  // This function is threadsafe.70  std::optional<StdLibLocation> add(const LangOptions &, const HeaderSearch &);71 72  // Indicates whether a built index should be used.73  // It should not be used if a newer version has subsequently been added.74  //75  // Intended pattern is:76  //   if (add()) {77  //     symbols = indexStandardLibrary();78  //     if (isBest())79  //       index.update(symbols);80  //   }81  //82  // This is still technically racy: we could return true here, then another83  // thread could add->index->update a better library before we can update.84  // We'd then overwrite it with the older version.85  // However, it's very unlikely: indexing takes a long time.86  bool isBest(const LangOptions &) const;87};88 89// Index a standard library and return the discovered symbols.90//91// The compiler invocation should describe the file whose config we're reusing.92// We overwrite its virtual buffer with a lot of #include statements.93SymbolSlab indexStandardLibrary(std::unique_ptr<CompilerInvocation> Invocation,94                                const StdLibLocation &Loc,95                                const ThreadsafeFS &TFS);96 97// Variant that allows the umbrella header source to be specified.98// Exposed for testing.99SymbolSlab indexStandardLibrary(llvm::StringRef HeaderSources,100                                std::unique_ptr<CompilerInvocation> CI,101                                const StdLibLocation &Loc,102                                const ThreadsafeFS &TFS);103 104// Generate header containing #includes for all standard library headers.105// Exposed for testing.106llvm::StringRef getStdlibUmbrellaHeader(const LangOptions &);107 108} // namespace clangd109} // namespace clang110 111#endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_STDLIB_H112