Skip to content

Commit ddb18ff

Browse files
author
git apple-llvm automerger
committed
Merge commit 'd20ae6985438' from apple/stable/20200108 into swift/master-rebranch
2 parents cb317fc + d20ae69 commit ddb18ff

File tree

11 files changed

+1185
-763
lines changed

11 files changed

+1185
-763
lines changed

clang/include/clang/AST/DeclObjC.h

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1196,6 +1196,7 @@ class ObjCContainerDecl : public NamedDecl, public DeclContext {
11961196
class ObjCInterfaceDecl : public ObjCContainerDecl
11971197
, public Redeclarable<ObjCInterfaceDecl> {
11981198
friend class ASTContext;
1199+
friend class ASTReader;
11991200

12001201
/// TypeForDecl - This indicates the Type object that represents this
12011202
/// TypeDecl. It is a cache maintained by ASTContext::getObjCInterfaceType
@@ -1253,6 +1254,12 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
12531254
/// One of the \c InheritedDesignatedInitializersState enumeratos.
12541255
mutable unsigned InheritedDesignatedInitializers : 2;
12551256

1257+
/// Tracks whether a ODR hash has been computed for this interface.
1258+
unsigned HasODRHash : 1;
1259+
1260+
/// A hash of parts of the class to help in ODR checking.
1261+
unsigned ODRHash = 0;
1262+
12561263
/// The location of the last location in this declaration, before
12571264
/// the properties/methods. For example, this will be the '>', '}', or
12581265
/// identifier,
@@ -1261,7 +1268,7 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
12611268
DefinitionData()
12621269
: ExternallyCompleted(false), IvarListMissingImplementation(true),
12631270
HasDesignatedInitializers(false),
1264-
InheritedDesignatedInitializers(IDI_Unknown) {}
1271+
InheritedDesignatedInitializers(IDI_Unknown), HasODRHash(false) {}
12651272
};
12661273

12671274
/// The type parameters associated with this class, if any.
@@ -1946,7 +1953,14 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
19461953
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
19471954
static bool classofKind(Kind K) { return K == ObjCInterface; }
19481955

1956+
/// Get precomputed ODRHash or add a new one.
1957+
unsigned getODRHash();
1958+
19491959
private:
1960+
/// True if a valid hash is stored in ODRHash.
1961+
bool hasODRHash() const;
1962+
void setHasODRHash(bool Hash = true);
1963+
19501964
const ObjCInterfaceDecl *findInterfaceWithDesignatedInitializers() const;
19511965
bool inheritsDesignatedInitializers() const;
19521966
};

