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