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/Type.h"
22 #include "clang/AST/TypeLoc.h"
23 #include "clang/Basic/Diagnostic.h"
24 #include "llvm/ADT/FoldingSet.h"
28 using namespace clang;
30 /// \brief Print a template integral argument value.
32 /// \param TemplArg the TemplateArgument instance to print.
34 /// \param Out the raw_ostream instance to use for printing.
35 static void printIntegral(const TemplateArgument &TemplArg,
36 llvm::raw_ostream &Out) {
37 const ::clang::Type *T = TemplArg.getIntegralType().getTypePtr();
38 const llvm::APSInt *Val = TemplArg.getAsIntegral();
40 if (T->isBooleanType()) {
41 Out << (Val->getBoolValue() ? "true" : "false");
42 } else if (T->isCharType()) {
43 const unsigned char Ch = Val->getZExtValue();
44 const std::string Str(1, Ch);
45 Out << ((Ch == '\'') ? "'\\" : "'");
46 Out.write_escaped(Str, /*UseHexEscapes=*/ true);
49 Out << Val->toString(10);
53 //===----------------------------------------------------------------------===//
54 // TemplateArgument Implementation
55 //===----------------------------------------------------------------------===//
57 TemplateArgument TemplateArgument::CreatePackCopy(ASTContext &Context,
58 const TemplateArgument *Args,
61 return TemplateArgument(0, 0);
63 TemplateArgument *Storage = new (Context) TemplateArgument [NumArgs];
64 std::copy(Args, Args + NumArgs, Storage);
65 return TemplateArgument(Storage, NumArgs);
68 bool TemplateArgument::isDependent() const {
71 assert(false && "Should not have a NULL template argument");
75 return getAsType()->isDependentType();
78 return getAsTemplate().isDependent();
80 case TemplateExpansion:
84 if (DeclContext *DC = dyn_cast<DeclContext>(getAsDecl()))
85 return DC->isDependentContext();
86 return getAsDecl()->getDeclContext()->isDependentContext();
93 return (getAsExpr()->isTypeDependent() || getAsExpr()->isValueDependent());
96 for (pack_iterator P = pack_begin(), PEnd = pack_end(); P != PEnd; ++P) {
107 bool TemplateArgument::isInstantiationDependent() const {
110 assert(false && "Should not have a NULL template argument");
114 return getAsType()->isInstantiationDependentType();
117 return getAsTemplate().isInstantiationDependent();
119 case TemplateExpansion:
123 if (DeclContext *DC = dyn_cast<DeclContext>(getAsDecl()))
124 return DC->isDependentContext();
125 return getAsDecl()->getDeclContext()->isDependentContext();
132 return getAsExpr()->isInstantiationDependent();
135 for (pack_iterator P = pack_begin(), PEnd = pack_end(); P != PEnd; ++P) {
136 if (P->isInstantiationDependent())
146 bool TemplateArgument::isPackExpansion() const {
155 case TemplateExpansion:
159 return isa<PackExpansionType>(getAsType());
162 return isa<PackExpansionExpr>(getAsExpr());
168 bool TemplateArgument::containsUnexpandedParameterPack() const {
173 case TemplateExpansion:
177 if (getAsType()->containsUnexpandedParameterPack())
182 if (getAsTemplate().containsUnexpandedParameterPack())
187 if (getAsExpr()->containsUnexpandedParameterPack())
192 for (pack_iterator P = pack_begin(), PEnd = pack_end(); P != PEnd; ++P)
193 if (P->containsUnexpandedParameterPack())
202 llvm::Optional<unsigned> TemplateArgument::getNumTemplateExpansions() const {
203 assert(Kind == TemplateExpansion);
204 if (TemplateArg.NumExpansions)
205 return TemplateArg.NumExpansions - 1;
207 return llvm::Optional<unsigned>();
210 void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID,
211 const ASTContext &Context) const {
218 getAsType().Profile(ID);
222 ID.AddPointer(getAsDecl()? getAsDecl()->getCanonicalDecl() : 0);
226 case TemplateExpansion: {
227 TemplateName Template = getAsTemplateOrTemplatePattern();
228 if (TemplateTemplateParmDecl *TTP
229 = dyn_cast_or_null<TemplateTemplateParmDecl>(
230 Template.getAsTemplateDecl())) {
232 ID.AddInteger(TTP->getDepth());
233 ID.AddInteger(TTP->getPosition());
234 ID.AddBoolean(TTP->isParameterPack());
236 ID.AddBoolean(false);
237 ID.AddPointer(Context.getCanonicalTemplateName(Template)
238 .getAsVoidPointer());
244 getAsIntegral()->Profile(ID);
245 getIntegralType().Profile(ID);
249 getAsExpr()->Profile(ID, Context, true);
253 ID.AddInteger(Args.NumArgs);
254 for (unsigned I = 0; I != Args.NumArgs; ++I)
255 Args.Args[I].Profile(ID, Context);
259 bool TemplateArgument::structurallyEquals(const TemplateArgument &Other) const {
260 if (getKind() != Other.getKind()) return false;
268 case TemplateExpansion:
269 return TypeOrValue == Other.TypeOrValue;
272 return getIntegralType() == Other.getIntegralType() &&
273 *getAsIntegral() == *Other.getAsIntegral();
276 if (Args.NumArgs != Other.Args.NumArgs) return false;
277 for (unsigned I = 0, E = Args.NumArgs; I != E; ++I)
278 if (!Args.Args[I].structurallyEquals(Other.Args.Args[I]))
283 // Suppress warnings.
287 TemplateArgument TemplateArgument::getPackExpansionPattern() const {
288 assert(isPackExpansion());
292 return getAsType()->getAs<PackExpansionType>()->getPattern();
295 return cast<PackExpansionExpr>(getAsExpr())->getPattern();
297 case TemplateExpansion:
298 return TemplateArgument(getAsTemplateOrTemplatePattern());
305 return TemplateArgument();
308 return TemplateArgument();
311 void TemplateArgument::print(const PrintingPolicy &Policy,
312 llvm::raw_ostream &Out) const {
319 PrintingPolicy SubPolicy(Policy);
320 SubPolicy.SuppressStrongLifetime = true;
322 getAsType().getAsStringInternal(TypeStr, SubPolicy);
329 if (NamedDecl *ND = dyn_cast_or_null<NamedDecl>(getAsDecl())) {
330 if (ND->getDeclName()) {
332 Out << ND->getNameAsString();
337 Out << "<anonymous>";
343 getAsTemplate().print(Out, Policy);
346 case TemplateExpansion:
347 getAsTemplateOrTemplatePattern().print(Out, Policy);
352 printIntegral(*this, Out);
357 getAsExpr()->printPretty(Out, 0, Policy);
363 for (TemplateArgument::pack_iterator P = pack_begin(), PEnd = pack_end();
370 P->print(Policy, Out);
377 //===----------------------------------------------------------------------===//
378 // TemplateArgumentLoc Implementation
379 //===----------------------------------------------------------------------===//
381 TemplateArgumentLocInfo::TemplateArgumentLocInfo() {
382 memset((void*)this, 0, sizeof(TemplateArgumentLocInfo));
385 SourceRange TemplateArgumentLoc::getSourceRange() const {
386 switch (Argument.getKind()) {
387 case TemplateArgument::Expression:
388 return getSourceExpression()->getSourceRange();
390 case TemplateArgument::Declaration:
391 return getSourceDeclExpression()->getSourceRange();
393 case TemplateArgument::Type:
394 if (TypeSourceInfo *TSI = getTypeSourceInfo())
395 return TSI->getTypeLoc().getSourceRange();
397 return SourceRange();
399 case TemplateArgument::Template:
400 if (getTemplateQualifierLoc())
401 return SourceRange(getTemplateQualifierLoc().getBeginLoc(),
402 getTemplateNameLoc());
403 return SourceRange(getTemplateNameLoc());
405 case TemplateArgument::TemplateExpansion:
406 if (getTemplateQualifierLoc())
407 return SourceRange(getTemplateQualifierLoc().getBeginLoc(),
408 getTemplateEllipsisLoc());
409 return SourceRange(getTemplateNameLoc(), getTemplateEllipsisLoc());
411 case TemplateArgument::Integral:
412 case TemplateArgument::Pack:
413 case TemplateArgument::Null:
414 return SourceRange();
417 // Silence bonus gcc warning.
418 return SourceRange();
422 TemplateArgumentLoc::getPackExpansionPattern(SourceLocation &Ellipsis,
423 llvm::Optional<unsigned> &NumExpansions,
424 ASTContext &Context) const {
425 assert(Argument.isPackExpansion());
427 switch (Argument.getKind()) {
428 case TemplateArgument::Type: {
429 // FIXME: We shouldn't ever have to worry about missing
431 TypeSourceInfo *ExpansionTSInfo = getTypeSourceInfo();
432 if (!ExpansionTSInfo)
433 ExpansionTSInfo = Context.getTrivialTypeSourceInfo(
434 getArgument().getAsType(),
436 PackExpansionTypeLoc Expansion
437 = cast<PackExpansionTypeLoc>(ExpansionTSInfo->getTypeLoc());
438 Ellipsis = Expansion.getEllipsisLoc();
440 TypeLoc Pattern = Expansion.getPatternLoc();
441 NumExpansions = Expansion.getTypePtr()->getNumExpansions();
443 // FIXME: This is horrible. We know where the source location data is for
444 // the pattern, and we have the pattern's type, but we are forced to copy
445 // them into an ASTContext because TypeSourceInfo bundles them together
446 // and TemplateArgumentLoc traffics in TypeSourceInfo pointers.
447 TypeSourceInfo *PatternTSInfo
448 = Context.CreateTypeSourceInfo(Pattern.getType(),
449 Pattern.getFullDataSize());
450 memcpy(PatternTSInfo->getTypeLoc().getOpaqueData(),
451 Pattern.getOpaqueData(), Pattern.getFullDataSize());
452 return TemplateArgumentLoc(TemplateArgument(Pattern.getType()),
456 case TemplateArgument::Expression: {
457 PackExpansionExpr *Expansion
458 = cast<PackExpansionExpr>(Argument.getAsExpr());
459 Expr *Pattern = Expansion->getPattern();
460 Ellipsis = Expansion->getEllipsisLoc();
461 NumExpansions = Expansion->getNumExpansions();
462 return TemplateArgumentLoc(Pattern, Pattern);
465 case TemplateArgument::TemplateExpansion:
466 Ellipsis = getTemplateEllipsisLoc();
467 NumExpansions = Argument.getNumTemplateExpansions();
468 return TemplateArgumentLoc(Argument.getPackExpansionPattern(),
469 getTemplateQualifierLoc(),
470 getTemplateNameLoc());
472 case TemplateArgument::Declaration:
473 case TemplateArgument::Template:
474 case TemplateArgument::Integral:
475 case TemplateArgument::Pack:
476 case TemplateArgument::Null:
477 return TemplateArgumentLoc();
480 return TemplateArgumentLoc();
483 const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
484 const TemplateArgument &Arg) {
485 switch (Arg.getKind()) {
486 case TemplateArgument::Null:
487 // This is bad, but not as bad as crashing because of argument
489 return DB << "(null template argument)";
491 case TemplateArgument::Type:
492 return DB << Arg.getAsType();
494 case TemplateArgument::Declaration:
495 return DB << Arg.getAsDecl();
497 case TemplateArgument::Integral:
498 return DB << Arg.getAsIntegral()->toString(10);
500 case TemplateArgument::Template:
501 return DB << Arg.getAsTemplate();
503 case TemplateArgument::TemplateExpansion:
504 return DB << Arg.getAsTemplateOrTemplatePattern() << "...";
506 case TemplateArgument::Expression: {
507 // This shouldn't actually ever happen, so it's okay that we're
508 // regurgitating an expression here.
509 // FIXME: We're guessing at LangOptions!
510 llvm::SmallString<32> Str;
511 llvm::raw_svector_ostream OS(Str);
512 LangOptions LangOpts;
513 LangOpts.CPlusPlus = true;
514 PrintingPolicy Policy(LangOpts);
515 Arg.getAsExpr()->printPretty(OS, 0, Policy);
516 return DB << OS.str();
519 case TemplateArgument::Pack: {
520 // FIXME: We're guessing at LangOptions!
521 llvm::SmallString<32> Str;
522 llvm::raw_svector_ostream OS(Str);
523 LangOptions LangOpts;
524 LangOpts.CPlusPlus = true;
525 PrintingPolicy Policy(LangOpts);
526 Arg.print(Policy, OS);
527 return DB << OS.str();