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