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 (Ty->isVectorType()) { 304 const VectorType *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() : 608 CurrentNode(0), NextFreeNode(1) { 609 FlatTree.push_back(DiffNode()); 610 } 611 612 // Node writing functions, one for each valid DiffKind element. 613 void SetTemplateDiff(TemplateDecl *FromTD, TemplateDecl *ToTD, 614 Qualifiers FromQual, Qualifiers ToQual, 615 bool FromDefault, bool ToDefault) { 616 assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty."); 617 FlatTree[CurrentNode].Kind = Template; 618 FlatTree[CurrentNode].FromArgInfo.TD = FromTD; 619 FlatTree[CurrentNode].ToArgInfo.TD = ToTD; 620 FlatTree[CurrentNode].FromArgInfo.Qual = FromQual; 621 FlatTree[CurrentNode].ToArgInfo.Qual = ToQual; 622 SetDefault(FromDefault, ToDefault); 623 } 624 625 void SetTypeDiff(QualType FromType, QualType ToType, bool FromDefault, 626 bool ToDefault) { 627 assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty."); 628 FlatTree[CurrentNode].Kind = Type; 629 FlatTree[CurrentNode].FromArgInfo.ArgType = FromType; 630 FlatTree[CurrentNode].ToArgInfo.ArgType = ToType; 631 SetDefault(FromDefault, ToDefault); 632 } 633 634 void SetExpressionDiff(Expr *FromExpr, Expr *ToExpr, bool FromDefault, 635 bool ToDefault) { 636 assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty."); 637 FlatTree[CurrentNode].Kind = Expression; 638 FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr; 639 FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr; 640 SetDefault(FromDefault, ToDefault); 641 } 642 643 void SetTemplateTemplateDiff(TemplateDecl *FromTD, TemplateDecl *ToTD, 644 bool FromDefault, bool ToDefault) { 645 assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty."); 646 FlatTree[CurrentNode].Kind = TemplateTemplate; 647 FlatTree[CurrentNode].FromArgInfo.TD = FromTD; 648 FlatTree[CurrentNode].ToArgInfo.TD = ToTD; 649 SetDefault(FromDefault, ToDefault); 650 } 651 652 void SetIntegerDiff(const llvm::APSInt &FromInt, const llvm::APSInt &ToInt, 653 bool IsValidFromInt, bool IsValidToInt, 654 QualType FromIntType, QualType ToIntType, 655 Expr *FromExpr, Expr *ToExpr, bool FromDefault, 656 bool ToDefault) { 657 assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty."); 658 FlatTree[CurrentNode].Kind = Integer; 659 FlatTree[CurrentNode].FromArgInfo.Val = FromInt; 660 FlatTree[CurrentNode].ToArgInfo.Val = ToInt; 661 FlatTree[CurrentNode].FromArgInfo.IsValidInt = IsValidFromInt; 662 FlatTree[CurrentNode].ToArgInfo.IsValidInt = IsValidToInt; 663 FlatTree[CurrentNode].FromArgInfo.ArgType = FromIntType; 664 FlatTree[CurrentNode].ToArgInfo.ArgType = ToIntType; 665 FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr; 666 FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr; 667 SetDefault(FromDefault, ToDefault); 668 } 669 670 void SetDeclarationDiff(ValueDecl *FromValueDecl, ValueDecl *ToValueDecl, 671 bool FromAddressOf, bool ToAddressOf, 672 bool FromNullPtr, bool ToNullPtr, Expr *FromExpr, 673 Expr *ToExpr, bool FromDefault, bool ToDefault) { 674 assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty."); 675 FlatTree[CurrentNode].Kind = Declaration; 676 FlatTree[CurrentNode].FromArgInfo.VD = FromValueDecl; 677 FlatTree[CurrentNode].ToArgInfo.VD = ToValueDecl; 678 FlatTree[CurrentNode].FromArgInfo.NeedAddressOf = FromAddressOf; 679 FlatTree[CurrentNode].ToArgInfo.NeedAddressOf = ToAddressOf; 680 FlatTree[CurrentNode].FromArgInfo.IsNullPtr = FromNullPtr; 681 FlatTree[CurrentNode].ToArgInfo.IsNullPtr = ToNullPtr; 682 FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr; 683 FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr; 684 SetDefault(FromDefault, ToDefault); 685 } 686 687 void SetFromDeclarationAndToIntegerDiff( 688 ValueDecl *FromValueDecl, bool FromAddressOf, bool FromNullPtr, 689 Expr *FromExpr, const llvm::APSInt &ToInt, bool IsValidToInt, 690 QualType ToIntType, Expr *ToExpr, bool FromDefault, bool ToDefault) { 691 assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty."); 692 FlatTree[CurrentNode].Kind = FromDeclarationAndToInteger; 693 FlatTree[CurrentNode].FromArgInfo.VD = FromValueDecl; 694 FlatTree[CurrentNode].FromArgInfo.NeedAddressOf = FromAddressOf; 695 FlatTree[CurrentNode].FromArgInfo.IsNullPtr = FromNullPtr; 696 FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr; 697 FlatTree[CurrentNode].ToArgInfo.Val = ToInt; 698 FlatTree[CurrentNode].ToArgInfo.IsValidInt = IsValidToInt; 699 FlatTree[CurrentNode].ToArgInfo.ArgType = ToIntType; 700 FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr; 701 SetDefault(FromDefault, ToDefault); 702 } 703 704 void SetFromIntegerAndToDeclarationDiff( 705 const llvm::APSInt &FromInt, bool IsValidFromInt, QualType FromIntType, 706 Expr *FromExpr, ValueDecl *ToValueDecl, bool ToAddressOf, 707 bool ToNullPtr, Expr *ToExpr, bool FromDefault, bool ToDefault) { 708 assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty."); 709 FlatTree[CurrentNode].Kind = FromIntegerAndToDeclaration; 710 FlatTree[CurrentNode].FromArgInfo.Val = FromInt; 711 FlatTree[CurrentNode].FromArgInfo.IsValidInt = IsValidFromInt; 712 FlatTree[CurrentNode].FromArgInfo.ArgType = FromIntType; 713 FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr; 714 FlatTree[CurrentNode].ToArgInfo.VD = ToValueDecl; 715 FlatTree[CurrentNode].ToArgInfo.NeedAddressOf = ToAddressOf; 716 FlatTree[CurrentNode].ToArgInfo.IsNullPtr = ToNullPtr; 717 FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr; 718 SetDefault(FromDefault, ToDefault); 719 } 720 721 /// SetDefault - Sets FromDefault and ToDefault flags of the current node. 722 void SetDefault(bool FromDefault, bool ToDefault) { 723 assert((!FromDefault || !ToDefault) && "Both arguments cannot be default."); 724 FlatTree[CurrentNode].FromArgInfo.IsDefault = FromDefault; 725 FlatTree[CurrentNode].ToArgInfo.IsDefault = ToDefault; 726 } 727 728 /// SetSame - Sets the same flag of the current node. 729 void SetSame(bool Same) { 730 FlatTree[CurrentNode].Same = Same; 731 } 732 733 /// SetKind - Sets the current node's type. 734 void SetKind(DiffKind Kind) { 735 FlatTree[CurrentNode].Kind = Kind; 736 } 737 738 /// Up - Changes the node to the parent of the current node. 739 void Up() { 740 assert(FlatTree[CurrentNode].Kind != Invalid && 741 "Cannot exit node before setting node information."); 742 CurrentNode = FlatTree[CurrentNode].ParentNode; 743 } 744 745 /// AddNode - Adds a child node to the current node, then sets that node 746 /// node as the current node. 747 void AddNode() { 748 assert(FlatTree[CurrentNode].Kind == Template && 749 "Only Template nodes can have children nodes."); 750 FlatTree.push_back(DiffNode(CurrentNode)); 751 DiffNode &Node = FlatTree[CurrentNode]; 752 if (Node.ChildNode == 0) { 753 // If a child node doesn't exist, add one. 754 Node.ChildNode = NextFreeNode; 755 } else { 756 // If a child node exists, find the last child node and add a 757 // next node to it. 758 unsigned i; 759 for (i = Node.ChildNode; FlatTree[i].NextNode != 0; 760 i = FlatTree[i].NextNode) { 761 } 762 FlatTree[i].NextNode = NextFreeNode; 763 } 764 CurrentNode = NextFreeNode; 765 ++NextFreeNode; 766 } 767 768 // Node reading functions. 769 /// StartTraverse - Prepares the tree for recursive traversal. 770 void StartTraverse() { 771 ReadNode = 0; 772 CurrentNode = NextFreeNode; 773 NextFreeNode = 0; 774 } 775 776 /// Parent - Move the current read node to its parent. 777 void Parent() { 778 ReadNode = FlatTree[ReadNode].ParentNode; 779 } 780 781 void GetTemplateDiff(TemplateDecl *&FromTD, TemplateDecl *&ToTD, 782 Qualifiers &FromQual, Qualifiers &ToQual) { 783 assert(FlatTree[ReadNode].Kind == Template && "Unexpected kind."); 784 FromTD = FlatTree[ReadNode].FromArgInfo.TD; 785 ToTD = FlatTree[ReadNode].ToArgInfo.TD; 786 FromQual = FlatTree[ReadNode].FromArgInfo.Qual; 787 ToQual = FlatTree[ReadNode].ToArgInfo.Qual; 788 } 789 790 void GetTypeDiff(QualType &FromType, QualType &ToType) { 791 assert(FlatTree[ReadNode].Kind == Type && "Unexpected kind"); 792 FromType = FlatTree[ReadNode].FromArgInfo.ArgType; 793 ToType = FlatTree[ReadNode].ToArgInfo.ArgType; 794 } 795 796 void GetExpressionDiff(Expr *&FromExpr, Expr *&ToExpr) { 797 assert(FlatTree[ReadNode].Kind == Expression && "Unexpected kind"); 798 FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr; 799 ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr; 800 } 801 802 void GetTemplateTemplateDiff(TemplateDecl *&FromTD, TemplateDecl *&ToTD) { 803 assert(FlatTree[ReadNode].Kind == TemplateTemplate && "Unexpected kind."); 804 FromTD = FlatTree[ReadNode].FromArgInfo.TD; 805 ToTD = FlatTree[ReadNode].ToArgInfo.TD; 806 } 807 808 void GetIntegerDiff(llvm::APSInt &FromInt, llvm::APSInt &ToInt, 809 bool &IsValidFromInt, bool &IsValidToInt, 810 QualType &FromIntType, QualType &ToIntType, 811 Expr *&FromExpr, Expr *&ToExpr) { 812 assert(FlatTree[ReadNode].Kind == Integer && "Unexpected kind."); 813 FromInt = FlatTree[ReadNode].FromArgInfo.Val; 814 ToInt = FlatTree[ReadNode].ToArgInfo.Val; 815 IsValidFromInt = FlatTree[ReadNode].FromArgInfo.IsValidInt; 816 IsValidToInt = FlatTree[ReadNode].ToArgInfo.IsValidInt; 817 FromIntType = FlatTree[ReadNode].FromArgInfo.ArgType; 818 ToIntType = FlatTree[ReadNode].ToArgInfo.ArgType; 819 FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr; 820 ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr; 821 } 822 823 void GetDeclarationDiff(ValueDecl *&FromValueDecl, ValueDecl *&ToValueDecl, 824 bool &FromAddressOf, bool &ToAddressOf, 825 bool &FromNullPtr, bool &ToNullPtr, Expr *&FromExpr, 826 Expr *&ToExpr) { 827 assert(FlatTree[ReadNode].Kind == Declaration && "Unexpected kind."); 828 FromValueDecl = FlatTree[ReadNode].FromArgInfo.VD; 829 ToValueDecl = FlatTree[ReadNode].ToArgInfo.VD; 830 FromAddressOf = FlatTree[ReadNode].FromArgInfo.NeedAddressOf; 831 ToAddressOf = FlatTree[ReadNode].ToArgInfo.NeedAddressOf; 832 FromNullPtr = FlatTree[ReadNode].FromArgInfo.IsNullPtr; 833 ToNullPtr = FlatTree[ReadNode].ToArgInfo.IsNullPtr; 834 FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr; 835 ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr; 836 } 837 838 void GetFromDeclarationAndToIntegerDiff( 839 ValueDecl *&FromValueDecl, bool &FromAddressOf, bool &FromNullPtr, 840 Expr *&FromExpr, llvm::APSInt &ToInt, bool &IsValidToInt, 841 QualType &ToIntType, Expr *&ToExpr) { 842 assert(FlatTree[ReadNode].Kind == FromDeclarationAndToInteger && 843 "Unexpected kind."); 844 FromValueDecl = FlatTree[ReadNode].FromArgInfo.VD; 845 FromAddressOf = FlatTree[ReadNode].FromArgInfo.NeedAddressOf; 846 FromNullPtr = FlatTree[ReadNode].FromArgInfo.IsNullPtr; 847 FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr; 848 ToInt = FlatTree[ReadNode].ToArgInfo.Val; 849 IsValidToInt = FlatTree[ReadNode].ToArgInfo.IsValidInt; 850 ToIntType = FlatTree[ReadNode].ToArgInfo.ArgType; 851 ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr; 852 } 853 854 void GetFromIntegerAndToDeclarationDiff( 855 llvm::APSInt &FromInt, bool &IsValidFromInt, QualType &FromIntType, 856 Expr *&FromExpr, ValueDecl *&ToValueDecl, bool &ToAddressOf, 857 bool &ToNullPtr, Expr *&ToExpr) { 858 assert(FlatTree[ReadNode].Kind == FromIntegerAndToDeclaration && 859 "Unexpected kind."); 860 FromInt = FlatTree[ReadNode].FromArgInfo.Val; 861 IsValidFromInt = FlatTree[ReadNode].FromArgInfo.IsValidInt; 862 FromIntType = FlatTree[ReadNode].FromArgInfo.ArgType; 863 FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr; 864 ToValueDecl = FlatTree[ReadNode].ToArgInfo.VD; 865 ToAddressOf = FlatTree[ReadNode].ToArgInfo.NeedAddressOf; 866 ToNullPtr = FlatTree[ReadNode].ToArgInfo.IsNullPtr; 867 ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr; 868 } 869 870 /// FromDefault - Return true if the from argument is the default. 871 bool FromDefault() { 872 return FlatTree[ReadNode].FromArgInfo.IsDefault; 873 } 874 875 /// ToDefault - Return true if the to argument is the default. 876 bool ToDefault() { 877 return FlatTree[ReadNode].ToArgInfo.IsDefault; 878 } 879 880 /// NodeIsSame - Returns true the arguments are the same. 881 bool NodeIsSame() { 882 return FlatTree[ReadNode].Same; 883 } 884 885 /// HasChildrend - Returns true if the node has children. 886 bool HasChildren() { 887 return FlatTree[ReadNode].ChildNode != 0; 888 } 889 890 /// MoveToChild - Moves from the current node to its child. 891 void MoveToChild() { 892 ReadNode = FlatTree[ReadNode].ChildNode; 893 } 894 895 /// AdvanceSibling - If there is a next sibling, advance to it and return 896 /// true. Otherwise, return false. 897 bool AdvanceSibling() { 898 if (FlatTree[ReadNode].NextNode == 0) 899 return false; 900 901 ReadNode = FlatTree[ReadNode].NextNode; 902 return true; 903 } 904 905 /// HasNextSibling - Return true if the node has a next sibling. 906 bool HasNextSibling() { 907 return FlatTree[ReadNode].NextNode != 0; 908 } 909 910 /// Empty - Returns true if the tree has no information. 911 bool Empty() { 912 return GetKind() == Invalid; 913 } 914 915 /// GetKind - Returns the current node's type. 916 DiffKind GetKind() { 917 return FlatTree[ReadNode].Kind; 918 } 919 }; 920 921 DiffTree Tree; 922 923 /// TSTiterator - a pair of iterators that walks the 924 /// TemplateSpecializationType and the desugared TemplateSpecializationType. 925 /// The deseguared TemplateArgument should provide the canonical argument 926 /// for comparisons. 927 class TSTiterator { 928 typedef const TemplateArgument& reference; 929 typedef const TemplateArgument* pointer; 930 931 /// InternalIterator - an iterator that is used to enter a 932 /// TemplateSpecializationType and read TemplateArguments inside template 933 /// parameter packs in order with the rest of the TemplateArguments. 934 struct InternalIterator { 935 /// TST - the template specialization whose arguments this iterator 936 /// traverse over. 937 const TemplateSpecializationType *TST; 938 939 /// Index - the index of the template argument in TST. 940 unsigned Index; 941 942 /// CurrentTA - if CurrentTA is not the same as EndTA, then CurrentTA 943 /// points to a TemplateArgument within a parameter pack. 944 TemplateArgument::pack_iterator CurrentTA; 945 946 /// EndTA - the end iterator of a parameter pack 947 TemplateArgument::pack_iterator EndTA; 948 949 /// InternalIterator - Constructs an iterator and sets it to the first 950 /// template argument. 951 InternalIterator(const TemplateSpecializationType *TST) 952 : TST(TST), Index(0), CurrentTA(nullptr), EndTA(nullptr) { 953 if (!TST) return; 954 955 if (isEnd()) return; 956 957 // Set to first template argument. If not a parameter pack, done. 958 TemplateArgument TA = TST->getArg(0); 959 if (TA.getKind() != TemplateArgument::Pack) return; 960 961 // Start looking into the parameter pack. 962 CurrentTA = TA.pack_begin(); 963 EndTA = TA.pack_end(); 964 965 // Found a valid template argument. 966 if (CurrentTA != EndTA) return; 967 968 // Parameter pack is empty, use the increment to get to a valid 969 // template argument. 970 ++(*this); 971 } 972 973 /// Return true if the iterator is non-singular. 974 bool isValid() const { return TST; } 975 976 /// isEnd - Returns true if the iterator is one past the end. 977 bool isEnd() const { 978 assert(TST && "InternalIterator is invalid with a null TST."); 979 return Index >= TST->getNumArgs(); 980 } 981 982 /// &operator++ - Increment the iterator to the next template argument. 983 InternalIterator &operator++() { 984 assert(TST && "InternalIterator is invalid with a null TST."); 985 if (isEnd()) { 986 return *this; 987 } 988 989 // If in a parameter pack, advance in the parameter pack. 990 if (CurrentTA != EndTA) { 991 ++CurrentTA; 992 if (CurrentTA != EndTA) 993 return *this; 994 } 995 996 // Loop until a template argument is found, or the end is reached. 997 while (true) { 998 // Advance to the next template argument. Break if reached the end. 999 if (++Index == TST->getNumArgs()) 1000 break; 1001 1002 // If the TemplateArgument is not a parameter pack, done. 1003 TemplateArgument TA = TST->getArg(Index); 1004 if (TA.getKind() != TemplateArgument::Pack) 1005 break; 1006 1007 // Handle parameter packs. 1008 CurrentTA = TA.pack_begin(); 1009 EndTA = TA.pack_end(); 1010 1011 // If the parameter pack is empty, try to advance again. 1012 if (CurrentTA != EndTA) 1013 break; 1014 } 1015 return *this; 1016 } 1017 1018 /// operator* - Returns the appropriate TemplateArgument. 1019 reference operator*() const { 1020 assert(TST && "InternalIterator is invalid with a null TST."); 1021 assert(!isEnd() && "Index exceeds number of arguments."); 1022 if (CurrentTA == EndTA) 1023 return TST->getArg(Index); 1024 else 1025 return *CurrentTA; 1026 } 1027 1028 /// operator-> - Allow access to the underlying TemplateArgument. 1029 pointer operator->() const { 1030 assert(TST && "InternalIterator is invalid with a null TST."); 1031 return &operator*(); 1032 } 1033 }; 1034 1035 InternalIterator SugaredIterator; 1036 InternalIterator DesugaredIterator; 1037 1038 public: 1039 TSTiterator(ASTContext &Context, const TemplateSpecializationType *TST) 1040 : SugaredIterator(TST), 1041 DesugaredIterator( 1042 (TST->isSugared() && !TST->isTypeAlias()) 1043 ? GetTemplateSpecializationType(Context, TST->desugar()) 1044 : nullptr) {} 1045 1046 /// &operator++ - Increment the iterator to the next template argument. 1047 TSTiterator &operator++() { 1048 ++SugaredIterator; 1049 if (DesugaredIterator.isValid()) 1050 ++DesugaredIterator; 1051 return *this; 1052 } 1053 1054 /// operator* - Returns the appropriate TemplateArgument. 1055 reference operator*() const { 1056 return *SugaredIterator; 1057 } 1058 1059 /// operator-> - Allow access to the underlying TemplateArgument. 1060 pointer operator->() const { 1061 return &operator*(); 1062 } 1063 1064 /// isEnd - Returns true if no more TemplateArguments are available. 1065 bool isEnd() const { 1066 return SugaredIterator.isEnd(); 1067 } 1068 1069 /// hasDesugaredTA - Returns true if there is another TemplateArgument 1070 /// available. 1071 bool hasDesugaredTA() const { 1072 return DesugaredIterator.isValid() && !DesugaredIterator.isEnd(); 1073 } 1074 1075 /// getDesugaredTA - Returns the desugared TemplateArgument. 1076 reference getDesugaredTA() const { 1077 assert(DesugaredIterator.isValid() && 1078 "Desugared TemplateArgument should not be used."); 1079 return *DesugaredIterator; 1080 } 1081 }; 1082 1083 // These functions build up the template diff tree, including functions to 1084 // retrieve and compare template arguments. 1085 1086 static const TemplateSpecializationType *GetTemplateSpecializationType( 1087 ASTContext &Context, QualType Ty) { 1088 if (const TemplateSpecializationType *TST = 1089 Ty->getAs<TemplateSpecializationType>()) 1090 return TST; 1091 1092 const RecordType *RT = Ty->getAs<RecordType>(); 1093 1094 if (!RT) 1095 return nullptr; 1096 1097 const ClassTemplateSpecializationDecl *CTSD = 1098 dyn_cast<ClassTemplateSpecializationDecl>(RT->getDecl()); 1099 1100 if (!CTSD) 1101 return nullptr; 1102 1103 Ty = Context.getTemplateSpecializationType( 1104 TemplateName(CTSD->getSpecializedTemplate()), 1105 CTSD->getTemplateArgs().asArray(), 1106 Ty.getLocalUnqualifiedType().getCanonicalType()); 1107 1108 return Ty->getAs<TemplateSpecializationType>(); 1109 } 1110 1111 /// Returns true if the DiffType is Type and false for Template. 1112 static bool OnlyPerformTypeDiff(ASTContext &Context, QualType FromType, 1113 QualType ToType, 1114 const TemplateSpecializationType *&FromArgTST, 1115 const TemplateSpecializationType *&ToArgTST) { 1116 if (FromType.isNull() || ToType.isNull()) 1117 return true; 1118 1119 if (Context.hasSameType(FromType, ToType)) 1120 return true; 1121 1122 FromArgTST = GetTemplateSpecializationType(Context, FromType); 1123 ToArgTST = GetTemplateSpecializationType(Context, ToType); 1124 1125 if (!FromArgTST || !ToArgTST) 1126 return true; 1127 1128 if (!hasSameTemplate(FromArgTST, ToArgTST)) 1129 return true; 1130 1131 return false; 1132 } 1133 1134 /// DiffTypes - Fills a DiffNode with information about a type difference. 1135 void DiffTypes(const TSTiterator &FromIter, const TSTiterator &ToIter) { 1136 QualType FromType = GetType(FromIter); 1137 QualType ToType = GetType(ToIter); 1138 1139 bool FromDefault = FromIter.isEnd() && !FromType.isNull(); 1140 bool ToDefault = ToIter.isEnd() && !ToType.isNull(); 1141 1142 const TemplateSpecializationType *FromArgTST = nullptr; 1143 const TemplateSpecializationType *ToArgTST = nullptr; 1144 if (OnlyPerformTypeDiff(Context, FromType, ToType, FromArgTST, ToArgTST)) { 1145 Tree.SetTypeDiff(FromType, ToType, FromDefault, ToDefault); 1146 Tree.SetSame(!FromType.isNull() && !ToType.isNull() && 1147 Context.hasSameType(FromType, ToType)); 1148 } else { 1149 assert(FromArgTST && ToArgTST && 1150 "Both template specializations need to be valid."); 1151 Qualifiers FromQual = FromType.getQualifiers(), 1152 ToQual = ToType.getQualifiers(); 1153 FromQual -= QualType(FromArgTST, 0).getQualifiers(); 1154 ToQual -= QualType(ToArgTST, 0).getQualifiers(); 1155 Tree.SetTemplateDiff(FromArgTST->getTemplateName().getAsTemplateDecl(), 1156 ToArgTST->getTemplateName().getAsTemplateDecl(), 1157 FromQual, ToQual, FromDefault, ToDefault); 1158 DiffTemplate(FromArgTST, ToArgTST); 1159 } 1160 } 1161 1162 /// DiffTemplateTemplates - Fills a DiffNode with information about a 1163 /// template template difference. 1164 void DiffTemplateTemplates(const TSTiterator &FromIter, 1165 const TSTiterator &ToIter) { 1166 TemplateDecl *FromDecl = GetTemplateDecl(FromIter); 1167 TemplateDecl *ToDecl = GetTemplateDecl(ToIter); 1168 Tree.SetTemplateTemplateDiff(FromDecl, ToDecl, FromIter.isEnd() && FromDecl, 1169 ToIter.isEnd() && ToDecl); 1170 Tree.SetSame(FromDecl && ToDecl && 1171 FromDecl->getCanonicalDecl() == ToDecl->getCanonicalDecl()); 1172 } 1173 1174 /// InitializeNonTypeDiffVariables - Helper function for DiffNonTypes 1175 static void InitializeNonTypeDiffVariables(ASTContext &Context, 1176 const TSTiterator &Iter, 1177 NonTypeTemplateParmDecl *Default, 1178 llvm::APSInt &Value, bool &HasInt, 1179 QualType &IntType, bool &IsNullPtr, 1180 Expr *&E, ValueDecl *&VD, 1181 bool &NeedAddressOf) { 1182 if (!Iter.isEnd()) { 1183 switch (Iter->getKind()) { 1184 default: 1185 llvm_unreachable("unknown ArgumentKind"); 1186 case TemplateArgument::Integral: 1187 Value = Iter->getAsIntegral(); 1188 HasInt = true; 1189 IntType = Iter->getIntegralType(); 1190 return; 1191 case TemplateArgument::Declaration: { 1192 VD = Iter->getAsDecl(); 1193 QualType ArgType = Iter->getParamTypeForDecl(); 1194 QualType VDType = VD->getType(); 1195 if (ArgType->isPointerType() && 1196 Context.hasSameType(ArgType->getPointeeType(), VDType)) 1197 NeedAddressOf = true; 1198 return; 1199 } 1200 case TemplateArgument::NullPtr: 1201 IsNullPtr = true; 1202 return; 1203 case TemplateArgument::Expression: 1204 E = Iter->getAsExpr(); 1205 } 1206 } else if (!Default->isParameterPack()) { 1207 E = Default->getDefaultArgument(); 1208 } 1209 1210 if (!Iter.hasDesugaredTA()) return; 1211 1212 const TemplateArgument& TA = Iter.getDesugaredTA(); 1213 switch (TA.getKind()) { 1214 default: 1215 llvm_unreachable("unknown ArgumentKind"); 1216 case TemplateArgument::Integral: 1217 Value = TA.getAsIntegral(); 1218 HasInt = true; 1219 IntType = TA.getIntegralType(); 1220 return; 1221 case TemplateArgument::Declaration: { 1222 VD = TA.getAsDecl(); 1223 QualType ArgType = TA.getParamTypeForDecl(); 1224 QualType VDType = VD->getType(); 1225 if (ArgType->isPointerType() && 1226 Context.hasSameType(ArgType->getPointeeType(), VDType)) 1227 NeedAddressOf = true; 1228 return; 1229 } 1230 case TemplateArgument::NullPtr: 1231 IsNullPtr = true; 1232 return; 1233 case TemplateArgument::Expression: 1234 // TODO: Sometimes, the desugared template argument Expr differs from 1235 // the sugared template argument Expr. It may be useful in the future 1236 // but for now, it is just discarded. 1237 if (!E) 1238 E = TA.getAsExpr(); 1239 return; 1240 } 1241 } 1242 1243 /// DiffNonTypes - Handles any template parameters not handled by DiffTypes 1244 /// of DiffTemplatesTemplates, such as integer and declaration parameters. 1245 void DiffNonTypes(const TSTiterator &FromIter, const TSTiterator &ToIter, 1246 NonTypeTemplateParmDecl *FromDefaultNonTypeDecl, 1247 NonTypeTemplateParmDecl *ToDefaultNonTypeDecl) { 1248 Expr *FromExpr = nullptr, *ToExpr = nullptr; 1249 llvm::APSInt FromInt, ToInt; 1250 QualType FromIntType, ToIntType; 1251 ValueDecl *FromValueDecl = nullptr, *ToValueDecl = nullptr; 1252 bool HasFromInt = false, HasToInt = false, FromNullPtr = false, 1253 ToNullPtr = false, NeedFromAddressOf = false, NeedToAddressOf = false; 1254 InitializeNonTypeDiffVariables( 1255 Context, FromIter, FromDefaultNonTypeDecl, FromInt, HasFromInt, 1256 FromIntType, FromNullPtr, FromExpr, FromValueDecl, NeedFromAddressOf); 1257 InitializeNonTypeDiffVariables(Context, ToIter, ToDefaultNonTypeDecl, ToInt, 1258 HasToInt, ToIntType, ToNullPtr, ToExpr, 1259 ToValueDecl, NeedToAddressOf); 1260 1261 bool FromDefault = FromIter.isEnd() && 1262 (FromExpr || FromValueDecl || HasFromInt || FromNullPtr); 1263 bool ToDefault = ToIter.isEnd() && 1264 (ToExpr || ToValueDecl || HasToInt || ToNullPtr); 1265 1266 bool FromDeclaration = FromValueDecl || FromNullPtr; 1267 bool ToDeclaration = ToValueDecl || ToNullPtr; 1268 1269 if (FromDeclaration && HasToInt) { 1270 Tree.SetFromDeclarationAndToIntegerDiff( 1271 FromValueDecl, NeedFromAddressOf, FromNullPtr, FromExpr, ToInt, 1272 HasToInt, ToIntType, ToExpr, FromDefault, ToDefault); 1273 Tree.SetSame(false); 1274 return; 1275 1276 } 1277 1278 if (HasFromInt && ToDeclaration) { 1279 Tree.SetFromIntegerAndToDeclarationDiff( 1280 FromInt, HasFromInt, FromIntType, FromExpr, ToValueDecl, 1281 NeedToAddressOf, ToNullPtr, ToExpr, FromDefault, ToDefault); 1282 Tree.SetSame(false); 1283 return; 1284 } 1285 1286 if (HasFromInt || HasToInt) { 1287 Tree.SetIntegerDiff(FromInt, ToInt, HasFromInt, HasToInt, FromIntType, 1288 ToIntType, FromExpr, ToExpr, FromDefault, ToDefault); 1289 if (HasFromInt && HasToInt) { 1290 Tree.SetSame(Context.hasSameType(FromIntType, ToIntType) && 1291 FromInt == ToInt); 1292 } 1293 return; 1294 } 1295 1296 if (FromDeclaration || ToDeclaration) { 1297 Tree.SetDeclarationDiff(FromValueDecl, ToValueDecl, NeedFromAddressOf, 1298 NeedToAddressOf, FromNullPtr, ToNullPtr, FromExpr, 1299 ToExpr, FromDefault, ToDefault); 1300 bool BothNull = FromNullPtr && ToNullPtr; 1301 bool SameValueDecl = 1302 FromValueDecl && ToValueDecl && 1303 NeedFromAddressOf == NeedToAddressOf && 1304 FromValueDecl->getCanonicalDecl() == ToValueDecl->getCanonicalDecl(); 1305 Tree.SetSame(BothNull || SameValueDecl); 1306 return; 1307 } 1308 1309 assert((FromExpr || ToExpr) && "Both template arguments cannot be empty."); 1310 Tree.SetExpressionDiff(FromExpr, ToExpr, FromDefault, ToDefault); 1311 Tree.SetSame(IsEqualExpr(Context, FromExpr, ToExpr)); 1312 } 1313 1314 /// DiffTemplate - recursively visits template arguments and stores the 1315 /// argument info into a tree. 1316 void DiffTemplate(const TemplateSpecializationType *FromTST, 1317 const TemplateSpecializationType *ToTST) { 1318 // Begin descent into diffing template tree. 1319 TemplateParameterList *ParamsFrom = 1320 FromTST->getTemplateName().getAsTemplateDecl()->getTemplateParameters(); 1321 TemplateParameterList *ParamsTo = 1322 ToTST->getTemplateName().getAsTemplateDecl()->getTemplateParameters(); 1323 unsigned TotalArgs = 0; 1324 for (TSTiterator FromIter(Context, FromTST), ToIter(Context, ToTST); 1325 !FromIter.isEnd() || !ToIter.isEnd(); ++TotalArgs) { 1326 Tree.AddNode(); 1327 1328 // Get the parameter at index TotalArgs. If index is larger 1329 // than the total number of parameters, then there is an 1330 // argument pack, so re-use the last parameter. 1331 unsigned FromParamIndex = std::min(TotalArgs, ParamsFrom->size() - 1); 1332 unsigned ToParamIndex = std::min(TotalArgs, ParamsTo->size() - 1); 1333 NamedDecl *FromParamND = ParamsFrom->getParam(FromParamIndex); 1334 NamedDecl *ToParamND = ParamsTo->getParam(ToParamIndex); 1335 1336 assert(FromParamND->getKind() == ToParamND->getKind() && 1337 "Parameter Decl are not the same kind."); 1338 1339 if (isa<TemplateTypeParmDecl>(FromParamND)) { 1340 DiffTypes(FromIter, ToIter); 1341 } else if (isa<TemplateTemplateParmDecl>(FromParamND)) { 1342 DiffTemplateTemplates(FromIter, ToIter); 1343 } else if (isa<NonTypeTemplateParmDecl>(FromParamND)) { 1344 NonTypeTemplateParmDecl *FromDefaultNonTypeDecl = 1345 cast<NonTypeTemplateParmDecl>(FromParamND); 1346 NonTypeTemplateParmDecl *ToDefaultNonTypeDecl = 1347 cast<NonTypeTemplateParmDecl>(ToParamND); 1348 DiffNonTypes(FromIter, ToIter, FromDefaultNonTypeDecl, 1349 ToDefaultNonTypeDecl); 1350 } else { 1351 llvm_unreachable("Unexpected Decl type."); 1352 } 1353 1354 ++FromIter; 1355 ++ToIter; 1356 Tree.Up(); 1357 } 1358 } 1359 1360 /// makeTemplateList - Dump every template alias into the vector. 1361 static void makeTemplateList( 1362 SmallVectorImpl<const TemplateSpecializationType *> &TemplateList, 1363 const TemplateSpecializationType *TST) { 1364 while (TST) { 1365 TemplateList.push_back(TST); 1366 if (!TST->isTypeAlias()) 1367 return; 1368 TST = TST->getAliasedType()->getAs<TemplateSpecializationType>(); 1369 } 1370 } 1371 1372 /// hasSameBaseTemplate - Returns true when the base templates are the same, 1373 /// even if the template arguments are not. 1374 static bool hasSameBaseTemplate(const TemplateSpecializationType *FromTST, 1375 const TemplateSpecializationType *ToTST) { 1376 return FromTST->getTemplateName().getAsTemplateDecl()->getCanonicalDecl() == 1377 ToTST->getTemplateName().getAsTemplateDecl()->getCanonicalDecl(); 1378 } 1379 1380 /// hasSameTemplate - Returns true if both types are specialized from the 1381 /// same template declaration. If they come from different template aliases, 1382 /// do a parallel ascension search to determine the highest template alias in 1383 /// common and set the arguments to them. 1384 static bool hasSameTemplate(const TemplateSpecializationType *&FromTST, 1385 const TemplateSpecializationType *&ToTST) { 1386 // Check the top templates if they are the same. 1387 if (hasSameBaseTemplate(FromTST, ToTST)) 1388 return true; 1389 1390 // Create vectors of template aliases. 1391 SmallVector<const TemplateSpecializationType*, 1> FromTemplateList, 1392 ToTemplateList; 1393 1394 makeTemplateList(FromTemplateList, FromTST); 1395 makeTemplateList(ToTemplateList, ToTST); 1396 1397 SmallVectorImpl<const TemplateSpecializationType *>::reverse_iterator 1398 FromIter = FromTemplateList.rbegin(), FromEnd = FromTemplateList.rend(), 1399 ToIter = ToTemplateList.rbegin(), ToEnd = ToTemplateList.rend(); 1400 1401 // Check if the lowest template types are the same. If not, return. 1402 if (!hasSameBaseTemplate(*FromIter, *ToIter)) 1403 return false; 1404 1405 // Begin searching up the template aliases. The bottom most template 1406 // matches so move up until one pair does not match. Use the template 1407 // right before that one. 1408 for (; FromIter != FromEnd && ToIter != ToEnd; ++FromIter, ++ToIter) { 1409 if (!hasSameBaseTemplate(*FromIter, *ToIter)) 1410 break; 1411 } 1412 1413 FromTST = FromIter[-1]; 1414 ToTST = ToIter[-1]; 1415 1416 return true; 1417 } 1418 1419 /// GetType - Retrieves the template type arguments, including default 1420 /// arguments. 1421 static QualType GetType(const TSTiterator &Iter) { 1422 if (!Iter.isEnd()) 1423 return Iter->getAsType(); 1424 if (Iter.hasDesugaredTA()) 1425 return Iter.getDesugaredTA().getAsType(); 1426 return QualType(); 1427 } 1428 1429 /// GetTemplateDecl - Retrieves the template template arguments, including 1430 /// default arguments. 1431 static TemplateDecl *GetTemplateDecl(const TSTiterator &Iter) { 1432 if (!Iter.isEnd()) 1433 return Iter->getAsTemplate().getAsTemplateDecl(); 1434 if (Iter.hasDesugaredTA()) 1435 return Iter.getDesugaredTA().getAsTemplate().getAsTemplateDecl(); 1436 return nullptr; 1437 } 1438 1439 /// IsEqualExpr - Returns true if the expressions are the same in regards to 1440 /// template arguments. These expressions are dependent, so profile them 1441 /// instead of trying to evaluate them. 1442 static bool IsEqualExpr(ASTContext &Context, Expr *FromExpr, Expr *ToExpr) { 1443 if (FromExpr == ToExpr) 1444 return true; 1445 1446 if (!FromExpr || !ToExpr) 1447 return false; 1448 1449 llvm::FoldingSetNodeID FromID, ToID; 1450 FromExpr->Profile(FromID, Context, true); 1451 ToExpr->Profile(ToID, Context, true); 1452 return FromID == ToID; 1453 } 1454 1455 // These functions converts the tree representation of the template 1456 // differences into the internal character vector. 1457 1458 /// TreeToString - Converts the Tree object into a character stream which 1459 /// will later be turned into the output string. 1460 void TreeToString(int Indent = 1) { 1461 if (PrintTree) { 1462 OS << '\n'; 1463 OS.indent(2 * Indent); 1464 ++Indent; 1465 } 1466 1467 // Handle cases where the difference is not templates with different 1468 // arguments. 1469 switch (Tree.GetKind()) { 1470 case DiffTree::Invalid: 1471 llvm_unreachable("Template diffing failed with bad DiffNode"); 1472 case DiffTree::Type: { 1473 QualType FromType, ToType; 1474 Tree.GetTypeDiff(FromType, ToType); 1475 PrintTypeNames(FromType, ToType, Tree.FromDefault(), Tree.ToDefault(), 1476 Tree.NodeIsSame()); 1477 return; 1478 } 1479 case DiffTree::Expression: { 1480 Expr *FromExpr, *ToExpr; 1481 Tree.GetExpressionDiff(FromExpr, ToExpr); 1482 PrintExpr(FromExpr, ToExpr, Tree.FromDefault(), Tree.ToDefault(), 1483 Tree.NodeIsSame()); 1484 return; 1485 } 1486 case DiffTree::TemplateTemplate: { 1487 TemplateDecl *FromTD, *ToTD; 1488 Tree.GetTemplateTemplateDiff(FromTD, ToTD); 1489 PrintTemplateTemplate(FromTD, ToTD, Tree.FromDefault(), 1490 Tree.ToDefault(), Tree.NodeIsSame()); 1491 return; 1492 } 1493 case DiffTree::Integer: { 1494 llvm::APSInt FromInt, ToInt; 1495 Expr *FromExpr, *ToExpr; 1496 bool IsValidFromInt, IsValidToInt; 1497 QualType FromIntType, ToIntType; 1498 Tree.GetIntegerDiff(FromInt, ToInt, IsValidFromInt, IsValidToInt, 1499 FromIntType, ToIntType, FromExpr, ToExpr); 1500 PrintAPSInt(FromInt, ToInt, IsValidFromInt, IsValidToInt, FromIntType, 1501 ToIntType, FromExpr, ToExpr, Tree.FromDefault(), 1502 Tree.ToDefault(), Tree.NodeIsSame()); 1503 return; 1504 } 1505 case DiffTree::Declaration: { 1506 ValueDecl *FromValueDecl, *ToValueDecl; 1507 bool FromAddressOf, ToAddressOf; 1508 bool FromNullPtr, ToNullPtr; 1509 Expr *FromExpr, *ToExpr; 1510 Tree.GetDeclarationDiff(FromValueDecl, ToValueDecl, FromAddressOf, 1511 ToAddressOf, FromNullPtr, ToNullPtr, FromExpr, 1512 ToExpr); 1513 PrintValueDecl(FromValueDecl, ToValueDecl, FromAddressOf, ToAddressOf, 1514 FromNullPtr, ToNullPtr, FromExpr, ToExpr, 1515 Tree.FromDefault(), Tree.ToDefault(), Tree.NodeIsSame()); 1516 return; 1517 } 1518 case DiffTree::FromDeclarationAndToInteger: { 1519 ValueDecl *FromValueDecl; 1520 bool FromAddressOf; 1521 bool FromNullPtr; 1522 Expr *FromExpr; 1523 llvm::APSInt ToInt; 1524 bool IsValidToInt; 1525 QualType ToIntType; 1526 Expr *ToExpr; 1527 Tree.GetFromDeclarationAndToIntegerDiff( 1528 FromValueDecl, FromAddressOf, FromNullPtr, FromExpr, ToInt, 1529 IsValidToInt, ToIntType, ToExpr); 1530 assert((FromValueDecl || FromNullPtr) && IsValidToInt); 1531 PrintValueDeclAndInteger(FromValueDecl, FromAddressOf, FromNullPtr, 1532 FromExpr, Tree.FromDefault(), ToInt, ToIntType, 1533 ToExpr, Tree.ToDefault()); 1534 return; 1535 } 1536 case DiffTree::FromIntegerAndToDeclaration: { 1537 llvm::APSInt FromInt; 1538 bool IsValidFromInt; 1539 QualType FromIntType; 1540 Expr *FromExpr; 1541 ValueDecl *ToValueDecl; 1542 bool ToAddressOf; 1543 bool ToNullPtr; 1544 Expr *ToExpr; 1545 Tree.GetFromIntegerAndToDeclarationDiff( 1546 FromInt, IsValidFromInt, FromIntType, FromExpr, ToValueDecl, 1547 ToAddressOf, ToNullPtr, ToExpr); 1548 assert(IsValidFromInt && (ToValueDecl || ToNullPtr)); 1549 PrintIntegerAndValueDecl(FromInt, FromIntType, FromExpr, 1550 Tree.FromDefault(), ToValueDecl, ToAddressOf, 1551 ToNullPtr, ToExpr, Tree.ToDefault()); 1552 return; 1553 } 1554 case DiffTree::Template: { 1555 // Node is root of template. Recurse on children. 1556 TemplateDecl *FromTD, *ToTD; 1557 Qualifiers FromQual, ToQual; 1558 Tree.GetTemplateDiff(FromTD, ToTD, FromQual, ToQual); 1559 1560 PrintQualifiers(FromQual, ToQual); 1561 1562 if (!Tree.HasChildren()) { 1563 // If we're dealing with a template specialization with zero 1564 // arguments, there are no children; special-case this. 1565 OS << FromTD->getNameAsString() << "<>"; 1566 return; 1567 } 1568 1569 OS << FromTD->getNameAsString() << '<'; 1570 Tree.MoveToChild(); 1571 unsigned NumElideArgs = 0; 1572 bool AllArgsElided = true; 1573 do { 1574 if (ElideType) { 1575 if (Tree.NodeIsSame()) { 1576 ++NumElideArgs; 1577 continue; 1578 } 1579 AllArgsElided = false; 1580 if (NumElideArgs > 0) { 1581 PrintElideArgs(NumElideArgs, Indent); 1582 NumElideArgs = 0; 1583 OS << ", "; 1584 } 1585 } 1586 TreeToString(Indent); 1587 if (Tree.HasNextSibling()) 1588 OS << ", "; 1589 } while (Tree.AdvanceSibling()); 1590 if (NumElideArgs > 0) { 1591 if (AllArgsElided) 1592 OS << "..."; 1593 else 1594 PrintElideArgs(NumElideArgs, Indent); 1595 } 1596 1597 Tree.Parent(); 1598 OS << ">"; 1599 return; 1600 } 1601 } 1602 } 1603 1604 // To signal to the text printer that a certain text needs to be bolded, 1605 // a special character is injected into the character stream which the 1606 // text printer will later strip out. 1607 1608 /// Bold - Start bolding text. 1609 void Bold() { 1610 assert(!IsBold && "Attempting to bold text that is already bold."); 1611 IsBold = true; 1612 if (ShowColor) 1613 OS << ToggleHighlight; 1614 } 1615 1616 /// Unbold - Stop bolding text. 1617 void Unbold() { 1618 assert(IsBold && "Attempting to remove bold from unbold text."); 1619 IsBold = false; 1620 if (ShowColor) 1621 OS << ToggleHighlight; 1622 } 1623 1624 // Functions to print out the arguments and highlighting the difference. 1625 1626 /// PrintTypeNames - prints the typenames, bolding differences. Will detect 1627 /// typenames that are the same and attempt to disambiguate them by using 1628 /// canonical typenames. 1629 void PrintTypeNames(QualType FromType, QualType ToType, 1630 bool FromDefault, bool ToDefault, bool Same) { 1631 assert((!FromType.isNull() || !ToType.isNull()) && 1632 "Only one template argument may be missing."); 1633 1634 if (Same) { 1635 OS << FromType.getAsString(Policy); 1636 return; 1637 } 1638 1639 if (!FromType.isNull() && !ToType.isNull() && 1640 FromType.getLocalUnqualifiedType() == 1641 ToType.getLocalUnqualifiedType()) { 1642 Qualifiers FromQual = FromType.getLocalQualifiers(), 1643 ToQual = ToType.getLocalQualifiers(); 1644 PrintQualifiers(FromQual, ToQual); 1645 FromType.getLocalUnqualifiedType().print(OS, Policy); 1646 return; 1647 } 1648 1649 std::string FromTypeStr = FromType.isNull() ? "(no argument)" 1650 : FromType.getAsString(Policy); 1651 std::string ToTypeStr = ToType.isNull() ? "(no argument)" 1652 : ToType.getAsString(Policy); 1653 // Switch to canonical typename if it is better. 1654 // TODO: merge this with other aka printing above. 1655 if (FromTypeStr == ToTypeStr) { 1656 std::string FromCanTypeStr = 1657 FromType.getCanonicalType().getAsString(Policy); 1658 std::string ToCanTypeStr = ToType.getCanonicalType().getAsString(Policy); 1659 if (FromCanTypeStr != ToCanTypeStr) { 1660 FromTypeStr = FromCanTypeStr; 1661 ToTypeStr = ToCanTypeStr; 1662 } 1663 } 1664 1665 if (PrintTree) OS << '['; 1666 OS << (FromDefault ? "(default) " : ""); 1667 Bold(); 1668 OS << FromTypeStr; 1669 Unbold(); 1670 if (PrintTree) { 1671 OS << " != " << (ToDefault ? "(default) " : ""); 1672 Bold(); 1673 OS << ToTypeStr; 1674 Unbold(); 1675 OS << "]"; 1676 } 1677 } 1678 1679 /// PrintExpr - Prints out the expr template arguments, highlighting argument 1680 /// differences. 1681 void PrintExpr(const Expr *FromExpr, const Expr *ToExpr, bool FromDefault, 1682 bool ToDefault, bool Same) { 1683 assert((FromExpr || ToExpr) && 1684 "Only one template argument may be missing."); 1685 if (Same) { 1686 PrintExpr(FromExpr); 1687 } else if (!PrintTree) { 1688 OS << (FromDefault ? "(default) " : ""); 1689 Bold(); 1690 PrintExpr(FromExpr); 1691 Unbold(); 1692 } else { 1693 OS << (FromDefault ? "[(default) " : "["); 1694 Bold(); 1695 PrintExpr(FromExpr); 1696 Unbold(); 1697 OS << " != " << (ToDefault ? "(default) " : ""); 1698 Bold(); 1699 PrintExpr(ToExpr); 1700 Unbold(); 1701 OS << ']'; 1702 } 1703 } 1704 1705 /// PrintExpr - Actual formatting and printing of expressions. 1706 void PrintExpr(const Expr *E) { 1707 if (E) { 1708 E->printPretty(OS, nullptr, Policy); 1709 return; 1710 } 1711 OS << "(no argument)"; 1712 } 1713 1714 /// PrintTemplateTemplate - Handles printing of template template arguments, 1715 /// highlighting argument differences. 1716 void PrintTemplateTemplate(TemplateDecl *FromTD, TemplateDecl *ToTD, 1717 bool FromDefault, bool ToDefault, bool Same) { 1718 assert((FromTD || ToTD) && "Only one template argument may be missing."); 1719 1720 std::string FromName = FromTD ? FromTD->getName() : "(no argument)"; 1721 std::string ToName = 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->getNameAsString(); 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 << FromInt.toString(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 << Val.toString(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 OS << VD->getName(); 1839 return; 1840 } 1841 1842 if (NullPtr) { 1843 if (E && !isa<CXXNullPtrLiteralExpr>(E)) { 1844 PrintExpr(E); 1845 if (IsBold) { 1846 Unbold(); 1847 OS << " aka "; 1848 Bold(); 1849 } else { 1850 OS << " aka "; 1851 } 1852 } 1853 1854 OS << "nullptr"; 1855 return; 1856 } 1857 1858 OS << "(no argument)"; 1859 } 1860 1861 /// PrintDecl - Handles printing of Decl arguments, highlighting 1862 /// argument differences. 1863 void PrintValueDecl(ValueDecl *FromValueDecl, ValueDecl *ToValueDecl, 1864 bool FromAddressOf, bool ToAddressOf, bool FromNullPtr, 1865 bool ToNullPtr, Expr *FromExpr, Expr *ToExpr, 1866 bool FromDefault, bool ToDefault, bool Same) { 1867 assert((FromValueDecl || FromNullPtr || ToValueDecl || ToNullPtr) && 1868 "Only one Decl argument may be NULL"); 1869 1870 if (Same) { 1871 PrintValueDecl(FromValueDecl, FromAddressOf, FromExpr, FromNullPtr); 1872 } else if (!PrintTree) { 1873 OS << (FromDefault ? "(default) " : ""); 1874 Bold(); 1875 PrintValueDecl(FromValueDecl, FromAddressOf, FromExpr, FromNullPtr); 1876 Unbold(); 1877 } else { 1878 OS << (FromDefault ? "[(default) " : "["); 1879 Bold(); 1880 PrintValueDecl(FromValueDecl, FromAddressOf, FromExpr, FromNullPtr); 1881 Unbold(); 1882 OS << " != " << (ToDefault ? "(default) " : ""); 1883 Bold(); 1884 PrintValueDecl(ToValueDecl, ToAddressOf, ToExpr, ToNullPtr); 1885 Unbold(); 1886 OS << ']'; 1887 } 1888 } 1889 1890 /// PrintValueDeclAndInteger - Uses the print functions for ValueDecl and 1891 /// APSInt to print a mixed difference. 1892 void PrintValueDeclAndInteger(ValueDecl *VD, bool NeedAddressOf, 1893 bool IsNullPtr, Expr *VDExpr, bool DefaultDecl, 1894 const llvm::APSInt &Val, QualType IntType, 1895 Expr *IntExpr, bool DefaultInt) { 1896 if (!PrintTree) { 1897 OS << (DefaultDecl ? "(default) " : ""); 1898 Bold(); 1899 PrintValueDecl(VD, NeedAddressOf, VDExpr, IsNullPtr); 1900 Unbold(); 1901 } else { 1902 OS << (DefaultDecl ? "[(default) " : "["); 1903 Bold(); 1904 PrintValueDecl(VD, NeedAddressOf, VDExpr, IsNullPtr); 1905 Unbold(); 1906 OS << " != " << (DefaultInt ? "(default) " : ""); 1907 PrintAPSInt(Val, IntExpr, true /*Valid*/, IntType, false /*PrintType*/); 1908 OS << ']'; 1909 } 1910 } 1911 1912 /// PrintIntegerAndValueDecl - Uses the print functions for APSInt and 1913 /// ValueDecl to print a mixed difference. 1914 void PrintIntegerAndValueDecl(const llvm::APSInt &Val, QualType IntType, 1915 Expr *IntExpr, bool DefaultInt, ValueDecl *VD, 1916 bool NeedAddressOf, bool IsNullPtr, 1917 Expr *VDExpr, bool DefaultDecl) { 1918 if (!PrintTree) { 1919 OS << (DefaultInt ? "(default) " : ""); 1920 PrintAPSInt(Val, IntExpr, true /*Valid*/, IntType, false /*PrintType*/); 1921 } else { 1922 OS << (DefaultInt ? "[(default) " : "["); 1923 PrintAPSInt(Val, IntExpr, true /*Valid*/, IntType, false /*PrintType*/); 1924 OS << " != " << (DefaultDecl ? "(default) " : ""); 1925 Bold(); 1926 PrintValueDecl(VD, NeedAddressOf, VDExpr, IsNullPtr); 1927 Unbold(); 1928 OS << ']'; 1929 } 1930 } 1931 1932 // Prints the appropriate placeholder for elided template arguments. 1933 void PrintElideArgs(unsigned NumElideArgs, unsigned Indent) { 1934 if (PrintTree) { 1935 OS << '\n'; 1936 for (unsigned i = 0; i < Indent; ++i) 1937 OS << " "; 1938 } 1939 if (NumElideArgs == 0) return; 1940 if (NumElideArgs == 1) 1941 OS << "[...]"; 1942 else 1943 OS << "[" << NumElideArgs << " * ...]"; 1944 } 1945 1946 // Prints and highlights differences in Qualifiers. 1947 void PrintQualifiers(Qualifiers FromQual, Qualifiers ToQual) { 1948 // Both types have no qualifiers 1949 if (FromQual.empty() && ToQual.empty()) 1950 return; 1951 1952 // Both types have same qualifiers 1953 if (FromQual == ToQual) { 1954 PrintQualifier(FromQual, /*ApplyBold*/false); 1955 return; 1956 } 1957 1958 // Find common qualifiers and strip them from FromQual and ToQual. 1959 Qualifiers CommonQual = Qualifiers::removeCommonQualifiers(FromQual, 1960 ToQual); 1961 1962 // The qualifiers are printed before the template name. 1963 // Inline printing: 1964 // The common qualifiers are printed. Then, qualifiers only in this type 1965 // are printed and highlighted. Finally, qualifiers only in the other 1966 // type are printed and highlighted inside parentheses after "missing". 1967 // Tree printing: 1968 // Qualifiers are printed next to each other, inside brackets, and 1969 // separated by "!=". The printing order is: 1970 // common qualifiers, highlighted from qualifiers, "!=", 1971 // common qualifiers, highlighted to qualifiers 1972 if (PrintTree) { 1973 OS << "["; 1974 if (CommonQual.empty() && FromQual.empty()) { 1975 Bold(); 1976 OS << "(no qualifiers) "; 1977 Unbold(); 1978 } else { 1979 PrintQualifier(CommonQual, /*ApplyBold*/false); 1980 PrintQualifier(FromQual, /*ApplyBold*/true); 1981 } 1982 OS << "!= "; 1983 if (CommonQual.empty() && ToQual.empty()) { 1984 Bold(); 1985 OS << "(no qualifiers)"; 1986 Unbold(); 1987 } else { 1988 PrintQualifier(CommonQual, /*ApplyBold*/false, 1989 /*appendSpaceIfNonEmpty*/!ToQual.empty()); 1990 PrintQualifier(ToQual, /*ApplyBold*/true, 1991 /*appendSpaceIfNonEmpty*/false); 1992 } 1993 OS << "] "; 1994 } else { 1995 PrintQualifier(CommonQual, /*ApplyBold*/false); 1996 PrintQualifier(FromQual, /*ApplyBold*/true); 1997 } 1998 } 1999 2000 void PrintQualifier(Qualifiers Q, bool ApplyBold, 2001 bool AppendSpaceIfNonEmpty = true) { 2002 if (Q.empty()) return; 2003 if (ApplyBold) Bold(); 2004 Q.print(OS, Policy, AppendSpaceIfNonEmpty); 2005 if (ApplyBold) Unbold(); 2006 } 2007 2008 public: 2009 2010 TemplateDiff(raw_ostream &OS, ASTContext &Context, QualType FromType, 2011 QualType ToType, bool PrintTree, bool PrintFromType, 2012 bool ElideType, bool ShowColor) 2013 : Context(Context), 2014 Policy(Context.getLangOpts()), 2015 ElideType(ElideType), 2016 PrintTree(PrintTree), 2017 ShowColor(ShowColor), 2018 // When printing a single type, the FromType is the one printed. 2019 FromTemplateType(PrintFromType ? FromType : ToType), 2020 ToTemplateType(PrintFromType ? ToType : FromType), 2021 OS(OS), 2022 IsBold(false) { 2023 } 2024 2025 /// DiffTemplate - Start the template type diffing. 2026 void DiffTemplate() { 2027 Qualifiers FromQual = FromTemplateType.getQualifiers(), 2028 ToQual = ToTemplateType.getQualifiers(); 2029 2030 const TemplateSpecializationType *FromOrigTST = 2031 GetTemplateSpecializationType(Context, FromTemplateType); 2032 const TemplateSpecializationType *ToOrigTST = 2033 GetTemplateSpecializationType(Context, ToTemplateType); 2034 2035 // Only checking templates. 2036 if (!FromOrigTST || !ToOrigTST) 2037 return; 2038 2039 // Different base templates. 2040 if (!hasSameTemplate(FromOrigTST, ToOrigTST)) { 2041 return; 2042 } 2043 2044 FromQual -= QualType(FromOrigTST, 0).getQualifiers(); 2045 ToQual -= QualType(ToOrigTST, 0).getQualifiers(); 2046 2047 // Same base template, but different arguments. 2048 Tree.SetTemplateDiff(FromOrigTST->getTemplateName().getAsTemplateDecl(), 2049 ToOrigTST->getTemplateName().getAsTemplateDecl(), 2050 FromQual, ToQual, false /*FromDefault*/, 2051 false /*ToDefault*/); 2052 2053 DiffTemplate(FromOrigTST, ToOrigTST); 2054 } 2055 2056 /// Emit - When the two types given are templated types with the same 2057 /// base template, a string representation of the type difference will be 2058 /// emitted to the stream and return true. Otherwise, return false. 2059 bool Emit() { 2060 Tree.StartTraverse(); 2061 if (Tree.Empty()) 2062 return false; 2063 2064 TreeToString(); 2065 assert(!IsBold && "Bold is applied to end of string."); 2066 return true; 2067 } 2068 }; // end class TemplateDiff 2069 } // end anonymous namespace 2070 2071 /// FormatTemplateTypeDiff - A helper static function to start the template 2072 /// diff and return the properly formatted string. Returns true if the diff 2073 /// is successful. 2074 static bool FormatTemplateTypeDiff(ASTContext &Context, QualType FromType, 2075 QualType ToType, bool PrintTree, 2076 bool PrintFromType, bool ElideType, 2077 bool ShowColors, raw_ostream &OS) { 2078 if (PrintTree) 2079 PrintFromType = true; 2080 TemplateDiff TD(OS, Context, FromType, ToType, PrintTree, PrintFromType, 2081 ElideType, ShowColors); 2082 TD.DiffTemplate(); 2083 return TD.Emit(); 2084 } 2085