dgoldman updated this revision to Diff 417623. dgoldman marked 2 inline comments as done. dgoldman added a comment.
Minor fixes Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D122179/new/ https://reviews.llvm.org/D122179 Files: clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp clang/include/clang/Lex/PreprocessorOptions.h clang/include/clang/Serialization/ASTBitCodes.h clang/lib/Lex/PPLexerChange.cpp clang/lib/Serialization/ASTReader.cpp clang/lib/Serialization/ASTWriter.cpp clang/test/Index/preamble-assume-nonnull.c
Index: clang/test/Index/preamble-assume-nonnull.c =================================================================== --- /dev/null +++ clang/test/Index/preamble-assume-nonnull.c @@ -0,0 +1,6 @@ +// RUN: env CINDEXTEST_EDITING=1 c-index-test -test-load-source local %s 2>&1 \ +// RUN: | FileCheck %s --implicit-check-not "error:" + +#pragma clang assume_nonnull begin +void foo(int *x); +#pragma clang assume_nonnull end Index: clang/lib/Serialization/ASTWriter.cpp =================================================================== --- clang/lib/Serialization/ASTWriter.cpp +++ clang/lib/Serialization/ASTWriter.cpp @@ -872,6 +872,7 @@ RECORD(PP_CONDITIONAL_STACK); RECORD(DECLS_TO_CHECK_FOR_DEFERRED_DIAGS); RECORD(PP_INCLUDED_FILES); + RECORD(PP_ASSUME_NONNULL_LOC); // SourceManager Block. BLOCK(SOURCE_MANAGER_BLOCK); @@ -2299,6 +2300,16 @@ Stream.EmitRecord(PP_COUNTER_VALUE, Record); } + // If we have an unterminated #pragma assume_nonnull, remember it since we + // should be at the end of a preamble. + SourceLocation AssumeNonNullLoc = PP.getPragmaAssumeNonNullLoc(); + if (AssumeNonNullLoc.isValid()) { + assert(PP.isRecordingPreamble()); + AddSourceLocation(AssumeNonNullLoc, Record); + Stream.EmitRecord(PP_ASSUME_NONNULL_LOC, Record); + Record.clear(); + } + if (PP.isRecordingPreamble() && PP.hasRecordedPreamble()) { assert(!IsModule); auto SkipInfo = PP.getPreambleSkipInfo(); Index: clang/lib/Serialization/ASTReader.cpp =================================================================== --- clang/lib/Serialization/ASTReader.cpp +++ clang/lib/Serialization/ASTReader.cpp @@ -3109,6 +3109,7 @@ case IDENTIFIER_OFFSET: case INTERESTING_IDENTIFIERS: case STATISTICS: + case PP_ASSUME_NONNULL_LOC: case PP_CONDITIONAL_STACK: case PP_COUNTER_VALUE: case SOURCE_LOCATION_OFFSETS: @@ -3371,6 +3372,13 @@ } break; + case PP_ASSUME_NONNULL_LOC: { + unsigned Idx = 0; + if (!Record.empty()) + PP.setPragmaAssumeNonNullLoc(ReadSourceLocation(F, Record, Idx)); + break; + } + case PP_CONDITIONAL_STACK: if (!Record.empty()) { unsigned Idx = 0, End = Record.size() - 1; Index: clang/lib/Lex/PPLexerChange.cpp =================================================================== --- clang/lib/Lex/PPLexerChange.cpp +++ clang/lib/Lex/PPLexerChange.cpp @@ -427,10 +427,16 @@ PragmaARCCFCodeAuditedInfo = {nullptr, SourceLocation()}; } - // Complain about reaching a true EOF within assume_nonnull. + // Complain about reaching a true EOF. + // // We don't want to complain about reaching the end of a macro // instantiation or a _Pragma. - if (PragmaAssumeNonNullLoc.isValid() && + // + // In addition, we don't want to complain about reaching the end of the + // preamble that we're generating, nor the end of the preamble that the main + // file is using. + if (PragmaAssumeNonNullLoc.isValid() && !this->PPOpts->GeneratePreamble && + !(CurLexer && CurLexer->getFileID() == PredefinesFileID) && !isEndOfMacro && !(CurLexer && CurLexer->Is_PragmaLexer)) { Diag(PragmaAssumeNonNullLoc, diag::err_pp_eof_in_assume_nonnull); Index: clang/include/clang/Serialization/ASTBitCodes.h =================================================================== --- clang/include/clang/Serialization/ASTBitCodes.h +++ clang/include/clang/Serialization/ASTBitCodes.h @@ -698,6 +698,9 @@ /// Record code for included files. PP_INCLUDED_FILES = 66, + + /// Record code for an unterminated \#pragma clang assume_nonnull begin. + PP_ASSUME_NONNULL_LOC = 67, }; /// Record types used within a source manager block. Index: clang/include/clang/Lex/PreprocessorOptions.h =================================================================== --- clang/include/clang/Lex/PreprocessorOptions.h +++ clang/include/clang/Lex/PreprocessorOptions.h @@ -128,7 +128,8 @@ /// /// When the lexer is done, one of the things that need to be preserved is the /// conditional #if stack, so the ASTWriter/ASTReader can save/restore it when - /// processing the rest of the file. + /// processing the rest of the file. Similarly, we track an unterminated + /// #pragma assume_nonnull. bool GeneratePreamble = false; /// Whether to write comment locations into the PCH when building it. Index: clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp =================================================================== --- clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp +++ clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp @@ -20,6 +20,7 @@ #include "index/MemIndex.h" #include "support/Context.h" #include "support/Path.h" +#include "clang/AST/Attr.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/DiagnosticSema.h" #include "llvm/Support/ScopedPrinter.h" @@ -745,6 +746,19 @@ EXPECT_THAT(TU.build().getLocalTopLevelDecls(), SizeIs(1)); } +TEST(DiagnosticsTest, PreambleWithPragmaAssumeNonnull) { + auto TU = TestTU::withCode(R"cpp( +#pragma clang assume_nonnull begin +void foo(int *x); +#pragma clang assume_nonnull end +)cpp"); + auto AST = TU.build(); + EXPECT_THAT(*AST.getDiagnostics(), IsEmpty()); + const auto *X = cast<FunctionDecl>(findDecl(AST, "foo")).getParamDecl(0); + ASSERT_TRUE(X->getOriginalType()->getNullability(X->getASTContext()) == + NullabilityKind::NonNull); +} + TEST(DiagnosticsTest, InsideMacros) { Annotations Test(R"cpp( #define TEN 10
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits