diff options
author | Richard Trieu <rtrieu@google.com> | 2017-02-23 03:25:57 +0000 |
---|---|---|
committer | Richard Trieu <rtrieu@google.com> | 2017-02-23 03:25:57 +0000 |
commit | ee4fecad433df890feadf8b3a6dae422dfe4b2f0 (patch) | |
tree | a86d1eaef643562300440c31cbd71a1a8ecfd67f /lib | |
parent | 1a04b13fd8f7b63a60f34c0e64dd184559ba8c74 (diff) | |
download | clang-ee4fecad433df890feadf8b3a6dae422dfe4b2f0.tar.gz |
[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
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@295931 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/ODRHash.cpp | 64 |
1 files changed, 62 insertions, 2 deletions
diff --git a/lib/AST/ODRHash.cpp b/lib/AST/ODRHash.cpp index 35af0e98a9..b75de54e07 100644 --- a/lib/AST/ODRHash.cpp +++ b/lib/AST/ODRHash.cpp @@ -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); } |