clang/include/clang/AST/ODRHash.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ class ODRHash {
5959
// method compares more information than the AddDecl class.
6060
void AddRecordDecl(const RecordDecl *Record);
6161

62+
// Use this for ODR checking ObjC interfaces. This
63+
// method compares more information than the AddDecl class.
64+
void AddObjCInterfaceDecl(const ObjCInterfaceDecl *Record);
65+
6266
// Use this for ODR checking functions between modules. This method compares
6367
// more information than the AddDecl class. SkipBody will process the
6468
// hash as if the function has no body.

clang/include/clang/Basic/DiagnosticSerializationKinds.td

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,21 @@ def note_module_odr_violation_definition_data : Note <
153153
"%ordinal2 base class %3 with "
154154
"%select{public|protected|private|no}4 access specifier}1">;
155155

156+
def err_module_odr_violation_obj_interface_definition_data : Error <
157+
"%q0 has different definitions in different modules; first difference is "
158+
"%select{definition in module '%2'|defined here}1 found "
159+
"%select{"
160+
"%select{no super class|super class with type %5}4|"
161+
"%4 referenced %plural{1:protocol|:protocols}4|"
162+
"}3">;
163+
164+
def note_module_odr_violation_obj_interface_definition_data : Note <
165+
"but in '%0' found "
166+
"%select{"
167+
"%select{no super class|super class with type %3}2|"
168+
"%2 referenced %plural{1:protocol|:protocols}2|"
169+
"}1">;
170+
156171
def err_module_odr_violation_template_parameter : Error <
157172
"%q0 has different definitions in different modules; first difference is "
158173
"%select{definition in module '%2'|defined here}1 found "

clang/include/clang/Serialization/ASTReader.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#ifndef LLVM_CLANG_SERIALIZATION_ASTREADER_H
1414
#define LLVM_CLANG_SERIALIZATION_ASTREADER_H
1515

16+
#include "clang/AST/DeclObjC.h"
1617
#include "clang/AST/Type.h"
1718
#include "clang/Basic/Diagnostic.h"
1819
#include "clang/Basic/DiagnosticOptions.h"
@@ -1087,6 +1088,8 @@ class ASTReader
10871088

10881089
using DataPointers =
10891090
std::pair<CXXRecordDecl *, struct CXXRecordDecl::DefinitionData *>;
1091+
using IDDataPointers = std::pair<ObjCInterfaceDecl *,
1092+
struct ObjCInterfaceDecl::DefinitionData *>;
10901093

10911094
/// Record definitions in which we found an ODR violation.
10921095
llvm::SmallDenseMap<CXXRecordDecl *, llvm::SmallVector<DataPointers, 2>, 2>
@@ -1104,6 +1107,11 @@ class ASTReader
11041107
llvm::SmallDenseMap<RecordDecl *, llvm::SmallVector<RecordDecl *, 2>, 2>
11051108
PendingRecordOdrMergeFailures;
11061109

1110+
/// ObjCInterfaceDecl in which we found an ODR violation.
1111+
llvm::SmallDenseMap<ObjCInterfaceDecl *, llvm::SmallVector<IDDataPointers, 2>,
1112+
2>
1113+
PendingObjCInterfaceOdrMergeFailures;
1114+
11071115
/// DeclContexts in which we have diagnosed an ODR violation.
11081116
llvm::SmallPtrSet<DeclContext*, 2> DiagnosedOdrMergeFailures;
11091117

clang/lib/AST/DeclObjC.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "clang/AST/Attr.h"
1717
#include "clang/AST/Decl.h"
1818
#include "clang/AST/DeclBase.h"
19+
#include "clang/AST/ODRHash.h"
1920
#include "clang/AST/Stmt.h"
2021
#include "clang/AST/Type.h"
2122
#include "clang/AST/TypeLoc.h"
@@ -771,6 +772,33 @@ ObjCMethodDecl *ObjCInterfaceDecl::lookupPrivateMethod(
771772
return Method;
772773
}
773774

775+
unsigned ObjCInterfaceDecl::getODRHash() {
776+
assert(hasDefinition() && "ODRHash only for records with definitions");
777+
778+
// Previously calculated hash is stored in DefinitionData.
779+
if (hasODRHash())
780+
return data().ODRHash;
781+
782+
// Only calculate hash on first call of getODRHash per record.
783+
class ODRHash Hash;
784+
Hash.AddObjCInterfaceDecl(getDefinition());
785+
setHasODRHash();
786+
data().ODRHash = Hash.CalculateHash();
787+
788+
return data().ODRHash;
789+
}
790+
791+
bool ObjCInterfaceDecl::hasODRHash() const {
792+
if (!hasDefinition())
793+
return false;
794+
return data().HasODRHash;
795+
}
796+
797+
void ObjCInterfaceDecl::setHasODRHash(bool Hash) {
798+
assert(hasDefinition() && "Cannot set ODRHash without definition");
799+
data().HasODRHash = Hash;
800+
}
801+
774802
//===----------------------------------------------------------------------===//
775803
// ObjCMethodDecl
776804
//===----------------------------------------------------------------------===//

clang/lib/AST/ODRHash.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,27 @@ void ODRHash::AddSubDecl(const Decl *D) {
464464
ODRDeclVisitor(ID, *this).Visit(D);
465465
}
466466

467+
void ODRHash::AddObjCInterfaceDecl(const ObjCInterfaceDecl *IF) {
468+
AddDecl(IF);
469+
470+
auto *SuperClass = IF->getSuperClass();
471+
AddBoolean(SuperClass);
472+
if (SuperClass)
473+
ID.AddInteger(SuperClass->getODRHash());
474+
ID.AddInteger(IF->getReferencedProtocols().size());
475+
476+
// Filter out sub-Decls which will not be processed in order to get an
477+
// accurate count of Decl's.
478+
llvm::SmallVector<const Decl *, 16> Decls;
479+
for (Decl *SubDecl : IF->decls())
480+
if (isWhitelistedDecl(SubDecl, IF))
481+
Decls.push_back(SubDecl);
482+
483+
ID.AddInteger(Decls.size());
484+
for (auto *SubDecl : Decls)
485+
AddSubDecl(SubDecl);
486+
}
487+
467488
void ODRHash::AddRecordDecl(const RecordDecl *Record) {
468489
AddDecl(Record);
469490

0 commit comments

Comments
 (0)