xref: /freebsd-src/contrib/llvm-project/clang/lib/AST/TemplateBase.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- TemplateBase.cpp - Common template AST class implementation --------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements common classes used throughout C++ template
100b57cec5SDimitry Andric // representations.
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric #include "clang/AST/TemplateBase.h"
150b57cec5SDimitry Andric #include "clang/AST/ASTContext.h"
160b57cec5SDimitry Andric #include "clang/AST/Decl.h"
170b57cec5SDimitry Andric #include "clang/AST/DeclBase.h"
180b57cec5SDimitry Andric #include "clang/AST/DeclTemplate.h"
195ffd83dbSDimitry Andric #include "clang/AST/DependenceFlags.h"
200b57cec5SDimitry Andric #include "clang/AST/Expr.h"
210b57cec5SDimitry Andric #include "clang/AST/ExprCXX.h"
220b57cec5SDimitry Andric #include "clang/AST/PrettyPrinter.h"
230b57cec5SDimitry Andric #include "clang/AST/TemplateName.h"
240b57cec5SDimitry Andric #include "clang/AST/Type.h"
250b57cec5SDimitry Andric #include "clang/AST/TypeLoc.h"
260b57cec5SDimitry Andric #include "clang/Basic/Diagnostic.h"
270b57cec5SDimitry Andric #include "clang/Basic/LLVM.h"
280b57cec5SDimitry Andric #include "clang/Basic/LangOptions.h"
290b57cec5SDimitry Andric #include "clang/Basic/SourceLocation.h"
300b57cec5SDimitry Andric #include "llvm/ADT/APSInt.h"
310b57cec5SDimitry Andric #include "llvm/ADT/FoldingSet.h"
320b57cec5SDimitry Andric #include "llvm/ADT/SmallString.h"
33fe6060f1SDimitry Andric #include "llvm/ADT/StringExtras.h"
340b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
350b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
360b57cec5SDimitry Andric #include "llvm/Support/Compiler.h"
370b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
380b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
390b57cec5SDimitry Andric #include <cassert>
400b57cec5SDimitry Andric #include <cstddef>
410b57cec5SDimitry Andric #include <cstdint>
420b57cec5SDimitry Andric #include <cstring>
43bdd1243dSDimitry Andric #include <optional>
440b57cec5SDimitry Andric 
450b57cec5SDimitry Andric using namespace clang;
460b57cec5SDimitry Andric 
470b57cec5SDimitry Andric /// Print a template integral argument value.
480b57cec5SDimitry Andric ///
490b57cec5SDimitry Andric /// \param TemplArg the TemplateArgument instance to print.
500b57cec5SDimitry Andric ///
510b57cec5SDimitry Andric /// \param Out the raw_ostream instance to use for printing.
520b57cec5SDimitry Andric ///
530b57cec5SDimitry Andric /// \param Policy the printing policy for EnumConstantDecl printing.
54fe6060f1SDimitry Andric ///
55fe6060f1SDimitry Andric /// \param IncludeType If set, ensure that the type of the expression printed
56fe6060f1SDimitry Andric /// matches the type of the template argument.
57fe6060f1SDimitry Andric static void printIntegral(const TemplateArgument &TemplArg, raw_ostream &Out,
58fe6060f1SDimitry Andric                           const PrintingPolicy &Policy, bool IncludeType) {
590b57cec5SDimitry Andric   const Type *T = TemplArg.getIntegralType().getTypePtr();
600b57cec5SDimitry Andric   const llvm::APSInt &Val = TemplArg.getAsIntegral();
610b57cec5SDimitry Andric 
6281ad6265SDimitry Andric   if (Policy.UseEnumerators) {
630b57cec5SDimitry Andric     if (const EnumType *ET = T->getAs<EnumType>()) {
640b57cec5SDimitry Andric       for (const EnumConstantDecl *ECD : ET->getDecl()->enumerators()) {
650b57cec5SDimitry Andric         // In Sema::CheckTemplateArugment, enum template arguments value are
660b57cec5SDimitry Andric         // extended to the size of the integer underlying the enum type.  This
670b57cec5SDimitry Andric         // may create a size difference between the enum value and template
680b57cec5SDimitry Andric         // argument value, requiring isSameValue here instead of operator==.
690b57cec5SDimitry Andric         if (llvm::APSInt::isSameValue(ECD->getInitVal(), Val)) {
700b57cec5SDimitry Andric           ECD->printQualifiedName(Out, Policy);
710b57cec5SDimitry Andric           return;
720b57cec5SDimitry Andric         }
730b57cec5SDimitry Andric       }
740b57cec5SDimitry Andric     }
7581ad6265SDimitry Andric   }
760b57cec5SDimitry Andric 
77fe6060f1SDimitry Andric   if (Policy.MSVCFormatting)
78fe6060f1SDimitry Andric     IncludeType = false;
79fe6060f1SDimitry Andric 
80fe6060f1SDimitry Andric   if (T->isBooleanType()) {
81fe6060f1SDimitry Andric     if (!Policy.MSVCFormatting)
820b57cec5SDimitry Andric       Out << (Val.getBoolValue() ? "true" : "false");
83fe6060f1SDimitry Andric     else
84fe6060f1SDimitry Andric       Out << Val;
850b57cec5SDimitry Andric   } else if (T->isCharType()) {
86fe6060f1SDimitry Andric     if (IncludeType) {
87fe6060f1SDimitry Andric       if (T->isSpecificBuiltinType(BuiltinType::SChar))
88fe6060f1SDimitry Andric         Out << "(signed char)";
89fe6060f1SDimitry Andric       else if (T->isSpecificBuiltinType(BuiltinType::UChar))
90fe6060f1SDimitry Andric         Out << "(unsigned char)";
91fe6060f1SDimitry Andric     }
925f757f3fSDimitry Andric     CharacterLiteral::print(Val.getZExtValue(), CharacterLiteralKind::Ascii,
935f757f3fSDimitry Andric                             Out);
94fe6060f1SDimitry Andric   } else if (T->isAnyCharacterType() && !Policy.MSVCFormatting) {
955f757f3fSDimitry Andric     CharacterLiteralKind Kind;
96fe6060f1SDimitry Andric     if (T->isWideCharType())
975f757f3fSDimitry Andric       Kind = CharacterLiteralKind::Wide;
98fe6060f1SDimitry Andric     else if (T->isChar8Type())
995f757f3fSDimitry Andric       Kind = CharacterLiteralKind::UTF8;
100fe6060f1SDimitry Andric     else if (T->isChar16Type())
1015f757f3fSDimitry Andric       Kind = CharacterLiteralKind::UTF16;
102fe6060f1SDimitry Andric     else if (T->isChar32Type())
1035f757f3fSDimitry Andric       Kind = CharacterLiteralKind::UTF32;
104fe6060f1SDimitry Andric     else
1055f757f3fSDimitry Andric       Kind = CharacterLiteralKind::Ascii;
106fe6060f1SDimitry Andric     CharacterLiteral::print(Val.getExtValue(), Kind, Out);
107fe6060f1SDimitry Andric   } else if (IncludeType) {
108fe6060f1SDimitry Andric     if (const auto *BT = T->getAs<BuiltinType>()) {
109fe6060f1SDimitry Andric       switch (BT->getKind()) {
110fe6060f1SDimitry Andric       case BuiltinType::ULongLong:
111fe6060f1SDimitry Andric         Out << Val << "ULL";
112fe6060f1SDimitry Andric         break;
113fe6060f1SDimitry Andric       case BuiltinType::LongLong:
114fe6060f1SDimitry Andric         Out << Val << "LL";
115fe6060f1SDimitry Andric         break;
116fe6060f1SDimitry Andric       case BuiltinType::ULong:
117fe6060f1SDimitry Andric         Out << Val << "UL";
118fe6060f1SDimitry Andric         break;
119fe6060f1SDimitry Andric       case BuiltinType::Long:
120fe6060f1SDimitry Andric         Out << Val << "L";
121fe6060f1SDimitry Andric         break;
122fe6060f1SDimitry Andric       case BuiltinType::UInt:
123fe6060f1SDimitry Andric         Out << Val << "U";
124fe6060f1SDimitry Andric         break;
125fe6060f1SDimitry Andric       case BuiltinType::Int:
126fe6060f1SDimitry Andric         Out << Val;
127fe6060f1SDimitry Andric         break;
128fe6060f1SDimitry Andric       default:
129fe6060f1SDimitry Andric         Out << "(" << T->getCanonicalTypeInternal().getAsString(Policy) << ")"
130fe6060f1SDimitry Andric             << Val;
131fe6060f1SDimitry Andric         break;
132fe6060f1SDimitry Andric       }
133fe6060f1SDimitry Andric     } else
134fe6060f1SDimitry Andric       Out << "(" << T->getCanonicalTypeInternal().getAsString(Policy) << ")"
135fe6060f1SDimitry Andric           << Val;
136fe6060f1SDimitry Andric   } else
1370b57cec5SDimitry Andric     Out << Val;
1380b57cec5SDimitry Andric }
139fe6060f1SDimitry Andric 
140fe6060f1SDimitry Andric static unsigned getArrayDepth(QualType type) {
141fe6060f1SDimitry Andric   unsigned count = 0;
142fe6060f1SDimitry Andric   while (const auto *arrayType = type->getAsArrayTypeUnsafe()) {
143fe6060f1SDimitry Andric     count++;
144fe6060f1SDimitry Andric     type = arrayType->getElementType();
145fe6060f1SDimitry Andric   }
146fe6060f1SDimitry Andric   return count;
147fe6060f1SDimitry Andric }
148fe6060f1SDimitry Andric 
149fe6060f1SDimitry Andric static bool needsAmpersandOnTemplateArg(QualType paramType, QualType argType) {
150fe6060f1SDimitry Andric   // Generally, if the parameter type is a pointer, we must be taking the
151fe6060f1SDimitry Andric   // address of something and need a &.  However, if the argument is an array,
152fe6060f1SDimitry Andric   // this could be implicit via array-to-pointer decay.
153fe6060f1SDimitry Andric   if (!paramType->isPointerType())
154fe6060f1SDimitry Andric     return paramType->isMemberPointerType();
155fe6060f1SDimitry Andric   if (argType->isArrayType())
156fe6060f1SDimitry Andric     return getArrayDepth(argType) == getArrayDepth(paramType->getPointeeType());
157fe6060f1SDimitry Andric   return true;
1580b57cec5SDimitry Andric }
1590b57cec5SDimitry Andric 
1600b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
1610b57cec5SDimitry Andric // TemplateArgument Implementation
1620b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
1630b57cec5SDimitry Andric 
1647a6dacacSDimitry Andric void TemplateArgument::initFromType(QualType T, bool IsNullPtr,
1657a6dacacSDimitry Andric                                     bool IsDefaulted) {
1667a6dacacSDimitry Andric   TypeOrValue.Kind = IsNullPtr ? NullPtr : Type;
1677a6dacacSDimitry Andric   TypeOrValue.IsDefaulted = IsDefaulted;
1687a6dacacSDimitry Andric   TypeOrValue.V = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
1697a6dacacSDimitry Andric }
1707a6dacacSDimitry Andric 
1717a6dacacSDimitry Andric void TemplateArgument::initFromDeclaration(ValueDecl *D, QualType QT,
1727a6dacacSDimitry Andric                                            bool IsDefaulted) {
1737a6dacacSDimitry Andric   assert(D && "Expected decl");
1747a6dacacSDimitry Andric   DeclArg.Kind = Declaration;
1757a6dacacSDimitry Andric   DeclArg.IsDefaulted = IsDefaulted;
1767a6dacacSDimitry Andric   DeclArg.QT = QT.getAsOpaquePtr();
1777a6dacacSDimitry Andric   DeclArg.D = D;
1787a6dacacSDimitry Andric }
1797a6dacacSDimitry Andric 
1807a6dacacSDimitry Andric void TemplateArgument::initFromIntegral(const ASTContext &Ctx,
1817a6dacacSDimitry Andric                                         const llvm::APSInt &Value,
18206c3fb27SDimitry Andric                                         QualType Type, bool IsDefaulted) {
1830b57cec5SDimitry Andric   Integer.Kind = Integral;
18406c3fb27SDimitry Andric   Integer.IsDefaulted = IsDefaulted;
1850b57cec5SDimitry Andric   // Copy the APSInt value into our decomposed form.
1860b57cec5SDimitry Andric   Integer.BitWidth = Value.getBitWidth();
1870b57cec5SDimitry Andric   Integer.IsUnsigned = Value.isUnsigned();
1880b57cec5SDimitry Andric   // If the value is large, we have to get additional memory from the ASTContext
1890b57cec5SDimitry Andric   unsigned NumWords = Value.getNumWords();
1900b57cec5SDimitry Andric   if (NumWords > 1) {
1910b57cec5SDimitry Andric     void *Mem = Ctx.Allocate(NumWords * sizeof(uint64_t));
1920b57cec5SDimitry Andric     std::memcpy(Mem, Value.getRawData(), NumWords * sizeof(uint64_t));
1930b57cec5SDimitry Andric     Integer.pVal = static_cast<uint64_t *>(Mem);
1940b57cec5SDimitry Andric   } else {
1950b57cec5SDimitry Andric     Integer.VAL = Value.getZExtValue();
1960b57cec5SDimitry Andric   }
1970b57cec5SDimitry Andric 
1980b57cec5SDimitry Andric   Integer.Type = Type.getAsOpaquePtr();
1990b57cec5SDimitry Andric }
2000b57cec5SDimitry Andric 
2017a6dacacSDimitry Andric void TemplateArgument::initFromStructural(const ASTContext &Ctx, QualType Type,
2027a6dacacSDimitry Andric                                           const APValue &V, bool IsDefaulted) {
2037a6dacacSDimitry Andric   Value.Kind = StructuralValue;
2047a6dacacSDimitry Andric   Value.IsDefaulted = IsDefaulted;
2057a6dacacSDimitry Andric   Value.Value = new (Ctx) APValue(V);
2067a6dacacSDimitry Andric   Ctx.addDestruction(Value.Value);
2077a6dacacSDimitry Andric   Value.Type = Type.getAsOpaquePtr();
2087a6dacacSDimitry Andric }
2097a6dacacSDimitry Andric 
2107a6dacacSDimitry Andric TemplateArgument::TemplateArgument(const ASTContext &Ctx,
2117a6dacacSDimitry Andric                                    const llvm::APSInt &Value, QualType Type,
2127a6dacacSDimitry Andric                                    bool IsDefaulted) {
2137a6dacacSDimitry Andric   initFromIntegral(Ctx, Value, Type, IsDefaulted);
2147a6dacacSDimitry Andric }
2157a6dacacSDimitry Andric 
2167a6dacacSDimitry Andric static const ValueDecl *getAsSimpleValueDeclRef(const ASTContext &Ctx,
2177a6dacacSDimitry Andric                                                 QualType T, const APValue &V) {
2187a6dacacSDimitry Andric   // Pointers to members are relatively easy.
2197a6dacacSDimitry Andric   if (V.isMemberPointer() && V.getMemberPointerPath().empty())
2207a6dacacSDimitry Andric     return V.getMemberPointerDecl();
2217a6dacacSDimitry Andric 
2227a6dacacSDimitry Andric   // We model class non-type template parameters as their template parameter
2237a6dacacSDimitry Andric   // object declaration.
224*0fca6ea1SDimitry Andric   if (V.isStruct() || V.isUnion()) {
225*0fca6ea1SDimitry Andric     // Dependent types are not supposed to be described as
226*0fca6ea1SDimitry Andric     // TemplateParamObjectDecls.
227*0fca6ea1SDimitry Andric     if (T->isDependentType() || T->isInstantiationDependentType())
228*0fca6ea1SDimitry Andric       return nullptr;
2297a6dacacSDimitry Andric     return Ctx.getTemplateParamObjectDecl(T, V);
230*0fca6ea1SDimitry Andric   }
2317a6dacacSDimitry Andric 
2327a6dacacSDimitry Andric   // Pointers and references with an empty path use the special 'Declaration'
2337a6dacacSDimitry Andric   // representation.
2347a6dacacSDimitry Andric   if (V.isLValue() && V.hasLValuePath() && V.getLValuePath().empty() &&
2357a6dacacSDimitry Andric       !V.isLValueOnePastTheEnd())
2367a6dacacSDimitry Andric     return V.getLValueBase().dyn_cast<const ValueDecl *>();
2377a6dacacSDimitry Andric 
2387a6dacacSDimitry Andric   // Everything else uses the 'structural' representation.
2397a6dacacSDimitry Andric   return nullptr;
2407a6dacacSDimitry Andric }
2417a6dacacSDimitry Andric 
2427a6dacacSDimitry Andric TemplateArgument::TemplateArgument(const ASTContext &Ctx, QualType Type,
2437a6dacacSDimitry Andric                                    const APValue &V, bool IsDefaulted) {
2447a6dacacSDimitry Andric   if (Type->isIntegralOrEnumerationType() && V.isInt())
2457a6dacacSDimitry Andric     initFromIntegral(Ctx, V.getInt(), Type, IsDefaulted);
2467a6dacacSDimitry Andric   else if ((V.isLValue() && V.isNullPointer()) ||
2477a6dacacSDimitry Andric            (V.isMemberPointer() && !V.getMemberPointerDecl()))
2487a6dacacSDimitry Andric     initFromType(Type, /*isNullPtr=*/true, IsDefaulted);
2497a6dacacSDimitry Andric   else if (const ValueDecl *VD = getAsSimpleValueDeclRef(Ctx, Type, V))
2507a6dacacSDimitry Andric     // FIXME: The Declaration form should expose a const ValueDecl*.
2517a6dacacSDimitry Andric     initFromDeclaration(const_cast<ValueDecl *>(VD), Type, IsDefaulted);
2527a6dacacSDimitry Andric   else
2537a6dacacSDimitry Andric     initFromStructural(Ctx, Type, V, IsDefaulted);
2547a6dacacSDimitry Andric }
2557a6dacacSDimitry Andric 
2560b57cec5SDimitry Andric TemplateArgument
2570b57cec5SDimitry Andric TemplateArgument::CreatePackCopy(ASTContext &Context,
2580b57cec5SDimitry Andric                                  ArrayRef<TemplateArgument> Args) {
2590b57cec5SDimitry Andric   if (Args.empty())
2600b57cec5SDimitry Andric     return getEmptyPack();
2610b57cec5SDimitry Andric 
2620b57cec5SDimitry Andric   return TemplateArgument(Args.copy(Context));
2630b57cec5SDimitry Andric }
2640b57cec5SDimitry Andric 
2655ffd83dbSDimitry Andric TemplateArgumentDependence TemplateArgument::getDependence() const {
2665ffd83dbSDimitry Andric   auto Deps = TemplateArgumentDependence::None;
2670b57cec5SDimitry Andric   switch (getKind()) {
2680b57cec5SDimitry Andric   case Null:
2690b57cec5SDimitry Andric     llvm_unreachable("Should not have a NULL template argument");
2700b57cec5SDimitry Andric 
2710b57cec5SDimitry Andric   case Type:
2725ffd83dbSDimitry Andric     Deps = toTemplateArgumentDependence(getAsType()->getDependence());
2735ffd83dbSDimitry Andric     if (isa<PackExpansionType>(getAsType()))
2745ffd83dbSDimitry Andric       Deps |= TemplateArgumentDependence::Dependent;
2755ffd83dbSDimitry Andric     return Deps;
2760b57cec5SDimitry Andric 
2770b57cec5SDimitry Andric   case Template:
2785ffd83dbSDimitry Andric     return toTemplateArgumentDependence(getAsTemplate().getDependence());
2790b57cec5SDimitry Andric 
2800b57cec5SDimitry Andric   case TemplateExpansion:
2815ffd83dbSDimitry Andric     return TemplateArgumentDependence::Dependent |
2825ffd83dbSDimitry Andric            TemplateArgumentDependence::Instantiation;
2830b57cec5SDimitry Andric 
2845ffd83dbSDimitry Andric   case Declaration: {
2855ffd83dbSDimitry Andric     auto *DC = dyn_cast<DeclContext>(getAsDecl());
2865ffd83dbSDimitry Andric     if (!DC)
2875ffd83dbSDimitry Andric       DC = getAsDecl()->getDeclContext();
2885ffd83dbSDimitry Andric     if (DC->isDependentContext())
2895ffd83dbSDimitry Andric       Deps = TemplateArgumentDependence::Dependent |
2905ffd83dbSDimitry Andric              TemplateArgumentDependence::Instantiation;
2915ffd83dbSDimitry Andric     return Deps;
2925ffd83dbSDimitry Andric   }
2930b57cec5SDimitry Andric 
2940b57cec5SDimitry Andric   case NullPtr:
2950b57cec5SDimitry Andric   case Integral:
2967a6dacacSDimitry Andric   case StructuralValue:
2975ffd83dbSDimitry Andric     return TemplateArgumentDependence::None;
2980b57cec5SDimitry Andric 
2990b57cec5SDimitry Andric   case Expression:
3005ffd83dbSDimitry Andric     Deps = toTemplateArgumentDependence(getAsExpr()->getDependence());
3015ffd83dbSDimitry Andric     if (isa<PackExpansionExpr>(getAsExpr()))
3025ffd83dbSDimitry Andric       Deps |= TemplateArgumentDependence::Dependent |
3035ffd83dbSDimitry Andric               TemplateArgumentDependence::Instantiation;
3045ffd83dbSDimitry Andric     return Deps;
3050b57cec5SDimitry Andric 
3060b57cec5SDimitry Andric   case Pack:
3070b57cec5SDimitry Andric     for (const auto &P : pack_elements())
3085ffd83dbSDimitry Andric       Deps |= P.getDependence();
3095ffd83dbSDimitry Andric     return Deps;
3105ffd83dbSDimitry Andric   }
3115ffd83dbSDimitry Andric   llvm_unreachable("unhandled ArgKind");
3120b57cec5SDimitry Andric }
3130b57cec5SDimitry Andric 
3145ffd83dbSDimitry Andric bool TemplateArgument::isDependent() const {
3155ffd83dbSDimitry Andric   return getDependence() & TemplateArgumentDependence::Dependent;
3160b57cec5SDimitry Andric }
3170b57cec5SDimitry Andric 
3180b57cec5SDimitry Andric bool TemplateArgument::isInstantiationDependent() const {
3195ffd83dbSDimitry Andric   return getDependence() & TemplateArgumentDependence::Instantiation;
3200b57cec5SDimitry Andric }
3210b57cec5SDimitry Andric 
3220b57cec5SDimitry Andric bool TemplateArgument::isPackExpansion() const {
3230b57cec5SDimitry Andric   switch (getKind()) {
3240b57cec5SDimitry Andric   case Null:
3250b57cec5SDimitry Andric   case Declaration:
3260b57cec5SDimitry Andric   case Integral:
3277a6dacacSDimitry Andric   case StructuralValue:
3280b57cec5SDimitry Andric   case Pack:
3290b57cec5SDimitry Andric   case Template:
3300b57cec5SDimitry Andric   case NullPtr:
3310b57cec5SDimitry Andric     return false;
3320b57cec5SDimitry Andric 
3330b57cec5SDimitry Andric   case TemplateExpansion:
3340b57cec5SDimitry Andric     return true;
3350b57cec5SDimitry Andric 
3360b57cec5SDimitry Andric   case Type:
3370b57cec5SDimitry Andric     return isa<PackExpansionType>(getAsType());
3380b57cec5SDimitry Andric 
3390b57cec5SDimitry Andric   case Expression:
3400b57cec5SDimitry Andric     return isa<PackExpansionExpr>(getAsExpr());
3410b57cec5SDimitry Andric   }
3420b57cec5SDimitry Andric 
3430b57cec5SDimitry Andric   llvm_unreachable("Invalid TemplateArgument Kind!");
3440b57cec5SDimitry Andric }
3450b57cec5SDimitry Andric 
3460b57cec5SDimitry Andric bool TemplateArgument::containsUnexpandedParameterPack() const {
3475ffd83dbSDimitry Andric   return getDependence() & TemplateArgumentDependence::UnexpandedPack;
3480b57cec5SDimitry Andric }
3490b57cec5SDimitry Andric 
350bdd1243dSDimitry Andric std::optional<unsigned> TemplateArgument::getNumTemplateExpansions() const {
3510b57cec5SDimitry Andric   assert(getKind() == TemplateExpansion);
3520b57cec5SDimitry Andric   if (TemplateArg.NumExpansions)
3530b57cec5SDimitry Andric     return TemplateArg.NumExpansions - 1;
3540b57cec5SDimitry Andric 
355bdd1243dSDimitry Andric   return std::nullopt;
3560b57cec5SDimitry Andric }
3570b57cec5SDimitry Andric 
3580b57cec5SDimitry Andric QualType TemplateArgument::getNonTypeTemplateArgumentType() const {
3590b57cec5SDimitry Andric   switch (getKind()) {
3600b57cec5SDimitry Andric   case TemplateArgument::Null:
3610b57cec5SDimitry Andric   case TemplateArgument::Type:
3620b57cec5SDimitry Andric   case TemplateArgument::Template:
3630b57cec5SDimitry Andric   case TemplateArgument::TemplateExpansion:
3640b57cec5SDimitry Andric   case TemplateArgument::Pack:
3650b57cec5SDimitry Andric     return QualType();
3660b57cec5SDimitry Andric 
3670b57cec5SDimitry Andric   case TemplateArgument::Integral:
3680b57cec5SDimitry Andric     return getIntegralType();
3690b57cec5SDimitry Andric 
3700b57cec5SDimitry Andric   case TemplateArgument::Expression:
3710b57cec5SDimitry Andric     return getAsExpr()->getType();
3720b57cec5SDimitry Andric 
3730b57cec5SDimitry Andric   case TemplateArgument::Declaration:
3740b57cec5SDimitry Andric     return getParamTypeForDecl();
3750b57cec5SDimitry Andric 
3760b57cec5SDimitry Andric   case TemplateArgument::NullPtr:
3770b57cec5SDimitry Andric     return getNullPtrType();
3787a6dacacSDimitry Andric 
3797a6dacacSDimitry Andric   case TemplateArgument::StructuralValue:
3807a6dacacSDimitry Andric     return getStructuralValueType();
3810b57cec5SDimitry Andric   }
3820b57cec5SDimitry Andric 
3830b57cec5SDimitry Andric   llvm_unreachable("Invalid TemplateArgument Kind!");
3840b57cec5SDimitry Andric }
3850b57cec5SDimitry Andric 
3860b57cec5SDimitry Andric void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID,
3870b57cec5SDimitry Andric                                const ASTContext &Context) const {
3880b57cec5SDimitry Andric   ID.AddInteger(getKind());
3890b57cec5SDimitry Andric   switch (getKind()) {
3900b57cec5SDimitry Andric   case Null:
3910b57cec5SDimitry Andric     break;
3920b57cec5SDimitry Andric 
3930b57cec5SDimitry Andric   case Type:
3940b57cec5SDimitry Andric     getAsType().Profile(ID);
3950b57cec5SDimitry Andric     break;
3960b57cec5SDimitry Andric 
3970b57cec5SDimitry Andric   case NullPtr:
3980b57cec5SDimitry Andric     getNullPtrType().Profile(ID);
3990b57cec5SDimitry Andric     break;
4000b57cec5SDimitry Andric 
4010b57cec5SDimitry Andric   case Declaration:
402e8d8bef9SDimitry Andric     getParamTypeForDecl().Profile(ID);
403bdd1243dSDimitry Andric     ID.AddPointer(getAsDecl());
4040b57cec5SDimitry Andric     break;
4050b57cec5SDimitry Andric 
406bdd1243dSDimitry Andric   case TemplateExpansion:
407bdd1243dSDimitry Andric     ID.AddInteger(TemplateArg.NumExpansions);
40806c3fb27SDimitry Andric     [[fallthrough]];
4090b57cec5SDimitry Andric   case Template:
41006c3fb27SDimitry Andric     ID.AddPointer(TemplateArg.Name);
4110b57cec5SDimitry Andric     break;
4120b57cec5SDimitry Andric 
4130b57cec5SDimitry Andric   case Integral:
4140b57cec5SDimitry Andric     getIntegralType().Profile(ID);
4157a6dacacSDimitry Andric     getAsIntegral().Profile(ID);
4167a6dacacSDimitry Andric     break;
4177a6dacacSDimitry Andric 
4187a6dacacSDimitry Andric   case StructuralValue:
4197a6dacacSDimitry Andric     getStructuralValueType().Profile(ID);
4207a6dacacSDimitry Andric     getAsStructuralValue().Profile(ID);
4210b57cec5SDimitry Andric     break;
4220b57cec5SDimitry Andric 
4230b57cec5SDimitry Andric   case Expression:
4240b57cec5SDimitry Andric     getAsExpr()->Profile(ID, Context, true);
4250b57cec5SDimitry Andric     break;
4260b57cec5SDimitry Andric 
4270b57cec5SDimitry Andric   case Pack:
4280b57cec5SDimitry Andric     ID.AddInteger(Args.NumArgs);
4290b57cec5SDimitry Andric     for (unsigned I = 0; I != Args.NumArgs; ++I)
4300b57cec5SDimitry Andric       Args.Args[I].Profile(ID, Context);
4310b57cec5SDimitry Andric   }
4320b57cec5SDimitry Andric }
4330b57cec5SDimitry Andric 
4340b57cec5SDimitry Andric bool TemplateArgument::structurallyEquals(const TemplateArgument &Other) const {
4350b57cec5SDimitry Andric   if (getKind() != Other.getKind()) return false;
4360b57cec5SDimitry Andric 
4370b57cec5SDimitry Andric   switch (getKind()) {
4380b57cec5SDimitry Andric   case Null:
4390b57cec5SDimitry Andric   case Type:
4400b57cec5SDimitry Andric   case Expression:
4410b57cec5SDimitry Andric   case NullPtr:
4420b57cec5SDimitry Andric     return TypeOrValue.V == Other.TypeOrValue.V;
4430b57cec5SDimitry Andric 
444e8d8bef9SDimitry Andric   case Template:
445e8d8bef9SDimitry Andric   case TemplateExpansion:
446e8d8bef9SDimitry Andric     return TemplateArg.Name == Other.TemplateArg.Name &&
447e8d8bef9SDimitry Andric            TemplateArg.NumExpansions == Other.TemplateArg.NumExpansions;
448e8d8bef9SDimitry Andric 
4490b57cec5SDimitry Andric   case Declaration:
450bdd1243dSDimitry Andric     return getAsDecl() == Other.getAsDecl() &&
451bdd1243dSDimitry Andric            getParamTypeForDecl() == Other.getParamTypeForDecl();
4520b57cec5SDimitry Andric 
4530b57cec5SDimitry Andric   case Integral:
4540b57cec5SDimitry Andric     return getIntegralType() == Other.getIntegralType() &&
4550b57cec5SDimitry Andric            getAsIntegral() == Other.getAsIntegral();
4560b57cec5SDimitry Andric 
4577a6dacacSDimitry Andric   case StructuralValue: {
458b3edf446SDimitry Andric     if (getStructuralValueType().getCanonicalType() !=
459b3edf446SDimitry Andric         Other.getStructuralValueType().getCanonicalType())
4607a6dacacSDimitry Andric       return false;
4617a6dacacSDimitry Andric 
4627a6dacacSDimitry Andric     llvm::FoldingSetNodeID A, B;
4637a6dacacSDimitry Andric     getAsStructuralValue().Profile(A);
4647a6dacacSDimitry Andric     Other.getAsStructuralValue().Profile(B);
4657a6dacacSDimitry Andric     return A == B;
4667a6dacacSDimitry Andric   }
4677a6dacacSDimitry Andric 
4680b57cec5SDimitry Andric   case Pack:
4690b57cec5SDimitry Andric     if (Args.NumArgs != Other.Args.NumArgs) return false;
4700b57cec5SDimitry Andric     for (unsigned I = 0, E = Args.NumArgs; I != E; ++I)
4710b57cec5SDimitry Andric       if (!Args.Args[I].structurallyEquals(Other.Args.Args[I]))
4720b57cec5SDimitry Andric         return false;
4730b57cec5SDimitry Andric     return true;
4740b57cec5SDimitry Andric   }
4750b57cec5SDimitry Andric 
4760b57cec5SDimitry Andric   llvm_unreachable("Invalid TemplateArgument Kind!");
4770b57cec5SDimitry Andric }
4780b57cec5SDimitry Andric 
4790b57cec5SDimitry Andric TemplateArgument TemplateArgument::getPackExpansionPattern() const {
4800b57cec5SDimitry Andric   assert(isPackExpansion());
4810b57cec5SDimitry Andric 
4820b57cec5SDimitry Andric   switch (getKind()) {
4830b57cec5SDimitry Andric   case Type:
484a7dea167SDimitry Andric     return getAsType()->castAs<PackExpansionType>()->getPattern();
4850b57cec5SDimitry Andric 
4860b57cec5SDimitry Andric   case Expression:
4870b57cec5SDimitry Andric     return cast<PackExpansionExpr>(getAsExpr())->getPattern();
4880b57cec5SDimitry Andric 
4890b57cec5SDimitry Andric   case TemplateExpansion:
4900b57cec5SDimitry Andric     return TemplateArgument(getAsTemplateOrTemplatePattern());
4910b57cec5SDimitry Andric 
4920b57cec5SDimitry Andric   case Declaration:
4930b57cec5SDimitry Andric   case Integral:
4947a6dacacSDimitry Andric   case StructuralValue:
4950b57cec5SDimitry Andric   case Pack:
4960b57cec5SDimitry Andric   case Null:
4970b57cec5SDimitry Andric   case Template:
4980b57cec5SDimitry Andric   case NullPtr:
4990b57cec5SDimitry Andric     return TemplateArgument();
5000b57cec5SDimitry Andric   }
5010b57cec5SDimitry Andric 
5020b57cec5SDimitry Andric   llvm_unreachable("Invalid TemplateArgument Kind!");
5030b57cec5SDimitry Andric }
5040b57cec5SDimitry Andric 
505fe6060f1SDimitry Andric void TemplateArgument::print(const PrintingPolicy &Policy, raw_ostream &Out,
506fe6060f1SDimitry Andric                              bool IncludeType) const {
507fe6060f1SDimitry Andric 
5080b57cec5SDimitry Andric   switch (getKind()) {
5090b57cec5SDimitry Andric   case Null:
5100b57cec5SDimitry Andric     Out << "(no value)";
5110b57cec5SDimitry Andric     break;
5120b57cec5SDimitry Andric 
5130b57cec5SDimitry Andric   case Type: {
5140b57cec5SDimitry Andric     PrintingPolicy SubPolicy(Policy);
5150b57cec5SDimitry Andric     SubPolicy.SuppressStrongLifetime = true;
5160b57cec5SDimitry Andric     getAsType().print(Out, SubPolicy);
5170b57cec5SDimitry Andric     break;
5180b57cec5SDimitry Andric   }
5190b57cec5SDimitry Andric 
5200b57cec5SDimitry Andric   case Declaration: {
5210b57cec5SDimitry Andric     NamedDecl *ND = getAsDecl();
522e8d8bef9SDimitry Andric     if (getParamTypeForDecl()->isRecordType()) {
523e8d8bef9SDimitry Andric       if (auto *TPO = dyn_cast<TemplateParamObjectDecl>(ND)) {
524bdd1243dSDimitry Andric         TPO->getType().getUnqualifiedType().print(Out, Policy);
52581ad6265SDimitry Andric         TPO->printAsInit(Out, Policy);
526e8d8bef9SDimitry Andric         break;
527e8d8bef9SDimitry Andric       }
528e8d8bef9SDimitry Andric     }
529fe6060f1SDimitry Andric     if (auto *VD = dyn_cast<ValueDecl>(ND)) {
530fe6060f1SDimitry Andric       if (needsAmpersandOnTemplateArg(getParamTypeForDecl(), VD->getType()))
531fe6060f1SDimitry Andric         Out << "&";
532fe6060f1SDimitry Andric     }
5330b57cec5SDimitry Andric     ND->printQualifiedName(Out);
5340b57cec5SDimitry Andric     break;
5350b57cec5SDimitry Andric   }
5360b57cec5SDimitry Andric 
5377a6dacacSDimitry Andric   case StructuralValue:
5387a6dacacSDimitry Andric     getAsStructuralValue().printPretty(Out, Policy, getStructuralValueType());
5397a6dacacSDimitry Andric     break;
5407a6dacacSDimitry Andric 
5410b57cec5SDimitry Andric   case NullPtr:
542fe6060f1SDimitry Andric     // FIXME: Include the type if it's not obvious from the context.
5430b57cec5SDimitry Andric     Out << "nullptr";
5440b57cec5SDimitry Andric     break;
5450b57cec5SDimitry Andric 
546*0fca6ea1SDimitry Andric   case Template: {
547*0fca6ea1SDimitry Andric     getAsTemplate().print(Out, Policy);
5480b57cec5SDimitry Andric     break;
549*0fca6ea1SDimitry Andric   }
5500b57cec5SDimitry Andric 
5510b57cec5SDimitry Andric   case TemplateExpansion:
5520b57cec5SDimitry Andric     getAsTemplateOrTemplatePattern().print(Out, Policy);
5530b57cec5SDimitry Andric     Out << "...";
5540b57cec5SDimitry Andric     break;
5550b57cec5SDimitry Andric 
5560b57cec5SDimitry Andric   case Integral:
557fe6060f1SDimitry Andric     printIntegral(*this, Out, Policy, IncludeType);
5580b57cec5SDimitry Andric     break;
5590b57cec5SDimitry Andric 
5600b57cec5SDimitry Andric   case Expression:
5610b57cec5SDimitry Andric     getAsExpr()->printPretty(Out, nullptr, Policy);
5620b57cec5SDimitry Andric     break;
5630b57cec5SDimitry Andric 
5640b57cec5SDimitry Andric   case Pack:
5650b57cec5SDimitry Andric     Out << "<";
5660b57cec5SDimitry Andric     bool First = true;
5670b57cec5SDimitry Andric     for (const auto &P : pack_elements()) {
5680b57cec5SDimitry Andric       if (First)
5690b57cec5SDimitry Andric         First = false;
5700b57cec5SDimitry Andric       else
5710b57cec5SDimitry Andric         Out << ", ";
5720b57cec5SDimitry Andric 
573fe6060f1SDimitry Andric       P.print(Policy, Out, IncludeType);
5740b57cec5SDimitry Andric     }
5750b57cec5SDimitry Andric     Out << ">";
5760b57cec5SDimitry Andric     break;
5770b57cec5SDimitry Andric   }
5780b57cec5SDimitry Andric }
5790b57cec5SDimitry Andric 
5800b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
5810b57cec5SDimitry Andric // TemplateArgumentLoc Implementation
5820b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
5830b57cec5SDimitry Andric 
5840b57cec5SDimitry Andric SourceRange TemplateArgumentLoc::getSourceRange() const {
5850b57cec5SDimitry Andric   switch (Argument.getKind()) {
5860b57cec5SDimitry Andric   case TemplateArgument::Expression:
5870b57cec5SDimitry Andric     return getSourceExpression()->getSourceRange();
5880b57cec5SDimitry Andric 
5890b57cec5SDimitry Andric   case TemplateArgument::Declaration:
5900b57cec5SDimitry Andric     return getSourceDeclExpression()->getSourceRange();
5910b57cec5SDimitry Andric 
5920b57cec5SDimitry Andric   case TemplateArgument::NullPtr:
5930b57cec5SDimitry Andric     return getSourceNullPtrExpression()->getSourceRange();
5940b57cec5SDimitry Andric 
5950b57cec5SDimitry Andric   case TemplateArgument::Type:
5960b57cec5SDimitry Andric     if (TypeSourceInfo *TSI = getTypeSourceInfo())
5970b57cec5SDimitry Andric       return TSI->getTypeLoc().getSourceRange();
5980b57cec5SDimitry Andric     else
5990b57cec5SDimitry Andric       return SourceRange();
6000b57cec5SDimitry Andric 
6010b57cec5SDimitry Andric   case TemplateArgument::Template:
6020b57cec5SDimitry Andric     if (getTemplateQualifierLoc())
6030b57cec5SDimitry Andric       return SourceRange(getTemplateQualifierLoc().getBeginLoc(),
6040b57cec5SDimitry Andric                          getTemplateNameLoc());
6050b57cec5SDimitry Andric     return SourceRange(getTemplateNameLoc());
6060b57cec5SDimitry Andric 
6070b57cec5SDimitry Andric   case TemplateArgument::TemplateExpansion:
6080b57cec5SDimitry Andric     if (getTemplateQualifierLoc())
6090b57cec5SDimitry Andric       return SourceRange(getTemplateQualifierLoc().getBeginLoc(),
6100b57cec5SDimitry Andric                          getTemplateEllipsisLoc());
6110b57cec5SDimitry Andric     return SourceRange(getTemplateNameLoc(), getTemplateEllipsisLoc());
6120b57cec5SDimitry Andric 
6130b57cec5SDimitry Andric   case TemplateArgument::Integral:
6140b57cec5SDimitry Andric     return getSourceIntegralExpression()->getSourceRange();
6150b57cec5SDimitry Andric 
6167a6dacacSDimitry Andric   case TemplateArgument::StructuralValue:
6177a6dacacSDimitry Andric     return getSourceStructuralValueExpression()->getSourceRange();
6187a6dacacSDimitry Andric 
6190b57cec5SDimitry Andric   case TemplateArgument::Pack:
6200b57cec5SDimitry Andric   case TemplateArgument::Null:
6210b57cec5SDimitry Andric     return SourceRange();
6220b57cec5SDimitry Andric   }
6230b57cec5SDimitry Andric 
6240b57cec5SDimitry Andric   llvm_unreachable("Invalid TemplateArgument Kind!");
6250b57cec5SDimitry Andric }
6260b57cec5SDimitry Andric 
627e8d8bef9SDimitry Andric template <typename T>
628e8d8bef9SDimitry Andric static const T &DiagTemplateArg(const T &DB, const TemplateArgument &Arg) {
6290b57cec5SDimitry Andric   switch (Arg.getKind()) {
6300b57cec5SDimitry Andric   case TemplateArgument::Null:
6310b57cec5SDimitry Andric     // This is bad, but not as bad as crashing because of argument
6320b57cec5SDimitry Andric     // count mismatches.
6330b57cec5SDimitry Andric     return DB << "(null template argument)";
6340b57cec5SDimitry Andric 
6350b57cec5SDimitry Andric   case TemplateArgument::Type:
6360b57cec5SDimitry Andric     return DB << Arg.getAsType();
6370b57cec5SDimitry Andric 
6380b57cec5SDimitry Andric   case TemplateArgument::Declaration:
6390b57cec5SDimitry Andric     return DB << Arg.getAsDecl();
6400b57cec5SDimitry Andric 
6410b57cec5SDimitry Andric   case TemplateArgument::NullPtr:
6420b57cec5SDimitry Andric     return DB << "nullptr";
6430b57cec5SDimitry Andric 
6440b57cec5SDimitry Andric   case TemplateArgument::Integral:
645fe6060f1SDimitry Andric     return DB << toString(Arg.getAsIntegral(), 10);
6460b57cec5SDimitry Andric 
6477a6dacacSDimitry Andric   case TemplateArgument::StructuralValue: {
6487a6dacacSDimitry Andric     // FIXME: We're guessing at LangOptions!
6497a6dacacSDimitry Andric     SmallString<32> Str;
6507a6dacacSDimitry Andric     llvm::raw_svector_ostream OS(Str);
6517a6dacacSDimitry Andric     LangOptions LangOpts;
6527a6dacacSDimitry Andric     LangOpts.CPlusPlus = true;
6537a6dacacSDimitry Andric     PrintingPolicy Policy(LangOpts);
6547a6dacacSDimitry Andric     Arg.getAsStructuralValue().printPretty(OS, Policy,
6557a6dacacSDimitry Andric                                            Arg.getStructuralValueType());
6567a6dacacSDimitry Andric     return DB << OS.str();
6577a6dacacSDimitry Andric   }
6587a6dacacSDimitry Andric 
6590b57cec5SDimitry Andric   case TemplateArgument::Template:
6600b57cec5SDimitry Andric     return DB << Arg.getAsTemplate();
6610b57cec5SDimitry Andric 
6620b57cec5SDimitry Andric   case TemplateArgument::TemplateExpansion:
6630b57cec5SDimitry Andric     return DB << Arg.getAsTemplateOrTemplatePattern() << "...";
6640b57cec5SDimitry Andric 
6650b57cec5SDimitry Andric   case TemplateArgument::Expression: {
6660b57cec5SDimitry Andric     // This shouldn't actually ever happen, so it's okay that we're
6670b57cec5SDimitry Andric     // regurgitating an expression here.
6680b57cec5SDimitry Andric     // FIXME: We're guessing at LangOptions!
6690b57cec5SDimitry Andric     SmallString<32> Str;
6700b57cec5SDimitry Andric     llvm::raw_svector_ostream OS(Str);
6710b57cec5SDimitry Andric     LangOptions LangOpts;
6720b57cec5SDimitry Andric     LangOpts.CPlusPlus = true;
6730b57cec5SDimitry Andric     PrintingPolicy Policy(LangOpts);
6740b57cec5SDimitry Andric     Arg.getAsExpr()->printPretty(OS, nullptr, Policy);
6750b57cec5SDimitry Andric     return DB << OS.str();
6760b57cec5SDimitry Andric   }
6770b57cec5SDimitry Andric 
6780b57cec5SDimitry Andric   case TemplateArgument::Pack: {
6790b57cec5SDimitry Andric     // FIXME: We're guessing at LangOptions!
6800b57cec5SDimitry Andric     SmallString<32> Str;
6810b57cec5SDimitry Andric     llvm::raw_svector_ostream OS(Str);
6820b57cec5SDimitry Andric     LangOptions LangOpts;
6830b57cec5SDimitry Andric     LangOpts.CPlusPlus = true;
6840b57cec5SDimitry Andric     PrintingPolicy Policy(LangOpts);
685fe6060f1SDimitry Andric     Arg.print(Policy, OS, /*IncludeType*/ true);
6860b57cec5SDimitry Andric     return DB << OS.str();
6870b57cec5SDimitry Andric   }
6880b57cec5SDimitry Andric   }
6890b57cec5SDimitry Andric 
6900b57cec5SDimitry Andric   llvm_unreachable("Invalid TemplateArgument Kind!");
6910b57cec5SDimitry Andric }
6920b57cec5SDimitry Andric 
693e8d8bef9SDimitry Andric const StreamingDiagnostic &clang::operator<<(const StreamingDiagnostic &DB,
694e8d8bef9SDimitry Andric                                              const TemplateArgument &Arg) {
695e8d8bef9SDimitry Andric   return DiagTemplateArg(DB, Arg);
696e8d8bef9SDimitry Andric }
697e8d8bef9SDimitry Andric 
698e8d8bef9SDimitry Andric clang::TemplateArgumentLocInfo::TemplateArgumentLocInfo(
699e8d8bef9SDimitry Andric     ASTContext &Ctx, NestedNameSpecifierLoc QualifierLoc,
700e8d8bef9SDimitry Andric     SourceLocation TemplateNameLoc, SourceLocation EllipsisLoc) {
701e8d8bef9SDimitry Andric   TemplateTemplateArgLocInfo *Template = new (Ctx) TemplateTemplateArgLocInfo;
702e8d8bef9SDimitry Andric   Template->Qualifier = QualifierLoc.getNestedNameSpecifier();
703e8d8bef9SDimitry Andric   Template->QualifierLocData = QualifierLoc.getOpaqueData();
704e8d8bef9SDimitry Andric   Template->TemplateNameLoc = TemplateNameLoc;
705e8d8bef9SDimitry Andric   Template->EllipsisLoc = EllipsisLoc;
706e8d8bef9SDimitry Andric   Pointer = Template;
707e8d8bef9SDimitry Andric }
708e8d8bef9SDimitry Andric 
7090b57cec5SDimitry Andric const ASTTemplateArgumentListInfo *
71055e4f9d5SDimitry Andric ASTTemplateArgumentListInfo::Create(const ASTContext &C,
7110b57cec5SDimitry Andric                                     const TemplateArgumentListInfo &List) {
7120b57cec5SDimitry Andric   std::size_t size = totalSizeToAlloc<TemplateArgumentLoc>(List.size());
7130b57cec5SDimitry Andric   void *Mem = C.Allocate(size, alignof(ASTTemplateArgumentListInfo));
7140b57cec5SDimitry Andric   return new (Mem) ASTTemplateArgumentListInfo(List);
7150b57cec5SDimitry Andric }
7160b57cec5SDimitry Andric 
71781ad6265SDimitry Andric const ASTTemplateArgumentListInfo *
71881ad6265SDimitry Andric ASTTemplateArgumentListInfo::Create(const ASTContext &C,
71981ad6265SDimitry Andric                                     const ASTTemplateArgumentListInfo *List) {
72081ad6265SDimitry Andric   if (!List)
72181ad6265SDimitry Andric     return nullptr;
72281ad6265SDimitry Andric   std::size_t size =
72381ad6265SDimitry Andric       totalSizeToAlloc<TemplateArgumentLoc>(List->getNumTemplateArgs());
72481ad6265SDimitry Andric   void *Mem = C.Allocate(size, alignof(ASTTemplateArgumentListInfo));
72581ad6265SDimitry Andric   return new (Mem) ASTTemplateArgumentListInfo(List);
72681ad6265SDimitry Andric }
72781ad6265SDimitry Andric 
7280b57cec5SDimitry Andric ASTTemplateArgumentListInfo::ASTTemplateArgumentListInfo(
7290b57cec5SDimitry Andric     const TemplateArgumentListInfo &Info) {
7300b57cec5SDimitry Andric   LAngleLoc = Info.getLAngleLoc();
7310b57cec5SDimitry Andric   RAngleLoc = Info.getRAngleLoc();
7320b57cec5SDimitry Andric   NumTemplateArgs = Info.size();
7330b57cec5SDimitry Andric 
7340b57cec5SDimitry Andric   TemplateArgumentLoc *ArgBuffer = getTrailingObjects<TemplateArgumentLoc>();
7350b57cec5SDimitry Andric   for (unsigned i = 0; i != NumTemplateArgs; ++i)
7360b57cec5SDimitry Andric     new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]);
7370b57cec5SDimitry Andric }
7380b57cec5SDimitry Andric 
73981ad6265SDimitry Andric ASTTemplateArgumentListInfo::ASTTemplateArgumentListInfo(
74081ad6265SDimitry Andric     const ASTTemplateArgumentListInfo *Info) {
74181ad6265SDimitry Andric   LAngleLoc = Info->getLAngleLoc();
74281ad6265SDimitry Andric   RAngleLoc = Info->getRAngleLoc();
74381ad6265SDimitry Andric   NumTemplateArgs = Info->getNumTemplateArgs();
74481ad6265SDimitry Andric 
74581ad6265SDimitry Andric   TemplateArgumentLoc *ArgBuffer = getTrailingObjects<TemplateArgumentLoc>();
74681ad6265SDimitry Andric   for (unsigned i = 0; i != NumTemplateArgs; ++i)
74781ad6265SDimitry Andric     new (&ArgBuffer[i]) TemplateArgumentLoc((*Info)[i]);
74881ad6265SDimitry Andric }
74981ad6265SDimitry Andric 
7500b57cec5SDimitry Andric void ASTTemplateKWAndArgsInfo::initializeFrom(
7510b57cec5SDimitry Andric     SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info,
7520b57cec5SDimitry Andric     TemplateArgumentLoc *OutArgArray) {
7530b57cec5SDimitry Andric   this->TemplateKWLoc = TemplateKWLoc;
7540b57cec5SDimitry Andric   LAngleLoc = Info.getLAngleLoc();
7550b57cec5SDimitry Andric   RAngleLoc = Info.getRAngleLoc();
7560b57cec5SDimitry Andric   NumTemplateArgs = Info.size();
7570b57cec5SDimitry Andric 
7580b57cec5SDimitry Andric   for (unsigned i = 0; i != NumTemplateArgs; ++i)
7590b57cec5SDimitry Andric     new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]);
7600b57cec5SDimitry Andric }
7610b57cec5SDimitry Andric 
7620b57cec5SDimitry Andric void ASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation TemplateKWLoc) {
7630b57cec5SDimitry Andric   assert(TemplateKWLoc.isValid());
7640b57cec5SDimitry Andric   LAngleLoc = SourceLocation();
7650b57cec5SDimitry Andric   RAngleLoc = SourceLocation();
7660b57cec5SDimitry Andric   this->TemplateKWLoc = TemplateKWLoc;
7670b57cec5SDimitry Andric   NumTemplateArgs = 0;
7680b57cec5SDimitry Andric }
7690b57cec5SDimitry Andric 
7700b57cec5SDimitry Andric void ASTTemplateKWAndArgsInfo::initializeFrom(
7710b57cec5SDimitry Andric     SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info,
7725ffd83dbSDimitry Andric     TemplateArgumentLoc *OutArgArray, TemplateArgumentDependence &Deps) {
7730b57cec5SDimitry Andric   this->TemplateKWLoc = TemplateKWLoc;
7740b57cec5SDimitry Andric   LAngleLoc = Info.getLAngleLoc();
7750b57cec5SDimitry Andric   RAngleLoc = Info.getRAngleLoc();
7760b57cec5SDimitry Andric   NumTemplateArgs = Info.size();
7770b57cec5SDimitry Andric 
7780b57cec5SDimitry Andric   for (unsigned i = 0; i != NumTemplateArgs; ++i) {
7795ffd83dbSDimitry Andric     Deps |= Info[i].getArgument().getDependence();
7800b57cec5SDimitry Andric 
7810b57cec5SDimitry Andric     new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]);
7820b57cec5SDimitry Andric   }
7830b57cec5SDimitry Andric }
7840b57cec5SDimitry Andric 
7850b57cec5SDimitry Andric void ASTTemplateKWAndArgsInfo::copyInto(const TemplateArgumentLoc *ArgArray,
7860b57cec5SDimitry Andric                                         TemplateArgumentListInfo &Info) const {
7870b57cec5SDimitry Andric   Info.setLAngleLoc(LAngleLoc);
7880b57cec5SDimitry Andric   Info.setRAngleLoc(RAngleLoc);
7890b57cec5SDimitry Andric   for (unsigned I = 0; I != NumTemplateArgs; ++I)
7900b57cec5SDimitry Andric     Info.addArgument(ArgArray[I]);
7910b57cec5SDimitry Andric }
792