]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - contrib/llvm/tools/clang/lib/AST/TemplateName.cpp
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / contrib / llvm / tools / clang / lib / AST / TemplateName.cpp
1 //===--- TemplateName.cpp - C++ Template Name Representation---------------===//
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 //===----------------------------------------------------------------------===//
13
14 #include "clang/AST/TemplateName.h"
15 #include "clang/AST/DeclTemplate.h"
16 #include "clang/AST/NestedNameSpecifier.h"
17 #include "clang/AST/PrettyPrinter.h"
18 #include "clang/AST/TemplateBase.h"
19 #include "clang/Basic/Diagnostic.h"
20 #include "clang/Basic/LangOptions.h"
21 #include "llvm/Support/raw_ostream.h"
22 using namespace clang;
23 using namespace llvm;
24
25 TemplateArgument 
26 SubstTemplateTemplateParmPackStorage::getArgumentPack() const {
27   return TemplateArgument(Arguments, size());
28 }
29
30 void SubstTemplateTemplateParmStorage::Profile(llvm::FoldingSetNodeID &ID) {
31   Profile(ID, Parameter, Replacement);
32 }
33
34 void SubstTemplateTemplateParmStorage::Profile(llvm::FoldingSetNodeID &ID, 
35                                            TemplateTemplateParmDecl *parameter,
36                                                TemplateName replacement) {
37   ID.AddPointer(parameter);
38   ID.AddPointer(replacement.getAsVoidPointer());
39 }
40
41 void SubstTemplateTemplateParmPackStorage::Profile(llvm::FoldingSetNodeID &ID,
42                                                    ASTContext &Context) {
43   Profile(ID, Context, Parameter, TemplateArgument(Arguments, size()));
44 }
45
46 void 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
54 TemplateName::NameKind TemplateName::getKind() const {
55   if (Storage.is<TemplateDecl *>())
56     return Template;
57   if (Storage.is<DependentTemplateName *>())
58     return DependentTemplate;
59   if (Storage.is<QualifiedTemplateName *>())
60     return QualifiedTemplate;
61
62   UncommonTemplateNameStorage *uncommon
63     = Storage.get<UncommonTemplateNameStorage*>();
64   if (uncommon->getAsOverloadedStorage())
65     return OverloadedTemplate;
66   if (uncommon->getAsSubstTemplateTemplateParm())
67     return SubstTemplateTemplateParm;
68   return SubstTemplateTemplateParmPack;
69 }
70
71 TemplateDecl *TemplateName::getAsTemplateDecl() const {
72   if (TemplateDecl *Template = Storage.dyn_cast<TemplateDecl *>())
73     return Template;
74
75   if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName())
76     return QTN->getTemplateDecl();
77
78   if (SubstTemplateTemplateParmStorage *sub = getAsSubstTemplateTemplateParm())
79     return sub->getReplacement().getAsTemplateDecl();
80
81   return 0;
82 }
83
84 bool TemplateName::isDependent() const {
85   if (TemplateDecl *Template = getAsTemplateDecl()) {
86     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();
94   }
95
96   assert(!getAsOverloadedTemplate() &&
97          "overloaded templates shouldn't survive to here");
98
99   return true;
100 }
101
102 bool TemplateName::isInstantiationDependent() const {
103   if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName()) {
104     if (QTN->getQualifier()->isInstantiationDependent())
105       return true;
106   }
107   
108   return isDependent();
109 }
110
111 bool 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
124   return getAsSubstTemplateTemplateParmPack() != 0;
125 }
126
127 void
128 TemplateName::print(raw_ostream &OS, const PrintingPolicy &Policy,
129                     bool SuppressNNS) const {
130   if (TemplateDecl *Template = Storage.dyn_cast<TemplateDecl *>())
131     OS << *Template;
132   else if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName()) {
133     if (!SuppressNNS)
134       QTN->getQualifier()->print(OS, Policy);
135     if (QTN->hasTemplateKeyword())
136       OS << "template ";
137     OS << *QTN->getDecl();
138   } else if (DependentTemplateName *DTN = getAsDependentTemplateName()) {
139     if (!SuppressNNS && DTN->getQualifier())
140       DTN->getQualifier()->print(OS, Policy);
141     OS << "template ";
142     
143     if (DTN->isIdentifier())
144       OS << DTN->getIdentifier()->getName();
145     else
146       OS << "operator " << getOperatorSpelling(DTN->getOperator());
147   } else if (SubstTemplateTemplateParmStorage *subst
148                = getAsSubstTemplateTemplateParm()) {
149     subst->getReplacement().print(OS, Policy, SuppressNNS);
150   } else if (SubstTemplateTemplateParmPackStorage *SubstPack
151                                         = getAsSubstTemplateTemplateParmPack())
152     OS << *SubstPack->getParameterPack();
153   else {
154     OverloadedTemplateStorage *OTS = getAsOverloadedTemplate();
155     (*OTS->begin())->printName(OS);
156   }
157 }
158
159 const 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   OS << '\'';
167   N.print(OS, PrintingPolicy(LO));
168   OS << '\'';
169   OS.flush();
170   return DB << NameStr;
171 }
172
173 void TemplateName::dump(raw_ostream &OS) const {
174   LangOptions LO;  // FIXME!
175   LO.CPlusPlus = true;
176   LO.Bool = true;
177   print(OS, PrintingPolicy(LO));
178 }
179
180 void TemplateName::dump() const {
181   dump(llvm::errs());
182 }