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