nik updated this revision to Diff 176941. nik added a comment. Added a dedicated diagnostic.
Repository: rC Clang CHANGES SINCE LAST ACTION https://reviews.llvm.org/D53866/new/ https://reviews.llvm.org/D53866 Files: include/clang/Basic/DiagnosticLexKinds.td include/clang/Lex/Preprocessor.h include/clang/Serialization/ASTWriter.h lib/Frontend/PrecompiledPreamble.cpp lib/Lex/PPDirectives.cpp test/Index/preamble-cyclic-include.cpp
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 + 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_including_mainfile_for_preamble); + 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: 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: 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<char> &getPCH() const { return Buffer->Data; } + const Preprocessor &getPreprocessor() const { return PP; } public: PCHGenerator(const Preprocessor &PP, StringRef OutputFile, StringRef isysroot, Index: include/clang/Lex/Preprocessor.h =================================================================== --- include/clang/Lex/Preprocessor.h +++ include/clang/Lex/Preprocessor.h @@ -388,6 +388,7 @@ SmallVector<PPConditionalInfo, 4> 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/Basic/DiagnosticLexKinds.td =================================================================== --- include/clang/Basic/DiagnosticLexKinds.td +++ include/clang/Basic/DiagnosticLexKinds.td @@ -428,6 +428,8 @@ : Error<"'%0' file not found, did you mean '%1'?">; def err_pp_error_opening_file : Error< "error opening file '%0': %1">, DefaultFatal; +def err_pp_including_mainfile_for_preamble : Error< + "main file cannot be included recursively for preamble">, DefaultFatal; def err_pp_empty_filename : Error<"empty filename">; def err_pp_include_too_deep : Error<"#include nested too deeply">; def err_pp_expects_filename : Error<"expected \"FILENAME\" or <FILENAME>">;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits