]> granicus.if.org Git - clang/commitdiff
Read/write from/to PCH the diagnostic mappings that the user set so that e.g. #pragma...
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Fri, 5 Nov 2010 22:10:18 +0000 (22:10 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Fri, 5 Nov 2010 22:10:18 +0000 (22:10 +0000)
Fixes rdar://8435969.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@118303 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/Diagnostic.h
include/clang/Serialization/ASTBitCodes.h
include/clang/Serialization/ASTReader.h
include/clang/Serialization/ASTWriter.h
lib/Serialization/ASTReader.cpp
lib/Serialization/ASTWriter.cpp
test/PCH/pragma-diag.c [new file with mode: 0644]

index f9c211f3b14a34f17e612e11d2567417367dc177..53679b8ce3a374b8cd859d27cec80e690b5ab03a 100644 (file)
@@ -640,6 +640,9 @@ private:
   /// \returns true if the diagnostic was emitted, false if it was
   /// suppressed.
   bool ProcessDiag();
+
+  friend class ASTReader;
+  friend class ASTWriter;
 };
 
 //===----------------------------------------------------------------------===//
index dbd4fa91e98eb0792fa3c1efe9aff96c1299bfdd..38b87ed47ca78b9c4baf0043ab3ce20c64675215 100644 (file)
@@ -341,7 +341,10 @@ namespace clang {
       
       /// \brief Record code for the table of offsets to CXXBaseSpecifier
       /// sets.
-      CXX_BASE_SPECIFIER_OFFSETS = 37
+      CXX_BASE_SPECIFIER_OFFSETS = 37,
+
+      /// \brief Record code for diagnostic mappings specified by the user.
+      DIAG_USER_MAPPINGS = 38
     };
 
     /// \brief Record types used within a source manager block.
index 420197c260693d70c9875e716335b5089059de66..b92ca0b6a724a25e235a84a5491327b6e4f2af95 100644 (file)
@@ -570,6 +570,9 @@ private:
 
   //@}
 
+  /// \brief Diagnostic IDs and their mappings that the user changed.
+  llvm::SmallVector<uint64_t, 8> UserDiagMappings;
+
   /// \brief The original file name that was used to build the primary AST file,
   /// which may have been modified for relocatable-pch support.
   std::string OriginalFileName;
@@ -849,6 +852,8 @@ public:
   /// \brief Read preprocessed entities into the 
   virtual void ReadPreprocessedEntities();
 
+  void ReadUserDiagnosticMappings(Diagnostic &Diag);
+
   /// \brief Returns the number of source locations found in the chain.
   unsigned getTotalNumSLocs() const {
     return TotalNumSLocEntries;
index 5a3fd93d495cafd756ad586277fc2515aef081e2..6b7884d525d9dc78e8b969e88fe1732622589625 100644 (file)
@@ -304,6 +304,7 @@ private:
                                const Preprocessor &PP,
                                const char* isysroot);
   void WritePreprocessor(const Preprocessor &PP);
+  void WriteUserDiagnosticMappings(const Diagnostic &Diag);
   void WriteType(QualType T);
   uint64_t WriteDeclContextLexicalBlock(ASTContext &Context, DeclContext *DC);
   uint64_t WriteDeclContextVisibleBlock(ASTContext &Context, DeclContext *DC);
index b90203b477b0dae2d12704fd6b03548a4cd0717c..d70546dbbcf4bb9a813864c7801d9e9fec928a02 100644 (file)
@@ -2130,6 +2130,18 @@ ASTReader::ReadASTBlock(PerFileData &F) {
       F.CXXBaseSpecifiersOffsets = (const uint32_t *)BlobStart;
       break;
     }
+
+    case DIAG_USER_MAPPINGS:
+      if (Record.size() % 2 != 0) {
+        Error("invalid DIAG_USER_MAPPINGS block in AST file");
+        return Failure;
+      }
+      if (UserDiagMappings.empty())
+        UserDiagMappings.swap(Record);
+      else
+        UserDiagMappings.insert(UserDiagMappings.end(),
+                                Record.begin(), Record.end());
+      break;
     }
     First = false;
   }
