109 lines · c
1//===----------------- ModulesBuilder.h --------------------------*- 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//9// Experimental support for C++20 Modules.10//11// Currently we simplify the implementations by preventing reusing module files12// across different versions and different source files. But this is clearly a13// waste of time and space in the end of the day.14//15// TODO: Supporting reusing module files across different versions and16// different source files.17//18//===----------------------------------------------------------------------===//19 20#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_MODULES_BUILDER_H21#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_MODULES_BUILDER_H22 23#include "GlobalCompilationDatabase.h"24#include "ProjectModules.h"25#include "support/Path.h"26#include "support/ThreadsafeFS.h"27#include "clang/Frontend/CompilerInvocation.h"28#include "llvm/ADT/SmallString.h"29#include <memory>30 31namespace clang {32namespace clangd {33 34/// Store all the needed module files information to parse a single35/// source file. e.g.,36///37/// ```38/// // a.cppm39/// export module a;40///41/// // b.cppm42/// export module b;43/// import a;44///45/// // c.cppm46/// export module c;47/// import b;48/// ```49///50/// For the source file `c.cppm`, an instance of the class will store51/// the module files for `a.cppm` and `b.cppm`. But the module file for `c.cppm`52/// won't be stored. Since it is not needed to parse `c.cppm`.53///54/// Users should only get PrerequisiteModules from55/// `ModulesBuilder::buildPrerequisiteModulesFor(...)`.56///57/// Users can detect whether the PrerequisiteModules is still up to date by58/// calling the `canReuse()` member function.59///60/// The users should call `adjustHeaderSearchOptions(...)` to update the61/// compilation commands to select the built module files first. Before calling62/// `adjustHeaderSearchOptions()`, users should call `canReuse()` first to check63/// if all the stored module files are valid. In case they are not valid,64/// users should call `ModulesBuilder::buildPrerequisiteModulesFor(...)` again65/// to get the new PrerequisiteModules.66class PrerequisiteModules {67public:68 /// Change commands to load the module files recorded in this69 /// PrerequisiteModules first.70 virtual void71 adjustHeaderSearchOptions(HeaderSearchOptions &Options) const = 0;72 73 /// Whether or not the built module files are up to date.74 /// Note that this can only be used after building the module files.75 virtual bool76 canReuse(const CompilerInvocation &CI,77 llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>) const = 0;78 79 virtual ~PrerequisiteModules() = default;80};81 82/// This class handles building module files for a given source file.83///84/// In the future, we want the class to manage the module files acorss85/// different versions and different source files.86class ModulesBuilder {87public:88 ModulesBuilder(const GlobalCompilationDatabase &CDB);89 ~ModulesBuilder();90 91 ModulesBuilder(const ModulesBuilder &) = delete;92 ModulesBuilder(ModulesBuilder &&) = delete;93 94 ModulesBuilder &operator=(const ModulesBuilder &) = delete;95 ModulesBuilder &operator=(ModulesBuilder &&) = delete;96 97 std::unique_ptr<PrerequisiteModules>98 buildPrerequisiteModulesFor(PathRef File, const ThreadsafeFS &TFS);99 100private:101 class ModulesBuilderImpl;102 std::unique_ptr<ModulesBuilderImpl> Impl;103};104 105} // namespace clangd106} // namespace clang107 108#endif109