Teach CompilerInstance to create and hold on to the Sema object used
for parsing, so that it can persist beyond the lifetime of the parsing
call.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@110978 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Frontend/CompilerInstance.h b/include/clang/Frontend/CompilerInstance.h
index 4a4d5ae..bd1791d 100644
--- a/include/clang/Frontend/CompilerInstance.h
+++ b/include/clang/Frontend/CompilerInstance.h
@@ -36,6 +36,7 @@
class FrontendAction;
class PCHReader;
class Preprocessor;
+class Sema;
class SourceManager;
class TargetInfo;
@@ -91,6 +92,9 @@
/// The code completion consumer.
llvm::OwningPtr<CodeCompleteConsumer> CompletionConsumer;
+ /// \brief The semantic analysis object.
+ llvm::OwningPtr<Sema> TheSema;
+
/// The frontend timer
llvm::OwningPtr<llvm::Timer> FrontendTimer;
@@ -369,6 +373,10 @@
/// takes ownership of \arg Value.
void setASTContext(ASTContext *Value);
+ /// \brief Replace the current Sema; the compiler instance takes ownership
+ /// of S.
+ void setSema(Sema *S);
+
/// }
/// @name ASTConsumer
/// {
@@ -389,6 +397,18 @@
void setASTConsumer(ASTConsumer *Value);
/// }
+ /// @name Semantic analysis
+ /// {
+ bool hasSema() const { return TheSema != 0; }
+
+ Sema &getSema() const {
+ assert(TheSema && "Compiler instance has no Sema object!");
+ return *TheSema;
+ }
+
+ Sema *takeSema() { return TheSema.take(); }
+
+ /// }
/// @name Code Completion
/// {
@@ -526,6 +546,10 @@
bool UseDebugPrinter, bool ShowMacros,
bool ShowCodePatterns, llvm::raw_ostream &OS);
+ /// \brief Create the Sema object to be used for parsing.
+ void createSema(bool CompleteTranslationUnit,
+ CodeCompleteConsumer *CompletionConsumer);
+
/// Create the frontend timer and replace any existing one with it.
void createFrontendTimer();
diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp
index 76773e4..e2bb0f2 100644
--- a/lib/Frontend/CompilerInstance.cpp
+++ b/lib/Frontend/CompilerInstance.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Sema/Sema.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/Basic/Diagnostic.h"
@@ -41,6 +42,7 @@
}
CompilerInstance::~CompilerInstance() {
+ TheSema.reset();
}
void CompilerInstance::setLLVMContext(llvm::LLVMContext *Value) {
@@ -79,6 +81,10 @@
Context.reset(Value);
}
+void CompilerInstance::setSema(Sema *S) {
+ TheSema.reset(S);
+}
+
void CompilerInstance::setASTConsumer(ASTConsumer *Value) {
Consumer.reset(Value);
}
@@ -362,6 +368,12 @@
return new CIndexCodeCompleteConsumer(ShowMacros, ShowCodePatterns, OS);
}
+void CompilerInstance::createSema(bool CompleteTranslationUnit,
+ CodeCompleteConsumer *CompletionConsumer) {
+ TheSema.reset(new Sema(getPreprocessor(), getASTContext(), getASTConsumer(),
+ CompleteTranslationUnit, CompletionConsumer));
+}
+
// Output Files
void CompilerInstance::addOutputFile(llvm::StringRef Path,
diff --git a/lib/Frontend/FrontendAction.cpp b/lib/Frontend/FrontendAction.cpp
index 90b8786..40b4e7f 100644
--- a/lib/Frontend/FrontendAction.cpp
+++ b/lib/Frontend/FrontendAction.cpp
@@ -196,12 +196,16 @@
// FIXME: There is more per-file stuff we could just drop here?
if (CI.getFrontendOpts().DisableFree) {
CI.takeASTConsumer();
- if (!isCurrentFileAST())
+ if (!isCurrentFileAST()) {
+ CI.takeSema();
CI.takeASTContext();
+ }
} else {
- CI.setASTConsumer(0);
- if (!isCurrentFileAST())
+ if (!isCurrentFileAST()) {
+ CI.setSema(0);
CI.setASTContext(0);
+ }
+ CI.setASTConsumer(0);
}
// Inform the preprocessor we are done.
@@ -225,6 +229,7 @@
CI.getDiagnosticClient().EndSourceFile();
if (isCurrentFileAST()) {
+ CI.takeSema();
CI.takeASTContext();
CI.takePreprocessor();
CI.takeSourceManager();
@@ -253,9 +258,10 @@
if (CI.hasCodeCompletionConsumer())
CompletionConsumer = &CI.getCodeCompletionConsumer();
- ParseAST(CI.getPreprocessor(), &CI.getASTConsumer(), CI.getASTContext(),
- CI.getFrontendOpts().ShowStats,
- usesCompleteTranslationUnit(), CompletionConsumer);
+ if (!CI.hasSema())
+ CI.createSema(usesCompleteTranslationUnit(), CompletionConsumer);
+
+ ParseAST(CI.getSema(), CI.getFrontendOpts().ShowStats);
}
ASTConsumer *