1 //===--- TemplateBase.cpp - Common template AST class implementation ------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements common classes used throughout C++ template
13 //===----------------------------------------------------------------------===//
15 #include "clang/AST/TemplateBase.h"
16 #include "clang/AST/ASTContext.h"
17 #include "clang/AST/DeclBase.h"
18 #include "clang/AST/DeclTemplate.h"
19 #include "clang/AST/Expr.h"
20 #include "clang/AST/ExprCXX.h"
21 #include "clang/AST/TypeLoc.h"
22 #include "clang/Basic/Diagnostic.h"
23 #include "llvm/ADT/FoldingSet.h"
25 using namespace clang;
27 //===----------------------------------------------------------------------===//
28 // TemplateArgument Implementation
29 //===----------------------------------------------------------------------===//
31 bool TemplateArgument::isDependent() const {
34 assert(false && "Should not have a NULL template argument");
38 return getAsType()->isDependentType();
41 return getAsTemplate().isDependent();
43 case TemplateExpansion:
47 if (DeclContext *DC = dyn_cast<DeclContext>(getAsDecl()))
48 return DC->isDependentContext();
49 return getAsDecl()->getDeclContext()->isDependentContext();
56 return (getAsExpr()->isTypeDependent() || getAsExpr()->isValueDependent());
59 for (pack_iterator P = pack_begin(), PEnd = pack_end(); P != PEnd; ++P) {
70 bool TemplateArgument::isPackExpansion() const {
79 case TemplateExpansion:
83 return isa<PackExpansionType>(getAsType());
86 return isa<PackExpansionExpr>(getAsExpr());
92 bool TemplateArgument::containsUnexpandedParameterPack() const {
97 case TemplateExpansion:
101 if (getAsType()->containsUnexpandedParameterPack())
106 if (getAsTemplate().containsUnexpandedParameterPack())
111 if (getAsExpr()->containsUnexpandedParameterPack())
116 for (pack_iterator P = pack_begin(), PEnd = pack_end(); P != PEnd; ++P)
117 if (P->containsUnexpandedParameterPack())
126 void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID,
127 ASTContext &Context) const {
134 getAsType().Profile(ID);
138 ID.AddPointer(getAsDecl()? getAsDecl()->getCanonicalDecl() : 0);
142 case TemplateExpansion: {
143 TemplateName Template = getAsTemplateOrTemplatePattern();
144 if (TemplateTemplateParmDecl *TTP
145 = dyn_cast_or_null<TemplateTemplateParmDecl>(
146 Template.getAsTemplateDecl())) {
148 ID.AddInteger(TTP->getDepth());
149 ID.AddInteger(TTP->getPosition());
150 ID.AddBoolean(TTP->isParameterPack());
152 ID.AddBoolean(false);
153 ID.AddPointer(Context.getCanonicalTemplateName(Template)
154 .getAsVoidPointer());
160 getAsIntegral()->Profile(ID);
161 getIntegralType().Profile(ID);
165 getAsExpr()->Profile(ID, Context, true);
169 ID.AddInteger(Args.NumArgs);
170 for (unsigned I = 0; I != Args.NumArgs; ++I)
171 Args.Args[I].Profile(ID, Context);
175 bool TemplateArgument::structurallyEquals(const TemplateArgument &Other) const {
176 if (getKind() != Other.getKind()) return false;
184 case TemplateExpansion:
185 return TypeOrValue == Other.TypeOrValue;
188 return getIntegralType() == Other.getIntegralType() &&
189 *getAsIntegral() == *Other.getAsIntegral();
192 if (Args.NumArgs != Other.Args.NumArgs) return false;
193 for (unsigned I = 0, E = Args.NumArgs; I != E; ++I)
194 if (!Args.Args[I].structurallyEquals(Other.Args.Args[I]))
199 // Suppress warnings.
203 TemplateArgument TemplateArgument::getPackExpansionPattern() const {
204 assert(isPackExpansion());
208 return getAsType()->getAs<PackExpansionType>()->getPattern();
211 return cast<PackExpansionExpr>(getAsExpr())->getPattern();
213 case TemplateExpansion:
214 return TemplateArgument(getAsTemplateOrTemplatePattern(), false);
221 return TemplateArgument();
224 return TemplateArgument();
227 void TemplateArgument::print(const PrintingPolicy &Policy,
228 llvm::raw_ostream &Out) const {
236 getAsType().getAsStringInternal(TypeStr, Policy);
243 if (NamedDecl *ND = dyn_cast_or_null<NamedDecl>(getAsDecl())) {
244 if (ND->getDeclName()) {
246 Out << ND->getNameAsString();
251 Out << "<anonymous>";
257 getAsTemplate().print(Out, Policy);
260 case TemplateExpansion:
261 getAsTemplateOrTemplatePattern().print(Out, Policy);
266 Out << getAsIntegral()->toString(10);
271 getAsExpr()->printPretty(Out, 0, Policy);
277 for (TemplateArgument::pack_iterator P = pack_begin(), PEnd = pack_end();
284 P->print(Policy, Out);
291 //===----------------------------------------------------------------------===//
292 // TemplateArgumentLoc Implementation
293 //===----------------------------------------------------------------------===//
295 TemplateArgumentLocInfo::TemplateArgumentLocInfo() {
296 memset(this, 0, sizeof(TemplateArgumentLocInfo));
299 SourceRange TemplateArgumentLoc::getSourceRange() const {
300 switch (Argument.getKind()) {
301 case TemplateArgument::Expression:
302 return getSourceExpression()->getSourceRange();
304 case TemplateArgument::Declaration:
305 return getSourceDeclExpression()->getSourceRange();
307 case TemplateArgument::Type:
308 if (TypeSourceInfo *TSI = getTypeSourceInfo())
309 return TSI->getTypeLoc().getSourceRange();
311 return SourceRange();
313 case TemplateArgument::Template:
314 if (getTemplateQualifierRange().isValid())
315 return SourceRange(getTemplateQualifierRange().getBegin(),
316 getTemplateNameLoc());
317 return SourceRange(getTemplateNameLoc());
319 case TemplateArgument::TemplateExpansion:
320 if (getTemplateQualifierRange().isValid())
321 return SourceRange(getTemplateQualifierRange().getBegin(),
322 getTemplateEllipsisLoc());
323 return SourceRange(getTemplateNameLoc(), getTemplateEllipsisLoc());
325 case TemplateArgument::Integral:
326 case TemplateArgument::Pack:
327 case TemplateArgument::Null:
328 return SourceRange();
331 // Silence bonus gcc warning.
332 return SourceRange();
336 TemplateArgumentLoc::getPackExpansionPattern(SourceLocation &Ellipsis,
337 ASTContext &Context) const {
338 assert(Argument.isPackExpansion());
340 switch (Argument.getKind()) {
341 case TemplateArgument::Type: {
342 // FIXME: We shouldn't ever have to worry about missing
344 TypeSourceInfo *ExpansionTSInfo = getTypeSourceInfo();
345 if (!ExpansionTSInfo)
346 ExpansionTSInfo = Context.getTrivialTypeSourceInfo(
347 getArgument().getAsType(),
349 PackExpansionTypeLoc Expansion
350 = cast<PackExpansionTypeLoc>(ExpansionTSInfo->getTypeLoc());
351 Ellipsis = Expansion.getEllipsisLoc();
353 TypeLoc Pattern = Expansion.getPatternLoc();
355 // FIXME: This is horrible. We know where the source location data is for
356 // the pattern, and we have the pattern's type, but we are forced to copy
357 // them into an ASTContext because TypeSourceInfo bundles them together
358 // and TemplateArgumentLoc traffics in TypeSourceInfo pointers.
359 TypeSourceInfo *PatternTSInfo
360 = Context.CreateTypeSourceInfo(Pattern.getType(),
361 Pattern.getFullDataSize());
362 memcpy(PatternTSInfo->getTypeLoc().getOpaqueData(),
363 Pattern.getOpaqueData(), Pattern.getFullDataSize());
364 return TemplateArgumentLoc(TemplateArgument(Pattern.getType()),
368 case TemplateArgument::Expression: {
369 PackExpansionExpr *Expansion
370 = cast<PackExpansionExpr>(Argument.getAsExpr());
371 Expr *Pattern = Expansion->getPattern();
372 Ellipsis = Expansion->getEllipsisLoc();
373 return TemplateArgumentLoc(Pattern, Pattern);
376 case TemplateArgument::TemplateExpansion:
377 Ellipsis = getTemplateEllipsisLoc();
378 return TemplateArgumentLoc(Argument.getPackExpansionPattern(),
379 getTemplateQualifierRange(),
380 getTemplateNameLoc());
382 case TemplateArgument::Declaration:
383 case TemplateArgument::Template:
384 case TemplateArgument::Integral:
385 case TemplateArgument::Pack:
386 case TemplateArgument::Null:
387 return TemplateArgumentLoc();
390 return TemplateArgumentLoc();
393 const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
394 const TemplateArgument &Arg) {
395 switch (Arg.getKind()) {
396 case TemplateArgument::Null:
397 // This is bad, but not as bad as crashing because of argument
399 return DB << "(null template argument)";
401 case TemplateArgument::Type:
402 return DB << Arg.getAsType();
404 case TemplateArgument::Declaration:
405 return DB << Arg.getAsDecl();
407 case TemplateArgument::Integral:
408 return DB << Arg.getAsIntegral()->toString(10);
410 case TemplateArgument::Template:
411 return DB << Arg.getAsTemplate();
413 case TemplateArgument::TemplateExpansion:
414 return DB << Arg.getAsTemplateOrTemplatePattern() << "...";
416 case TemplateArgument::Expression: {
417 // This shouldn't actually ever happen, so it's okay that we're
418 // regurgitating an expression here.
419 // FIXME: We're guessing at LangOptions!
420 llvm::SmallString<32> Str;
421 llvm::raw_svector_ostream OS(Str);
422 LangOptions LangOpts;
423 LangOpts.CPlusPlus = true;
424 PrintingPolicy Policy(LangOpts);
425 Arg.getAsExpr()->printPretty(OS, 0, Policy);
426 return DB << OS.str();
429 case TemplateArgument::Pack: {
430 // FIXME: We're guessing at LangOptions!
431 llvm::SmallString<32> Str;
432 llvm::raw_svector_ostream OS(Str);
433 LangOptions LangOpts;
434 LangOpts.CPlusPlus = true;
435 PrintingPolicy Policy(LangOpts);
436 Arg.print(Policy, OS);
437 return DB << OS.str();