Flip the order the preprocessor and frontendaction are informed of the end of a file.

This allows using EndOfMainFile from a PPCallback to access data from the
action. The pattern of PPCallback referencing an action is common in clang-tidy.

Differential Revision: http://reviews.llvm.org/D4773

llvm-svn: 215145
This commit is contained in:
Benjamin Kramer 2014-08-07 20:51:16 +00:00
parent ec2fac8a13
commit 88d99e4f42
2 changed files with 50 additions and 4 deletions

View File

@ -432,6 +432,10 @@ void FrontendAction::EndSourceFile() {
// Inform the diagnostic client we are done with this source file.
CI.getDiagnosticClient().EndSourceFile();
// Inform the preprocessor we are done.
if (CI.hasPreprocessor())
CI.getPreprocessor().EndSourceFile();
// Finalize the action.
EndSourceFileAction();
@ -453,10 +457,6 @@ void FrontendAction::EndSourceFile() {
CI.setASTConsumer(nullptr);
}
// Inform the preprocessor we are done.
if (CI.hasPreprocessor())
CI.getPreprocessor().EndSourceFile();
if (CI.getFrontendOpts().ShowStats) {
llvm::errs() << "\nSTATISTICS FOR '" << getCurrentFile() << "':\n";
CI.getPreprocessor().PrintStats();

View File

@ -100,4 +100,50 @@ TEST(ASTFrontendAction, IncrementalParsing) {
EXPECT_EQ("x", test_action.decl_names[1]);
}
struct TestPPCallbacks : public PPCallbacks {
TestPPCallbacks() : SeenEnd(false) {}
void EndOfMainFile() override { SeenEnd = true; }
bool SeenEnd;
};
class TestPPCallbacksFrontendAction : public PreprocessorFrontendAction {
TestPPCallbacks *Callbacks;
public:
TestPPCallbacksFrontendAction(TestPPCallbacks *C)
: Callbacks(C), SeenEnd(false) {}
void ExecuteAction() override {
Preprocessor &PP = getCompilerInstance().getPreprocessor();
PP.addPPCallbacks(Callbacks);
PP.EnterMainSourceFile();
}
void EndSourceFileAction() override { SeenEnd = Callbacks->SeenEnd; }
bool SeenEnd;
};
TEST(PreprocessorFrontendAction, EndSourceFile) {
CompilerInvocation *Invocation = new CompilerInvocation;
Invocation->getPreprocessorOpts().addRemappedFile(
"test.cc", MemoryBuffer::getMemBuffer("int main() { float x; }"));
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();
TestPPCallbacks *Callbacks = new TestPPCallbacks;
TestPPCallbacksFrontendAction TestAction(Callbacks);
ASSERT_FALSE(Callbacks->SeenEnd);
ASSERT_FALSE(TestAction.SeenEnd);
ASSERT_TRUE(Compiler.ExecuteAction(TestAction));
// Check that EndOfMainFile was called before EndSourceFileAction.
ASSERT_TRUE(TestAction.SeenEnd);
}
} // anonymous namespace