summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorRichard Trieu <rtrieu@google.com>2017-02-23 03:25:57 +0000
committerRichard Trieu <rtrieu@google.com>2017-02-23 03:25:57 +0000
commitee4fecad433df890feadf8b3a6dae422dfe4b2f0 (patch)
treea86d1eaef643562300440c31cbd71a1a8ecfd67f /lib
parent1a04b13fd8f7b63a60f34c0e64dd184559ba8c74 (diff)
downloadclang-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.cpp64
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);
}