[clang] 530eb26 - [clang] Add serialization for loop hint annotation tokens

Mike Rice via cfe-commits cfe-commits at lists.llvm.org
Tue Nov 29 10:56:07 PST 2022


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 at 17 {{unused variable 'zz'}}
+void foo()
+{
+  a(1);
+}
+#endif


        


More information about the cfe-commits mailing list