blob: 7cfd1cdbe0890266ad1bf938831a738bc3c13480 [file] [log] [blame]
Douglas Gregor7532dc62009-03-30 22:58:21 +00001//===--- TemplateName.h - C++ Template Name Representation-------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the TemplateName interface and subclasses.
11//
12//===----------------------------------------------------------------------===//
Chris Lattnerc960ee32009-04-02 06:07:12 +000013
Douglas Gregor7532dc62009-03-30 22:58:21 +000014#include "clang/AST/TemplateName.h"
Douglas Gregor1aee05d2011-01-15 06:45:20 +000015#include "clang/AST/TemplateBase.h"
Douglas Gregor7532dc62009-03-30 22:58:21 +000016#include "clang/AST/DeclTemplate.h"
17#include "clang/AST/NestedNameSpecifier.h"
Douglas Gregord249e1d1f2009-05-29 20:38:28 +000018#include "clang/AST/PrettyPrinter.h"
Jeffrey Yasskindb88d8a2010-04-08 00:03:06 +000019#include "clang/Basic/Diagnostic.h"
Chris Lattnere4f21422009-06-30 01:26:17 +000020#include "clang/Basic/LangOptions.h"
Douglas Gregor7532dc62009-03-30 22:58:21 +000021#include "llvm/Support/raw_ostream.h"
Douglas Gregor7532dc62009-03-30 22:58:21 +000022using namespace clang;
Jeffrey Yasskindb88d8a2010-04-08 00:03:06 +000023using namespace llvm;
Douglas Gregor7532dc62009-03-30 22:58:21 +000024
Douglas Gregor1aee05d2011-01-15 06:45:20 +000025TemplateArgument
26SubstTemplateTemplateParmPackStorage::getArgumentPack() const {
27 return TemplateArgument(Arguments, size());
28}
29
John McCall14606042011-06-30 08:33:18 +000030void SubstTemplateTemplateParmStorage::Profile(llvm::FoldingSetNodeID &ID) {
31 Profile(ID, Parameter, Replacement);
32}
33
34void SubstTemplateTemplateParmStorage::Profile(llvm::FoldingSetNodeID &ID,
35 TemplateTemplateParmDecl *parameter,
36 TemplateName replacement) {
37 ID.AddPointer(parameter);
38 ID.AddPointer(replacement.getAsVoidPointer());
39}
40
41void SubstTemplateTemplateParmPackStorage::Profile(llvm::FoldingSetNodeID &ID,
42 ASTContext &Context) {
Douglas Gregor1aee05d2011-01-15 06:45:20 +000043 Profile(ID, Context, Parameter, TemplateArgument(Arguments, size()));
44}
45
46void SubstTemplateTemplateParmPackStorage::Profile(llvm::FoldingSetNodeID &ID,
47 ASTContext &Context,
48 TemplateTemplateParmDecl *Parameter,
49 const TemplateArgument &ArgPack) {
50 ID.AddPointer(Parameter);
51 ArgPack.Profile(ID, Context);
52}
53
Argyrios Kyrtzidis90b715e2010-06-19 19:28:53 +000054TemplateName::NameKind TemplateName::getKind() const {
55 if (Storage.is<TemplateDecl *>())
56 return Template;
Douglas Gregor1aee05d2011-01-15 06:45:20 +000057 if (Storage.is<DependentTemplateName *>())
58 return DependentTemplate;
Argyrios Kyrtzidis90b715e2010-06-19 19:28:53 +000059 if (Storage.is<QualifiedTemplateName *>())
60 return QualifiedTemplate;
John McCall14606042011-06-30 08:33:18 +000061
62 UncommonTemplateNameStorage *uncommon
63 = Storage.get<UncommonTemplateNameStorage*>();
64 if (uncommon->getAsOverloadedStorage())
65 return OverloadedTemplate;
66 if (uncommon->getAsSubstTemplateTemplateParm())
67 return SubstTemplateTemplateParm;
68 return SubstTemplateTemplateParmPack;
Argyrios Kyrtzidis90b715e2010-06-19 19:28:53 +000069}
70
Douglas Gregor7532dc62009-03-30 22:58:21 +000071TemplateDecl *TemplateName::getAsTemplateDecl() const {
72 if (TemplateDecl *Template = Storage.dyn_cast<TemplateDecl *>())
73 return Template;
Mike Stump1eb44332009-09-09 15:08:12 +000074
Douglas Gregor7532dc62009-03-30 22:58:21 +000075 if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName())
76 return QTN->getTemplateDecl();
77
John McCall14606042011-06-30 08:33:18 +000078 if (SubstTemplateTemplateParmStorage *sub = getAsSubstTemplateTemplateParm())
79 return sub->getReplacement().getAsTemplateDecl();
80
Douglas Gregor7532dc62009-03-30 22:58:21 +000081 return 0;
82}
83
84bool TemplateName::isDependent() const {
85 if (TemplateDecl *Template = getAsTemplateDecl()) {
Argyrios Kyrtzidis6b541512010-09-08 19:31:22 +000086 if (isa<TemplateTemplateParmDecl>(Template))
87 return true;
88 // FIXME: Hack, getDeclContext() can be null if Template is still
89 // initializing due to PCH reading, so we check it before using it.
90 // Should probably modify TemplateSpecializationType to allow constructing
91 // it without the isDependent() checking.
92 return Template->getDeclContext() &&
93 Template->getDeclContext()->isDependentContext();
Douglas Gregor7532dc62009-03-30 22:58:21 +000094 }
95
John McCall0bd6feb2009-12-02 08:04:21 +000096 assert(!getAsOverloadedTemplate() &&
97 "overloaded templates shouldn't survive to here");
Mike Stump1eb44332009-09-09 15:08:12 +000098
Douglas Gregor7532dc62009-03-30 22:58:21 +000099 return true;
100}
101
Douglas Gregor561f8122011-07-01 01:22:09 +0000102bool TemplateName::isInstantiationDependent() const {
103 if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName()) {
104 if (QTN->getQualifier()->isInstantiationDependent())
105 return true;
106 }
107
108 return isDependent();
109}
110
Douglas Gregord0937222010-12-13 22:49:22 +0000111bool TemplateName::containsUnexpandedParameterPack() const {
112 if (TemplateDecl *Template = getAsTemplateDecl()) {
113 if (TemplateTemplateParmDecl *TTP
114 = dyn_cast<TemplateTemplateParmDecl>(Template))
115 return TTP->isParameterPack();
116
117 return false;
118 }
119
120 if (DependentTemplateName *DTN = getAsDependentTemplateName())
121 return DTN->getQualifier() &&
122 DTN->getQualifier()->containsUnexpandedParameterPack();
123
Douglas Gregor1aee05d2011-01-15 06:45:20 +0000124 return getAsSubstTemplateTemplateParmPack() != 0;
Douglas Gregord0937222010-12-13 22:49:22 +0000125}
126
Mike Stump1eb44332009-09-09 15:08:12 +0000127void
Chris Lattner5f9e2722011-07-23 10:55:15 +0000128TemplateName::print(raw_ostream &OS, const PrintingPolicy &Policy,
Douglas Gregord249e1d1f2009-05-29 20:38:28 +0000129 bool SuppressNNS) const {
Douglas Gregor7532dc62009-03-30 22:58:21 +0000130 if (TemplateDecl *Template = Storage.dyn_cast<TemplateDecl *>())
Benjamin Kramer900fc632010-04-17 09:33:03 +0000131 OS << Template;
Douglas Gregor7532dc62009-03-30 22:58:21 +0000132 else if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName()) {
Douglas Gregor17343172009-04-01 00:28:59 +0000133 if (!SuppressNNS)
Douglas Gregord249e1d1f2009-05-29 20:38:28 +0000134 QTN->getQualifier()->print(OS, Policy);
Douglas Gregor7532dc62009-03-30 22:58:21 +0000135 if (QTN->hasTemplateKeyword())
136 OS << "template ";
Benjamin Kramer900fc632010-04-17 09:33:03 +0000137 OS << QTN->getDecl();
Douglas Gregor7532dc62009-03-30 22:58:21 +0000138 } else if (DependentTemplateName *DTN = getAsDependentTemplateName()) {
Douglas Gregor3b6afbb2009-09-09 00:23:06 +0000139 if (!SuppressNNS && DTN->getQualifier())
Douglas Gregord249e1d1f2009-05-29 20:38:28 +0000140 DTN->getQualifier()->print(OS, Policy);
Douglas Gregor7532dc62009-03-30 22:58:21 +0000141 OS << "template ";
Douglas Gregorca1bdd72009-11-04 00:56:37 +0000142
143 if (DTN->isIdentifier())
144 OS << DTN->getIdentifier()->getName();
145 else
146 OS << "operator " << getOperatorSpelling(DTN->getOperator());
John McCall14606042011-06-30 08:33:18 +0000147 } else if (SubstTemplateTemplateParmStorage *subst
148 = getAsSubstTemplateTemplateParm()) {
149 subst->getReplacement().print(OS, Policy, SuppressNNS);
Douglas Gregor1aee05d2011-01-15 06:45:20 +0000150 } else if (SubstTemplateTemplateParmPackStorage *SubstPack
151 = getAsSubstTemplateTemplateParmPack())
152 OS << SubstPack->getParameterPack()->getNameAsString();
Douglas Gregor6cd9d4a2011-03-04 21:37:14 +0000153 else {
154 OverloadedTemplateStorage *OTS = getAsOverloadedTemplate();
155 (*OTS->begin())->printName(OS);
156 }
Douglas Gregor7532dc62009-03-30 22:58:21 +0000157}
Douglas Gregorde650ae2009-03-31 18:38:02 +0000158
Jeffrey Yasskindb88d8a2010-04-08 00:03:06 +0000159const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
160 TemplateName N) {
161 std::string NameStr;
162 raw_string_ostream OS(NameStr);
163 LangOptions LO;
164 LO.CPlusPlus = true;
165 LO.Bool = true;
166 N.print(OS, PrintingPolicy(LO));
167 OS.flush();
168 return DB << NameStr;
169}
170
Douglas Gregor9bde7732009-03-31 20:22:05 +0000171void TemplateName::dump() const {
Chris Lattnere4f21422009-06-30 01:26:17 +0000172 LangOptions LO; // FIXME!
173 LO.CPlusPlus = true;
174 LO.Bool = true;
175 print(llvm::errs(), PrintingPolicy(LO));
Douglas Gregorde650ae2009-03-31 18:38:02 +0000176}