1 //===- TemplateBase.cpp - Common template AST class implementation --------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file implements common classes used throughout C++ template 10 // representations. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "clang/AST/TemplateBase.h" 15 #include "clang/AST/ASTContext.h" 16 #include "clang/AST/Decl.h" 17 #include "clang/AST/DeclBase.h" 18 #include "clang/AST/DeclTemplate.h" 19 #include "clang/AST/DependenceFlags.h" 20 #include "clang/AST/Expr.h" 21 #include "clang/AST/ExprCXX.h" 22 #include "clang/AST/PrettyPrinter.h" 23 #include "clang/AST/TemplateName.h" 24 #include "clang/AST/Type.h" 25 #include "clang/AST/TypeLoc.h" 26 #include "clang/Basic/Diagnostic.h" 27 #include "clang/Basic/LLVM.h" 28 #include "clang/Basic/LangOptions.h" 29 #include "clang/Basic/SourceLocation.h" 30 #include "llvm/ADT/APSInt.h" 31 #include "llvm/ADT/FoldingSet.h" 32 #include "llvm/ADT/SmallString.h" 33 #include "llvm/ADT/StringExtras.h" 34 #include "llvm/ADT/StringRef.h" 35 #include "llvm/Support/Casting.h" 36 #include "llvm/Support/Compiler.h" 37 #include "llvm/Support/ErrorHandling.h" 38 #include "llvm/Support/raw_ostream.h" 39 #include <cassert> 40 #include <cstddef> 41 #include <cstdint> 42 #include <cstring> 43 #include <optional> 44 45 using namespace clang; 46 47 /// Print a template integral argument value. 48 /// 49 /// \param TemplArg the TemplateArgument instance to print. 50 /// 51 /// \param Out the raw_ostream instance to use for printing. 52 /// 53 /// \param Policy the printing policy for EnumConstantDecl printing. 54 /// 55 /// \param IncludeType If set, ensure that the type of the expression printed 56 /// matches the type of the template argument. 57 static void printIntegral(const TemplateArgument &TemplArg, raw_ostream &Out, 58 const PrintingPolicy &Policy, bool IncludeType) { 59 const Type *T = TemplArg.getIntegralType().getTypePtr(); 60 const llvm::APSInt &Val = TemplArg.getAsIntegral(); 61 62 if (Policy.UseEnumerators) { 63 if (const EnumType *ET = T->getAs<EnumType>()) { 64 for (const EnumConstantDecl *ECD : ET->getDecl()->enumerators()) { 65 // In Sema::CheckTemplateArugment, enum template arguments value are 66 // extended to the size of the integer underlying the enum type. This 67 // may create a size difference between the enum value and template 68 // argument value, requiring isSameValue here instead of operator==. 69 if (llvm::APSInt::isSameValue(ECD->getInitVal(), Val)) { 70 ECD->printQualifiedName(Out, Policy); 71 return; 72 } 73 } 74 } 75 } 76 77 if (Policy.MSVCFormatting) 78 IncludeType = false; 79 80 if (T->isBooleanType()) { 81 if (!Policy.MSVCFormatting) 82 Out << (Val.getBoolValue() ? "true" : "false"); 83 else 84 Out << Val; 85 } else if (T->isCharType()) { 86 if (IncludeType) { 87 if (T->isSpecificBuiltinType(BuiltinType::SChar)) 88 Out << "(signed char)"; 89 else if (T->isSpecificBuiltinType(BuiltinType::UChar)) 90 Out << "(unsigned char)"; 91 } 92 CharacterLiteral::print(Val.getZExtValue(), CharacterLiteral::Ascii, Out); 93 } else if (T->isAnyCharacterType() && !Policy.MSVCFormatting) { 94 CharacterLiteral::CharacterKind Kind; 95 if (T->isWideCharType()) 96 Kind = CharacterLiteral::Wide; 97 else if (T->isChar8Type()) 98 Kind = CharacterLiteral::UTF8; 99 else if (T->isChar16Type()) 100 Kind = CharacterLiteral::UTF16; 101 else if (T->isChar32Type()) 102 Kind = CharacterLiteral::UTF32; 103 else 104 Kind = CharacterLiteral::Ascii; 105 CharacterLiteral::print(Val.getExtValue(), Kind, Out); 106 } else if (IncludeType) { 107 if (const auto *BT = T->getAs<BuiltinType>()) { 108 switch (BT->getKind()) { 109 case BuiltinType::ULongLong: 110 Out << Val << "ULL"; 111 break; 112 case BuiltinType::LongLong: 113 Out << Val << "LL"; 114 break; 115 case BuiltinType::ULong: 116 Out << Val << "UL"; 117 break; 118 case BuiltinType::Long: 119 Out << Val << "L"; 120 break; 121 case BuiltinType::UInt: 122 Out << Val << "U"; 123 break; 124 case BuiltinType::Int: 125 Out << Val; 126 break; 127 default: 128 Out << "(" << T->getCanonicalTypeInternal().getAsString(Policy) << ")" 129 << Val; 130 break; 131 } 132 } else 133 Out << "(" << T->getCanonicalTypeInternal().getAsString(Policy) << ")" 134 << Val; 135 } else 136 Out << Val; 137 } 138 139 static unsigned getArrayDepth(QualType type) { 140 unsigned count = 0; 141 while (const auto *arrayType = type->getAsArrayTypeUnsafe()) { 142 count++; 143 type = arrayType->getElementType(); 144 } 145 return count; 146 } 147 148 static bool needsAmpersandOnTemplateArg(QualType paramType, QualType argType) { 149 // Generally, if the parameter type is a pointer, we must be taking the 150 // address of something and need a &. However, if the argument is an array, 151 // this could be implicit via array-to-pointer decay. 152 if (!paramType->isPointerType()) 153 return paramType->isMemberPointerType(); 154 if (argType->isArrayType()) 155 return getArrayDepth(argType) == getArrayDepth(paramType->getPointeeType()); 156 return true; 157 } 158 159 //===----------------------------------------------------------------------===// 160 // TemplateArgument Implementation 161 //===----------------------------------------------------------------------===// 162 163 TemplateArgument::TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value, 164 QualType Type, bool IsDefaulted) { 165 Integer.Kind = Integral; 166 Integer.IsDefaulted = IsDefaulted; 167 // Copy the APSInt value into our decomposed form. 168 Integer.BitWidth = Value.getBitWidth(); 169 Integer.IsUnsigned = Value.isUnsigned(); 170 // If the value is large, we have to get additional memory from the ASTContext 171 unsigned NumWords = Value.getNumWords(); 172 if (NumWords > 1) { 173 void *Mem = Ctx.Allocate(NumWords * sizeof(uint64_t)); 174 std::memcpy(Mem, Value.getRawData(), NumWords * sizeof(uint64_t)); 175 Integer.pVal = static_cast<uint64_t *>(Mem); 176 } else { 177 Integer.VAL = Value.getZExtValue(); 178 } 179 180 Integer.Type = Type.getAsOpaquePtr(); 181 } 182 183 TemplateArgument 184 TemplateArgument::CreatePackCopy(ASTContext &Context, 185 ArrayRef<TemplateArgument> Args) { 186 if (Args.empty()) 187 return getEmptyPack(); 188 189 return TemplateArgument(Args.copy(Context)); 190 } 191 192 TemplateArgumentDependence TemplateArgument::getDependence() const { 193 auto Deps = TemplateArgumentDependence::None; 194 switch (getKind()) { 195 case Null: 196 llvm_unreachable("Should not have a NULL template argument"); 197 198 case Type: 199 Deps = toTemplateArgumentDependence(getAsType()->getDependence()); 200 if (isa<PackExpansionType>(getAsType())) 201 Deps |= TemplateArgumentDependence::Dependent; 202 return Deps; 203 204 case Template: 205 return toTemplateArgumentDependence(getAsTemplate().getDependence()); 206 207 case TemplateExpansion: 208 return TemplateArgumentDependence::Dependent | 209 TemplateArgumentDependence::Instantiation; 210 211 case Declaration: { 212 auto *DC = dyn_cast<DeclContext>(getAsDecl()); 213 if (!DC) 214 DC = getAsDecl()->getDeclContext(); 215 if (DC->isDependentContext()) 216 Deps = TemplateArgumentDependence::Dependent | 217 TemplateArgumentDependence::Instantiation; 218 return Deps; 219 } 220 221 case NullPtr: 222 case Integral: 223 return TemplateArgumentDependence::None; 224 225 case Expression: 226 Deps = toTemplateArgumentDependence(getAsExpr()->getDependence()); 227 if (isa<PackExpansionExpr>(getAsExpr())) 228 Deps |= TemplateArgumentDependence::Dependent | 229 TemplateArgumentDependence::Instantiation; 230 return Deps; 231 232 case Pack: 233 for (const auto &P : pack_elements()) 234 Deps |= P.getDependence(); 235 return Deps; 236 } 237 llvm_unreachable("unhandled ArgKind"); 238 } 239 240 bool TemplateArgument::isDependent() const { 241 return getDependence() & TemplateArgumentDependence::Dependent; 242 } 243 244 bool TemplateArgument::isInstantiationDependent() const { 245 return getDependence() & TemplateArgumentDependence::Instantiation; 246 } 247 248 bool TemplateArgument::isPackExpansion() const { 249 switch (getKind()) { 250 case Null: 251 case Declaration: 252 case Integral: 253 case Pack: 254 case Template: 255 case NullPtr: 256 return false; 257 258 case TemplateExpansion: 259 return true; 260 261 case Type: 262 return isa<PackExpansionType>(getAsType()); 263 264 case Expression: 265 return isa<PackExpansionExpr>(getAsExpr()); 266 } 267 268 llvm_unreachable("Invalid TemplateArgument Kind!"); 269 } 270 271 bool TemplateArgument::containsUnexpandedParameterPack() const { 272 return getDependence() & TemplateArgumentDependence::UnexpandedPack; 273 } 274 275 std::optional<unsigned> TemplateArgument::getNumTemplateExpansions() const { 276 assert(getKind() == TemplateExpansion); 277 if (TemplateArg.NumExpansions) 278 return TemplateArg.NumExpansions - 1; 279 280 return std::nullopt; 281 } 282 283 QualType TemplateArgument::getNonTypeTemplateArgumentType() const { 284 switch (getKind()) { 285 case TemplateArgument::Null: 286 case TemplateArgument::Type: 287 case TemplateArgument::Template: 288 case TemplateArgument::TemplateExpansion: 289 case TemplateArgument::Pack: 290 return QualType(); 291 292 case TemplateArgument::Integral: 293 return getIntegralType(); 294 295 case TemplateArgument::Expression: 296 return getAsExpr()->getType(); 297 298 case TemplateArgument::Declaration: 299 return getParamTypeForDecl(); 300 301 case TemplateArgument::NullPtr: 302 return getNullPtrType(); 303 } 304 305 llvm_unreachable("Invalid TemplateArgument Kind!"); 306 } 307 308 void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID, 309 const ASTContext &Context) const { 310 ID.AddInteger(getKind()); 311 switch (getKind()) { 312 case Null: 313 break; 314 315 case Type: 316 getAsType().Profile(ID); 317 break; 318 319 case NullPtr: 320 getNullPtrType().Profile(ID); 321 break; 322 323 case Declaration: 324 getParamTypeForDecl().Profile(ID); 325 ID.AddPointer(getAsDecl()); 326 break; 327 328 case TemplateExpansion: 329 ID.AddInteger(TemplateArg.NumExpansions); 330 [[fallthrough]]; 331 case Template: 332 ID.AddPointer(TemplateArg.Name); 333 break; 334 335 case Integral: 336 getAsIntegral().Profile(ID); 337 getIntegralType().Profile(ID); 338 break; 339 340 case Expression: 341 getAsExpr()->Profile(ID, Context, true); 342 break; 343 344 case Pack: 345 ID.AddInteger(Args.NumArgs); 346 for (unsigned I = 0; I != Args.NumArgs; ++I) 347 Args.Args[I].Profile(ID, Context); 348 } 349 } 350 351 bool TemplateArgument::structurallyEquals(const TemplateArgument &Other) const { 352 if (getKind() != Other.getKind()) return false; 353 354 switch (getKind()) { 355 case Null: 356 case Type: 357 case Expression: 358 case NullPtr: 359 return TypeOrValue.V == Other.TypeOrValue.V; 360 361 case Template: 362 case TemplateExpansion: 363 return TemplateArg.Name == Other.TemplateArg.Name && 364 TemplateArg.NumExpansions == Other.TemplateArg.NumExpansions; 365 366 case Declaration: 367 return getAsDecl() == Other.getAsDecl() && 368 getParamTypeForDecl() == Other.getParamTypeForDecl(); 369 370 case Integral: 371 return getIntegralType() == Other.getIntegralType() && 372 getAsIntegral() == Other.getAsIntegral(); 373 374 case Pack: 375 if (Args.NumArgs != Other.Args.NumArgs) return false; 376 for (unsigned I = 0, E = Args.NumArgs; I != E; ++I) 377 if (!Args.Args[I].structurallyEquals(Other.Args.Args[I])) 378 return false; 379 return true; 380 } 381 382 llvm_unreachable("Invalid TemplateArgument Kind!"); 383 } 384 385 TemplateArgument TemplateArgument::getPackExpansionPattern() const { 386 assert(isPackExpansion()); 387 388 switch (getKind()) { 389 case Type: 390 return getAsType()->castAs<PackExpansionType>()->getPattern(); 391 392 case Expression: 393 return cast<PackExpansionExpr>(getAsExpr())->getPattern(); 394 395 case TemplateExpansion: 396 return TemplateArgument(getAsTemplateOrTemplatePattern()); 397 398 case Declaration: 399 case Integral: 400 case Pack: 401 case Null: 402 case Template: 403 case NullPtr: 404 return TemplateArgument(); 405 } 406 407 llvm_unreachable("Invalid TemplateArgument Kind!"); 408 } 409 410 void TemplateArgument::print(const PrintingPolicy &Policy, raw_ostream &Out, 411 bool IncludeType) const { 412 413 switch (getKind()) { 414 case Null: 415 Out << "(no value)"; 416 break; 417 418 case Type: { 419 PrintingPolicy SubPolicy(Policy); 420 SubPolicy.SuppressStrongLifetime = true; 421 getAsType().print(Out, SubPolicy); 422 break; 423 } 424 425 case Declaration: { 426 NamedDecl *ND = getAsDecl(); 427 if (getParamTypeForDecl()->isRecordType()) { 428 if (auto *TPO = dyn_cast<TemplateParamObjectDecl>(ND)) { 429 TPO->getType().getUnqualifiedType().print(Out, Policy); 430 TPO->printAsInit(Out, Policy); 431 break; 432 } 433 } 434 if (auto *VD = dyn_cast<ValueDecl>(ND)) { 435 if (needsAmpersandOnTemplateArg(getParamTypeForDecl(), VD->getType())) 436 Out << "&"; 437 } 438 ND->printQualifiedName(Out); 439 break; 440 } 441 442 case NullPtr: 443 // FIXME: Include the type if it's not obvious from the context. 444 Out << "nullptr"; 445 break; 446 447 case Template: 448 getAsTemplate().print(Out, Policy, TemplateName::Qualified::Fully); 449 break; 450 451 case TemplateExpansion: 452 getAsTemplateOrTemplatePattern().print(Out, Policy); 453 Out << "..."; 454 break; 455 456 case Integral: 457 printIntegral(*this, Out, Policy, IncludeType); 458 break; 459 460 case Expression: 461 getAsExpr()->printPretty(Out, nullptr, Policy); 462 break; 463 464 case Pack: 465 Out << "<"; 466 bool First = true; 467 for (const auto &P : pack_elements()) { 468 if (First) 469 First = false; 470 else 471 Out << ", "; 472 473 P.print(Policy, Out, IncludeType); 474 } 475 Out << ">"; 476 break; 477 } 478 } 479 480 void TemplateArgument::dump(raw_ostream &Out) const { 481 LangOptions LO; // FIXME! see also TemplateName::dump(). 482 LO.CPlusPlus = true; 483 LO.Bool = true; 484 print(PrintingPolicy(LO), Out, /*IncludeType*/ true); 485 } 486 487 LLVM_DUMP_METHOD void TemplateArgument::dump() const { dump(llvm::errs()); } 488 489 //===----------------------------------------------------------------------===// 490 // TemplateArgumentLoc Implementation 491 //===----------------------------------------------------------------------===// 492 493 SourceRange TemplateArgumentLoc::getSourceRange() const { 494 switch (Argument.getKind()) { 495 case TemplateArgument::Expression: 496 return getSourceExpression()->getSourceRange(); 497 498 case TemplateArgument::Declaration: 499 return getSourceDeclExpression()->getSourceRange(); 500 501 case TemplateArgument::NullPtr: 502 return getSourceNullPtrExpression()->getSourceRange(); 503 504 case TemplateArgument::Type: 505 if (TypeSourceInfo *TSI = getTypeSourceInfo()) 506 return TSI->getTypeLoc().getSourceRange(); 507 else 508 return SourceRange(); 509 510 case TemplateArgument::Template: 511 if (getTemplateQualifierLoc()) 512 return SourceRange(getTemplateQualifierLoc().getBeginLoc(), 513 getTemplateNameLoc()); 514 return SourceRange(getTemplateNameLoc()); 515 516 case TemplateArgument::TemplateExpansion: 517 if (getTemplateQualifierLoc()) 518 return SourceRange(getTemplateQualifierLoc().getBeginLoc(), 519 getTemplateEllipsisLoc()); 520 return SourceRange(getTemplateNameLoc(), getTemplateEllipsisLoc()); 521 522 case TemplateArgument::Integral: 523 return getSourceIntegralExpression()->getSourceRange(); 524 525 case TemplateArgument::Pack: 526 case TemplateArgument::Null: 527 return SourceRange(); 528 } 529 530 llvm_unreachable("Invalid TemplateArgument Kind!"); 531 } 532 533 template <typename T> 534 static const T &DiagTemplateArg(const T &DB, const TemplateArgument &Arg) { 535 switch (Arg.getKind()) { 536 case TemplateArgument::Null: 537 // This is bad, but not as bad as crashing because of argument 538 // count mismatches. 539 return DB << "(null template argument)"; 540 541 case TemplateArgument::Type: 542 return DB << Arg.getAsType(); 543 544 case TemplateArgument::Declaration: 545 return DB << Arg.getAsDecl(); 546 547 case TemplateArgument::NullPtr: 548 return DB << "nullptr"; 549 550 case TemplateArgument::Integral: 551 return DB << toString(Arg.getAsIntegral(), 10); 552 553 case TemplateArgument::Template: 554 return DB << Arg.getAsTemplate(); 555 556 case TemplateArgument::TemplateExpansion: 557 return DB << Arg.getAsTemplateOrTemplatePattern() << "..."; 558 559 case TemplateArgument::Expression: { 560 // This shouldn't actually ever happen, so it's okay that we're 561 // regurgitating an expression here. 562 // FIXME: We're guessing at LangOptions! 563 SmallString<32> Str; 564 llvm::raw_svector_ostream OS(Str); 565 LangOptions LangOpts; 566 LangOpts.CPlusPlus = true; 567 PrintingPolicy Policy(LangOpts); 568 Arg.getAsExpr()->printPretty(OS, nullptr, Policy); 569 return DB << OS.str(); 570 } 571 572 case TemplateArgument::Pack: { 573 // FIXME: We're guessing at LangOptions! 574 SmallString<32> Str; 575 llvm::raw_svector_ostream OS(Str); 576 LangOptions LangOpts; 577 LangOpts.CPlusPlus = true; 578 PrintingPolicy Policy(LangOpts); 579 Arg.print(Policy, OS, /*IncludeType*/ true); 580 return DB << OS.str(); 581 } 582 } 583 584 llvm_unreachable("Invalid TemplateArgument Kind!"); 585 } 586 587 const StreamingDiagnostic &clang::operator<<(const StreamingDiagnostic &DB, 588 const TemplateArgument &Arg) { 589 return DiagTemplateArg(DB, Arg); 590 } 591 592 clang::TemplateArgumentLocInfo::TemplateArgumentLocInfo( 593 ASTContext &Ctx, NestedNameSpecifierLoc QualifierLoc, 594 SourceLocation TemplateNameLoc, SourceLocation EllipsisLoc) { 595 TemplateTemplateArgLocInfo *Template = new (Ctx) TemplateTemplateArgLocInfo; 596 Template->Qualifier = QualifierLoc.getNestedNameSpecifier(); 597 Template->QualifierLocData = QualifierLoc.getOpaqueData(); 598 Template->TemplateNameLoc = TemplateNameLoc; 599 Template->EllipsisLoc = EllipsisLoc; 600 Pointer = Template; 601 } 602 603 const ASTTemplateArgumentListInfo * 604 ASTTemplateArgumentListInfo::Create(const ASTContext &C, 605 const TemplateArgumentListInfo &List) { 606 std::size_t size = totalSizeToAlloc<TemplateArgumentLoc>(List.size()); 607 void *Mem = C.Allocate(size, alignof(ASTTemplateArgumentListInfo)); 608 return new (Mem) ASTTemplateArgumentListInfo(List); 609 } 610 611 const ASTTemplateArgumentListInfo * 612 ASTTemplateArgumentListInfo::Create(const ASTContext &C, 613 const ASTTemplateArgumentListInfo *List) { 614 if (!List) 615 return nullptr; 616 std::size_t size = 617 totalSizeToAlloc<TemplateArgumentLoc>(List->getNumTemplateArgs()); 618 void *Mem = C.Allocate(size, alignof(ASTTemplateArgumentListInfo)); 619 return new (Mem) ASTTemplateArgumentListInfo(List); 620 } 621 622 ASTTemplateArgumentListInfo::ASTTemplateArgumentListInfo( 623 const TemplateArgumentListInfo &Info) { 624 LAngleLoc = Info.getLAngleLoc(); 625 RAngleLoc = Info.getRAngleLoc(); 626 NumTemplateArgs = Info.size(); 627 628 TemplateArgumentLoc *ArgBuffer = getTrailingObjects<TemplateArgumentLoc>(); 629 for (unsigned i = 0; i != NumTemplateArgs; ++i) 630 new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]); 631 } 632 633 ASTTemplateArgumentListInfo::ASTTemplateArgumentListInfo( 634 const ASTTemplateArgumentListInfo *Info) { 635 LAngleLoc = Info->getLAngleLoc(); 636 RAngleLoc = Info->getRAngleLoc(); 637 NumTemplateArgs = Info->getNumTemplateArgs(); 638 639 TemplateArgumentLoc *ArgBuffer = getTrailingObjects<TemplateArgumentLoc>(); 640 for (unsigned i = 0; i != NumTemplateArgs; ++i) 641 new (&ArgBuffer[i]) TemplateArgumentLoc((*Info)[i]); 642 } 643 644 void ASTTemplateKWAndArgsInfo::initializeFrom( 645 SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info, 646 TemplateArgumentLoc *OutArgArray) { 647 this->TemplateKWLoc = TemplateKWLoc; 648 LAngleLoc = Info.getLAngleLoc(); 649 RAngleLoc = Info.getRAngleLoc(); 650 NumTemplateArgs = Info.size(); 651 652 for (unsigned i = 0; i != NumTemplateArgs; ++i) 653 new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]); 654 } 655 656 void ASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation TemplateKWLoc) { 657 assert(TemplateKWLoc.isValid()); 658 LAngleLoc = SourceLocation(); 659 RAngleLoc = SourceLocation(); 660 this->TemplateKWLoc = TemplateKWLoc; 661 NumTemplateArgs = 0; 662 } 663 664 void ASTTemplateKWAndArgsInfo::initializeFrom( 665 SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info, 666 TemplateArgumentLoc *OutArgArray, TemplateArgumentDependence &Deps) { 667 this->TemplateKWLoc = TemplateKWLoc; 668 LAngleLoc = Info.getLAngleLoc(); 669 RAngleLoc = Info.getRAngleLoc(); 670 NumTemplateArgs = Info.size(); 671 672 for (unsigned i = 0; i != NumTemplateArgs; ++i) { 673 Deps |= Info[i].getArgument().getDependence(); 674 675 new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]); 676 } 677 } 678 679 void ASTTemplateKWAndArgsInfo::copyInto(const TemplateArgumentLoc *ArgArray, 680 TemplateArgumentListInfo &Info) const { 681 Info.setLAngleLoc(LAngleLoc); 682 Info.setRAngleLoc(RAngleLoc); 683 for (unsigned I = 0; I != NumTemplateArgs; ++I) 684 Info.addArgument(ArgArray[I]); 685 } 686