Skip to content

[Modules] Handle tag types and complain about bad merges in C/Objective-C mode #542

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 9, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions clang/include/clang/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -3716,6 +3716,7 @@ class RecordDecl : public TagDecl {
// to save some space. Use the provided accessors to access it.
public:
friend class DeclContext;
friend class ASTDeclReader;
/// Enum that represents the different ways arguments are passed to and
/// returned from function calls. This takes into account the target-specific
/// and version-specific rules along with the rules determined by the
Expand Down Expand Up @@ -3960,9 +3961,19 @@ class RecordDecl : public TagDecl {
/// nullptr is returned if no named data member exists.
const FieldDecl *findFirstNamedDataMember() const;

/// Get precomputed ODRHash or add a new one.
unsigned getODRHash();

private:
/// Deserialize just the fields.
void LoadFieldsFromExternalStorage() const;

/// True if a valid hash is stored in ODRHash.
bool hasODRHash() const { return RecordDeclBits.HasODRHash; }
void setHasODRHash(bool Hash = true) { RecordDeclBits.HasODRHash = Hash; }

/// Store the ODR hash for this decl.
unsigned ODRHash;
};

class FileScopeAsmDecl : public Decl {
Expand Down
5 changes: 4 additions & 1 deletion clang/include/clang/AST/DeclBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -1452,10 +1452,13 @@ class DeclContext {

/// Represents the way this type is passed to a function.
uint64_t ArgPassingRestrictions : 2;

/// True if a valid hash is stored in ODRHash.
uint64_t HasODRHash : 1;
};

/// Number of non-inherited bits in RecordDeclBitfields.
enum { NumRecordDeclBits = 14 };
enum { NumRecordDeclBits = 15 };

/// Stores the bits used by OMPDeclareReductionDecl.
/// If modified NumOMPDeclareReductionDeclBits and the accessor
Expand Down
4 changes: 4 additions & 0 deletions clang/include/clang/AST/ODRHash.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ class ODRHash {
// more information than the AddDecl class.
void AddCXXRecordDecl(const CXXRecordDecl *Record);

// Use this for ODR checking records in C/Objective-C between modules. This
// method compares more information than the AddDecl class.
void AddRecordDecl(const RecordDecl *Record);

// Use this for ODR checking functions between modules. This method compares
// more information than the AddDecl class. SkipBody will process the
// hash as if the function has no body.
Expand Down
4 changes: 4 additions & 0 deletions clang/include/clang/Serialization/ASTReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -1100,6 +1100,10 @@ class ASTReader
llvm::SmallDenseMap<EnumDecl *, llvm::SmallVector<EnumDecl *, 2>, 2>
PendingEnumOdrMergeFailures;

/// C/ObjC definitions in which the structural equivalence check fails
llvm::SmallDenseMap<RecordDecl *, llvm::SmallVector<RecordDecl *, 2>, 2>
PendingRecordOdrMergeFailures;

/// DeclContexts in which we have diagnosed an ODR violation.
llvm::SmallPtrSet<DeclContext*, 2> DiagnosedOdrMergeFailures;

Expand Down
15 changes: 15 additions & 0 deletions clang/lib/AST/Decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4360,6 +4360,8 @@ RecordDecl::RecordDecl(Kind DK, TagKind TK, const ASTContext &C,
setHasNonTrivialToPrimitiveCopyCUnion(false);
setParamDestroyedInCallee(false);
setArgPassingRestrictions(APK_CanPassInRegs);
setHasODRHash(false);
ODRHash = 0;
}

RecordDecl *RecordDecl::Create(const ASTContext &C, TagKind TK, DeclContext *DC,
Expand Down Expand Up @@ -4507,6 +4509,19 @@ const FieldDecl *RecordDecl::findFirstNamedDataMember() const {
return nullptr;
}

unsigned RecordDecl::getODRHash() {
if (hasODRHash())
return ODRHash;

// Only calculate hash on first call of getODRHash per record.
class ODRHash Hash;
Hash.AddRecordDecl(this);
setHasODRHash();
ODRHash = Hash.CalculateHash();

return ODRHash;
}

//===----------------------------------------------------------------------===//
// BlockDecl Implementation
//===----------------------------------------------------------------------===//
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/AST/DeclCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,7 @@ unsigned CXXRecordDecl::getODRHash() const {
return DefinitionData->ODRHash;

// Only calculate hash on first call of getODRHash per record.
ODRHash Hash;
class ODRHash Hash;
Hash.AddCXXRecordDecl(getDefinition());
DefinitionData->HasODRHash = true;
DefinitionData->ODRHash = Hash.CalculateHash();
Expand Down
15 changes: 15 additions & 0 deletions clang/lib/AST/ODRHash.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,21 @@ void ODRHash::AddSubDecl(const Decl *D) {
ODRDeclVisitor(ID, *this).Visit(D);
}

void ODRHash::AddRecordDecl(const RecordDecl *Record) {
AddDecl(Record);

// Filter out sub-Decls which will not be processed in order to get an
// accurate count of Decl's.
llvm::SmallVector<const Decl *, 16> Decls;
for (Decl *SubDecl : Record->decls())
if (isWhitelistedDecl(SubDecl, Record))
Decls.push_back(SubDecl);

ID.AddInteger(Decls.size());
for (auto SubDecl : Decls)
AddSubDecl(SubDecl);
}

void ODRHash::AddCXXRecordDecl(const CXXRecordDecl *Record) {
assert(Record && Record->hasDefinition() &&
"Expected non-null record to be a definition.");
Expand Down
Loading