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 const RecordType *RT = Ty->getAs<RecordType>(); 1092 1093 if (!RT) 1094 return nullptr; 1095 1096 const ClassTemplateSpecializationDecl *CTSD = 1097 dyn_cast<ClassTemplateSpecializationDecl>(RT->getDecl()); 1098 1099 if (!CTSD) 1100 return nullptr; 1101 1102 Ty = Context.getTemplateSpecializationType( 1103 TemplateName(CTSD->getSpecializedTemplate()), 1104 CTSD->getTemplateArgs().asArray(), 1105 Ty.getLocalUnqualifiedType().getCanonicalType()); 1106 1107 return Ty->getAs<TemplateSpecializationType>(); 1108 } 1109 1110 /// Returns true if the DiffType is Type and false for Template. 1111 static bool OnlyPerformTypeDiff(ASTContext &Context, QualType FromType, 1112 QualType ToType, 1113 const TemplateSpecializationType *&FromArgTST, 1114 const TemplateSpecializationType *&ToArgTST) { 1115 if (FromType.isNull() || ToType.isNull()) 1116 return true; 1117 1118 if (Context.hasSameType(FromType, ToType)) 1119 return true; 1120 1121 FromArgTST = GetTemplateSpecializationType(Context, FromType); 1122 ToArgTST = GetTemplateSpecializationType(Context, ToType); 1123 1124 if (!FromArgTST || !ToArgTST) 1125 return true; 1126 1127 if (!hasSameTemplate(FromArgTST, ToArgTST)) 1128 return true; 1129 1130 return false; 1131 } 1132 1133 /// DiffTypes - Fills a DiffNode with information about a type difference. 1134 void DiffTypes(const TSTiterator &FromIter, const TSTiterator &ToIter) { 1135 QualType FromType = GetType(FromIter); 1136 QualType ToType = GetType(ToIter); 1137 1138 bool FromDefault = FromIter.isEnd() && !FromType.isNull(); 1139 bool ToDefault = ToIter.isEnd() && !ToType.isNull(); 1140 1141 const TemplateSpecializationType *FromArgTST = nullptr; 1142 const TemplateSpecializationType *ToArgTST = nullptr; 1143 if (OnlyPerformTypeDiff(Context, FromType, ToType, FromArgTST, ToArgTST)) { 1144 Tree.SetTypeDiff(FromType, ToType, FromDefault, ToDefault); 1145 Tree.SetSame(!FromType.isNull() && !ToType.isNull() && 1146 Context.hasSameType(FromType, ToType)); 1147 } else { 1148 assert(FromArgTST && ToArgTST && 1149 "Both template specializations need to be valid."); 1150 Qualifiers FromQual = FromType.getQualifiers(), 1151 ToQual = ToType.getQualifiers(); 1152 FromQual -= QualType(FromArgTST, 0).getQualifiers(); 1153 ToQual -= QualType(ToArgTST, 0).getQualifiers(); 1154 Tree.SetTemplateDiff(FromArgTST->getTemplateName().getAsTemplateDecl(), 1155 ToArgTST->getTemplateName().getAsTemplateDecl(), 1156 FromQual, ToQual, FromDefault, ToDefault); 1157 DiffTemplate(FromArgTST, ToArgTST); 1158 } 1159 } 1160 1161 /// DiffTemplateTemplates - Fills a DiffNode with information about a 1162 /// template template difference. 1163 void DiffTemplateTemplates(const TSTiterator &FromIter, 1164 const TSTiterator &ToIter) { 1165 TemplateDecl *FromDecl = GetTemplateDecl(FromIter); 1166 TemplateDecl *ToDecl = GetTemplateDecl(ToIter); 1167 Tree.SetTemplateTemplateDiff(FromDecl, ToDecl, FromIter.isEnd() && FromDecl, 1168 ToIter.isEnd() && ToDecl); 1169 Tree.SetSame(FromDecl && ToDecl && 1170 FromDecl->getCanonicalDecl() == ToDecl->getCanonicalDecl()); 1171 } 1172 1173 /// InitializeNonTypeDiffVariables - Helper function for DiffNonTypes 1174 static void InitializeNonTypeDiffVariables(ASTContext &Context, 1175 const TSTiterator &Iter, 1176 NonTypeTemplateParmDecl *Default, 1177 llvm::APSInt &Value, bool &HasInt, 1178 QualType &IntType, bool &IsNullPtr, 1179 Expr *&E, ValueDecl *&VD, 1180 bool &NeedAddressOf) { 1181 if (!Iter.isEnd()) { 1182 switch (Iter->getKind()) { 1183 default: 1184 llvm_unreachable("unknown ArgumentKind"); 1185 case TemplateArgument::Integral: 1186 Value = Iter->getAsIntegral(); 1187 HasInt = true; 1188 IntType = Iter->getIntegralType(); 1189 return; 1190 case TemplateArgument::Declaration: { 1191 VD = Iter->getAsDecl(); 1192 QualType ArgType = Iter->getParamTypeForDecl(); 1193 QualType VDType = VD->getType(); 1194 if (ArgType->isPointerType() && 1195 Context.hasSameType(ArgType->getPointeeType(), VDType)) 1196 NeedAddressOf = true; 1197 return; 1198 } 1199 case TemplateArgument::NullPtr: 1200 IsNullPtr = true; 1201 return; 1202 case TemplateArgument::Expression: 1203 E = Iter->getAsExpr(); 1204 } 1205 } else if (!Default->isParameterPack()) { 1206 E = Default->getDefaultArgument(); 1207 } 1208 1209 if (!Iter.hasDesugaredTA()) return; 1210 1211 const TemplateArgument& TA = Iter.getDesugaredTA(); 1212 switch (TA.getKind()) { 1213 default: 1214 llvm_unreachable("unknown ArgumentKind"); 1215 case TemplateArgument::Integral: 1216 Value = TA.getAsIntegral(); 1217 HasInt = true; 1218 IntType = TA.getIntegralType(); 1219 return; 1220 case TemplateArgument::Declaration: { 1221 VD = TA.getAsDecl(); 1222 QualType ArgType = TA.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 // TODO: Sometimes, the desugared template argument Expr differs from 1234 // the sugared template argument Expr. It may be useful in the future 1235 // but for now, it is just discarded. 1236 if (!E) 1237 E = TA.getAsExpr(); 1238 return; 1239 } 1240 } 1241 1242 /// DiffNonTypes - Handles any template parameters not handled by DiffTypes 1243 /// of DiffTemplatesTemplates, such as integer and declaration parameters. 1244 void DiffNonTypes(const TSTiterator &FromIter, const TSTiterator &ToIter, 1245 NonTypeTemplateParmDecl *FromDefaultNonTypeDecl, 1246 NonTypeTemplateParmDecl *ToDefaultNonTypeDecl) { 1247 Expr *FromExpr = nullptr, *ToExpr = nullptr; 1248 llvm::APSInt FromInt, ToInt; 1249 QualType FromIntType, ToIntType; 1250 ValueDecl *FromValueDecl = nullptr, *ToValueDecl = nullptr; 1251 bool HasFromInt = false, HasToInt = false, FromNullPtr = false, 1252 ToNullPtr = false, NeedFromAddressOf = false, NeedToAddressOf = false; 1253 InitializeNonTypeDiffVariables( 1254 Context, FromIter, FromDefaultNonTypeDecl, FromInt, HasFromInt, 1255 FromIntType, FromNullPtr, FromExpr, FromValueDecl, NeedFromAddressOf); 1256 InitializeNonTypeDiffVariables(Context, ToIter, ToDefaultNonTypeDecl, ToInt, 1257 HasToInt, ToIntType, ToNullPtr, ToExpr, 1258 ToValueDecl, NeedToAddressOf); 1259 1260 bool FromDefault = FromIter.isEnd() && 1261 (FromExpr || FromValueDecl || HasFromInt || FromNullPtr); 1262 bool ToDefault = ToIter.isEnd() && 1263 (ToExpr || ToValueDecl || HasToInt || ToNullPtr); 1264 1265 bool FromDeclaration = FromValueDecl || FromNullPtr; 1266 bool ToDeclaration = ToValueDecl || ToNullPtr; 1267 1268 if (FromDeclaration && HasToInt) { 1269 Tree.SetFromDeclarationAndToIntegerDiff( 1270 FromValueDecl, NeedFromAddressOf, FromNullPtr, FromExpr, ToInt, 1271 HasToInt, ToIntType, ToExpr, FromDefault, ToDefault); 1272 Tree.SetSame(false); 1273 return; 1274 1275 } 1276 1277 if (HasFromInt && ToDeclaration) { 1278 Tree.SetFromIntegerAndToDeclarationDiff( 1279 FromInt, HasFromInt, FromIntType, FromExpr, ToValueDecl, 1280 NeedToAddressOf, ToNullPtr, ToExpr, FromDefault, ToDefault); 1281 Tree.SetSame(false); 1282 return; 1283 } 1284 1285 if (HasFromInt || HasToInt) { 1286 Tree.SetIntegerDiff(FromInt, ToInt, HasFromInt, HasToInt, FromIntType, 1287 ToIntType, FromExpr, ToExpr, FromDefault, ToDefault); 1288 if (HasFromInt && HasToInt) { 1289 Tree.SetSame(Context.hasSameType(FromIntType, ToIntType) && 1290 FromInt == ToInt); 1291 } 1292 return; 1293 } 1294 1295 if (FromDeclaration || ToDeclaration) { 1296 Tree.SetDeclarationDiff(FromValueDecl, ToValueDecl, NeedFromAddressOf, 1297 NeedToAddressOf, FromNullPtr, ToNullPtr, FromExpr, 1298 ToExpr, FromDefault, ToDefault); 1299 bool BothNull = FromNullPtr && ToNullPtr; 1300 bool SameValueDecl = 1301 FromValueDecl && ToValueDecl && 1302 NeedFromAddressOf == NeedToAddressOf && 1303 FromValueDecl->getCanonicalDecl() == ToValueDecl->getCanonicalDecl(); 1304 Tree.SetSame(BothNull || SameValueDecl); 1305 return; 1306 } 1307 1308 assert((FromExpr || ToExpr) && "Both template arguments cannot be empty."); 1309 Tree.SetExpressionDiff(FromExpr, ToExpr, FromDefault, ToDefault); 1310 Tree.SetSame(IsEqualExpr(Context, FromExpr, ToExpr)); 1311 } 1312 1313 /// DiffTemplate - recursively visits template arguments and stores the 1314 /// argument info into a tree. 1315 void DiffTemplate(const TemplateSpecializationType *FromTST, 1316 const TemplateSpecializationType *ToTST) { 1317 // Begin descent into diffing template tree. 1318 TemplateParameterList *ParamsFrom = 1319 FromTST->getTemplateName().getAsTemplateDecl()->getTemplateParameters(); 1320 TemplateParameterList *ParamsTo = 1321 ToTST->getTemplateName().getAsTemplateDecl()->getTemplateParameters(); 1322 unsigned TotalArgs = 0; 1323 for (TSTiterator FromIter(Context, FromTST), ToIter(Context, ToTST); 1324 !FromIter.isEnd() || !ToIter.isEnd(); ++TotalArgs) { 1325 Tree.AddNode(); 1326 1327 // Get the parameter at index TotalArgs. If index is larger 1328 // than the total number of parameters, then there is an 1329 // argument pack, so re-use the last parameter. 1330 unsigned FromParamIndex = std::min(TotalArgs, ParamsFrom->size() - 1); 1331 unsigned ToParamIndex = std::min(TotalArgs, ParamsTo->size() - 1); 1332 NamedDecl *FromParamND = ParamsFrom->getParam(FromParamIndex); 1333 NamedDecl *ToParamND = ParamsTo->getParam(ToParamIndex); 1334 1335 assert(FromParamND->getKind() == ToParamND->getKind() && 1336 "Parameter Decl are not the same kind."); 1337 1338 if (isa<TemplateTypeParmDecl>(FromParamND)) { 1339 DiffTypes(FromIter, ToIter); 1340 } else if (isa<TemplateTemplateParmDecl>(FromParamND)) { 1341 DiffTemplateTemplates(FromIter, ToIter); 1342 } else if (isa<NonTypeTemplateParmDecl>(FromParamND)) { 1343 NonTypeTemplateParmDecl *FromDefaultNonTypeDecl = 1344 cast<NonTypeTemplateParmDecl>(FromParamND); 1345 NonTypeTemplateParmDecl *ToDefaultNonTypeDecl = 1346 cast<NonTypeTemplateParmDecl>(ToParamND); 1347 DiffNonTypes(FromIter, ToIter, FromDefaultNonTypeDecl, 1348 ToDefaultNonTypeDecl); 1349 } else { 1350 llvm_unreachable("Unexpected Decl type."); 1351 } 1352 1353 ++FromIter; 1354 ++ToIter; 1355 Tree.Up(); 1356 } 1357 } 1358 1359 /// makeTemplateList - Dump every template alias into the vector. 1360 static void makeTemplateList( 1361 SmallVectorImpl<const TemplateSpecializationType *> &TemplateList, 1362 const TemplateSpecializationType *TST) { 1363 while (TST) { 1364 TemplateList.push_back(TST); 1365 if (!TST->isTypeAlias()) 1366 return; 1367 TST = TST->getAliasedType()->getAs<TemplateSpecializationType>(); 1368 } 1369 } 1370 1371 /// hasSameBaseTemplate - Returns true when the base templates are the same, 1372 /// even if the template arguments are not. 1373 static bool hasSameBaseTemplate(const TemplateSpecializationType *FromTST, 1374 const TemplateSpecializationType *ToTST) { 1375 return FromTST->getTemplateName().getAsTemplateDecl()->getCanonicalDecl() == 1376 ToTST->getTemplateName().getAsTemplateDecl()->getCanonicalDecl(); 1377 } 1378 1379 /// hasSameTemplate - Returns true if both types are specialized from the 1380 /// same template declaration. If they come from different template aliases, 1381 /// do a parallel ascension search to determine the highest template alias in 1382 /// common and set the arguments to them. 1383 static bool hasSameTemplate(const TemplateSpecializationType *&FromTST, 1384 const TemplateSpecializationType *&ToTST) { 1385 // Check the top templates if they are the same. 1386 if (hasSameBaseTemplate(FromTST, ToTST)) 1387 return true; 1388 1389 // Create vectors of template aliases. 1390 SmallVector<const TemplateSpecializationType*, 1> FromTemplateList, 1391 ToTemplateList; 1392 1393 makeTemplateList(FromTemplateList, FromTST); 1394 makeTemplateList(ToTemplateList, ToTST); 1395 1396 SmallVectorImpl<const TemplateSpecializationType *>::reverse_iterator 1397 FromIter = FromTemplateList.rbegin(), FromEnd = FromTemplateList.rend(), 1398 ToIter = ToTemplateList.rbegin(), ToEnd = ToTemplateList.rend(); 1399 1400 // Check if the lowest template types are the same. If not, return. 1401 if (!hasSameBaseTemplate(*FromIter, *ToIter)) 1402 return false; 1403 1404 // Begin searching up the template aliases. The bottom most template 1405 // matches so move up until one pair does not match. Use the template 1406 // right before that one. 1407 for (; FromIter != FromEnd && ToIter != ToEnd; ++FromIter, ++ToIter) { 1408 if (!hasSameBaseTemplate(*FromIter, *ToIter)) 1409 break; 1410 } 1411 1412 FromTST = FromIter[-1]; 1413 ToTST = ToIter[-1]; 1414 1415 return true; 1416 } 1417 1418 /// GetType - Retrieves the template type arguments, including default 1419 /// arguments. 1420 static QualType GetType(const TSTiterator &Iter) { 1421 if (!Iter.isEnd()) 1422 return Iter->getAsType(); 1423 if (Iter.hasDesugaredTA()) 1424 return Iter.getDesugaredTA().getAsType(); 1425 return QualType(); 1426 } 1427 1428 /// GetTemplateDecl - Retrieves the template template arguments, including 1429 /// default arguments. 1430 static TemplateDecl *GetTemplateDecl(const TSTiterator &Iter) { 1431 if (!Iter.isEnd()) 1432 return Iter->getAsTemplate().getAsTemplateDecl(); 1433 if (Iter.hasDesugaredTA()) 1434 return Iter.getDesugaredTA().getAsTemplate().getAsTemplateDecl(); 1435 return nullptr; 1436 } 1437 1438 /// IsEqualExpr - Returns true if the expressions are the same in regards to 1439 /// template arguments. These expressions are dependent, so profile them 1440 /// instead of trying to evaluate them. 1441 static bool IsEqualExpr(ASTContext &Context, Expr *FromExpr, Expr *ToExpr) { 1442 if (FromExpr == ToExpr) 1443 return true; 1444 1445 if (!FromExpr || !ToExpr) 1446 return false; 1447 1448 llvm::FoldingSetNodeID FromID, ToID; 1449 FromExpr->Profile(FromID, Context, true); 1450 ToExpr->Profile(ToID, Context, true); 1451 return FromID == ToID; 1452 } 1453 1454 // These functions converts the tree representation of the template 1455 // differences into the internal character vector. 1456 1457 /// TreeToString - Converts the Tree object into a character stream which 1458 /// will later be turned into the output string. 1459 void TreeToString(int Indent = 1) { 1460 if (PrintTree) { 1461 OS << '\n'; 1462 OS.indent(2 * Indent); 1463 ++Indent; 1464 } 1465 1466 // Handle cases where the difference is not templates with different 1467 // arguments. 1468 switch (Tree.GetKind()) { 1469 case DiffTree::Invalid: 1470 llvm_unreachable("Template diffing failed with bad DiffNode"); 1471 case DiffTree::Type: { 1472 QualType FromType, ToType; 1473 Tree.GetTypeDiff(FromType, ToType); 1474 PrintTypeNames(FromType, ToType, Tree.FromDefault(), Tree.ToDefault(), 1475 Tree.NodeIsSame()); 1476 return; 1477 } 1478 case DiffTree::Expression: { 1479 Expr *FromExpr, *ToExpr; 1480 Tree.GetExpressionDiff(FromExpr, ToExpr); 1481 PrintExpr(FromExpr, ToExpr, Tree.FromDefault(), Tree.ToDefault(), 1482 Tree.NodeIsSame()); 1483 return; 1484 } 1485 case DiffTree::TemplateTemplate: { 1486 TemplateDecl *FromTD, *ToTD; 1487 Tree.GetTemplateTemplateDiff(FromTD, ToTD); 1488 PrintTemplateTemplate(FromTD, ToTD, Tree.FromDefault(), 1489 Tree.ToDefault(), Tree.NodeIsSame()); 1490 return; 1491 } 1492 case DiffTree::Integer: { 1493 llvm::APSInt FromInt, ToInt; 1494 Expr *FromExpr, *ToExpr; 1495 bool IsValidFromInt, IsValidToInt; 1496 QualType FromIntType, ToIntType; 1497 Tree.GetIntegerDiff(FromInt, ToInt, IsValidFromInt, IsValidToInt, 1498 FromIntType, ToIntType, FromExpr, ToExpr); 1499 PrintAPSInt(FromInt, ToInt, IsValidFromInt, IsValidToInt, FromIntType, 1500 ToIntType, FromExpr, ToExpr, Tree.FromDefault(), 1501 Tree.ToDefault(), Tree.NodeIsSame()); 1502 return; 1503 } 1504 case DiffTree::Declaration: { 1505 ValueDecl *FromValueDecl, *ToValueDecl; 1506 bool FromAddressOf, ToAddressOf; 1507 bool FromNullPtr, ToNullPtr; 1508 Expr *FromExpr, *ToExpr; 1509 Tree.GetDeclarationDiff(FromValueDecl, ToValueDecl, FromAddressOf, 1510 ToAddressOf, FromNullPtr, ToNullPtr, FromExpr, 1511 ToExpr); 1512 PrintValueDecl(FromValueDecl, ToValueDecl, FromAddressOf, ToAddressOf, 1513 FromNullPtr, ToNullPtr, FromExpr, ToExpr, 1514 Tree.FromDefault(), Tree.ToDefault(), Tree.NodeIsSame()); 1515 return; 1516 } 1517 case DiffTree::FromDeclarationAndToInteger: { 1518 ValueDecl *FromValueDecl; 1519 bool FromAddressOf; 1520 bool FromNullPtr; 1521 Expr *FromExpr; 1522 llvm::APSInt ToInt; 1523 bool IsValidToInt; 1524 QualType ToIntType; 1525 Expr *ToExpr; 1526 Tree.GetFromDeclarationAndToIntegerDiff( 1527 FromValueDecl, FromAddressOf, FromNullPtr, FromExpr, ToInt, 1528 IsValidToInt, ToIntType, ToExpr); 1529 assert((FromValueDecl || FromNullPtr) && IsValidToInt); 1530 PrintValueDeclAndInteger(FromValueDecl, FromAddressOf, FromNullPtr, 1531 FromExpr, Tree.FromDefault(), ToInt, ToIntType, 1532 ToExpr, Tree.ToDefault()); 1533 return; 1534 } 1535 case DiffTree::FromIntegerAndToDeclaration: { 1536 llvm::APSInt FromInt; 1537 bool IsValidFromInt; 1538 QualType FromIntType; 1539 Expr *FromExpr; 1540 ValueDecl *ToValueDecl; 1541 bool ToAddressOf; 1542 bool ToNullPtr; 1543 Expr *ToExpr; 1544 Tree.GetFromIntegerAndToDeclarationDiff( 1545 FromInt, IsValidFromInt, FromIntType, FromExpr, ToValueDecl, 1546 ToAddressOf, ToNullPtr, ToExpr); 1547 assert(IsValidFromInt && (ToValueDecl || ToNullPtr)); 1548 PrintIntegerAndValueDecl(FromInt, FromIntType, FromExpr, 1549 Tree.FromDefault(), ToValueDecl, ToAddressOf, 1550 ToNullPtr, ToExpr, Tree.ToDefault()); 1551 return; 1552 } 1553 case DiffTree::Template: { 1554 // Node is root of template. Recurse on children. 1555 TemplateDecl *FromTD, *ToTD; 1556 Qualifiers FromQual, ToQual; 1557 Tree.GetTemplateDiff(FromTD, ToTD, FromQual, ToQual); 1558 1559 PrintQualifiers(FromQual, ToQual); 1560 1561 if (!Tree.HasChildren()) { 1562 // If we're dealing with a template specialization with zero 1563 // arguments, there are no children; special-case this. 1564 OS << FromTD->getDeclName() << "<>"; 1565 return; 1566 } 1567 1568 OS << FromTD->getDeclName() << '<'; 1569 Tree.MoveToChild(); 1570 unsigned NumElideArgs = 0; 1571 bool AllArgsElided = true; 1572 do { 1573 if (ElideType) { 1574 if (Tree.NodeIsSame()) { 1575 ++NumElideArgs; 1576 continue; 1577 } 1578 AllArgsElided = false; 1579 if (NumElideArgs > 0) { 1580 PrintElideArgs(NumElideArgs, Indent); 1581 NumElideArgs = 0; 1582 OS << ", "; 1583 } 1584 } 1585 TreeToString(Indent); 1586 if (Tree.HasNextSibling()) 1587 OS << ", "; 1588 } while (Tree.AdvanceSibling()); 1589 if (NumElideArgs > 0) { 1590 if (AllArgsElided) 1591 OS << "..."; 1592 else 1593 PrintElideArgs(NumElideArgs, Indent); 1594 } 1595 1596 Tree.Parent(); 1597 OS << ">"; 1598 return; 1599 } 1600 } 1601 } 1602 1603 // To signal to the text printer that a certain text needs to be bolded, 1604 // a special character is injected into the character stream which the 1605 // text printer will later strip out. 1606 1607 /// Bold - Start bolding text. 1608 void Bold() { 1609 assert(!IsBold && "Attempting to bold text that is already bold."); 1610 IsBold = true; 1611 if (ShowColor) 1612 OS << ToggleHighlight; 1613 } 1614 1615 /// Unbold - Stop bolding text. 1616 void Unbold() { 1617 assert(IsBold && "Attempting to remove bold from unbold text."); 1618 IsBold = false; 1619 if (ShowColor) 1620 OS << ToggleHighlight; 1621 } 1622 1623 // Functions to print out the arguments and highlighting the difference. 1624 1625 /// PrintTypeNames - prints the typenames, bolding differences. Will detect 1626 /// typenames that are the same and attempt to disambiguate them by using 1627 /// canonical typenames. 1628 void PrintTypeNames(QualType FromType, QualType ToType, 1629 bool FromDefault, bool ToDefault, bool Same) { 1630 assert((!FromType.isNull() || !ToType.isNull()) && 1631 "Only one template argument may be missing."); 1632 1633 if (Same) { 1634 OS << FromType.getAsString(Policy); 1635 return; 1636 } 1637 1638 if (!FromType.isNull() && !ToType.isNull() && 1639 FromType.getLocalUnqualifiedType() == 1640 ToType.getLocalUnqualifiedType()) { 1641 Qualifiers FromQual = FromType.getLocalQualifiers(), 1642 ToQual = ToType.getLocalQualifiers(); 1643 PrintQualifiers(FromQual, ToQual); 1644 FromType.getLocalUnqualifiedType().print(OS, Policy); 1645 return; 1646 } 1647 1648 std::string FromTypeStr = FromType.isNull() ? "(no argument)" 1649 : FromType.getAsString(Policy); 1650 std::string ToTypeStr = ToType.isNull() ? "(no argument)" 1651 : ToType.getAsString(Policy); 1652 // Switch to canonical typename if it is better. 1653 // TODO: merge this with other aka printing above. 1654 if (FromTypeStr == ToTypeStr) { 1655 std::string FromCanTypeStr = 1656 FromType.getCanonicalType().getAsString(Policy); 1657 std::string ToCanTypeStr = ToType.getCanonicalType().getAsString(Policy); 1658 if (FromCanTypeStr != ToCanTypeStr) { 1659 FromTypeStr = FromCanTypeStr; 1660 ToTypeStr = ToCanTypeStr; 1661 } 1662 } 1663 1664 if (PrintTree) OS << '['; 1665 OS << (FromDefault ? "(default) " : ""); 1666 Bold(); 1667 OS << FromTypeStr; 1668 Unbold(); 1669 if (PrintTree) { 1670 OS << " != " << (ToDefault ? "(default) " : ""); 1671 Bold(); 1672 OS << ToTypeStr; 1673 Unbold(); 1674 OS << "]"; 1675 } 1676 } 1677 1678 /// PrintExpr - Prints out the expr template arguments, highlighting argument 1679 /// differences. 1680 void PrintExpr(const Expr *FromExpr, const Expr *ToExpr, bool FromDefault, 1681 bool ToDefault, bool Same) { 1682 assert((FromExpr || ToExpr) && 1683 "Only one template argument may be missing."); 1684 if (Same) { 1685 PrintExpr(FromExpr); 1686 } else if (!PrintTree) { 1687 OS << (FromDefault ? "(default) " : ""); 1688 Bold(); 1689 PrintExpr(FromExpr); 1690 Unbold(); 1691 } else { 1692 OS << (FromDefault ? "[(default) " : "["); 1693 Bold(); 1694 PrintExpr(FromExpr); 1695 Unbold(); 1696 OS << " != " << (ToDefault ? "(default) " : ""); 1697 Bold(); 1698 PrintExpr(ToExpr); 1699 Unbold(); 1700 OS << ']'; 1701 } 1702 } 1703 1704 /// PrintExpr - Actual formatting and printing of expressions. 1705 void PrintExpr(const Expr *E) { 1706 if (E) { 1707 E->printPretty(OS, nullptr, Policy); 1708 return; 1709 } 1710 OS << "(no argument)"; 1711 } 1712 1713 /// PrintTemplateTemplate - Handles printing of template template arguments, 1714 /// highlighting argument differences. 1715 void PrintTemplateTemplate(TemplateDecl *FromTD, TemplateDecl *ToTD, 1716 bool FromDefault, bool ToDefault, bool Same) { 1717 assert((FromTD || ToTD) && "Only one template argument may be missing."); 1718 1719 std::string FromName = 1720 std::string(FromTD ? FromTD->getName() : "(no argument)"); 1721 std::string ToName = std::string(ToTD ? ToTD->getName() : "(no argument)"); 1722 if (FromTD && ToTD && FromName == ToName) { 1723 FromName = FromTD->getQualifiedNameAsString(); 1724 ToName = ToTD->getQualifiedNameAsString(); 1725 } 1726 1727 if (Same) { 1728 OS << "template " << FromTD->getDeclName(); 1729 } else if (!PrintTree) { 1730 OS << (FromDefault ? "(default) template " : "template "); 1731 Bold(); 1732 OS << FromName; 1733 Unbold(); 1734 } else { 1735 OS << (FromDefault ? "[(default) template " : "[template "); 1736 Bold(); 1737 OS << FromName; 1738 Unbold(); 1739 OS << " != " << (ToDefault ? "(default) template " : "template "); 1740 Bold(); 1741 OS << ToName; 1742 Unbold(); 1743 OS << ']'; 1744 } 1745 } 1746 1747 /// PrintAPSInt - Handles printing of integral arguments, highlighting 1748 /// argument differences. 1749 void PrintAPSInt(const llvm::APSInt &FromInt, const llvm::APSInt &ToInt, 1750 bool IsValidFromInt, bool IsValidToInt, QualType FromIntType, 1751 QualType ToIntType, Expr *FromExpr, Expr *ToExpr, 1752 bool FromDefault, bool ToDefault, bool Same) { 1753 assert((IsValidFromInt || IsValidToInt) && 1754 "Only one integral argument may be missing."); 1755 1756 if (Same) { 1757 if (FromIntType->isBooleanType()) { 1758 OS << ((FromInt == 0) ? "false" : "true"); 1759 } else { 1760 OS << toString(FromInt, 10); 1761 } 1762 return; 1763 } 1764 1765 bool PrintType = IsValidFromInt && IsValidToInt && 1766 !Context.hasSameType(FromIntType, ToIntType); 1767 1768 if (!PrintTree) { 1769 OS << (FromDefault ? "(default) " : ""); 1770 PrintAPSInt(FromInt, FromExpr, IsValidFromInt, FromIntType, PrintType); 1771 } else { 1772 OS << (FromDefault ? "[(default) " : "["); 1773 PrintAPSInt(FromInt, FromExpr, IsValidFromInt, FromIntType, PrintType); 1774 OS << " != " << (ToDefault ? "(default) " : ""); 1775 PrintAPSInt(ToInt, ToExpr, IsValidToInt, ToIntType, PrintType); 1776 OS << ']'; 1777 } 1778 } 1779 1780 /// PrintAPSInt - If valid, print the APSInt. If the expression is 1781 /// gives more information, print it too. 1782 void PrintAPSInt(const llvm::APSInt &Val, Expr *E, bool Valid, 1783 QualType IntType, bool PrintType) { 1784 Bold(); 1785 if (Valid) { 1786 if (HasExtraInfo(E)) { 1787 PrintExpr(E); 1788 Unbold(); 1789 OS << " aka "; 1790 Bold(); 1791 } 1792 if (PrintType) { 1793 Unbold(); 1794 OS << "("; 1795 Bold(); 1796 IntType.print(OS, Context.getPrintingPolicy()); 1797 Unbold(); 1798 OS << ") "; 1799 Bold(); 1800 } 1801 if (IntType->isBooleanType()) { 1802 OS << ((Val == 0) ? "false" : "true"); 1803 } else { 1804 OS << toString(Val, 10); 1805 } 1806 } else if (E) { 1807 PrintExpr(E); 1808 } else { 1809 OS << "(no argument)"; 1810 } 1811 Unbold(); 1812 } 1813 1814 /// HasExtraInfo - Returns true if E is not an integer literal, the 1815 /// negation of an integer literal, or a boolean literal. 1816 bool HasExtraInfo(Expr *E) { 1817 if (!E) return false; 1818 1819 E = E->IgnoreImpCasts(); 1820 1821 if (isa<IntegerLiteral>(E)) return false; 1822 1823 if (UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) 1824 if (UO->getOpcode() == UO_Minus) 1825 if (isa<IntegerLiteral>(UO->getSubExpr())) 1826 return false; 1827 1828 if (isa<CXXBoolLiteralExpr>(E)) 1829 return false; 1830 1831 return true; 1832 } 1833 1834 void PrintValueDecl(ValueDecl *VD, bool AddressOf, Expr *E, bool NullPtr) { 1835 if (VD) { 1836 if (AddressOf) 1837 OS << "&"; 1838 else if (auto *TPO = dyn_cast<TemplateParamObjectDecl>(VD)) { 1839 // FIXME: Diffing the APValue would be neat. 1840 // FIXME: Suppress this and use the full name of the declaration if the 1841 // parameter is a pointer or reference. 1842 TPO->printAsInit(OS); 1843 return; 1844 } 1845 VD->printName(OS); 1846 return; 1847 } 1848 1849 if (NullPtr) { 1850 if (E && !isa<CXXNullPtrLiteralExpr>(E)) { 1851 PrintExpr(E); 1852 if (IsBold) { 1853 Unbold(); 1854 OS << " aka "; 1855 Bold(); 1856 } else { 1857 OS << " aka "; 1858 } 1859 } 1860 1861 OS << "nullptr"; 1862 return; 1863 } 1864 1865 OS << "(no argument)"; 1866 } 1867 1868 /// PrintDecl - Handles printing of Decl arguments, highlighting 1869 /// argument differences. 1870 void PrintValueDecl(ValueDecl *FromValueDecl, ValueDecl *ToValueDecl, 1871 bool FromAddressOf, bool ToAddressOf, bool FromNullPtr, 1872 bool ToNullPtr, Expr *FromExpr, Expr *ToExpr, 1873 bool FromDefault, bool ToDefault, bool Same) { 1874 assert((FromValueDecl || FromNullPtr || ToValueDecl || ToNullPtr) && 1875 "Only one Decl argument may be NULL"); 1876 1877 if (Same) { 1878 PrintValueDecl(FromValueDecl, FromAddressOf, FromExpr, FromNullPtr); 1879 } else if (!PrintTree) { 1880 OS << (FromDefault ? "(default) " : ""); 1881 Bold(); 1882 PrintValueDecl(FromValueDecl, FromAddressOf, FromExpr, FromNullPtr); 1883 Unbold(); 1884 } else { 1885 OS << (FromDefault ? "[(default) " : "["); 1886 Bold(); 1887 PrintValueDecl(FromValueDecl, FromAddressOf, FromExpr, FromNullPtr); 1888 Unbold(); 1889 OS << " != " << (ToDefault ? "(default) " : ""); 1890 Bold(); 1891 PrintValueDecl(ToValueDecl, ToAddressOf, ToExpr, ToNullPtr); 1892 Unbold(); 1893 OS << ']'; 1894 } 1895 } 1896 1897 /// PrintValueDeclAndInteger - Uses the print functions for ValueDecl and 1898 /// APSInt to print a mixed difference. 1899 void PrintValueDeclAndInteger(ValueDecl *VD, bool NeedAddressOf, 1900 bool IsNullPtr, Expr *VDExpr, bool DefaultDecl, 1901 const llvm::APSInt &Val, QualType IntType, 1902 Expr *IntExpr, bool DefaultInt) { 1903 if (!PrintTree) { 1904 OS << (DefaultDecl ? "(default) " : ""); 1905 Bold(); 1906 PrintValueDecl(VD, NeedAddressOf, VDExpr, IsNullPtr); 1907 Unbold(); 1908 } else { 1909 OS << (DefaultDecl ? "[(default) " : "["); 1910 Bold(); 1911 PrintValueDecl(VD, NeedAddressOf, VDExpr, IsNullPtr); 1912 Unbold(); 1913 OS << " != " << (DefaultInt ? "(default) " : ""); 1914 PrintAPSInt(Val, IntExpr, true /*Valid*/, IntType, false /*PrintType*/); 1915 OS << ']'; 1916 } 1917 } 1918 1919 /// PrintIntegerAndValueDecl - Uses the print functions for APSInt and 1920 /// ValueDecl to print a mixed difference. 1921 void PrintIntegerAndValueDecl(const llvm::APSInt &Val, QualType IntType, 1922 Expr *IntExpr, bool DefaultInt, ValueDecl *VD, 1923 bool NeedAddressOf, bool IsNullPtr, 1924 Expr *VDExpr, bool DefaultDecl) { 1925 if (!PrintTree) { 1926 OS << (DefaultInt ? "(default) " : ""); 1927 PrintAPSInt(Val, IntExpr, true /*Valid*/, IntType, false /*PrintType*/); 1928 } else { 1929 OS << (DefaultInt ? "[(default) " : "["); 1930 PrintAPSInt(Val, IntExpr, true /*Valid*/, IntType, false /*PrintType*/); 1931 OS << " != " << (DefaultDecl ? "(default) " : ""); 1932 Bold(); 1933 PrintValueDecl(VD, NeedAddressOf, VDExpr, IsNullPtr); 1934 Unbold(); 1935 OS << ']'; 1936 } 1937 } 1938 1939 // Prints the appropriate placeholder for elided template arguments. 1940 void PrintElideArgs(unsigned NumElideArgs, unsigned Indent) { 1941 if (PrintTree) { 1942 OS << '\n'; 1943 for (unsigned i = 0; i < Indent; ++i) 1944 OS << " "; 1945 } 1946 if (NumElideArgs == 0) return; 1947 if (NumElideArgs == 1) 1948 OS << "[...]"; 1949 else 1950 OS << "[" << NumElideArgs << " * ...]"; 1951 } 1952 1953 // Prints and highlights differences in Qualifiers. 1954 void PrintQualifiers(Qualifiers FromQual, Qualifiers ToQual) { 1955 // Both types have no qualifiers 1956 if (FromQual.empty() && ToQual.empty()) 1957 return; 1958 1959 // Both types have same qualifiers 1960 if (FromQual == ToQual) { 1961 PrintQualifier(FromQual, /*ApplyBold*/false); 1962 return; 1963 } 1964 1965 // Find common qualifiers and strip them from FromQual and ToQual. 1966 Qualifiers CommonQual = Qualifiers::removeCommonQualifiers(FromQual, 1967 ToQual); 1968 1969 // The qualifiers are printed before the template name. 1970 // Inline printing: 1971 // The common qualifiers are printed. Then, qualifiers only in this type 1972 // are printed and highlighted. Finally, qualifiers only in the other 1973 // type are printed and highlighted inside parentheses after "missing". 1974 // Tree printing: 1975 // Qualifiers are printed next to each other, inside brackets, and 1976 // separated by "!=". The printing order is: 1977 // common qualifiers, highlighted from qualifiers, "!=", 1978 // common qualifiers, highlighted to qualifiers 1979 if (PrintTree) { 1980 OS << "["; 1981 if (CommonQual.empty() && FromQual.empty()) { 1982 Bold(); 1983 OS << "(no qualifiers) "; 1984 Unbold(); 1985 } else { 1986 PrintQualifier(CommonQual, /*ApplyBold*/false); 1987 PrintQualifier(FromQual, /*ApplyBold*/true); 1988 } 1989 OS << "!= "; 1990 if (CommonQual.empty() && ToQual.empty()) { 1991 Bold(); 1992 OS << "(no qualifiers)"; 1993 Unbold(); 1994 } else { 1995 PrintQualifier(CommonQual, /*ApplyBold*/false, 1996 /*appendSpaceIfNonEmpty*/!ToQual.empty()); 1997 PrintQualifier(ToQual, /*ApplyBold*/true, 1998 /*appendSpaceIfNonEmpty*/false); 1999 } 2000 OS << "] "; 2001 } else { 2002 PrintQualifier(CommonQual, /*ApplyBold*/false); 2003 PrintQualifier(FromQual, /*ApplyBold*/true); 2004 } 2005 } 2006 2007 void PrintQualifier(Qualifiers Q, bool ApplyBold, 2008 bool AppendSpaceIfNonEmpty = true) { 2009 if (Q.empty()) return; 2010 if (ApplyBold) Bold(); 2011 Q.print(OS, Policy, AppendSpaceIfNonEmpty); 2012 if (ApplyBold) Unbold(); 2013 } 2014 2015 public: 2016 2017 TemplateDiff(raw_ostream &OS, ASTContext &Context, QualType FromType, 2018 QualType ToType, bool PrintTree, bool PrintFromType, 2019 bool ElideType, bool ShowColor) 2020 : Context(Context), 2021 Policy(Context.getLangOpts()), 2022 ElideType(ElideType), 2023 PrintTree(PrintTree), 2024 ShowColor(ShowColor), 2025 // When printing a single type, the FromType is the one printed. 2026 FromTemplateType(PrintFromType ? FromType : ToType), 2027 ToTemplateType(PrintFromType ? ToType : FromType), 2028 OS(OS), 2029 IsBold(false) { 2030 } 2031 2032 /// DiffTemplate - Start the template type diffing. 2033 void DiffTemplate() { 2034 Qualifiers FromQual = FromTemplateType.getQualifiers(), 2035 ToQual = ToTemplateType.getQualifiers(); 2036 2037 const TemplateSpecializationType *FromOrigTST = 2038 GetTemplateSpecializationType(Context, FromTemplateType); 2039 const TemplateSpecializationType *ToOrigTST = 2040 GetTemplateSpecializationType(Context, ToTemplateType); 2041 2042 // Only checking templates. 2043 if (!FromOrigTST || !ToOrigTST) 2044 return; 2045 2046 // Different base templates. 2047 if (!hasSameTemplate(FromOrigTST, ToOrigTST)) { 2048 return; 2049 } 2050 2051 FromQual -= QualType(FromOrigTST, 0).getQualifiers(); 2052 ToQual -= QualType(ToOrigTST, 0).getQualifiers(); 2053 2054 // Same base template, but different arguments. 2055 Tree.SetTemplateDiff(FromOrigTST->getTemplateName().getAsTemplateDecl(), 2056 ToOrigTST->getTemplateName().getAsTemplateDecl(), 2057 FromQual, ToQual, false /*FromDefault*/, 2058 false /*ToDefault*/); 2059 2060 DiffTemplate(FromOrigTST, ToOrigTST); 2061 } 2062 2063 /// Emit - When the two types given are templated types with the same 2064 /// base template, a string representation of the type difference will be 2065 /// emitted to the stream and return true. Otherwise, return false. 2066 bool Emit() { 2067 Tree.StartTraverse(); 2068 if (Tree.Empty()) 2069 return false; 2070 2071 TreeToString(); 2072 assert(!IsBold && "Bold is applied to end of string."); 2073 return true; 2074 } 2075 }; // end class TemplateDiff 2076 } // end anonymous namespace 2077 2078 /// FormatTemplateTypeDiff - A helper static function to start the template 2079 /// diff and return the properly formatted string. Returns true if the diff 2080 /// is successful. 2081 static bool FormatTemplateTypeDiff(ASTContext &Context, QualType FromType, 2082 QualType ToType, bool PrintTree, 2083 bool PrintFromType, bool ElideType, 2084 bool ShowColors, raw_ostream &OS) { 2085 if (PrintTree) 2086 PrintFromType = true; 2087 TemplateDiff TD(OS, Context, FromType, ToType, PrintTree, PrintFromType, 2088 ElideType, ShowColors); 2089 TD.DiffTemplate(); 2090 return TD.Emit(); 2091 } 2092