Index: include/clang/Lex/Preprocessor.h =================================================================== --- include/clang/Lex/Preprocessor.h +++ include/clang/Lex/Preprocessor.h @@ -388,6 +388,7 @@ SmallVector ConditionalStack; State ConditionalStackState = Off; } PreambleConditionalStack; + bool PreambleGenerationFailed = false; /// The current top of the stack that we're lexing from if /// not expanding a macro and we are lexing directly from source code. @@ -2159,6 +2160,10 @@ Module *M, SourceLocation MLoc); + bool preambleGenerationFailed() const { + return PreambleGenerationFailed; + } + bool isRecordingPreamble() const { return PreambleConditionalStack.isRecording(); } Index: include/clang/Serialization/ASTWriter.h =================================================================== --- include/clang/Serialization/ASTWriter.h +++ include/clang/Serialization/ASTWriter.h @@ -979,6 +979,7 @@ ASTWriter &getWriter() { return Writer; } const ASTWriter &getWriter() const { return Writer; } SmallVectorImpl &getPCH() const { return Buffer->Data; } + const Preprocessor &getPreprocessor() const { return PP; } public: PCHGenerator(const Preprocessor &PP, StringRef OutputFile, StringRef isysroot, Index: lib/Frontend/PrecompiledPreamble.cpp =================================================================== --- lib/Frontend/PrecompiledPreamble.cpp +++ lib/Frontend/PrecompiledPreamble.cpp @@ -170,6 +170,9 @@ } void HandleTranslationUnit(ASTContext &Ctx) override { + if (getPreprocessor().preambleGenerationFailed()) + return; + PCHGenerator::HandleTranslationUnit(Ctx); if (!hasEmittedPCH()) return; Index: lib/Lex/PPDirectives.cpp =================================================================== --- lib/Lex/PPDirectives.cpp +++ lib/Lex/PPDirectives.cpp @@ -1933,6 +1933,20 @@ return; } + // Check whether it makes sense to continue preamble generation. We can't + // generate a consistent preamble with regard to the conditional stack if the + // main file is included again as due to the preamble bounds some directives + // (e.g. #endif of a header guard) will never be seen. Since this will lead to + // confusing errors, abort the preamble generation. + if (File && PreambleConditionalStack.isRecording() && + SourceMgr.translateFile(File) == SourceMgr.getMainFileID()) { + PreambleGenerationFailed = true; + // Generate a fatal error to skip further processing. + Diag(FilenameTok.getLocation(), diag::err_pp_error_opening_file) << "" + << ""; + return; + } + // Should we enter the source file? Set to false if either the source file is // known to have no effect beyond its effect on module visibility -- that is, // if it's got an include guard that is already defined or is a modular header Index: test/Index/preamble-cyclic-include.cpp =================================================================== --- /dev/null +++ test/Index/preamble-cyclic-include.cpp @@ -0,0 +1,9 @@ +// RUN: env CINDEXTEST_EDITING=1 c-index-test -test-annotate-tokens=%s:4:1:8:1 %s 2>&1 | FileCheck %s +// CHECK-NOT: error: unterminated conditional directive +// CHECK-NOT: Skipping: [4:1 - 8:7] +#ifndef A_H +#define A_H +# include "preamble-cyclic-include.cpp" +int bar(); +#endif +