]> granicus.if.org Git - clang/commitdiff
Part of adding an improved ODR checker.
authorRichard Trieu <rtrieu@google.com>
Sat, 18 Feb 2017 02:09:28 +0000 (02:09 +0000)
committerRichard Trieu <rtrieu@google.com>
Sat, 18 Feb 2017 02:09:28 +0000 (02:09 +0000)
Reserve a spot for ODR hash in CXXRecordDecl and in its modules storage.
Default the hash value to 0 for all classes.

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

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

include/clang/AST/DeclCXX.h
lib/AST/DeclCXX.cpp
lib/Sema/SemaDecl.cpp
lib/Serialization/ASTReaderDecl.cpp
lib/Serialization/ASTWriter.cpp

index 7267afdc7ffb7e7ced85d06bce2b75321ab4b6a1..d321d19068bf4a1e3dc21bb0b5b4e33e75a9e9fc 100644 (file)
@@ -458,6 +458,9 @@ class CXXRecordDecl : public RecordDecl {
     /// \brief Whether we are currently parsing base specifiers.
     unsigned IsParsingBaseSpecifiers : 1;
 
+    /// \brief A hash of parts of the class to help in ODR checking.
+    unsigned ODRHash;
+
     /// \brief The number of base class specifiers in Bases.
     unsigned NumBases;
 
@@ -703,6 +706,9 @@ public:
     return data().IsParsingBaseSpecifiers;
   }
 
+  void computeODRHash();
+  unsigned getODRHash() const { return data().ODRHash; }
+
   /// \brief Sets the base classes of this struct or class.
   void setBases(CXXBaseSpecifier const * const *Bases, unsigned NumBases);
 
index fdfd6c07059a78cf54de56034d6487273c65fa68..19ffe1a720b375454c5eaa744665926a957c7fc2 100644 (file)
@@ -71,8 +71,8 @@ CXXRecordDecl::DefinitionData::DefinitionData(CXXRecordDecl *D)
       ImplicitCopyAssignmentHasConstParam(true),
       HasDeclaredCopyConstructorWithConstParam(false),
       HasDeclaredCopyAssignmentWithConstParam(false), IsLambda(false),
-      IsParsingBaseSpecifiers(false), NumBases(0), NumVBases(0), Bases(),
-      VBases(), Definition(D), FirstFriend() {}
+      IsParsingBaseSpecifiers(false), ODRHash(0), NumBases(0), NumVBases(0),
+      Bases(), VBases(), Definition(D), FirstFriend() {}
 
 CXXBaseSpecifier *CXXRecordDecl::DefinitionData::getBasesSlowCase() const {
   return Bases.get(Definition->getASTContext().getExternalSource());
@@ -371,6 +371,8 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases,
   data().IsParsingBaseSpecifiers = false;
 }
 
+void CXXRecordDecl::computeODRHash() {}
+
 void CXXRecordDecl::addedClassSubobject(CXXRecordDecl *Subobj) {
   // C++11 [class.copy]p11:
   //   A defaulted copy/move constructor for a class X is defined as
index 77d749830286a2b92d37f80f16d464c016556182..e96860a294ea12c354d0324ba6c034f6ebf40573 100644 (file)
@@ -13771,8 +13771,11 @@ void Sema::ActOnTagFinishDefinition(Scope *S, Decl *TagD,
       RD->completeDefinition();
   }
 
-  if (isa<CXXRecordDecl>(Tag))
+  if (auto *RD = dyn_cast<CXXRecordDecl>(Tag)) {
     FieldCollector->FinishClass();
+    if (Context.getLangOpts().Modules)
+      RD->computeODRHash();
+  }
 
   // Exit this scope of this tag's definition.
   PopDeclContext();
index add3b3e828e39a2429fa7fb3395d75fd461c6bdd..0f43e9fcf643b9b511e26b3349c51eccf0b4e05c 100644 (file)
@@ -1528,6 +1528,7 @@ void ASTDeclReader::ReadCXXDefinitionData(
   Data.ImplicitCopyAssignmentHasConstParam = Record.readInt();
   Data.HasDeclaredCopyConstructorWithConstParam = Record.readInt();
   Data.HasDeclaredCopyAssignmentWithConstParam = Record.readInt();
+  Data.ODRHash = Record.readInt();
 
   Data.NumBases = Record.readInt();
   if (Data.NumBases)
@@ -1658,6 +1659,7 @@ void ASTDeclReader::MergeDefinitionData(
   OR_FIELD(HasDeclaredCopyConstructorWithConstParam)
   OR_FIELD(HasDeclaredCopyAssignmentWithConstParam)
   MATCH_FIELD(IsLambda)
+  MATCH_FIELD(ODRHash)
 #undef OR_FIELD
 #undef MATCH_FIELD
 
index 5dee86c14190ed753242b9ab12e41025382172ca..5fe693ba8e1528a931b7546d340365a436a65252 100644 (file)
@@ -5707,6 +5707,7 @@ void ASTRecordWriter::AddCXXDefinitionData(const CXXRecordDecl *D) {
   Record->push_back(Data.ImplicitCopyAssignmentHasConstParam);
   Record->push_back(Data.HasDeclaredCopyConstructorWithConstParam);
   Record->push_back(Data.HasDeclaredCopyAssignmentWithConstParam);
+  Record->push_back(Data.ODRHash);
   // IsLambda bit is already saved.
 
   Record->push_back(Data.NumBases);