Skip to content

Commit 306ef83

Browse files
committed
[clang-repl] Teach clang-repl how to load PCHs.
1 parent 8dc63ca commit 306ef83

File tree

6 files changed

+39
-11
lines changed

6 files changed

+39
-11
lines changed

clang/include/clang/CodeGen/ModuleBuilder.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,12 @@ namespace CodeGen {
5252
class CodeGenerator : public ASTConsumer {
5353
virtual void anchor();
5454

55+
protected:
56+
/// True if we've finished generating IR. This prevents us from generating
57+
/// additional LLVM IR after emitting output in HandleTranslationUnit. This
58+
/// can happen when Clang plugins trigger additional AST deserialization.
59+
bool IRGenFinished = false;
60+
5561
public:
5662
/// Return an opaque reference to the CodeGenModule object, which can
5763
/// be used in various secondary APIs. It is valid as long as the

clang/lib/CodeGen/BackendConsumer.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,6 @@ class BackendConsumer : public ASTConsumer {
4040
llvm::Timer LLVMIRGeneration;
4141
unsigned LLVMIRGenerationRefCount = 0;
4242

43-
/// True if we've finished generating IR. This prevents us from generating
44-
/// additional LLVM IR after emitting output in HandleTranslationUnit. This
45-
/// can happen when Clang plugins trigger additional AST deserialization.
46-
bool IRGenFinished = false;
47-
4843
bool TimerIsEnabled = false;
4944

5045
BackendAction Action;

clang/lib/CodeGen/CodeGenAction.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -189,9 +189,7 @@ void BackendConsumer::HandleInlineFunctionDefinition(FunctionDecl *D) {
189189
}
190190

191191
void BackendConsumer::HandleInterestingDecl(DeclGroupRef D) {
192-
// Ignore interesting decls from the AST reader after IRGen is finished.
193-
if (!IRGenFinished)
194-
HandleTopLevelDecl(D);
192+
HandleTopLevelDecl(D);
195193
}
196194

197195
// Links each entry in LinkModules into our module. Returns true on error.
@@ -240,10 +238,13 @@ void BackendConsumer::HandleTranslationUnit(ASTContext &C) {
240238

241239
Gen->HandleTranslationUnit(C);
242240

243-
if (TimerIsEnabled && !--LLVMIRGenerationRefCount)
244-
LLVMIRGeneration.yieldTo(CI.getFrontendTimer());
245-
246241
IRGenFinished = true;
242+
243+
if (TimerIsEnabled) {
244+
LLVMIRGenerationRefCount -= 1;
245+
if (LLVMIRGenerationRefCount == 0)
246+
LLVMIRGeneration.stopTimer();
247+
}
247248
}
248249

249250
// Silently ignore if we weren't initialized for some reason.

clang/lib/CodeGen/ModuleBuilder.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,8 @@ namespace {
138138
assert(!M && "Replacing existing Module?");
139139
M.reset(new llvm::Module(ExpandModuleName(ModuleName, CodeGenOpts), C));
140140

141+
IRGenFinished = false;
142+
141143
std::unique_ptr<CodeGenModule> OldBuilder = std::move(Builder);
142144

143145
Initialize(*Ctx);
@@ -179,6 +181,10 @@ namespace {
179181
}
180182

181183
bool HandleTopLevelDecl(DeclGroupRef DG) override {
184+
// Ignore interesting decls from the AST reader after IRGen is finished.
185+
if (IRGenFinished)
186+
return true; // We can't CodeGen more but pass to other consumers.
187+
182188
// FIXME: Why not return false and abort parsing?
183189
if (Diags.hasUnrecoverableErrorOccurred())
184190
return true;
@@ -282,6 +288,8 @@ namespace {
282288
}
283289

284290
void HandleTranslationUnit(ASTContext &Ctx) override {
291+
IRGenFinished = true;
292+
285293
// Release the Builder when there is no error.
286294
if (!Diags.hasUnrecoverableErrorOccurred() && Builder)
287295
Builder->Release();

clang/lib/Interpreter/IncrementalParser.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ IncrementalParser::IncrementalParser(CompilerInstance &Instance,
3232
llvm::ErrorAsOutParameter EAO(&Err);
3333
Consumer = &S.getASTConsumer();
3434
P.reset(new Parser(S.getPreprocessor(), S, /*SkipBodies=*/false));
35+
36+
if (ExternalASTSource *External = S->getASTContext().getExternalSource())
37+
External->StartTranslationUnit(Consumer);
38+
3539
P->Initialize();
3640
}
3741

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// REQUIRES: host-supports-jit
2+
// UNSUPPORTED: system-aix
3+
4+
// RUN: rm -f %t.pch
5+
// RUN: %clang_cc1 -fmax-type-align=16 -pic-level 2 -fdeprecated-macro -stack-protector 1 -fblocks -fskip-odr-check-in-gmf -fexceptions -fcxx-exceptions -fgnuc-version=0 -triple=%target_triple -DPCH -fincremental-extensions -emit-pch -x c++-header -o %t.pch %s
6+
// RUN: clang-repl -Xcc -fgnuc-version=0 -Xcc -triple=%target_triple -Xcc -include-pch -Xcc %t.pch '#include "%s"' | FileCheck %s
7+
8+
#ifdef PCH
9+
int f_pch() { return 5; }
10+
#endif // PCH
11+
12+
extern "C" int printf(const char *, ...);
13+
auto r1 = printf("f_pch = %d\n", f_pch());
14+
// CHECK: f_pch = 5

0 commit comments

Comments
 (0)