summaryrefslogtreecommitdiff
path: root/lib/AST/ODRHash.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/AST/ODRHash.cpp')
-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);
}