summaryrefslogtreecommitdiffstats
path: root/gnu/llvm/tools/clang/lib/AST/ODRHash.cpp
diff options
context:
space:
mode:
authorpatrick <patrick@openbsd.org>2018-04-06 14:26:03 +0000
committerpatrick <patrick@openbsd.org>2018-04-06 14:26:03 +0000
commitbdabc2f19ffb9e20600dad6e8a300842a7bda50e (patch)
treec50e7b2e5449b074651bb82a58517a8ebc4a8cf7 /gnu/llvm/tools/clang/lib/AST/ODRHash.cpp
parentPrint a 'p' flag for file descriptors that were opened after pledge(2). (diff)
downloadwireguard-openbsd-bdabc2f19ffb9e20600dad6e8a300842a7bda50e.tar.xz
wireguard-openbsd-bdabc2f19ffb9e20600dad6e8a300842a7bda50e.zip
Import LLVM 6.0.1 release including clang, lld and lldb.
"where is the kaboom?" deraadt@
Diffstat (limited to 'gnu/llvm/tools/clang/lib/AST/ODRHash.cpp')
-rw-r--r--gnu/llvm/tools/clang/lib/AST/ODRHash.cpp103
1 files changed, 102 insertions, 1 deletions
diff --git a/gnu/llvm/tools/clang/lib/AST/ODRHash.cpp b/gnu/llvm/tools/clang/lib/AST/ODRHash.cpp
index 121724a7315..38e8d34135f 100644
--- a/gnu/llvm/tools/clang/lib/AST/ODRHash.cpp
+++ b/gnu/llvm/tools/clang/lib/AST/ODRHash.cpp
@@ -158,7 +158,14 @@ void ODRHash::AddTemplateArgument(TemplateArgument TA) {
}
}
-void ODRHash::AddTemplateParameterList(const TemplateParameterList *TPL) {}
+void ODRHash::AddTemplateParameterList(const TemplateParameterList *TPL) {
+ assert(TPL && "Expecting non-null pointer.");
+
+ ID.AddInteger(TPL->size());
+ for (auto *ND : TPL->asArray()) {
+ AddSubDecl(ND);
+ }
+}
void ODRHash::clear() {
DeclMap.clear();
@@ -199,6 +206,7 @@ unsigned ODRHash::CalculateHash() {
return ID.ComputeHash();
}
+namespace {
// Process a Decl pointer. Add* methods call back into ODRHash while Visit*
// methods process the relevant parts of the Decl.
class ODRDeclVisitor : public ConstDeclVisitor<ODRDeclVisitor> {
@@ -235,6 +243,10 @@ public:
}
}
+ void AddTemplateArgument(TemplateArgument TA) {
+ Hash.AddTemplateArgument(TA);
+ }
+
void Visit(const Decl *D) {
ID.AddInteger(D->getKind());
Inherited::Visit(D);
@@ -342,7 +354,44 @@ public:
AddDecl(D->getFriendDecl());
}
}
+
+ void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
+ // Only care about default arguments as part of the definition.
+ const bool hasDefaultArgument =
+ D->hasDefaultArgument() && !D->defaultArgumentWasInherited();
+ Hash.AddBoolean(hasDefaultArgument);
+ if (hasDefaultArgument) {
+ AddTemplateArgument(D->getDefaultArgument());
+ }
+
+ Inherited::VisitTemplateTypeParmDecl(D);
+ }
+
+ void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) {
+ // Only care about default arguments as part of the definition.
+ const bool hasDefaultArgument =
+ D->hasDefaultArgument() && !D->defaultArgumentWasInherited();
+ Hash.AddBoolean(hasDefaultArgument);
+ if (hasDefaultArgument) {
+ AddStmt(D->getDefaultArgument());
+ }
+
+ Inherited::VisitNonTypeTemplateParmDecl(D);
+ }
+
+ void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D) {
+ // Only care about default arguments as part of the definition.
+ const bool hasDefaultArgument =
+ D->hasDefaultArgument() && !D->defaultArgumentWasInherited();
+ Hash.AddBoolean(hasDefaultArgument);
+ if (hasDefaultArgument) {
+ AddTemplateArgument(D->getDefaultArgument().getArgument());
+ }
+
+ Inherited::VisitTemplateTemplateParmDecl(D);
+ }
};
+} // namespace
// Only allow a small portion of Decl's to be processed. Remove this once
// all Decl's can be handled.
@@ -401,10 +450,60 @@ void ODRHash::AddCXXRecordDecl(const CXXRecordDecl *Record) {
for (auto SubDecl : Decls) {
AddSubDecl(SubDecl);
}
+
+ const ClassTemplateDecl *TD = Record->getDescribedClassTemplate();
+ AddBoolean(TD);
+ if (TD) {
+ AddTemplateParameterList(TD->getTemplateParameters());
+ }
+
+ ID.AddInteger(Record->getNumBases());
+ auto Bases = Record->bases();
+ for (auto Base : Bases) {
+ AddQualType(Base.getType());
+ ID.AddInteger(Base.isVirtual());
+ ID.AddInteger(Base.getAccessSpecifierAsWritten());
+ }
+}
+
+void ODRHash::AddFunctionDecl(const FunctionDecl *Function) {
+ assert(Function && "Expecting non-null pointer.");
+
+ // Skip hashing these kinds of function.
+ if (Function->isImplicit()) return;
+ if (Function->isDefaulted()) return;
+ if (Function->isDeleted()) return;
+ if (!Function->hasBody()) return;
+ if (!Function->getBody()) return;
+
+ // TODO: Fix hashing for class methods.
+ if (isa<CXXMethodDecl>(Function)) return;
+ // And friend functions.
+ if (Function->getFriendObjectKind()) return;
+
+ // Skip functions that are specializations or in specialization context.
+ const DeclContext *DC = Function;
+ while (DC) {
+ if (isa<ClassTemplateSpecializationDecl>(DC)) return;
+ if (auto *F = dyn_cast<FunctionDecl>(DC))
+ if (F->isFunctionTemplateSpecialization()) return;
+ DC = DC->getParent();
+ }
+
+ AddDecl(Function);
+
+ AddQualType(Function->getReturnType());
+
+ ID.AddInteger(Function->param_size());
+ for (auto Param : Function->parameters())
+ AddSubDecl(Param);
+
+ AddStmt(Function->getBody());
}
void ODRHash::AddDecl(const Decl *D) {
assert(D && "Expecting non-null pointer.");
+ D = D->getCanonicalDecl();
auto Result = DeclMap.insert(std::make_pair(D, DeclMap.size()));
ID.AddInteger(Result.first->second);
// On first encounter of a Decl pointer, process it. Every time afterwards,
@@ -420,6 +519,7 @@ void ODRHash::AddDecl(const Decl *D) {
}
}
+namespace {
// 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> {
@@ -608,6 +708,7 @@ public:
AddDecl(T->getDecl());
}
};
+} // namespace
void ODRHash::AddType(const Type *T) {
assert(T && "Expecting non-null pointer.");