Reshuffle the PCH generator action and consumer, so that we can re-use
it while generating precompiled preambles. No functionality change.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@110108 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp
index b36a338..bd60296 100644
--- a/lib/Frontend/ASTUnit.cpp
+++ b/lib/Frontend/ASTUnit.cpp
@@ -12,7 +12,7 @@
//===----------------------------------------------------------------------===//
#include "clang/Frontend/ASTUnit.h"
-#include "clang/Frontend/PCHReader.h"
+#include "clang/Frontend/PCHWriter.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/DeclVisitor.h"
@@ -25,6 +25,7 @@
#include "clang/Frontend/FrontendActions.h"
#include "clang/Frontend/FrontendDiagnostic.h"
#include "clang/Frontend/FrontendOptions.h"
+#include "clang/Frontend/PCHReader.h"
#include "clang/Lex/HeaderSearch.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Basic/TargetOptions.h"
@@ -328,6 +329,54 @@
virtual bool hasCodeCompletionSupport() const { return false; }
};
+class PrecompilePreambleConsumer : public PCHGenerator {
+ ASTUnit &Unit;
+
+public:
+ PrecompilePreambleConsumer(ASTUnit &Unit,
+ const Preprocessor &PP, bool Chaining,
+ const char *isysroot, llvm::raw_ostream *Out)
+ : PCHGenerator(PP, Chaining, isysroot, Out), Unit(Unit) { }
+
+ void HandleTopLevelDecl(DeclGroupRef D) {
+ for (DeclGroupRef::iterator it = D.begin(), ie = D.end(); it != ie; ++it) {
+ Decl *D = *it;
+ // FIXME: Currently ObjC method declarations are incorrectly being
+ // reported as top-level declarations, even though their DeclContext
+ // is the containing ObjC @interface/@implementation. This is a
+ // fundamental problem in the parser right now.
+ if (isa<ObjCMethodDecl>(D))
+ continue;
+ Unit.getTopLevelDecls().push_back(D);
+ }
+ }
+};
+
+class PrecompilePreambleAction : public ASTFrontendAction {
+ ASTUnit &Unit;
+
+public:
+ explicit PrecompilePreambleAction(ASTUnit &Unit) : Unit(Unit) {}
+
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile) {
+ std::string Sysroot;
+ llvm::raw_ostream *OS = 0;
+ bool Chaining;
+ if (GeneratePCHAction::ComputeASTConsumerArguments(CI, InFile, Sysroot,
+ OS, Chaining))
+ return 0;
+
+ const char *isysroot = CI.getFrontendOpts().RelocatablePCH ?
+ Sysroot.c_str() : 0;
+ return new PrecompilePreambleConsumer(Unit, CI.getPreprocessor(), Chaining,
+ isysroot, OS);
+ }
+
+ virtual bool hasCodeCompletionSupport() const { return false; }
+ virtual bool hasASTFileSupport() const { return false; }
+};
+
}
/// Parse the source file into a translation unit using the given compiler
@@ -819,8 +868,8 @@
Clang.setSourceManager(new SourceManager(getDiagnostics()));
// FIXME: Eventually, we'll have to track top-level declarations here, too.
- llvm::OwningPtr<GeneratePCHAction> Act;
- Act.reset(new GeneratePCHAction);
+ llvm::OwningPtr<PrecompilePreambleAction> Act;
+ Act.reset(new PrecompilePreambleAction(*this));
if (!Act->BeginSourceFile(Clang, Clang.getFrontendOpts().Inputs[0].second,
Clang.getFrontendOpts().Inputs[0].first)) {
Clang.takeDiagnosticClient();
diff --git a/lib/Frontend/FrontendActions.cpp b/lib/Frontend/FrontendActions.cpp
index b0f85f1..08639b6 100644
--- a/lib/Frontend/FrontendActions.cpp
+++ b/lib/Frontend/FrontendActions.cpp
@@ -17,6 +17,7 @@
#include "clang/Frontend/ASTUnit.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendDiagnostic.h"
+#include "clang/Frontend/PCHWriter.h"
#include "clang/Frontend/Utils.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/Support/MemoryBuffer.h"
@@ -70,22 +71,35 @@
ASTConsumer *GeneratePCHAction::CreateASTConsumer(CompilerInstance &CI,
llvm::StringRef InFile) {
- const std::string &Sysroot = CI.getHeaderSearchOpts().Sysroot;
- if (CI.getFrontendOpts().RelocatablePCH &&
- Sysroot.empty()) {
- CI.getDiagnostics().Report(diag::err_relocatable_without_without_isysroot);
+ std::string Sysroot;
+ llvm::raw_ostream *OS = 0;
+ bool Chaining;
+ if (ComputeASTConsumerArguments(CI, InFile, Sysroot, OS, Chaining))
return 0;
+
+ const char *isysroot = CI.getFrontendOpts().RelocatablePCH ?
+ Sysroot.c_str() : 0;
+ return new PCHGenerator(CI.getPreprocessor(), Chaining, isysroot, OS);
+}
+
+bool GeneratePCHAction::ComputeASTConsumerArguments(CompilerInstance &CI,
+ llvm::StringRef InFile,
+ std::string &Sysroot,
+ llvm::raw_ostream *&OS,
+ bool &Chaining) {
+ Sysroot = CI.getHeaderSearchOpts().Sysroot;
+ if (CI.getFrontendOpts().RelocatablePCH && Sysroot.empty()) {
+ CI.getDiagnostics().Report(diag::err_relocatable_without_without_isysroot);
+ return true;
}
- llvm::raw_ostream *OS = CI.createDefaultOutputFile(true, InFile);
+ OS = CI.createDefaultOutputFile(true, InFile);
if (!OS)
- return 0;
+ return true;
- bool Chaining = CI.getInvocation().getFrontendOpts().ChainedPCH &&
- !CI.getPreprocessorOpts().ImplicitPCHInclude.empty();
- const char *isysroot = CI.getFrontendOpts().RelocatablePCH ?
- Sysroot.c_str() : 0;
- return CreatePCHGenerator(CI.getPreprocessor(), OS, Chaining, isysroot);
+ Chaining = CI.getInvocation().getFrontendOpts().ChainedPCH &&
+ !CI.getPreprocessorOpts().ImplicitPCHInclude.empty();
+ return false;
}
ASTConsumer *InheritanceViewAction::CreateASTConsumer(CompilerInstance &CI,
diff --git a/lib/Frontend/GeneratePCH.cpp b/lib/Frontend/GeneratePCH.cpp
index 561a68a..33f5ef5 100644
--- a/lib/Frontend/GeneratePCH.cpp
+++ b/lib/Frontend/GeneratePCH.cpp
@@ -25,26 +25,6 @@
using namespace clang;
-namespace {
- class PCHGenerator : public SemaConsumer {
- const Preprocessor &PP;
- const char *isysroot;
- llvm::raw_ostream *Out;
- Sema *SemaPtr;
- MemorizeStatCalls *StatCalls; // owned by the FileManager
- std::vector<unsigned char> Buffer;
- llvm::BitstreamWriter Stream;
- PCHWriter Writer;
-
- public:
- PCHGenerator(const Preprocessor &PP, bool Chaining,
- const char *isysroot, llvm::raw_ostream *Out);
- virtual void InitializeSema(Sema &S) { SemaPtr = &S; }
- virtual void HandleTranslationUnit(ASTContext &Ctx);
- virtual PCHDeserializationListener *GetPCHDeserializationListener();
- };
-}
-
PCHGenerator::PCHGenerator(const Preprocessor &PP,
bool Chaining,
const char *isysroot,
@@ -82,10 +62,3 @@
PCHDeserializationListener *PCHGenerator::GetPCHDeserializationListener() {
return &Writer;
}
-
-ASTConsumer *clang::CreatePCHGenerator(const Preprocessor &PP,
- llvm::raw_ostream *OS,
- bool Chaining,
- const char *isysroot) {
- return new PCHGenerator(PP, Chaining, isysroot, OS);
-}