summaryrefslogtreecommitdiffstats
path: root/lib/AST/TemplateName.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/AST/TemplateName.cpp')
-rw-r--r--lib/AST/TemplateName.cpp57
1 files changed, 50 insertions, 7 deletions
diff --git a/lib/AST/TemplateName.cpp b/lib/AST/TemplateName.cpp
index ef7b315..6b378a0 100644
--- a/lib/AST/TemplateName.cpp
+++ b/lib/AST/TemplateName.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "clang/AST/TemplateName.h"
+#include "clang/AST/TemplateBase.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/PrettyPrinter.h"
@@ -21,15 +22,33 @@
using namespace clang;
using namespace llvm;
+TemplateArgument
+SubstTemplateTemplateParmPackStorage::getArgumentPack() const {
+ return TemplateArgument(Arguments, size());
+}
+
+void SubstTemplateTemplateParmPackStorage::Profile(llvm::FoldingSetNodeID &ID) {
+ Profile(ID, Context, Parameter, TemplateArgument(Arguments, size()));
+}
+
+void SubstTemplateTemplateParmPackStorage::Profile(llvm::FoldingSetNodeID &ID,
+ ASTContext &Context,
+ TemplateTemplateParmDecl *Parameter,
+ const TemplateArgument &ArgPack) {
+ ID.AddPointer(Parameter);
+ ArgPack.Profile(ID, Context);
+}
+
TemplateName::NameKind TemplateName::getKind() const {
if (Storage.is<TemplateDecl *>())
return Template;
- if (Storage.is<OverloadedTemplateStorage *>())
- return OverloadedTemplate;
+ if (Storage.is<DependentTemplateName *>())
+ return DependentTemplate;
if (Storage.is<QualifiedTemplateName *>())
return QualifiedTemplate;
- assert(Storage.is<DependentTemplateName *>() && "There's a case unhandled!");
- return DependentTemplate;
+
+ return getAsOverloadedTemplate()? OverloadedTemplate
+ : SubstTemplateTemplateParmPack;
}
TemplateDecl *TemplateName::getAsTemplateDecl() const {
@@ -44,8 +63,14 @@ TemplateDecl *TemplateName::getAsTemplateDecl() const {
bool TemplateName::isDependent() const {
if (TemplateDecl *Template = getAsTemplateDecl()) {
- return isa<TemplateTemplateParmDecl>(Template) ||
- Template->getDeclContext()->isDependentContext();
+ if (isa<TemplateTemplateParmDecl>(Template))
+ return true;
+ // FIXME: Hack, getDeclContext() can be null if Template is still
+ // initializing due to PCH reading, so we check it before using it.
+ // Should probably modify TemplateSpecializationType to allow constructing
+ // it without the isDependent() checking.
+ return Template->getDeclContext() &&
+ Template->getDeclContext()->isDependentContext();
}
assert(!getAsOverloadedTemplate() &&
@@ -54,6 +79,22 @@ bool TemplateName::isDependent() const {
return true;
}
+bool TemplateName::containsUnexpandedParameterPack() const {
+ if (TemplateDecl *Template = getAsTemplateDecl()) {
+ if (TemplateTemplateParmDecl *TTP
+ = dyn_cast<TemplateTemplateParmDecl>(Template))
+ return TTP->isParameterPack();
+
+ return false;
+ }
+
+ if (DependentTemplateName *DTN = getAsDependentTemplateName())
+ return DTN->getQualifier() &&
+ DTN->getQualifier()->containsUnexpandedParameterPack();
+
+ return getAsSubstTemplateTemplateParmPack() != 0;
+}
+
void
TemplateName::print(llvm::raw_ostream &OS, const PrintingPolicy &Policy,
bool SuppressNNS) const {
@@ -74,7 +115,9 @@ TemplateName::print(llvm::raw_ostream &OS, const PrintingPolicy &Policy,
OS << DTN->getIdentifier()->getName();
else
OS << "operator " << getOperatorSpelling(DTN->getOperator());
- }
+ } else if (SubstTemplateTemplateParmPackStorage *SubstPack
+ = getAsSubstTemplateTemplateParmPack())
+ OS << SubstPack->getParameterPack()->getNameAsString();
}
const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
OpenPOWER on IntegriCloud