@@ -2457,6 +2469,8 @@ void ASTReader::InitializeContext(ASTContext &Ctx) {
 
   if (SpecialTypes[SPECIAL_TYPE_INT128_INSTALLED])
     Context->setInt128Installed();
+
+  ReadUserDiagnosticMappings(Context->getDiagnostics());
 }
 
 /// \brief Retrieve the name of the original source file name
@@ -2623,6 +2637,15 @@ void ASTReader::ReadPreprocessedEntities() {
   ReadDefinedMacros();
 }
 
+void ASTReader::ReadUserDiagnosticMappings(Diagnostic &Diag) {
+  unsigned Idx = 0;
+  while (Idx < UserDiagMappings.size()) {
+    unsigned DiagID = UserDiagMappings[Idx++];
+    unsigned Map = UserDiagMappings[Idx++];
+    Diag.setDiagnosticMappingInternal(DiagID, Map, /*isUser=*/true);
+  }
+}
+
 /// \brief Get the correct cursor and offset for loading a type.
 ASTReader::RecordLocation ASTReader::TypeCursorForIndex(unsigned Index) {
   PerFileData *F = 0;
index 47ef72f7bd64a26c1535243dcf1742da71f0a396..a5977f5cfe8d9592119e3b89c9ec4bf80f410e35 100644 (file)
@@ -1441,6 +1441,19 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP) {
   }
 }
 
+void ASTWriter::WriteUserDiagnosticMappings(const Diagnostic &Diag) {
+  RecordData Record;
+  for (unsigned i = 0; i != diag::DIAG_UPPER_LIMIT; ++i) {
+    diag::Mapping Map = Diag.getDiagnosticMappingInfo(i);
+    if (Map & 0x8) { // user mapping.
+      Record.push_back(i);
+      Record.push_back(Map & 0x7);
+    }
+  }
+
+  Stream.EmitRecord(DIAG_USER_MAPPINGS, Record);
+}
+
 //===----------------------------------------------------------------------===//
 // Type Serialization
 //===----------------------------------------------------------------------===//
@@ -2402,6 +2415,7 @@ void ASTWriter::WriteASTCore(Sema &SemaRef, MemorizeStatCalls *StatCalls,
   WriteIdentifierTable(PP);
 
   WriteTypeDeclOffsets();
+  WriteUserDiagnosticMappings(Context.getDiagnostics());
 
   // Write the C++ base-specifier set offsets.
   if (!CXXBaseSpecifiersOffsets.empty()) {
@@ -2635,6 +2649,9 @@ void ASTWriter::WriteASTChain(Sema &SemaRef, MemorizeStatCalls *StatCalls,
   WriteReferencedSelectorsPool(SemaRef);
   WriteIdentifierTable(PP);
   WriteTypeDeclOffsets();
+  // FIXME: For chained PCH only write the new mappings (we currently
+  // write all of them again).
+  WriteUserDiagnosticMappings(Context.getDiagnostics());
 
   /// Build a record containing first declarations from a chained PCH and the
   /// most recent declarations in this AST that they point to.
diff --git a/test/PCH/pragma-diag.c b/test/PCH/pragma-diag.c
new file mode 100644 (file)
index 0000000..c517103
--- /dev/null
@@ -0,0 +1,19 @@
+// Test this without pch.
+// RUN: %clang_cc1 %s -include %s -verify -fsyntax-only
+
+// Test with pch.
+// RUN: %clang_cc1 %s -emit-pch -o %t
+// RUN: %clang_cc1 %s -include-pch %t -verify -fsyntax-only
+
+#ifndef HEADER
+#define HEADER
+
+#pragma clang diagnostic ignored "-Wtautological-compare"
+
+#else
+
+void f() {
+  int b = b==b;
+}
+
+#endif