TemplateBase.cpp revision 8fe83e1df954d72c0f4ffc15d20a5222ec151c21
1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com//===--- TemplateBase.cpp - Common template AST class implementation ------===// 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com// 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com// The LLVM Compiler Infrastructure 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com// 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com// This file is distributed under the University of Illinois Open Source 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com// License. See LICENSE.TXT for details. 7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com// 8ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com//===----------------------------------------------------------------------===// 9b7061176c7f414616fe2e79e832b3e0abe326af6robertphillips@google.com// 10b7061176c7f414616fe2e79e832b3e0abe326af6robertphillips@google.com// This file implements common classes used throughout C++ template 11ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com// representations. 12ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com// 13ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com//===----------------------------------------------------------------------===// 14ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com 15ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com#include "clang/AST/TemplateBase.h" 16ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com#include "clang/AST/ASTContext.h" 174913b7794ad5f699a92feaee8e514571d218645breed@android.com#include "clang/AST/DeclBase.h" 1804d86c6a6b8eb8631752b3680f1292fa0a2c7119reed@android.com#include "clang/AST/DeclTemplate.h" 1904d86c6a6b8eb8631752b3680f1292fa0a2c7119reed@android.com#include "clang/AST/Expr.h" 2004d86c6a6b8eb8631752b3680f1292fa0a2c7119reed@android.com#include "clang/AST/ExprCXX.h" 21ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com#include "clang/AST/Type.h" 2204d86c6a6b8eb8631752b3680f1292fa0a2c7119reed@android.com#include "clang/AST/TypeLoc.h" 2304d86c6a6b8eb8631752b3680f1292fa0a2c7119reed@android.com#include "clang/Basic/Diagnostic.h" 2404d86c6a6b8eb8631752b3680f1292fa0a2c7119reed@android.com#include "llvm/ADT/FoldingSet.h" 2504d86c6a6b8eb8631752b3680f1292fa0a2c7119reed@android.com#include "llvm/ADT/SmallString.h" 2604d86c6a6b8eb8631752b3680f1292fa0a2c7119reed@android.com#include <algorithm> 2704d86c6a6b8eb8631752b3680f1292fa0a2c7119reed@android.com#include <cctype> 28ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 2904d86c6a6b8eb8631752b3680f1292fa0a2c7119reed@android.comusing namespace clang; 3004d86c6a6b8eb8631752b3680f1292fa0a2c7119reed@android.com 3104d86c6a6b8eb8631752b3680f1292fa0a2c7119reed@android.com/// \brief Print a template integral argument value. 3204d86c6a6b8eb8631752b3680f1292fa0a2c7119reed@android.com/// 3304d86c6a6b8eb8631752b3680f1292fa0a2c7119reed@android.com/// \param TemplArg the TemplateArgument instance to print. 3404d86c6a6b8eb8631752b3680f1292fa0a2c7119reed@android.com/// 3504d86c6a6b8eb8631752b3680f1292fa0a2c7119reed@android.com/// \param Out the raw_ostream instance to use for printing. 3604d86c6a6b8eb8631752b3680f1292fa0a2c7119reed@android.comstatic void printIntegral(const TemplateArgument &TemplArg, 3704d86c6a6b8eb8631752b3680f1292fa0a2c7119reed@android.com raw_ostream &Out) { 3804d86c6a6b8eb8631752b3680f1292fa0a2c7119reed@android.com const ::clang::Type *T = TemplArg.getIntegralType().getTypePtr(); 3904d86c6a6b8eb8631752b3680f1292fa0a2c7119reed@android.com const llvm::APSInt *Val = TemplArg.getAsIntegral(); 4004d86c6a6b8eb8631752b3680f1292fa0a2c7119reed@android.com 4104d86c6a6b8eb8631752b3680f1292fa0a2c7119reed@android.com if (T->isBooleanType()) { 4204d86c6a6b8eb8631752b3680f1292fa0a2c7119reed@android.com Out << (Val->getBoolValue() ? "true" : "false"); 4304d86c6a6b8eb8631752b3680f1292fa0a2c7119reed@android.com } else if (T->isCharType()) { 447ab2cf90b617e25a2ae031fe12c22d71583eee48reed@android.com const char Ch = Val->getZExtValue(); 454913b7794ad5f699a92feaee8e514571d218645breed@android.com Out << ((Ch == '\'') ? "'\\" : "'"); 464913b7794ad5f699a92feaee8e514571d218645breed@android.com Out.write_escaped(StringRef(&Ch, 1), /*UseHexEscapes=*/ true); 474913b7794ad5f699a92feaee8e514571d218645breed@android.com Out << "'"; 484913b7794ad5f699a92feaee8e514571d218645breed@android.com } else { 494913b7794ad5f699a92feaee8e514571d218645breed@android.com Out << Val->toString(10); 504913b7794ad5f699a92feaee8e514571d218645breed@android.com } 514913b7794ad5f699a92feaee8e514571d218645breed@android.com} 524913b7794ad5f699a92feaee8e514571d218645breed@android.com 534913b7794ad5f699a92feaee8e514571d218645breed@android.com//===----------------------------------------------------------------------===// 544913b7794ad5f699a92feaee8e514571d218645breed@android.com// TemplateArgument Implementation 554913b7794ad5f699a92feaee8e514571d218645breed@android.com//===----------------------------------------------------------------------===// 564913b7794ad5f699a92feaee8e514571d218645breed@android.com 57ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.comTemplateArgument TemplateArgument::CreatePackCopy(ASTContext &Context, 584913b7794ad5f699a92feaee8e514571d218645breed@android.com const TemplateArgument *Args, 594913b7794ad5f699a92feaee8e514571d218645breed@android.com unsigned NumArgs) { 604913b7794ad5f699a92feaee8e514571d218645breed@android.com if (NumArgs == 0) 614913b7794ad5f699a92feaee8e514571d218645breed@android.com return TemplateArgument(0, 0); 624913b7794ad5f699a92feaee8e514571d218645breed@android.com 634913b7794ad5f699a92feaee8e514571d218645breed@android.com TemplateArgument *Storage = new (Context) TemplateArgument [NumArgs]; 644913b7794ad5f699a92feaee8e514571d218645breed@android.com std::copy(Args, Args + NumArgs, Storage); 654913b7794ad5f699a92feaee8e514571d218645breed@android.com return TemplateArgument(Storage, NumArgs); 664913b7794ad5f699a92feaee8e514571d218645breed@android.com} 674913b7794ad5f699a92feaee8e514571d218645breed@android.com 684913b7794ad5f699a92feaee8e514571d218645breed@android.combool TemplateArgument::isDependent() const { 694913b7794ad5f699a92feaee8e514571d218645breed@android.com switch (getKind()) { 704913b7794ad5f699a92feaee8e514571d218645breed@android.com case Null: 714913b7794ad5f699a92feaee8e514571d218645breed@android.com llvm_unreachable("Should not have a NULL template argument"); 724913b7794ad5f699a92feaee8e514571d218645breed@android.com 734913b7794ad5f699a92feaee8e514571d218645breed@android.com case Type: 744913b7794ad5f699a92feaee8e514571d218645breed@android.com return getAsType()->isDependentType(); 754913b7794ad5f699a92feaee8e514571d218645breed@android.com 767ab2cf90b617e25a2ae031fe12c22d71583eee48reed@android.com case Template: 77da449a38a2ac06f47f504cef7897afe322981daereed@android.com return getAsTemplate().isDependent(); 78ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com 79ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com case TemplateExpansion: 80ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com return true; 81ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com 82ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com case Declaration: 83ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com if (DeclContext *DC = dyn_cast<DeclContext>(getAsDecl())) 84ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com return DC->isDependentContext(); 85ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com return getAsDecl()->getDeclContext()->isDependentContext(); 86ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com 87ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com case Integral: 88ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com // Never dependent 89ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com return false; 90ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com 91ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com case Expression: 92ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com return (getAsExpr()->isTypeDependent() || getAsExpr()->isValueDependent()); 93ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com 94ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com case Pack: 95ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com for (pack_iterator P = pack_begin(), PEnd = pack_end(); P != PEnd; ++P) { 96ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com if (P->isDependent()) 97ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com return true; 9881e3d7f7943d5c257a07580b75218a5e256b0aadreed@google.com } 99ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com 100ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com return false; 101ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com } 102ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 1037ab2cf90b617e25a2ae031fe12c22d71583eee48reed@android.com llvm_unreachable("Invalid TemplateArgument Kind!"); 104ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com} 105ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com 106ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.combool TemplateArgument::isInstantiationDependent() const { 107ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com switch (getKind()) { 108ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com case Null: 109ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com llvm_unreachable("Should not have a NULL template argument"); 110ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com 111ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com case Type: 112ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com return getAsType()->isInstantiationDependentType(); 113ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com 114ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com case Template: 115ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com return getAsTemplate().isInstantiationDependent(); 116ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com 117ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com case TemplateExpansion: 118ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com return true; 119ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com 120ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com case Declaration: 12181e3d7f7943d5c257a07580b75218a5e256b0aadreed@google.com if (DeclContext *DC = dyn_cast<DeclContext>(getAsDecl())) 12281e3d7f7943d5c257a07580b75218a5e256b0aadreed@google.com return DC->isDependentContext(); 123ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com return getAsDecl()->getDeclContext()->isDependentContext(); 124ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 125ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com case Integral: 126ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com // Never dependent 127ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com return false; 128ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com 129ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com case Expression: 130ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com return getAsExpr()->isInstantiationDependent(); 131ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com 132ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com case Pack: 133ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com for (pack_iterator P = pack_begin(), PEnd = pack_end(); P != PEnd; ++P) { 134ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com if (P->isInstantiationDependent()) 135e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.org return true; 136ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com } 137ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com 138ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com return false; 139ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com } 140ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com 141ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com llvm_unreachable("Invalid TemplateArgument Kind!"); 142ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com} 143ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com 144ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.combool TemplateArgument::isPackExpansion() const { 145ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com switch (getKind()) { 146ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com case Null: 147ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com case Declaration: 148ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com case Integral: 14981e3d7f7943d5c257a07580b75218a5e256b0aadreed@google.com case Pack: 15004d86c6a6b8eb8631752b3680f1292fa0a2c7119reed@android.com case Template: 151ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com return false; 152ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com 153ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com case TemplateExpansion: 154ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com return true; 155ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 156da449a38a2ac06f47f504cef7897afe322981daereed@android.com case Type: 157da449a38a2ac06f47f504cef7897afe322981daereed@android.com return isa<PackExpansionType>(getAsType()); 158da449a38a2ac06f47f504cef7897afe322981daereed@android.com 159da449a38a2ac06f47f504cef7897afe322981daereed@android.com case Expression: 160da449a38a2ac06f47f504cef7897afe322981daereed@android.com return isa<PackExpansionExpr>(getAsExpr()); 161da449a38a2ac06f47f504cef7897afe322981daereed@android.com } 162da449a38a2ac06f47f504cef7897afe322981daereed@android.com 163e396455d2d60ddf8e625b5037254f3c09fbcdcf5commit-bot@chromium.org llvm_unreachable("Invalid TemplateArgument Kind!"); 164e396455d2d60ddf8e625b5037254f3c09fbcdcf5commit-bot@chromium.org} 165e396455d2d60ddf8e625b5037254f3c09fbcdcf5commit-bot@chromium.org 166e396455d2d60ddf8e625b5037254f3c09fbcdcf5commit-bot@chromium.orgbool TemplateArgument::containsUnexpandedParameterPack() const { 167e396455d2d60ddf8e625b5037254f3c09fbcdcf5commit-bot@chromium.org switch (getKind()) { 168da449a38a2ac06f47f504cef7897afe322981daereed@android.com case Null: 169da449a38a2ac06f47f504cef7897afe322981daereed@android.com case Declaration: 170da449a38a2ac06f47f504cef7897afe322981daereed@android.com case Integral: 171b7061176c7f414616fe2e79e832b3e0abe326af6robertphillips@google.com case TemplateExpansion: 172da449a38a2ac06f47f504cef7897afe322981daereed@android.com break; 173da449a38a2ac06f47f504cef7897afe322981daereed@android.com 174b7061176c7f414616fe2e79e832b3e0abe326af6robertphillips@google.com case Type: 175da449a38a2ac06f47f504cef7897afe322981daereed@android.com if (getAsType()->containsUnexpandedParameterPack()) 176da449a38a2ac06f47f504cef7897afe322981daereed@android.com return true; 177261b8e2ca1cf22303ad95267f0bdc6e87e1bbe70reed@google.com break; 178b7061176c7f414616fe2e79e832b3e0abe326af6robertphillips@google.com 179da449a38a2ac06f47f504cef7897afe322981daereed@android.com case Template: 180ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com if (getAsTemplate().containsUnexpandedParameterPack()) 181da449a38a2ac06f47f504cef7897afe322981daereed@android.com return true; 182da449a38a2ac06f47f504cef7897afe322981daereed@android.com break; 183da449a38a2ac06f47f504cef7897afe322981daereed@android.com 184da449a38a2ac06f47f504cef7897afe322981daereed@android.com case Expression: 185ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com if (getAsExpr()->containsUnexpandedParameterPack()) 186ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com return true; 187ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com break; 188ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com 189ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com case Pack: 190ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com for (pack_iterator P = pack_begin(), PEnd = pack_end(); P != PEnd; ++P) 191ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com if (P->containsUnexpandedParameterPack()) 192ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com return true; 193ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com 194ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com break; 195ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com } 196ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com 197ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com return false; 198ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com} 199ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com 200ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.comllvm::Optional<unsigned> TemplateArgument::getNumTemplateExpansions() const { 201ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com assert(Kind == TemplateExpansion); 202ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com if (TemplateArg.NumExpansions) 203ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com return TemplateArg.NumExpansions - 1; 204ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com 205ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com return llvm::Optional<unsigned>(); 206ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com} 207ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com 208ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.comvoid TemplateArgument::Profile(llvm::FoldingSetNodeID &ID, 209ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com const ASTContext &Context) const { 210ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com ID.AddInteger(Kind); 211ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com switch (Kind) { 2124d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com case Null: 2134d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com break; 214ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com 2154d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com case Type: 216ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com getAsType().Profile(ID); 217ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com break; 21881e3d7f7943d5c257a07580b75218a5e256b0aadreed@google.com 219ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com case Declaration: 220ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com ID.AddPointer(getAsDecl()? getAsDecl()->getCanonicalDecl() : 0); 221ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com break; 222ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com 223ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com case Template: 224ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com case TemplateExpansion: { 225 TemplateName Template = getAsTemplateOrTemplatePattern(); 226 if (TemplateTemplateParmDecl *TTP 227 = dyn_cast_or_null<TemplateTemplateParmDecl>( 228 Template.getAsTemplateDecl())) { 229 ID.AddBoolean(true); 230 ID.AddInteger(TTP->getDepth()); 231 ID.AddInteger(TTP->getPosition()); 232 ID.AddBoolean(TTP->isParameterPack()); 233 } else { 234 ID.AddBoolean(false); 235 ID.AddPointer(Context.getCanonicalTemplateName(Template) 236 .getAsVoidPointer()); 237 } 238 break; 239 } 240 241 case Integral: 242 getAsIntegral()->Profile(ID); 243 getIntegralType().Profile(ID); 244 break; 245 246 case Expression: 247 getAsExpr()->Profile(ID, Context, true); 248 break; 249 250 case Pack: 251 ID.AddInteger(Args.NumArgs); 252 for (unsigned I = 0; I != Args.NumArgs; ++I) 253 Args.Args[I].Profile(ID, Context); 254 } 255} 256 257bool TemplateArgument::structurallyEquals(const TemplateArgument &Other) const { 258 if (getKind() != Other.getKind()) return false; 259 260 switch (getKind()) { 261 case Null: 262 case Type: 263 case Declaration: 264 case Expression: 265 case Template: 266 case TemplateExpansion: 267 return TypeOrValue == Other.TypeOrValue; 268 269 case Integral: 270 return getIntegralType() == Other.getIntegralType() && 271 *getAsIntegral() == *Other.getAsIntegral(); 272 273 case Pack: 274 if (Args.NumArgs != Other.Args.NumArgs) return false; 275 for (unsigned I = 0, E = Args.NumArgs; I != E; ++I) 276 if (!Args.Args[I].structurallyEquals(Other.Args.Args[I])) 277 return false; 278 return true; 279 } 280 281 llvm_unreachable("Invalid TemplateArgument Kind!"); 282} 283 284TemplateArgument TemplateArgument::getPackExpansionPattern() const { 285 assert(isPackExpansion()); 286 287 switch (getKind()) { 288 case Type: 289 return getAsType()->getAs<PackExpansionType>()->getPattern(); 290 291 case Expression: 292 return cast<PackExpansionExpr>(getAsExpr())->getPattern(); 293 294 case TemplateExpansion: 295 return TemplateArgument(getAsTemplateOrTemplatePattern()); 296 297 case Declaration: 298 case Integral: 299 case Pack: 300 case Null: 301 case Template: 302 return TemplateArgument(); 303 } 304 305 llvm_unreachable("Invalid TemplateArgument Kind!"); 306} 307 308void TemplateArgument::print(const PrintingPolicy &Policy, 309 raw_ostream &Out) const { 310 switch (getKind()) { 311 case Null: 312 Out << "<no value>"; 313 break; 314 315 case Type: { 316 PrintingPolicy SubPolicy(Policy); 317 SubPolicy.SuppressStrongLifetime = true; 318 std::string TypeStr; 319 getAsType().getAsStringInternal(TypeStr, SubPolicy); 320 Out << TypeStr; 321 break; 322 } 323 324 case Declaration: { 325 bool Unnamed = true; 326 if (NamedDecl *ND = dyn_cast_or_null<NamedDecl>(getAsDecl())) { 327 if (ND->getDeclName()) { 328 Unnamed = false; 329 Out << ND->getNameAsString(); 330 } 331 } 332 333 if (Unnamed) { 334 Out << "<anonymous>"; 335 } 336 break; 337 } 338 339 case Template: 340 getAsTemplate().print(Out, Policy); 341 break; 342 343 case TemplateExpansion: 344 getAsTemplateOrTemplatePattern().print(Out, Policy); 345 Out << "..."; 346 break; 347 348 case Integral: { 349 printIntegral(*this, Out); 350 break; 351 } 352 353 case Expression: 354 getAsExpr()->printPretty(Out, 0, Policy); 355 break; 356 357 case Pack: 358 Out << "<"; 359 bool First = true; 360 for (TemplateArgument::pack_iterator P = pack_begin(), PEnd = pack_end(); 361 P != PEnd; ++P) { 362 if (First) 363 First = false; 364 else 365 Out << ", "; 366 367 P->print(Policy, Out); 368 } 369 Out << ">"; 370 break; 371 } 372} 373 374//===----------------------------------------------------------------------===// 375// TemplateArgumentLoc Implementation 376//===----------------------------------------------------------------------===// 377 378TemplateArgumentLocInfo::TemplateArgumentLocInfo() { 379 memset((void*)this, 0, sizeof(TemplateArgumentLocInfo)); 380} 381 382SourceRange TemplateArgumentLoc::getSourceRange() const { 383 switch (Argument.getKind()) { 384 case TemplateArgument::Expression: 385 return getSourceExpression()->getSourceRange(); 386 387 case TemplateArgument::Declaration: 388 return getSourceDeclExpression()->getSourceRange(); 389 390 case TemplateArgument::Type: 391 if (TypeSourceInfo *TSI = getTypeSourceInfo()) 392 return TSI->getTypeLoc().getSourceRange(); 393 else 394 return SourceRange(); 395 396 case TemplateArgument::Template: 397 if (getTemplateQualifierLoc()) 398 return SourceRange(getTemplateQualifierLoc().getBeginLoc(), 399 getTemplateNameLoc()); 400 return SourceRange(getTemplateNameLoc()); 401 402 case TemplateArgument::TemplateExpansion: 403 if (getTemplateQualifierLoc()) 404 return SourceRange(getTemplateQualifierLoc().getBeginLoc(), 405 getTemplateEllipsisLoc()); 406 return SourceRange(getTemplateNameLoc(), getTemplateEllipsisLoc()); 407 408 case TemplateArgument::Integral: 409 case TemplateArgument::Pack: 410 case TemplateArgument::Null: 411 return SourceRange(); 412 } 413 414 llvm_unreachable("Invalid TemplateArgument Kind!"); 415} 416 417TemplateArgumentLoc 418TemplateArgumentLoc::getPackExpansionPattern(SourceLocation &Ellipsis, 419 llvm::Optional<unsigned> &NumExpansions, 420 ASTContext &Context) const { 421 assert(Argument.isPackExpansion()); 422 423 switch (Argument.getKind()) { 424 case TemplateArgument::Type: { 425 // FIXME: We shouldn't ever have to worry about missing 426 // type-source info! 427 TypeSourceInfo *ExpansionTSInfo = getTypeSourceInfo(); 428 if (!ExpansionTSInfo) 429 ExpansionTSInfo = Context.getTrivialTypeSourceInfo( 430 getArgument().getAsType(), 431 Ellipsis); 432 PackExpansionTypeLoc Expansion 433 = cast<PackExpansionTypeLoc>(ExpansionTSInfo->getTypeLoc()); 434 Ellipsis = Expansion.getEllipsisLoc(); 435 436 TypeLoc Pattern = Expansion.getPatternLoc(); 437 NumExpansions = Expansion.getTypePtr()->getNumExpansions(); 438 439 // FIXME: This is horrible. We know where the source location data is for 440 // the pattern, and we have the pattern's type, but we are forced to copy 441 // them into an ASTContext because TypeSourceInfo bundles them together 442 // and TemplateArgumentLoc traffics in TypeSourceInfo pointers. 443 TypeSourceInfo *PatternTSInfo 444 = Context.CreateTypeSourceInfo(Pattern.getType(), 445 Pattern.getFullDataSize()); 446 memcpy(PatternTSInfo->getTypeLoc().getOpaqueData(), 447 Pattern.getOpaqueData(), Pattern.getFullDataSize()); 448 return TemplateArgumentLoc(TemplateArgument(Pattern.getType()), 449 PatternTSInfo); 450 } 451 452 case TemplateArgument::Expression: { 453 PackExpansionExpr *Expansion 454 = cast<PackExpansionExpr>(Argument.getAsExpr()); 455 Expr *Pattern = Expansion->getPattern(); 456 Ellipsis = Expansion->getEllipsisLoc(); 457 NumExpansions = Expansion->getNumExpansions(); 458 return TemplateArgumentLoc(Pattern, Pattern); 459 } 460 461 case TemplateArgument::TemplateExpansion: 462 Ellipsis = getTemplateEllipsisLoc(); 463 NumExpansions = Argument.getNumTemplateExpansions(); 464 return TemplateArgumentLoc(Argument.getPackExpansionPattern(), 465 getTemplateQualifierLoc(), 466 getTemplateNameLoc()); 467 468 case TemplateArgument::Declaration: 469 case TemplateArgument::Template: 470 case TemplateArgument::Integral: 471 case TemplateArgument::Pack: 472 case TemplateArgument::Null: 473 return TemplateArgumentLoc(); 474 } 475 476 llvm_unreachable("Invalid TemplateArgument Kind!"); 477} 478 479const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB, 480 const TemplateArgument &Arg) { 481 switch (Arg.getKind()) { 482 case TemplateArgument::Null: 483 // This is bad, but not as bad as crashing because of argument 484 // count mismatches. 485 return DB << "(null template argument)"; 486 487 case TemplateArgument::Type: 488 return DB << Arg.getAsType(); 489 490 case TemplateArgument::Declaration: 491 return DB << Arg.getAsDecl(); 492 493 case TemplateArgument::Integral: 494 return DB << Arg.getAsIntegral()->toString(10); 495 496 case TemplateArgument::Template: 497 return DB << Arg.getAsTemplate(); 498 499 case TemplateArgument::TemplateExpansion: 500 return DB << Arg.getAsTemplateOrTemplatePattern() << "..."; 501 502 case TemplateArgument::Expression: { 503 // This shouldn't actually ever happen, so it's okay that we're 504 // regurgitating an expression here. 505 // FIXME: We're guessing at LangOptions! 506 llvm::SmallString<32> Str; 507 llvm::raw_svector_ostream OS(Str); 508 LangOptions LangOpts; 509 LangOpts.CPlusPlus = true; 510 PrintingPolicy Policy(LangOpts); 511 Arg.getAsExpr()->printPretty(OS, 0, Policy); 512 return DB << OS.str(); 513 } 514 515 case TemplateArgument::Pack: { 516 // FIXME: We're guessing at LangOptions! 517 llvm::SmallString<32> Str; 518 llvm::raw_svector_ostream OS(Str); 519 LangOptions LangOpts; 520 LangOpts.CPlusPlus = true; 521 PrintingPolicy Policy(LangOpts); 522 Arg.print(Policy, OS); 523 return DB << OS.str(); 524 } 525 } 526 527 llvm_unreachable("Invalid TemplateArgument Kind!"); 528} 529 530const ASTTemplateArgumentListInfo * 531ASTTemplateArgumentListInfo::Create(ASTContext &C, 532 const TemplateArgumentListInfo &List) { 533 std::size_t size = sizeof(CXXDependentScopeMemberExpr) + 534 ASTTemplateArgumentListInfo::sizeFor(List.size()); 535 void *Mem = C.Allocate(size, llvm::alignOf<ASTTemplateArgumentListInfo>()); 536 ASTTemplateArgumentListInfo *TAI = new (Mem) ASTTemplateArgumentListInfo(); 537 TAI->initializeFrom(List); 538 return TAI; 539} 540 541void ASTTemplateArgumentListInfo::initializeFrom( 542 const TemplateArgumentListInfo &Info) { 543 LAngleLoc = Info.getLAngleLoc(); 544 RAngleLoc = Info.getRAngleLoc(); 545 NumTemplateArgs = Info.size(); 546 547 TemplateArgumentLoc *ArgBuffer = getTemplateArgs(); 548 for (unsigned i = 0; i != NumTemplateArgs; ++i) 549 new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]); 550} 551 552void ASTTemplateArgumentListInfo::initializeFrom( 553 const TemplateArgumentListInfo &Info, 554 bool &Dependent, 555 bool &InstantiationDependent, 556 bool &ContainsUnexpandedParameterPack) { 557 LAngleLoc = Info.getLAngleLoc(); 558 RAngleLoc = Info.getRAngleLoc(); 559 NumTemplateArgs = Info.size(); 560 561 TemplateArgumentLoc *ArgBuffer = getTemplateArgs(); 562 for (unsigned i = 0; i != NumTemplateArgs; ++i) { 563 Dependent = Dependent || Info[i].getArgument().isDependent(); 564 InstantiationDependent = InstantiationDependent || 565 Info[i].getArgument().isInstantiationDependent(); 566 ContainsUnexpandedParameterPack 567 = ContainsUnexpandedParameterPack || 568 Info[i].getArgument().containsUnexpandedParameterPack(); 569 570 new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]); 571 } 572} 573 574void ASTTemplateArgumentListInfo::copyInto( 575 TemplateArgumentListInfo &Info) const { 576 Info.setLAngleLoc(LAngleLoc); 577 Info.setRAngleLoc(RAngleLoc); 578 for (unsigned I = 0; I != NumTemplateArgs; ++I) 579 Info.addArgument(getTemplateArgs()[I]); 580} 581 582std::size_t ASTTemplateArgumentListInfo::sizeFor(unsigned NumTemplateArgs) { 583 return sizeof(ASTTemplateArgumentListInfo) + 584 sizeof(TemplateArgumentLoc) * NumTemplateArgs; 585} 586 587void 588ASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation TemplateKWLoc, 589 const TemplateArgumentListInfo &Info) { 590 Base::initializeFrom(Info); 591 setTemplateKeywordLoc(TemplateKWLoc); 592} 593 594void 595ASTTemplateKWAndArgsInfo 596::initializeFrom(SourceLocation TemplateKWLoc, 597 const TemplateArgumentListInfo &Info, 598 bool &Dependent, 599 bool &InstantiationDependent, 600 bool &ContainsUnexpandedParameterPack) { 601 Base::initializeFrom(Info, Dependent, InstantiationDependent, 602 ContainsUnexpandedParameterPack); 603 setTemplateKeywordLoc(TemplateKWLoc); 604} 605 606void 607ASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation TemplateKWLoc) { 608 // No explicit template arguments, but template keyword loc is valid. 609 assert(TemplateKWLoc.isValid()); 610 LAngleLoc = SourceLocation(); 611 RAngleLoc = SourceLocation(); 612 NumTemplateArgs = 0; 613 setTemplateKeywordLoc(TemplateKWLoc); 614} 615 616std::size_t 617ASTTemplateKWAndArgsInfo::sizeFor(unsigned NumTemplateArgs) { 618 // Add space for the template keyword location. 619 return Base::sizeFor(NumTemplateArgs) + sizeof(SourceLocation); 620} 621 622