aboutsummaryrefslogtreecommitdiff
path: root/lib/Frontend
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Frontend')
-rw-r--r--lib/Frontend/ASTUnit.cpp33
-rw-r--r--lib/Frontend/CompilerInvocation.cpp10
-rw-r--r--lib/Frontend/FrontendAction.cpp13
3 files changed, 49 insertions, 7 deletions
diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp
index 5e534b3d57..41f2442a11 100644
--- a/lib/Frontend/ASTUnit.cpp
+++ b/lib/Frontend/ASTUnit.cpp
@@ -92,7 +92,8 @@ const unsigned DefaultPreambleRebuildInterval = 5;
static llvm::sys::cas_flag ActiveASTUnitObjects;
ASTUnit::ASTUnit(bool _MainFileIsAST)
- : CaptureDiagnostics(false), MainFileIsAST(_MainFileIsAST),
+ : OnlyLocalDecls(false), CaptureDiagnostics(false),
+ MainFileIsAST(_MainFileIsAST),
CompleteTranslationUnit(true), WantTiming(getenv("LIBCLANG_TIMING")),
OwnsRemappedFileBuffers(true),
NumStoredDiagnosticsFromDriver(0),
@@ -1522,6 +1523,19 @@ llvm::StringRef ASTUnit::getMainFileName() const {
return Invocation->getFrontendOpts().Inputs[0].second;
}
+ASTUnit *ASTUnit::create(CompilerInvocation *CI,
+ llvm::IntrusiveRefCntPtr<Diagnostic> Diags) {
+ llvm::OwningPtr<ASTUnit> AST;
+ AST.reset(new ASTUnit(false));
+ ConfigureDiags(Diags, 0, 0, *AST, /*CaptureDiagnostics=*/false);
+ AST->Diagnostics = Diags;
+ AST->Invocation.reset(CI);
+ AST->FileMgr.reset(new FileManager(CI->getFileSystemOpts()));
+ AST->SourceMgr.reset(new SourceManager(*Diags, *AST->FileMgr));
+
+ return AST.take();
+}
+
bool ASTUnit::LoadFromCompilerInvocation(bool PrecompilePreamble) {
if (!Invocation)
return true;
@@ -2148,7 +2162,16 @@ bool ASTUnit::Save(llvm::StringRef File) {
llvm::raw_fd_ostream::F_Binary);
if (!ErrorInfo.empty() || Out.has_error())
return true;
-
+
+ serialize(Out);
+ Out.close();
+ return Out.has_error();
+}
+
+bool ASTUnit::serialize(llvm::raw_ostream &OS) {
+ if (getDiagnostics().hasErrorOccurred())
+ return true;
+
std::vector<unsigned char> Buffer;
llvm::BitstreamWriter Stream(Buffer);
ASTWriter Writer(Stream);
@@ -2156,7 +2179,7 @@ bool ASTUnit::Save(llvm::StringRef File) {
// Write the generated bitstream to "Out".
if (!Buffer.empty())
- Out.write((char *)&Buffer.front(), Buffer.size());
- Out.close();
- return Out.has_error();
+ OS.write((char *)&Buffer.front(), Buffer.size());
+
+ return false;
}
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 8f99403923..d8de7c08b4 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -704,6 +704,10 @@ static void PreprocessorOptsToArgs(const PreprocessorOptions &Opts,
assert(Opts.ImplicitPTHInclude == Opts.TokenCache &&
"Unsupported option combination!");
}
+ for (unsigned i = 0, e = Opts.ChainedIncludes.size(); i != e; ++i) {
+ Res.push_back("-chain-include");
+ Res.push_back(Opts.ChainedIncludes[i]);
+ }
for (unsigned i = 0, e = Opts.RemappedFiles.size(); i != e; ++i) {
Res.push_back("-remap-file");
Res.push_back(Opts.RemappedFiles[i].first + ";" +
@@ -1562,6 +1566,12 @@ static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args,
Opts.Includes.push_back(A->getValue(Args));
}
+ for (arg_iterator it = Args.filtered_begin(OPT_chain_include),
+ ie = Args.filtered_end(); it != ie; ++it) {
+ const Arg *A = *it;
+ Opts.ChainedIncludes.push_back(A->getValue(Args));
+ }
+
// Include 'altivec.h' if -faltivec option present
if (Args.hasArg(OPT_faltivec))
Opts.Includes.push_back("altivec.h");
diff --git a/lib/Frontend/FrontendAction.cpp b/lib/Frontend/FrontendAction.cpp
index e3d8b85941..5c34e9491b 100644
--- a/lib/Frontend/FrontendAction.cpp
+++ b/lib/Frontend/FrontendAction.cpp
@@ -20,6 +20,7 @@
#include "clang/Frontend/MultiplexConsumer.h"
#include "clang/Parse/ParseAST.h"
#include "clang/Serialization/ASTDeserializationListener.h"
+#include "clang/Serialization/ChainedIncludesSource.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Timer.h"
#include "llvm/Support/ErrorHandling.h"
@@ -209,8 +210,16 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
CI.getASTContext().setASTMutationListener(Consumer->GetASTMutationListener());
- /// Use PCH?
- if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) {
+ if (!CI.getPreprocessorOpts().ChainedIncludes.empty()) {
+ // Convert headers to PCH and chain them.
+ llvm::OwningPtr<ExternalASTSource> source;
+ source.reset(ChainedIncludesSource::create(CI));
+ if (!source)
+ goto failure;
+ CI.getASTContext().setExternalSource(source);
+
+ } else if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) {
+ // Use PCH.
assert(hasPCHSupport() && "This action does not have PCH support!");
ASTDeserializationListener *DeserialListener
= CI.getInvocation().getFrontendOpts().ChainedPCH ?