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