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