Skip to content
This repository was archived by the owner on Nov 1, 2021. It is now read-only.

Commit ae2de79

Browse files
committed
Add #pragma clang module build/endbuild pragmas for performing a module build
as part of a compilation. This is intended for two purposes: 1) Writing self-contained test cases for modules: we can now write a single source file test that builds some number of module files on the side and imports them. 2) Debugging / test case reduction. A single-source testcase is much more amenable to reduction, compared to a VFS tarball or .pcm files. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@305101 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent ce2bd42 commit ae2de79

File tree

13 files changed

+377
-168
lines changed

13 files changed

+377
-168
lines changed

include/clang/Basic/DiagnosticLexKinds.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,10 @@ def err_pp_module_end_without_module_begin : Error<
527527
"'#pragma clang module end'">;
528528
def note_pp_module_begin_here : Note<
529529
"entering module '%0' due to this pragma">;
530+
def err_pp_module_build_pth : Error<
531+
"'#pragma clang module build' not supported in pretokenized header">;
532+
def err_pp_module_build_missing_end : Error<
533+
"no matching '#pragma clang module endbuild' for this '#pragma clang module build'">;
530534

531535
def err_defined_macro_name : Error<"'defined' cannot be used as a macro name">;
532536
def err_paste_at_start : Error<

include/clang/Frontend/ASTUnit.h

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ class FileSystem;
6767

