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