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