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