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