r295931 - [ODRHash] Handle types in ODR hashing.

Richard Trieu via cfe-commits cfe-commits at lists.llvm.org
Wed Feb 22 19:25:58 PST 2017


Author: rtrieu
Date: Wed Feb 22 21:25:57 2017
New Revision: 295931

URL: http://llvm.org/viewvc/llvm-project?rev=295931&view=rev
Log:
[ODRHash] Handle types in ODR hashing.

Fields will now have their types added to the hash, allowing for detection of
mismatched field types.  This detection allows the existing ODR checking to
produce the correct message.

Differential Revision: https://reviews.llvm.org/D21675

Modified:
    cfe/trunk/lib/AST/ODRHash.cpp
    cfe/trunk/test/Modules/odr_hash.cpp

Modified: cfe/trunk/lib/AST/ODRHash.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ODRHash.cpp?rev=295931&r1=295930&r2=295931&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ODRHash.cpp (original)
+++ cfe/trunk/lib/AST/ODRHash.cpp Wed Feb 22 21:25:57 2017
@@ -102,6 +102,10 @@ public:
     }
   }
 
+  void AddQualType(QualType T) {
+    Hash.AddQualType(T);
+  }
+
   void Visit(const Decl *D) {
     ID.AddInteger(D->getKind());
     Inherited::Visit(D);
@@ -112,6 +116,11 @@ public:
     Inherited::VisitNamedDecl(D);
   }
 
+  void VisitValueDecl(const ValueDecl *D) {
+    AddQualType(D->getType());
+    Inherited::VisitValueDecl(D);
+  }
+
   void VisitAccessSpecDecl(const AccessSpecDecl *D) {
     ID.AddInteger(D->getAccess());
     Inherited::VisitAccessSpecDecl(D);
@@ -185,8 +194,59 @@ void ODRHash::AddDecl(const Decl *D) {
   ID.AddInteger(D->getKind());
 }
 
-void ODRHash::AddType(const Type *T) {}
-void ODRHash::AddQualType(QualType T) {}
+// Process a Type pointer.  Add* methods call back into ODRHash while Visit*
+// methods process the relevant parts of the Type.
+class ODRTypeVisitor : public TypeVisitor<ODRTypeVisitor> {
+  typedef TypeVisitor<ODRTypeVisitor> Inherited;
+  llvm::FoldingSetNodeID &ID;
+  ODRHash &Hash;
+
+public:
+  ODRTypeVisitor(llvm::FoldingSetNodeID &ID, ODRHash &Hash)
+      : ID(ID), Hash(Hash) {}
+
+  void AddStmt(Stmt *S) {
+    Hash.AddBoolean(S);
+    if (S) {
+      Hash.AddStmt(S);
+    }
+  }
+
+  void Visit(const Type *T) {
+    ID.AddInteger(T->getTypeClass());
+    Inherited::Visit(T);
+  }
+
+  void VisitType(const Type *T) {}
+
+  void VisitBuiltinType(const BuiltinType *T) {
+    ID.AddInteger(T->getKind());
+    VisitType(T);
+  }
+};
+
+void ODRHash::AddType(const Type *T) {
+  assert(T && "Expecting non-null pointer.");
+  auto Result = TypeMap.insert(std::make_pair(T, TypeMap.size()));
+  ID.AddInteger(Result.first->second);
+  // On first encounter of a Type pointer, process it.  Every time afterwards,
+  // only the index value is needed.
+  if (!Result.second) {
+    return;
+  }
+
+  ODRTypeVisitor(ID, *this).Visit(T);
+}
+
+void ODRHash::AddQualType(QualType T) {
+  AddBoolean(T.isNull());
+  if (T.isNull())
+    return;
+  SplitQualType split = T.split();
+  ID.AddInteger(split.Quals.getAsOpaqueValue());
+  AddType(split.Ty);
+}
+
 void ODRHash::AddBoolean(bool Value) {
   Bools.push_back(Value);
 }

Modified: cfe/trunk/test/Modules/odr_hash.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/odr_hash.cpp?rev=295931&r1=295930&r2=295931&view=diff
==============================================================================
--- cfe/trunk/test/Modules/odr_hash.cpp (original)
+++ cfe/trunk/test/Modules/odr_hash.cpp Wed Feb 22 21:25:57 2017
@@ -148,6 +148,20 @@ S2 s2;
 // expected-error at second.h:* {{'Field::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'y'}}
 // expected-note at first.h:* {{but in 'FirstModule' found field 'x'}}
 #endif
+
+#if defined(FIRST)
+struct S3 {
+  double x;
+};
+#elif defined(SECOND)
+struct S3 {
+  int x;
+};
+#else
+S3 s3;
+// expected-error at first.h:* {{'Field::S3::x' from module 'FirstModule' is not present in definition of 'Field::S3' in module 'SecondModule'}}
+// expected-note at second.h:* {{declaration of 'x' does not match}}
+#endif
 }  // namespace Field
 
 // Naive parsing of AST can lead to cycles in processing.  Ensure




More information about the cfe-commits mailing list