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"
26 using namespace clang;
28 //===----------------------------------------------------------------------===//
29 // TemplateArgument Implementation
30 //===----------------------------------------------------------------------===//
32 TemplateArgument TemplateArgument::CreatePackCopy(ASTContext &Context,
33 const TemplateArgument *Args,
36 return TemplateArgument(0, 0);
38 TemplateArgument *Storage = new (Context) TemplateArgument [NumArgs];
39 std::copy(Args, Args + NumArgs, Storage);
40 return TemplateArgument(Storage, NumArgs);
43 bool TemplateArgument::isDependent() const {
46 assert(false && "Should not have a NULL template argument");
50 return getAsType()->isDependentType();
53 return getAsTemplate().isDependent();
55 case TemplateExpansion:
59 if (DeclContext *DC = dyn_cast<DeclContext>(getAsDecl()))
60 return DC->isDependentContext();
61 return getAsDecl()->getDeclContext()->isDependentContext();
68 return (getAsExpr()->isTypeDependent() || getAsExpr()->isValueDependent());
71 for (pack_iterator P = pack_begin(), PEnd = pack_end(); P != PEnd; ++P) {
82 bool TemplateArgument::isPackExpansion() const {
91 case TemplateExpansion:
95 return isa<PackExpansionType>(getAsType());
98 return isa<PackExpansionExpr>(getAsExpr());
104 bool TemplateArgument::containsUnexpandedParameterPack() const {
109 case TemplateExpansion:
113 if (getAsType()->containsUnexpandedParameterPack())
118 if (getAsTemplate().containsUnexpandedParameterPack())
123 if (getAsExpr()->containsUnexpandedParameterPack())
128 for (pack_iterator P = pack_begin(), PEnd = pack_end(); P != PEnd; ++P)
129 if (P->containsUnexpandedParameterPack())
138 void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID,
139 const ASTContext &Context) const {
146 getAsType().Profile(ID);
150 ID.AddPointer(getAsDecl()? getAsDecl()->getCanonicalDecl() : 0);
154 case TemplateExpansion: {
155 TemplateName Template = getAsTemplateOrTemplatePattern();
156 if (TemplateTemplateParmDecl *TTP
157 = dyn_cast_or_null<TemplateTemplateParmDecl>(
158 Template.getAsTemplateDecl())) {
160 ID.AddInteger(TTP->getDepth());
161 ID.AddInteger(TTP->getPosition());
162 ID.AddBoolean(TTP->isParameterPack());
164 ID.AddBoolean(false);
165 ID.AddPointer(Context.getCanonicalTemplateName(Template)
166 .getAsVoidPointer());
172 getAsIntegral()->Profile(ID);
173 getIntegralType().Profile(ID);
177 getAsExpr()->Profile(ID, Context, true);
181 ID.AddInteger(Args.NumArgs);
182 for (unsigned I = 0; I != Args.NumArgs; ++I)
183 Args.Args[I].Profile(ID, Context);
187 bool TemplateArgument::structurallyEquals(const TemplateArgument &Other) const {
188 if (getKind() != Other.getKind()) return false;
196 case TemplateExpansion:
197 return TypeOrValue == Other.TypeOrValue;
200 return getIntegralType() == Other.getIntegralType() &&
201 *getAsIntegral() == *Other.getAsIntegral();
204 if (Args.NumArgs != Other.Args.NumArgs) return false;
205 for (unsigned I = 0, E = Args.NumArgs; I != E; ++I)
206 if (!Args.Args[I].structurallyEquals(Other.Args.Args[I]))
211 // Suppress warnings.
215 TemplateArgument TemplateArgument::getPackExpansionPattern() const {
216 assert(isPackExpansion());
220 return getAsType()->getAs<PackExpansionType>()->getPattern();
223 return cast<PackExpansionExpr>(getAsExpr())->getPattern();
225 case TemplateExpansion:
226 return TemplateArgument(getAsTemplateOrTemplatePattern(), false);
233 return TemplateArgument();
236 return TemplateArgument();
239 void TemplateArgument::print(const PrintingPolicy &Policy,
240 llvm::raw_ostream &Out) const {
248 getAsType().getAsStringInternal(TypeStr, Policy);
255 if (NamedDecl *ND = dyn_cast_or_null<NamedDecl>(getAsDecl())) {
256 if (ND->getDeclName()) {
258 Out << ND->getNameAsString();
263 Out << "<anonymous>";
269 getAsTemplate().print(Out, Policy);
272 case TemplateExpansion:
273 getAsTemplateOrTemplatePattern().print(Out, Policy);
278 Out << getAsIntegral()->toString(10);
283 getAsExpr()->printPretty(Out, 0, Policy);
289 for (TemplateArgument::pack_iterator P = pack_begin(), PEnd = pack_end();
296 P->print(Policy, Out);
303 //===----------------------------------------------------------------------===//
304 // TemplateArgumentLoc Implementation
305 //===----------------------------------------------------------------------===//
307 TemplateArgumentLocInfo::TemplateArgumentLocInfo() {
308 memset(this, 0, sizeof(TemplateArgumentLocInfo));
311 SourceRange TemplateArgumentLoc::getSourceRange() const {
312 switch (Argument.getKind()) {
313 case TemplateArgument::Expression:
314 return getSourceExpression()->getSourceRange();
316 case TemplateArgument::Declaration:
317 return getSourceDeclExpression()->getSourceRange();
319 case TemplateArgument::Type:
320 if (TypeSourceInfo *TSI = getTypeSourceInfo())
321 return TSI->getTypeLoc().getSourceRange();
323 return SourceRange();
325 case TemplateArgument::Template:
326 if (getTemplateQualifierRange().isValid())
327 return SourceRange(getTemplateQualifierRange().getBegin(),
328 getTemplateNameLoc());
329 return SourceRange(getTemplateNameLoc());
331 case TemplateArgument::TemplateExpansion:
332 if (getTemplateQualifierRange().isValid())
333 return SourceRange(getTemplateQualifierRange().getBegin(),
334 getTemplateEllipsisLoc());
335 return SourceRange(getTemplateNameLoc(), getTemplateEllipsisLoc());
337 case TemplateArgument::Integral:
338 case TemplateArgument::Pack:
339 case TemplateArgument::Null:
340 return SourceRange();
343 // Silence bonus gcc warning.
344 return SourceRange();
348 TemplateArgumentLoc::getPackExpansionPattern(SourceLocation &Ellipsis,
349 llvm::Optional<unsigned> &NumExpansions,
350 ASTContext &Context) const {
351 assert(Argument.isPackExpansion());
353 switch (Argument.getKind()) {
354 case TemplateArgument::Type: {
355 // FIXME: We shouldn't ever have to worry about missing
357 TypeSourceInfo *ExpansionTSInfo = getTypeSourceInfo();
358 if (!ExpansionTSInfo)
359 ExpansionTSInfo = Context.getTrivialTypeSourceInfo(
360 getArgument().getAsType(),
362 PackExpansionTypeLoc Expansion
363 = cast<PackExpansionTypeLoc>(ExpansionTSInfo->getTypeLoc());
364 Ellipsis = Expansion.getEllipsisLoc();
366 TypeLoc Pattern = Expansion.getPatternLoc();
367 NumExpansions = Expansion.getTypePtr()->getNumExpansions();
369 // FIXME: This is horrible. We know where the source location data is for
370 // the pattern, and we have the pattern's type, but we are forced to copy
371 // them into an ASTContext because TypeSourceInfo bundles them together
372 // and TemplateArgumentLoc traffics in TypeSourceInfo pointers.
373 TypeSourceInfo *PatternTSInfo
374 = Context.CreateTypeSourceInfo(Pattern.getType(),
375 Pattern.getFullDataSize());
376 memcpy(PatternTSInfo->getTypeLoc().getOpaqueData(),
377 Pattern.getOpaqueData(), Pattern.getFullDataSize());
378 return TemplateArgumentLoc(TemplateArgument(Pattern.getType()),
382 case TemplateArgument::Expression: {
383 PackExpansionExpr *Expansion
384 = cast<PackExpansionExpr>(Argument.getAsExpr());
385 Expr *Pattern = Expansion->getPattern();
386 Ellipsis = Expansion->getEllipsisLoc();
387 NumExpansions = Expansion->getNumExpansions();
388 return TemplateArgumentLoc(Pattern, Pattern);
391 case TemplateArgument::TemplateExpansion:
392 // FIXME: Variadic templates num expansions
393 Ellipsis = getTemplateEllipsisLoc();
394 return TemplateArgumentLoc(Argument.getPackExpansionPattern(),
395 getTemplateQualifierRange(),
396 getTemplateNameLoc());
398 case TemplateArgument::Declaration:
399 case TemplateArgument::Template:
400 case TemplateArgument::Integral:
401 case TemplateArgument::Pack:
402 case TemplateArgument::Null:
403 return TemplateArgumentLoc();
406 return TemplateArgumentLoc();
409 const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
410 const TemplateArgument &Arg) {
411 switch (Arg.getKind()) {
412 case TemplateArgument::Null:
413 // This is bad, but not as bad as crashing because of argument
415 return DB << "(null template argument)";
417 case TemplateArgument::Type:
418 return DB << Arg.getAsType();
420 case TemplateArgument::Declaration:
421 return DB << Arg.getAsDecl();
423 case TemplateArgument::Integral:
424 return DB << Arg.getAsIntegral()->toString(10);
426 case TemplateArgument::Template:
427 return DB << Arg.getAsTemplate();
429 case TemplateArgument::TemplateExpansion:
430 return DB << Arg.getAsTemplateOrTemplatePattern() << "...";
432 case TemplateArgument::Expression: {
433 // This shouldn't actually ever happen, so it's okay that we're
434 // regurgitating an expression here.
435 // FIXME: We're guessing at LangOptions!
436 llvm::SmallString<32> Str;
437 llvm::raw_svector_ostream OS(Str);
438 LangOptions LangOpts;
439 LangOpts.CPlusPlus = true;
440 PrintingPolicy Policy(LangOpts);
441 Arg.getAsExpr()->printPretty(OS, 0, Policy);
442 return DB << OS.str();
445 case TemplateArgument::Pack: {
446 // FIXME: We're guessing at LangOptions!
447 llvm::SmallString<32> Str;
448 llvm::raw_svector_ostream OS(Str);
449 LangOptions LangOpts;
450 LangOpts.CPlusPlus = true;
451 PrintingPolicy Policy(LangOpts);
452 Arg.print(Policy, OS);
453 return DB << OS.str();