Author: Mike Rice Date: 2022-11-29T10:51:11-08:00 New Revision: 530eb263c0ec02fe8d107cbdb41ac6e482514a00
URL: https://github.com/llvm/llvm-project/commit/530eb263c0ec02fe8d107cbdb41ac6e482514a00 DIFF: https://github.com/llvm/llvm-project/commit/530eb263c0ec02fe8d107cbdb41ac6e482514a00.diff LOG: [clang] Add serialization for loop hint annotation tokens When late parsed templates are used with PCH tokens are serialized. The existing code does not handle annotation tokens which can occur due to various pragmas. This patch implements the serialization for annot_pragma_loop_hint. This also enables use of OpenMP pragmas and #pragma unused which do not need special serialization of the PtrData field. Fixes https://github.com/llvm/llvm-project/issues/39504 Differential Revision: https://reviews.llvm.org/D138453 Added: clang/test/PCH/delayed-template-with-pragma.cpp Modified: clang/docs/ReleaseNotes.rst clang/include/clang/Lex/Token.h clang/include/clang/Serialization/ASTBitCodes.h clang/lib/Parse/ParsePragma.cpp clang/lib/Serialization/ASTReader.cpp clang/lib/Serialization/ASTWriter.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index b4f217c92ffc8..7580b14fac5d6 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -450,6 +450,10 @@ Non-comprehensive list of changes in this release It can be used to writing conditionally constexpr code that uses builtins. - The time profiler (using ``-ftime-trace`` option) now traces various constant evaluation events. +- Clang can now generate a PCH when using ``-fdelayed-template-parsing`` for + code with templates containing loop hint pragmas, OpenMP pragmas, and + ``#pragma unused``. + New Compiler Flags ------------------ diff --git a/clang/include/clang/Lex/Token.h b/clang/include/clang/Lex/Token.h index f0c0794096778..7fd48b1b4391e 100644 --- a/clang/include/clang/Lex/Token.h +++ b/clang/include/clang/Lex/Token.h @@ -15,6 +15,7 @@ #include "clang/Basic/SourceLocation.h" #include "clang/Basic/TokenKinds.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" #include <cassert> @@ -330,6 +331,12 @@ struct PPConditionalInfo { bool FoundElse; }; +// Extra information needed for annonation tokens. +struct PragmaLoopHintInfo { + Token PragmaName; + Token Option; + ArrayRef<Token> Toks; +}; } // end namespace clang #endif // LLVM_CLANG_LEX_TOKEN_H diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h index 591eb34ec8839..ceaade4a6e1e8 100644 --- a/clang/include/clang/Serialization/ASTBitCodes.h +++ b/clang/include/clang/Serialization/ASTBitCodes.h @@ -41,7 +41,7 @@ namespace serialization { /// Version 4 of AST files also requires that the version control branch and /// revision match exactly, since there is no backward compatibility of /// AST files at this time. -const unsigned VERSION_MAJOR = 23; +const unsigned VERSION_MAJOR = 24; /// AST file minor version number supported by this version of /// Clang. diff --git a/clang/lib/Parse/ParsePragma.cpp b/clang/lib/Parse/ParsePragma.cpp index cddc3780133b8..360601f27176a 100644 --- a/clang/lib/Parse/ParsePragma.cpp +++ b/clang/lib/Parse/ParsePragma.cpp @@ -1293,14 +1293,6 @@ bool Parser::HandlePragmaMSAllocText(StringRef PragmaName, return true; } -namespace { -struct PragmaLoopHintInfo { - Token PragmaName; - Token Option; - ArrayRef<Token> Toks; -}; -} // end anonymous namespace - static std::string PragmaLoopHintString(Token PragmaName, Token Option) { StringRef Str = PragmaName.getIdentifierInfo()->getName(); std::string ClangLoopStr("clang loop "); diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 4c0395cc4107b..ff324cab57bf7 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -1669,11 +1669,38 @@ Token ASTReader::ReadToken(ModuleFile &F, const RecordDataImpl &Record, Token Tok; Tok.startToken(); Tok.setLocation(ReadSourceLocation(F, Record, Idx)); - Tok.setLength(Record[Idx++]); - if (IdentifierInfo *II = getLocalIdentifier(F, Record[Idx++])) - Tok.setIdentifierInfo(II); Tok.setKind((tok::TokenKind)Record[Idx++]); Tok.setFlag((Token::TokenFlags)Record[Idx++]); + + if (Tok.isAnnotation()) { + Tok.setAnnotationEndLoc(ReadSourceLocation(F, Record, Idx)); + switch (Tok.getKind()) { + case tok::annot_pragma_loop_hint: { + auto *Info = new (PP.getPreprocessorAllocator()) PragmaLoopHintInfo; + Info->PragmaName = ReadToken(F, Record, Idx); + Info->Option = ReadToken(F, Record, Idx); + unsigned NumTokens = Record[Idx++]; + SmallVector<Token, 4> Toks; + Toks.reserve(NumTokens); + for (unsigned I = 0; I < NumTokens; ++I) + Toks.push_back(ReadToken(F, Record, Idx)); + Info->Toks = llvm::makeArrayRef(Toks).copy(PP.getPreprocessorAllocator()); + Tok.setAnnotationValue(static_cast<void *>(Info)); + break; + } + // Some annotation tokens do not use the PtrData field. + case tok::annot_pragma_openmp: + case tok::annot_pragma_openmp_end: + case tok::annot_pragma_unused: + break; + default: + llvm_unreachable("missing deserialization code for annotation token"); + } + } else { + Tok.setLength(Record[Idx++]); + if (IdentifierInfo *II = getLocalIdentifier(F, Record[Idx++])) + Tok.setIdentifierInfo(II); + } return Tok; } diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 197bbe1b477ac..f1dab7e051e2e 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -4372,15 +4372,37 @@ void ASTRecordWriter::AddAttributes(ArrayRef<const Attr *> Attrs) { void ASTWriter::AddToken(const Token &Tok, RecordDataImpl &Record) { AddSourceLocation(Tok.getLocation(), Record); - Record.push_back(Tok.getLength()); - - // FIXME: When reading literal tokens, reconstruct the literal pointer - // if it is needed. - AddIdentifierRef(Tok.getIdentifierInfo(), Record); // FIXME: Should translate token kind to a stable encoding. Record.push_back(Tok.getKind()); // FIXME: Should translate token flags to a stable encoding. Record.push_back(Tok.getFlags()); + + if (Tok.isAnnotation()) { + AddSourceLocation(Tok.getAnnotationEndLoc(), Record); + switch (Tok.getKind()) { + case tok::annot_pragma_loop_hint: { + auto *Info = static_cast<PragmaLoopHintInfo *>(Tok.getAnnotationValue()); + AddToken(Info->PragmaName, Record); + AddToken(Info->Option, Record); + Record.push_back(Info->Toks.size()); + for (const auto &T : Info->Toks) + AddToken(T, Record); + break; + } + // Some annotation tokens do not use the PtrData field. + case tok::annot_pragma_openmp: + case tok::annot_pragma_openmp_end: + case tok::annot_pragma_unused: + break; + default: + llvm_unreachable("missing serialization code for annotation token"); + } + } else { + Record.push_back(Tok.getLength()); + // FIXME: When reading literal tokens, reconstruct the literal pointer if it + // is needed. + AddIdentifierRef(Tok.getIdentifierInfo(), Record); + } } void ASTWriter::AddString(StringRef Str, RecordDataImpl &Record) { diff --git a/clang/test/PCH/delayed-template-with-pragma.cpp b/clang/test/PCH/delayed-template-with-pragma.cpp new file mode 100644 index 0000000000000..abc959b20707e --- /dev/null +++ b/clang/test/PCH/delayed-template-with-pragma.cpp @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 -fopenmp -emit-pch -o %t.pch %s +// RUN: %clang_cc1 -fopenmp -fdelayed-template-parsing -emit-pch -o %t.delayed.pch %s +// RUN: %clang_cc1 -DMAIN_FILE -fopenmp -include-pch %t.pch \ +// RUN: -emit-llvm -o - %s -fopenmp | FileCheck %s +// RUN: %clang_cc1 -DMAIN_FILE -fopenmp -fdelayed-template-parsing -verify \ +// RUN: -Wunused-variable -include-pch %t.delayed.pch \ +// RUN: -emit-llvm -o - %s | FileCheck %s + +#ifndef MAIN_FILE +template <typename T> +void a(T t) { + #pragma clang loop unroll_count(4) + for(int i=0;i<8;++i) {} + #pragma omp simd + for(int i=0;i<8;++i) {} + { + int x, y, z, zz; + #pragma unused(x) + #pragma unused(y, z) + } +} +#else +// CHECK: !llvm.loop !3 +// CHECK: !llvm.loop !7 +// CHECK: !3 = distinct !{!3, !4, !5} +// CHECK: !4 = !{!"llvm.loop.mustprogress"} +// CHECK: !5 = !{!"llvm.loop.unroll.count", i32 4} +// CHECK: !7 = distinct !{!7, !8, !9} +// CHECK: !8 = !{!"llvm.loop.parallel_accesses", !6} +// CHECK: !9 = !{!"llvm.loop.vectorize.enable", i1 true} +// expected-warning@17 {{unused variable 'zz'}} +void foo() +{ + a(1); +} +#endif _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits