<div dir="ltr"><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Feb 1, 2016 at 2:10 PM, Richard Smith <span dir="ltr"><<a href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div class=""><div class="h5">On Thu, Jan 14, 2016 at 2:57 PM, Richard Trieu via cfe-commits<br>
<<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a>> wrote:<br>
> Author: rtrieu<br>
> Date: Thu Jan 14 16:56:39 2016<br>
> New Revision: 257831<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=257831&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=257831&view=rev</a><br>
> Log:<br>
> Refactor template type diffing<br>
><br>
> 1) Instead of using pairs of From/To* fields, combine fields into a struct<br>
> TemplateArgInfo and have two in each DiffNode.<br>
> 2) Use default initialization in DiffNode so that the constructor shows the<br>
> only field that is initialized differently on construction.<br>
> 3) Use Set and Get functions per each DiffKind to make sure all fields for the<br>
> diff is set.  In one case, the Expr fields were not set.<br>
> 4) Don't print boolean literals for boolean template arguments.  This prevents<br>
> printing 'false aka 0'<br>
><br>
> Only #3 has a functional change, which is reflected in the test change.<br>
><br>
> Modified:<br>
>     cfe/trunk/lib/AST/ASTDiagnostic.cpp<br>
>     cfe/trunk/test/Misc/diag-template-diffing.cpp<br>
><br>
> Modified: cfe/trunk/lib/AST/ASTDiagnostic.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTDiagnostic.cpp?rev=257831&r1=257830&r2=257831&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTDiagnostic.cpp?rev=257831&r1=257830&r2=257831&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/lib/AST/ASTDiagnostic.cpp (original)<br>
> +++ cfe/trunk/lib/AST/ASTDiagnostic.cpp Thu Jan 14 16:56:39 2016<br>
> @@ -491,82 +491,67 @@ class TemplateDiff {<br>
>    /// DiffTree - A tree representation the differences between two types.<br>
>    class DiffTree {<br>
>    public:<br>
> -    /// DiffKind - The difference in a DiffNode and which fields are used.<br>
> +    /// DiffKind - The difference in a DiffNode.  Fields of<br>
> +    /// TemplateArgumentInfo needed by each difference can be found in the<br>
> +    /// Set* and Get* functions.<br>
>      enum DiffKind {<br>
>        /// Incomplete or invalid node.<br>
>        Invalid,<br>
> -      /// Another level of templates, uses TemplateDecl and Qualifiers<br>
> +      /// Another level of templates, requires that<br>
<br>
</div></div>... requires that what?<br></blockquote><div>Comment fixed in r259445. </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div class=""><div class="h5"><br>
>        Template,<br>
> -      /// Type difference, uses QualType<br>
> +      /// Type difference, all type differences except those falling under<br>
> +      /// the Template difference.<br>
>        Type,<br>
> -      /// Expression difference, uses Expr<br>
> +      /// Expression difference, this is only when both arguments are<br>
> +      /// expressions.  If one argument is an expression and the other is<br>
> +      /// Integer or Declaration, then use that diff type instead.<br>
>        Expression,<br>
> -      /// Template argument difference, uses TemplateDecl<br>
> +      /// Template argument difference<br>
>        TemplateTemplate,<br>
> -      /// Integer difference, uses APSInt and Expr<br>
> +      /// Integer difference<br>
>        Integer,<br>
> -      /// Declaration difference, uses ValueDecl<br>
> +      /// Declaration difference, nullptr arguments are included here<br>
>        Declaration<br>
>      };<br>
> +<br>
>    private:<br>
> +    /// TemplateArgumentInfo - All the information needed to pretty print<br>
> +    /// a template argument.  See the Set* and Get* functions to see which<br>
> +    /// fields are used for each DiffKind.<br>
> +    struct TemplateArgumentInfo {<br>
> +      QualType ArgType;<br>
> +      Qualifiers Qual;<br>
> +      llvm::APSInt Val;<br>
> +      bool IsValidInt = false;<br>
> +      Expr *ArgExpr = nullptr;<br>
> +      TemplateDecl *TD = nullptr;<br>
> +      ValueDecl *VD = nullptr;<br>
> +      bool NeedAddressOf = false;<br>
> +      bool IsNullPtr = false;<br>
> +      bool IsDefault = false;<br>
> +    };<br>
> +<br>
>      /// DiffNode - The root node stores the original type.  Each child node<br>
>      /// stores template arguments of their parents.  For templated types, the<br>
>      /// template decl is also stored.<br>
>      struct DiffNode {<br>
> -      DiffKind Kind;<br>
> +      DiffKind Kind = Invalid;<br>
><br>
>        /// NextNode - The index of the next sibling node or 0.<br>
> -      unsigned NextNode;<br>
> +      unsigned NextNode = 0;<br>
><br>
>        /// ChildNode - The index of the first child node or 0.<br>
> -      unsigned ChildNode;<br>
> +      unsigned ChildNode = 0;<br>
><br>
>        /// ParentNode - The index of the parent node.<br>
> -      unsigned ParentNode;<br>
> -<br>
> -      /// FromType, ToType - The type arguments.<br>
> -      QualType FromType, ToType;<br>
> -<br>
> -      /// FromExpr, ToExpr - The expression arguments.<br>
> -      Expr *FromExpr, *ToExpr;<br>
> -<br>
> -      /// FromNullPtr, ToNullPtr - If the template argument is a nullptr<br>
> -      bool FromNullPtr, ToNullPtr;<br>
> -<br>
> -      /// FromTD, ToTD - The template decl for template template<br>
> -      /// arguments or the type arguments that are templates.<br>
> -      TemplateDecl *FromTD, *ToTD;<br>
> -<br>
> -      /// FromQual, ToQual - Qualifiers for template types.<br>
> -      Qualifiers FromQual, ToQual;<br>
> -<br>
> -      /// FromInt, ToInt - APSInt's for integral arguments.<br>
> -      llvm::APSInt FromInt, ToInt;<br>
> -<br>
> -      /// IsValidFromInt, IsValidToInt - Whether the APSInt's are valid.<br>
> -      bool IsValidFromInt, IsValidToInt;<br>
> +      unsigned ParentNode = 0;<br>
><br>
> -      /// FromValueDecl, ToValueDecl - Whether the argument is a decl.<br>
> -      ValueDecl *FromValueDecl, *ToValueDecl;<br>
> -<br>
> -      /// FromAddressOf, ToAddressOf - Whether the ValueDecl needs an address of<br>
> -      /// operator before it.<br>
> -      bool FromAddressOf, ToAddressOf;<br>
> -<br>
> -      /// FromDefault, ToDefault - Whether the argument is a default argument.<br>
> -      bool FromDefault, ToDefault;<br>
> +      TemplateArgumentInfo FromArgInfo, ToArgInfo;<br>
><br>
>        /// Same - Whether the two arguments evaluate to the same value.<br>
> -      bool Same;<br>
> +      bool Same = false;<br>
><br>
> -      DiffNode(unsigned ParentNode = 0)<br>
> -        : Kind(Invalid), NextNode(0), ChildNode(0), ParentNode(ParentNode),<br>
> -          FromType(), ToType(), FromExpr(nullptr), ToExpr(nullptr),<br>
> -          FromNullPtr(false), ToNullPtr(false),<br>
> -          FromTD(nullptr), ToTD(nullptr), IsValidFromInt(false),<br>
> -          IsValidToInt(false), FromValueDecl(nullptr), ToValueDecl(nullptr),<br>
> -          FromAddressOf(false), ToAddressOf(false), FromDefault(false),<br>
> -          ToDefault(false), Same(false) {}<br>
> +      DiffNode(unsigned ParentNode = 0) : ParentNode(ParentNode) {}<br>
>      };<br>
><br>
>      /// FlatTree - A flattened tree used to store the DiffNodes.<br>
> @@ -581,54 +566,90 @@ class TemplateDiff {<br>
><br>
>      /// ReadNode - The index of the current node being read.<br>
>      unsigned ReadNode;<br>
> -<br>
> +<br>
>    public:<br>
>      DiffTree() :<br>
>          CurrentNode(0), NextFreeNode(1) {<br>
>        FlatTree.push_back(DiffNode());<br>
>      }<br>
><br>
> -    // Node writing functions.<br>
> -    /// SetNode - Sets FromTD and ToTD of the current node.<br>
> -    void SetNode(TemplateDecl *FromTD, TemplateDecl *ToTD) {<br>
> -      FlatTree[CurrentNode].FromTD = FromTD;<br>
> -      FlatTree[CurrentNode].ToTD = ToTD;<br>
> -    }<br>
> -<br>
> -    /// SetNode - Sets FromType and ToType of the current node.<br>
> -    void SetNode(QualType FromType, QualType ToType) {<br>
> -      FlatTree[CurrentNode].FromType = FromType;<br>
> -      FlatTree[CurrentNode].ToType = ToType;<br>
> -    }<br>
> -<br>
> -    /// SetNode - Set FromExpr and ToExpr of the current node.<br>
> -    void SetNode(Expr *FromExpr, Expr *ToExpr) {<br>
> -      FlatTree[CurrentNode].FromExpr = FromExpr;<br>
> -      FlatTree[CurrentNode].ToExpr = ToExpr;<br>
> -    }<br>
> -<br>
> -    /// SetNode - Set FromInt and ToInt of the current node.<br>
> -    void SetNode(llvm::APSInt FromInt, llvm::APSInt ToInt,<br>
> -                 bool IsValidFromInt, bool IsValidToInt) {<br>
> -      FlatTree[CurrentNode].FromInt = FromInt;<br>
> -      FlatTree[CurrentNode].ToInt = ToInt;<br>
> -      FlatTree[CurrentNode].IsValidFromInt = IsValidFromInt;<br>
> -      FlatTree[CurrentNode].IsValidToInt = IsValidToInt;<br>
> -    }<br>
> -<br>
> -    /// SetNode - Set FromQual and ToQual of the current node.<br>
> -    void SetNode(Qualifiers FromQual, Qualifiers ToQual) {<br>
> -      FlatTree[CurrentNode].FromQual = FromQual;<br>
> -      FlatTree[CurrentNode].ToQual = ToQual;<br>
> -    }<br>
> -<br>
> -    /// SetNode - Set FromValueDecl and ToValueDecl of the current node.<br>
> -    void SetNode(ValueDecl *FromValueDecl, ValueDecl *ToValueDecl,<br>
> -                 bool FromAddressOf, bool ToAddressOf) {<br>
> -      FlatTree[CurrentNode].FromValueDecl = FromValueDecl;<br>
> -      FlatTree[CurrentNode].ToValueDecl = ToValueDecl;<br>
> -      FlatTree[CurrentNode].FromAddressOf = FromAddressOf;<br>
> -      FlatTree[CurrentNode].ToAddressOf = ToAddressOf;<br>
> +    // Node writing functions, one for each valid DiffKind element.<br>
> +    void SetTemplateDiff(TemplateDecl *FromTD, TemplateDecl *ToTD,<br>
> +                         Qualifiers FromQual, Qualifiers ToQual,<br>
> +                         bool FromDefault, bool ToDefault) {<br>
> +      assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty.");<br>
> +      FlatTree[CurrentNode].Kind = Template;<br>
> +      FlatTree[CurrentNode].FromArgInfo.TD = FromTD;<br>
> +      FlatTree[CurrentNode].ToArgInfo.TD = ToTD;<br>
> +      FlatTree[CurrentNode].FromArgInfo.Qual = FromQual;<br>
> +      FlatTree[CurrentNode].ToArgInfo.Qual = ToQual;<br>
> +      SetDefault(FromDefault, ToDefault);<br>
> +    }<br>
> +<br>
> +    void SetTypeDiff(QualType FromType, QualType ToType, bool FromDefault,<br>
> +                     bool ToDefault) {<br>
> +      assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty.");<br>
> +      FlatTree[CurrentNode].Kind = Type;<br>
> +      FlatTree[CurrentNode].FromArgInfo.ArgType = FromType;<br>
> +      FlatTree[CurrentNode].ToArgInfo.ArgType = ToType;<br>
> +      SetDefault(FromDefault, ToDefault);<br>
> +    }<br>
> +<br>
> +    void SetExpressionDiff(Expr *FromExpr, Expr *ToExpr, bool IsFromNullPtr,<br>
> +                           bool IsToNullPtr, bool FromDefault, bool ToDefault) {<br>
> +      assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty.");<br>
> +      FlatTree[CurrentNode].Kind = Expression;<br>
> +      FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr;<br>
> +      FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr;<br>
> +      FlatTree[CurrentNode].FromArgInfo.IsNullPtr = IsFromNullPtr;<br>
> +      FlatTree[CurrentNode].ToArgInfo.IsNullPtr = IsToNullPtr;<br>
> +      SetDefault(FromDefault, ToDefault);<br>
> +    }<br>
> +<br>
> +    void SetTemplateTemplateDiff(TemplateDecl *FromTD, TemplateDecl *ToTD,<br>
> +                                 bool FromDefault, bool ToDefault) {<br>
> +      assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty.");<br>
> +      FlatTree[CurrentNode].Kind = TemplateTemplate;<br>
> +      FlatTree[CurrentNode].FromArgInfo.TD = FromTD;<br>
> +      FlatTree[CurrentNode].ToArgInfo.TD = ToTD;<br>
> +      SetDefault(FromDefault, ToDefault);<br>
> +    }<br>
> +<br>
> +    void SetIntegerDiff(llvm::APSInt FromInt, llvm::APSInt ToInt,<br>
> +                        bool IsValidFromInt, bool IsValidToInt,<br>
> +                        Expr *FromExpr, Expr *ToExpr, bool FromDefault,<br>
> +                        bool ToDefault) {<br>
> +      assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty.");<br>
> +      FlatTree[CurrentNode].Kind = Integer;<br>
> +      FlatTree[CurrentNode].FromArgInfo.Val = FromInt;<br>
> +      FlatTree[CurrentNode].ToArgInfo.Val = ToInt;<br>
> +      FlatTree[CurrentNode].FromArgInfo.IsValidInt = IsValidFromInt;<br>
> +      FlatTree[CurrentNode].ToArgInfo.IsValidInt = IsValidToInt;<br>
> +      FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr;<br>
> +      FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr;<br>
> +      SetDefault(FromDefault, ToDefault);<br>
> +    }<br>
> +<br>
> +    void SetDeclarationDiff(ValueDecl *FromValueDecl, ValueDecl *ToValueDecl,<br>
> +                            bool FromAddressOf, bool ToAddressOf,<br>
> +                            bool FromNullPtr, bool ToNullPtr, bool FromDefault,<br>
> +                            bool ToDefault) {<br>
> +      assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty.");<br>
> +      FlatTree[CurrentNode].Kind = Declaration;<br>
> +      FlatTree[CurrentNode].FromArgInfo.VD = FromValueDecl;<br>
> +      FlatTree[CurrentNode].ToArgInfo.VD = ToValueDecl;<br>
> +      FlatTree[CurrentNode].FromArgInfo.NeedAddressOf = FromAddressOf;<br>
> +      FlatTree[CurrentNode].ToArgInfo.NeedAddressOf = ToAddressOf;<br>
> +      FlatTree[CurrentNode].FromArgInfo.IsNullPtr = FromNullPtr;<br>
> +      FlatTree[CurrentNode].ToArgInfo.IsNullPtr = ToNullPtr;<br>
> +      SetDefault(FromDefault, ToDefault);<br>
> +    }<br>
> +<br>
> +    /// SetDefault - Sets FromDefault and ToDefault flags of the current node.<br>
> +    void SetDefault(bool FromDefault, bool ToDefault) {<br>
> +      assert(!FromDefault || !ToDefault && "Both arguments cannot be default.");<br>
> +      FlatTree[CurrentNode].FromArgInfo.IsDefault = FromDefault;<br>
> +      FlatTree[CurrentNode].ToArgInfo.IsDefault = ToDefault;<br>
>      }<br>
><br>
>      /// SetSame - Sets the same flag of the current node.<br>
> @@ -636,18 +657,6 @@ class TemplateDiff {<br>
>        FlatTree[CurrentNode].Same = Same;<br>
>      }<br>
><br>
> -    /// SetNullPtr - Sets the NullPtr flags of the current node.<br>
> -    void SetNullPtr(bool FromNullPtr, bool ToNullPtr) {<br>
> -      FlatTree[CurrentNode].FromNullPtr = FromNullPtr;<br>
> -      FlatTree[CurrentNode].ToNullPtr = ToNullPtr;<br>
> -    }<br>
> -<br>
> -    /// SetDefault - Sets FromDefault and ToDefault flags of the current node.<br>
> -    void SetDefault(bool FromDefault, bool ToDefault) {<br>
> -      FlatTree[CurrentNode].FromDefault = FromDefault;<br>
> -      FlatTree[CurrentNode].ToDefault = ToDefault;<br>
> -    }<br>
> -<br>
>      /// SetKind - Sets the current node's type.<br>
>      void SetKind(DiffKind Kind) {<br>
>        FlatTree[CurrentNode].Kind = Kind;<br>
> @@ -692,46 +701,68 @@ class TemplateDiff {<br>
>        ReadNode = FlatTree[ReadNode].ParentNode;<br>
>      }<br>
><br>
> -    /// GetNode - Gets the FromType and ToType.<br>
> -    void GetNode(QualType &FromType, QualType &ToType) {<br>
> -      FromType = FlatTree[ReadNode].FromType;<br>
> -      ToType = FlatTree[ReadNode].ToType;<br>
> -    }<br>
> -<br>
> -    /// GetNode - Gets the FromExpr and ToExpr.<br>
> -    void GetNode(Expr *&FromExpr, Expr *&ToExpr) {<br>
> -      FromExpr = FlatTree[ReadNode].FromExpr;<br>
> -      ToExpr = FlatTree[ReadNode].ToExpr;<br>
> -    }<br>
> -<br>
> -    /// GetNode - Gets the FromTD and ToTD.<br>
> -    void GetNode(TemplateDecl *&FromTD, TemplateDecl *&ToTD) {<br>
> -      FromTD = FlatTree[ReadNode].FromTD;<br>
> -      ToTD = FlatTree[ReadNode].ToTD;<br>
> -    }<br>
> -<br>
> -    /// GetNode - Gets the FromInt and ToInt.<br>
> -    void GetNode(llvm::APSInt &FromInt, llvm::APSInt &ToInt,<br>
> -                 bool &IsValidFromInt, bool &IsValidToInt) {<br>
> -      FromInt = FlatTree[ReadNode].FromInt;<br>
> -      ToInt = FlatTree[ReadNode].ToInt;<br>
> -      IsValidFromInt = FlatTree[ReadNode].IsValidFromInt;<br>
> -      IsValidToInt = FlatTree[ReadNode].IsValidToInt;<br>
> -    }<br>
> -<br>
> -    /// GetNode - Gets the FromQual and ToQual.<br>
> -    void GetNode(Qualifiers &FromQual, Qualifiers &ToQual) {<br>
> -      FromQual = FlatTree[ReadNode].FromQual;<br>
> -      ToQual = FlatTree[ReadNode].ToQual;<br>
> -    }<br>
> -<br>
> -    /// GetNode - Gets the FromValueDecl and ToValueDecl.<br>
> -    void GetNode(ValueDecl *&FromValueDecl, ValueDecl *&ToValueDecl,<br>
> -                 bool &FromAddressOf, bool &ToAddressOf) {<br>
> -      FromValueDecl = FlatTree[ReadNode].FromValueDecl;<br>
> -      ToValueDecl = FlatTree[ReadNode].ToValueDecl;<br>
> -      FromAddressOf = FlatTree[ReadNode].FromAddressOf;<br>
> -      ToAddressOf = FlatTree[ReadNode].ToAddressOf;<br>
> +    void GetTemplateDiff(TemplateDecl *&FromTD, TemplateDecl *&ToTD,<br>
> +                         Qualifiers &FromQual, Qualifiers &ToQual) {<br>
> +      assert(FlatTree[ReadNode].Kind == Template && "Unexpected kind.");<br>
> +      FromTD = FlatTree[ReadNode].FromArgInfo.TD;<br>
> +      ToTD = FlatTree[ReadNode].ToArgInfo.TD;<br>
> +      FromQual = FlatTree[ReadNode].FromArgInfo.Qual;<br>
> +      ToQual = FlatTree[ReadNode].ToArgInfo.Qual;<br>
> +    }<br>
> +<br>
> +    void GetTypeDiff(QualType &FromType, QualType &ToType) {<br>
> +      assert(FlatTree[ReadNode].Kind == Type && "Unexpected kind");<br>
> +      FromType = FlatTree[ReadNode].FromArgInfo.ArgType;<br>
> +      ToType = FlatTree[ReadNode].ToArgInfo.ArgType;<br>
> +    }<br>
> +<br>
> +    void GetExpressionDiff(Expr *&FromExpr, Expr *&ToExpr, bool &FromNullPtr,<br>
> +                           bool &ToNullPtr) {<br>
> +      assert(FlatTree[ReadNode].Kind == Expression && "Unexpected kind");<br>
> +      FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr;<br>
> +      ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr;<br>
> +      FromNullPtr = FlatTree[ReadNode].FromArgInfo.IsNullPtr;<br>
> +      ToNullPtr = FlatTree[ReadNode].ToArgInfo.IsNullPtr;<br>
> +    }<br>
> +<br>
> +    void GetTemplateTemplateDiff(TemplateDecl *&FromTD, TemplateDecl *&ToTD) {<br>
> +      assert(FlatTree[ReadNode].Kind == TemplateTemplate && "Unexpected kind.");<br>
> +      FromTD = FlatTree[ReadNode].FromArgInfo.TD;<br>
> +      ToTD = FlatTree[ReadNode].ToArgInfo.TD;<br>
> +    }<br>
> +<br>
> +    void GetIntegerDiff(llvm::APSInt &FromInt, llvm::APSInt &ToInt,<br>
> +                        bool &IsValidFromInt, bool &IsValidToInt,<br>
> +                        Expr *&FromExpr, Expr *&ToExpr) {<br>
> +      assert(FlatTree[ReadNode].Kind == Integer && "Unexpected kind.");<br>
> +      FromInt = FlatTree[ReadNode].FromArgInfo.Val;<br>
> +      ToInt = FlatTree[ReadNode].ToArgInfo.Val;<br>
> +      IsValidFromInt = FlatTree[ReadNode].FromArgInfo.IsValidInt;<br>
> +      IsValidToInt = FlatTree[ReadNode].ToArgInfo.IsValidInt;<br>
> +      FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr;<br>
> +      ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr;<br>
> +    }<br>
> +<br>
> +    void GetDeclarationDiff(ValueDecl *&FromValueDecl, ValueDecl *&ToValueDecl,<br>
> +                            bool &FromAddressOf, bool &ToAddressOf,<br>
> +                            bool &FromNullPtr, bool &ToNullPtr) {<br>
> +      assert(FlatTree[ReadNode].Kind == Declaration && "Unexpected kind.");<br>
> +      FromValueDecl = FlatTree[ReadNode].FromArgInfo.VD;<br>
> +      ToValueDecl = FlatTree[ReadNode].ToArgInfo.VD;<br>
> +      FromAddressOf = FlatTree[ReadNode].FromArgInfo.NeedAddressOf;<br>
> +      ToAddressOf = FlatTree[ReadNode].ToArgInfo.NeedAddressOf;<br>
> +      FromNullPtr = FlatTree[ReadNode].FromArgInfo.IsNullPtr;<br>
> +      ToNullPtr = FlatTree[ReadNode].ToArgInfo.IsNullPtr;<br>
> +    }<br>
> +<br>
> +    /// FromDefault - Return true if the from argument is the default.<br>
> +    bool FromDefault() {<br>
> +      return FlatTree[ReadNode].FromArgInfo.IsDefault;<br>
> +    }<br>
> +<br>
> +    /// ToDefault - Return true if the to argument is the default.<br>
> +    bool ToDefault() {<br>
> +      return FlatTree[ReadNode].ToArgInfo.IsDefault;<br>
>      }<br>
><br>
>      /// NodeIsSame - Returns true the arguments are the same.<br>
> @@ -764,26 +795,6 @@ class TemplateDiff {<br>
>        return FlatTree[ReadNode].NextNode != 0;<br>
>      }<br>
><br>
> -    /// FromNullPtr - Returns true if the from argument is null.<br>
> -    bool FromNullPtr() {<br>
> -      return FlatTree[ReadNode].FromNullPtr;<br>
> -    }<br>
> -<br>
> -    /// ToNullPtr - Returns true if the to argument is null.<br>
> -    bool ToNullPtr() {<br>
> -      return FlatTree[ReadNode].ToNullPtr;<br>
> -    }<br>
> -<br>
> -    /// FromDefault - Return true if the from argument is the default.<br>
> -    bool FromDefault() {<br>
> -      return FlatTree[ReadNode].FromDefault;<br>
> -    }<br>
> -<br>
> -    /// ToDefault - Return true if the to argument is the default.<br>
> -    bool ToDefault() {<br>
> -      return FlatTree[ReadNode].ToDefault;<br>
> -    }<br>
> -<br>
>      /// Empty - Returns true if the tree has no information.<br>
>      bool Empty() {<br>
>        return GetKind() == Invalid;<br>
> @@ -935,6 +946,29 @@ class TemplateDiff {<br>
>      return Ty->getAs<TemplateSpecializationType>();<br>
>    }<br>
><br>
> +  /// Returns true if the DiffType is Type and false for Template.<br>
> +  static bool OnlyPerformTypeDiff(ASTContext &Context, QualType FromType,<br>
> +                                  QualType ToType,<br>
> +                                  const TemplateSpecializationType *&FromArgTST,<br>
> +                                  const TemplateSpecializationType *&ToArgTST) {<br>
> +    if (FromType.isNull() || ToType.isNull())<br>
> +      return true;<br>
> +<br>
> +    if (Context.hasSameType(FromType, ToType))<br>
> +      return true;<br>
> +<br>
> +    FromArgTST = GetTemplateSpecializationType(Context, FromType);<br>
> +    ToArgTST = GetTemplateSpecializationType(Context, ToType);<br>
> +<br>
> +    if (!FromArgTST || !ToArgTST)<br>
> +      return true;<br>
> +<br>
> +    if (!hasSameTemplate(FromArgTST, ToArgTST))<br>
> +      return true;<br>
> +<br>
> +    return false;<br>
> +  }<br>
> +<br>
>    /// DiffTypes - Fills a DiffNode with information about a type difference.<br>
>    void DiffTypes(const TSTiterator &FromIter, const TSTiterator &ToIter,<br>
>                   TemplateTypeParmDecl *FromDefaultTypeDecl,<br>
> @@ -942,40 +976,27 @@ class TemplateDiff {<br>
>      QualType FromType = GetType(FromIter, FromDefaultTypeDecl);<br>
>      QualType ToType = GetType(ToIter, ToDefaultTypeDecl);<br>
><br>
> -    Tree.SetNode(FromType, ToType);<br>
> -    Tree.SetDefault(FromIter.isEnd() && !FromType.isNull(),<br>
> -                    ToIter.isEnd() && !ToType.isNull());<br>
> -    Tree.SetKind(DiffTree::Type);<br>
> -    if (FromType.isNull() || ToType.isNull())<br>
> -      return;<br>
> +    bool FromDefault = FromIter.isEnd() && !FromType.isNull();<br>
> +    bool ToDefault = ToIter.isEnd() && !ToType.isNull();<br>
><br>
> -    if (Context.hasSameType(FromType, ToType)) {<br>
> -      Tree.SetSame(true);<br>
> -      return;<br>
> +    const TemplateSpecializationType *FromArgTST = nullptr;<br>
> +    const TemplateSpecializationType *ToArgTST = nullptr;<br>
> +    if (OnlyPerformTypeDiff(Context, FromType, ToType, FromArgTST, ToArgTST)) {<br>
> +      Tree.SetTypeDiff(FromType, ToType, FromDefault, ToDefault);<br>
> +      Tree.SetSame(!FromType.isNull() && !ToType.isNull() &&<br>
> +                   Context.hasSameType(FromType, ToType));<br>
> +    } else {<br>
> +      assert(FromArgTST && ToArgTST &&<br>
> +             "Both template specializations need to be valid.");<br>
> +      Qualifiers FromQual = FromType.getQualifiers(),<br>
> +                 ToQual = ToType.getQualifiers();<br>
> +      FromQual -= QualType(FromArgTST, 0).getQualifiers();<br>
> +      ToQual -= QualType(ToArgTST, 0).getQualifiers();<br>
> +      Tree.SetTemplateDiff(FromArgTST->getTemplateName().getAsTemplateDecl(),<br>
> +                           ToArgTST->getTemplateName().getAsTemplateDecl(),<br>
> +                           FromQual, ToQual, FromDefault, ToDefault);<br>
> +      DiffTemplate(FromArgTST, ToArgTST);<br>
>      }<br>
> -<br>
> -    const TemplateSpecializationType *FromArgTST =<br>
> -        GetTemplateSpecializationType(Context, FromType);<br>
> -    if (!FromArgTST)<br>
> -      return;<br>
> -<br>
> -    const TemplateSpecializationType *ToArgTST =<br>
> -        GetTemplateSpecializationType(Context, ToType);<br>
> -    if (!ToArgTST)<br>
> -      return;<br>
> -<br>
> -    if (!hasSameTemplate(FromArgTST, ToArgTST))<br>
> -      return;<br>
> -<br>
> -    Qualifiers FromQual = FromType.getQualifiers(),<br>
> -               ToQual = ToType.getQualifiers();<br>
> -    FromQual -= QualType(FromArgTST, 0).getQualifiers();<br>
> -    ToQual -= QualType(ToArgTST, 0).getQualifiers();<br>
> -    Tree.SetNode(FromArgTST->getTemplateName().getAsTemplateDecl(),<br>
> -                 ToArgTST->getTemplateName().getAsTemplateDecl());<br>
> -    Tree.SetNode(FromQual, ToQual);<br>
> -    Tree.SetKind(DiffTree::Template);<br>
> -    DiffTemplate(FromArgTST, ToArgTST);<br>
>    }<br>
><br>
>    /// DiffTemplateTemplates - Fills a DiffNode with information about a<br>
> @@ -986,11 +1007,10 @@ class TemplateDiff {<br>
>                               TemplateTemplateParmDecl *ToDefaultTemplateDecl) {<br>
>      TemplateDecl *FromDecl = GetTemplateDecl(FromIter, FromDefaultTemplateDecl);<br>
>      TemplateDecl *ToDecl = GetTemplateDecl(ToIter, ToDefaultTemplateDecl);<br>
> -    Tree.SetNode(FromDecl, ToDecl);<br>
> +    Tree.SetTemplateTemplateDiff(FromDecl, ToDecl, FromIter.isEnd() && FromDecl,<br>
> +                                 ToIter.isEnd() && ToDecl);<br>
>      Tree.SetSame(FromDecl && ToDecl &&<br>
>                   FromDecl->getCanonicalDecl() == ToDecl->getCanonicalDecl());<br>
> -    Tree.SetDefault(FromIter.isEnd() && FromDecl, ToIter.isEnd() && ToDecl);<br>
> -    Tree.SetKind(DiffTree::TemplateTemplate);<br>
>    }<br>
><br>
>    /// InitializeNonTypeDiffVariables - Helper function for DiffNonTypes<br>
> @@ -1060,9 +1080,12 @@ class TemplateDiff {<br>
>              (!HasFromValueDecl && !HasToValueDecl)) &&<br>
>             "Template argument cannot be both integer and declaration");<br>
><br>
> +    bool FromDefault = FromIter.isEnd() &&<br>
> +                       (FromExpr || FromValueDecl || HasFromInt || FromNullPtr);<br>
> +    bool ToDefault = ToIter.isEnd() &&<br>
> +                     (ToExpr || ToValueDecl || HasToInt || ToNullPtr);<br>
> +<br>
>      if (!HasFromInt && !HasToInt && !HasFromValueDecl && !HasToValueDecl) {<br>
> -      Tree.SetNode(FromExpr, ToExpr);<br>
> -      Tree.SetDefault(FromIter.isEnd() && FromExpr, ToIter.isEnd() && ToExpr);<br>
>        if (FromDefaultNonTypeDecl->getType()->isIntegralOrEnumerationType()) {<br>
>          if (FromExpr)<br>
>            HasFromInt = GetInt(Context, FromIter, FromExpr, FromInt,<br>
> @@ -1072,18 +1095,18 @@ class TemplateDiff {<br>
>                              ToDefaultNonTypeDecl->getType());<br>
>        }<br>
>        if (HasFromInt && HasToInt) {<br>
> -        Tree.SetNode(FromInt, ToInt, HasFromInt, HasToInt);<br>
> +        Tree.SetIntegerDiff(FromInt, ToInt, HasFromInt, HasToInt, FromExpr,<br>
> +                            ToExpr, FromDefault, ToDefault);<br>
>          Tree.SetSame(FromInt == ToInt);<br>
> -        Tree.SetKind(DiffTree::Integer);<br>
>        } else if (HasFromInt || HasToInt) {<br>
> -        Tree.SetNode(FromInt, ToInt, HasFromInt, HasToInt);<br>
> +        Tree.SetIntegerDiff(FromInt, ToInt, HasFromInt, HasToInt, FromExpr,<br>
> +                            ToExpr, FromDefault, ToDefault);<br>
>          Tree.SetSame(false);<br>
> -        Tree.SetKind(DiffTree::Integer);<br>
>        } else {<br>
>          Tree.SetSame(IsEqualExpr(Context, FromExpr, ToExpr) ||<br>
>                       (FromNullPtr && ToNullPtr));<br>
> -        Tree.SetNullPtr(FromNullPtr, ToNullPtr);<br>
> -        Tree.SetKind(DiffTree::Expression);<br>
> +        Tree.SetExpressionDiff(FromExpr, ToExpr, FromNullPtr, ToNullPtr,<br>
> +                               FromDefault, ToDefault);<br>
>        }<br>
>        return;<br>
>      }<br>
> @@ -1095,15 +1118,13 @@ class TemplateDiff {<br>
>        if (!HasToInt && ToExpr)<br>
>          HasToInt = GetInt(Context, ToIter, ToExpr, ToInt,<br>
>                            ToDefaultNonTypeDecl->getType());<br>
> -      Tree.SetNode(FromInt, ToInt, HasFromInt, HasToInt);<br>
> +      Tree.SetIntegerDiff(FromInt, ToInt, HasFromInt, HasToInt, FromExpr,<br>
> +                          ToExpr, FromDefault, ToDefault);<br>
>        if (HasFromInt && HasToInt) {<br>
>          Tree.SetSame(FromInt == ToInt);<br>
>        } else {<br>
>          Tree.SetSame(false);<br>
>        }<br>
> -      Tree.SetDefault(FromIter.isEnd() && HasFromInt,<br>
> -                      ToIter.isEnd() && HasToInt);<br>
> -      Tree.SetKind(DiffTree::Integer);<br>
>        return;<br>
>      }<br>
><br>
> @@ -1117,14 +1138,12 @@ class TemplateDiff {<br>
>      bool ToAddressOf =<br>
>          NeedsAddressOf(ToValueDecl, ToExpr, ToDefaultNonTypeDecl);<br>
><br>
> -    Tree.SetNullPtr(FromNullPtr, ToNullPtr);<br>
> -    Tree.SetNode(FromValueDecl, ToValueDecl, FromAddressOf, ToAddressOf);<br>
> +    Tree.SetDeclarationDiff(FromValueDecl, ToValueDecl, FromAddressOf,<br>
> +                            ToAddressOf, FromNullPtr, ToNullPtr, FromDefault,<br>
> +                            ToDefault);<br>
>      Tree.SetSame(FromValueDecl && ToValueDecl &&<br>
>                   FromValueDecl->getCanonicalDecl() ==<br>
>                       ToValueDecl->getCanonicalDecl());<br>
> -    Tree.SetDefault(FromIter.isEnd() && FromValueDecl,<br>
> -                    ToIter.isEnd() && ToValueDecl);<br>
> -    Tree.SetKind(DiffTree::Declaration);<br>
>    }<br>
><br>
>    /// DiffTemplate - recursively visits template arguments and stores the<br>
> @@ -1442,21 +1461,22 @@ class TemplateDiff {<br>
>          llvm_unreachable("Template diffing failed with bad DiffNode");<br>
>        case DiffTree::Type: {<br>
>          QualType FromType, ToType;<br>
> -        Tree.GetNode(FromType, ToType);<br>
> +        Tree.GetTypeDiff(FromType, ToType);<br>
>          PrintTypeNames(FromType, ToType, Tree.FromDefault(), Tree.ToDefault(),<br>
>                         Tree.NodeIsSame());<br>
>          return;<br>
>        }<br>
>        case DiffTree::Expression: {<br>
>          Expr *FromExpr, *ToExpr;<br>
> -        Tree.GetNode(FromExpr, ToExpr);<br>
> -        PrintExpr(FromExpr, ToExpr, Tree.FromNullPtr(), Tree.ToNullPtr(),<br>
> -                  Tree.FromDefault(), Tree.ToDefault(), Tree.NodeIsSame());<br>
> +        bool FromNullPtr, ToNullPtr;<br>
> +        Tree.GetExpressionDiff(FromExpr, ToExpr, FromNullPtr, ToNullPtr);<br>
> +        PrintExpr(FromExpr, ToExpr, FromNullPtr, ToNullPtr, Tree.FromDefault(),<br>
> +                  Tree.ToDefault(), Tree.NodeIsSame());<br>
>          return;<br>
>        }<br>
>        case DiffTree::TemplateTemplate: {<br>
>          TemplateDecl *FromTD, *ToTD;<br>
> -        Tree.GetNode(FromTD, ToTD);<br>
> +        Tree.GetTemplateTemplateDiff(FromTD, ToTD);<br>
>          PrintTemplateTemplate(FromTD, ToTD, Tree.FromDefault(),<br>
>                                Tree.ToDefault(), Tree.NodeIsSame());<br>
>          return;<br>
> @@ -1465,8 +1485,8 @@ class TemplateDiff {<br>
>          llvm::APSInt FromInt, ToInt;<br>
>          Expr *FromExpr, *ToExpr;<br>
>          bool IsValidFromInt, IsValidToInt;<br>
> -        Tree.GetNode(FromExpr, ToExpr);<br>
> -        Tree.GetNode(FromInt, ToInt, IsValidFromInt, IsValidToInt);<br>
> +        Tree.GetIntegerDiff(FromInt, ToInt, IsValidFromInt, IsValidToInt,<br>
> +                            FromExpr, ToExpr);<br>
>          PrintAPSInt(FromInt, ToInt, IsValidFromInt, IsValidToInt,<br>
>                      FromExpr, ToExpr, Tree.FromDefault(), Tree.ToDefault(),<br>
>                      Tree.NodeIsSame());<br>
> @@ -1475,16 +1495,19 @@ class TemplateDiff {<br>
>        case DiffTree::Declaration: {<br>
>          ValueDecl *FromValueDecl, *ToValueDecl;<br>
>          bool FromAddressOf, ToAddressOf;<br>
> -        Tree.GetNode(FromValueDecl, ToValueDecl, FromAddressOf, ToAddressOf);<br>
> +        bool FromNullPtr, ToNullPtr;<br>
> +        Tree.GetDeclarationDiff(FromValueDecl, ToValueDecl, FromAddressOf,<br>
> +                                ToAddressOf, FromNullPtr, ToNullPtr);<br>
>          PrintValueDecl(FromValueDecl, ToValueDecl, FromAddressOf, ToAddressOf,<br>
> -                       Tree.FromNullPtr(), Tree.ToNullPtr(), Tree.FromDefault(),<br>
> +                       FromNullPtr, ToNullPtr, Tree.FromDefault(),<br>
>                         Tree.ToDefault(), Tree.NodeIsSame());<br>
>          return;<br>
>        }<br>
>        case DiffTree::Template: {<br>
>          // Node is root of template.  Recurse on children.<br>
>          TemplateDecl *FromTD, *ToTD;<br>
> -        Tree.GetNode(FromTD, ToTD);<br>
> +        Qualifiers FromQual, ToQual;<br>
> +        Tree.GetTemplateDiff(FromTD, ToTD, FromQual, ToQual);<br>
><br>
>          if (!Tree.HasChildren()) {<br>
>            // If we're dealing with a template specialization with zero<br>
> @@ -1493,11 +1516,9 @@ class TemplateDiff {<br>
>            return;<br>
>          }<br>
><br>
> -        Qualifiers FromQual, ToQual;<br>
> -        Tree.GetNode(FromQual, ToQual);<br>
>          PrintQualifiers(FromQual, ToQual);<br>
><br>
> -        OS << FromTD->getNameAsString() << '<';<br>
> +        OS << FromTD->getNameAsString() << '<';<br>
>          Tree.MoveToChild();<br>
>          unsigned NumElideArgs = 0;<br>
>          do {<br>
> @@ -1716,8 +1737,8 @@ class TemplateDiff {<br>
>      Unbold();<br>
>    }<br>
><br>
> -  /// HasExtraInfo - Returns true if E is not an integer literal or the<br>
> -  /// negation of an integer literal<br>
> +  /// HasExtraInfo - Returns true if E is not an integer literal, the<br>
> +  /// negation of an integer literal, or a boolean literal.<br>
>    bool HasExtraInfo(Expr *E) {<br>
>      if (!E) return false;<br>
><br>
> @@ -1730,6 +1751,9 @@ class TemplateDiff {<br>
>          if (isa<IntegerLiteral>(UO->getSubExpr()))<br>
>            return false;<br>
><br>
> +    if (isa<CXXBoolLiteralExpr>(E))<br>
> +      return false;<br>
> +<br>
>      return true;<br>
>    }<br>
><br>
> @@ -1893,13 +1917,12 @@ public:<br>
><br>
>      FromQual -= QualType(FromOrigTST, 0).getQualifiers();<br>
>      ToQual -= QualType(ToOrigTST, 0).getQualifiers();<br>
> -    Tree.SetNode(FromType, ToType);<br>
> -    Tree.SetNode(FromQual, ToQual);<br>
> -    Tree.SetKind(DiffTree::Template);<br>
><br>
>      // Same base template, but different arguments.<br>
> -    Tree.SetNode(FromOrigTST->getTemplateName().getAsTemplateDecl(),<br>
> -                 ToOrigTST->getTemplateName().getAsTemplateDecl());<br>
> +    Tree.SetTemplateDiff(FromOrigTST->getTemplateName().getAsTemplateDecl(),<br>
> +                         ToOrigTST->getTemplateName().getAsTemplateDecl(),<br>
> +                         FromQual, ToQual, false /*FromDefault*/,<br>
> +                         false /*ToDefault*/);<br>
><br>
>      DiffTemplate(FromOrigTST, ToOrigTST);<br>
>    }<br>
><br>
> Modified: cfe/trunk/test/Misc/diag-template-diffing.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Misc/diag-template-diffing.cpp?rev=257831&r1=257830&r2=257831&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Misc/diag-template-diffing.cpp?rev=257831&r1=257830&r2=257831&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/test/Misc/diag-template-diffing.cpp (original)<br>
> +++ cfe/trunk/test/Misc/diag-template-diffing.cpp Thu Jan 14 16:56:39 2016<br>
> @@ -925,7 +925,7 @@ namespace DependentDefault {<br>
>      // CHECK-ELIDE-NOTREE: no known conversion from 'A<char, [...]>' to 'A<int, [...]>'<br>
>      a3 = a1;<br>
>      // CHECK-ELIDE-NOTREE: no viable overloaded '='<br>
> -    // CHECK-ELIDE-NOTREE: no known conversion from 'A<[...], (default) 40>' to 'A<[...], 10>'<br>
> +    // CHECK-ELIDE-NOTREE: no known conversion from 'A<[...], (default) Trait<T>::V aka 40>' to 'A<[...], 10>'<br>
>      a2 = a3;<br>
>      // CHECK-ELIDE-NOTREE: no viable overloaded '='<br>
>      // CHECK-ELIDE-NOTREE: no known conversion from 'A<int, 10>' to 'A<char, 40>'<br>
><br>
><br>
> _______________________________________________<br>
> cfe-commits mailing list<br>
> <a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><br>
</div></div></blockquote></div><br></div></div>