summaryrefslogtreecommitdiffstats
path: root/clang/unittests/Frontend/FrontendActionTest.cpp
diff options
context:
space:
mode:
authorReid Kleckner <reid@kleckner.net>2014-10-15 17:08:33 +0000
committerReid Kleckner <reid@kleckner.net>2014-10-15 17:08:33 +0000
commit001fe64333f184251ea72aba8b3b8144e2a2b9df (patch)
tree391de84dfaa5949a547d46c32d325d59642948f7 /clang/unittests/Frontend/FrontendActionTest.cpp
parent4e0854f23c9b084c4fbfd02e304c28c292588f1a (diff)
downloadbcm5719-llvm-001fe64333f184251ea72aba8b3b8144e2a2b9df.tar.gz
bcm5719-llvm-001fe64333f184251ea72aba8b3b8144e2a2b9df.zip
Fix late template parsing leak with incremental processing
Add a second late template parser callback meant to cleanup any resources allocated by late template parsing. Call it from the Sema::ActOnEndOfTranslationUnit method after all pending template instantiations have been completed. Teach Parser::ParseTopLevelDecl to install the cleanup callback when incremental processing is enabled so that Parser::TemplateIds can be freed. Patch by Brad King! llvm-svn: 219810
Diffstat (limited to 'clang/unittests/Frontend/FrontendActionTest.cpp')
-rw-r--r--clang/unittests/Frontend/FrontendActionTest.cpp49
1 files changed, 45 insertions, 4 deletions
diff --git a/clang/unittests/Frontend/FrontendActionTest.cpp b/clang/unittests/Frontend/FrontendActionTest.cpp
index 31711566921..9973d3f8bea 100644
--- a/clang/unittests/Frontend/FrontendActionTest.cpp
+++ b/clang/unittests/Frontend/FrontendActionTest.cpp
@@ -14,6 +14,7 @@
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/CompilerInvocation.h"
#include "clang/Lex/Preprocessor.h"
+#include "clang/Sema/Sema.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Support/MemoryBuffer.h"
#include "gtest/gtest.h"
@@ -25,10 +26,13 @@ namespace {
class TestASTFrontendAction : public ASTFrontendAction {
public:
- TestASTFrontendAction(bool enableIncrementalProcessing = false)
- : EnableIncrementalProcessing(enableIncrementalProcessing) { }
+ TestASTFrontendAction(bool enableIncrementalProcessing = false,
+ bool actOnEndOfTranslationUnit = false)
+ : EnableIncrementalProcessing(enableIncrementalProcessing),
+ ActOnEndOfTranslationUnit(actOnEndOfTranslationUnit) { }
bool EnableIncrementalProcessing;
+ bool ActOnEndOfTranslationUnit;
std::vector<std::string> decl_names;
virtual bool BeginSourceFileAction(CompilerInstance &ci, StringRef filename) {
@@ -40,15 +44,22 @@ public:
virtual std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
StringRef InFile) {
- return llvm::make_unique<Visitor>(decl_names);
+ return llvm::make_unique<Visitor>(CI, ActOnEndOfTranslationUnit,
+ decl_names);
}
private:
class Visitor : public ASTConsumer, public RecursiveASTVisitor<Visitor> {
public:
- Visitor(std::vector<std::string> &decl_names) : decl_names_(decl_names) {}
+ Visitor(CompilerInstance &ci, bool actOnEndOfTranslationUnit,
+ std::vector<std::string> &decl_names) :
+ CI(ci), ActOnEndOfTranslationUnit(actOnEndOfTranslationUnit),
+ decl_names_(decl_names) {}
virtual void HandleTranslationUnit(ASTContext &context) {
+ if (ActOnEndOfTranslationUnit) {
+ CI.getSema().ActOnEndOfTranslationUnit();
+ }
TraverseDecl(context.getTranslationUnitDecl());
}
@@ -58,6 +69,8 @@ private:
}
private:
+ CompilerInstance &CI;
+ bool ActOnEndOfTranslationUnit;
std::vector<std::string> &decl_names_;
};
};
@@ -102,6 +115,34 @@ TEST(ASTFrontendAction, IncrementalParsing) {
EXPECT_EQ("x", test_action.decl_names[1]);
}
+TEST(ASTFrontendAction, LateTemplateIncrementalParsing) {
+ CompilerInvocation *invocation = new CompilerInvocation;
+ invocation->getLangOpts()->CPlusPlus = true;
+ invocation->getLangOpts()->DelayedTemplateParsing = true;
+ invocation->getPreprocessorOpts().addRemappedFile(
+ "test.cc", MemoryBuffer::getMemBuffer(
+ "template<typename T> struct A { A(T); T data; };\n"
+ "template<typename T> struct B: public A<T> {\n"
+ " B();\n"
+ " B(B const& b): A<T>(b.data) {}\n"
+ "};\n"
+ "B<char> c() { return B<char>(); }\n").release());
+ invocation->getFrontendOpts().Inputs.push_back(FrontendInputFile("test.cc",
+ IK_CXX));
+ invocation->getFrontendOpts().ProgramAction = frontend::ParseSyntaxOnly;
+ invocation->getTargetOpts().Triple = "i386-unknown-linux-gnu";
+ CompilerInstance compiler;
+ compiler.setInvocation(invocation);
+ compiler.createDiagnostics();
+
+ TestASTFrontendAction test_action(/*enableIncrementalProcessing=*/true,
+ /*actOnEndOfTranslationUnit=*/true);
+ ASSERT_TRUE(compiler.ExecuteAction(test_action));
+ ASSERT_EQ(13U, test_action.decl_names.size());
+ EXPECT_EQ("A", test_action.decl_names[0]);
+ EXPECT_EQ("c", test_action.decl_names[12]);
+}
+
struct TestPPCallbacks : public PPCallbacks {
TestPPCallbacks() : SeenEnd(false) {}
OpenPOWER on IntegriCloud