1 //===--- ASTDiagnostic.cpp - Diagnostic Printing Hooks for AST Nodes ------===// 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 a diagnostic formatting hook for AST elements. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "clang/AST/ASTDiagnostic.h" 14 #include "clang/AST/ASTContext.h" 15 #include "clang/AST/ASTLambda.h" 16 #include "clang/AST/Attr.h" 17 #include "clang/AST/DeclObjC.h" 18 #include "clang/AST/DeclTemplate.h" 19 #include "clang/AST/ExprCXX.h" 20 #include "clang/AST/TemplateBase.h" 21 #include "clang/AST/Type.h" 22 #include "llvm/ADT/StringExtras.h" 23 #include "llvm/Support/raw_ostream.h" 24 25 using namespace clang; 26 27 // Returns a desugared version of the QualType, and marks ShouldAKA as true 28 // whenever we remove significant sugar from the type. Make sure ShouldAKA 29 // is initialized before passing it in. 30 QualType clang::desugarForDiagnostic(ASTContext &Context, QualType QT, 31 bool &ShouldAKA) { 32 QualifierCollector QC; 33 34 while (true) { 35 const Type *Ty = QC.strip(QT); 36 37 // Don't aka just because we saw an elaborated type... 38 if (const ElaboratedType *ET = dyn_cast<ElaboratedType>(Ty)) { 39 QT = ET->desugar(); 40 continue; 41 } 42 // ... or a using type ... 43 if (const UsingType *UT = dyn_cast<UsingType>(Ty)) { 44 QT = UT->desugar(); 45 continue; 46 } 47 // ... or a paren type ... 48 if (const ParenType *PT = dyn_cast<ParenType>(Ty)) { 49 QT = PT->desugar(); 50 continue; 51 } 52 // ... or a macro defined type ... 53 if (const MacroQualifiedType *MDT = dyn_cast<MacroQualifiedType>(Ty)) { 54 QT = MDT->desugar(); 55 continue; 56 } 57 // ...or a substituted template type parameter ... 58 if (const SubstTemplateTypeParmType *ST = 59 dyn_cast<SubstTemplateTypeParmType>(Ty)) { 60 QT = ST->desugar(); 61 continue; 62 } 63 // ...or an attributed type... 64 if (const AttributedType *AT = dyn_cast<AttributedType>(Ty)) { 65 QT = AT->desugar(); 66 continue; 67 } 68 // ...or an adjusted type... 69 if (const AdjustedType *AT = dyn_cast<AdjustedType>(Ty)) { 70 QT = AT->desugar(); 71 continue; 72 } 73 // ... or an auto type. 74 if (const AutoType *AT = dyn_cast<AutoType>(Ty)) { 75 if (!AT->isSugared()) 76 break; 77 QT = AT->desugar(); 78 continue; 79 } 80 81 // Desugar FunctionType if return type or any parameter type should be 82 // desugared. Preserve nullability attribute on desugared types. 83 if (const FunctionType *FT = dyn_cast<FunctionType>(Ty)) { 84 bool DesugarReturn = false; 85 QualType SugarRT = FT->getReturnType(); 86 QualType RT = desugarForDiagnostic(Context, SugarRT, DesugarReturn); 87 if (auto nullability = AttributedType::stripOuterNullability(SugarRT)) { 88 RT = Context.getAttributedType( 89 AttributedType::getNullabilityAttrKind(*nullability), RT, RT); 90 } 91 92 bool DesugarArgument = false; 93 SmallVector<QualType, 4> Args; 94 const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(FT); 95 if (FPT) { 96 for (QualType SugarPT : FPT->param_types()) { 97 QualType PT = desugarForDiagnostic(Context, SugarPT, DesugarArgument); 98 if (auto nullability = 99 AttributedType::stripOuterNullability(SugarPT)) { 100 PT = Context.getAttributedType( 101 AttributedType::getNullabilityAttrKind(*nullability), PT, PT); 102 } 103 Args.push_back(PT); 104 } 105 } 106 107 if (DesugarReturn || DesugarArgument) { 108 ShouldAKA = true; 109 QT = FPT ? Context.getFunctionType(RT, Args, FPT->getExtProtoInfo()) 110 : Context.getFunctionNoProtoType(RT, FT->getExtInfo()); 111 break; 112 } 113 } 114 115 // Desugar template specializations if any template argument should be 116 // desugared. 117 if (const TemplateSpecializationType *TST = 118 dyn_cast<TemplateSpecializationType>(Ty)) { 119 if (!TST->isTypeAlias()) { 120 bool DesugarArgument = false; 121 SmallVector<TemplateArgument, 4> Args; 122 for (const TemplateArgument &Arg : TST->template_arguments()) { 123 if (Arg.getKind() == TemplateArgument::Type) 124 Args.push_back(desugarForDiagnostic(Context, Arg.getAsType(), 125 DesugarArgument)); 126 else 127 Args.push_back(Arg); 128 } 129 130 if (DesugarArgument) { 131 ShouldAKA = true; 132 QT = Context.getTemplateSpecializationType( 133 TST->getTemplateName(), Args, QT); 134 } 135 break; 136 } 137 } 138 139 if (const auto *AT = dyn_cast<ArrayType>(Ty)) { 140 QualType ElementTy = 141 desugarForDiagnostic(Context, AT->getElementType(), ShouldAKA); 142 if (const auto *CAT = dyn_cast<ConstantArrayType>(AT)) 143 QT = Context.getConstantArrayType( 144 ElementTy, CAT->getSize(), CAT->getSizeExpr(), 145 CAT->getSizeModifier(), CAT->getIndexTypeCVRQualifiers()); 146 else if (const auto *VAT = dyn_cast<VariableArrayType>(AT)) 147 QT = Context.getVariableArrayType( 148 ElementTy, VAT->getSizeExpr(), VAT->getSizeModifier(), 149 VAT->getIndexTypeCVRQualifiers(), VAT->getBracketsRange()); 150 else if (const auto *DSAT = dyn_cast<DependentSizedArrayType>(AT)) 151 QT = Context.getDependentSizedArrayType( 152 ElementTy, DSAT->getSizeExpr(), DSAT->getSizeModifier(), 153 DSAT->getIndexTypeCVRQualifiers(), DSAT->getBracketsRange()); 154 else if (const auto *IAT = dyn_cast<IncompleteArrayType>(AT)) 155 QT = Context.getIncompleteArrayType(ElementTy, IAT->getSizeModifier(), 156 IAT->getIndexTypeCVRQualifiers()); 157 else 158 llvm_unreachable("Unhandled array type"); 159 break; 160 } 161 162 // Don't desugar magic Objective-C types. 163 if (QualType(Ty,0) == Context.getObjCIdType() || 164 QualType(Ty,0) == Context.getObjCClassType() || 165 QualType(Ty,0) == Context.getObjCSelType() || 166 QualType(Ty,0) == Context.getObjCProtoType()) 167 break; 168 169 // Don't desugar va_list. 170 if (QualType(Ty, 0) == Context.getBuiltinVaListType() || 171 QualType(Ty, 0) == Context.getBuiltinMSVaListType()) 172 break; 173 174 // Otherwise, do a single-step desugar. 175 QualType Underlying; 176 bool IsSugar = false; 177 switch (Ty->getTypeClass()) { 178 #define ABSTRACT_TYPE(Class, Base) 179 #define TYPE(Class, Base) \ 180 case Type::Class: { \ 181 const Class##Type *CTy = cast<Class##Type>(Ty); \ 182 if (CTy->isSugared()) { \ 183 IsSugar = true; \ 184 Underlying = CTy->desugar(); \ 185 } \ 186 break; \ 187 } 188 #include "clang/AST/TypeNodes.inc" 189 } 190 191 // If it wasn't sugared, we're done. 192 if (!IsSugar) 193 break; 194 195 // If the desugared type is a vector type, we don't want to expand 196 // it, it will turn into an attribute mess. People want their "vec4". 197 if (isa<VectorType>(Underlying)) 198 break; 199 200 // Don't desugar through the primary typedef of an anonymous type. 201 if (const TagType *UTT = Underlying->getAs<TagType>()) 202 if (const TypedefType *QTT = dyn_cast<TypedefType>(QT)) 203 if (UTT->getDecl()->getTypedefNameForAnonDecl() == QTT->getDecl()) 204 break; 205 206 // Record that we actually looked through an opaque type here. 207 ShouldAKA = true; 208 QT = Underlying; 209 } 210 211 // If we have a pointer-like type, desugar the pointee as well. 212 // FIXME: Handle other pointer-like types. 213 if (const PointerType *Ty = QT->getAs<PointerType>()) { 214 QT = Context.getPointerType( 215 desugarForDiagnostic(Context, Ty->getPointeeType(), ShouldAKA)); 216 } else if (const auto *Ty = QT->getAs<ObjCObjectPointerType>()) { 217 QT = Context.getObjCObjectPointerType( 218 desugarForDiagnostic(Context, Ty->getPointeeType(), ShouldAKA)); 219 } else if (const LValueReferenceType *Ty = QT->getAs<LValueReferenceType>()) { 220 QT = Context.getLValueReferenceType( 221 desugarForDiagnostic(Context, Ty->getPointeeType(), ShouldAKA)); 222 } else if (const RValueReferenceType *Ty = QT->getAs<RValueReferenceType>()) { 223 QT = Context.getRValueReferenceType( 224 desugarForDiagnostic(Context, Ty->getPointeeType(), ShouldAKA)); 225 } else if (const auto *Ty = QT->getAs<ObjCObjectType>()) { 226 if (Ty->getBaseType().getTypePtr() != Ty && !ShouldAKA) { 227 QualType BaseType = 228 desugarForDiagnostic(Context, Ty->getBaseType(), ShouldAKA); 229 QT = Context.getObjCObjectType( 230 BaseType, Ty->getTypeArgsAsWritten(), 231 llvm::ArrayRef(Ty->qual_begin(), Ty->getNumProtocols()), 232 Ty->isKindOfTypeAsWritten()); 233 } 234 } 235 236 return QC.apply(Context, QT); 237 } 238 239 /// Convert the given type to a string suitable for printing as part of 240 /// a diagnostic. 241 /// 242 /// There are four main criteria when determining whether we should have an 243 /// a.k.a. clause when pretty-printing a type: 244 /// 245 /// 1) Some types provide very minimal sugar that doesn't impede the 246 /// user's understanding --- for example, elaborated type 247 /// specifiers. If this is all the sugar we see, we don't want an 248 /// a.k.a. clause. 249 /// 2) Some types are technically sugared but are much more familiar 250 /// when seen in their sugared form --- for example, va_list, 251 /// vector types, and the magic Objective C types. We don't 252 /// want to desugar these, even if we do produce an a.k.a. clause. 253 /// 3) Some types may have already been desugared previously in this diagnostic. 254 /// if this is the case, doing another "aka" would just be clutter. 255 /// 4) Two different types within the same diagnostic have the same output 256 /// string. In this case, force an a.k.a with the desugared type when 257 /// doing so will provide additional information. 258 /// 259 /// \param Context the context in which the type was allocated 260 /// \param Ty the type to print 261 /// \param QualTypeVals pointer values to QualTypes which are used in the 262 /// diagnostic message 263 static std::string 264 ConvertTypeToDiagnosticString(ASTContext &Context, QualType Ty, 265 ArrayRef<DiagnosticsEngine::ArgumentValue> PrevArgs, 266 ArrayRef<intptr_t> QualTypeVals) { 267 // FIXME: Playing with std::string is really slow. 268 bool ForceAKA = false; 269 QualType CanTy = Ty.getCanonicalType(); 270 std::string S = Ty.getAsString(Context.getPrintingPolicy()); 271 std::string CanS = CanTy.getAsString(Context.getPrintingPolicy()); 272 273 for (const intptr_t &QualTypeVal : QualTypeVals) { 274 QualType CompareTy = 275 QualType::getFromOpaquePtr(reinterpret_cast<void *>(QualTypeVal)); 276 if (CompareTy.isNull()) 277 continue; 278 if (CompareTy == Ty) 279 continue; // Same types 280 QualType CompareCanTy = CompareTy.getCanonicalType(); 281 if (CompareCanTy == CanTy) 282 continue; // Same canonical types 283 std::string CompareS = CompareTy.getAsString(Context.getPrintingPolicy()); 284 bool ShouldAKA = false; 285 QualType CompareDesugar = 286 desugarForDiagnostic(Context, CompareTy, ShouldAKA); 287 std::string CompareDesugarStr = 288 CompareDesugar.getAsString(Context.getPrintingPolicy()); 289 if (CompareS != S && CompareDesugarStr != S) 290 continue; // The type string is different than the comparison string 291 // and the desugared comparison string. 292 std::string CompareCanS = 293 CompareCanTy.getAsString(Context.getPrintingPolicy()); 294 295 if (CompareCanS == CanS) 296 continue; // No new info from canonical type 297 298 ForceAKA = true; 299 break; 300 } 301 302 // Check to see if we already desugared this type in this 303 // diagnostic. If so, don't do it again. 304 bool Repeated = false; 305 for (const auto &PrevArg : PrevArgs) { 306 // TODO: Handle ak_declcontext case. 307 if (PrevArg.first == DiagnosticsEngine::ak_qualtype) { 308 QualType PrevTy( 309 QualType::getFromOpaquePtr(reinterpret_cast<void *>(PrevArg.second))); 310 if (PrevTy == Ty) { 311 Repeated = true; 312 break; 313 } 314 } 315 } 316 317 // Consider producing an a.k.a. clause if removing all the direct 318 // sugar gives us something "significantly different". 319 if (!Repeated) { 320 bool ShouldAKA = false; 321 QualType DesugaredTy = desugarForDiagnostic(Context, Ty, ShouldAKA); 322 if (ShouldAKA || ForceAKA) { 323 if (DesugaredTy == Ty) { 324 DesugaredTy = Ty.getCanonicalType(); 325 } 326 std::string akaStr = DesugaredTy.getAsString(Context.getPrintingPolicy()); 327 if (akaStr != S) { 328 S = "'" + S + "' (aka '" + akaStr + "')"; 329 return S; 330 } 331 } 332 333 // Give some additional info on vector types. These are either not desugared 334 // or displaying complex __attribute__ expressions so add details of the 335 // type and element count. 336 if (const auto *VTy = Ty->getAs<VectorType>()) { 337 std::string DecoratedString; 338 llvm::raw_string_ostream OS(DecoratedString); 339 const char *Values = VTy->getNumElements() > 1 ? "values" : "value"; 340 OS << "'" << S << "' (vector of " << VTy->getNumElements() << " '" 341 << VTy->getElementType().getAsString(Context.getPrintingPolicy()) 342 << "' " << Values << ")"; 343 return DecoratedString; 344 } 345 } 346 347 S = "'" + S + "'"; 348 return S; 349 } 350 351 static bool FormatTemplateTypeDiff(ASTContext &Context, QualType FromType, 352 QualType ToType, bool PrintTree, 353 bool PrintFromType, bool ElideType, 354 bool ShowColors, raw_ostream &OS); 355 356 void clang::FormatASTNodeDiagnosticArgument( 357 DiagnosticsEngine::ArgumentKind Kind, 358 intptr_t Val, 359 StringRef Modifier, 360 StringRef Argument, 361 ArrayRef<DiagnosticsEngine::ArgumentValue> PrevArgs, 362 SmallVectorImpl<char> &Output, 363 void *Cookie, 364 ArrayRef<intptr_t> QualTypeVals) { 365 ASTContext &Context = *static_cast<ASTContext*>(Cookie); 366 367 size_t OldEnd = Output.size(); 368 llvm::raw_svector_ostream OS(Output); 369 bool NeedQuotes = true; 370 371 switch (Kind) { 372 default: llvm_unreachable("unknown ArgumentKind"); 373 case DiagnosticsEngine::ak_addrspace: { 374 assert(Modifier.empty() && Argument.empty() && 375 "Invalid modifier for Qualifiers argument"); 376 377 auto S = Qualifiers::getAddrSpaceAsString(static_cast<LangAS>(Val)); 378 if (S.empty()) { 379 OS << (Context.getLangOpts().OpenCL ? "default" : "generic"); 380 OS << " address space"; 381 } else { 382 OS << "address space"; 383 OS << " '" << S << "'"; 384 } 385 NeedQuotes = false; 386 break; 387 } 388 case DiagnosticsEngine::ak_qual: { 389 assert(Modifier.empty() && Argument.empty() && 390 "Invalid modifier for Qualifiers argument"); 391 392 Qualifiers Q(Qualifiers::fromOpaqueValue(Val)); 393 auto S = Q.getAsString(); 394 if (S.empty()) { 395 OS << "unqualified"; 396 NeedQuotes = false; 397 } else { 398 OS << S; 399 } 400 break; 401 } 402 case DiagnosticsEngine::ak_qualtype_pair: { 403 TemplateDiffTypes &TDT = *reinterpret_cast<TemplateDiffTypes*>(Val); 404 QualType FromType = 405 QualType::getFromOpaquePtr(reinterpret_cast<void*>(TDT.FromType)); 406 QualType ToType = 407 QualType::getFromOpaquePtr(reinterpret_cast<void*>(TDT.ToType)); 408 409 if (FormatTemplateTypeDiff(Context, FromType, ToType, TDT.PrintTree, 410 TDT.PrintFromType, TDT.ElideType, 411 TDT.ShowColors, OS)) { 412 NeedQuotes = !TDT.PrintTree; 413 TDT.TemplateDiffUsed = true; 414 break; 415 } 416 417 // Don't fall-back during tree printing. The caller will handle 418 // this case. 419 if (TDT.PrintTree) 420 return; 421 422 // Attempting to do a template diff on non-templates. Set the variables 423 // and continue with regular type printing of the appropriate type. 424 Val = TDT.PrintFromType ? TDT.FromType : TDT.ToType; 425 Modifier = StringRef(); 426 Argument = StringRef(); 427 // Fall through 428 [[fallthrough]]; 429 } 430 case DiagnosticsEngine::ak_qualtype: { 431 assert(Modifier.empty() && Argument.empty() && 432 "Invalid modifier for QualType argument"); 433 434 QualType Ty(QualType::getFromOpaquePtr(reinterpret_cast<void*>(Val))); 435 OS << ConvertTypeToDiagnosticString(Context, Ty, PrevArgs, QualTypeVals); 436 NeedQuotes = false; 437 break; 438 } 439 case DiagnosticsEngine::ak_declarationname: { 440 if (Modifier == "objcclass" && Argument.empty()) 441 OS << '+'; 442 else if (Modifier == "objcinstance" && Argument.empty()) 443 OS << '-'; 444 else 445 assert(Modifier.empty() && Argument.empty() && 446 "Invalid modifier for DeclarationName argument"); 447 448 OS << DeclarationName::getFromOpaqueInteger(Val); 449 break; 450 } 451 case DiagnosticsEngine::ak_nameddecl: { 452 bool Qualified; 453 if (Modifier == "q" && Argument.empty()) 454 Qualified = true; 455 else { 456 assert(Modifier.empty() && Argument.empty() && 457 "Invalid modifier for NamedDecl* argument"); 458 Qualified = false; 459 } 460 const NamedDecl *ND = reinterpret_cast<const NamedDecl*>(Val); 461 ND->getNameForDiagnostic(OS, Context.getPrintingPolicy(), Qualified); 462 break; 463 } 464 case DiagnosticsEngine::ak_nestednamespec: { 465 NestedNameSpecifier *NNS = reinterpret_cast<NestedNameSpecifier*>(Val); 466 NNS->print(OS, Context.getPrintingPolicy()); 467 NeedQuotes = false; 468 break; 469 } 470 case DiagnosticsEngine::ak_declcontext: { 471 DeclContext *DC = reinterpret_cast<DeclContext *> (Val); 472 assert(DC && "Should never have a null declaration context"); 473 NeedQuotes = false; 474 475 // FIXME: Get the strings for DeclContext from some localized place 476 if (DC->isTranslationUnit()) { 477 if (Context.getLangOpts().CPlusPlus) 478 OS << "the global namespace"; 479 else 480 OS << "the global scope"; 481 } else if (DC->isClosure()) { 482 OS << "block literal"; 483 } else if (isLambdaCallOperator(DC)) { 484 OS << "lambda expression"; 485 } else if (TypeDecl *Type = dyn_cast<TypeDecl>(DC)) { 486 OS << ConvertTypeToDiagnosticString(Context, 487 Context.getTypeDeclType(Type), 488 PrevArgs, QualTypeVals); 489 } else { 490 assert(isa<NamedDecl>(DC) && "Expected a NamedDecl"); 491 NamedDecl *ND = cast<NamedDecl>(DC); 492 if (isa<NamespaceDecl>(ND)) 493 OS << "namespace "; 494 else if (isa<ObjCMethodDecl>(ND)) 495 OS << "method "; 496 else if (isa<FunctionDecl>(ND)) 497 OS << "function "; 498 499 OS << '\''; 500 ND->getNameForDiagnostic(OS, Context.getPrintingPolicy(), true); 501 OS << '\''; 502 } 503 break; 504 } 505 case DiagnosticsEngine::ak_attr: { 506 const Attr *At = reinterpret_cast<Attr *>(Val); 507 assert(At && "Received null Attr object!"); 508 OS << '\'' << At->getSpelling() << '\''; 509 NeedQuotes = false; 510 break; 511 } 512 } 513 514 if (NeedQuotes) { 515 Output.insert(Output.begin()+OldEnd, '\''); 516 Output.push_back('\''); 517 } 518 } 519 520 /// TemplateDiff - A class that constructs a pretty string for a pair of 521 /// QualTypes. For the pair of types, a diff tree will be created containing 522 /// all the information about the templates and template arguments. Afterwards, 523 /// the tree is transformed to a string according to the options passed in. 524 namespace { 525 class TemplateDiff { 526 /// Context - The ASTContext which is used for comparing template arguments. 527 ASTContext &Context; 528 529 /// Policy - Used during expression printing. 530 PrintingPolicy Policy; 531 532 /// ElideType - Option to elide identical types. 533 bool ElideType; 534 535 /// PrintTree - Format output string as a tree. 536 bool PrintTree; 537 538 /// ShowColor - Diagnostics support color, so bolding will be used. 539 bool ShowColor; 540 541 /// FromTemplateType - When single type printing is selected, this is the 542 /// type to be printed. When tree printing is selected, this type will 543 /// show up first in the tree. 544 QualType FromTemplateType; 545 546 /// ToTemplateType - The type that FromType is compared to. Only in tree 547 /// printing will this type be outputed. 548 QualType ToTemplateType; 549 550 /// OS - The stream used to construct the output strings. 551 raw_ostream &OS; 552 553 /// IsBold - Keeps track of the bold formatting for the output string. 554 bool IsBold; 555 556 /// DiffTree - A tree representation the differences between two types. 557 class DiffTree { 558 public: 559 /// DiffKind - The difference in a DiffNode. Fields of 560 /// TemplateArgumentInfo needed by each difference can be found in the 561 /// Set* and Get* functions. 562 enum DiffKind { 563 /// Incomplete or invalid node. 564 Invalid, 565 /// Another level of templates 566 Template, 567 /// Type difference, all type differences except those falling under 568 /// the Template difference. 569 Type, 570 /// Expression difference, this is only when both arguments are 571 /// expressions. If one argument is an expression and the other is 572 /// Integer or Declaration, then use that diff type instead. 573 Expression, 574 /// Template argument difference 575 TemplateTemplate, 576 /// Integer difference 577 Integer, 578 /// Declaration difference, nullptr arguments are included here 579 Declaration, 580 /// One argument being integer and the other being declaration 581 FromIntegerAndToDeclaration, 582 FromDeclarationAndToInteger 583 }; 584 585 private: 586 /// TemplateArgumentInfo - All the information needed to pretty print 587 /// a template argument. See the Set* and Get* functions to see which 588 /// fields are used for each DiffKind. 589 struct TemplateArgumentInfo { 590 QualType ArgType; 591 Qualifiers Qual; 592 llvm::APSInt Val; 593 bool IsValidInt = false; 594 Expr *ArgExpr = nullptr; 595 TemplateDecl *TD = nullptr; 596 ValueDecl *VD = nullptr; 597 bool NeedAddressOf = false; 598 bool IsNullPtr = false; 599 bool IsDefault = false; 600 }; 601 602 /// DiffNode - The root node stores the original type. Each child node 603 /// stores template arguments of their parents. For templated types, the 604 /// template decl is also stored. 605 struct DiffNode { 606 DiffKind Kind = Invalid; 607 608 /// NextNode - The index of the next sibling node or 0. 609 unsigned NextNode = 0; 610 611 /// ChildNode - The index of the first child node or 0. 612 unsigned ChildNode = 0; 613 614 /// ParentNode - The index of the parent node. 615 unsigned ParentNode = 0; 616 617 TemplateArgumentInfo FromArgInfo, ToArgInfo; 618 619 /// Same - Whether the two arguments evaluate to the same value. 620 bool Same = false; 621 622 DiffNode(unsigned ParentNode = 0) : ParentNode(ParentNode) {} 623 }; 624 625 /// FlatTree - A flattened tree used to store the DiffNodes. 626 SmallVector<DiffNode, 16> FlatTree; 627 628 /// CurrentNode - The index of the current node being used. 629 unsigned CurrentNode; 630 631 /// NextFreeNode - The index of the next unused node. Used when creating 632 /// child nodes. 633 unsigned NextFreeNode; 634 635 /// ReadNode - The index of the current node being read. 636 unsigned ReadNode; 637 638 public: 639 DiffTree() : CurrentNode(0), NextFreeNode(1), ReadNode(0) { 640 FlatTree.push_back(DiffNode()); 641 } 642 643 // Node writing functions, one for each valid DiffKind element. 644 void SetTemplateDiff(TemplateDecl *FromTD, TemplateDecl *ToTD, 645 Qualifiers FromQual, Qualifiers ToQual, 646 bool FromDefault, bool ToDefault) { 647 assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty."); 648 FlatTree[CurrentNode].Kind = Template; 649 FlatTree[CurrentNode].FromArgInfo.TD = FromTD; 650 FlatTree[CurrentNode].ToArgInfo.TD = ToTD; 651 FlatTree[CurrentNode].FromArgInfo.Qual = FromQual; 652 FlatTree[CurrentNode].ToArgInfo.Qual = ToQual; 653 SetDefault(FromDefault, ToDefault); 654 } 655 656 void SetTypeDiff(QualType FromType, QualType ToType, bool FromDefault, 657 bool ToDefault) { 658 assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty."); 659 FlatTree[CurrentNode].Kind = Type; 660 FlatTree[CurrentNode].FromArgInfo.ArgType = FromType; 661 FlatTree[CurrentNode].ToArgInfo.ArgType = ToType; 662 SetDefault(FromDefault, ToDefault); 663 } 664 665 void SetExpressionDiff(Expr *FromExpr, Expr *ToExpr, bool FromDefault, 666 bool ToDefault) { 667 assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty."); 668 FlatTree[CurrentNode].Kind = Expression; 669 FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr; 670 FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr; 671 SetDefault(FromDefault, ToDefault); 672 } 673 674 void SetTemplateTemplateDiff(TemplateDecl *FromTD, TemplateDecl *ToTD, 675 bool FromDefault, bool ToDefault) { 676 assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty."); 677 FlatTree[CurrentNode].Kind = TemplateTemplate; 678 FlatTree[CurrentNode].FromArgInfo.TD = FromTD; 679 FlatTree[CurrentNode].ToArgInfo.TD = ToTD; 680 SetDefault(FromDefault, ToDefault); 681 } 682 683 void SetIntegerDiff(const llvm::APSInt &FromInt, const llvm::APSInt &ToInt, 684 bool IsValidFromInt, bool IsValidToInt, 685 QualType FromIntType, QualType ToIntType, 686 Expr *FromExpr, Expr *ToExpr, bool FromDefault, 687 bool ToDefault) { 688 assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty."); 689 FlatTree[CurrentNode].Kind = Integer; 690 FlatTree[CurrentNode].FromArgInfo.Val = FromInt; 691 FlatTree[CurrentNode].ToArgInfo.Val = ToInt; 692 FlatTree[CurrentNode].FromArgInfo.IsValidInt = IsValidFromInt; 693 FlatTree[CurrentNode].ToArgInfo.IsValidInt = IsValidToInt; 694 FlatTree[CurrentNode].FromArgInfo.ArgType = FromIntType; 695 FlatTree[CurrentNode].ToArgInfo.ArgType = ToIntType; 696 FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr; 697 FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr; 698 SetDefault(FromDefault, ToDefault); 699 } 700 701 void SetDeclarationDiff(ValueDecl *FromValueDecl, ValueDecl *ToValueDecl, 702 bool FromAddressOf, bool ToAddressOf, 703 bool FromNullPtr, bool ToNullPtr, Expr *FromExpr, 704 Expr *ToExpr, bool FromDefault, bool ToDefault) { 705 assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty."); 706 FlatTree[CurrentNode].Kind = Declaration; 707 FlatTree[CurrentNode].FromArgInfo.VD = FromValueDecl; 708 FlatTree[CurrentNode].ToArgInfo.VD = ToValueDecl; 709 FlatTree[CurrentNode].FromArgInfo.NeedAddressOf = FromAddressOf; 710 FlatTree[CurrentNode].ToArgInfo.NeedAddressOf = ToAddressOf; 711 FlatTree[CurrentNode].FromArgInfo.IsNullPtr = FromNullPtr; 712 FlatTree[CurrentNode].ToArgInfo.IsNullPtr = ToNullPtr; 713 FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr; 714 FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr; 715 SetDefault(FromDefault, ToDefault); 716 } 717 718 void SetFromDeclarationAndToIntegerDiff( 719 ValueDecl *FromValueDecl, bool FromAddressOf, bool FromNullPtr, 720 Expr *FromExpr, const llvm::APSInt &ToInt, bool IsValidToInt, 721 QualType ToIntType, Expr *ToExpr, bool FromDefault, bool ToDefault) { 722 assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty."); 723 FlatTree[CurrentNode].Kind = FromDeclarationAndToInteger; 724 FlatTree[CurrentNode].FromArgInfo.VD = FromValueDecl; 725 FlatTree[CurrentNode].FromArgInfo.NeedAddressOf = FromAddressOf; 726 FlatTree[CurrentNode].FromArgInfo.IsNullPtr = FromNullPtr; 727 FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr; 728 FlatTree[CurrentNode].ToArgInfo.Val = ToInt; 729 FlatTree[CurrentNode].ToArgInfo.IsValidInt = IsValidToInt; 730 FlatTree[CurrentNode].ToArgInfo.ArgType = ToIntType; 731 FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr; 732 SetDefault(FromDefault, ToDefault); 733 } 734 735 void SetFromIntegerAndToDeclarationDiff( 736 const llvm::APSInt &FromInt, bool IsValidFromInt, QualType FromIntType, 737 Expr *FromExpr, ValueDecl *ToValueDecl, bool ToAddressOf, 738 bool ToNullPtr, Expr *ToExpr, bool FromDefault, bool ToDefault) { 739 assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty."); 740 FlatTree[CurrentNode].Kind = FromIntegerAndToDeclaration; 741 FlatTree[CurrentNode].FromArgInfo.Val = FromInt; 742 FlatTree[CurrentNode].FromArgInfo.IsValidInt = IsValidFromInt; 743 FlatTree[CurrentNode].FromArgInfo.ArgType = FromIntType; 744 FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr; 745 FlatTree[CurrentNode].ToArgInfo.VD = ToValueDecl; 746 FlatTree[CurrentNode].ToArgInfo.NeedAddressOf = ToAddressOf; 747 FlatTree[CurrentNode].ToArgInfo.IsNullPtr = ToNullPtr; 748 FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr; 749 SetDefault(FromDefault, ToDefault); 750 } 751 752 /// SetDefault - Sets FromDefault and ToDefault flags of the current node. 753 void SetDefault(bool FromDefault, bool ToDefault) { 754 assert((!FromDefault || !ToDefault) && "Both arguments cannot be default."); 755 FlatTree[CurrentNode].FromArgInfo.IsDefault = FromDefault; 756 FlatTree[CurrentNode].ToArgInfo.IsDefault = ToDefault; 757 } 758 759 /// SetSame - Sets the same flag of the current node. 760 void SetSame(bool Same) { 761 FlatTree[CurrentNode].Same = Same; 762 } 763 764 /// SetKind - Sets the current node's type. 765 void SetKind(DiffKind Kind) { 766 FlatTree[CurrentNode].Kind = Kind; 767 } 768 769 /// Up - Changes the node to the parent of the current node. 770 void Up() { 771 assert(FlatTree[CurrentNode].Kind != Invalid && 772 "Cannot exit node before setting node information."); 773 CurrentNode = FlatTree[CurrentNode].ParentNode; 774 } 775 776 /// AddNode - Adds a child node to the current node, then sets that node 777 /// node as the current node. 778 void AddNode() { 779 assert(FlatTree[CurrentNode].Kind == Template && 780 "Only Template nodes can have children nodes."); 781 FlatTree.push_back(DiffNode(CurrentNode)); 782 DiffNode &Node = FlatTree[CurrentNode]; 783 if (Node.ChildNode == 0) { 784 // If a child node doesn't exist, add one. 785 Node.ChildNode = NextFreeNode; 786 } else { 787 // If a child node exists, find the last child node and add a 788 // next node to it. 789 unsigned i; 790 for (i = Node.ChildNode; FlatTree[i].NextNode != 0; 791 i = FlatTree[i].NextNode) { 792 } 793 FlatTree[i].NextNode = NextFreeNode; 794 } 795 CurrentNode = NextFreeNode; 796 ++NextFreeNode; 797 } 798 799 // Node reading functions. 800 /// StartTraverse - Prepares the tree for recursive traversal. 801 void StartTraverse() { 802 ReadNode = 0; 803 CurrentNode = NextFreeNode; 804 NextFreeNode = 0; 805 } 806 807 /// Parent - Move the current read node to its parent. 808 void Parent() { 809 ReadNode = FlatTree[ReadNode].ParentNode; 810 } 811 812 void GetTemplateDiff(TemplateDecl *&FromTD, TemplateDecl *&ToTD, 813 Qualifiers &FromQual, Qualifiers &ToQual) { 814 assert(FlatTree[ReadNode].Kind == Template && "Unexpected kind."); 815 FromTD = FlatTree[ReadNode].FromArgInfo.TD; 816 ToTD = FlatTree[ReadNode].ToArgInfo.TD; 817 FromQual = FlatTree[ReadNode].FromArgInfo.Qual; 818 ToQual = FlatTree[ReadNode].ToArgInfo.Qual; 819 } 820 821 void GetTypeDiff(QualType &FromType, QualType &ToType) { 822 assert(FlatTree[ReadNode].Kind == Type && "Unexpected kind"); 823 FromType = FlatTree[ReadNode].FromArgInfo.ArgType; 824 ToType = FlatTree[ReadNode].ToArgInfo.ArgType; 825 } 826 827 void GetExpressionDiff(Expr *&FromExpr, Expr *&ToExpr) { 828 assert(FlatTree[ReadNode].Kind == Expression && "Unexpected kind"); 829 FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr; 830 ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr; 831 } 832 833 void GetTemplateTemplateDiff(TemplateDecl *&FromTD, TemplateDecl *&ToTD) { 834 assert(FlatTree[ReadNode].Kind == TemplateTemplate && "Unexpected kind."); 835 FromTD = FlatTree[ReadNode].FromArgInfo.TD; 836 ToTD = FlatTree[ReadNode].ToArgInfo.TD; 837 } 838 839 void GetIntegerDiff(llvm::APSInt &FromInt, llvm::APSInt &ToInt, 840 bool &IsValidFromInt, bool &IsValidToInt, 841 QualType &FromIntType, QualType &ToIntType, 842 Expr *&FromExpr, Expr *&ToExpr) { 843 assert(FlatTree[ReadNode].Kind == Integer && "Unexpected kind."); 844 FromInt = FlatTree[ReadNode].FromArgInfo.Val; 845 ToInt = FlatTree[ReadNode].ToArgInfo.Val; 846 IsValidFromInt = FlatTree[ReadNode].FromArgInfo.IsValidInt; 847 IsValidToInt = FlatTree[ReadNode].ToArgInfo.IsValidInt; 848 FromIntType = FlatTree[ReadNode].FromArgInfo.ArgType; 849 ToIntType = FlatTree[ReadNode].ToArgInfo.ArgType; 850 FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr; 851 ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr; 852 } 853 854 void GetDeclarationDiff(ValueDecl *&FromValueDecl, ValueDecl *&ToValueDecl, 855 bool &FromAddressOf, bool &ToAddressOf, 856 bool &FromNullPtr, bool &ToNullPtr, Expr *&FromExpr, 857 Expr *&ToExpr) { 858 assert(FlatTree[ReadNode].Kind == Declaration && "Unexpected kind."); 859 FromValueDecl = FlatTree[ReadNode].FromArgInfo.VD; 860 ToValueDecl = FlatTree[ReadNode].ToArgInfo.VD; 861 FromAddressOf = FlatTree[ReadNode].FromArgInfo.NeedAddressOf; 862 ToAddressOf = FlatTree[ReadNode].ToArgInfo.NeedAddressOf; 863 FromNullPtr = FlatTree[ReadNode].FromArgInfo.IsNullPtr; 864 ToNullPtr = FlatTree[ReadNode].ToArgInfo.IsNullPtr; 865 FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr; 866 ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr; 867 } 868 869 void GetFromDeclarationAndToIntegerDiff( 870 ValueDecl *&FromValueDecl, bool &FromAddressOf, bool &FromNullPtr, 871 Expr *&FromExpr, llvm::APSInt &ToInt, bool &IsValidToInt, 872 QualType &ToIntType, Expr *&ToExpr) { 873 assert(FlatTree[ReadNode].Kind == FromDeclarationAndToInteger && 874 "Unexpected kind."); 875 FromValueDecl = FlatTree[ReadNode].FromArgInfo.VD; 876 FromAddressOf = FlatTree[ReadNode].FromArgInfo.NeedAddressOf; 877 FromNullPtr = FlatTree[ReadNode].FromArgInfo.IsNullPtr; 878 FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr; 879 ToInt = FlatTree[ReadNode].ToArgInfo.Val; 880 IsValidToInt = FlatTree[ReadNode].ToArgInfo.IsValidInt; 881 ToIntType = FlatTree[ReadNode].ToArgInfo.ArgType; 882 ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr; 883 } 884 885 void GetFromIntegerAndToDeclarationDiff( 886 llvm::APSInt &FromInt, bool &IsValidFromInt, QualType &FromIntType, 887 Expr *&FromExpr, ValueDecl *&ToValueDecl, bool &ToAddressOf, 888 bool &ToNullPtr, Expr *&ToExpr) { 889 assert(FlatTree[ReadNode].Kind == FromIntegerAndToDeclaration && 890 "Unexpected kind."); 891 FromInt = FlatTree[ReadNode].FromArgInfo.Val; 892 IsValidFromInt = FlatTree[ReadNode].FromArgInfo.IsValidInt; 893 FromIntType = FlatTree[ReadNode].FromArgInfo.ArgType; 894 FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr; 895 ToValueDecl = FlatTree[ReadNode].ToArgInfo.VD; 896 ToAddressOf = FlatTree[ReadNode].ToArgInfo.NeedAddressOf; 897 ToNullPtr = FlatTree[ReadNode].ToArgInfo.IsNullPtr; 898 ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr; 899 } 900 901 /// FromDefault - Return true if the from argument is the default. 902 bool FromDefault() { 903 return FlatTree[ReadNode].FromArgInfo.IsDefault; 904 } 905 906 /// ToDefault - Return true if the to argument is the default. 907 bool ToDefault() { 908 return FlatTree[ReadNode].ToArgInfo.IsDefault; 909 } 910 911 /// NodeIsSame - Returns true the arguments are the same. 912 bool NodeIsSame() { 913 return FlatTree[ReadNode].Same; 914 } 915 916 /// HasChildrend - Returns true if the node has children. 917 bool HasChildren() { 918 return FlatTree[ReadNode].ChildNode != 0; 919 } 920 921 /// MoveToChild - Moves from the current node to its child. 922 void MoveToChild() { 923 ReadNode = FlatTree[ReadNode].ChildNode; 924 } 925 926 /// AdvanceSibling - If there is a next sibling, advance to it and return 927 /// true. Otherwise, return false. 928 bool AdvanceSibling() { 929 if (FlatTree[ReadNode].NextNode == 0) 930 return false; 931 932 ReadNode = FlatTree[ReadNode].NextNode; 933 return true; 934 } 935 936 /// HasNextSibling - Return true if the node has a next sibling. 937 bool HasNextSibling() { 938 return FlatTree[ReadNode].NextNode != 0; 939 } 940 941 /// Empty - Returns true if the tree has no information. 942 bool Empty() { 943 return GetKind() == Invalid; 944 } 945 946 /// GetKind - Returns the current node's type. 947 DiffKind GetKind() { 948 return FlatTree[ReadNode].Kind; 949 } 950 }; 951 952 DiffTree Tree; 953 954 /// TSTiterator - a pair of iterators that walks the 955 /// TemplateSpecializationType and the desugared TemplateSpecializationType. 956 /// The deseguared TemplateArgument should provide the canonical argument 957 /// for comparisons. 958 class TSTiterator { 959 typedef const TemplateArgument& reference; 960 typedef const TemplateArgument* pointer; 961 962 /// InternalIterator - an iterator that is used to enter a 963 /// TemplateSpecializationType and read TemplateArguments inside template 964 /// parameter packs in order with the rest of the TemplateArguments. 965 struct InternalIterator { 966 /// TST - the template specialization whose arguments this iterator 967 /// traverse over. 968 const TemplateSpecializationType *TST; 969 970 /// Index - the index of the template argument in TST. 971 unsigned Index; 972 973 /// CurrentTA - if CurrentTA is not the same as EndTA, then CurrentTA 974 /// points to a TemplateArgument within a parameter pack. 975 TemplateArgument::pack_iterator CurrentTA; 976 977 /// EndTA - the end iterator of a parameter pack 978 TemplateArgument::pack_iterator EndTA; 979 980 /// InternalIterator - Constructs an iterator and sets it to the first 981 /// template argument. 982 InternalIterator(const TemplateSpecializationType *TST) 983 : TST(TST), Index(0), CurrentTA(nullptr), EndTA(nullptr) { 984 if (!TST) return; 985 986 if (isEnd()) return; 987 988 // Set to first template argument. If not a parameter pack, done. 989 TemplateArgument TA = TST->template_arguments()[0]; 990 if (TA.getKind() != TemplateArgument::Pack) return; 991 992 // Start looking into the parameter pack. 993 CurrentTA = TA.pack_begin(); 994 EndTA = TA.pack_end(); 995 996 // Found a valid template argument. 997 if (CurrentTA != EndTA) return; 998 999 // Parameter pack is empty, use the increment to get to a valid 1000 // template argument. 1001 ++(*this); 1002 } 1003 1004 /// Return true if the iterator is non-singular. 1005 bool isValid() const { return TST; } 1006 1007 /// isEnd - Returns true if the iterator is one past the end. 1008 bool isEnd() const { 1009 assert(TST && "InternalIterator is invalid with a null TST."); 1010 return Index >= TST->template_arguments().size(); 1011 } 1012 1013 /// &operator++ - Increment the iterator to the next template argument. 1014 InternalIterator &operator++() { 1015 assert(TST && "InternalIterator is invalid with a null TST."); 1016 if (isEnd()) { 1017 return *this; 1018 } 1019 1020 // If in a parameter pack, advance in the parameter pack. 1021 if (CurrentTA != EndTA) { 1022 ++CurrentTA; 1023 if (CurrentTA != EndTA) 1024 return *this; 1025 } 1026 1027 // Loop until a template argument is found, or the end is reached. 1028 while (true) { 1029 // Advance to the next template argument. Break if reached the end. 1030 if (++Index == TST->template_arguments().size()) 1031 break; 1032 1033 // If the TemplateArgument is not a parameter pack, done. 1034 TemplateArgument TA = TST->template_arguments()[Index]; 1035 if (TA.getKind() != TemplateArgument::Pack) 1036 break; 1037 1038 // Handle parameter packs. 1039 CurrentTA = TA.pack_begin(); 1040 EndTA = TA.pack_end(); 1041 1042 // If the parameter pack is empty, try to advance again. 1043 if (CurrentTA != EndTA) 1044 break; 1045 } 1046 return *this; 1047 } 1048 1049 /// operator* - Returns the appropriate TemplateArgument. 1050 reference operator*() const { 1051 assert(TST && "InternalIterator is invalid with a null TST."); 1052 assert(!isEnd() && "Index exceeds number of arguments."); 1053 if (CurrentTA == EndTA) 1054 return TST->template_arguments()[Index]; 1055 else 1056 return *CurrentTA; 1057 } 1058 1059 /// operator-> - Allow access to the underlying TemplateArgument. 1060 pointer operator->() const { 1061 assert(TST && "InternalIterator is invalid with a null TST."); 1062 return &operator*(); 1063 } 1064 }; 1065 1066 InternalIterator SugaredIterator; 1067 InternalIterator DesugaredIterator; 1068 1069 public: 1070 TSTiterator(ASTContext &Context, const TemplateSpecializationType *TST) 1071 : SugaredIterator(TST), 1072 DesugaredIterator( 1073 (TST->isSugared() && !TST->isTypeAlias()) 1074 ? GetTemplateSpecializationType(Context, TST->desugar()) 1075 : nullptr) {} 1076 1077 /// &operator++ - Increment the iterator to the next template argument. 1078 TSTiterator &operator++() { 1079 ++SugaredIterator; 1080 if (DesugaredIterator.isValid()) 1081 ++DesugaredIterator; 1082 return *this; 1083 } 1084 1085 /// operator* - Returns the appropriate TemplateArgument. 1086 reference operator*() const { 1087 return *SugaredIterator; 1088 } 1089 1090 /// operator-> - Allow access to the underlying TemplateArgument. 1091 pointer operator->() const { 1092 return &operator*(); 1093 } 1094 1095 /// isEnd - Returns true if no more TemplateArguments are available. 1096 bool isEnd() const { 1097 return SugaredIterator.isEnd(); 1098 } 1099 1100 /// hasDesugaredTA - Returns true if there is another TemplateArgument 1101 /// available. 1102 bool hasDesugaredTA() const { 1103 return DesugaredIterator.isValid() && !DesugaredIterator.isEnd(); 1104 } 1105 1106 /// getDesugaredTA - Returns the desugared TemplateArgument. 1107 reference getDesugaredTA() const { 1108 assert(DesugaredIterator.isValid() && 1109 "Desugared TemplateArgument should not be used."); 1110 return *DesugaredIterator; 1111 } 1112 }; 1113 1114 // These functions build up the template diff tree, including functions to 1115 // retrieve and compare template arguments. 1116 1117 static const TemplateSpecializationType *GetTemplateSpecializationType( 1118 ASTContext &Context, QualType Ty) { 1119 if (const TemplateSpecializationType *TST = 1120 Ty->getAs<TemplateSpecializationType>()) 1121 return TST; 1122 1123 if (const auto* SubstType = Ty->getAs<SubstTemplateTypeParmType>()) 1124 Ty = SubstType->getReplacementType(); 1125 1126 const RecordType *RT = Ty->getAs<RecordType>(); 1127 1128 if (!RT) 1129 return nullptr; 1130 1131 const ClassTemplateSpecializationDecl *CTSD = 1132 dyn_cast<ClassTemplateSpecializationDecl>(RT->getDecl()); 1133 1134 if (!CTSD) 1135 return nullptr; 1136 1137 Ty = Context.getTemplateSpecializationType( 1138 TemplateName(CTSD->getSpecializedTemplate()), 1139 CTSD->getTemplateArgs().asArray(), 1140 Ty.getLocalUnqualifiedType().getCanonicalType()); 1141 1142 return Ty->getAs<TemplateSpecializationType>(); 1143 } 1144 1145 /// Returns true if the DiffType is Type and false for Template. 1146 static bool OnlyPerformTypeDiff(ASTContext &Context, QualType FromType, 1147 QualType ToType, 1148 const TemplateSpecializationType *&FromArgTST, 1149 const TemplateSpecializationType *&ToArgTST) { 1150 if (FromType.isNull() || ToType.isNull()) 1151 return true; 1152 1153 if (Context.hasSameType(FromType, ToType)) 1154 return true; 1155 1156 FromArgTST = GetTemplateSpecializationType(Context, FromType); 1157 ToArgTST = GetTemplateSpecializationType(Context, ToType); 1158 1159 if (!FromArgTST || !ToArgTST) 1160 return true; 1161 1162 if (!hasSameTemplate(FromArgTST, ToArgTST)) 1163 return true; 1164 1165 return false; 1166 } 1167 1168 /// DiffTypes - Fills a DiffNode with information about a type difference. 1169 void DiffTypes(const TSTiterator &FromIter, const TSTiterator &ToIter) { 1170 QualType FromType = GetType(FromIter); 1171 QualType ToType = GetType(ToIter); 1172 1173 bool FromDefault = FromIter.isEnd() && !FromType.isNull(); 1174 bool ToDefault = ToIter.isEnd() && !ToType.isNull(); 1175 1176 const TemplateSpecializationType *FromArgTST = nullptr; 1177 const TemplateSpecializationType *ToArgTST = nullptr; 1178 if (OnlyPerformTypeDiff(Context, FromType, ToType, FromArgTST, ToArgTST)) { 1179 Tree.SetTypeDiff(FromType, ToType, FromDefault, ToDefault); 1180 Tree.SetSame(!FromType.isNull() && !ToType.isNull() && 1181 Context.hasSameType(FromType, ToType)); 1182 } else { 1183 assert(FromArgTST && ToArgTST && 1184 "Both template specializations need to be valid."); 1185 Qualifiers FromQual = FromType.getQualifiers(), 1186 ToQual = ToType.getQualifiers(); 1187 FromQual -= QualType(FromArgTST, 0).getQualifiers(); 1188 ToQual -= QualType(ToArgTST, 0).getQualifiers(); 1189 Tree.SetTemplateDiff(FromArgTST->getTemplateName().getAsTemplateDecl(), 1190 ToArgTST->getTemplateName().getAsTemplateDecl(), 1191 FromQual, ToQual, FromDefault, ToDefault); 1192 DiffTemplate(FromArgTST, ToArgTST); 1193 } 1194 } 1195 1196 /// DiffTemplateTemplates - Fills a DiffNode with information about a 1197 /// template template difference. 1198 void DiffTemplateTemplates(const TSTiterator &FromIter, 1199 const TSTiterator &ToIter) { 1200 TemplateDecl *FromDecl = GetTemplateDecl(FromIter); 1201 TemplateDecl *ToDecl = GetTemplateDecl(ToIter); 1202 Tree.SetTemplateTemplateDiff(FromDecl, ToDecl, FromIter.isEnd() && FromDecl, 1203 ToIter.isEnd() && ToDecl); 1204 Tree.SetSame(FromDecl && ToDecl && 1205 FromDecl->getCanonicalDecl() == ToDecl->getCanonicalDecl()); 1206 } 1207 1208 /// InitializeNonTypeDiffVariables - Helper function for DiffNonTypes 1209 static void InitializeNonTypeDiffVariables(ASTContext &Context, 1210 const TSTiterator &Iter, 1211 NonTypeTemplateParmDecl *Default, 1212 llvm::APSInt &Value, bool &HasInt, 1213 QualType &IntType, bool &IsNullPtr, 1214 Expr *&E, ValueDecl *&VD, 1215 bool &NeedAddressOf) { 1216 if (!Iter.isEnd()) { 1217 switch (Iter->getKind()) { 1218 case TemplateArgument::StructuralValue: 1219 // FIXME: Diffing of structural values is not implemented. 1220 // There is no possible fallback in this case, this will show up 1221 // as '(no argument)'. 1222 return; 1223 case TemplateArgument::Integral: 1224 Value = Iter->getAsIntegral(); 1225 HasInt = true; 1226 IntType = Iter->getIntegralType(); 1227 return; 1228 case TemplateArgument::Declaration: { 1229 VD = Iter->getAsDecl(); 1230 QualType ArgType = Iter->getParamTypeForDecl(); 1231 QualType VDType = VD->getType(); 1232 if (ArgType->isPointerType() && 1233 Context.hasSameType(ArgType->getPointeeType(), VDType)) 1234 NeedAddressOf = true; 1235 return; 1236 } 1237 case TemplateArgument::NullPtr: 1238 IsNullPtr = true; 1239 return; 1240 case TemplateArgument::Expression: 1241 E = Iter->getAsExpr(); 1242 break; 1243 case TemplateArgument::Null: 1244 case TemplateArgument::Type: 1245 case TemplateArgument::Template: 1246 case TemplateArgument::TemplateExpansion: 1247 llvm_unreachable("TemplateArgument kind is not expected for NTTP"); 1248 case TemplateArgument::Pack: 1249 llvm_unreachable("TemplateArgument kind should be handled elsewhere"); 1250 } 1251 } else if (!Default->isParameterPack()) { 1252 E = Default->getDefaultArgument().getArgument().getAsExpr(); 1253 } 1254 1255 if (!Iter.hasDesugaredTA()) 1256 return; 1257 1258 const TemplateArgument &TA = Iter.getDesugaredTA(); 1259 switch (TA.getKind()) { 1260 case TemplateArgument::StructuralValue: 1261 // FIXME: Diffing of structural values is not implemented. 1262 // Just fall back to the expression. 1263 return; 1264 case TemplateArgument::Integral: 1265 Value = TA.getAsIntegral(); 1266 HasInt = true; 1267 IntType = TA.getIntegralType(); 1268 return; 1269 case TemplateArgument::Declaration: { 1270 VD = TA.getAsDecl(); 1271 QualType ArgType = TA.getParamTypeForDecl(); 1272 QualType VDType = VD->getType(); 1273 if (ArgType->isPointerType() && 1274 Context.hasSameType(ArgType->getPointeeType(), VDType)) 1275 NeedAddressOf = true; 1276 return; 1277 } 1278 case TemplateArgument::NullPtr: 1279 IsNullPtr = true; 1280 return; 1281 case TemplateArgument::Expression: 1282 // TODO: Sometimes, the desugared template argument Expr differs from 1283 // the sugared template argument Expr. It may be useful in the future 1284 // but for now, it is just discarded. 1285 if (!E) 1286 E = TA.getAsExpr(); 1287 return; 1288 case TemplateArgument::Null: 1289 case TemplateArgument::Type: 1290 case TemplateArgument::Template: 1291 case TemplateArgument::TemplateExpansion: 1292 llvm_unreachable("TemplateArgument kind is not expected for NTTP"); 1293 case TemplateArgument::Pack: 1294 llvm_unreachable("TemplateArgument kind should be handled elsewhere"); 1295 } 1296 llvm_unreachable("Unexpected TemplateArgument kind"); 1297 } 1298 1299 /// DiffNonTypes - Handles any template parameters not handled by DiffTypes 1300 /// of DiffTemplatesTemplates, such as integer and declaration parameters. 1301 void DiffNonTypes(const TSTiterator &FromIter, const TSTiterator &ToIter, 1302 NonTypeTemplateParmDecl *FromDefaultNonTypeDecl, 1303 NonTypeTemplateParmDecl *ToDefaultNonTypeDecl) { 1304 Expr *FromExpr = nullptr, *ToExpr = nullptr; 1305 llvm::APSInt FromInt, ToInt; 1306 QualType FromIntType, ToIntType; 1307 ValueDecl *FromValueDecl = nullptr, *ToValueDecl = nullptr; 1308 bool HasFromInt = false, HasToInt = false, FromNullPtr = false, 1309 ToNullPtr = false, NeedFromAddressOf = false, NeedToAddressOf = false; 1310 InitializeNonTypeDiffVariables( 1311 Context, FromIter, FromDefaultNonTypeDecl, FromInt, HasFromInt, 1312 FromIntType, FromNullPtr, FromExpr, FromValueDecl, NeedFromAddressOf); 1313 InitializeNonTypeDiffVariables(Context, ToIter, ToDefaultNonTypeDecl, ToInt, 1314 HasToInt, ToIntType, ToNullPtr, ToExpr, 1315 ToValueDecl, NeedToAddressOf); 1316 1317 bool FromDefault = FromIter.isEnd() && 1318 (FromExpr || FromValueDecl || HasFromInt || FromNullPtr); 1319 bool ToDefault = ToIter.isEnd() && 1320 (ToExpr || ToValueDecl || HasToInt || ToNullPtr); 1321 1322 bool FromDeclaration = FromValueDecl || FromNullPtr; 1323 bool ToDeclaration = ToValueDecl || ToNullPtr; 1324 1325 if (FromDeclaration && HasToInt) { 1326 Tree.SetFromDeclarationAndToIntegerDiff( 1327 FromValueDecl, NeedFromAddressOf, FromNullPtr, FromExpr, ToInt, 1328 HasToInt, ToIntType, ToExpr, FromDefault, ToDefault); 1329 Tree.SetSame(false); 1330 return; 1331 1332 } 1333 1334 if (HasFromInt && ToDeclaration) { 1335 Tree.SetFromIntegerAndToDeclarationDiff( 1336 FromInt, HasFromInt, FromIntType, FromExpr, ToValueDecl, 1337 NeedToAddressOf, ToNullPtr, ToExpr, FromDefault, ToDefault); 1338 Tree.SetSame(false); 1339 return; 1340 } 1341 1342 if (HasFromInt || HasToInt) { 1343 Tree.SetIntegerDiff(FromInt, ToInt, HasFromInt, HasToInt, FromIntType, 1344 ToIntType, FromExpr, ToExpr, FromDefault, ToDefault); 1345 if (HasFromInt && HasToInt) { 1346 Tree.SetSame(Context.hasSameType(FromIntType, ToIntType) && 1347 FromInt == ToInt); 1348 } 1349 return; 1350 } 1351 1352 if (FromDeclaration || ToDeclaration) { 1353 Tree.SetDeclarationDiff(FromValueDecl, ToValueDecl, NeedFromAddressOf, 1354 NeedToAddressOf, FromNullPtr, ToNullPtr, FromExpr, 1355 ToExpr, FromDefault, ToDefault); 1356 bool BothNull = FromNullPtr && ToNullPtr; 1357 bool SameValueDecl = 1358 FromValueDecl && ToValueDecl && 1359 NeedFromAddressOf == NeedToAddressOf && 1360 FromValueDecl->getCanonicalDecl() == ToValueDecl->getCanonicalDecl(); 1361 Tree.SetSame(BothNull || SameValueDecl); 1362 return; 1363 } 1364 1365 assert((FromExpr || ToExpr) && "Both template arguments cannot be empty."); 1366 Tree.SetExpressionDiff(FromExpr, ToExpr, FromDefault, ToDefault); 1367 Tree.SetSame(IsEqualExpr(Context, FromExpr, ToExpr)); 1368 } 1369 1370 /// DiffTemplate - recursively visits template arguments and stores the 1371 /// argument info into a tree. 1372 void DiffTemplate(const TemplateSpecializationType *FromTST, 1373 const TemplateSpecializationType *ToTST) { 1374 // Begin descent into diffing template tree. 1375 TemplateParameterList *ParamsFrom = 1376 FromTST->getTemplateName().getAsTemplateDecl()->getTemplateParameters(); 1377 TemplateParameterList *ParamsTo = 1378 ToTST->getTemplateName().getAsTemplateDecl()->getTemplateParameters(); 1379 unsigned TotalArgs = 0; 1380 for (TSTiterator FromIter(Context, FromTST), ToIter(Context, ToTST); 1381 !FromIter.isEnd() || !ToIter.isEnd(); ++TotalArgs) { 1382 Tree.AddNode(); 1383 1384 // Get the parameter at index TotalArgs. If index is larger 1385 // than the total number of parameters, then there is an 1386 // argument pack, so re-use the last parameter. 1387 unsigned FromParamIndex = std::min(TotalArgs, ParamsFrom->size() - 1); 1388 unsigned ToParamIndex = std::min(TotalArgs, ParamsTo->size() - 1); 1389 NamedDecl *FromParamND = ParamsFrom->getParam(FromParamIndex); 1390 NamedDecl *ToParamND = ParamsTo->getParam(ToParamIndex); 1391 1392 assert(FromParamND->getKind() == ToParamND->getKind() && 1393 "Parameter Decl are not the same kind."); 1394 1395 if (isa<TemplateTypeParmDecl>(FromParamND)) { 1396 DiffTypes(FromIter, ToIter); 1397 } else if (isa<TemplateTemplateParmDecl>(FromParamND)) { 1398 DiffTemplateTemplates(FromIter, ToIter); 1399 } else if (isa<NonTypeTemplateParmDecl>(FromParamND)) { 1400 NonTypeTemplateParmDecl *FromDefaultNonTypeDecl = 1401 cast<NonTypeTemplateParmDecl>(FromParamND); 1402 NonTypeTemplateParmDecl *ToDefaultNonTypeDecl = 1403 cast<NonTypeTemplateParmDecl>(ToParamND); 1404 DiffNonTypes(FromIter, ToIter, FromDefaultNonTypeDecl, 1405 ToDefaultNonTypeDecl); 1406 } else { 1407 llvm_unreachable("Unexpected Decl type."); 1408 } 1409 1410 ++FromIter; 1411 ++ToIter; 1412 Tree.Up(); 1413 } 1414 } 1415 1416 /// makeTemplateList - Dump every template alias into the vector. 1417 static void makeTemplateList( 1418 SmallVectorImpl<const TemplateSpecializationType *> &TemplateList, 1419 const TemplateSpecializationType *TST) { 1420 while (TST) { 1421 TemplateList.push_back(TST); 1422 if (!TST->isTypeAlias()) 1423 return; 1424 TST = TST->getAliasedType()->getAs<TemplateSpecializationType>(); 1425 } 1426 } 1427 1428 /// hasSameBaseTemplate - Returns true when the base templates are the same, 1429 /// even if the template arguments are not. 1430 static bool hasSameBaseTemplate(const TemplateSpecializationType *FromTST, 1431 const TemplateSpecializationType *ToTST) { 1432 return FromTST->getTemplateName().getAsTemplateDecl()->getCanonicalDecl() == 1433 ToTST->getTemplateName().getAsTemplateDecl()->getCanonicalDecl(); 1434 } 1435 1436 /// hasSameTemplate - Returns true if both types are specialized from the 1437 /// same template declaration. If they come from different template aliases, 1438 /// do a parallel ascension search to determine the highest template alias in 1439 /// common and set the arguments to them. 1440 static bool hasSameTemplate(const TemplateSpecializationType *&FromTST, 1441 const TemplateSpecializationType *&ToTST) { 1442 // Check the top templates if they are the same. 1443 if (hasSameBaseTemplate(FromTST, ToTST)) 1444 return true; 1445 1446 // Create vectors of template aliases. 1447 SmallVector<const TemplateSpecializationType*, 1> FromTemplateList, 1448 ToTemplateList; 1449 1450 makeTemplateList(FromTemplateList, FromTST); 1451 makeTemplateList(ToTemplateList, ToTST); 1452 1453 SmallVectorImpl<const TemplateSpecializationType *>::reverse_iterator 1454 FromIter = FromTemplateList.rbegin(), FromEnd = FromTemplateList.rend(), 1455 ToIter = ToTemplateList.rbegin(), ToEnd = ToTemplateList.rend(); 1456 1457 // Check if the lowest template types are the same. If not, return. 1458 if (!hasSameBaseTemplate(*FromIter, *ToIter)) 1459 return false; 1460 1461 // Begin searching up the template aliases. The bottom most template 1462 // matches so move up until one pair does not match. Use the template 1463 // right before that one. 1464 for (; FromIter != FromEnd && ToIter != ToEnd; ++FromIter, ++ToIter) { 1465 if (!hasSameBaseTemplate(*FromIter, *ToIter)) 1466 break; 1467 } 1468 1469 FromTST = FromIter[-1]; 1470 ToTST = ToIter[-1]; 1471 1472 return true; 1473 } 1474 1475 /// GetType - Retrieves the template type arguments, including default 1476 /// arguments. 1477 static QualType GetType(const TSTiterator &Iter) { 1478 if (!Iter.isEnd()) 1479 return Iter->getAsType(); 1480 if (Iter.hasDesugaredTA()) 1481 return Iter.getDesugaredTA().getAsType(); 1482 return QualType(); 1483 } 1484 1485 /// GetTemplateDecl - Retrieves the template template arguments, including 1486 /// default arguments. 1487 static TemplateDecl *GetTemplateDecl(const TSTiterator &Iter) { 1488 if (!Iter.isEnd()) 1489 return Iter->getAsTemplate().getAsTemplateDecl(); 1490 if (Iter.hasDesugaredTA()) 1491 return Iter.getDesugaredTA().getAsTemplate().getAsTemplateDecl(); 1492 return nullptr; 1493 } 1494 1495 /// IsEqualExpr - Returns true if the expressions are the same in regards to 1496 /// template arguments. These expressions are dependent, so profile them 1497 /// instead of trying to evaluate them. 1498 static bool IsEqualExpr(ASTContext &Context, Expr *FromExpr, Expr *ToExpr) { 1499 if (FromExpr == ToExpr) 1500 return true; 1501 1502 if (!FromExpr || !ToExpr) 1503 return false; 1504 1505 llvm::FoldingSetNodeID FromID, ToID; 1506 FromExpr->Profile(FromID, Context, true); 1507 ToExpr->Profile(ToID, Context, true); 1508 return FromID == ToID; 1509 } 1510 1511 // These functions converts the tree representation of the template 1512 // differences into the internal character vector. 1513 1514 /// TreeToString - Converts the Tree object into a character stream which 1515 /// will later be turned into the output string. 1516 void TreeToString(int Indent = 1) { 1517 if (PrintTree) { 1518 OS << '\n'; 1519 OS.indent(2 * Indent); 1520 ++Indent; 1521 } 1522 1523 // Handle cases where the difference is not templates with different 1524 // arguments. 1525 switch (Tree.GetKind()) { 1526 case DiffTree::Invalid: 1527 llvm_unreachable("Template diffing failed with bad DiffNode"); 1528 case DiffTree::Type: { 1529 QualType FromType, ToType; 1530 Tree.GetTypeDiff(FromType, ToType); 1531 PrintTypeNames(FromType, ToType, Tree.FromDefault(), Tree.ToDefault(), 1532 Tree.NodeIsSame()); 1533 return; 1534 } 1535 case DiffTree::Expression: { 1536 Expr *FromExpr, *ToExpr; 1537 Tree.GetExpressionDiff(FromExpr, ToExpr); 1538 PrintExpr(FromExpr, ToExpr, Tree.FromDefault(), Tree.ToDefault(), 1539 Tree.NodeIsSame()); 1540 return; 1541 } 1542 case DiffTree::TemplateTemplate: { 1543 TemplateDecl *FromTD, *ToTD; 1544 Tree.GetTemplateTemplateDiff(FromTD, ToTD); 1545 PrintTemplateTemplate(FromTD, ToTD, Tree.FromDefault(), 1546 Tree.ToDefault(), Tree.NodeIsSame()); 1547 return; 1548 } 1549 case DiffTree::Integer: { 1550 llvm::APSInt FromInt, ToInt; 1551 Expr *FromExpr, *ToExpr; 1552 bool IsValidFromInt, IsValidToInt; 1553 QualType FromIntType, ToIntType; 1554 Tree.GetIntegerDiff(FromInt, ToInt, IsValidFromInt, IsValidToInt, 1555 FromIntType, ToIntType, FromExpr, ToExpr); 1556 PrintAPSInt(FromInt, ToInt, IsValidFromInt, IsValidToInt, FromIntType, 1557 ToIntType, FromExpr, ToExpr, Tree.FromDefault(), 1558 Tree.ToDefault(), Tree.NodeIsSame()); 1559 return; 1560 } 1561 case DiffTree::Declaration: { 1562 ValueDecl *FromValueDecl, *ToValueDecl; 1563 bool FromAddressOf, ToAddressOf; 1564 bool FromNullPtr, ToNullPtr; 1565 Expr *FromExpr, *ToExpr; 1566 Tree.GetDeclarationDiff(FromValueDecl, ToValueDecl, FromAddressOf, 1567 ToAddressOf, FromNullPtr, ToNullPtr, FromExpr, 1568 ToExpr); 1569 PrintValueDecl(FromValueDecl, ToValueDecl, FromAddressOf, ToAddressOf, 1570 FromNullPtr, ToNullPtr, FromExpr, ToExpr, 1571 Tree.FromDefault(), Tree.ToDefault(), Tree.NodeIsSame()); 1572 return; 1573 } 1574 case DiffTree::FromDeclarationAndToInteger: { 1575 ValueDecl *FromValueDecl; 1576 bool FromAddressOf; 1577 bool FromNullPtr; 1578 Expr *FromExpr; 1579 llvm::APSInt ToInt; 1580 bool IsValidToInt; 1581 QualType ToIntType; 1582 Expr *ToExpr; 1583 Tree.GetFromDeclarationAndToIntegerDiff( 1584 FromValueDecl, FromAddressOf, FromNullPtr, FromExpr, ToInt, 1585 IsValidToInt, ToIntType, ToExpr); 1586 assert((FromValueDecl || FromNullPtr) && IsValidToInt); 1587 PrintValueDeclAndInteger(FromValueDecl, FromAddressOf, FromNullPtr, 1588 FromExpr, Tree.FromDefault(), ToInt, ToIntType, 1589 ToExpr, Tree.ToDefault()); 1590 return; 1591 } 1592 case DiffTree::FromIntegerAndToDeclaration: { 1593 llvm::APSInt FromInt; 1594 bool IsValidFromInt; 1595 QualType FromIntType; 1596 Expr *FromExpr; 1597 ValueDecl *ToValueDecl; 1598 bool ToAddressOf; 1599 bool ToNullPtr; 1600 Expr *ToExpr; 1601 Tree.GetFromIntegerAndToDeclarationDiff( 1602 FromInt, IsValidFromInt, FromIntType, FromExpr, ToValueDecl, 1603 ToAddressOf, ToNullPtr, ToExpr); 1604 assert(IsValidFromInt && (ToValueDecl || ToNullPtr)); 1605 PrintIntegerAndValueDecl(FromInt, FromIntType, FromExpr, 1606 Tree.FromDefault(), ToValueDecl, ToAddressOf, 1607 ToNullPtr, ToExpr, Tree.ToDefault()); 1608 return; 1609 } 1610 case DiffTree::Template: { 1611 // Node is root of template. Recurse on children. 1612 TemplateDecl *FromTD, *ToTD; 1613 Qualifiers FromQual, ToQual; 1614 Tree.GetTemplateDiff(FromTD, ToTD, FromQual, ToQual); 1615 1616 PrintQualifiers(FromQual, ToQual); 1617 1618 if (!Tree.HasChildren()) { 1619 // If we're dealing with a template specialization with zero 1620 // arguments, there are no children; special-case this. 1621 OS << FromTD->getDeclName() << "<>"; 1622 return; 1623 } 1624 1625 OS << FromTD->getDeclName() << '<'; 1626 Tree.MoveToChild(); 1627 unsigned NumElideArgs = 0; 1628 bool AllArgsElided = true; 1629 do { 1630 if (ElideType) { 1631 if (Tree.NodeIsSame()) { 1632 ++NumElideArgs; 1633 continue; 1634 } 1635 AllArgsElided = false; 1636 if (NumElideArgs > 0) { 1637 PrintElideArgs(NumElideArgs, Indent); 1638 NumElideArgs = 0; 1639 OS << ", "; 1640 } 1641 } 1642 TreeToString(Indent); 1643 if (Tree.HasNextSibling()) 1644 OS << ", "; 1645 } while (Tree.AdvanceSibling()); 1646 if (NumElideArgs > 0) { 1647 if (AllArgsElided) 1648 OS << "..."; 1649 else 1650 PrintElideArgs(NumElideArgs, Indent); 1651 } 1652 1653 Tree.Parent(); 1654 OS << ">"; 1655 return; 1656 } 1657 } 1658 } 1659 1660 // To signal to the text printer that a certain text needs to be bolded, 1661 // a special character is injected into the character stream which the 1662 // text printer will later strip out. 1663 1664 /// Bold - Start bolding text. 1665 void Bold() { 1666 assert(!IsBold && "Attempting to bold text that is already bold."); 1667 IsBold = true; 1668 if (ShowColor) 1669 OS << ToggleHighlight; 1670 } 1671 1672 /// Unbold - Stop bolding text. 1673 void Unbold() { 1674 assert(IsBold && "Attempting to remove bold from unbold text."); 1675 IsBold = false; 1676 if (ShowColor) 1677 OS << ToggleHighlight; 1678 } 1679 1680 // Functions to print out the arguments and highlighting the difference. 1681 1682 /// PrintTypeNames - prints the typenames, bolding differences. Will detect 1683 /// typenames that are the same and attempt to disambiguate them by using 1684 /// canonical typenames. 1685 void PrintTypeNames(QualType FromType, QualType ToType, 1686 bool FromDefault, bool ToDefault, bool Same) { 1687 assert((!FromType.isNull() || !ToType.isNull()) && 1688 "Only one template argument may be missing."); 1689 1690 if (Same) { 1691 OS << FromType.getAsString(Policy); 1692 return; 1693 } 1694 1695 if (!FromType.isNull() && !ToType.isNull() && 1696 FromType.getLocalUnqualifiedType() == 1697 ToType.getLocalUnqualifiedType()) { 1698 Qualifiers FromQual = FromType.getLocalQualifiers(), 1699 ToQual = ToType.getLocalQualifiers(); 1700 PrintQualifiers(FromQual, ToQual); 1701 FromType.getLocalUnqualifiedType().print(OS, Policy); 1702 return; 1703 } 1704 1705 std::string FromTypeStr = FromType.isNull() ? "(no argument)" 1706 : FromType.getAsString(Policy); 1707 std::string ToTypeStr = ToType.isNull() ? "(no argument)" 1708 : ToType.getAsString(Policy); 1709 // Print without ElaboratedType sugar if it is better. 1710 // TODO: merge this with other aka printing above. 1711 if (FromTypeStr == ToTypeStr) { 1712 const auto *FromElTy = dyn_cast<ElaboratedType>(FromType), 1713 *ToElTy = dyn_cast<ElaboratedType>(ToType); 1714 if (FromElTy || ToElTy) { 1715 std::string FromNamedTypeStr = 1716 FromElTy ? FromElTy->getNamedType().getAsString(Policy) 1717 : FromTypeStr; 1718 std::string ToNamedTypeStr = 1719 ToElTy ? ToElTy->getNamedType().getAsString(Policy) : ToTypeStr; 1720 if (FromNamedTypeStr != ToNamedTypeStr) { 1721 FromTypeStr = FromNamedTypeStr; 1722 ToTypeStr = ToNamedTypeStr; 1723 goto PrintTypes; 1724 } 1725 } 1726 // Switch to canonical typename if it is better. 1727 std::string FromCanTypeStr = 1728 FromType.getCanonicalType().getAsString(Policy); 1729 std::string ToCanTypeStr = ToType.getCanonicalType().getAsString(Policy); 1730 if (FromCanTypeStr != ToCanTypeStr) { 1731 FromTypeStr = FromCanTypeStr; 1732 ToTypeStr = ToCanTypeStr; 1733 } 1734 } 1735 1736 PrintTypes: 1737 if (PrintTree) OS << '['; 1738 OS << (FromDefault ? "(default) " : ""); 1739 Bold(); 1740 OS << FromTypeStr; 1741 Unbold(); 1742 if (PrintTree) { 1743 OS << " != " << (ToDefault ? "(default) " : ""); 1744 Bold(); 1745 OS << ToTypeStr; 1746 Unbold(); 1747 OS << "]"; 1748 } 1749 } 1750 1751 /// PrintExpr - Prints out the expr template arguments, highlighting argument 1752 /// differences. 1753 void PrintExpr(const Expr *FromExpr, const Expr *ToExpr, bool FromDefault, 1754 bool ToDefault, bool Same) { 1755 assert((FromExpr || ToExpr) && 1756 "Only one template argument may be missing."); 1757 if (Same) { 1758 PrintExpr(FromExpr); 1759 } else if (!PrintTree) { 1760 OS << (FromDefault ? "(default) " : ""); 1761 Bold(); 1762 PrintExpr(FromExpr); 1763 Unbold(); 1764 } else { 1765 OS << (FromDefault ? "[(default) " : "["); 1766 Bold(); 1767 PrintExpr(FromExpr); 1768 Unbold(); 1769 OS << " != " << (ToDefault ? "(default) " : ""); 1770 Bold(); 1771 PrintExpr(ToExpr); 1772 Unbold(); 1773 OS << ']'; 1774 } 1775 } 1776 1777 /// PrintExpr - Actual formatting and printing of expressions. 1778 void PrintExpr(const Expr *E) { 1779 if (E) { 1780 E->printPretty(OS, nullptr, Policy); 1781 return; 1782 } 1783 OS << "(no argument)"; 1784 } 1785 1786 /// PrintTemplateTemplate - Handles printing of template template arguments, 1787 /// highlighting argument differences. 1788 void PrintTemplateTemplate(TemplateDecl *FromTD, TemplateDecl *ToTD, 1789 bool FromDefault, bool ToDefault, bool Same) { 1790 assert((FromTD || ToTD) && "Only one template argument may be missing."); 1791 1792 std::string FromName = 1793 std::string(FromTD ? FromTD->getName() : "(no argument)"); 1794 std::string ToName = std::string(ToTD ? ToTD->getName() : "(no argument)"); 1795 if (FromTD && ToTD && FromName == ToName) { 1796 FromName = FromTD->getQualifiedNameAsString(); 1797 ToName = ToTD->getQualifiedNameAsString(); 1798 } 1799 1800 if (Same) { 1801 OS << "template " << FromTD->getDeclName(); 1802 } else if (!PrintTree) { 1803 OS << (FromDefault ? "(default) template " : "template "); 1804 Bold(); 1805 OS << FromName; 1806 Unbold(); 1807 } else { 1808 OS << (FromDefault ? "[(default) template " : "[template "); 1809 Bold(); 1810 OS << FromName; 1811 Unbold(); 1812 OS << " != " << (ToDefault ? "(default) template " : "template "); 1813 Bold(); 1814 OS << ToName; 1815 Unbold(); 1816 OS << ']'; 1817 } 1818 } 1819 1820 /// PrintAPSInt - Handles printing of integral arguments, highlighting 1821 /// argument differences. 1822 void PrintAPSInt(const llvm::APSInt &FromInt, const llvm::APSInt &ToInt, 1823 bool IsValidFromInt, bool IsValidToInt, QualType FromIntType, 1824 QualType ToIntType, Expr *FromExpr, Expr *ToExpr, 1825 bool FromDefault, bool ToDefault, bool Same) { 1826 assert((IsValidFromInt || IsValidToInt) && 1827 "Only one integral argument may be missing."); 1828 1829 if (Same) { 1830 if (FromIntType->isBooleanType()) { 1831 OS << ((FromInt == 0) ? "false" : "true"); 1832 } else { 1833 OS << toString(FromInt, 10); 1834 } 1835 return; 1836 } 1837 1838 bool PrintType = IsValidFromInt && IsValidToInt && 1839 !Context.hasSameType(FromIntType, ToIntType); 1840 1841 if (!PrintTree) { 1842 OS << (FromDefault ? "(default) " : ""); 1843 PrintAPSInt(FromInt, FromExpr, IsValidFromInt, FromIntType, PrintType); 1844 } else { 1845 OS << (FromDefault ? "[(default) " : "["); 1846 PrintAPSInt(FromInt, FromExpr, IsValidFromInt, FromIntType, PrintType); 1847 OS << " != " << (ToDefault ? "(default) " : ""); 1848 PrintAPSInt(ToInt, ToExpr, IsValidToInt, ToIntType, PrintType); 1849 OS << ']'; 1850 } 1851 } 1852 1853 /// PrintAPSInt - If valid, print the APSInt. If the expression is 1854 /// gives more information, print it too. 1855 void PrintAPSInt(const llvm::APSInt &Val, Expr *E, bool Valid, 1856 QualType IntType, bool PrintType) { 1857 Bold(); 1858 if (Valid) { 1859 if (HasExtraInfo(E)) { 1860 PrintExpr(E); 1861 Unbold(); 1862 OS << " aka "; 1863 Bold(); 1864 } 1865 if (PrintType) { 1866 Unbold(); 1867 OS << "("; 1868 Bold(); 1869 IntType.print(OS, Context.getPrintingPolicy()); 1870 Unbold(); 1871 OS << ") "; 1872 Bold(); 1873 } 1874 if (IntType->isBooleanType()) { 1875 OS << ((Val == 0) ? "false" : "true"); 1876 } else { 1877 OS << toString(Val, 10); 1878 } 1879 } else if (E) { 1880 PrintExpr(E); 1881 } else { 1882 OS << "(no argument)"; 1883 } 1884 Unbold(); 1885 } 1886 1887 /// HasExtraInfo - Returns true if E is not an integer literal, the 1888 /// negation of an integer literal, or a boolean literal. 1889 bool HasExtraInfo(Expr *E) { 1890 if (!E) return false; 1891 1892 E = E->IgnoreImpCasts(); 1893 1894 if (isa<IntegerLiteral>(E)) return false; 1895 1896 if (UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) 1897 if (UO->getOpcode() == UO_Minus) 1898 if (isa<IntegerLiteral>(UO->getSubExpr())) 1899 return false; 1900 1901 if (isa<CXXBoolLiteralExpr>(E)) 1902 return false; 1903 1904 return true; 1905 } 1906 1907 void PrintValueDecl(ValueDecl *VD, bool AddressOf, Expr *E, bool NullPtr) { 1908 if (VD) { 1909 if (AddressOf) 1910 OS << "&"; 1911 else if (auto *TPO = dyn_cast<TemplateParamObjectDecl>(VD)) { 1912 // FIXME: Diffing the APValue would be neat. 1913 // FIXME: Suppress this and use the full name of the declaration if the 1914 // parameter is a pointer or reference. 1915 TPO->getType().getUnqualifiedType().print(OS, Policy); 1916 TPO->printAsInit(OS, Policy); 1917 return; 1918 } 1919 VD->printName(OS, Policy); 1920 return; 1921 } 1922 1923 if (NullPtr) { 1924 if (E && !isa<CXXNullPtrLiteralExpr>(E)) { 1925 PrintExpr(E); 1926 if (IsBold) { 1927 Unbold(); 1928 OS << " aka "; 1929 Bold(); 1930 } else { 1931 OS << " aka "; 1932 } 1933 } 1934 1935 OS << "nullptr"; 1936 return; 1937 } 1938 1939 if (E) { 1940 PrintExpr(E); 1941 return; 1942 } 1943 1944 OS << "(no argument)"; 1945 } 1946 1947 /// PrintDecl - Handles printing of Decl arguments, highlighting 1948 /// argument differences. 1949 void PrintValueDecl(ValueDecl *FromValueDecl, ValueDecl *ToValueDecl, 1950 bool FromAddressOf, bool ToAddressOf, bool FromNullPtr, 1951 bool ToNullPtr, Expr *FromExpr, Expr *ToExpr, 1952 bool FromDefault, bool ToDefault, bool Same) { 1953 assert((FromValueDecl || FromNullPtr || ToValueDecl || ToNullPtr) && 1954 "Only one Decl argument may be NULL"); 1955 1956 if (Same) { 1957 PrintValueDecl(FromValueDecl, FromAddressOf, FromExpr, FromNullPtr); 1958 } else if (!PrintTree) { 1959 OS << (FromDefault ? "(default) " : ""); 1960 Bold(); 1961 PrintValueDecl(FromValueDecl, FromAddressOf, FromExpr, FromNullPtr); 1962 Unbold(); 1963 } else { 1964 OS << (FromDefault ? "[(default) " : "["); 1965 Bold(); 1966 PrintValueDecl(FromValueDecl, FromAddressOf, FromExpr, FromNullPtr); 1967 Unbold(); 1968 OS << " != " << (ToDefault ? "(default) " : ""); 1969 Bold(); 1970 PrintValueDecl(ToValueDecl, ToAddressOf, ToExpr, ToNullPtr); 1971 Unbold(); 1972 OS << ']'; 1973 } 1974 } 1975 1976 /// PrintValueDeclAndInteger - Uses the print functions for ValueDecl and 1977 /// APSInt to print a mixed difference. 1978 void PrintValueDeclAndInteger(ValueDecl *VD, bool NeedAddressOf, 1979 bool IsNullPtr, Expr *VDExpr, bool DefaultDecl, 1980 const llvm::APSInt &Val, QualType IntType, 1981 Expr *IntExpr, bool DefaultInt) { 1982 if (!PrintTree) { 1983 OS << (DefaultDecl ? "(default) " : ""); 1984 Bold(); 1985 PrintValueDecl(VD, NeedAddressOf, VDExpr, IsNullPtr); 1986 Unbold(); 1987 } else { 1988 OS << (DefaultDecl ? "[(default) " : "["); 1989 Bold(); 1990 PrintValueDecl(VD, NeedAddressOf, VDExpr, IsNullPtr); 1991 Unbold(); 1992 OS << " != " << (DefaultInt ? "(default) " : ""); 1993 PrintAPSInt(Val, IntExpr, true /*Valid*/, IntType, false /*PrintType*/); 1994 OS << ']'; 1995 } 1996 } 1997 1998 /// PrintIntegerAndValueDecl - Uses the print functions for APSInt and 1999 /// ValueDecl to print a mixed difference. 2000 void PrintIntegerAndValueDecl(const llvm::APSInt &Val, QualType IntType, 2001 Expr *IntExpr, bool DefaultInt, ValueDecl *VD, 2002 bool NeedAddressOf, bool IsNullPtr, 2003 Expr *VDExpr, bool DefaultDecl) { 2004 if (!PrintTree) { 2005 OS << (DefaultInt ? "(default) " : ""); 2006 PrintAPSInt(Val, IntExpr, true /*Valid*/, IntType, false /*PrintType*/); 2007 } else { 2008 OS << (DefaultInt ? "[(default) " : "["); 2009 PrintAPSInt(Val, IntExpr, true /*Valid*/, IntType, false /*PrintType*/); 2010 OS << " != " << (DefaultDecl ? "(default) " : ""); 2011 Bold(); 2012 PrintValueDecl(VD, NeedAddressOf, VDExpr, IsNullPtr); 2013 Unbold(); 2014 OS << ']'; 2015 } 2016 } 2017 2018 // Prints the appropriate placeholder for elided template arguments. 2019 void PrintElideArgs(unsigned NumElideArgs, unsigned Indent) { 2020 if (PrintTree) { 2021 OS << '\n'; 2022 for (unsigned i = 0; i < Indent; ++i) 2023 OS << " "; 2024 } 2025 if (NumElideArgs == 0) return; 2026 if (NumElideArgs == 1) 2027 OS << "[...]"; 2028 else 2029 OS << "[" << NumElideArgs << " * ...]"; 2030 } 2031 2032 // Prints and highlights differences in Qualifiers. 2033 void PrintQualifiers(Qualifiers FromQual, Qualifiers ToQual) { 2034 // Both types have no qualifiers 2035 if (FromQual.empty() && ToQual.empty()) 2036 return; 2037 2038 // Both types have same qualifiers 2039 if (FromQual == ToQual) { 2040 PrintQualifier(FromQual, /*ApplyBold*/false); 2041 return; 2042 } 2043 2044 // Find common qualifiers and strip them from FromQual and ToQual. 2045 Qualifiers CommonQual = Qualifiers::removeCommonQualifiers(FromQual, 2046 ToQual); 2047 2048 // The qualifiers are printed before the template name. 2049 // Inline printing: 2050 // The common qualifiers are printed. Then, qualifiers only in this type 2051 // are printed and highlighted. Finally, qualifiers only in the other 2052 // type are printed and highlighted inside parentheses after "missing". 2053 // Tree printing: 2054 // Qualifiers are printed next to each other, inside brackets, and 2055 // separated by "!=". The printing order is: 2056 // common qualifiers, highlighted from qualifiers, "!=", 2057 // common qualifiers, highlighted to qualifiers 2058 if (PrintTree) { 2059 OS << "["; 2060 if (CommonQual.empty() && FromQual.empty()) { 2061 Bold(); 2062 OS << "(no qualifiers) "; 2063 Unbold(); 2064 } else { 2065 PrintQualifier(CommonQual, /*ApplyBold*/false); 2066 PrintQualifier(FromQual, /*ApplyBold*/true); 2067 } 2068 OS << "!= "; 2069 if (CommonQual.empty() && ToQual.empty()) { 2070 Bold(); 2071 OS << "(no qualifiers)"; 2072 Unbold(); 2073 } else { 2074 PrintQualifier(CommonQual, /*ApplyBold*/false, 2075 /*appendSpaceIfNonEmpty*/!ToQual.empty()); 2076 PrintQualifier(ToQual, /*ApplyBold*/true, 2077 /*appendSpaceIfNonEmpty*/false); 2078 } 2079 OS << "] "; 2080 } else { 2081 PrintQualifier(CommonQual, /*ApplyBold*/false); 2082 PrintQualifier(FromQual, /*ApplyBold*/true); 2083 } 2084 } 2085 2086 void PrintQualifier(Qualifiers Q, bool ApplyBold, 2087 bool AppendSpaceIfNonEmpty = true) { 2088 if (Q.empty()) return; 2089 if (ApplyBold) Bold(); 2090 Q.print(OS, Policy, AppendSpaceIfNonEmpty); 2091 if (ApplyBold) Unbold(); 2092 } 2093 2094 public: 2095 2096 TemplateDiff(raw_ostream &OS, ASTContext &Context, QualType FromType, 2097 QualType ToType, bool PrintTree, bool PrintFromType, 2098 bool ElideType, bool ShowColor) 2099 : Context(Context), 2100 Policy(Context.getLangOpts()), 2101 ElideType(ElideType), 2102 PrintTree(PrintTree), 2103 ShowColor(ShowColor), 2104 // When printing a single type, the FromType is the one printed. 2105 FromTemplateType(PrintFromType ? FromType : ToType), 2106 ToTemplateType(PrintFromType ? ToType : FromType), 2107 OS(OS), 2108 IsBold(false) { 2109 } 2110 2111 /// DiffTemplate - Start the template type diffing. 2112 void DiffTemplate() { 2113 Qualifiers FromQual = FromTemplateType.getQualifiers(), 2114 ToQual = ToTemplateType.getQualifiers(); 2115 2116 const TemplateSpecializationType *FromOrigTST = 2117 GetTemplateSpecializationType(Context, FromTemplateType); 2118 const TemplateSpecializationType *ToOrigTST = 2119 GetTemplateSpecializationType(Context, ToTemplateType); 2120 2121 // Only checking templates. 2122 if (!FromOrigTST || !ToOrigTST) 2123 return; 2124 2125 // Different base templates. 2126 if (!hasSameTemplate(FromOrigTST, ToOrigTST)) { 2127 return; 2128 } 2129 2130 FromQual -= QualType(FromOrigTST, 0).getQualifiers(); 2131 ToQual -= QualType(ToOrigTST, 0).getQualifiers(); 2132 2133 // Same base template, but different arguments. 2134 Tree.SetTemplateDiff(FromOrigTST->getTemplateName().getAsTemplateDecl(), 2135 ToOrigTST->getTemplateName().getAsTemplateDecl(), 2136 FromQual, ToQual, false /*FromDefault*/, 2137 false /*ToDefault*/); 2138 2139 DiffTemplate(FromOrigTST, ToOrigTST); 2140 } 2141 2142 /// Emit - When the two types given are templated types with the same 2143 /// base template, a string representation of the type difference will be 2144 /// emitted to the stream and return true. Otherwise, return false. 2145 bool Emit() { 2146 Tree.StartTraverse(); 2147 if (Tree.Empty()) 2148 return false; 2149 2150 TreeToString(); 2151 assert(!IsBold && "Bold is applied to end of string."); 2152 return true; 2153 } 2154 }; // end class TemplateDiff 2155 } // end anonymous namespace 2156 2157 /// FormatTemplateTypeDiff - A helper static function to start the template 2158 /// diff and return the properly formatted string. Returns true if the diff 2159 /// is successful. 2160 static bool FormatTemplateTypeDiff(ASTContext &Context, QualType FromType, 2161 QualType ToType, bool PrintTree, 2162 bool PrintFromType, bool ElideType, 2163 bool ShowColors, raw_ostream &OS) { 2164 if (PrintTree) 2165 PrintFromType = true; 2166 TemplateDiff TD(OS, Context, FromType, ToType, PrintTree, PrintFromType, 2167 ElideType, ShowColors); 2168 TD.DiffTemplate(); 2169 return TD.Emit(); 2170 } 2171