Update Clang for 3.5 rebase (r209713).
Change-Id: I8c9133b0f8f776dc915f270b60f94962e771bc83
diff --git a/lib/Frontend/FrontendAction.cpp b/lib/Frontend/FrontendAction.cpp
index d2ece7e..b085749 100644
--- a/lib/Frontend/FrontendAction.cpp
+++ b/lib/Frontend/FrontendAction.cpp
@@ -37,11 +37,16 @@
class DelegatingDeserializationListener : public ASTDeserializationListener {
ASTDeserializationListener *Previous;
+ bool DeletePrevious;
public:
explicit DelegatingDeserializationListener(
- ASTDeserializationListener *Previous)
- : Previous(Previous) { }
+ ASTDeserializationListener *Previous, bool DeletePrevious)
+ : Previous(Previous), DeletePrevious(DeletePrevious) {}
+ virtual ~DelegatingDeserializationListener() {
+ if (DeletePrevious)
+ delete Previous;
+ }
void ReaderInitialized(ASTReader *Reader) override {
if (Previous)
@@ -74,8 +79,9 @@
/// \brief Dumps deserialized declarations.
class DeserializedDeclsDumper : public DelegatingDeserializationListener {
public:
- explicit DeserializedDeclsDumper(ASTDeserializationListener *Previous)
- : DelegatingDeserializationListener(Previous) { }
+ explicit DeserializedDeclsDumper(ASTDeserializationListener *Previous,
+ bool DeletePrevious)
+ : DelegatingDeserializationListener(Previous, DeletePrevious) {}
void DeclRead(serialization::DeclID ID, const Decl *D) override {
llvm::outs() << "PCH DECL: " << D->getDeclKindName();
@@ -96,9 +102,10 @@
public:
DeserializedDeclsChecker(ASTContext &Ctx,
const std::set<std::string> &NamesToCheck,
- ASTDeserializationListener *Previous)
- : DelegatingDeserializationListener(Previous),
- Ctx(Ctx), NamesToCheck(NamesToCheck) { }
+ ASTDeserializationListener *Previous,
+ bool DeletePrevious)
+ : DelegatingDeserializationListener(Previous, DeletePrevious), Ctx(Ctx),
+ NamesToCheck(NamesToCheck) {}
void DeclRead(serialization::DeclID ID, const Decl *D) override {
if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
@@ -116,7 +123,7 @@
} // end anonymous namespace
-FrontendAction::FrontendAction() : Instance(0) {}
+FrontendAction::FrontendAction() : Instance(nullptr) {}
FrontendAction::~FrontendAction() {}
@@ -130,7 +137,7 @@
StringRef InFile) {
ASTConsumer* Consumer = CreateASTConsumer(CI, InFile);
if (!Consumer)
- return 0;
+ return nullptr;
if (CI.getFrontendOpts().AddPluginActions.size() == 0)
return Consumer;
@@ -189,7 +196,7 @@
setCurrentInput(Input, AST);
// Inform the diagnostic client we are processing a source file.
- CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), 0);
+ CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), nullptr);
HasBegunSourceFile = true;
// Set the shared objects, these are reset when we finish processing the
@@ -211,30 +218,13 @@
return true;
}
- if (!CI.getHeaderSearchOpts().VFSOverlayFiles.empty()) {
- IntrusiveRefCntPtr<vfs::OverlayFileSystem>
- Overlay(new vfs::OverlayFileSystem(vfs::getRealFileSystem()));
- // earlier vfs files are on the bottom
- const std::vector<std::string> &Files =
- CI.getHeaderSearchOpts().VFSOverlayFiles;
- for (std::vector<std::string>::const_iterator I = Files.begin(),
- E = Files.end();
- I != E; ++I) {
- std::unique_ptr<llvm::MemoryBuffer> Buffer;
- if (llvm::errc::success != llvm::MemoryBuffer::getFile(*I, Buffer)) {
- CI.getDiagnostics().Report(diag::err_missing_vfs_overlay_file) << *I;
- goto failure;
- }
-
- IntrusiveRefCntPtr<vfs::FileSystem> FS =
- vfs::getVFSFromYAML(Buffer.release(), /*DiagHandler*/ 0);
- if (!FS.getPtr()) {
- CI.getDiagnostics().Report(diag::err_invalid_vfs_overlay) << *I;
- goto failure;
- }
- Overlay->pushOverlay(FS);
- }
- CI.setVirtualFileSystem(Overlay);
+ if (!CI.hasVirtualFileSystem()) {
+ if (IntrusiveRefCntPtr<vfs::FileSystem> VFS =
+ createVFSFromCompilerInvocation(CI.getInvocation(),
+ CI.getDiagnostics()))
+ CI.setVirtualFileSystem(VFS);
+ else
+ goto failure;
}
// Set up the file and source managers, if needed.
@@ -249,13 +239,17 @@
"This action does not have IR file support!");
// Inform the diagnostic client we are processing a source file.
- CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), 0);
+ CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), nullptr);
HasBegunSourceFile = true;
// Initialize the action.
if (!BeginSourceFileAction(CI, InputFile))
goto failure;
+ // Initialize the main file entry.
+ if (!CI.InitializeSourceManager(CurrentInput))
+ goto failure;
+
return true;
}
@@ -302,6 +296,11 @@
if (!BeginSourceFileAction(CI, InputFile))
goto failure;
+ // Initialize the main file entry. It is important that this occurs after
+ // BeginSourceFileAction, which may change CurrentInput during module builds.
+ if (!CI.InitializeSourceManager(CurrentInput))
+ goto failure;
+
// Create the AST context and consumer unless this is a preprocessor only
// action.
if (!usesPreprocessorOnly()) {
@@ -328,17 +327,24 @@
assert(hasPCHSupport() && "This action does not have PCH support!");
ASTDeserializationListener *DeserialListener =
Consumer->GetASTDeserializationListener();
- if (CI.getPreprocessorOpts().DumpDeserializedPCHDecls)
- DeserialListener = new DeserializedDeclsDumper(DeserialListener);
- if (!CI.getPreprocessorOpts().DeserializedPCHDeclsToErrorOn.empty())
- DeserialListener = new DeserializedDeclsChecker(CI.getASTContext(),
- CI.getPreprocessorOpts().DeserializedPCHDeclsToErrorOn,
- DeserialListener);
+ bool DeleteDeserialListener = false;
+ if (CI.getPreprocessorOpts().DumpDeserializedPCHDecls) {
+ DeserialListener = new DeserializedDeclsDumper(DeserialListener,
+ DeleteDeserialListener);
+ DeleteDeserialListener = true;
+ }
+ if (!CI.getPreprocessorOpts().DeserializedPCHDeclsToErrorOn.empty()) {
+ DeserialListener = new DeserializedDeclsChecker(
+ CI.getASTContext(),
+ CI.getPreprocessorOpts().DeserializedPCHDeclsToErrorOn,
+ DeserialListener, DeleteDeserialListener);
+ DeleteDeserialListener = true;
+ }
CI.createPCHExternalASTSource(
- CI.getPreprocessorOpts().ImplicitPCHInclude,
- CI.getPreprocessorOpts().DisablePCHValidation,
- CI.getPreprocessorOpts().AllowPCHWithCompilerErrors,
- DeserialListener);
+ CI.getPreprocessorOpts().ImplicitPCHInclude,
+ CI.getPreprocessorOpts().DisablePCHValidation,
+ CI.getPreprocessorOpts().AllowPCHWithCompilerErrors, DeserialListener,
+ DeleteDeserialListener);
if (!CI.getASTContext().getExternalSource())
goto failure;
}
@@ -352,8 +358,21 @@
// source.
if (!CI.hasASTContext() || !CI.getASTContext().getExternalSource()) {
Preprocessor &PP = CI.getPreprocessor();
+
+ // If modules are enabled, create the module manager before creating
+ // any builtins, so that all declarations know that they might be
+ // extended by an external source.
+ if (CI.getLangOpts().Modules)
+ CI.createModuleManager();
+
PP.getBuiltinInfo().InitializeBuiltins(PP.getIdentifierTable(),
PP.getLangOpts());
+ } else {
+ // FIXME: If this is a problem, recover from it by creating a multiplex
+ // source.
+ assert((!CI.getLangOpts().Modules || CI.getModuleManager()) &&
+ "modules enabled but created an external source that "
+ "doesn't support modules");
}
// If there is a layout overrides file, attach an external AST source that
@@ -365,37 +384,30 @@
CI.getFrontendOpts().OverrideRecordLayoutsFile));
CI.getASTContext().setExternalSource(Override);
}
-
+
return true;
// If we failed, reset state since the client will not end up calling the
// matching EndSourceFile().
failure:
if (isCurrentFileAST()) {
- CI.setASTContext(0);
- CI.setPreprocessor(0);
- CI.setSourceManager(0);
- CI.setFileManager(0);
+ CI.setASTContext(nullptr);
+ CI.setPreprocessor(nullptr);
+ CI.setSourceManager(nullptr);
+ CI.setFileManager(nullptr);
}
if (HasBegunSourceFile)
CI.getDiagnosticClient().EndSourceFile();
CI.clearOutputFiles(/*EraseFiles=*/true);
setCurrentInput(FrontendInputFile());
- setCompilerInstance(0);
+ setCompilerInstance(nullptr);
return false;
}
bool FrontendAction::Execute() {
CompilerInstance &CI = getCompilerInstance();
- // Initialize the main file entry. This needs to be delayed until after PCH
- // has loaded.
- if (!isCurrentFileAST()) {
- if (!CI.InitializeSourceManager(getCurrentInput()))
- return false;
- }
-
if (CI.hasFrontendTimer()) {
llvm::TimeRegion Timer(CI.getFrontendTimer());
ExecuteAction();
@@ -423,22 +435,22 @@
// Finalize the action.
EndSourceFileAction();
- // Release the consumer and the AST, in that order since the consumer may
- // perform actions in its destructor which require the context.
+ // Sema references the ast consumer, so reset sema first.
//
// FIXME: There is more per-file stuff we could just drop here?
- if (CI.getFrontendOpts().DisableFree) {
- BuryPointer(CI.takeASTConsumer());
+ bool DisableFree = CI.getFrontendOpts().DisableFree;
+ if (DisableFree) {
if (!isCurrentFileAST()) {
- BuryPointer(CI.takeSema());
+ CI.resetAndLeakSema();
CI.resetAndLeakASTContext();
}
+ BuryPointer(CI.takeASTConsumer());
} else {
if (!isCurrentFileAST()) {
- CI.setSema(0);
- CI.setASTContext(0);
+ CI.setSema(nullptr);
+ CI.setASTContext(nullptr);
}
- CI.setASTConsumer(0);
+ CI.setASTConsumer(nullptr);
}
// Inform the preprocessor we are done.
@@ -458,15 +470,16 @@
// FrontendAction.
CI.clearOutputFiles(/*EraseFiles=*/shouldEraseOutputFiles());
+ // FIXME: Only do this if DisableFree is set.
if (isCurrentFileAST()) {
- CI.takeSema();
+ CI.resetAndLeakSema();
CI.resetAndLeakASTContext();
CI.resetAndLeakPreprocessor();
CI.resetAndLeakSourceManager();
CI.resetAndLeakFileManager();
}
- setCompilerInstance(0);
+ setCompilerInstance(nullptr);
setCurrentInput(FrontendInputFile());
}
@@ -490,7 +503,7 @@
CI.createCodeCompletionConsumer();
// Use a code completion consumer?
- CodeCompleteConsumer *CompletionConsumer = 0;
+ CodeCompleteConsumer *CompletionConsumer = nullptr;
if (CI.hasCodeCompletionConsumer())
CompletionConsumer = &CI.getCodeCompletionConsumer();