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