6868
/// \brief Utility class for loading a ASTContext from an AST file.
6969
///
70-
class ASTUnit : public ModuleLoader {
70+
class ASTUnit {
7171
public:
7272
struct StandaloneFixIt {
7373
std::pair<unsigned, unsigned> RemoveRange;
@@ -119,10 +119,13 @@ class ASTUnit : public ModuleLoader {
119119
/// LoadFromCommandLine available.
120120
std::shared_ptr<CompilerInvocation> Invocation;
121121

122+
/// Fake module loader: the AST unit doesn't need to load any modules.
123+
TrivialModuleLoader ModuleLoader;
124+
122125
// OnlyLocalDecls - when true, walking this AST should only visit declarations
123126
// that come from the AST itself, not from included precompiled headers.
124127
// FIXME: This is temporary; eventually, CIndex will always do this.
125-
bool OnlyLocalDecls;
128+
bool OnlyLocalDecls;
126129

127130
/// \brief Whether to capture any diagnostics produced.
128131
bool CaptureDiagnostics;
@@ -496,7 +499,7 @@ class ASTUnit : public ModuleLoader {
496499
};
497500
friend class ConcurrencyCheck;
498501

499-
~ASTUnit() override;
502+
~ASTUnit();
500503

501504
bool isMainFileAST() const { return MainFileIsAST; }
502505

@@ -945,21 +948,6 @@ class ASTUnit : public ModuleLoader {
945948
///
946949
/// \returns True if an error occurred, false otherwise.
947950
bool serialize(raw_ostream &OS);
948-
949-
ModuleLoadResult loadModule(SourceLocation ImportLoc, ModuleIdPath Path,
950-
Module::NameVisibilityKind Visibility,
951-
bool IsInclusionDirective) override {
952-
// ASTUnit doesn't know how to load modules (not that this matters).
953-
return ModuleLoadResult();
954-
}
955-
956-
void makeModuleVisible(Module *Mod, Module::NameVisibilityKind Visibility,
957-
SourceLocation ImportLoc) override {}
958-
959-
GlobalModuleIndex *loadGlobalModuleIndex(SourceLocation TriggerLoc) override
960-
{ return nullptr; }
961-
bool lookupMissingImports(StringRef Name, SourceLocation TriggerLoc) override
962-
{ return 0; }
963951
};
964952

965953
} // namespace clang

include/clang/Frontend/CompilerInstance.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,10 @@ class CompilerInstance : public ModuleLoader {
136136
/// along with the module map
137137
llvm::DenseMap<const IdentifierInfo *, Module *> KnownModules;
138138

139+
/// \brief The set of top-level modules that has already been built on the
140+
/// fly as part of this overall compilation action.
141+
std::map<std::string, std::string> BuiltModules;
142+
139143
/// \brief The location of the module-import keyword for the last module
140144
/// import.
141145
SourceLocation LastModuleImportLoc;
@@ -773,6 +777,9 @@ class CompilerInstance : public ModuleLoader {
773777
Module::NameVisibilityKind Visibility,
774778
bool IsInclusionDirective) override;
775779

780+
void loadModuleFromSource(SourceLocation ImportLoc, StringRef ModuleName,
781+
StringRef Source) override;
782+
776783
void makeModuleVisible(Module *Mod, Module::NameVisibilityKind Visibility,
777784
SourceLocation ImportLoc) override;
778785

include/clang/Lex/ModuleLoader.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,16 @@ class ModuleLoader {
109109
Module::NameVisibilityKind Visibility,
110110
bool IsInclusionDirective) = 0;
111111

112+
/// Attempt to load the given module from the specified source buffer. Does
113+
/// not make any submodule visible; for that, use loadModule or
114+
/// makeModuleVisible.
115+
///
116+
/// \param Loc The location at which the module was loaded.
117+
/// \param ModuleName The name of the module to build.
118+
/// \param Source The source of the module: a (preprocessed) module map.
119+
virtual void loadModuleFromSource(SourceLocation Loc, StringRef ModuleName,
120+
StringRef Source) = 0;
121+
112122
/// \brief Make the given module visible.
113123
virtual void makeModuleVisible(Module *Mod,
114124
Module::NameVisibilityKind Visibility,
@@ -136,6 +146,30 @@ class ModuleLoader {
136146

137147
bool HadFatalFailure;
138148
};
149+
150+
/// A module loader that doesn't know how to load modules.
151+
class TrivialModuleLoader : public ModuleLoader {
152+
public:
153+
ModuleLoadResult loadModule(SourceLocation ImportLoc, ModuleIdPath Path,
154+
Module::NameVisibilityKind Visibility,
155+
bool IsInclusionDirective) override {
156+
return ModuleLoadResult();
157+
}
158+
159+
void loadModuleFromSource(SourceLocation ImportLoc, StringRef ModuleName,
160+
StringRef Source) override {}
161+
162+
void makeModuleVisible(Module *Mod, Module::NameVisibilityKind Visibility,
163+
SourceLocation ImportLoc) override {}
164+
165+
GlobalModuleIndex *loadGlobalModuleIndex(SourceLocation TriggerLoc) override {
166+
return nullptr;
167+
}
168+
bool lookupMissingImports(StringRef Name,
169+
SourceLocation TriggerLoc) override {
170+
return 0;
171+
}
172+
};
139173

140174
}
141175

include/clang/Lex/Preprocessor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2028,6 +2028,7 @@ class Preprocessor {
20282028
void HandlePragmaPushMacro(Token &Tok);
20292029
void HandlePragmaPopMacro(Token &Tok);
20302030
void HandlePragmaIncludeAlias(Token &Tok);
2031+
void HandlePragmaModuleBuild(Token &Tok);
20312032
IdentifierInfo *ParsePragmaPushOrPopMacro(Token &Tok);
20322033

20332034
// Return true and store the first token only if any CommentHandler

lib/Frontend/ASTUnit.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -716,7 +716,7 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile(
716716

717717
AST->PP = std::make_shared<Preprocessor>(
718718
AST->PPOpts, AST->getDiagnostics(), *AST->LangOpts,
719-
AST->getSourceManager(), *AST->PCMCache, HeaderInfo, *AST,
719+
AST->getSourceManager(), *AST->PCMCache, HeaderInfo, AST->ModuleLoader,
720720
/*IILookup=*/nullptr,
721721
/*OwnsHeaderSearch=*/false);
722722
Preprocessor &PP = *AST->PP;

0 commit comments

Comments
 (0)