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-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// Experimental support for C++20 Modules.
10//
11// Currently we simplify the implementations by preventing reusing module files
12// across different versions and different source files. But this is clearly a
13// waste of time and space in the end of the day.
14//
15// TODO: Supporting reusing module files across different versions and
16// different source files.
17//
18//===----------------------------------------------------------------------===//
19
20#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_MODULES_BUILDER_H
21#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_MODULES_BUILDER_H
22
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 single
35/// source file. e.g.,
36///
37/// ```
38/// // a.cppm
39/// export module a;
40///
41/// // b.cppm
42/// export module b;
43/// import a;
44///
45/// // c.cppm
46/// export module c;
47/// import b;
48/// ```
49///
50/// For the source file `c.cppm`, an instance of the class will store
51/// 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 from
55/// `ModulesBuilder::buildPrerequisiteModulesFor(...)`.
56///
57/// Users can detect whether the PrerequisiteModules is still up to date by
58/// calling the `canReuse()` member function.
59///
60/// The users should call `adjustHeaderSearchOptions(...)` to update the
61/// compilation commands to select the built module files first. Before calling
62/// `adjustHeaderSearchOptions()`, users should call `canReuse()` first to check
63/// if all the stored module files are valid. In case they are not valid,
64/// users should call `ModulesBuilder::buildPrerequisiteModulesFor(...)` again
65/// to get the new PrerequisiteModules.
66class PrerequisiteModules {
67public:
68 /// Change commands to load the module files recorded in this
69 /// PrerequisiteModules first.
70 virtual void
71 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 bool
76 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 acorss
85/// 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 clangd
106} // namespace clang
107
108#endif
109

source code of clang-tools-extra/clangd/ModulesBuilder.h