clang API Documentation
00001 //===--- ASTDiagnostic.cpp - Diagnostic Printing Hooks for AST Nodes ------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements a diagnostic formatting hook for AST elements. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 #include "clang/AST/ASTDiagnostic.h" 00014 #include "clang/AST/ASTContext.h" 00015 #include "clang/AST/ASTLambda.h" 00016 #include "clang/AST/Attr.h" 00017 #include "clang/AST/DeclObjC.h" 00018 #include "clang/AST/DeclTemplate.h" 00019 #include "clang/AST/ExprCXX.h" 00020 #include "clang/AST/TemplateBase.h" 00021 #include "clang/AST/Type.h" 00022 #include "llvm/ADT/SmallString.h" 00023 #include "llvm/Support/raw_ostream.h" 00024 00025 using namespace clang; 00026 00027 // Returns a desugared version of the QualType, and marks ShouldAKA as true 00028 // whenever we remove significant sugar from the type. 00029 static QualType Desugar(ASTContext &Context, QualType QT, bool &ShouldAKA) { 00030 QualifierCollector QC; 00031 00032 while (true) { 00033 const Type *Ty = QC.strip(QT); 00034 00035 // Don't aka just because we saw an elaborated type... 00036 if (const ElaboratedType *ET = dyn_cast<ElaboratedType>(Ty)) { 00037 QT = ET->desugar(); 00038 continue; 00039 } 00040 // ... or a paren type ... 00041 if (const ParenType *PT = dyn_cast<ParenType>(Ty)) { 00042 QT = PT->desugar(); 00043 continue; 00044 } 00045 // ...or a substituted template type parameter ... 00046 if (const SubstTemplateTypeParmType *ST = 00047 dyn_cast<SubstTemplateTypeParmType>(Ty)) { 00048 QT = ST->desugar(); 00049 continue; 00050 } 00051 // ...or an attributed type... 00052 if (const AttributedType *AT = dyn_cast<AttributedType>(Ty)) { 00053 QT = AT->desugar(); 00054 continue; 00055 } 00056 // ...or an adjusted type... 00057 if (const AdjustedType *AT = dyn_cast<AdjustedType>(Ty)) { 00058 QT = AT->desugar(); 00059 continue; 00060 } 00061 // ... or an auto type. 00062 if (const AutoType *AT = dyn_cast<AutoType>(Ty)) { 00063 if (!AT->isSugared()) 00064 break; 00065 QT = AT->desugar(); 00066 continue; 00067 } 00068 00069 // Don't desugar template specializations, unless it's an alias template. 00070 if (const TemplateSpecializationType *TST 00071 = dyn_cast<TemplateSpecializationType>(Ty)) 00072 if (!TST->isTypeAlias()) 00073 break; 00074 00075 // Don't desugar magic Objective-C types. 00076 if (QualType(Ty,0) == Context.getObjCIdType() || 00077 QualType(Ty,0) == Context.getObjCClassType() || 00078 QualType(Ty,0) == Context.getObjCSelType() || 00079 QualType(Ty,0) == Context.getObjCProtoType()) 00080 break; 00081 00082 // Don't desugar va_list. 00083 if (QualType(Ty,0) == Context.getBuiltinVaListType()) 00084 break; 00085 00086 // Otherwise, do a single-step desugar. 00087 QualType Underlying; 00088 bool IsSugar = false; 00089 switch (Ty->getTypeClass()) { 00090 #define ABSTRACT_TYPE(Class, Base) 00091 #define TYPE(Class, Base) \ 00092 case Type::Class: { \ 00093 const Class##Type *CTy = cast<Class##Type>(Ty); \ 00094 if (CTy->isSugared()) { \ 00095 IsSugar = true; \ 00096 Underlying = CTy->desugar(); \ 00097 } \ 00098 break; \ 00099 } 00100 #include "clang/AST/TypeNodes.def" 00101 } 00102 00103 // If it wasn't sugared, we're done. 00104 if (!IsSugar) 00105 break; 00106 00107 // If the desugared type is a vector type, we don't want to expand 00108 // it, it will turn into an attribute mess. People want their "vec4". 00109 if (isa<VectorType>(Underlying)) 00110 break; 00111 00112 // Don't desugar through the primary typedef of an anonymous type. 00113 if (const TagType *UTT = Underlying->getAs<TagType>()) 00114 if (const TypedefType *QTT = dyn_cast<TypedefType>(QT)) 00115 if (UTT->getDecl()->getTypedefNameForAnonDecl() == QTT->getDecl()) 00116 break; 00117 00118 // Record that we actually looked through an opaque type here. 00119 ShouldAKA = true; 00120 QT = Underlying; 00121 } 00122 00123 // If we have a pointer-like type, desugar the pointee as well. 00124 // FIXME: Handle other pointer-like types. 00125 if (const PointerType *Ty = QT->getAs<PointerType>()) { 00126 QT = Context.getPointerType(Desugar(Context, Ty->getPointeeType(), 00127 ShouldAKA)); 00128 } else if (const LValueReferenceType *Ty = QT->getAs<LValueReferenceType>()) { 00129 QT = Context.getLValueReferenceType(Desugar(Context, Ty->getPointeeType(), 00130 ShouldAKA)); 00131 } else if (const RValueReferenceType *Ty = QT->getAs<RValueReferenceType>()) { 00132 QT = Context.getRValueReferenceType(Desugar(Context, Ty->getPointeeType(), 00133 ShouldAKA)); 00134 } 00135 00136 return QC.apply(Context, QT); 00137 } 00138 00139 /// \brief Convert the given type to a string suitable for printing as part of 00140 /// a diagnostic. 00141 /// 00142 /// There are four main criteria when determining whether we should have an 00143 /// a.k.a. clause when pretty-printing a type: 00144 /// 00145 /// 1) Some types provide very minimal sugar that doesn't impede the 00146 /// user's understanding --- for example, elaborated type 00147 /// specifiers. If this is all the sugar we see, we don't want an 00148 /// a.k.a. clause. 00149 /// 2) Some types are technically sugared but are much more familiar 00150 /// when seen in their sugared form --- for example, va_list, 00151 /// vector types, and the magic Objective C types. We don't 00152 /// want to desugar these, even if we do produce an a.k.a. clause. 00153 /// 3) Some types may have already been desugared previously in this diagnostic. 00154 /// if this is the case, doing another "aka" would just be clutter. 00155 /// 4) Two different types within the same diagnostic have the same output 00156 /// string. In this case, force an a.k.a with the desugared type when 00157 /// doing so will provide additional information. 00158 /// 00159 /// \param Context the context in which the type was allocated 00160 /// \param Ty the type to print 00161 /// \param QualTypeVals pointer values to QualTypes which are used in the 00162 /// diagnostic message 00163 static std::string 00164 ConvertTypeToDiagnosticString(ASTContext &Context, QualType Ty, 00165 ArrayRef<DiagnosticsEngine::ArgumentValue> PrevArgs, 00166 ArrayRef<intptr_t> QualTypeVals) { 00167 // FIXME: Playing with std::string is really slow. 00168 bool ForceAKA = false; 00169 QualType CanTy = Ty.getCanonicalType(); 00170 std::string S = Ty.getAsString(Context.getPrintingPolicy()); 00171 std::string CanS = CanTy.getAsString(Context.getPrintingPolicy()); 00172 00173 for (unsigned I = 0, E = QualTypeVals.size(); I != E; ++I) { 00174 QualType CompareTy = 00175 QualType::getFromOpaquePtr(reinterpret_cast<void*>(QualTypeVals[I])); 00176 if (CompareTy.isNull()) 00177 continue; 00178 if (CompareTy == Ty) 00179 continue; // Same types 00180 QualType CompareCanTy = CompareTy.getCanonicalType(); 00181 if (CompareCanTy == CanTy) 00182 continue; // Same canonical types 00183 std::string CompareS = CompareTy.getAsString(Context.getPrintingPolicy()); 00184 bool aka; 00185 QualType CompareDesugar = Desugar(Context, CompareTy, aka); 00186 std::string CompareDesugarStr = 00187 CompareDesugar.getAsString(Context.getPrintingPolicy()); 00188 if (CompareS != S && CompareDesugarStr != S) 00189 continue; // The type string is different than the comparison string 00190 // and the desugared comparison string. 00191 std::string CompareCanS = 00192 CompareCanTy.getAsString(Context.getPrintingPolicy()); 00193 00194 if (CompareCanS == CanS) 00195 continue; // No new info from canonical type 00196 00197 ForceAKA = true; 00198 break; 00199 } 00200 00201 // Check to see if we already desugared this type in this 00202 // diagnostic. If so, don't do it again. 00203 bool Repeated = false; 00204 for (unsigned i = 0, e = PrevArgs.size(); i != e; ++i) { 00205 // TODO: Handle ak_declcontext case. 00206 if (PrevArgs[i].first == DiagnosticsEngine::ak_qualtype) { 00207 void *Ptr = (void*)PrevArgs[i].second; 00208 QualType PrevTy(QualType::getFromOpaquePtr(Ptr)); 00209 if (PrevTy == Ty) { 00210 Repeated = true; 00211 break; 00212 } 00213 } 00214 } 00215 00216 // Consider producing an a.k.a. clause if removing all the direct 00217 // sugar gives us something "significantly different". 00218 if (!Repeated) { 00219 bool ShouldAKA = false; 00220 QualType DesugaredTy = Desugar(Context, Ty, ShouldAKA); 00221 if (ShouldAKA || ForceAKA) { 00222 if (DesugaredTy == Ty) { 00223 DesugaredTy = Ty.getCanonicalType(); 00224 } 00225 std::string akaStr = DesugaredTy.getAsString(Context.getPrintingPolicy()); 00226 if (akaStr != S) { 00227 S = "'" + S + "' (aka '" + akaStr + "')"; 00228 return S; 00229 } 00230 } 00231 00232 // Give some additional info on vector types. These are either not desugared 00233 // or displaying complex __attribute__ expressions so add details of the 00234 // type and element count. 00235 if (Ty->isVectorType()) { 00236 const VectorType *VTy = Ty->getAs<VectorType>(); 00237 std::string DecoratedString; 00238 llvm::raw_string_ostream OS(DecoratedString); 00239 const char *Values = VTy->getNumElements() > 1 ? "values" : "value"; 00240 OS << "'" << S << "' (vector of " << VTy->getNumElements() << " '" 00241 << VTy->getElementType().getAsString(Context.getPrintingPolicy()) 00242 << "' " << Values << ")"; 00243 return OS.str(); 00244 } 00245 } 00246 00247 S = "'" + S + "'"; 00248 return S; 00249 } 00250 00251 static bool FormatTemplateTypeDiff(ASTContext &Context, QualType FromType, 00252 QualType ToType, bool PrintTree, 00253 bool PrintFromType, bool ElideType, 00254 bool ShowColors, raw_ostream &OS); 00255 00256 void clang::FormatASTNodeDiagnosticArgument( 00257 DiagnosticsEngine::ArgumentKind Kind, 00258 intptr_t Val, 00259 StringRef Modifier, 00260 StringRef Argument, 00261 ArrayRef<DiagnosticsEngine::ArgumentValue> PrevArgs, 00262 SmallVectorImpl<char> &Output, 00263 void *Cookie, 00264 ArrayRef<intptr_t> QualTypeVals) { 00265 ASTContext &Context = *static_cast<ASTContext*>(Cookie); 00266 00267 size_t OldEnd = Output.size(); 00268 llvm::raw_svector_ostream OS(Output); 00269 bool NeedQuotes = true; 00270 00271 switch (Kind) { 00272 default: llvm_unreachable("unknown ArgumentKind"); 00273 case DiagnosticsEngine::ak_qualtype_pair: { 00274 TemplateDiffTypes &TDT = *reinterpret_cast<TemplateDiffTypes*>(Val); 00275 QualType FromType = 00276 QualType::getFromOpaquePtr(reinterpret_cast<void*>(TDT.FromType)); 00277 QualType ToType = 00278 QualType::getFromOpaquePtr(reinterpret_cast<void*>(TDT.ToType)); 00279 00280 if (FormatTemplateTypeDiff(Context, FromType, ToType, TDT.PrintTree, 00281 TDT.PrintFromType, TDT.ElideType, 00282 TDT.ShowColors, OS)) { 00283 NeedQuotes = !TDT.PrintTree; 00284 TDT.TemplateDiffUsed = true; 00285 break; 00286 } 00287 00288 // Don't fall-back during tree printing. The caller will handle 00289 // this case. 00290 if (TDT.PrintTree) 00291 return; 00292 00293 // Attempting to do a template diff on non-templates. Set the variables 00294 // and continue with regular type printing of the appropriate type. 00295 Val = TDT.PrintFromType ? TDT.FromType : TDT.ToType; 00296 Modifier = StringRef(); 00297 Argument = StringRef(); 00298 // Fall through 00299 } 00300 case DiagnosticsEngine::ak_qualtype: { 00301 assert(Modifier.empty() && Argument.empty() && 00302 "Invalid modifier for QualType argument"); 00303 00304 QualType Ty(QualType::getFromOpaquePtr(reinterpret_cast<void*>(Val))); 00305 OS << ConvertTypeToDiagnosticString(Context, Ty, PrevArgs, QualTypeVals); 00306 NeedQuotes = false; 00307 break; 00308 } 00309 case DiagnosticsEngine::ak_declarationname: { 00310 if (Modifier == "objcclass" && Argument.empty()) 00311 OS << '+'; 00312 else if (Modifier == "objcinstance" && Argument.empty()) 00313 OS << '-'; 00314 else 00315 assert(Modifier.empty() && Argument.empty() && 00316 "Invalid modifier for DeclarationName argument"); 00317 00318 OS << DeclarationName::getFromOpaqueInteger(Val); 00319 break; 00320 } 00321 case DiagnosticsEngine::ak_nameddecl: { 00322 bool Qualified; 00323 if (Modifier == "q" && Argument.empty()) 00324 Qualified = true; 00325 else { 00326 assert(Modifier.empty() && Argument.empty() && 00327 "Invalid modifier for NamedDecl* argument"); 00328 Qualified = false; 00329 } 00330 const NamedDecl *ND = reinterpret_cast<const NamedDecl*>(Val); 00331 ND->getNameForDiagnostic(OS, Context.getPrintingPolicy(), Qualified); 00332 break; 00333 } 00334 case DiagnosticsEngine::ak_nestednamespec: { 00335 NestedNameSpecifier *NNS = reinterpret_cast<NestedNameSpecifier*>(Val); 00336 NNS->print(OS, Context.getPrintingPolicy()); 00337 NeedQuotes = false; 00338 break; 00339 } 00340 case DiagnosticsEngine::ak_declcontext: { 00341 DeclContext *DC = reinterpret_cast<DeclContext *> (Val); 00342 assert(DC && "Should never have a null declaration context"); 00343 NeedQuotes = false; 00344 00345 // FIXME: Get the strings for DeclContext from some localized place 00346 if (DC->isTranslationUnit()) { 00347 if (Context.getLangOpts().CPlusPlus) 00348 OS << "the global namespace"; 00349 else 00350 OS << "the global scope"; 00351 } else if (DC->isClosure()) { 00352 OS << "block literal"; 00353 } else if (isLambdaCallOperator(DC)) { 00354 OS << "lambda expression"; 00355 } else if (TypeDecl *Type = dyn_cast<TypeDecl>(DC)) { 00356 OS << ConvertTypeToDiagnosticString(Context, 00357 Context.getTypeDeclType(Type), 00358 PrevArgs, QualTypeVals); 00359 } else { 00360 assert(isa<NamedDecl>(DC) && "Expected a NamedDecl"); 00361 NamedDecl *ND = cast<NamedDecl>(DC); 00362 if (isa<NamespaceDecl>(ND)) 00363 OS << "namespace "; 00364 else if (isa<ObjCMethodDecl>(ND)) 00365 OS << "method "; 00366 else if (isa<FunctionDecl>(ND)) 00367 OS << "function "; 00368 00369 OS << '\''; 00370 ND->getNameForDiagnostic(OS, Context.getPrintingPolicy(), true); 00371 OS << '\''; 00372 } 00373 break; 00374 } 00375 case DiagnosticsEngine::ak_attr: { 00376 const Attr *At = reinterpret_cast<Attr *>(Val); 00377 assert(At && "Received null Attr object!"); 00378 OS << '\'' << At->getSpelling() << '\''; 00379 NeedQuotes = false; 00380 break; 00381 } 00382 00383 } 00384 00385 OS.flush(); 00386 00387 if (NeedQuotes) { 00388 Output.insert(Output.begin()+OldEnd, '\''); 00389 Output.push_back('\''); 00390 } 00391 } 00392 00393 /// TemplateDiff - A class that constructs a pretty string for a pair of 00394 /// QualTypes. For the pair of types, a diff tree will be created containing 00395 /// all the information about the templates and template arguments. Afterwards, 00396 /// the tree is transformed to a string according to the options passed in. 00397 namespace { 00398 class TemplateDiff { 00399 /// Context - The ASTContext which is used for comparing template arguments. 00400 ASTContext &Context; 00401 00402 /// Policy - Used during expression printing. 00403 PrintingPolicy Policy; 00404 00405 /// ElideType - Option to elide identical types. 00406 bool ElideType; 00407 00408 /// PrintTree - Format output string as a tree. 00409 bool PrintTree; 00410 00411 /// ShowColor - Diagnostics support color, so bolding will be used. 00412 bool ShowColor; 00413 00414 /// FromType - When single type printing is selected, this is the type to be 00415 /// be printed. When tree printing is selected, this type will show up first 00416 /// in the tree. 00417 QualType FromType; 00418 00419 /// ToType - The type that FromType is compared to. Only in tree printing 00420 /// will this type be outputed. 00421 QualType ToType; 00422 00423 /// OS - The stream used to construct the output strings. 00424 raw_ostream &OS; 00425 00426 /// IsBold - Keeps track of the bold formatting for the output string. 00427 bool IsBold; 00428 00429 /// DiffTree - A tree representation the differences between two types. 00430 class DiffTree { 00431 public: 00432 /// DiffKind - The difference in a DiffNode and which fields are used. 00433 enum DiffKind { 00434 /// Incomplete or invalid node. 00435 Invalid, 00436 /// Another level of templates, uses TemplateDecl and Qualifiers 00437 Template, 00438 /// Type difference, uses QualType 00439 Type, 00440 /// Expression difference, uses Expr 00441 Expression, 00442 /// Template argument difference, uses TemplateDecl 00443 TemplateTemplate, 00444 /// Integer difference, uses APSInt and Expr 00445 Integer, 00446 /// Declaration difference, uses ValueDecl 00447 Declaration 00448 }; 00449 private: 00450 /// DiffNode - The root node stores the original type. Each child node 00451 /// stores template arguments of their parents. For templated types, the 00452 /// template decl is also stored. 00453 struct DiffNode { 00454 DiffKind Kind; 00455 00456 /// NextNode - The index of the next sibling node or 0. 00457 unsigned NextNode; 00458 00459 /// ChildNode - The index of the first child node or 0. 00460 unsigned ChildNode; 00461 00462 /// ParentNode - The index of the parent node. 00463 unsigned ParentNode; 00464 00465 /// FromType, ToType - The type arguments. 00466 QualType FromType, ToType; 00467 00468 /// FromExpr, ToExpr - The expression arguments. 00469 Expr *FromExpr, *ToExpr; 00470 00471 /// FromNullPtr, ToNullPtr - If the template argument is a nullptr 00472 bool FromNullPtr, ToNullPtr; 00473 00474 /// FromTD, ToTD - The template decl for template template 00475 /// arguments or the type arguments that are templates. 00476 TemplateDecl *FromTD, *ToTD; 00477 00478 /// FromQual, ToQual - Qualifiers for template types. 00479 Qualifiers FromQual, ToQual; 00480 00481 /// FromInt, ToInt - APSInt's for integral arguments. 00482 llvm::APSInt FromInt, ToInt; 00483 00484 /// IsValidFromInt, IsValidToInt - Whether the APSInt's are valid. 00485 bool IsValidFromInt, IsValidToInt; 00486 00487 /// FromValueDecl, ToValueDecl - Whether the argument is a decl. 00488 ValueDecl *FromValueDecl, *ToValueDecl; 00489 00490 /// FromAddressOf, ToAddressOf - Whether the ValueDecl needs an address of 00491 /// operator before it. 00492 bool FromAddressOf, ToAddressOf; 00493 00494 /// FromDefault, ToDefault - Whether the argument is a default argument. 00495 bool FromDefault, ToDefault; 00496 00497 /// Same - Whether the two arguments evaluate to the same value. 00498 bool Same; 00499 00500 DiffNode(unsigned ParentNode = 0) 00501 : Kind(Invalid), NextNode(0), ChildNode(0), ParentNode(ParentNode), 00502 FromType(), ToType(), FromExpr(nullptr), ToExpr(nullptr), 00503 FromNullPtr(false), ToNullPtr(false), 00504 FromTD(nullptr), ToTD(nullptr), IsValidFromInt(false), 00505 IsValidToInt(false), FromValueDecl(nullptr), ToValueDecl(nullptr), 00506 FromAddressOf(false), ToAddressOf(false), FromDefault(false), 00507 ToDefault(false), Same(false) {} 00508 }; 00509 00510 /// FlatTree - A flattened tree used to store the DiffNodes. 00511 SmallVector<DiffNode, 16> FlatTree; 00512 00513 /// CurrentNode - The index of the current node being used. 00514 unsigned CurrentNode; 00515 00516 /// NextFreeNode - The index of the next unused node. Used when creating 00517 /// child nodes. 00518 unsigned NextFreeNode; 00519 00520 /// ReadNode - The index of the current node being read. 00521 unsigned ReadNode; 00522 00523 public: 00524 DiffTree() : 00525 CurrentNode(0), NextFreeNode(1) { 00526 FlatTree.push_back(DiffNode()); 00527 } 00528 00529 // Node writing functions. 00530 /// SetNode - Sets FromTD and ToTD of the current node. 00531 void SetNode(TemplateDecl *FromTD, TemplateDecl *ToTD) { 00532 FlatTree[CurrentNode].FromTD = FromTD; 00533 FlatTree[CurrentNode].ToTD = ToTD; 00534 } 00535 00536 /// SetNode - Sets FromType and ToType of the current node. 00537 void SetNode(QualType FromType, QualType ToType) { 00538 FlatTree[CurrentNode].FromType = FromType; 00539 FlatTree[CurrentNode].ToType = ToType; 00540 } 00541 00542 /// SetNode - Set FromExpr and ToExpr of the current node. 00543 void SetNode(Expr *FromExpr, Expr *ToExpr) { 00544 FlatTree[CurrentNode].FromExpr = FromExpr; 00545 FlatTree[CurrentNode].ToExpr = ToExpr; 00546 } 00547 00548 /// SetNode - Set FromInt and ToInt of the current node. 00549 void SetNode(llvm::APSInt FromInt, llvm::APSInt ToInt, 00550 bool IsValidFromInt, bool IsValidToInt) { 00551 FlatTree[CurrentNode].FromInt = FromInt; 00552 FlatTree[CurrentNode].ToInt = ToInt; 00553 FlatTree[CurrentNode].IsValidFromInt = IsValidFromInt; 00554 FlatTree[CurrentNode].IsValidToInt = IsValidToInt; 00555 } 00556 00557 /// SetNode - Set FromQual and ToQual of the current node. 00558 void SetNode(Qualifiers FromQual, Qualifiers ToQual) { 00559 FlatTree[CurrentNode].FromQual = FromQual; 00560 FlatTree[CurrentNode].ToQual = ToQual; 00561 } 00562 00563 /// SetNode - Set FromValueDecl and ToValueDecl of the current node. 00564 void SetNode(ValueDecl *FromValueDecl, ValueDecl *ToValueDecl, 00565 bool FromAddressOf, bool ToAddressOf) { 00566 FlatTree[CurrentNode].FromValueDecl = FromValueDecl; 00567 FlatTree[CurrentNode].ToValueDecl = ToValueDecl; 00568 FlatTree[CurrentNode].FromAddressOf = FromAddressOf; 00569 FlatTree[CurrentNode].ToAddressOf = ToAddressOf; 00570 } 00571 00572 /// SetSame - Sets the same flag of the current node. 00573 void SetSame(bool Same) { 00574 FlatTree[CurrentNode].Same = Same; 00575 } 00576 00577 /// SetNullPtr - Sets the NullPtr flags of the current node. 00578 void SetNullPtr(bool FromNullPtr, bool ToNullPtr) { 00579 FlatTree[CurrentNode].FromNullPtr = FromNullPtr; 00580 FlatTree[CurrentNode].ToNullPtr = ToNullPtr; 00581 } 00582 00583 /// SetDefault - Sets FromDefault and ToDefault flags of the current node. 00584 void SetDefault(bool FromDefault, bool ToDefault) { 00585 FlatTree[CurrentNode].FromDefault = FromDefault; 00586 FlatTree[CurrentNode].ToDefault = ToDefault; 00587 } 00588 00589 /// SetKind - Sets the current node's type. 00590 void SetKind(DiffKind Kind) { 00591 FlatTree[CurrentNode].Kind = Kind; 00592 } 00593 00594 /// Up - Changes the node to the parent of the current node. 00595 void Up() { 00596 CurrentNode = FlatTree[CurrentNode].ParentNode; 00597 } 00598 00599 /// AddNode - Adds a child node to the current node, then sets that node 00600 /// node as the current node. 00601 void AddNode() { 00602 FlatTree.push_back(DiffNode(CurrentNode)); 00603 DiffNode &Node = FlatTree[CurrentNode]; 00604 if (Node.ChildNode == 0) { 00605 // If a child node doesn't exist, add one. 00606 Node.ChildNode = NextFreeNode; 00607 } else { 00608 // If a child node exists, find the last child node and add a 00609 // next node to it. 00610 unsigned i; 00611 for (i = Node.ChildNode; FlatTree[i].NextNode != 0; 00612 i = FlatTree[i].NextNode) { 00613 } 00614 FlatTree[i].NextNode = NextFreeNode; 00615 } 00616 CurrentNode = NextFreeNode; 00617 ++NextFreeNode; 00618 } 00619 00620 // Node reading functions. 00621 /// StartTraverse - Prepares the tree for recursive traversal. 00622 void StartTraverse() { 00623 ReadNode = 0; 00624 CurrentNode = NextFreeNode; 00625 NextFreeNode = 0; 00626 } 00627 00628 /// Parent - Move the current read node to its parent. 00629 void Parent() { 00630 ReadNode = FlatTree[ReadNode].ParentNode; 00631 } 00632 00633 /// GetNode - Gets the FromType and ToType. 00634 void GetNode(QualType &FromType, QualType &ToType) { 00635 FromType = FlatTree[ReadNode].FromType; 00636 ToType = FlatTree[ReadNode].ToType; 00637 } 00638 00639 /// GetNode - Gets the FromExpr and ToExpr. 00640 void GetNode(Expr *&FromExpr, Expr *&ToExpr) { 00641 FromExpr = FlatTree[ReadNode].FromExpr; 00642 ToExpr = FlatTree[ReadNode].ToExpr; 00643 } 00644 00645 /// GetNode - Gets the FromTD and ToTD. 00646 void GetNode(TemplateDecl *&FromTD, TemplateDecl *&ToTD) { 00647 FromTD = FlatTree[ReadNode].FromTD; 00648 ToTD = FlatTree[ReadNode].ToTD; 00649 } 00650 00651 /// GetNode - Gets the FromInt and ToInt. 00652 void GetNode(llvm::APSInt &FromInt, llvm::APSInt &ToInt, 00653 bool &IsValidFromInt, bool &IsValidToInt) { 00654 FromInt = FlatTree[ReadNode].FromInt; 00655 ToInt = FlatTree[ReadNode].ToInt; 00656 IsValidFromInt = FlatTree[ReadNode].IsValidFromInt; 00657 IsValidToInt = FlatTree[ReadNode].IsValidToInt; 00658 } 00659 00660 /// GetNode - Gets the FromQual and ToQual. 00661 void GetNode(Qualifiers &FromQual, Qualifiers &ToQual) { 00662 FromQual = FlatTree[ReadNode].FromQual; 00663 ToQual = FlatTree[ReadNode].ToQual; 00664 } 00665 00666 /// GetNode - Gets the FromValueDecl and ToValueDecl. 00667 void GetNode(ValueDecl *&FromValueDecl, ValueDecl *&ToValueDecl, 00668 bool &FromAddressOf, bool &ToAddressOf) { 00669 FromValueDecl = FlatTree[ReadNode].FromValueDecl; 00670 ToValueDecl = FlatTree[ReadNode].ToValueDecl; 00671 FromAddressOf = FlatTree[ReadNode].FromAddressOf; 00672 ToAddressOf = FlatTree[ReadNode].ToAddressOf; 00673 } 00674 00675 /// NodeIsSame - Returns true the arguments are the same. 00676 bool NodeIsSame() { 00677 return FlatTree[ReadNode].Same; 00678 } 00679 00680 /// HasChildrend - Returns true if the node has children. 00681 bool HasChildren() { 00682 return FlatTree[ReadNode].ChildNode != 0; 00683 } 00684 00685 /// MoveToChild - Moves from the current node to its child. 00686 void MoveToChild() { 00687 ReadNode = FlatTree[ReadNode].ChildNode; 00688 } 00689 00690 /// AdvanceSibling - If there is a next sibling, advance to it and return 00691 /// true. Otherwise, return false. 00692 bool AdvanceSibling() { 00693 if (FlatTree[ReadNode].NextNode == 0) 00694 return false; 00695 00696 ReadNode = FlatTree[ReadNode].NextNode; 00697 return true; 00698 } 00699 00700 /// HasNextSibling - Return true if the node has a next sibling. 00701 bool HasNextSibling() { 00702 return FlatTree[ReadNode].NextNode != 0; 00703 } 00704 00705 /// FromNullPtr - Returns true if the from argument is null. 00706 bool FromNullPtr() { 00707 return FlatTree[ReadNode].FromNullPtr; 00708 } 00709 00710 /// ToNullPtr - Returns true if the to argument is null. 00711 bool ToNullPtr() { 00712 return FlatTree[ReadNode].ToNullPtr; 00713 } 00714 00715 /// FromDefault - Return true if the from argument is the default. 00716 bool FromDefault() { 00717 return FlatTree[ReadNode].FromDefault; 00718 } 00719 00720 /// ToDefault - Return true if the to argument is the default. 00721 bool ToDefault() { 00722 return FlatTree[ReadNode].ToDefault; 00723 } 00724 00725 /// Empty - Returns true if the tree has no information. 00726 bool Empty() { 00727 return GetKind() == Invalid; 00728 } 00729 00730 /// GetKind - Returns the current node's type. 00731 DiffKind GetKind() { 00732 return FlatTree[ReadNode].Kind; 00733 } 00734 }; 00735 00736 DiffTree Tree; 00737 00738 /// TSTiterator - an iterator that is used to enter a 00739 /// TemplateSpecializationType and read TemplateArguments inside template 00740 /// parameter packs in order with the rest of the TemplateArguments. 00741 struct TSTiterator { 00742 typedef const TemplateArgument& reference; 00743 typedef const TemplateArgument* pointer; 00744 00745 /// TST - the template specialization whose arguments this iterator 00746 /// traverse over. 00747 const TemplateSpecializationType *TST; 00748 00749 /// DesugarTST - desugared template specialization used to extract 00750 /// default argument information 00751 const TemplateSpecializationType *DesugarTST; 00752 00753 /// Index - the index of the template argument in TST. 00754 unsigned Index; 00755 00756 /// CurrentTA - if CurrentTA is not the same as EndTA, then CurrentTA 00757 /// points to a TemplateArgument within a parameter pack. 00758 TemplateArgument::pack_iterator CurrentTA; 00759 00760 /// EndTA - the end iterator of a parameter pack 00761 TemplateArgument::pack_iterator EndTA; 00762 00763 /// TSTiterator - Constructs an iterator and sets it to the first template 00764 /// argument. 00765 TSTiterator(ASTContext &Context, const TemplateSpecializationType *TST) 00766 : TST(TST), 00767 DesugarTST(GetTemplateSpecializationType(Context, TST->desugar())), 00768 Index(0), CurrentTA(nullptr), EndTA(nullptr) { 00769 if (isEnd()) return; 00770 00771 // Set to first template argument. If not a parameter pack, done. 00772 TemplateArgument TA = TST->getArg(0); 00773 if (TA.getKind() != TemplateArgument::Pack) return; 00774 00775 // Start looking into the parameter pack. 00776 CurrentTA = TA.pack_begin(); 00777 EndTA = TA.pack_end(); 00778 00779 // Found a valid template argument. 00780 if (CurrentTA != EndTA) return; 00781 00782 // Parameter pack is empty, use the increment to get to a valid 00783 // template argument. 00784 ++(*this); 00785 } 00786 00787 /// isEnd - Returns true if the iterator is one past the end. 00788 bool isEnd() const { 00789 return Index >= TST->getNumArgs(); 00790 } 00791 00792 /// &operator++ - Increment the iterator to the next template argument. 00793 TSTiterator &operator++() { 00794 // After the end, Index should be the default argument position in 00795 // DesugarTST, if it exists. 00796 if (isEnd()) { 00797 ++Index; 00798 return *this; 00799 } 00800 00801 // If in a parameter pack, advance in the parameter pack. 00802 if (CurrentTA != EndTA) { 00803 ++CurrentTA; 00804 if (CurrentTA != EndTA) 00805 return *this; 00806 } 00807 00808 // Loop until a template argument is found, or the end is reached. 00809 while (true) { 00810 // Advance to the next template argument. Break if reached the end. 00811 if (++Index == TST->getNumArgs()) break; 00812 00813 // If the TemplateArgument is not a parameter pack, done. 00814 TemplateArgument TA = TST->getArg(Index); 00815 if (TA.getKind() != TemplateArgument::Pack) break; 00816 00817 // Handle parameter packs. 00818 CurrentTA = TA.pack_begin(); 00819 EndTA = TA.pack_end(); 00820 00821 // If the parameter pack is empty, try to advance again. 00822 if (CurrentTA != EndTA) break; 00823 } 00824 return *this; 00825 } 00826 00827 /// operator* - Returns the appropriate TemplateArgument. 00828 reference operator*() const { 00829 assert(!isEnd() && "Index exceeds number of arguments."); 00830 if (CurrentTA == EndTA) 00831 return TST->getArg(Index); 00832 else 00833 return *CurrentTA; 00834 } 00835 00836 /// operator-> - Allow access to the underlying TemplateArgument. 00837 pointer operator->() const { 00838 return &operator*(); 00839 } 00840 00841 /// getDesugar - Returns the deduced template argument from DesguarTST 00842 reference getDesugar() const { 00843 return DesugarTST->getArg(Index); 00844 } 00845 }; 00846 00847 // These functions build up the template diff tree, including functions to 00848 // retrieve and compare template arguments. 00849 00850 static const TemplateSpecializationType * GetTemplateSpecializationType( 00851 ASTContext &Context, QualType Ty) { 00852 if (const TemplateSpecializationType *TST = 00853 Ty->getAs<TemplateSpecializationType>()) 00854 return TST; 00855 00856 const RecordType *RT = Ty->getAs<RecordType>(); 00857 00858 if (!RT) 00859 return nullptr; 00860 00861 const ClassTemplateSpecializationDecl *CTSD = 00862 dyn_cast<ClassTemplateSpecializationDecl>(RT->getDecl()); 00863 00864 if (!CTSD) 00865 return nullptr; 00866 00867 Ty = Context.getTemplateSpecializationType( 00868 TemplateName(CTSD->getSpecializedTemplate()), 00869 CTSD->getTemplateArgs().data(), 00870 CTSD->getTemplateArgs().size(), 00871 Ty.getLocalUnqualifiedType().getCanonicalType()); 00872 00873 return Ty->getAs<TemplateSpecializationType>(); 00874 } 00875 00876 /// DiffTypes - Fills a DiffNode with information about a type difference. 00877 void DiffTypes(const TSTiterator &FromIter, const TSTiterator &ToIter, 00878 TemplateTypeParmDecl *FromDefaultTypeDecl, 00879 TemplateTypeParmDecl *ToDefaultTypeDecl) { 00880 QualType FromType = GetType(FromIter, FromDefaultTypeDecl); 00881 QualType ToType = GetType(ToIter, ToDefaultTypeDecl); 00882 00883 Tree.SetNode(FromType, ToType); 00884 Tree.SetDefault(FromIter.isEnd() && !FromType.isNull(), 00885 ToIter.isEnd() && !ToType.isNull()); 00886 Tree.SetKind(DiffTree::Type); 00887 if (FromType.isNull() || ToType.isNull()) 00888 return; 00889 00890 if (Context.hasSameType(FromType, ToType)) { 00891 Tree.SetSame(true); 00892 return; 00893 } 00894 00895 const TemplateSpecializationType *FromArgTST = 00896 GetTemplateSpecializationType(Context, FromType); 00897 if (!FromArgTST) 00898 return; 00899 00900 const TemplateSpecializationType *ToArgTST = 00901 GetTemplateSpecializationType(Context, ToType); 00902 if (!ToArgTST) 00903 return; 00904 00905 if (!hasSameTemplate(FromArgTST, ToArgTST)) 00906 return; 00907 00908 Qualifiers FromQual = FromType.getQualifiers(), 00909 ToQual = ToType.getQualifiers(); 00910 FromQual -= QualType(FromArgTST, 0).getQualifiers(); 00911 ToQual -= QualType(ToArgTST, 0).getQualifiers(); 00912 Tree.SetNode(FromArgTST->getTemplateName().getAsTemplateDecl(), 00913 ToArgTST->getTemplateName().getAsTemplateDecl()); 00914 Tree.SetNode(FromQual, ToQual); 00915 Tree.SetKind(DiffTree::Template); 00916 DiffTemplate(FromArgTST, ToArgTST); 00917 } 00918 00919 /// DiffTemplateTemplates - Fills a DiffNode with information about a 00920 /// template template difference. 00921 void DiffTemplateTemplates(const TSTiterator &FromIter, 00922 const TSTiterator &ToIter, 00923 TemplateTemplateParmDecl *FromDefaultTemplateDecl, 00924 TemplateTemplateParmDecl *ToDefaultTemplateDecl) { 00925 TemplateDecl *FromDecl = GetTemplateDecl(FromIter, FromDefaultTemplateDecl); 00926 TemplateDecl *ToDecl = GetTemplateDecl(ToIter, ToDefaultTemplateDecl); 00927 Tree.SetNode(FromDecl, ToDecl); 00928 Tree.SetSame(FromDecl && ToDecl && 00929 FromDecl->getCanonicalDecl() == ToDecl->getCanonicalDecl()); 00930 Tree.SetDefault(FromIter.isEnd() && FromDecl, ToIter.isEnd() && ToDecl); 00931 Tree.SetKind(DiffTree::TemplateTemplate); 00932 } 00933 00934 /// InitializeNonTypeDiffVariables - Helper function for DiffNonTypes 00935 static void InitializeNonTypeDiffVariables( 00936 ASTContext &Context, const TSTiterator &Iter, 00937 NonTypeTemplateParmDecl *Default, bool &HasInt, bool &HasValueDecl, 00938 bool &IsNullPtr, Expr *&E, llvm::APSInt &Value, ValueDecl *&VD) { 00939 HasInt = !Iter.isEnd() && Iter->getKind() == TemplateArgument::Integral; 00940 00941 HasValueDecl = 00942 !Iter.isEnd() && Iter->getKind() == TemplateArgument::Declaration; 00943 00944 IsNullPtr = !Iter.isEnd() && Iter->getKind() == TemplateArgument::NullPtr; 00945 00946 if (HasInt) 00947 Value = Iter->getAsIntegral(); 00948 else if (HasValueDecl) 00949 VD = Iter->getAsDecl(); 00950 else if (!IsNullPtr) 00951 E = GetExpr(Iter, Default); 00952 00953 if (E && Default->getType()->isPointerType()) 00954 IsNullPtr = CheckForNullPtr(Context, E); 00955 } 00956 00957 /// NeedsAddressOf - Helper function for DiffNonTypes. Returns true if the 00958 /// ValueDecl needs a '&' when printed. 00959 static bool NeedsAddressOf(ValueDecl *VD, Expr *E, 00960 NonTypeTemplateParmDecl *Default) { 00961 if (!VD) 00962 return false; 00963 00964 if (E) { 00965 if (UnaryOperator *UO = dyn_cast<UnaryOperator>(E->IgnoreParens())) { 00966 if (UO->getOpcode() == UO_AddrOf) { 00967 return true; 00968 } 00969 } 00970 return false; 00971 } 00972 00973 if (!Default->getType()->isReferenceType()) { 00974 return true; 00975 } 00976 00977 return false; 00978 } 00979 00980 /// DiffNonTypes - Handles any template parameters not handled by DiffTypes 00981 /// of DiffTemplatesTemplates, such as integer and declaration parameters. 00982 void DiffNonTypes(const TSTiterator &FromIter, const TSTiterator &ToIter, 00983 NonTypeTemplateParmDecl *FromDefaultNonTypeDecl, 00984 NonTypeTemplateParmDecl *ToDefaultNonTypeDecl) { 00985 Expr *FromExpr = nullptr, *ToExpr = nullptr; 00986 llvm::APSInt FromInt, ToInt; 00987 ValueDecl *FromValueDecl = nullptr, *ToValueDecl = nullptr; 00988 bool HasFromInt = false, HasToInt = false, HasFromValueDecl = false, 00989 HasToValueDecl = false, FromNullPtr = false, ToNullPtr = false; 00990 InitializeNonTypeDiffVariables(Context, FromIter, FromDefaultNonTypeDecl, 00991 HasFromInt, HasFromValueDecl, FromNullPtr, 00992 FromExpr, FromInt, FromValueDecl); 00993 InitializeNonTypeDiffVariables(Context, ToIter, ToDefaultNonTypeDecl, 00994 HasToInt, HasToValueDecl, ToNullPtr, 00995 ToExpr, ToInt, ToValueDecl); 00996 00997 assert(((!HasFromInt && !HasToInt) || 00998 (!HasFromValueDecl && !HasToValueDecl)) && 00999 "Template argument cannot be both integer and declaration"); 01000 01001 unsigned ParamWidth = 128; // Safe default 01002 if (FromDefaultNonTypeDecl->getType()->isIntegralOrEnumerationType()) 01003 ParamWidth = Context.getIntWidth(FromDefaultNonTypeDecl->getType()); 01004 01005 if (!HasFromInt && !HasToInt && !HasFromValueDecl && !HasToValueDecl) { 01006 Tree.SetNode(FromExpr, ToExpr); 01007 Tree.SetDefault(FromIter.isEnd() && FromExpr, ToIter.isEnd() && ToExpr); 01008 if (FromDefaultNonTypeDecl->getType()->isIntegralOrEnumerationType()) { 01009 if (FromExpr) 01010 HasFromInt = GetInt(Context, FromIter, FromExpr, FromInt); 01011 if (ToExpr) 01012 HasToInt = GetInt(Context, ToIter, ToExpr, ToInt); 01013 } 01014 if (HasFromInt && HasToInt) { 01015 Tree.SetNode(FromInt, ToInt, HasFromInt, HasToInt); 01016 Tree.SetSame(IsSameConvertedInt(ParamWidth, FromInt, ToInt)); 01017 Tree.SetKind(DiffTree::Integer); 01018 } else if (HasFromInt || HasToInt) { 01019 Tree.SetNode(FromInt, ToInt, HasFromInt, HasToInt); 01020 Tree.SetSame(false); 01021 Tree.SetKind(DiffTree::Integer); 01022 } else { 01023 Tree.SetSame(IsEqualExpr(Context, ParamWidth, FromExpr, ToExpr) || 01024 (FromNullPtr && ToNullPtr)); 01025 Tree.SetNullPtr(FromNullPtr, ToNullPtr); 01026 Tree.SetKind(DiffTree::Expression); 01027 } 01028 return; 01029 } 01030 01031 if (HasFromInt || HasToInt) { 01032 if (!HasFromInt && FromExpr) 01033 HasFromInt = GetInt(Context, FromIter, FromExpr, FromInt); 01034 if (!HasToInt && ToExpr) 01035 HasToInt = GetInt(Context, ToIter, ToExpr, ToInt); 01036 Tree.SetNode(FromInt, ToInt, HasFromInt, HasToInt); 01037 Tree.SetSame(IsSameConvertedInt(ParamWidth, FromInt, ToInt)); 01038 Tree.SetDefault(FromIter.isEnd() && HasFromInt, 01039 ToIter.isEnd() && HasToInt); 01040 Tree.SetKind(DiffTree::Integer); 01041 return; 01042 } 01043 01044 if (!HasFromValueDecl && FromExpr) 01045 FromValueDecl = GetValueDecl(FromIter, FromExpr); 01046 if (!HasToValueDecl && ToExpr) 01047 ToValueDecl = GetValueDecl(ToIter, ToExpr); 01048 01049 bool FromAddressOf = 01050 NeedsAddressOf(FromValueDecl, FromExpr, FromDefaultNonTypeDecl); 01051 bool ToAddressOf = 01052 NeedsAddressOf(ToValueDecl, ToExpr, ToDefaultNonTypeDecl); 01053 01054 Tree.SetNullPtr(FromNullPtr, ToNullPtr); 01055 Tree.SetNode(FromValueDecl, ToValueDecl, FromAddressOf, ToAddressOf); 01056 Tree.SetSame(FromValueDecl && ToValueDecl && 01057 FromValueDecl->getCanonicalDecl() == 01058 ToValueDecl->getCanonicalDecl()); 01059 Tree.SetDefault(FromIter.isEnd() && FromValueDecl, 01060 ToIter.isEnd() && ToValueDecl); 01061 Tree.SetKind(DiffTree::Declaration); 01062 } 01063 01064 /// DiffTemplate - recursively visits template arguments and stores the 01065 /// argument info into a tree. 01066 void DiffTemplate(const TemplateSpecializationType *FromTST, 01067 const TemplateSpecializationType *ToTST) { 01068 // Begin descent into diffing template tree. 01069 TemplateParameterList *ParamsFrom = 01070 FromTST->getTemplateName().getAsTemplateDecl()->getTemplateParameters(); 01071 TemplateParameterList *ParamsTo = 01072 ToTST->getTemplateName().getAsTemplateDecl()->getTemplateParameters(); 01073 unsigned TotalArgs = 0; 01074 for (TSTiterator FromIter(Context, FromTST), ToIter(Context, ToTST); 01075 !FromIter.isEnd() || !ToIter.isEnd(); ++TotalArgs) { 01076 Tree.AddNode(); 01077 01078 // Get the parameter at index TotalArgs. If index is larger 01079 // than the total number of parameters, then there is an 01080 // argument pack, so re-use the last parameter. 01081 unsigned FromParamIndex = std::min(TotalArgs, ParamsFrom->size() - 1); 01082 unsigned ToParamIndex = std::min(TotalArgs, ParamsTo->size() - 1); 01083 NamedDecl *FromParamND = ParamsFrom->getParam(FromParamIndex); 01084 NamedDecl *ToParamND = ParamsTo->getParam(ToParamIndex); 01085 01086 TemplateTypeParmDecl *FromDefaultTypeDecl = 01087 dyn_cast<TemplateTypeParmDecl>(FromParamND); 01088 TemplateTypeParmDecl *ToDefaultTypeDecl = 01089 dyn_cast<TemplateTypeParmDecl>(ToParamND); 01090 if (FromDefaultTypeDecl && ToDefaultTypeDecl) 01091 DiffTypes(FromIter, ToIter, FromDefaultTypeDecl, ToDefaultTypeDecl); 01092 01093 TemplateTemplateParmDecl *FromDefaultTemplateDecl = 01094 dyn_cast<TemplateTemplateParmDecl>(FromParamND); 01095 TemplateTemplateParmDecl *ToDefaultTemplateDecl = 01096 dyn_cast<TemplateTemplateParmDecl>(ToParamND); 01097 if (FromDefaultTemplateDecl && ToDefaultTemplateDecl) 01098 DiffTemplateTemplates(FromIter, ToIter, FromDefaultTemplateDecl, 01099 ToDefaultTemplateDecl); 01100 01101 NonTypeTemplateParmDecl *FromDefaultNonTypeDecl = 01102 dyn_cast<NonTypeTemplateParmDecl>(FromParamND); 01103 NonTypeTemplateParmDecl *ToDefaultNonTypeDecl = 01104 dyn_cast<NonTypeTemplateParmDecl>(ToParamND); 01105 if (FromDefaultNonTypeDecl && ToDefaultNonTypeDecl) 01106 DiffNonTypes(FromIter, ToIter, FromDefaultNonTypeDecl, 01107 ToDefaultNonTypeDecl); 01108 01109 ++FromIter; 01110 ++ToIter; 01111 Tree.Up(); 01112 } 01113 } 01114 01115 /// makeTemplateList - Dump every template alias into the vector. 01116 static void makeTemplateList( 01117 SmallVectorImpl<const TemplateSpecializationType *> &TemplateList, 01118 const TemplateSpecializationType *TST) { 01119 while (TST) { 01120 TemplateList.push_back(TST); 01121 if (!TST->isTypeAlias()) 01122 return; 01123 TST = TST->getAliasedType()->getAs<TemplateSpecializationType>(); 01124 } 01125 } 01126 01127 /// hasSameBaseTemplate - Returns true when the base templates are the same, 01128 /// even if the template arguments are not. 01129 static bool hasSameBaseTemplate(const TemplateSpecializationType *FromTST, 01130 const TemplateSpecializationType *ToTST) { 01131 return FromTST->getTemplateName().getAsTemplateDecl()->getCanonicalDecl() == 01132 ToTST->getTemplateName().getAsTemplateDecl()->getCanonicalDecl(); 01133 } 01134 01135 /// hasSameTemplate - Returns true if both types are specialized from the 01136 /// same template declaration. If they come from different template aliases, 01137 /// do a parallel ascension search to determine the highest template alias in 01138 /// common and set the arguments to them. 01139 static bool hasSameTemplate(const TemplateSpecializationType *&FromTST, 01140 const TemplateSpecializationType *&ToTST) { 01141 // Check the top templates if they are the same. 01142 if (hasSameBaseTemplate(FromTST, ToTST)) 01143 return true; 01144 01145 // Create vectors of template aliases. 01146 SmallVector<const TemplateSpecializationType*, 1> FromTemplateList, 01147 ToTemplateList; 01148 01149 makeTemplateList(FromTemplateList, FromTST); 01150 makeTemplateList(ToTemplateList, ToTST); 01151 01152 SmallVectorImpl<const TemplateSpecializationType *>::reverse_iterator 01153 FromIter = FromTemplateList.rbegin(), FromEnd = FromTemplateList.rend(), 01154 ToIter = ToTemplateList.rbegin(), ToEnd = ToTemplateList.rend(); 01155 01156 // Check if the lowest template types are the same. If not, return. 01157 if (!hasSameBaseTemplate(*FromIter, *ToIter)) 01158 return false; 01159 01160 // Begin searching up the template aliases. The bottom most template 01161 // matches so move up until one pair does not match. Use the template 01162 // right before that one. 01163 for (; FromIter != FromEnd && ToIter != ToEnd; ++FromIter, ++ToIter) { 01164 if (!hasSameBaseTemplate(*FromIter, *ToIter)) 01165 break; 01166 } 01167 01168 FromTST = FromIter[-1]; 01169 ToTST = ToIter[-1]; 01170 01171 return true; 01172 } 01173 01174 /// GetType - Retrieves the template type arguments, including default 01175 /// arguments. 01176 static QualType GetType(const TSTiterator &Iter, 01177 TemplateTypeParmDecl *DefaultTTPD) { 01178 bool isVariadic = DefaultTTPD->isParameterPack(); 01179 01180 if (!Iter.isEnd()) 01181 return Iter->getAsType(); 01182 if (isVariadic) 01183 return QualType(); 01184 01185 QualType ArgType = DefaultTTPD->getDefaultArgument(); 01186 if (ArgType->isDependentType()) 01187 return Iter.getDesugar().getAsType(); 01188 01189 return ArgType; 01190 } 01191 01192 /// GetExpr - Retrieves the template expression argument, including default 01193 /// arguments. 01194 static Expr *GetExpr(const TSTiterator &Iter, 01195 NonTypeTemplateParmDecl *DefaultNTTPD) { 01196 Expr *ArgExpr = nullptr; 01197 bool isVariadic = DefaultNTTPD->isParameterPack(); 01198 01199 if (!Iter.isEnd()) 01200 ArgExpr = Iter->getAsExpr(); 01201 else if (!isVariadic) 01202 ArgExpr = DefaultNTTPD->getDefaultArgument(); 01203 01204 if (ArgExpr) 01205 while (SubstNonTypeTemplateParmExpr *SNTTPE = 01206 dyn_cast<SubstNonTypeTemplateParmExpr>(ArgExpr)) 01207 ArgExpr = SNTTPE->getReplacement(); 01208 01209 return ArgExpr; 01210 } 01211 01212 /// GetInt - Retrieves the template integer argument, including evaluating 01213 /// default arguments. 01214 static bool GetInt(ASTContext &Context, const TSTiterator &Iter, 01215 Expr *ArgExpr, llvm::APInt &Int) { 01216 // Default, value-depenedent expressions require fetching 01217 // from the desugared TemplateArgument, otherwise expression needs to 01218 // be evaluatable. 01219 if (Iter.isEnd() && ArgExpr->isValueDependent()) { 01220 switch (Iter.getDesugar().getKind()) { 01221 case TemplateArgument::Integral: 01222 Int = Iter.getDesugar().getAsIntegral(); 01223 return true; 01224 case TemplateArgument::Expression: 01225 ArgExpr = Iter.getDesugar().getAsExpr(); 01226 Int = ArgExpr->EvaluateKnownConstInt(Context); 01227 return true; 01228 default: 01229 llvm_unreachable("Unexpected template argument kind"); 01230 } 01231 } else if (ArgExpr->isEvaluatable(Context)) { 01232 Int = ArgExpr->EvaluateKnownConstInt(Context); 01233 return true; 01234 } 01235 01236 return false; 01237 } 01238 01239 /// GetValueDecl - Retrieves the template Decl argument, including 01240 /// default expression argument. 01241 static ValueDecl *GetValueDecl(const TSTiterator &Iter, Expr *ArgExpr) { 01242 // Default, value-depenedent expressions require fetching 01243 // from the desugared TemplateArgument 01244 if (Iter.isEnd() && ArgExpr->isValueDependent()) 01245 switch (Iter.getDesugar().getKind()) { 01246 case TemplateArgument::Declaration: 01247 return Iter.getDesugar().getAsDecl(); 01248 case TemplateArgument::Expression: 01249 ArgExpr = Iter.getDesugar().getAsExpr(); 01250 return cast<DeclRefExpr>(ArgExpr)->getDecl(); 01251 default: 01252 llvm_unreachable("Unexpected template argument kind"); 01253 } 01254 DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(ArgExpr); 01255 if (!DRE) { 01256 UnaryOperator *UO = dyn_cast<UnaryOperator>(ArgExpr->IgnoreParens()); 01257 if (!UO) 01258 return nullptr; 01259 DRE = cast<DeclRefExpr>(UO->getSubExpr()); 01260 } 01261 01262 return DRE->getDecl(); 01263 } 01264 01265 /// CheckForNullPtr - returns true if the expression can be evaluated as 01266 /// a null pointer 01267 static bool CheckForNullPtr(ASTContext &Context, Expr *E) { 01268 assert(E && "Expected expression"); 01269 01270 E = E->IgnoreParenCasts(); 01271 if (E->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) 01272 return true; 01273 01274 DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E); 01275 if (!DRE) 01276 return false; 01277 01278 VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl()); 01279 if (!VD || !VD->hasInit()) 01280 return false; 01281 01282 return VD->getInit()->IgnoreParenCasts()->isNullPointerConstant( 01283 Context, Expr::NPC_ValueDependentIsNull); 01284 } 01285 01286 /// GetTemplateDecl - Retrieves the template template arguments, including 01287 /// default arguments. 01288 static TemplateDecl *GetTemplateDecl(const TSTiterator &Iter, 01289 TemplateTemplateParmDecl *DefaultTTPD) { 01290 bool isVariadic = DefaultTTPD->isParameterPack(); 01291 01292 TemplateArgument TA = DefaultTTPD->getDefaultArgument().getArgument(); 01293 TemplateDecl *DefaultTD = nullptr; 01294 if (TA.getKind() != TemplateArgument::Null) 01295 DefaultTD = TA.getAsTemplate().getAsTemplateDecl(); 01296 01297 if (!Iter.isEnd()) 01298 return Iter->getAsTemplate().getAsTemplateDecl(); 01299 if (!isVariadic) 01300 return DefaultTD; 01301 01302 return nullptr; 01303 } 01304 01305 /// IsSameConvertedInt - Returns true if both integers are equal when 01306 /// converted to an integer type with the given width. 01307 static bool IsSameConvertedInt(unsigned Width, const llvm::APSInt &X, 01308 const llvm::APSInt &Y) { 01309 llvm::APInt ConvertedX = X.extOrTrunc(Width); 01310 llvm::APInt ConvertedY = Y.extOrTrunc(Width); 01311 return ConvertedX == ConvertedY; 01312 } 01313 01314 /// IsEqualExpr - Returns true if the expressions evaluate to the same value. 01315 static bool IsEqualExpr(ASTContext &Context, unsigned ParamWidth, 01316 Expr *FromExpr, Expr *ToExpr) { 01317 if (FromExpr == ToExpr) 01318 return true; 01319 01320 if (!FromExpr || !ToExpr) 01321 return false; 01322 01323 DeclRefExpr *FromDRE = dyn_cast<DeclRefExpr>(FromExpr->IgnoreParens()), 01324 *ToDRE = dyn_cast<DeclRefExpr>(ToExpr->IgnoreParens()); 01325 01326 if (FromDRE || ToDRE) { 01327 if (!FromDRE || !ToDRE) 01328 return false; 01329 return FromDRE->getDecl() == ToDRE->getDecl(); 01330 } 01331 01332 Expr::EvalResult FromResult, ToResult; 01333 if (!FromExpr->EvaluateAsRValue(FromResult, Context) || 01334 !ToExpr->EvaluateAsRValue(ToResult, Context)) { 01335 llvm::FoldingSetNodeID FromID, ToID; 01336 FromExpr->Profile(FromID, Context, true); 01337 ToExpr->Profile(ToID, Context, true); 01338 return FromID == ToID; 01339 } 01340 01341 APValue &FromVal = FromResult.Val; 01342 APValue &ToVal = ToResult.Val; 01343 01344 if (FromVal.getKind() != ToVal.getKind()) return false; 01345 01346 switch (FromVal.getKind()) { 01347 case APValue::Int: 01348 return IsSameConvertedInt(ParamWidth, FromVal.getInt(), ToVal.getInt()); 01349 case APValue::LValue: { 01350 APValue::LValueBase FromBase = FromVal.getLValueBase(); 01351 APValue::LValueBase ToBase = ToVal.getLValueBase(); 01352 if (FromBase.isNull() && ToBase.isNull()) 01353 return true; 01354 if (FromBase.isNull() || ToBase.isNull()) 01355 return false; 01356 return FromBase.get<const ValueDecl*>() == 01357 ToBase.get<const ValueDecl*>(); 01358 } 01359 case APValue::MemberPointer: 01360 return FromVal.getMemberPointerDecl() == ToVal.getMemberPointerDecl(); 01361 default: 01362 llvm_unreachable("Unknown template argument expression."); 01363 } 01364 } 01365 01366 // These functions converts the tree representation of the template 01367 // differences into the internal character vector. 01368 01369 /// TreeToString - Converts the Tree object into a character stream which 01370 /// will later be turned into the output string. 01371 void TreeToString(int Indent = 1) { 01372 if (PrintTree) { 01373 OS << '\n'; 01374 OS.indent(2 * Indent); 01375 ++Indent; 01376 } 01377 01378 // Handle cases where the difference is not templates with different 01379 // arguments. 01380 switch (Tree.GetKind()) { 01381 case DiffTree::Invalid: 01382 llvm_unreachable("Template diffing failed with bad DiffNode"); 01383 case DiffTree::Type: { 01384 QualType FromType, ToType; 01385 Tree.GetNode(FromType, ToType); 01386 PrintTypeNames(FromType, ToType, Tree.FromDefault(), Tree.ToDefault(), 01387 Tree.NodeIsSame()); 01388 return; 01389 } 01390 case DiffTree::Expression: { 01391 Expr *FromExpr, *ToExpr; 01392 Tree.GetNode(FromExpr, ToExpr); 01393 PrintExpr(FromExpr, ToExpr, Tree.FromNullPtr(), Tree.ToNullPtr(), 01394 Tree.FromDefault(), Tree.ToDefault(), Tree.NodeIsSame()); 01395 return; 01396 } 01397 case DiffTree::TemplateTemplate: { 01398 TemplateDecl *FromTD, *ToTD; 01399 Tree.GetNode(FromTD, ToTD); 01400 PrintTemplateTemplate(FromTD, ToTD, Tree.FromDefault(), 01401 Tree.ToDefault(), Tree.NodeIsSame()); 01402 return; 01403 } 01404 case DiffTree::Integer: { 01405 llvm::APSInt FromInt, ToInt; 01406 Expr *FromExpr, *ToExpr; 01407 bool IsValidFromInt, IsValidToInt; 01408 Tree.GetNode(FromExpr, ToExpr); 01409 Tree.GetNode(FromInt, ToInt, IsValidFromInt, IsValidToInt); 01410 PrintAPSInt(FromInt, ToInt, IsValidFromInt, IsValidToInt, 01411 FromExpr, ToExpr, Tree.FromDefault(), Tree.ToDefault(), 01412 Tree.NodeIsSame()); 01413 return; 01414 } 01415 case DiffTree::Declaration: { 01416 ValueDecl *FromValueDecl, *ToValueDecl; 01417 bool FromAddressOf, ToAddressOf; 01418 Tree.GetNode(FromValueDecl, ToValueDecl, FromAddressOf, ToAddressOf); 01419 PrintValueDecl(FromValueDecl, ToValueDecl, FromAddressOf, ToAddressOf, 01420 Tree.FromNullPtr(), Tree.ToNullPtr(), Tree.FromDefault(), 01421 Tree.ToDefault(), Tree.NodeIsSame()); 01422 return; 01423 } 01424 case DiffTree::Template: { 01425 // Node is root of template. Recurse on children. 01426 TemplateDecl *FromTD, *ToTD; 01427 Tree.GetNode(FromTD, ToTD); 01428 01429 if (!Tree.HasChildren()) { 01430 // If we're dealing with a template specialization with zero 01431 // arguments, there are no children; special-case this. 01432 OS << FromTD->getNameAsString() << "<>"; 01433 return; 01434 } 01435 01436 Qualifiers FromQual, ToQual; 01437 Tree.GetNode(FromQual, ToQual); 01438 PrintQualifiers(FromQual, ToQual); 01439 01440 OS << FromTD->getNameAsString() << '<'; 01441 Tree.MoveToChild(); 01442 unsigned NumElideArgs = 0; 01443 do { 01444 if (ElideType) { 01445 if (Tree.NodeIsSame()) { 01446 ++NumElideArgs; 01447 continue; 01448 } 01449 if (NumElideArgs > 0) { 01450 PrintElideArgs(NumElideArgs, Indent); 01451 NumElideArgs = 0; 01452 OS << ", "; 01453 } 01454 } 01455 TreeToString(Indent); 01456 if (Tree.HasNextSibling()) 01457 OS << ", "; 01458 } while (Tree.AdvanceSibling()); 01459 if (NumElideArgs > 0) 01460 PrintElideArgs(NumElideArgs, Indent); 01461 01462 Tree.Parent(); 01463 OS << ">"; 01464 return; 01465 } 01466 } 01467 } 01468 01469 // To signal to the text printer that a certain text needs to be bolded, 01470 // a special character is injected into the character stream which the 01471 // text printer will later strip out. 01472 01473 /// Bold - Start bolding text. 01474 void Bold() { 01475 assert(!IsBold && "Attempting to bold text that is already bold."); 01476 IsBold = true; 01477 if (ShowColor) 01478 OS << ToggleHighlight; 01479 } 01480 01481 /// Unbold - Stop bolding text. 01482 void Unbold() { 01483 assert(IsBold && "Attempting to remove bold from unbold text."); 01484 IsBold = false; 01485 if (ShowColor) 01486 OS << ToggleHighlight; 01487 } 01488 01489 // Functions to print out the arguments and highlighting the difference. 01490 01491 /// PrintTypeNames - prints the typenames, bolding differences. Will detect 01492 /// typenames that are the same and attempt to disambiguate them by using 01493 /// canonical typenames. 01494 void PrintTypeNames(QualType FromType, QualType ToType, 01495 bool FromDefault, bool ToDefault, bool Same) { 01496 assert((!FromType.isNull() || !ToType.isNull()) && 01497 "Only one template argument may be missing."); 01498 01499 if (Same) { 01500 OS << FromType.getAsString(Policy); 01501 return; 01502 } 01503 01504 if (!FromType.isNull() && !ToType.isNull() && 01505 FromType.getLocalUnqualifiedType() == 01506 ToType.getLocalUnqualifiedType()) { 01507 Qualifiers FromQual = FromType.getLocalQualifiers(), 01508 ToQual = ToType.getLocalQualifiers(); 01509 PrintQualifiers(FromQual, ToQual); 01510 FromType.getLocalUnqualifiedType().print(OS, Policy); 01511 return; 01512 } 01513 01514 std::string FromTypeStr = FromType.isNull() ? "(no argument)" 01515 : FromType.getAsString(Policy); 01516 std::string ToTypeStr = ToType.isNull() ? "(no argument)" 01517 : ToType.getAsString(Policy); 01518 // Switch to canonical typename if it is better. 01519 // TODO: merge this with other aka printing above. 01520 if (FromTypeStr == ToTypeStr) { 01521 std::string FromCanTypeStr = 01522 FromType.getCanonicalType().getAsString(Policy); 01523 std::string ToCanTypeStr = ToType.getCanonicalType().getAsString(Policy); 01524 if (FromCanTypeStr != ToCanTypeStr) { 01525 FromTypeStr = FromCanTypeStr; 01526 ToTypeStr = ToCanTypeStr; 01527 } 01528 } 01529 01530 if (PrintTree) OS << '['; 01531 OS << (FromDefault ? "(default) " : ""); 01532 Bold(); 01533 OS << FromTypeStr; 01534 Unbold(); 01535 if (PrintTree) { 01536 OS << " != " << (ToDefault ? "(default) " : ""); 01537 Bold(); 01538 OS << ToTypeStr; 01539 Unbold(); 01540 OS << "]"; 01541 } 01542 return; 01543 } 01544 01545 /// PrintExpr - Prints out the expr template arguments, highlighting argument 01546 /// differences. 01547 void PrintExpr(const Expr *FromExpr, const Expr *ToExpr, bool FromNullPtr, 01548 bool ToNullPtr, bool FromDefault, bool ToDefault, bool Same) { 01549 assert((FromExpr || ToExpr) && 01550 "Only one template argument may be missing."); 01551 if (Same) { 01552 PrintExpr(FromExpr, FromNullPtr); 01553 } else if (!PrintTree) { 01554 OS << (FromDefault ? "(default) " : ""); 01555 Bold(); 01556 PrintExpr(FromExpr, FromNullPtr); 01557 Unbold(); 01558 } else { 01559 OS << (FromDefault ? "[(default) " : "["); 01560 Bold(); 01561 PrintExpr(FromExpr, FromNullPtr); 01562 Unbold(); 01563 OS << " != " << (ToDefault ? "(default) " : ""); 01564 Bold(); 01565 PrintExpr(ToExpr, ToNullPtr); 01566 Unbold(); 01567 OS << ']'; 01568 } 01569 } 01570 01571 /// PrintExpr - Actual formatting and printing of expressions. 01572 void PrintExpr(const Expr *E, bool NullPtr = false) { 01573 if (E) { 01574 E->printPretty(OS, nullptr, Policy); 01575 return; 01576 } 01577 if (NullPtr) { 01578 OS << "nullptr"; 01579 return; 01580 } 01581 OS << "(no argument)"; 01582 } 01583 01584 /// PrintTemplateTemplate - Handles printing of template template arguments, 01585 /// highlighting argument differences. 01586 void PrintTemplateTemplate(TemplateDecl *FromTD, TemplateDecl *ToTD, 01587 bool FromDefault, bool ToDefault, bool Same) { 01588 assert((FromTD || ToTD) && "Only one template argument may be missing."); 01589 01590 std::string FromName = FromTD ? FromTD->getName() : "(no argument)"; 01591 std::string ToName = ToTD ? ToTD->getName() : "(no argument)"; 01592 if (FromTD && ToTD && FromName == ToName) { 01593 FromName = FromTD->getQualifiedNameAsString(); 01594 ToName = ToTD->getQualifiedNameAsString(); 01595 } 01596 01597 if (Same) { 01598 OS << "template " << FromTD->getNameAsString(); 01599 } else if (!PrintTree) { 01600 OS << (FromDefault ? "(default) template " : "template "); 01601 Bold(); 01602 OS << FromName; 01603 Unbold(); 01604 } else { 01605 OS << (FromDefault ? "[(default) template " : "[template "); 01606 Bold(); 01607 OS << FromName; 01608 Unbold(); 01609 OS << " != " << (ToDefault ? "(default) template " : "template "); 01610 Bold(); 01611 OS << ToName; 01612 Unbold(); 01613 OS << ']'; 01614 } 01615 } 01616 01617 /// PrintAPSInt - Handles printing of integral arguments, highlighting 01618 /// argument differences. 01619 void PrintAPSInt(llvm::APSInt FromInt, llvm::APSInt ToInt, 01620 bool IsValidFromInt, bool IsValidToInt, Expr *FromExpr, 01621 Expr *ToExpr, bool FromDefault, bool ToDefault, bool Same) { 01622 assert((IsValidFromInt || IsValidToInt) && 01623 "Only one integral argument may be missing."); 01624 01625 if (Same) { 01626 OS << FromInt.toString(10); 01627 } else if (!PrintTree) { 01628 OS << (FromDefault ? "(default) " : ""); 01629 PrintAPSInt(FromInt, FromExpr, IsValidFromInt); 01630 } else { 01631 OS << (FromDefault ? "[(default) " : "["); 01632 PrintAPSInt(FromInt, FromExpr, IsValidFromInt); 01633 OS << " != " << (ToDefault ? "(default) " : ""); 01634 PrintAPSInt(ToInt, ToExpr, IsValidToInt); 01635 OS << ']'; 01636 } 01637 } 01638 01639 /// PrintAPSInt - If valid, print the APSInt. If the expression is 01640 /// gives more information, print it too. 01641 void PrintAPSInt(llvm::APSInt Val, Expr *E, bool Valid) { 01642 Bold(); 01643 if (Valid) { 01644 if (HasExtraInfo(E)) { 01645 PrintExpr(E); 01646 Unbold(); 01647 OS << " aka "; 01648 Bold(); 01649 } 01650 OS << Val.toString(10); 01651 } else if (E) { 01652 PrintExpr(E); 01653 } else { 01654 OS << "(no argument)"; 01655 } 01656 Unbold(); 01657 } 01658 01659 /// HasExtraInfo - Returns true if E is not an integer literal or the 01660 /// negation of an integer literal 01661 bool HasExtraInfo(Expr *E) { 01662 if (!E) return false; 01663 if (isa<IntegerLiteral>(E)) return false; 01664 01665 if (UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) 01666 if (UO->getOpcode() == UO_Minus) 01667 if (isa<IntegerLiteral>(UO->getSubExpr())) 01668 return false; 01669 01670 return true; 01671 } 01672 01673 void PrintValueDecl(ValueDecl *VD, bool AddressOf, bool NullPtr) { 01674 if (VD) { 01675 if (AddressOf) 01676 OS << "&"; 01677 OS << VD->getName(); 01678 return; 01679 } 01680 01681 if (NullPtr) { 01682 OS << "nullptr"; 01683 return; 01684 } 01685 01686 OS << "(no argument)"; 01687 } 01688 01689 /// PrintDecl - Handles printing of Decl arguments, highlighting 01690 /// argument differences. 01691 void PrintValueDecl(ValueDecl *FromValueDecl, ValueDecl *ToValueDecl, 01692 bool FromAddressOf, bool ToAddressOf, bool FromNullPtr, 01693 bool ToNullPtr, bool FromDefault, bool ToDefault, 01694 bool Same) { 01695 assert((FromValueDecl || FromNullPtr || ToValueDecl || ToNullPtr) && 01696 "Only one Decl argument may be NULL"); 01697 01698 if (Same) { 01699 PrintValueDecl(FromValueDecl, FromAddressOf, FromNullPtr); 01700 } else if (!PrintTree) { 01701 OS << (FromDefault ? "(default) " : ""); 01702 Bold(); 01703 PrintValueDecl(FromValueDecl, FromAddressOf, FromNullPtr); 01704 Unbold(); 01705 } else { 01706 OS << (FromDefault ? "[(default) " : "["); 01707 Bold(); 01708 PrintValueDecl(FromValueDecl, FromAddressOf, FromNullPtr); 01709 Unbold(); 01710 OS << " != " << (ToDefault ? "(default) " : ""); 01711 Bold(); 01712 PrintValueDecl(ToValueDecl, ToAddressOf, ToNullPtr); 01713 Unbold(); 01714 OS << ']'; 01715 } 01716 01717 } 01718 01719 // Prints the appropriate placeholder for elided template arguments. 01720 void PrintElideArgs(unsigned NumElideArgs, unsigned Indent) { 01721 if (PrintTree) { 01722 OS << '\n'; 01723 for (unsigned i = 0; i < Indent; ++i) 01724 OS << " "; 01725 } 01726 if (NumElideArgs == 0) return; 01727 if (NumElideArgs == 1) 01728 OS << "[...]"; 01729 else 01730 OS << "[" << NumElideArgs << " * ...]"; 01731 } 01732 01733 // Prints and highlights differences in Qualifiers. 01734 void PrintQualifiers(Qualifiers FromQual, Qualifiers ToQual) { 01735 // Both types have no qualifiers 01736 if (FromQual.empty() && ToQual.empty()) 01737 return; 01738 01739 // Both types have same qualifiers 01740 if (FromQual == ToQual) { 01741 PrintQualifier(FromQual, /*ApplyBold*/false); 01742 return; 01743 } 01744 01745 // Find common qualifiers and strip them from FromQual and ToQual. 01746 Qualifiers CommonQual = Qualifiers::removeCommonQualifiers(FromQual, 01747 ToQual); 01748 01749 // The qualifiers are printed before the template name. 01750 // Inline printing: 01751 // The common qualifiers are printed. Then, qualifiers only in this type 01752 // are printed and highlighted. Finally, qualifiers only in the other 01753 // type are printed and highlighted inside parentheses after "missing". 01754 // Tree printing: 01755 // Qualifiers are printed next to each other, inside brackets, and 01756 // separated by "!=". The printing order is: 01757 // common qualifiers, highlighted from qualifiers, "!=", 01758 // common qualifiers, highlighted to qualifiers 01759 if (PrintTree) { 01760 OS << "["; 01761 if (CommonQual.empty() && FromQual.empty()) { 01762 Bold(); 01763 OS << "(no qualifiers) "; 01764 Unbold(); 01765 } else { 01766 PrintQualifier(CommonQual, /*ApplyBold*/false); 01767 PrintQualifier(FromQual, /*ApplyBold*/true); 01768 } 01769 OS << "!= "; 01770 if (CommonQual.empty() && ToQual.empty()) { 01771 Bold(); 01772 OS << "(no qualifiers)"; 01773 Unbold(); 01774 } else { 01775 PrintQualifier(CommonQual, /*ApplyBold*/false, 01776 /*appendSpaceIfNonEmpty*/!ToQual.empty()); 01777 PrintQualifier(ToQual, /*ApplyBold*/true, 01778 /*appendSpaceIfNonEmpty*/false); 01779 } 01780 OS << "] "; 01781 } else { 01782 PrintQualifier(CommonQual, /*ApplyBold*/false); 01783 PrintQualifier(FromQual, /*ApplyBold*/true); 01784 } 01785 } 01786 01787 void PrintQualifier(Qualifiers Q, bool ApplyBold, 01788 bool AppendSpaceIfNonEmpty = true) { 01789 if (Q.empty()) return; 01790 if (ApplyBold) Bold(); 01791 Q.print(OS, Policy, AppendSpaceIfNonEmpty); 01792 if (ApplyBold) Unbold(); 01793 } 01794 01795 public: 01796 01797 TemplateDiff(raw_ostream &OS, ASTContext &Context, QualType FromType, 01798 QualType ToType, bool PrintTree, bool PrintFromType, 01799 bool ElideType, bool ShowColor) 01800 : Context(Context), 01801 Policy(Context.getLangOpts()), 01802 ElideType(ElideType), 01803 PrintTree(PrintTree), 01804 ShowColor(ShowColor), 01805 // When printing a single type, the FromType is the one printed. 01806 FromType(PrintFromType ? FromType : ToType), 01807 ToType(PrintFromType ? ToType : FromType), 01808 OS(OS), 01809 IsBold(false) { 01810 } 01811 01812 /// DiffTemplate - Start the template type diffing. 01813 void DiffTemplate() { 01814 Qualifiers FromQual = FromType.getQualifiers(), 01815 ToQual = ToType.getQualifiers(); 01816 01817 const TemplateSpecializationType *FromOrigTST = 01818 GetTemplateSpecializationType(Context, FromType); 01819 const TemplateSpecializationType *ToOrigTST = 01820 GetTemplateSpecializationType(Context, ToType); 01821 01822 // Only checking templates. 01823 if (!FromOrigTST || !ToOrigTST) 01824 return; 01825 01826 // Different base templates. 01827 if (!hasSameTemplate(FromOrigTST, ToOrigTST)) { 01828 return; 01829 } 01830 01831 FromQual -= QualType(FromOrigTST, 0).getQualifiers(); 01832 ToQual -= QualType(ToOrigTST, 0).getQualifiers(); 01833 Tree.SetNode(FromType, ToType); 01834 Tree.SetNode(FromQual, ToQual); 01835 Tree.SetKind(DiffTree::Template); 01836 01837 // Same base template, but different arguments. 01838 Tree.SetNode(FromOrigTST->getTemplateName().getAsTemplateDecl(), 01839 ToOrigTST->getTemplateName().getAsTemplateDecl()); 01840 01841 DiffTemplate(FromOrigTST, ToOrigTST); 01842 } 01843 01844 /// Emit - When the two types given are templated types with the same 01845 /// base template, a string representation of the type difference will be 01846 /// emitted to the stream and return true. Otherwise, return false. 01847 bool Emit() { 01848 Tree.StartTraverse(); 01849 if (Tree.Empty()) 01850 return false; 01851 01852 TreeToString(); 01853 assert(!IsBold && "Bold is applied to end of string."); 01854 return true; 01855 } 01856 }; // end class TemplateDiff 01857 } // end namespace 01858 01859 /// FormatTemplateTypeDiff - A helper static function to start the template 01860 /// diff and return the properly formatted string. Returns true if the diff 01861 /// is successful. 01862 static bool FormatTemplateTypeDiff(ASTContext &Context, QualType FromType, 01863 QualType ToType, bool PrintTree, 01864 bool PrintFromType, bool ElideType, 01865 bool ShowColors, raw_ostream &OS) { 01866 if (PrintTree) 01867 PrintFromType = true; 01868 TemplateDiff TD(OS, Context, FromType, ToType, PrintTree, PrintFromType, 01869 ElideType, ShowColors); 01870 TD.DiffTemplate(); 01871 return TD.Emit(); 01872 }