179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor//===--- ASTDiagnostic.cpp - Diagnostic Printing Hooks for AST Nodes ------===// 279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor// 379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor// The LLVM Compiler Infrastructure 479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor// 579a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor// This file is distributed under the University of Illinois Open Source 679a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor// License. See LICENSE.TXT for details. 779a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor// 879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor//===----------------------------------------------------------------------===// 979a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor// 1079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor// This file implements a diagnostic formatting hook for AST elements. 1179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor// 1279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor//===----------------------------------------------------------------------===// 1379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor#include "clang/AST/ASTDiagnostic.h" 1479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 1579a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor#include "clang/AST/ASTContext.h" 1679a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor#include "clang/AST/DeclObjC.h" 17246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu#include "clang/AST/TemplateBase.h" 18246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu#include "clang/AST/ExprCXX.h" 19246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu#include "clang/AST/DeclTemplate.h" 2079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor#include "clang/AST/Type.h" 21246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu#include "llvm/ADT/SmallString.h" 2279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor#include "llvm/Support/raw_ostream.h" 2379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 2479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregorusing namespace clang; 2579a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 261733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth// Returns a desugared version of the QualType, and marks ShouldAKA as true 271733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth// whenever we remove significant sugar from the type. 281733bc3747f242ddaea5b953d27f514253843e31Chandler Carruthstatic QualType Desugar(ASTContext &Context, QualType QT, bool &ShouldAKA) { 291733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth QualifierCollector QC; 301733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth 3179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor while (true) { 321733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth const Type *Ty = QC.strip(QT); 331733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth 3479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor // Don't aka just because we saw an elaborated type... 3534b41d939a1328f484511c6002ba2456db879a29Richard Smith if (const ElaboratedType *ET = dyn_cast<ElaboratedType>(Ty)) { 3634b41d939a1328f484511c6002ba2456db879a29Richard Smith QT = ET->desugar(); 3779a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor continue; 3879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor } 39075f8f1b6bed4d1b224c74f87508534cc6392ce6Abramo Bagnara // ... or a paren type ... 4034b41d939a1328f484511c6002ba2456db879a29Richard Smith if (const ParenType *PT = dyn_cast<ParenType>(Ty)) { 4134b41d939a1328f484511c6002ba2456db879a29Richard Smith QT = PT->desugar(); 42075f8f1b6bed4d1b224c74f87508534cc6392ce6Abramo Bagnara continue; 43075f8f1b6bed4d1b224c74f87508534cc6392ce6Abramo Bagnara } 4434b41d939a1328f484511c6002ba2456db879a29Richard Smith // ...or a substituted template type parameter ... 4534b41d939a1328f484511c6002ba2456db879a29Richard Smith if (const SubstTemplateTypeParmType *ST = 4634b41d939a1328f484511c6002ba2456db879a29Richard Smith dyn_cast<SubstTemplateTypeParmType>(Ty)) { 4734b41d939a1328f484511c6002ba2456db879a29Richard Smith QT = ST->desugar(); 4834b41d939a1328f484511c6002ba2456db879a29Richard Smith continue; 4934b41d939a1328f484511c6002ba2456db879a29Richard Smith } 5014aa2175416f79ef17811282afbf425f87d54ebfJohn McCall // ...or an attributed type... 5114aa2175416f79ef17811282afbf425f87d54ebfJohn McCall if (const AttributedType *AT = dyn_cast<AttributedType>(Ty)) { 5214aa2175416f79ef17811282afbf425f87d54ebfJohn McCall QT = AT->desugar(); 5314aa2175416f79ef17811282afbf425f87d54ebfJohn McCall continue; 5414aa2175416f79ef17811282afbf425f87d54ebfJohn McCall } 5534b41d939a1328f484511c6002ba2456db879a29Richard Smith // ... or an auto type. 5634b41d939a1328f484511c6002ba2456db879a29Richard Smith if (const AutoType *AT = dyn_cast<AutoType>(Ty)) { 5734b41d939a1328f484511c6002ba2456db879a29Richard Smith if (!AT->isSugared()) 5834b41d939a1328f484511c6002ba2456db879a29Richard Smith break; 5934b41d939a1328f484511c6002ba2456db879a29Richard Smith QT = AT->desugar(); 6079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor continue; 6179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor } 621733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth 633e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith // Don't desugar template specializations, unless it's an alias template. 643e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith if (const TemplateSpecializationType *TST 653e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith = dyn_cast<TemplateSpecializationType>(Ty)) 663e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith if (!TST->isTypeAlias()) 673e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith break; 681733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth 6979a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor // Don't desugar magic Objective-C types. 7079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor if (QualType(Ty,0) == Context.getObjCIdType() || 7179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor QualType(Ty,0) == Context.getObjCClassType() || 7279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor QualType(Ty,0) == Context.getObjCSelType() || 7379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor QualType(Ty,0) == Context.getObjCProtoType()) 7479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor break; 751733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth 7679a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor // Don't desugar va_list. 7779a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor if (QualType(Ty,0) == Context.getBuiltinVaListType()) 7879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor break; 791733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth 8079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor // Otherwise, do a single-step desugar. 8179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor QualType Underlying; 8279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor bool IsSugar = false; 8379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor switch (Ty->getTypeClass()) { 8479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor#define ABSTRACT_TYPE(Class, Base) 8579a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor#define TYPE(Class, Base) \ 8679a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregorcase Type::Class: { \ 8779a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregorconst Class##Type *CTy = cast<Class##Type>(Ty); \ 8879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregorif (CTy->isSugared()) { \ 8979a9a3417929e340e84dcbc06ed9c3a277cad959Douglas GregorIsSugar = true; \ 9079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas GregorUnderlying = CTy->desugar(); \ 9179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor} \ 9279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregorbreak; \ 9379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor} 9479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor#include "clang/AST/TypeNodes.def" 9579a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor } 961733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth 9779a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor // If it wasn't sugared, we're done. 9879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor if (!IsSugar) 9979a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor break; 1001733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth 10179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor // If the desugared type is a vector type, we don't want to expand 10279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor // it, it will turn into an attribute mess. People want their "vec4". 10379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor if (isa<VectorType>(Underlying)) 10479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor break; 1051733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth 10679a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor // Don't desugar through the primary typedef of an anonymous type. 107c3f8c0731ef59ba79753f89f1c108b8134f6ae83Chris Lattner if (const TagType *UTT = Underlying->getAs<TagType>()) 108c3f8c0731ef59ba79753f89f1c108b8134f6ae83Chris Lattner if (const TypedefType *QTT = dyn_cast<TypedefType>(QT)) 109162e1c1b487352434552147967c3dd296ebee2f7Richard Smith if (UTT->getDecl()->getTypedefNameForAnonDecl() == QTT->getDecl()) 110c3f8c0731ef59ba79753f89f1c108b8134f6ae83Chris Lattner break; 1111733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth 1121733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth // Record that we actually looked through an opaque type here. 1131733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth ShouldAKA = true; 11479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor QT = Underlying; 11579a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor } 1161733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth 1171733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth // If we have a pointer-like type, desugar the pointee as well. 1181733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth // FIXME: Handle other pointer-like types. 1191733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth if (const PointerType *Ty = QT->getAs<PointerType>()) { 120c3f8c0731ef59ba79753f89f1c108b8134f6ae83Chris Lattner QT = Context.getPointerType(Desugar(Context, Ty->getPointeeType(), 121c3f8c0731ef59ba79753f89f1c108b8134f6ae83Chris Lattner ShouldAKA)); 1221733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth } else if (const LValueReferenceType *Ty = QT->getAs<LValueReferenceType>()) { 123c3f8c0731ef59ba79753f89f1c108b8134f6ae83Chris Lattner QT = Context.getLValueReferenceType(Desugar(Context, Ty->getPointeeType(), 124c3f8c0731ef59ba79753f89f1c108b8134f6ae83Chris Lattner ShouldAKA)); 12569d831645f429d3b806d2ae220aee45ca44f8c6cDouglas Gregor } else if (const RValueReferenceType *Ty = QT->getAs<RValueReferenceType>()) { 12669d831645f429d3b806d2ae220aee45ca44f8c6cDouglas Gregor QT = Context.getRValueReferenceType(Desugar(Context, Ty->getPointeeType(), 12769d831645f429d3b806d2ae220aee45ca44f8c6cDouglas Gregor ShouldAKA)); 12879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor } 1291733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth 13049f4e1cbd839da27ff4814b4ea6d85a79f786cbdJohn McCall return QC.apply(Context, QT); 13179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor} 13279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 13379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor/// \brief Convert the given type to a string suitable for printing as part of 1341733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth/// a diagnostic. 1351733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth/// 1360673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth/// There are four main criteria when determining whether we should have an 1371733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth/// a.k.a. clause when pretty-printing a type: 1381733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth/// 1391733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth/// 1) Some types provide very minimal sugar that doesn't impede the 1401733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth/// user's understanding --- for example, elaborated type 1411733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth/// specifiers. If this is all the sugar we see, we don't want an 1421733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth/// a.k.a. clause. 1431733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth/// 2) Some types are technically sugared but are much more familiar 1441733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth/// when seen in their sugared form --- for example, va_list, 1451733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth/// vector types, and the magic Objective C types. We don't 1461733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth/// want to desugar these, even if we do produce an a.k.a. clause. 1471733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth/// 3) Some types may have already been desugared previously in this diagnostic. 1481733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth/// if this is the case, doing another "aka" would just be clutter. 1490673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth/// 4) Two different types within the same diagnostic have the same output 1500673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth/// string. In this case, force an a.k.a with the desugared type when 1510673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth/// doing so will provide additional information. 15279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor/// 15379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor/// \param Context the context in which the type was allocated 15479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor/// \param Ty the type to print 1550673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth/// \param QualTypeVals pointer values to QualTypes which are used in the 1560673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth/// diagnostic message 15779a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregorstatic std::string 15879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas GregorConvertTypeToDiagnosticString(ASTContext &Context, QualType Ty, 159d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie const DiagnosticsEngine::ArgumentValue *PrevArgs, 1600673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth unsigned NumPrevArgs, 161341785ec52f87c0803ba52dc88faac4e136f8593Bill Wendling ArrayRef<intptr_t> QualTypeVals) { 16279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor // FIXME: Playing with std::string is really slow. 1630673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth bool ForceAKA = false; 1640673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth QualType CanTy = Ty.getCanonicalType(); 16530c42404202d2e2512e51efc6066bd614cfdb5a4Douglas Gregor std::string S = Ty.getAsString(Context.getPrintingPolicy()); 16630c42404202d2e2512e51efc6066bd614cfdb5a4Douglas Gregor std::string CanS = CanTy.getAsString(Context.getPrintingPolicy()); 1670673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth 168341785ec52f87c0803ba52dc88faac4e136f8593Bill Wendling for (unsigned I = 0, E = QualTypeVals.size(); I != E; ++I) { 1690673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth QualType CompareTy = 170341785ec52f87c0803ba52dc88faac4e136f8593Bill Wendling QualType::getFromOpaquePtr(reinterpret_cast<void*>(QualTypeVals[I])); 17136f5cfe4df32af6c5fe01228102512996f566f9dRichard Smith if (CompareTy.isNull()) 17236f5cfe4df32af6c5fe01228102512996f566f9dRichard Smith continue; 1730673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth if (CompareTy == Ty) 1740673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth continue; // Same types 1750673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth QualType CompareCanTy = CompareTy.getCanonicalType(); 1760673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth if (CompareCanTy == CanTy) 1770673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth continue; // Same canonical types 17830c42404202d2e2512e51efc6066bd614cfdb5a4Douglas Gregor std::string CompareS = CompareTy.getAsString(Context.getPrintingPolicy()); 179ecb912e8a2a683a2e1db1743a862ee21e788eea6Richard Trieu bool aka; 180ecb912e8a2a683a2e1db1743a862ee21e788eea6Richard Trieu QualType CompareDesugar = Desugar(Context, CompareTy, aka); 181ecb912e8a2a683a2e1db1743a862ee21e788eea6Richard Trieu std::string CompareDesugarStr = 182ecb912e8a2a683a2e1db1743a862ee21e788eea6Richard Trieu CompareDesugar.getAsString(Context.getPrintingPolicy()); 183ecb912e8a2a683a2e1db1743a862ee21e788eea6Richard Trieu if (CompareS != S && CompareDesugarStr != S) 184ecb912e8a2a683a2e1db1743a862ee21e788eea6Richard Trieu continue; // The type string is different than the comparison string 185ecb912e8a2a683a2e1db1743a862ee21e788eea6Richard Trieu // and the desugared comparison string. 186ecb912e8a2a683a2e1db1743a862ee21e788eea6Richard Trieu std::string CompareCanS = 187ecb912e8a2a683a2e1db1743a862ee21e788eea6Richard Trieu CompareCanTy.getAsString(Context.getPrintingPolicy()); 188ecb912e8a2a683a2e1db1743a862ee21e788eea6Richard Trieu 1890673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth if (CompareCanS == CanS) 1900673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth continue; // No new info from canonical type 1910673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth 1920673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth ForceAKA = true; 1930673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth break; 1940673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth } 1951733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth 1961733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth // Check to see if we already desugared this type in this 1971733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth // diagnostic. If so, don't do it again. 1981733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth bool Repeated = false; 1991733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth for (unsigned i = 0; i != NumPrevArgs; ++i) { 2001733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth // TODO: Handle ak_declcontext case. 201d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie if (PrevArgs[i].first == DiagnosticsEngine::ak_qualtype) { 2021733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth void *Ptr = (void*)PrevArgs[i].second; 2031733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth QualType PrevTy(QualType::getFromOpaquePtr(Ptr)); 2041733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth if (PrevTy == Ty) { 2051733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth Repeated = true; 2061733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth break; 2071733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth } 2081733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth } 2091733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth } 2101733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth 21179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor // Consider producing an a.k.a. clause if removing all the direct 21279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor // sugar gives us something "significantly different". 2131733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth if (!Repeated) { 2141733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth bool ShouldAKA = false; 2151733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth QualType DesugaredTy = Desugar(Context, Ty, ShouldAKA); 2160673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth if (ShouldAKA || ForceAKA) { 2170673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth if (DesugaredTy == Ty) { 2180673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth DesugaredTy = Ty.getCanonicalType(); 2190673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth } 22030c42404202d2e2512e51efc6066bd614cfdb5a4Douglas Gregor std::string akaStr = DesugaredTy.getAsString(Context.getPrintingPolicy()); 2210673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth if (akaStr != S) { 2220673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth S = "'" + S + "' (aka '" + akaStr + "')"; 2230673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth return S; 2240673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth } 2251733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth } 22679a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor } 2271733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth 22879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor S = "'" + S + "'"; 22979a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor return S; 23079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor} 23179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 232246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieustatic bool FormatTemplateTypeDiff(ASTContext &Context, QualType FromType, 233246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu QualType ToType, bool PrintTree, 234246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu bool PrintFromType, bool ElideType, 235246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu bool ShowColors, std::string &S); 236246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 2370673cb30340aadaede7b795c763b00f6b64e611cChandler Carruthvoid clang::FormatASTNodeDiagnosticArgument( 238d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie DiagnosticsEngine::ArgumentKind Kind, 2390673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth intptr_t Val, 2400673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth const char *Modifier, 2410673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth unsigned ModLen, 2420673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth const char *Argument, 2430673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth unsigned ArgLen, 244d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie const DiagnosticsEngine::ArgumentValue *PrevArgs, 2450673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth unsigned NumPrevArgs, 2465f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<char> &Output, 2470673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth void *Cookie, 248341785ec52f87c0803ba52dc88faac4e136f8593Bill Wendling ArrayRef<intptr_t> QualTypeVals) { 24979a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor ASTContext &Context = *static_cast<ASTContext*>(Cookie); 25079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 25179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor std::string S; 25279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor bool NeedQuotes = true; 25379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 25479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor switch (Kind) { 255b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie default: llvm_unreachable("unknown ArgumentKind"); 256246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu case DiagnosticsEngine::ak_qualtype_pair: { 2575409d28b6167032696f4915bb765a6f7db579f3fRichard Trieu TemplateDiffTypes &TDT = *reinterpret_cast<TemplateDiffTypes*>(Val); 258246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu QualType FromType = 259246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu QualType::getFromOpaquePtr(reinterpret_cast<void*>(TDT.FromType)); 260246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu QualType ToType = 261246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu QualType::getFromOpaquePtr(reinterpret_cast<void*>(TDT.ToType)); 262246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 263246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (FormatTemplateTypeDiff(Context, FromType, ToType, TDT.PrintTree, 264246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu TDT.PrintFromType, TDT.ElideType, 265246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu TDT.ShowColors, S)) { 266246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu NeedQuotes = !TDT.PrintTree; 2675409d28b6167032696f4915bb765a6f7db579f3fRichard Trieu TDT.TemplateDiffUsed = true; 268246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu break; 269246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 270246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 271246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu // Don't fall-back during tree printing. The caller will handle 272246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu // this case. 273246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (TDT.PrintTree) 274246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu return; 275246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 276246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu // Attempting to do a templete diff on non-templates. Set the variables 277246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu // and continue with regular type printing of the appropriate type. 278246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu Val = TDT.PrintFromType ? TDT.FromType : TDT.ToType; 279246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu ModLen = 0; 280246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu ArgLen = 0; 281246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu // Fall through 282246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 283d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie case DiagnosticsEngine::ak_qualtype: { 28479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor assert(ModLen == 0 && ArgLen == 0 && 28579a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor "Invalid modifier for QualType argument"); 28679a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 28779a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor QualType Ty(QualType::getFromOpaquePtr(reinterpret_cast<void*>(Val))); 2880673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth S = ConvertTypeToDiagnosticString(Context, Ty, PrevArgs, NumPrevArgs, 2890673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth QualTypeVals); 29079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor NeedQuotes = false; 29179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor break; 29279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor } 293d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie case DiagnosticsEngine::ak_declarationname: { 29479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor DeclarationName N = DeclarationName::getFromOpaqueInteger(Val); 29579a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor S = N.getAsString(); 29679a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 29779a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor if (ModLen == 9 && !memcmp(Modifier, "objcclass", 9) && ArgLen == 0) 29879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor S = '+' + S; 29979a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor else if (ModLen == 12 && !memcmp(Modifier, "objcinstance", 12) 30079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor && ArgLen==0) 30179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor S = '-' + S; 30279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor else 30379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor assert(ModLen == 0 && ArgLen == 0 && 30479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor "Invalid modifier for DeclarationName argument"); 30579a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor break; 30679a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor } 307d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie case DiagnosticsEngine::ak_nameddecl: { 30879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor bool Qualified; 30979a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor if (ModLen == 1 && Modifier[0] == 'q' && ArgLen == 0) 31079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor Qualified = true; 31179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor else { 31279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor assert(ModLen == 0 && ArgLen == 0 && 31379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor "Invalid modifier for NamedDecl* argument"); 31479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor Qualified = false; 31579a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor } 316b0656ec72e25e5c8e463c2dc39914636f0cb06d1Chandler Carruth const NamedDecl *ND = reinterpret_cast<const NamedDecl*>(Val); 31730c42404202d2e2512e51efc6066bd614cfdb5a4Douglas Gregor ND->getNameForDiagnostic(S, Context.getPrintingPolicy(), Qualified); 31879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor break; 31979a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor } 320d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie case DiagnosticsEngine::ak_nestednamespec: { 32179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor llvm::raw_string_ostream OS(S); 32279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor reinterpret_cast<NestedNameSpecifier*>(Val)->print(OS, 32330c42404202d2e2512e51efc6066bd614cfdb5a4Douglas Gregor Context.getPrintingPolicy()); 32479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor NeedQuotes = false; 32579a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor break; 32679a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor } 327d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie case DiagnosticsEngine::ak_declcontext: { 32879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor DeclContext *DC = reinterpret_cast<DeclContext *> (Val); 32979a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor assert(DC && "Should never have a null declaration context"); 33079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 33179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor if (DC->isTranslationUnit()) { 33279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor // FIXME: Get these strings from some localized place 3334e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (Context.getLangOpts().CPlusPlus) 33479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor S = "the global namespace"; 33579a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor else 33679a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor S = "the global scope"; 33779a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor } else if (TypeDecl *Type = dyn_cast<TypeDecl>(DC)) { 33879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor S = ConvertTypeToDiagnosticString(Context, 33979a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor Context.getTypeDeclType(Type), 3400673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth PrevArgs, NumPrevArgs, QualTypeVals); 34179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor } else { 34279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor // FIXME: Get these strings from some localized place 34379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor NamedDecl *ND = cast<NamedDecl>(DC); 34479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor if (isa<NamespaceDecl>(ND)) 34579a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor S += "namespace "; 34679a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor else if (isa<ObjCMethodDecl>(ND)) 34779a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor S += "method "; 34879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor else if (isa<FunctionDecl>(ND)) 34979a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor S += "function "; 35079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 35179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor S += "'"; 35230c42404202d2e2512e51efc6066bd614cfdb5a4Douglas Gregor ND->getNameForDiagnostic(S, Context.getPrintingPolicy(), true); 35379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor S += "'"; 35479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor } 35579a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor NeedQuotes = false; 35679a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor break; 35779a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor } 35879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor } 35979a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 36079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor if (NeedQuotes) 36179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor Output.push_back('\''); 36279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 36379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor Output.append(S.begin(), S.end()); 36479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 36579a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor if (NeedQuotes) 36679a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor Output.push_back('\''); 36779a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor} 368246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 369246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu/// TemplateDiff - A class that constructs a pretty string for a pair of 370246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu/// QualTypes. For the pair of types, a diff tree will be created containing 371246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu/// all the information about the templates and template arguments. Afterwards, 372246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu/// the tree is transformed to a string according to the options passed in. 373246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieunamespace { 374246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieuclass TemplateDiff { 375246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// Context - The ASTContext which is used for comparing template arguments. 376246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu ASTContext &Context; 377246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 378246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// Policy - Used during expression printing. 379246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu PrintingPolicy Policy; 380246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 381246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// ElideType - Option to elide identical types. 382246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu bool ElideType; 383246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 384246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// PrintTree - Format output string as a tree. 385246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu bool PrintTree; 386246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 387246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// ShowColor - Diagnostics support color, so bolding will be used. 388246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu bool ShowColor; 389246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 390246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// FromType - When single type printing is selected, this is the type to be 391246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// be printed. When tree printing is selected, this type will show up first 392246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// in the tree. 393246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu QualType FromType; 394246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 395246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// ToType - The type that FromType is compared to. Only in tree printing 396246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// will this type be outputed. 397246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu QualType ToType; 398246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 399246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// Str - Storage for the output stream. 400246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu llvm::SmallString<128> Str; 401246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 402246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// OS - The stream used to construct the output strings. 403246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu llvm::raw_svector_ostream OS; 404246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 405246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// IsBold - Keeps track of the bold formatting for the output string. 406246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu bool IsBold; 407246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 408246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// DiffTree - A tree representation the differences between two types. 409246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu class DiffTree { 410246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// DiffNode - The root node stores the original type. Each child node 411246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// stores template arguments of their parents. For templated types, the 412246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// template decl is also stored. 413246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu struct DiffNode { 414246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// NextNode - The index of the next sibling node or 0. 415246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu unsigned NextNode; 416246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 417246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// ChildNode - The index of the first child node or 0. 418246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu unsigned ChildNode; 419246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 420246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// ParentNode - The index of the parent node. 421246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu unsigned ParentNode; 422246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 423246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// FromType, ToType - The type arguments. 424246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu QualType FromType, ToType; 425246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 426246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// FromExpr, ToExpr - The expression arguments. 427246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu Expr *FromExpr, *ToExpr; 428246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 429246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// FromTD, ToTD - The template decl for template template 430246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// arguments or the type arguments that are templates. 431246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu TemplateDecl *FromTD, *ToTD; 432246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 433246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// FromDefault, ToDefault - Whether the argument is a default argument. 434246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu bool FromDefault, ToDefault; 435246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 436246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// Same - Whether the two arguments evaluate to the same value. 437246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu bool Same; 438246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 439246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu DiffNode(unsigned ParentNode = 0) 440246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu : NextNode(0), ChildNode(0), ParentNode(ParentNode), 441246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu FromType(), ToType(), FromExpr(0), ToExpr(0), FromTD(0), ToTD(0), 442246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu FromDefault(false), ToDefault(false), Same(false) { } 443246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu }; 444246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 445246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// FlatTree - A flattened tree used to store the DiffNodes. 446246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu llvm::SmallVector<DiffNode, 16> FlatTree; 447246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 448246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// CurrentNode - The index of the current node being used. 449246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu unsigned CurrentNode; 450246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 451246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// NextFreeNode - The index of the next unused node. Used when creating 452246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// child nodes. 453246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu unsigned NextFreeNode; 454246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 455246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// ReadNode - The index of the current node being read. 456246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu unsigned ReadNode; 457246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 458246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu public: 459246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu DiffTree() : 460246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu CurrentNode(0), NextFreeNode(1) { 461246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu FlatTree.push_back(DiffNode()); 462246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 463246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 464246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu // Node writing functions. 465246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// SetNode - Sets FromTD and ToTD of the current node. 466246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu void SetNode(TemplateDecl *FromTD, TemplateDecl *ToTD) { 467246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu FlatTree[CurrentNode].FromTD = FromTD; 468246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu FlatTree[CurrentNode].ToTD = ToTD; 469246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 470246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 471246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// SetNode - Sets FromType and ToType of the current node. 472246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu void SetNode(QualType FromType, QualType ToType) { 473246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu FlatTree[CurrentNode].FromType = FromType; 474246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu FlatTree[CurrentNode].ToType = ToType; 475246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 476246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 477246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// SetNode - Set FromExpr and ToExpr of the current node. 478246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu void SetNode(Expr *FromExpr, Expr *ToExpr) { 479246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu FlatTree[CurrentNode].FromExpr = FromExpr; 480246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu FlatTree[CurrentNode].ToExpr = ToExpr; 481246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 482246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 483246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// SetSame - Sets the same flag of the current node. 484246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu void SetSame(bool Same) { 485246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu FlatTree[CurrentNode].Same = Same; 486246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 487246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 488246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// SetDefault - Sets FromDefault and ToDefault flags of the current node. 489246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu void SetDefault(bool FromDefault, bool ToDefault) { 490246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu FlatTree[CurrentNode].FromDefault = FromDefault; 491246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu FlatTree[CurrentNode].ToDefault = ToDefault; 492246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 493246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 494246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// Up - Changes the node to the parent of the current node. 495246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu void Up() { 496246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu CurrentNode = FlatTree[CurrentNode].ParentNode; 497246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 498246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 499246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// AddNode - Adds a child node to the current node, then sets that node 500246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// node as the current node. 501246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu void AddNode() { 502246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu FlatTree.push_back(DiffNode(CurrentNode)); 503246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu DiffNode &Node = FlatTree[CurrentNode]; 504246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (Node.ChildNode == 0) { 505246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu // If a child node doesn't exist, add one. 506246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu Node.ChildNode = NextFreeNode; 507246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } else { 508246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu // If a child node exists, find the last child node and add a 509246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu // next node to it. 510246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu unsigned i; 511246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu for (i = Node.ChildNode; FlatTree[i].NextNode != 0; 512246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu i = FlatTree[i].NextNode) { 513246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 514246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu FlatTree[i].NextNode = NextFreeNode; 515246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 516246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu CurrentNode = NextFreeNode; 517246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu ++NextFreeNode; 518246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 519246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 520246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu // Node reading functions. 521246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// StartTraverse - Prepares the tree for recursive traversal. 522246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu void StartTraverse() { 523246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu ReadNode = 0; 524246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu CurrentNode = NextFreeNode; 525246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu NextFreeNode = 0; 526246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 527246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 528246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// Parent - Move the current read node to its parent. 529246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu void Parent() { 530246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu ReadNode = FlatTree[ReadNode].ParentNode; 531246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 532246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 533246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// NodeIsTemplate - Returns true if a template decl is set, and types are 534246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// set. 535246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu bool NodeIsTemplate() { 536246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu return (FlatTree[ReadNode].FromTD && 537246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu !FlatTree[ReadNode].ToType.isNull()) || 538246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu (FlatTree[ReadNode].ToTD && !FlatTree[ReadNode].ToType.isNull()); 539246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 540246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 541246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// NodeIsQualType - Returns true if a Qualtype is set. 542246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu bool NodeIsQualType() { 543246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu return !FlatTree[ReadNode].FromType.isNull() || 544246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu !FlatTree[ReadNode].ToType.isNull(); 545246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 546246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 547246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// NodeIsExpr - Returns true if an expr is set. 548246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu bool NodeIsExpr() { 549246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu return FlatTree[ReadNode].FromExpr || FlatTree[ReadNode].ToExpr; 550246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 551246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 552246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// NodeIsTemplateTemplate - Returns true if the argument is a template 553246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// template type. 554246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu bool NodeIsTemplateTemplate() { 555246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu return FlatTree[ReadNode].FromType.isNull() && 556246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu FlatTree[ReadNode].ToType.isNull() && 557246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu (FlatTree[ReadNode].FromTD || FlatTree[ReadNode].ToTD); 558246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 559246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 560246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// GetNode - Gets the FromType and ToType. 561246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu void GetNode(QualType &FromType, QualType &ToType) { 562246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu FromType = FlatTree[ReadNode].FromType; 563246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu ToType = FlatTree[ReadNode].ToType; 564246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 565246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 566246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// GetNode - Gets the FromExpr and ToExpr. 567246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu void GetNode(Expr *&FromExpr, Expr *&ToExpr) { 568246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu FromExpr = FlatTree[ReadNode].FromExpr; 569246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu ToExpr = FlatTree[ReadNode].ToExpr; 570246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 571246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 572246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// GetNode - Gets the FromTD and ToTD. 573246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu void GetNode(TemplateDecl *&FromTD, TemplateDecl *&ToTD) { 574246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu FromTD = FlatTree[ReadNode].FromTD; 575246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu ToTD = FlatTree[ReadNode].ToTD; 576246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 577246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 578246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// NodeIsSame - Returns true the arguments are the same. 579246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu bool NodeIsSame() { 580246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu return FlatTree[ReadNode].Same; 581246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 582246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 583246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// HasChildrend - Returns true if the node has children. 584246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu bool HasChildren() { 585246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu return FlatTree[ReadNode].ChildNode != 0; 586246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 587246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 588246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// MoveToChild - Moves from the current node to its child. 589246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu void MoveToChild() { 590246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu ReadNode = FlatTree[ReadNode].ChildNode; 591246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 592246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 593246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// AdvanceSibling - If there is a next sibling, advance to it and return 594246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// true. Otherwise, return false. 595246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu bool AdvanceSibling() { 596246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (FlatTree[ReadNode].NextNode == 0) 597246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu return false; 598246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 599246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu ReadNode = FlatTree[ReadNode].NextNode; 600246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu return true; 601246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 602246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 603246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// HasNextSibling - Return true if the node has a next sibling. 604246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu bool HasNextSibling() { 605246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu return FlatTree[ReadNode].NextNode != 0; 606246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 607246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 608246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// FromDefault - Return true if the from argument is the default. 609246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu bool FromDefault() { 610246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu return FlatTree[ReadNode].FromDefault; 611246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 612246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 613246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// ToDefault - Return true if the to argument is the default. 614246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu bool ToDefault() { 615246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu return FlatTree[ReadNode].ToDefault; 616246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 617246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 618246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// Empty - Returns true if the tree has no information. 619246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu bool Empty() { 620246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu return !FlatTree[0].FromTD && !FlatTree[0].ToTD && 621246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu !FlatTree[0].FromExpr && !FlatTree[0].ToExpr && 622246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu FlatTree[0].FromType.isNull() && FlatTree[0].ToType.isNull(); 623246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 624246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu }; 625246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 626246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu DiffTree Tree; 627246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 628246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// TSTiterator - an iterator that is used to enter a 629246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// TemplateSpecializationType and read TemplateArguments inside template 630246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// parameter packs in order with the rest of the TemplateArguments. 631246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu struct TSTiterator { 632246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu typedef const TemplateArgument& reference; 633246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu typedef const TemplateArgument* pointer; 634246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 635246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// TST - the template specialization whose arguments this iterator 636246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// traverse over. 637246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu const TemplateSpecializationType *TST; 638246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 639246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// Index - the index of the template argument in TST. 640246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu unsigned Index; 641246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 642246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// CurrentTA - if CurrentTA is not the same as EndTA, then CurrentTA 643246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// points to a TemplateArgument within a parameter pack. 644246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu TemplateArgument::pack_iterator CurrentTA; 645246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 646246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// EndTA - the end iterator of a parameter pack 647246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu TemplateArgument::pack_iterator EndTA; 648246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 649246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// TSTiterator - Constructs an iterator and sets it to the first template 650246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// argument. 651246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu TSTiterator(const TemplateSpecializationType *TST) 652246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu : TST(TST), Index(0), CurrentTA(0), EndTA(0) { 653246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (isEnd()) return; 654246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 655246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu // Set to first template argument. If not a parameter pack, done. 656246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu TemplateArgument TA = TST->getArg(0); 657246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (TA.getKind() != TemplateArgument::Pack) return; 658246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 659246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu // Start looking into the parameter pack. 660246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu CurrentTA = TA.pack_begin(); 661246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu EndTA = TA.pack_end(); 662246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 663246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu // Found a valid template argument. 664246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (CurrentTA != EndTA) return; 665246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 666246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu // Parameter pack is empty, use the increment to get to a valid 667246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu // template argument. 668246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu ++(*this); 669246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 670246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 671246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// isEnd - Returns true if the iterator is one past the end. 672246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu bool isEnd() const { 673246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu return Index == TST->getNumArgs(); 674246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 675246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 676246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// &operator++ - Increment the iterator to the next template argument. 677246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu TSTiterator &operator++() { 678246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu assert(!isEnd() && "Iterator incremented past end of arguments."); 679246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 680246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu // If in a parameter pack, advance in the parameter pack. 681246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (CurrentTA != EndTA) { 682246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu ++CurrentTA; 683246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (CurrentTA != EndTA) 684246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu return *this; 685246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 686246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 687246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu // Loop until a template argument is found, or the end is reached. 688246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu while (true) { 689246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu // Advance to the next template argument. Break if reached the end. 690246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (++Index == TST->getNumArgs()) break; 691246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 692246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu // If the TemplateArgument is not a parameter pack, done. 693246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu TemplateArgument TA = TST->getArg(Index); 694246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (TA.getKind() != TemplateArgument::Pack) break; 695246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 696246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu // Handle parameter packs. 697246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu CurrentTA = TA.pack_begin(); 698246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu EndTA = TA.pack_end(); 699246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 700246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu // If the parameter pack is empty, try to advance again. 701246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (CurrentTA != EndTA) break; 702246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 703246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu return *this; 704246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 705246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 706246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// operator* - Returns the appropriate TemplateArgument. 707246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu reference operator*() const { 708246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu assert(!isEnd() && "Index exceeds number of arguments."); 709246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (CurrentTA == EndTA) 710246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu return TST->getArg(Index); 711246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu else 712246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu return *CurrentTA; 713246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 714246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 715246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// operator-> - Allow access to the underlying TemplateArgument. 716246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu pointer operator->() const { 717246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu return &operator*(); 718246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 719246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu }; 720246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 721246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu // These functions build up the template diff tree, including functions to 722246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu // retrieve and compare template arguments. 723246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 724246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu static const TemplateSpecializationType * GetTemplateSpecializationType( 725246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu ASTContext &Context, QualType Ty) { 726246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (const TemplateSpecializationType *TST = 727246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu Ty->getAs<TemplateSpecializationType>()) 728246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu return TST; 729246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 730246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu const RecordType *RT = Ty->getAs<RecordType>(); 731246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 732246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (!RT) 733246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu return 0; 734246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 735246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu const ClassTemplateSpecializationDecl *CTSD = 736246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu dyn_cast<ClassTemplateSpecializationDecl>(RT->getDecl()); 737246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 738246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (!CTSD) 739246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu return 0; 740246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 741246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu Ty = Context.getTemplateSpecializationType( 742246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu TemplateName(CTSD->getSpecializedTemplate()), 743246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu CTSD->getTemplateArgs().data(), 744246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu CTSD->getTemplateArgs().size(), 745246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu Ty.getCanonicalType()); 746246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 747246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu return Ty->getAs<TemplateSpecializationType>(); 748246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 749246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 750246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// DiffTemplate - recursively visits template arguments and stores the 751246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// argument info into a tree. 752246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu void DiffTemplate(const TemplateSpecializationType *FromTST, 753246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu const TemplateSpecializationType *ToTST) { 754246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu // Begin descent into diffing template tree. 755246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu TemplateParameterList *Params = 756246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu FromTST->getTemplateName().getAsTemplateDecl()->getTemplateParameters(); 757246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu unsigned TotalArgs = 0; 758246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu for (TSTiterator FromIter(FromTST), ToIter(ToTST); 759246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu !FromIter.isEnd() || !ToIter.isEnd(); ++TotalArgs) { 760246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu Tree.AddNode(); 761246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 762246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu // Get the parameter at index TotalArgs. If index is larger 763246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu // than the total number of parameters, then there is an 764246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu // argument pack, so re-use the last parameter. 765246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu NamedDecl *ParamND = Params->getParam( 766246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu (TotalArgs < Params->size()) ? TotalArgs 767246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu : Params->size() - 1); 768246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu // Handle Types 769246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (TemplateTypeParmDecl *DefaultTTPD = 770246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu dyn_cast<TemplateTypeParmDecl>(ParamND)) { 771246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu QualType FromType, ToType; 772246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu GetType(FromIter, DefaultTTPD, FromType); 773246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu GetType(ToIter, DefaultTTPD, ToType); 774246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu Tree.SetNode(FromType, ToType); 775246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu Tree.SetDefault(FromIter.isEnd() && !FromType.isNull(), 776246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu ToIter.isEnd() && !ToType.isNull()); 777246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (!FromType.isNull() && !ToType.isNull()) { 778246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (Context.hasSameType(FromType, ToType)) { 779246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu Tree.SetSame(true); 780246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } else { 781246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu const TemplateSpecializationType *FromArgTST = 782246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu GetTemplateSpecializationType(Context, FromType); 783246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu const TemplateSpecializationType *ToArgTST = 784246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu GetTemplateSpecializationType(Context, ToType); 785246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 786246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (FromArgTST && ToArgTST) { 787246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu bool SameTemplate = hasSameTemplate(FromArgTST, ToArgTST); 788246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (SameTemplate) { 789246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu Tree.SetNode(FromArgTST->getTemplateName().getAsTemplateDecl(), 790246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu ToArgTST->getTemplateName().getAsTemplateDecl()); 791246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu DiffTemplate(FromArgTST, ToArgTST); 792246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 793246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 794246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 795246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 796246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 797246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 798246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu // Handle Expressions 799246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (NonTypeTemplateParmDecl *DefaultNTTPD = 800246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu dyn_cast<NonTypeTemplateParmDecl>(ParamND)) { 801246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu Expr *FromExpr, *ToExpr; 802246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu GetExpr(FromIter, DefaultNTTPD, FromExpr); 803246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu GetExpr(ToIter, DefaultNTTPD, ToExpr); 804246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu Tree.SetNode(FromExpr, ToExpr); 805246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu Tree.SetSame(IsEqualExpr(Context, FromExpr, ToExpr)); 806246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu Tree.SetDefault(FromIter.isEnd() && FromExpr, 807246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu ToIter.isEnd() && ToExpr); 808246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 809246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 810246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu // Handle Templates 811246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (TemplateTemplateParmDecl *DefaultTTPD = 812246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu dyn_cast<TemplateTemplateParmDecl>(ParamND)) { 813246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu TemplateDecl *FromDecl, *ToDecl; 814246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu GetTemplateDecl(FromIter, DefaultTTPD, FromDecl); 815246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu GetTemplateDecl(ToIter, DefaultTTPD, ToDecl); 816246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu Tree.SetNode(FromDecl, ToDecl); 817246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu Tree.SetSame(FromDecl && ToDecl && 818246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu FromDecl->getIdentifier() == ToDecl->getIdentifier()); 819246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 820246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 821246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (!FromIter.isEnd()) ++FromIter; 822246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (!ToIter.isEnd()) ++ToIter; 823246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu Tree.Up(); 824246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 825246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 826246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 827246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// hasSameTemplate - Returns true if both types are specialized from the 828246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// same template declaration. If they come from different template aliases, 829246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// do a parallel ascension search to determine the highest template alias in 830246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// common and set the arguments to them. 831246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu static bool hasSameTemplate(const TemplateSpecializationType *&FromTST, 832246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu const TemplateSpecializationType *&ToTST) { 833246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu // Check the top templates if they are the same. 834246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (FromTST->getTemplateName().getAsTemplateDecl()->getIdentifier() == 835246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu ToTST->getTemplateName().getAsTemplateDecl()->getIdentifier()) 836246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu return true; 837246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 838246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu // Create vectors of template aliases. 839246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu SmallVector<const TemplateSpecializationType*, 1> FromTemplateList, 840246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu ToTemplateList; 841246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 842246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu const TemplateSpecializationType *TempToTST = ToTST, *TempFromTST = FromTST; 843246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu FromTemplateList.push_back(FromTST); 844246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu ToTemplateList.push_back(ToTST); 845246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 846246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu // Dump every template alias into the vectors. 847246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu while (TempFromTST->isTypeAlias()) { 848246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu TempFromTST = 849246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu TempFromTST->getAliasedType()->getAs<TemplateSpecializationType>(); 850246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (!TempFromTST) 851246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu break; 852246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu FromTemplateList.push_back(TempFromTST); 853246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 854246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu while (TempToTST->isTypeAlias()) { 855246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu TempToTST = 856246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu TempToTST->getAliasedType()->getAs<TemplateSpecializationType>(); 857246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (!TempToTST) 858246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu break; 859246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu ToTemplateList.push_back(TempToTST); 860246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 861246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 862246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu SmallVector<const TemplateSpecializationType*, 1>::reverse_iterator 863246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu FromIter = FromTemplateList.rbegin(), FromEnd = FromTemplateList.rend(), 864246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu ToIter = ToTemplateList.rbegin(), ToEnd = ToTemplateList.rend(); 865246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 866246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu // Check if the lowest template types are the same. If not, return. 867246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if ((*FromIter)->getTemplateName().getAsTemplateDecl()->getIdentifier() != 868246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu (*ToIter)->getTemplateName().getAsTemplateDecl()->getIdentifier()) 869246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu return false; 870246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 871246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu // Begin searching up the template aliases. The bottom most template 872246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu // matches so move up until one pair does not match. Use the template 873246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu // right before that one. 874246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu for (; FromIter != FromEnd && ToIter != ToEnd; ++FromIter, ++ToIter) { 875246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if ((*FromIter)->getTemplateName().getAsTemplateDecl()->getIdentifier() != 876246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu (*ToIter)->getTemplateName().getAsTemplateDecl()->getIdentifier()) 877246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu break; 878246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 879246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 880246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu FromTST = FromIter[-1]; 881246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu ToTST = ToIter[-1]; 882246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 883246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu return true; 884246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 885246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 886246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// GetType - Retrieves the template type arguments, including default 887246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// arguments. 888246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu void GetType(const TSTiterator &Iter, TemplateTypeParmDecl *DefaultTTPD, 889246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu QualType &ArgType) { 890246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu ArgType = QualType(); 891246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu bool isVariadic = DefaultTTPD->isParameterPack(); 892246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 893246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (!Iter.isEnd()) 894246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu ArgType = Iter->getAsType(); 895246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu else if (!isVariadic) 896246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu ArgType = DefaultTTPD->getDefaultArgument(); 89737d2a00f4ca5689dac7fec2931fcef37556f5092David Blaikie } 898246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 899246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// GetExpr - Retrieves the template expression argument, including default 900246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// arguments. 901246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu void GetExpr(const TSTiterator &Iter, NonTypeTemplateParmDecl *DefaultNTTPD, 902246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu Expr *&ArgExpr) { 903246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu ArgExpr = 0; 904246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu bool isVariadic = DefaultNTTPD->isParameterPack(); 905246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 906246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (!Iter.isEnd()) 907246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu ArgExpr = Iter->getAsExpr(); 908246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu else if (!isVariadic) 909246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu ArgExpr = DefaultNTTPD->getDefaultArgument(); 910246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 911246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (ArgExpr) 912246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu while (SubstNonTypeTemplateParmExpr *SNTTPE = 913246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu dyn_cast<SubstNonTypeTemplateParmExpr>(ArgExpr)) 914246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu ArgExpr = SNTTPE->getReplacement(); 915246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 916246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 917246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// GetTemplateDecl - Retrieves the template template arguments, including 918246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// default arguments. 919246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu void GetTemplateDecl(const TSTiterator &Iter, 920246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu TemplateTemplateParmDecl *DefaultTTPD, 921246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu TemplateDecl *&ArgDecl) { 922246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu ArgDecl = 0; 923246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu bool isVariadic = DefaultTTPD->isParameterPack(); 924246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 925246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu TemplateArgument TA = DefaultTTPD->getDefaultArgument().getArgument(); 926246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu TemplateDecl *DefaultTD = TA.getAsTemplate().getAsTemplateDecl(); 927246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 928246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (!Iter.isEnd()) 929246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu ArgDecl = Iter->getAsTemplate().getAsTemplateDecl(); 930246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu else if (!isVariadic) 931246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu ArgDecl = DefaultTD; 932246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 933246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 934246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// IsEqualExpr - Returns true if the expressions evaluate to the same value. 935246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu static bool IsEqualExpr(ASTContext &Context, Expr *FromExpr, Expr *ToExpr) { 936246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (FromExpr == ToExpr) 937246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu return true; 938246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 939246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (!FromExpr || !ToExpr) 940246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu return false; 941246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 942246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu FromExpr = FromExpr->IgnoreParens(); 943246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu ToExpr = ToExpr->IgnoreParens(); 944246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 945246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu DeclRefExpr *FromDRE = dyn_cast<DeclRefExpr>(FromExpr), 946246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu *ToDRE = dyn_cast<DeclRefExpr>(ToExpr); 947246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 948246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (FromDRE || ToDRE) { 949246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (!FromDRE || !ToDRE) 950246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu return false; 951246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu return FromDRE->getDecl() == ToDRE->getDecl(); 952246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 953246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 954246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu Expr::EvalResult FromResult, ToResult; 955246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (!FromExpr->EvaluateAsRValue(FromResult, Context) || 956246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu !ToExpr->EvaluateAsRValue(ToResult, Context)) 957246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu assert(0 && "Template arguments must be known at compile time."); 958246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 959246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu APValue &FromVal = FromResult.Val; 960246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu APValue &ToVal = ToResult.Val; 961246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 962246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (FromVal.getKind() != ToVal.getKind()) return false; 963246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 964246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu switch (FromVal.getKind()) { 965246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu case APValue::Int: 966246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu return FromVal.getInt() == ToVal.getInt(); 967246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu case APValue::LValue: { 968246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu APValue::LValueBase FromBase = FromVal.getLValueBase(); 969246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu APValue::LValueBase ToBase = ToVal.getLValueBase(); 970246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (FromBase.isNull() && ToBase.isNull()) 971246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu return true; 972246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (FromBase.isNull() || ToBase.isNull()) 973246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu return false; 974246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu return FromBase.get<const ValueDecl*>() == 975246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu ToBase.get<const ValueDecl*>(); 976246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 977246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu case APValue::MemberPointer: 978246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu return FromVal.getMemberPointerDecl() == ToVal.getMemberPointerDecl(); 979246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu default: 980246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu llvm_unreachable("Unknown template argument expression."); 981246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 982246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 983246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 984246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu // These functions converts the tree representation of the template 985246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu // differences into the internal character vector. 986246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 987246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// TreeToString - Converts the Tree object into a character stream which 988246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// will later be turned into the output string. 989246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu void TreeToString(int Indent = 1) { 990246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (PrintTree) { 991246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu OS << '\n'; 992246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu for (int i = 0; i < Indent; ++i) 993246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu OS << " "; 994246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu ++Indent; 995246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 996246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 997246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu // Handle cases where the difference is not templates with different 998246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu // arguments. 999246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (!Tree.NodeIsTemplate()) { 1000246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (Tree.NodeIsQualType()) { 1001246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu QualType FromType, ToType; 1002246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu Tree.GetNode(FromType, ToType); 1003246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu PrintTypeNames(FromType, ToType, Tree.FromDefault(), Tree.ToDefault(), 1004246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu Tree.NodeIsSame()); 1005246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu return; 1006246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 1007246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (Tree.NodeIsExpr()) { 1008246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu Expr *FromExpr, *ToExpr; 1009246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu Tree.GetNode(FromExpr, ToExpr); 1010246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu PrintExpr(FromExpr, ToExpr, Tree.FromDefault(), Tree.ToDefault(), 1011246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu Tree.NodeIsSame()); 1012246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu return; 1013246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 1014246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (Tree.NodeIsTemplateTemplate()) { 1015246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu TemplateDecl *FromTD, *ToTD; 1016246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu Tree.GetNode(FromTD, ToTD); 1017246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu PrintTemplateTemplate(FromTD, ToTD, Tree.FromDefault(), 1018246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu Tree.ToDefault(), Tree.NodeIsSame()); 1019246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu return; 1020246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 1021246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu llvm_unreachable("Unable to deduce template difference."); 1022246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 1023246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 1024246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu // Node is root of template. Recurse on children. 1025246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu TemplateDecl *FromTD, *ToTD; 1026246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu Tree.GetNode(FromTD, ToTD); 1027246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 1028246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu assert(Tree.HasChildren() && "Template difference not found in diff tree."); 1029246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 1030246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu OS << FromTD->getNameAsString() << '<'; 1031246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu Tree.MoveToChild(); 1032246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu unsigned NumElideArgs = 0; 1033246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu do { 1034246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (ElideType) { 1035246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (Tree.NodeIsSame()) { 1036246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu ++NumElideArgs; 1037246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu continue; 1038246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 1039246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (NumElideArgs > 0) { 1040246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu PrintElideArgs(NumElideArgs, Indent); 1041246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu NumElideArgs = 0; 1042246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu OS << ", "; 1043246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 1044246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 1045246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu TreeToString(Indent); 1046246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (Tree.HasNextSibling()) 1047246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu OS << ", "; 1048246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } while (Tree.AdvanceSibling()); 1049246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (NumElideArgs > 0) 1050246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu PrintElideArgs(NumElideArgs, Indent); 1051246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 1052246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu Tree.Parent(); 1053246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu OS << ">"; 1054246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 1055246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 1056246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu // To signal to the text printer that a certain text needs to be bolded, 1057246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu // a special character is injected into the character stream which the 1058246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu // text printer will later strip out. 1059246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 1060246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// Bold - Start bolding text. 1061246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu void Bold() { 1062246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu assert(!IsBold && "Attempting to bold text that is already bold."); 1063246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu IsBold = true; 1064246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (ShowColor) 1065246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu OS << ToggleHighlight; 1066246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 1067246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 1068246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// Unbold - Stop bolding text. 1069246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu void Unbold() { 1070246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu assert(IsBold && "Attempting to remove bold from unbold text."); 1071246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu IsBold = false; 1072246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (ShowColor) 1073246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu OS << ToggleHighlight; 1074246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 1075246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 1076246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu // Functions to print out the arguments and highlighting the difference. 1077246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 1078246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// PrintTypeNames - prints the typenames, bolding differences. Will detect 1079246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// typenames that are the same and attempt to disambiguate them by using 1080246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// canonical typenames. 1081246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu void PrintTypeNames(QualType FromType, QualType ToType, 1082246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu bool FromDefault, bool ToDefault, bool Same) { 1083246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu assert((!FromType.isNull() || !ToType.isNull()) && 1084246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu "Only one template argument may be missing."); 1085246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 1086246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (Same) { 1087246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu OS << FromType.getAsString(); 1088246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu return; 1089246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 1090246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 1091246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu std::string FromTypeStr = FromType.isNull() ? "(no argument)" 1092246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu : FromType.getAsString(); 1093246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu std::string ToTypeStr = ToType.isNull() ? "(no argument)" 1094246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu : ToType.getAsString(); 1095246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu // Switch to canonical typename if it is better. 1096246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu // TODO: merge this with other aka printing above. 1097246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (FromTypeStr == ToTypeStr) { 1098246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu std::string FromCanTypeStr = FromType.getCanonicalType().getAsString(); 1099246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu std::string ToCanTypeStr = ToType.getCanonicalType().getAsString(); 1100246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (FromCanTypeStr != ToCanTypeStr) { 1101246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu FromTypeStr = FromCanTypeStr; 1102246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu ToTypeStr = ToCanTypeStr; 1103246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 1104246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 1105246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 1106246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (PrintTree) OS << '['; 1107246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu OS << (FromDefault ? "(default) " : ""); 1108246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu Bold(); 1109246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu OS << FromTypeStr; 1110246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu Unbold(); 1111246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (PrintTree) { 1112246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu OS << " != " << (ToDefault ? "(default) " : ""); 1113246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu Bold(); 1114246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu OS << ToTypeStr; 1115246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu Unbold(); 1116246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu OS << "]"; 1117246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 1118246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu return; 1119246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 1120246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 1121246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// PrintExpr - Prints out the expr template arguments, highlighting argument 1122246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// differences. 1123246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu void PrintExpr(const Expr *FromExpr, const Expr *ToExpr, 1124246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu bool FromDefault, bool ToDefault, bool Same) { 1125246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu assert((FromExpr || ToExpr) && 1126246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu "Only one template argument may be missing."); 1127246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (Same) { 1128246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu PrintExpr(FromExpr); 1129246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } else if (!PrintTree) { 1130246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu OS << (FromDefault ? "(default) " : ""); 1131246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu Bold(); 1132246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu PrintExpr(FromExpr); 1133246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu Unbold(); 1134246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } else { 1135246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu OS << (FromDefault ? "[(default) " : "["); 1136246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu Bold(); 1137246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu PrintExpr(FromExpr); 1138246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu Unbold(); 1139246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu OS << " != " << (ToDefault ? "(default) " : ""); 1140246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu Bold(); 1141246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu PrintExpr(ToExpr); 1142246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu Unbold(); 1143246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu OS << ']'; 1144246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 1145246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 1146246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 1147246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// PrintExpr - Actual formatting and printing of expressions. 1148246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu void PrintExpr(const Expr *E) { 1149246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (!E) 1150246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu OS << "(no argument)"; 1151246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu else 1152d1420c6fa788669e49f21e184927c7833881e399Richard Smith E->printPretty(OS, 0, Policy); return; 1153246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 1154246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 1155246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// PrintTemplateTemplate - Handles printing of template template arguments, 1156246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// highlighting argument differences. 1157246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu void PrintTemplateTemplate(TemplateDecl *FromTD, TemplateDecl *ToTD, 1158246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu bool FromDefault, bool ToDefault, bool Same) { 1159246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu assert((FromTD || ToTD) && "Only one template argument may be missing."); 1160246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (Same) { 1161246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu OS << "template " << FromTD->getNameAsString(); 1162246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } else if (!PrintTree) { 1163246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu OS << (FromDefault ? "(default) template " : "template "); 1164246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu Bold(); 1165246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu OS << (FromTD ? FromTD->getNameAsString() : "(no argument)"); 1166246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu Unbold(); 1167246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } else { 1168246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu OS << (FromDefault ? "[(default) template " : "[template "); 1169246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu Bold(); 1170246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu OS << (FromTD ? FromTD->getNameAsString() : "(no argument)"); 1171246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu Unbold(); 1172246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu OS << " != " << (ToDefault ? "(default) template " : "template "); 1173246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu Bold(); 1174246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu OS << (ToTD ? ToTD->getNameAsString() : "(no argument)"); 1175246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu Unbold(); 1176246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu OS << ']'; 1177246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 1178246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 1179246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 1180246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu // Prints the appropriate placeholder for elided template arguments. 1181246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu void PrintElideArgs(unsigned NumElideArgs, unsigned Indent) { 1182246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (PrintTree) { 1183246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu OS << '\n'; 1184246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu for (unsigned i = 0; i < Indent; ++i) 1185246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu OS << " "; 1186246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 1187246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (NumElideArgs == 0) return; 1188246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (NumElideArgs == 1) 1189246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu OS << "[...]"; 1190246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu else 1191246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu OS << "[" << NumElideArgs << " * ...]"; 1192246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 1193246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 1194246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieupublic: 1195246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 1196246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu TemplateDiff(ASTContext &Context, QualType FromType, QualType ToType, 1197246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu bool PrintTree, bool PrintFromType, bool ElideType, 1198246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu bool ShowColor) 1199246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu : Context(Context), 1200246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu Policy(Context.getLangOpts()), 1201246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu ElideType(ElideType), 1202246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu PrintTree(PrintTree), 1203246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu ShowColor(ShowColor), 1204246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu // When printing a single type, the FromType is the one printed. 1205246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu FromType(PrintFromType ? FromType : ToType), 1206246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu ToType(PrintFromType ? ToType : FromType), 1207246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu OS(Str), 1208246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu IsBold(false) { 1209246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 1210246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 1211246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// DiffTemplate - Start the template type diffing. 1212246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu void DiffTemplate() { 1213246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu const TemplateSpecializationType *FromOrigTST = 1214246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu GetTemplateSpecializationType(Context, FromType); 1215246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu const TemplateSpecializationType *ToOrigTST = 1216246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu GetTemplateSpecializationType(Context, ToType); 1217246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 1218246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu // Only checking templates. 1219246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (!FromOrigTST || !ToOrigTST) 1220246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu return; 1221246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 1222246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu // Different base templates. 1223246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (!hasSameTemplate(FromOrigTST, ToOrigTST)) { 1224246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu return; 1225246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 1226246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 1227246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu Tree.SetNode(FromType, ToType); 1228246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 1229246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu // Same base template, but different arguments. 1230246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu Tree.SetNode(FromOrigTST->getTemplateName().getAsTemplateDecl(), 1231246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu ToOrigTST->getTemplateName().getAsTemplateDecl()); 1232246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 1233246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu DiffTemplate(FromOrigTST, ToOrigTST); 123437d2a00f4ca5689dac7fec2931fcef37556f5092David Blaikie } 1235246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 1236246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// MakeString - When the two types given are templated types with the same 1237246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// base template, a string representation of the type difference will be 1238246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu /// loaded into S and return true. Otherwise, return false. 1239246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu bool MakeString(std::string &S) { 1240246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu Tree.StartTraverse(); 1241246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (Tree.Empty()) 1242246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu return false; 1243246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 1244246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu TreeToString(); 1245246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu assert(!IsBold && "Bold is applied to end of string."); 1246246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu S = OS.str(); 1247246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu return true; 1248246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu } 1249246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu}; // end class TemplateDiff 1250246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu} // end namespace 1251246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu 1252246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu/// FormatTemplateTypeDiff - A helper static function to start the template 1253246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu/// diff and return the properly formatted string. Returns true if the diff 1254246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu/// is successful. 1255246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieustatic bool FormatTemplateTypeDiff(ASTContext &Context, QualType FromType, 1256246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu QualType ToType, bool PrintTree, 1257246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu bool PrintFromType, bool ElideType, 1258246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu bool ShowColors, std::string &S) { 1259246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu if (PrintTree) 1260246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu PrintFromType = true; 1261246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu TemplateDiff TD(Context, FromType, ToType, PrintTree, PrintFromType, 1262246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu ElideType, ShowColors); 1263246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu TD.DiffTemplate(); 1264246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu return TD.MakeString(S); 1265246b6aa6763de8c617d564ef33123a8f3293a80eRichard Trieu} 1266