diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/AST')
-rw-r--r-- | contrib/llvm/tools/clang/lib/AST/ASTDiagnostic.cpp | 1367 |
1 files changed, 733 insertions, 634 deletions
diff --git a/contrib/llvm/tools/clang/lib/AST/ASTDiagnostic.cpp b/contrib/llvm/tools/clang/lib/AST/ASTDiagnostic.cpp index 0ab1fa7..2ab5a32 100644 --- a/contrib/llvm/tools/clang/lib/AST/ASTDiagnostic.cpp +++ b/contrib/llvm/tools/clang/lib/AST/ASTDiagnostic.cpp @@ -473,14 +473,14 @@ class TemplateDiff { /// ShowColor - Diagnostics support color, so bolding will be used. bool ShowColor; - /// FromType - When single type printing is selected, this is the type to be - /// be printed. When tree printing is selected, this type will show up first - /// in the tree. - QualType FromType; + /// FromTemplateType - When single type printing is selected, this is the + /// type to be be printed. When tree printing is selected, this type will + /// show up first in the tree. + QualType FromTemplateType; - /// ToType - The type that FromType is compared to. Only in tree printing - /// will this type be outputed. - QualType ToType; + /// ToTemplateType - The type that FromType is compared to. Only in tree + /// printing will this type be outputed. + QualType ToTemplateType; /// OS - The stream used to construct the output strings. raw_ostream &OS; @@ -491,82 +491,70 @@ class TemplateDiff { /// DiffTree - A tree representation the differences between two types. class DiffTree { public: - /// DiffKind - The difference in a DiffNode and which fields are used. + /// DiffKind - The difference in a DiffNode. Fields of + /// TemplateArgumentInfo needed by each difference can be found in the + /// Set* and Get* functions. enum DiffKind { /// Incomplete or invalid node. Invalid, - /// Another level of templates, uses TemplateDecl and Qualifiers + /// Another level of templates, requires that Template, - /// Type difference, uses QualType + /// Type difference, all type differences except those falling under + /// the Template difference. Type, - /// Expression difference, uses Expr + /// Expression difference, this is only when both arguments are + /// expressions. If one argument is an expression and the other is + /// Integer or Declaration, then use that diff type instead. Expression, - /// Template argument difference, uses TemplateDecl + /// Template argument difference TemplateTemplate, - /// Integer difference, uses APSInt and Expr + /// Integer difference Integer, - /// Declaration difference, uses ValueDecl - Declaration + /// Declaration difference, nullptr arguments are included here + Declaration, + /// One argument being integer and the other being declaration + FromIntegerAndToDeclaration, + FromDeclarationAndToInteger }; + private: + /// TemplateArgumentInfo - All the information needed to pretty print + /// a template argument. See the Set* and Get* functions to see which + /// fields are used for each DiffKind. + struct TemplateArgumentInfo { + QualType ArgType; + Qualifiers Qual; + llvm::APSInt Val; + bool IsValidInt = false; + Expr *ArgExpr = nullptr; + TemplateDecl *TD = nullptr; + ValueDecl *VD = nullptr; + bool NeedAddressOf = false; + bool IsNullPtr = false; + bool IsDefault = false; + }; + /// DiffNode - The root node stores the original type. Each child node /// stores template arguments of their parents. For templated types, the /// template decl is also stored. struct DiffNode { - DiffKind Kind; + DiffKind Kind = Invalid; /// NextNode - The index of the next sibling node or 0. - unsigned NextNode; + unsigned NextNode = 0; /// ChildNode - The index of the first child node or 0. - unsigned ChildNode; + unsigned ChildNode = 0; /// ParentNode - The index of the parent node. - unsigned ParentNode; - - /// FromType, ToType - The type arguments. - QualType FromType, ToType; - - /// FromExpr, ToExpr - The expression arguments. - Expr *FromExpr, *ToExpr; - - /// FromNullPtr, ToNullPtr - If the template argument is a nullptr - bool FromNullPtr, ToNullPtr; - - /// FromTD, ToTD - The template decl for template template - /// arguments or the type arguments that are templates. - TemplateDecl *FromTD, *ToTD; - - /// FromQual, ToQual - Qualifiers for template types. - Qualifiers FromQual, ToQual; + unsigned ParentNode = 0; - /// FromInt, ToInt - APSInt's for integral arguments. - llvm::APSInt FromInt, ToInt; - - /// IsValidFromInt, IsValidToInt - Whether the APSInt's are valid. - bool IsValidFromInt, IsValidToInt; - - /// FromValueDecl, ToValueDecl - Whether the argument is a decl. - ValueDecl *FromValueDecl, *ToValueDecl; - - /// FromAddressOf, ToAddressOf - Whether the ValueDecl needs an address of - /// operator before it. - bool FromAddressOf, ToAddressOf; - - /// FromDefault, ToDefault - Whether the argument is a default argument. - bool FromDefault, ToDefault; + TemplateArgumentInfo FromArgInfo, ToArgInfo; /// Same - Whether the two arguments evaluate to the same value. - bool Same; - - DiffNode(unsigned ParentNode = 0) - : Kind(Invalid), NextNode(0), ChildNode(0), ParentNode(ParentNode), - FromType(), ToType(), FromExpr(nullptr), ToExpr(nullptr), - FromNullPtr(false), ToNullPtr(false), - FromTD(nullptr), ToTD(nullptr), IsValidFromInt(false), - IsValidToInt(false), FromValueDecl(nullptr), ToValueDecl(nullptr), - FromAddressOf(false), ToAddressOf(false), FromDefault(false), - ToDefault(false), Same(false) {} + bool Same = false; + + DiffNode(unsigned ParentNode = 0) : ParentNode(ParentNode) {} }; /// FlatTree - A flattened tree used to store the DiffNodes. @@ -581,54 +569,127 @@ class TemplateDiff { /// ReadNode - The index of the current node being read. unsigned ReadNode; - + public: DiffTree() : CurrentNode(0), NextFreeNode(1) { FlatTree.push_back(DiffNode()); } - // Node writing functions. - /// SetNode - Sets FromTD and ToTD of the current node. - void SetNode(TemplateDecl *FromTD, TemplateDecl *ToTD) { - FlatTree[CurrentNode].FromTD = FromTD; - FlatTree[CurrentNode].ToTD = ToTD; + // Node writing functions, one for each valid DiffKind element. + void SetTemplateDiff(TemplateDecl *FromTD, TemplateDecl *ToTD, + Qualifiers FromQual, Qualifiers ToQual, + bool FromDefault, bool ToDefault) { + assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty."); + FlatTree[CurrentNode].Kind = Template; + FlatTree[CurrentNode].FromArgInfo.TD = FromTD; + FlatTree[CurrentNode].ToArgInfo.TD = ToTD; + FlatTree[CurrentNode].FromArgInfo.Qual = FromQual; + FlatTree[CurrentNode].ToArgInfo.Qual = ToQual; + SetDefault(FromDefault, ToDefault); + } + + void SetTypeDiff(QualType FromType, QualType ToType, bool FromDefault, + bool ToDefault) { + assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty."); + FlatTree[CurrentNode].Kind = Type; + FlatTree[CurrentNode].FromArgInfo.ArgType = FromType; + FlatTree[CurrentNode].ToArgInfo.ArgType = ToType; + SetDefault(FromDefault, ToDefault); + } + + void SetExpressionDiff(Expr *FromExpr, Expr *ToExpr, bool FromDefault, + bool ToDefault) { + assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty."); + FlatTree[CurrentNode].Kind = Expression; + FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr; + FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr; + SetDefault(FromDefault, ToDefault); + } + + void SetTemplateTemplateDiff(TemplateDecl *FromTD, TemplateDecl *ToTD, + bool FromDefault, bool ToDefault) { + assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty."); + FlatTree[CurrentNode].Kind = TemplateTemplate; + FlatTree[CurrentNode].FromArgInfo.TD = FromTD; + FlatTree[CurrentNode].ToArgInfo.TD = ToTD; + SetDefault(FromDefault, ToDefault); + } + + void SetIntegerDiff(llvm::APSInt FromInt, llvm::APSInt ToInt, + bool IsValidFromInt, bool IsValidToInt, + QualType FromIntType, QualType ToIntType, + Expr *FromExpr, Expr *ToExpr, bool FromDefault, + bool ToDefault) { + assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty."); + FlatTree[CurrentNode].Kind = Integer; + FlatTree[CurrentNode].FromArgInfo.Val = FromInt; + FlatTree[CurrentNode].ToArgInfo.Val = ToInt; + FlatTree[CurrentNode].FromArgInfo.IsValidInt = IsValidFromInt; + FlatTree[CurrentNode].ToArgInfo.IsValidInt = IsValidToInt; + FlatTree[CurrentNode].FromArgInfo.ArgType = FromIntType; + FlatTree[CurrentNode].ToArgInfo.ArgType = ToIntType; + FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr; + FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr; + SetDefault(FromDefault, ToDefault); + } + + void SetDeclarationDiff(ValueDecl *FromValueDecl, ValueDecl *ToValueDecl, + bool FromAddressOf, bool ToAddressOf, + bool FromNullPtr, bool ToNullPtr, Expr *FromExpr, + Expr *ToExpr, bool FromDefault, bool ToDefault) { + assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty."); + FlatTree[CurrentNode].Kind = Declaration; + FlatTree[CurrentNode].FromArgInfo.VD = FromValueDecl; + FlatTree[CurrentNode].ToArgInfo.VD = ToValueDecl; + FlatTree[CurrentNode].FromArgInfo.NeedAddressOf = FromAddressOf; + FlatTree[CurrentNode].ToArgInfo.NeedAddressOf = ToAddressOf; + FlatTree[CurrentNode].FromArgInfo.IsNullPtr = FromNullPtr; + FlatTree[CurrentNode].ToArgInfo.IsNullPtr = ToNullPtr; + FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr; + FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr; + SetDefault(FromDefault, ToDefault); + } + + void SetFromDeclarationAndToIntegerDiff( + ValueDecl *FromValueDecl, bool FromAddressOf, bool FromNullPtr, + Expr *FromExpr, llvm::APSInt ToInt, bool IsValidToInt, + QualType ToIntType, Expr *ToExpr, bool FromDefault, bool ToDefault) { + assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty."); + FlatTree[CurrentNode].Kind = FromDeclarationAndToInteger; + FlatTree[CurrentNode].FromArgInfo.VD = FromValueDecl; + FlatTree[CurrentNode].FromArgInfo.NeedAddressOf = FromAddressOf; + FlatTree[CurrentNode].FromArgInfo.IsNullPtr = FromNullPtr; + FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr; + FlatTree[CurrentNode].ToArgInfo.Val = ToInt; + FlatTree[CurrentNode].ToArgInfo.IsValidInt = IsValidToInt; + FlatTree[CurrentNode].ToArgInfo.ArgType = ToIntType; + FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr; + SetDefault(FromDefault, ToDefault); + } + + void SetFromIntegerAndToDeclarationDiff( + llvm::APSInt FromInt, bool IsValidFromInt, QualType FromIntType, + Expr *FromExpr, ValueDecl *ToValueDecl, bool ToAddressOf, + bool ToNullPtr, Expr *ToExpr, bool FromDefault, bool ToDefault) { + assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty."); + FlatTree[CurrentNode].Kind = FromIntegerAndToDeclaration; + FlatTree[CurrentNode].FromArgInfo.Val = FromInt; + FlatTree[CurrentNode].FromArgInfo.IsValidInt = IsValidFromInt; + FlatTree[CurrentNode].FromArgInfo.ArgType = FromIntType; + FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr; + FlatTree[CurrentNode].ToArgInfo.VD = ToValueDecl; + FlatTree[CurrentNode].ToArgInfo.NeedAddressOf = ToAddressOf; + FlatTree[CurrentNode].ToArgInfo.IsNullPtr = ToNullPtr; + FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr; + SetDefault(FromDefault, ToDefault); } - /// SetNode - Sets FromType and ToType of the current node. - void SetNode(QualType FromType, QualType ToType) { - FlatTree[CurrentNode].FromType = FromType; - FlatTree[CurrentNode].ToType = ToType; - } - - /// SetNode - Set FromExpr and ToExpr of the current node. - void SetNode(Expr *FromExpr, Expr *ToExpr) { - FlatTree[CurrentNode].FromExpr = FromExpr; - FlatTree[CurrentNode].ToExpr = ToExpr; - } - - /// SetNode - Set FromInt and ToInt of the current node. - void SetNode(llvm::APSInt FromInt, llvm::APSInt ToInt, - bool IsValidFromInt, bool IsValidToInt) { - FlatTree[CurrentNode].FromInt = FromInt; - FlatTree[CurrentNode].ToInt = ToInt; - FlatTree[CurrentNode].IsValidFromInt = IsValidFromInt; - FlatTree[CurrentNode].IsValidToInt = IsValidToInt; - } - - /// SetNode - Set FromQual and ToQual of the current node. - void SetNode(Qualifiers FromQual, Qualifiers ToQual) { - FlatTree[CurrentNode].FromQual = FromQual; - FlatTree[CurrentNode].ToQual = ToQual; - } - - /// SetNode - Set FromValueDecl and ToValueDecl of the current node. - void SetNode(ValueDecl *FromValueDecl, ValueDecl *ToValueDecl, - bool FromAddressOf, bool ToAddressOf) { - FlatTree[CurrentNode].FromValueDecl = FromValueDecl; - FlatTree[CurrentNode].ToValueDecl = ToValueDecl; - FlatTree[CurrentNode].FromAddressOf = FromAddressOf; - FlatTree[CurrentNode].ToAddressOf = ToAddressOf; + /// SetDefault - Sets FromDefault and ToDefault flags of the current node. + void SetDefault(bool FromDefault, bool ToDefault) { + assert((!FromDefault || !ToDefault) && "Both arguments cannot be default."); + FlatTree[CurrentNode].FromArgInfo.IsDefault = FromDefault; + FlatTree[CurrentNode].ToArgInfo.IsDefault = ToDefault; } /// SetSame - Sets the same flag of the current node. @@ -636,18 +697,6 @@ class TemplateDiff { FlatTree[CurrentNode].Same = Same; } - /// SetNullPtr - Sets the NullPtr flags of the current node. - void SetNullPtr(bool FromNullPtr, bool ToNullPtr) { - FlatTree[CurrentNode].FromNullPtr = FromNullPtr; - FlatTree[CurrentNode].ToNullPtr = ToNullPtr; - } - - /// SetDefault - Sets FromDefault and ToDefault flags of the current node. - void SetDefault(bool FromDefault, bool ToDefault) { - FlatTree[CurrentNode].FromDefault = FromDefault; - FlatTree[CurrentNode].ToDefault = ToDefault; - } - /// SetKind - Sets the current node's type. void SetKind(DiffKind Kind) { FlatTree[CurrentNode].Kind = Kind; @@ -655,12 +704,16 @@ class TemplateDiff { /// Up - Changes the node to the parent of the current node. void Up() { + assert(FlatTree[CurrentNode].Kind != Invalid && + "Cannot exit node before setting node information."); CurrentNode = FlatTree[CurrentNode].ParentNode; } /// AddNode - Adds a child node to the current node, then sets that node /// node as the current node. void AddNode() { + assert(FlatTree[CurrentNode].Kind == Template && + "Only Template nodes can have children nodes."); FlatTree.push_back(DiffNode(CurrentNode)); DiffNode &Node = FlatTree[CurrentNode]; if (Node.ChildNode == 0) { @@ -692,46 +745,103 @@ class TemplateDiff { ReadNode = FlatTree[ReadNode].ParentNode; } - /// GetNode - Gets the FromType and ToType. - void GetNode(QualType &FromType, QualType &ToType) { - FromType = FlatTree[ReadNode].FromType; - ToType = FlatTree[ReadNode].ToType; + void GetTemplateDiff(TemplateDecl *&FromTD, TemplateDecl *&ToTD, + Qualifiers &FromQual, Qualifiers &ToQual) { + assert(FlatTree[ReadNode].Kind == Template && "Unexpected kind."); + FromTD = FlatTree[ReadNode].FromArgInfo.TD; + ToTD = FlatTree[ReadNode].ToArgInfo.TD; + FromQual = FlatTree[ReadNode].FromArgInfo.Qual; + ToQual = FlatTree[ReadNode].ToArgInfo.Qual; + } + + void GetTypeDiff(QualType &FromType, QualType &ToType) { + assert(FlatTree[ReadNode].Kind == Type && "Unexpected kind"); + FromType = FlatTree[ReadNode].FromArgInfo.ArgType; + ToType = FlatTree[ReadNode].ToArgInfo.ArgType; + } + + void GetExpressionDiff(Expr *&FromExpr, Expr *&ToExpr) { + assert(FlatTree[ReadNode].Kind == Expression && "Unexpected kind"); + FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr; + ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr; + } + + void GetTemplateTemplateDiff(TemplateDecl *&FromTD, TemplateDecl *&ToTD) { + assert(FlatTree[ReadNode].Kind == TemplateTemplate && "Unexpected kind."); + FromTD = FlatTree[ReadNode].FromArgInfo.TD; + ToTD = FlatTree[ReadNode].ToArgInfo.TD; + } + + void GetIntegerDiff(llvm::APSInt &FromInt, llvm::APSInt &ToInt, + bool &IsValidFromInt, bool &IsValidToInt, + QualType &FromIntType, QualType &ToIntType, + Expr *&FromExpr, Expr *&ToExpr) { + assert(FlatTree[ReadNode].Kind == Integer && "Unexpected kind."); + FromInt = FlatTree[ReadNode].FromArgInfo.Val; + ToInt = FlatTree[ReadNode].ToArgInfo.Val; + IsValidFromInt = FlatTree[ReadNode].FromArgInfo.IsValidInt; + IsValidToInt = FlatTree[ReadNode].ToArgInfo.IsValidInt; + FromIntType = FlatTree[ReadNode].FromArgInfo.ArgType; + ToIntType = FlatTree[ReadNode].ToArgInfo.ArgType; + FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr; + ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr; + } + + void GetDeclarationDiff(ValueDecl *&FromValueDecl, ValueDecl *&ToValueDecl, + bool &FromAddressOf, bool &ToAddressOf, + bool &FromNullPtr, bool &ToNullPtr, Expr *&FromExpr, + Expr *&ToExpr) { + assert(FlatTree[ReadNode].Kind == Declaration && "Unexpected kind."); + FromValueDecl = FlatTree[ReadNode].FromArgInfo.VD; + ToValueDecl = FlatTree[ReadNode].ToArgInfo.VD; + FromAddressOf = FlatTree[ReadNode].FromArgInfo.NeedAddressOf; + ToAddressOf = FlatTree[ReadNode].ToArgInfo.NeedAddressOf; + FromNullPtr = FlatTree[ReadNode].FromArgInfo.IsNullPtr; + ToNullPtr = FlatTree[ReadNode].ToArgInfo.IsNullPtr; + FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr; + ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr; + } + + void GetFromDeclarationAndToIntegerDiff( + ValueDecl *&FromValueDecl, bool &FromAddressOf, bool &FromNullPtr, + Expr *&FromExpr, llvm::APSInt &ToInt, bool &IsValidToInt, + QualType &ToIntType, Expr *&ToExpr) { + assert(FlatTree[ReadNode].Kind == FromDeclarationAndToInteger && + "Unexpected kind."); + FromValueDecl = FlatTree[ReadNode].FromArgInfo.VD; + FromAddressOf = FlatTree[ReadNode].FromArgInfo.NeedAddressOf; + FromNullPtr = FlatTree[ReadNode].FromArgInfo.IsNullPtr; + FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr; + ToInt = FlatTree[ReadNode].ToArgInfo.Val; + IsValidToInt = FlatTree[ReadNode].ToArgInfo.IsValidInt; + ToIntType = FlatTree[ReadNode].ToArgInfo.ArgType; + ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr; + } + + void GetFromIntegerAndToDeclarationDiff( + llvm::APSInt &FromInt, bool &IsValidFromInt, QualType &FromIntType, + Expr *&FromExpr, ValueDecl *&ToValueDecl, bool &ToAddressOf, + bool &ToNullPtr, Expr *&ToExpr) { + assert(FlatTree[ReadNode].Kind == FromIntegerAndToDeclaration && + "Unexpected kind."); + FromInt = FlatTree[ReadNode].FromArgInfo.Val; + IsValidFromInt = FlatTree[ReadNode].FromArgInfo.IsValidInt; + FromIntType = FlatTree[ReadNode].FromArgInfo.ArgType; + FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr; + ToValueDecl = FlatTree[ReadNode].ToArgInfo.VD; + ToAddressOf = FlatTree[ReadNode].ToArgInfo.NeedAddressOf; + ToNullPtr = FlatTree[ReadNode].ToArgInfo.IsNullPtr; + ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr; } - /// GetNode - Gets the FromExpr and ToExpr. - void GetNode(Expr *&FromExpr, Expr *&ToExpr) { - FromExpr = FlatTree[ReadNode].FromExpr; - ToExpr = FlatTree[ReadNode].ToExpr; - } - - /// GetNode - Gets the FromTD and ToTD. - void GetNode(TemplateDecl *&FromTD, TemplateDecl *&ToTD) { - FromTD = FlatTree[ReadNode].FromTD; - ToTD = FlatTree[ReadNode].ToTD; - } - - /// GetNode - Gets the FromInt and ToInt. - void GetNode(llvm::APSInt &FromInt, llvm::APSInt &ToInt, - bool &IsValidFromInt, bool &IsValidToInt) { - FromInt = FlatTree[ReadNode].FromInt; - ToInt = FlatTree[ReadNode].ToInt; - IsValidFromInt = FlatTree[ReadNode].IsValidFromInt; - IsValidToInt = FlatTree[ReadNode].IsValidToInt; - } - - /// GetNode - Gets the FromQual and ToQual. - void GetNode(Qualifiers &FromQual, Qualifiers &ToQual) { - FromQual = FlatTree[ReadNode].FromQual; - ToQual = FlatTree[ReadNode].ToQual; + /// FromDefault - Return true if the from argument is the default. + bool FromDefault() { + return FlatTree[ReadNode].FromArgInfo.IsDefault; } - /// GetNode - Gets the FromValueDecl and ToValueDecl. - void GetNode(ValueDecl *&FromValueDecl, ValueDecl *&ToValueDecl, - bool &FromAddressOf, bool &ToAddressOf) { - FromValueDecl = FlatTree[ReadNode].FromValueDecl; - ToValueDecl = FlatTree[ReadNode].ToValueDecl; - FromAddressOf = FlatTree[ReadNode].FromAddressOf; - ToAddressOf = FlatTree[ReadNode].ToAddressOf; + /// ToDefault - Return true if the to argument is the default. + bool ToDefault() { + return FlatTree[ReadNode].ToArgInfo.IsDefault; } /// NodeIsSame - Returns true the arguments are the same. @@ -764,26 +874,6 @@ class TemplateDiff { return FlatTree[ReadNode].NextNode != 0; } - /// FromNullPtr - Returns true if the from argument is null. - bool FromNullPtr() { - return FlatTree[ReadNode].FromNullPtr; - } - - /// ToNullPtr - Returns true if the to argument is null. - bool ToNullPtr() { - return FlatTree[ReadNode].ToNullPtr; - } - - /// FromDefault - Return true if the from argument is the default. - bool FromDefault() { - return FlatTree[ReadNode].FromDefault; - } - - /// ToDefault - Return true if the to argument is the default. - bool ToDefault() { - return FlatTree[ReadNode].ToDefault; - } - /// Empty - Returns true if the tree has no information. bool Empty() { return GetKind() == Invalid; @@ -797,102 +887,128 @@ class TemplateDiff { DiffTree Tree; - /// TSTiterator - an iterator that is used to enter a - /// TemplateSpecializationType and read TemplateArguments inside template - /// parameter packs in order with the rest of the TemplateArguments. - struct TSTiterator { + /// TSTiterator - a pair of iterators that walks the + /// TemplateSpecializationType and the desugared TemplateSpecializationType. + /// The deseguared TemplateArgument should provide the canonical argument + /// for comparisons. + class TSTiterator { typedef const TemplateArgument& reference; typedef const TemplateArgument* pointer; - /// TST - the template specialization whose arguments this iterator - /// traverse over. - const TemplateSpecializationType *TST; + /// InternalIterator - an iterator that is used to enter a + /// TemplateSpecializationType and read TemplateArguments inside template + /// parameter packs in order with the rest of the TemplateArguments. + struct InternalIterator { + /// TST - the template specialization whose arguments this iterator + /// traverse over. + const TemplateSpecializationType *TST; - /// DesugarTST - desugared template specialization used to extract - /// default argument information - const TemplateSpecializationType *DesugarTST; + /// Index - the index of the template argument in TST. + unsigned Index; - /// Index - the index of the template argument in TST. - unsigned Index; + /// CurrentTA - if CurrentTA is not the same as EndTA, then CurrentTA + /// points to a TemplateArgument within a parameter pack. + TemplateArgument::pack_iterator CurrentTA; - /// CurrentTA - if CurrentTA is not the same as EndTA, then CurrentTA - /// points to a TemplateArgument within a parameter pack. - TemplateArgument::pack_iterator CurrentTA; + /// EndTA - the end iterator of a parameter pack + TemplateArgument::pack_iterator EndTA; - /// EndTA - the end iterator of a parameter pack - TemplateArgument::pack_iterator EndTA; + /// InternalIterator - Constructs an iterator and sets it to the first + /// template argument. + InternalIterator(const TemplateSpecializationType *TST) + : TST(TST), Index(0), CurrentTA(nullptr), EndTA(nullptr) { + if (isEnd()) return; - /// TSTiterator - Constructs an iterator and sets it to the first template - /// argument. - TSTiterator(ASTContext &Context, const TemplateSpecializationType *TST) - : TST(TST), - DesugarTST(GetTemplateSpecializationType(Context, TST->desugar())), - Index(0), CurrentTA(nullptr), EndTA(nullptr) { - if (isEnd()) return; + // Set to first template argument. If not a parameter pack, done. + TemplateArgument TA = TST->getArg(0); + if (TA.getKind() != TemplateArgument::Pack) return; - // Set to first template argument. If not a parameter pack, done. - TemplateArgument TA = TST->getArg(0); - if (TA.getKind() != TemplateArgument::Pack) return; + // Start looking into the parameter pack. + CurrentTA = TA.pack_begin(); + EndTA = TA.pack_end(); - // Start looking into the parameter pack. - CurrentTA = TA.pack_begin(); - EndTA = TA.pack_end(); + // Found a valid template argument. + if (CurrentTA != EndTA) return; - // Found a valid template argument. - if (CurrentTA != EndTA) return; + // Parameter pack is empty, use the increment to get to a valid + // template argument. + ++(*this); + } - // Parameter pack is empty, use the increment to get to a valid - // template argument. - ++(*this); - } + /// isEnd - Returns true if the iterator is one past the end. + bool isEnd() const { + return Index >= TST->getNumArgs(); + } - /// isEnd - Returns true if the iterator is one past the end. - bool isEnd() const { - return Index >= TST->getNumArgs(); - } + /// &operator++ - Increment the iterator to the next template argument. + InternalIterator &operator++() { + if (isEnd()) { + return *this; + } - /// &operator++ - Increment the iterator to the next template argument. - TSTiterator &operator++() { - // After the end, Index should be the default argument position in - // DesugarTST, if it exists. - if (isEnd()) { - ++Index; + // If in a parameter pack, advance in the parameter pack. + if (CurrentTA != EndTA) { + ++CurrentTA; + if (CurrentTA != EndTA) + return *this; + } + + // Loop until a template argument is found, or the end is reached. + while (true) { + // Advance to the next template argument. Break if reached the end. + if (++Index == TST->getNumArgs()) + break; + + // If the TemplateArgument is not a parameter pack, done. + TemplateArgument TA = TST->getArg(Index); + if (TA.getKind() != TemplateArgument::Pack) + break; + + // Handle parameter packs. + CurrentTA = TA.pack_begin(); + EndTA = TA.pack_end(); + + // If the parameter pack is empty, try to advance again. + if (CurrentTA != EndTA) + break; + } return *this; } - // If in a parameter pack, advance in the parameter pack. - if (CurrentTA != EndTA) { - ++CurrentTA; - if (CurrentTA != EndTA) - return *this; + /// operator* - Returns the appropriate TemplateArgument. + reference operator*() const { + assert(!isEnd() && "Index exceeds number of arguments."); + if (CurrentTA == EndTA) + return TST->getArg(Index); + else + return *CurrentTA; } - // Loop until a template argument is found, or the end is reached. - while (true) { - // Advance to the next template argument. Break if reached the end. - if (++Index == TST->getNumArgs()) break; + /// operator-> - Allow access to the underlying TemplateArgument. + pointer operator->() const { + return &operator*(); + } + }; - // If the TemplateArgument is not a parameter pack, done. - TemplateArgument TA = TST->getArg(Index); - if (TA.getKind() != TemplateArgument::Pack) break; + InternalIterator SugaredIterator; + InternalIterator DesugaredIterator; - // Handle parameter packs. - CurrentTA = TA.pack_begin(); - EndTA = TA.pack_end(); + public: + TSTiterator(ASTContext &Context, const TemplateSpecializationType *TST) + : SugaredIterator(TST), + DesugaredIterator( + GetTemplateSpecializationType(Context, TST->desugar())) {} - // If the parameter pack is empty, try to advance again. - if (CurrentTA != EndTA) break; - } + /// &operator++ - Increment the iterator to the next template argument. + TSTiterator &operator++() { + ++SugaredIterator; + ++DesugaredIterator; return *this; } /// operator* - Returns the appropriate TemplateArgument. reference operator*() const { - assert(!isEnd() && "Index exceeds number of arguments."); - if (CurrentTA == EndTA) - return TST->getArg(Index); - else - return *CurrentTA; + return *SugaredIterator; } /// operator-> - Allow access to the underlying TemplateArgument. @@ -900,16 +1016,27 @@ class TemplateDiff { return &operator*(); } - /// getDesugar - Returns the deduced template argument from DesguarTST - reference getDesugar() const { - return DesugarTST->getArg(Index); + /// isEnd - Returns true if no more TemplateArguments are available. + bool isEnd() const { + return SugaredIterator.isEnd(); + } + + /// hasDesugaredTA - Returns true if there is another TemplateArgument + /// available. + bool hasDesugaredTA() const { + return !DesugaredIterator.isEnd(); + } + + /// getDesugaredTA - Returns the desugared TemplateArgument. + reference getDesugaredTA() const { + return *DesugaredIterator; } }; // These functions build up the template diff tree, including functions to - // retrieve and compare template arguments. + // retrieve and compare template arguments. - static const TemplateSpecializationType * GetTemplateSpecializationType( + static const TemplateSpecializationType *GetTemplateSpecializationType( ASTContext &Context, QualType Ty) { if (const TemplateSpecializationType *TST = Ty->getAs<TemplateSpecializationType>()) @@ -935,108 +1062,136 @@ class TemplateDiff { return Ty->getAs<TemplateSpecializationType>(); } - /// DiffTypes - Fills a DiffNode with information about a type difference. - void DiffTypes(const TSTiterator &FromIter, const TSTiterator &ToIter, - TemplateTypeParmDecl *FromDefaultTypeDecl, - TemplateTypeParmDecl *ToDefaultTypeDecl) { - QualType FromType = GetType(FromIter, FromDefaultTypeDecl); - QualType ToType = GetType(ToIter, ToDefaultTypeDecl); - - Tree.SetNode(FromType, ToType); - Tree.SetDefault(FromIter.isEnd() && !FromType.isNull(), - ToIter.isEnd() && !ToType.isNull()); - Tree.SetKind(DiffTree::Type); + /// Returns true if the DiffType is Type and false for Template. + static bool OnlyPerformTypeDiff(ASTContext &Context, QualType FromType, + QualType ToType, + const TemplateSpecializationType *&FromArgTST, + const TemplateSpecializationType *&ToArgTST) { if (FromType.isNull() || ToType.isNull()) - return; + return true; - if (Context.hasSameType(FromType, ToType)) { - Tree.SetSame(true); - return; - } + if (Context.hasSameType(FromType, ToType)) + return true; - const TemplateSpecializationType *FromArgTST = - GetTemplateSpecializationType(Context, FromType); - if (!FromArgTST) - return; + FromArgTST = GetTemplateSpecializationType(Context, FromType); + ToArgTST = GetTemplateSpecializationType(Context, ToType); - const TemplateSpecializationType *ToArgTST = - GetTemplateSpecializationType(Context, ToType); - if (!ToArgTST) - return; + if (!FromArgTST || !ToArgTST) + return true; if (!hasSameTemplate(FromArgTST, ToArgTST)) - return; + return true; - Qualifiers FromQual = FromType.getQualifiers(), - ToQual = ToType.getQualifiers(); - FromQual -= QualType(FromArgTST, 0).getQualifiers(); - ToQual -= QualType(ToArgTST, 0).getQualifiers(); - Tree.SetNode(FromArgTST->getTemplateName().getAsTemplateDecl(), - ToArgTST->getTemplateName().getAsTemplateDecl()); - Tree.SetNode(FromQual, ToQual); - Tree.SetKind(DiffTree::Template); - DiffTemplate(FromArgTST, ToArgTST); + return false; + } + + /// DiffTypes - Fills a DiffNode with information about a type difference. + void DiffTypes(const TSTiterator &FromIter, const TSTiterator &ToIter) { + QualType FromType = GetType(FromIter); + QualType ToType = GetType(ToIter); + + bool FromDefault = FromIter.isEnd() && !FromType.isNull(); + bool ToDefault = ToIter.isEnd() && !ToType.isNull(); + + const TemplateSpecializationType *FromArgTST = nullptr; + const TemplateSpecializationType *ToArgTST = nullptr; + if (OnlyPerformTypeDiff(Context, FromType, ToType, FromArgTST, ToArgTST)) { + Tree.SetTypeDiff(FromType, ToType, FromDefault, ToDefault); + Tree.SetSame(!FromType.isNull() && !ToType.isNull() && + Context.hasSameType(FromType, ToType)); + } else { + assert(FromArgTST && ToArgTST && + "Both template specializations need to be valid."); + Qualifiers FromQual = FromType.getQualifiers(), + ToQual = ToType.getQualifiers(); + FromQual -= QualType(FromArgTST, 0).getQualifiers(); + ToQual -= QualType(ToArgTST, 0).getQualifiers(); + Tree.SetTemplateDiff(FromArgTST->getTemplateName().getAsTemplateDecl(), + ToArgTST->getTemplateName().getAsTemplateDecl(), + FromQual, ToQual, FromDefault, ToDefault); + DiffTemplate(FromArgTST, ToArgTST); + } } /// DiffTemplateTemplates - Fills a DiffNode with information about a /// template template difference. void DiffTemplateTemplates(const TSTiterator &FromIter, - const TSTiterator &ToIter, - TemplateTemplateParmDecl *FromDefaultTemplateDecl, - TemplateTemplateParmDecl *ToDefaultTemplateDecl) { - TemplateDecl *FromDecl = GetTemplateDecl(FromIter, FromDefaultTemplateDecl); - TemplateDecl *ToDecl = GetTemplateDecl(ToIter, ToDefaultTemplateDecl); - Tree.SetNode(FromDecl, ToDecl); + const TSTiterator &ToIter) { + TemplateDecl *FromDecl = GetTemplateDecl(FromIter); + TemplateDecl *ToDecl = GetTemplateDecl(ToIter); + Tree.SetTemplateTemplateDiff(FromDecl, ToDecl, FromIter.isEnd() && FromDecl, + ToIter.isEnd() && ToDecl); Tree.SetSame(FromDecl && ToDecl && FromDecl->getCanonicalDecl() == ToDecl->getCanonicalDecl()); - Tree.SetDefault(FromIter.isEnd() && FromDecl, ToIter.isEnd() && ToDecl); - Tree.SetKind(DiffTree::TemplateTemplate); } /// InitializeNonTypeDiffVariables - Helper function for DiffNonTypes - static void InitializeNonTypeDiffVariables( - ASTContext &Context, const TSTiterator &Iter, - NonTypeTemplateParmDecl *Default, bool &HasInt, bool &HasValueDecl, - bool &IsNullPtr, Expr *&E, llvm::APSInt &Value, ValueDecl *&VD) { - HasInt = !Iter.isEnd() && Iter->getKind() == TemplateArgument::Integral; - - HasValueDecl = - !Iter.isEnd() && Iter->getKind() == TemplateArgument::Declaration; - - IsNullPtr = !Iter.isEnd() && Iter->getKind() == TemplateArgument::NullPtr; - - if (HasInt) - Value = Iter->getAsIntegral(); - else if (HasValueDecl) - VD = Iter->getAsDecl(); - else if (!IsNullPtr) - E = GetExpr(Iter, Default); - - if (E && Default->getType()->isPointerType()) - IsNullPtr = CheckForNullPtr(Context, E); - } - - /// NeedsAddressOf - Helper function for DiffNonTypes. Returns true if the - /// ValueDecl needs a '&' when printed. - static bool NeedsAddressOf(ValueDecl *VD, Expr *E, - NonTypeTemplateParmDecl *Default) { - if (!VD) - return false; - - if (E) { - if (UnaryOperator *UO = dyn_cast<UnaryOperator>(E->IgnoreParens())) { - if (UO->getOpcode() == UO_AddrOf) { - return true; + static void InitializeNonTypeDiffVariables(ASTContext &Context, + const TSTiterator &Iter, + NonTypeTemplateParmDecl *Default, + llvm::APSInt &Value, bool &HasInt, + QualType &IntType, bool &IsNullPtr, + Expr *&E, ValueDecl *&VD, + bool &NeedAddressOf) { + if (!Iter.isEnd()) { + switch (Iter->getKind()) { + default: + llvm_unreachable("unknown ArgumentKind"); + case TemplateArgument::Integral: + Value = Iter->getAsIntegral(); + HasInt = true; + IntType = Iter->getIntegralType(); + return; + case TemplateArgument::Declaration: { + VD = Iter->getAsDecl(); + QualType ArgType = Iter->getParamTypeForDecl(); + QualType VDType = VD->getType(); + if (ArgType->isPointerType() && + Context.hasSameType(ArgType->getPointeeType(), VDType)) + NeedAddressOf = true; + return; } + case TemplateArgument::NullPtr: + IsNullPtr = true; + return; + case TemplateArgument::Expression: + E = Iter->getAsExpr(); } - return false; + } else if (!Default->isParameterPack()) { + E = Default->getDefaultArgument(); } - if (!Default->getType()->isReferenceType()) { - return true; - } + if (!Iter.hasDesugaredTA()) return; - return false; + const TemplateArgument& TA = Iter.getDesugaredTA(); + switch (TA.getKind()) { + default: + llvm_unreachable("unknown ArgumentKind"); + case TemplateArgument::Integral: + Value = TA.getAsIntegral(); + HasInt = true; + IntType = TA.getIntegralType(); + return; + case TemplateArgument::Declaration: { + VD = TA.getAsDecl(); + QualType ArgType = TA.getParamTypeForDecl(); + QualType VDType = VD->getType(); + if (ArgType->isPointerType() && + Context.hasSameType(ArgType->getPointeeType(), VDType)) + NeedAddressOf = true; + return; + } + case TemplateArgument::NullPtr: + IsNullPtr = true; + return; + case TemplateArgument::Expression: + // TODO: Sometimes, the desugared template argument Expr differs from + // the sugared template argument Expr. It may be useful in the future + // but for now, it is just discarded. + if (!E) + E = TA.getAsExpr(); + return; + } } /// DiffNonTypes - Handles any template parameters not handled by DiffTypes @@ -1046,85 +1201,68 @@ class TemplateDiff { NonTypeTemplateParmDecl *ToDefaultNonTypeDecl) { Expr *FromExpr = nullptr, *ToExpr = nullptr; llvm::APSInt FromInt, ToInt; + QualType FromIntType, ToIntType; ValueDecl *FromValueDecl = nullptr, *ToValueDecl = nullptr; - bool HasFromInt = false, HasToInt = false, HasFromValueDecl = false, - HasToValueDecl = false, FromNullPtr = false, ToNullPtr = false; - InitializeNonTypeDiffVariables(Context, FromIter, FromDefaultNonTypeDecl, - HasFromInt, HasFromValueDecl, FromNullPtr, - FromExpr, FromInt, FromValueDecl); - InitializeNonTypeDiffVariables(Context, ToIter, ToDefaultNonTypeDecl, - HasToInt, HasToValueDecl, ToNullPtr, - ToExpr, ToInt, ToValueDecl); - - assert(((!HasFromInt && !HasToInt) || - (!HasFromValueDecl && !HasToValueDecl)) && - "Template argument cannot be both integer and declaration"); - - if (!HasFromInt && !HasToInt && !HasFromValueDecl && !HasToValueDecl) { - Tree.SetNode(FromExpr, ToExpr); - Tree.SetDefault(FromIter.isEnd() && FromExpr, ToIter.isEnd() && ToExpr); - if (FromDefaultNonTypeDecl->getType()->isIntegralOrEnumerationType()) { - if (FromExpr) - HasFromInt = GetInt(Context, FromIter, FromExpr, FromInt, - FromDefaultNonTypeDecl->getType()); - if (ToExpr) - HasToInt = GetInt(Context, ToIter, ToExpr, ToInt, - ToDefaultNonTypeDecl->getType()); - } - if (HasFromInt && HasToInt) { - Tree.SetNode(FromInt, ToInt, HasFromInt, HasToInt); - Tree.SetSame(FromInt == ToInt); - Tree.SetKind(DiffTree::Integer); - } else if (HasFromInt || HasToInt) { - Tree.SetNode(FromInt, ToInt, HasFromInt, HasToInt); - Tree.SetSame(false); - Tree.SetKind(DiffTree::Integer); - } else { - Tree.SetSame(IsEqualExpr(Context, FromExpr, ToExpr) || - (FromNullPtr && ToNullPtr)); - Tree.SetNullPtr(FromNullPtr, ToNullPtr); - Tree.SetKind(DiffTree::Expression); - } + bool HasFromInt = false, HasToInt = false, FromNullPtr = false, + ToNullPtr = false, NeedFromAddressOf = false, NeedToAddressOf = false; + InitializeNonTypeDiffVariables( + Context, FromIter, FromDefaultNonTypeDecl, FromInt, HasFromInt, + FromIntType, FromNullPtr, FromExpr, FromValueDecl, NeedFromAddressOf); + InitializeNonTypeDiffVariables(Context, ToIter, ToDefaultNonTypeDecl, ToInt, + HasToInt, ToIntType, ToNullPtr, ToExpr, + ToValueDecl, NeedToAddressOf); + + bool FromDefault = FromIter.isEnd() && + (FromExpr || FromValueDecl || HasFromInt || FromNullPtr); + bool ToDefault = ToIter.isEnd() && + (ToExpr || ToValueDecl || HasToInt || ToNullPtr); + + bool FromDeclaration = FromValueDecl || FromNullPtr; + bool ToDeclaration = ToValueDecl || ToNullPtr; + + if (FromDeclaration && HasToInt) { + Tree.SetFromDeclarationAndToIntegerDiff( + FromValueDecl, NeedFromAddressOf, FromNullPtr, FromExpr, ToInt, + HasToInt, ToIntType, ToExpr, FromDefault, ToDefault); + Tree.SetSame(false); + return; + + } + + if (HasFromInt && ToDeclaration) { + Tree.SetFromIntegerAndToDeclarationDiff( + FromInt, HasFromInt, FromIntType, FromExpr, ToValueDecl, + NeedToAddressOf, ToNullPtr, ToExpr, FromDefault, ToDefault); + Tree.SetSame(false); return; } if (HasFromInt || HasToInt) { - if (!HasFromInt && FromExpr) - HasFromInt = GetInt(Context, FromIter, FromExpr, FromInt, - FromDefaultNonTypeDecl->getType()); - if (!HasToInt && ToExpr) - HasToInt = GetInt(Context, ToIter, ToExpr, ToInt, - ToDefaultNonTypeDecl->getType()); - Tree.SetNode(FromInt, ToInt, HasFromInt, HasToInt); + Tree.SetIntegerDiff(FromInt, ToInt, HasFromInt, HasToInt, FromIntType, + ToIntType, FromExpr, ToExpr, FromDefault, ToDefault); if (HasFromInt && HasToInt) { - Tree.SetSame(FromInt == ToInt); - } else { - Tree.SetSame(false); + Tree.SetSame(Context.hasSameType(FromIntType, ToIntType) && + FromInt == ToInt); } - Tree.SetDefault(FromIter.isEnd() && HasFromInt, - ToIter.isEnd() && HasToInt); - Tree.SetKind(DiffTree::Integer); return; } - if (!HasFromValueDecl && FromExpr) - FromValueDecl = GetValueDecl(FromIter, FromExpr); - if (!HasToValueDecl && ToExpr) - ToValueDecl = GetValueDecl(ToIter, ToExpr); - - bool FromAddressOf = - NeedsAddressOf(FromValueDecl, FromExpr, FromDefaultNonTypeDecl); - bool ToAddressOf = - NeedsAddressOf(ToValueDecl, ToExpr, ToDefaultNonTypeDecl); - - Tree.SetNullPtr(FromNullPtr, ToNullPtr); - Tree.SetNode(FromValueDecl, ToValueDecl, FromAddressOf, ToAddressOf); - Tree.SetSame(FromValueDecl && ToValueDecl && - FromValueDecl->getCanonicalDecl() == - ToValueDecl->getCanonicalDecl()); - Tree.SetDefault(FromIter.isEnd() && FromValueDecl, - ToIter.isEnd() && ToValueDecl); - Tree.SetKind(DiffTree::Declaration); + if (FromDeclaration || ToDeclaration) { + Tree.SetDeclarationDiff(FromValueDecl, ToValueDecl, NeedFromAddressOf, + NeedToAddressOf, FromNullPtr, ToNullPtr, FromExpr, + ToExpr, FromDefault, ToDefault); + bool BothNull = FromNullPtr && ToNullPtr; + bool SameValueDecl = + FromValueDecl && ToValueDecl && + NeedFromAddressOf == NeedToAddressOf && + FromValueDecl->getCanonicalDecl() == ToValueDecl->getCanonicalDecl(); + Tree.SetSame(BothNull || SameValueDecl); + return; + } + + assert((FromExpr || ToExpr) && "Both template arguments cannot be empty."); + Tree.SetExpressionDiff(FromExpr, ToExpr, FromDefault, ToDefault); + Tree.SetSame(IsEqualExpr(Context, FromExpr, ToExpr)); } /// DiffTemplate - recursively visits template arguments and stores the @@ -1149,28 +1287,23 @@ class TemplateDiff { NamedDecl *FromParamND = ParamsFrom->getParam(FromParamIndex); NamedDecl *ToParamND = ParamsTo->getParam(ToParamIndex); - TemplateTypeParmDecl *FromDefaultTypeDecl = - dyn_cast<TemplateTypeParmDecl>(FromParamND); - TemplateTypeParmDecl *ToDefaultTypeDecl = - dyn_cast<TemplateTypeParmDecl>(ToParamND); - if (FromDefaultTypeDecl && ToDefaultTypeDecl) - DiffTypes(FromIter, ToIter, FromDefaultTypeDecl, ToDefaultTypeDecl); - - TemplateTemplateParmDecl *FromDefaultTemplateDecl = - dyn_cast<TemplateTemplateParmDecl>(FromParamND); - TemplateTemplateParmDecl *ToDefaultTemplateDecl = - dyn_cast<TemplateTemplateParmDecl>(ToParamND); - if (FromDefaultTemplateDecl && ToDefaultTemplateDecl) - DiffTemplateTemplates(FromIter, ToIter, FromDefaultTemplateDecl, - ToDefaultTemplateDecl); - - NonTypeTemplateParmDecl *FromDefaultNonTypeDecl = - dyn_cast<NonTypeTemplateParmDecl>(FromParamND); - NonTypeTemplateParmDecl *ToDefaultNonTypeDecl = - dyn_cast<NonTypeTemplateParmDecl>(ToParamND); - if (FromDefaultNonTypeDecl && ToDefaultNonTypeDecl) + assert(FromParamND->getKind() == ToParamND->getKind() && + "Parameter Decl are not the same kind."); + + if (isa<TemplateTypeParmDecl>(FromParamND)) { + DiffTypes(FromIter, ToIter); + } else if (isa<TemplateTemplateParmDecl>(FromParamND)) { + DiffTemplateTemplates(FromIter, ToIter); + } else if (isa<NonTypeTemplateParmDecl>(FromParamND)) { + NonTypeTemplateParmDecl *FromDefaultNonTypeDecl = + cast<NonTypeTemplateParmDecl>(FromParamND); + NonTypeTemplateParmDecl *ToDefaultNonTypeDecl = + cast<NonTypeTemplateParmDecl>(ToParamND); DiffNonTypes(FromIter, ToIter, FromDefaultNonTypeDecl, ToDefaultNonTypeDecl); + } else { + llvm_unreachable("Unexpected Decl type."); + } ++FromIter; ++ToIter; @@ -1239,140 +1372,27 @@ class TemplateDiff { /// GetType - Retrieves the template type arguments, including default /// arguments. - static QualType GetType(const TSTiterator &Iter, - TemplateTypeParmDecl *DefaultTTPD) { - bool isVariadic = DefaultTTPD->isParameterPack(); - + static QualType GetType(const TSTiterator &Iter) { if (!Iter.isEnd()) return Iter->getAsType(); - if (isVariadic) - return QualType(); - - QualType ArgType = DefaultTTPD->getDefaultArgument(); - if (ArgType->isDependentType()) - return Iter.getDesugar().getAsType(); - - return ArgType; - } - - /// GetExpr - Retrieves the template expression argument, including default - /// arguments. - static Expr *GetExpr(const TSTiterator &Iter, - NonTypeTemplateParmDecl *DefaultNTTPD) { - Expr *ArgExpr = nullptr; - bool isVariadic = DefaultNTTPD->isParameterPack(); - - if (!Iter.isEnd()) - ArgExpr = Iter->getAsExpr(); - else if (!isVariadic) - ArgExpr = DefaultNTTPD->getDefaultArgument(); - - if (ArgExpr) - while (SubstNonTypeTemplateParmExpr *SNTTPE = - dyn_cast<SubstNonTypeTemplateParmExpr>(ArgExpr)) - ArgExpr = SNTTPE->getReplacement(); - - return ArgExpr; - } - - /// GetInt - Retrieves the template integer argument, including evaluating - /// default arguments. If the value comes from an expression, extend the - /// APSInt to size of IntegerType to match the behavior in - /// Sema::CheckTemplateArgument - static bool GetInt(ASTContext &Context, const TSTiterator &Iter, - Expr *ArgExpr, llvm::APSInt &Int, QualType IntegerType) { - // Default, value-depenedent expressions require fetching - // from the desugared TemplateArgument, otherwise expression needs to - // be evaluatable. - if (Iter.isEnd() && ArgExpr->isValueDependent()) { - switch (Iter.getDesugar().getKind()) { - case TemplateArgument::Integral: - Int = Iter.getDesugar().getAsIntegral(); - return true; - case TemplateArgument::Expression: - ArgExpr = Iter.getDesugar().getAsExpr(); - Int = ArgExpr->EvaluateKnownConstInt(Context); - Int = Int.extOrTrunc(Context.getTypeSize(IntegerType)); - return true; - default: - llvm_unreachable("Unexpected template argument kind"); - } - } else if (ArgExpr->isEvaluatable(Context)) { - Int = ArgExpr->EvaluateKnownConstInt(Context); - Int = Int.extOrTrunc(Context.getTypeSize(IntegerType)); - return true; - } - - return false; - } - - /// GetValueDecl - Retrieves the template Decl argument, including - /// default expression argument. - static ValueDecl *GetValueDecl(const TSTiterator &Iter, Expr *ArgExpr) { - // Default, value-depenedent expressions require fetching - // from the desugared TemplateArgument - if (Iter.isEnd() && ArgExpr->isValueDependent()) - switch (Iter.getDesugar().getKind()) { - case TemplateArgument::Declaration: - return Iter.getDesugar().getAsDecl(); - case TemplateArgument::Expression: - ArgExpr = Iter.getDesugar().getAsExpr(); - return cast<DeclRefExpr>(ArgExpr)->getDecl(); - default: - llvm_unreachable("Unexpected template argument kind"); - } - DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(ArgExpr); - if (!DRE) { - UnaryOperator *UO = dyn_cast<UnaryOperator>(ArgExpr->IgnoreParens()); - if (!UO) - return nullptr; - DRE = cast<DeclRefExpr>(UO->getSubExpr()); - } - - return DRE->getDecl(); - } - - /// CheckForNullPtr - returns true if the expression can be evaluated as - /// a null pointer - static bool CheckForNullPtr(ASTContext &Context, Expr *E) { - assert(E && "Expected expression"); - - E = E->IgnoreParenCasts(); - if (E->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) - return true; - - DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E); - if (!DRE) - return false; - - VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl()); - if (!VD || !VD->hasInit()) - return false; - - return VD->getInit()->IgnoreParenCasts()->isNullPointerConstant( - Context, Expr::NPC_ValueDependentIsNull); + if (Iter.hasDesugaredTA()) + return Iter.getDesugaredTA().getAsType(); + return QualType(); } /// GetTemplateDecl - Retrieves the template template arguments, including /// default arguments. - static TemplateDecl *GetTemplateDecl(const TSTiterator &Iter, - TemplateTemplateParmDecl *DefaultTTPD) { - bool isVariadic = DefaultTTPD->isParameterPack(); - - TemplateArgument TA = DefaultTTPD->getDefaultArgument().getArgument(); - TemplateDecl *DefaultTD = nullptr; - if (TA.getKind() != TemplateArgument::Null) - DefaultTD = TA.getAsTemplate().getAsTemplateDecl(); - + static TemplateDecl *GetTemplateDecl(const TSTiterator &Iter) { if (!Iter.isEnd()) return Iter->getAsTemplate().getAsTemplateDecl(); - if (!isVariadic) - return DefaultTD; - + if (Iter.hasDesugaredTA()) + return Iter.getDesugaredTA().getAsTemplate().getAsTemplateDecl(); return nullptr; } - /// IsEqualExpr - Returns true if the expressions evaluate to the same value. + /// IsEqualExpr - Returns true if the expressions are the same in regards to + /// template arguments. These expressions are dependent, so profile them + /// instead of trying to evaluate them. static bool IsEqualExpr(ASTContext &Context, Expr *FromExpr, Expr *ToExpr) { if (FromExpr == ToExpr) return true; @@ -1380,47 +1400,10 @@ class TemplateDiff { if (!FromExpr || !ToExpr) return false; - DeclRefExpr *FromDRE = dyn_cast<DeclRefExpr>(FromExpr->IgnoreParens()), - *ToDRE = dyn_cast<DeclRefExpr>(ToExpr->IgnoreParens()); - - if (FromDRE || ToDRE) { - if (!FromDRE || !ToDRE) - return false; - return FromDRE->getDecl() == ToDRE->getDecl(); - } - - Expr::EvalResult FromResult, ToResult; - if (!FromExpr->EvaluateAsRValue(FromResult, Context) || - !ToExpr->EvaluateAsRValue(ToResult, Context)) { - llvm::FoldingSetNodeID FromID, ToID; - FromExpr->Profile(FromID, Context, true); - ToExpr->Profile(ToID, Context, true); - return FromID == ToID; - } - - APValue &FromVal = FromResult.Val; - APValue &ToVal = ToResult.Val; - - if (FromVal.getKind() != ToVal.getKind()) return false; - - switch (FromVal.getKind()) { - case APValue::Int: - return FromVal.getInt() == ToVal.getInt(); - case APValue::LValue: { - APValue::LValueBase FromBase = FromVal.getLValueBase(); - APValue::LValueBase ToBase = ToVal.getLValueBase(); - if (FromBase.isNull() && ToBase.isNull()) - return true; - if (FromBase.isNull() || ToBase.isNull()) - return false; - return FromBase.get<const ValueDecl*>() == - ToBase.get<const ValueDecl*>(); - } - case APValue::MemberPointer: - return FromVal.getMemberPointerDecl() == ToVal.getMemberPointerDecl(); - default: - llvm_unreachable("Unknown template argument expression."); - } + llvm::FoldingSetNodeID FromID, ToID; + FromExpr->Profile(FromID, Context, true); + ToExpr->Profile(ToID, Context, true); + return FromID == ToID; } // These functions converts the tree representation of the template @@ -1442,21 +1425,21 @@ class TemplateDiff { llvm_unreachable("Template diffing failed with bad DiffNode"); case DiffTree::Type: { QualType FromType, ToType; - Tree.GetNode(FromType, ToType); + Tree.GetTypeDiff(FromType, ToType); PrintTypeNames(FromType, ToType, Tree.FromDefault(), Tree.ToDefault(), Tree.NodeIsSame()); return; } case DiffTree::Expression: { Expr *FromExpr, *ToExpr; - Tree.GetNode(FromExpr, ToExpr); - PrintExpr(FromExpr, ToExpr, Tree.FromNullPtr(), Tree.ToNullPtr(), - Tree.FromDefault(), Tree.ToDefault(), Tree.NodeIsSame()); + Tree.GetExpressionDiff(FromExpr, ToExpr); + PrintExpr(FromExpr, ToExpr, Tree.FromDefault(), Tree.ToDefault(), + Tree.NodeIsSame()); return; } case DiffTree::TemplateTemplate: { TemplateDecl *FromTD, *ToTD; - Tree.GetNode(FromTD, ToTD); + Tree.GetTemplateTemplateDiff(FromTD, ToTD); PrintTemplateTemplate(FromTD, ToTD, Tree.FromDefault(), Tree.ToDefault(), Tree.NodeIsSame()); return; @@ -1465,26 +1448,70 @@ class TemplateDiff { llvm::APSInt FromInt, ToInt; Expr *FromExpr, *ToExpr; bool IsValidFromInt, IsValidToInt; - Tree.GetNode(FromExpr, ToExpr); - Tree.GetNode(FromInt, ToInt, IsValidFromInt, IsValidToInt); - PrintAPSInt(FromInt, ToInt, IsValidFromInt, IsValidToInt, - FromExpr, ToExpr, Tree.FromDefault(), Tree.ToDefault(), - Tree.NodeIsSame()); + QualType FromIntType, ToIntType; + Tree.GetIntegerDiff(FromInt, ToInt, IsValidFromInt, IsValidToInt, + FromIntType, ToIntType, FromExpr, ToExpr); + PrintAPSInt(FromInt, ToInt, IsValidFromInt, IsValidToInt, FromIntType, + ToIntType, FromExpr, ToExpr, Tree.FromDefault(), + Tree.ToDefault(), Tree.NodeIsSame()); return; } case DiffTree::Declaration: { ValueDecl *FromValueDecl, *ToValueDecl; bool FromAddressOf, ToAddressOf; - Tree.GetNode(FromValueDecl, ToValueDecl, FromAddressOf, ToAddressOf); + bool FromNullPtr, ToNullPtr; + Expr *FromExpr, *ToExpr; + Tree.GetDeclarationDiff(FromValueDecl, ToValueDecl, FromAddressOf, + ToAddressOf, FromNullPtr, ToNullPtr, FromExpr, + ToExpr); PrintValueDecl(FromValueDecl, ToValueDecl, FromAddressOf, ToAddressOf, - Tree.FromNullPtr(), Tree.ToNullPtr(), Tree.FromDefault(), - Tree.ToDefault(), Tree.NodeIsSame()); + FromNullPtr, ToNullPtr, FromExpr, ToExpr, + Tree.FromDefault(), Tree.ToDefault(), Tree.NodeIsSame()); + return; + } + case DiffTree::FromDeclarationAndToInteger: { + ValueDecl *FromValueDecl; + bool FromAddressOf; + bool FromNullPtr; + Expr *FromExpr; + llvm::APSInt ToInt; + bool IsValidToInt; + QualType ToIntType; + Expr *ToExpr; + Tree.GetFromDeclarationAndToIntegerDiff( + FromValueDecl, FromAddressOf, FromNullPtr, FromExpr, ToInt, + IsValidToInt, ToIntType, ToExpr); + assert((FromValueDecl || FromNullPtr) && IsValidToInt); + PrintValueDeclAndInteger(FromValueDecl, FromAddressOf, FromNullPtr, + FromExpr, Tree.FromDefault(), ToInt, ToIntType, + ToExpr, Tree.ToDefault()); + return; + } + case DiffTree::FromIntegerAndToDeclaration: { + llvm::APSInt FromInt; + bool IsValidFromInt; + QualType FromIntType; + Expr *FromExpr; + ValueDecl *ToValueDecl; + bool ToAddressOf; + bool ToNullPtr; + Expr *ToExpr; + Tree.GetFromIntegerAndToDeclarationDiff( + FromInt, IsValidFromInt, FromIntType, FromExpr, ToValueDecl, + ToAddressOf, ToNullPtr, ToExpr); + assert(IsValidFromInt && (ToValueDecl || ToNullPtr)); + PrintIntegerAndValueDecl(FromInt, FromIntType, FromExpr, + Tree.FromDefault(), ToValueDecl, ToAddressOf, + ToNullPtr, ToExpr, Tree.ToDefault()); return; } case DiffTree::Template: { // Node is root of template. Recurse on children. TemplateDecl *FromTD, *ToTD; - Tree.GetNode(FromTD, ToTD); + Qualifiers FromQual, ToQual; + Tree.GetTemplateDiff(FromTD, ToTD, FromQual, ToQual); + + PrintQualifiers(FromQual, ToQual); if (!Tree.HasChildren()) { // If we're dealing with a template specialization with zero @@ -1493,11 +1520,7 @@ class TemplateDiff { return; } - Qualifiers FromQual, ToQual; - Tree.GetNode(FromQual, ToQual); - PrintQualifiers(FromQual, ToQual); - - OS << FromTD->getNameAsString() << '<'; + OS << FromTD->getNameAsString() << '<'; Tree.MoveToChild(); unsigned NumElideArgs = 0; do { @@ -1604,40 +1627,36 @@ class TemplateDiff { /// PrintExpr - Prints out the expr template arguments, highlighting argument /// differences. - void PrintExpr(const Expr *FromExpr, const Expr *ToExpr, bool FromNullPtr, - bool ToNullPtr, bool FromDefault, bool ToDefault, bool Same) { + void PrintExpr(const Expr *FromExpr, const Expr *ToExpr, bool FromDefault, + bool ToDefault, bool Same) { assert((FromExpr || ToExpr) && "Only one template argument may be missing."); if (Same) { - PrintExpr(FromExpr, FromNullPtr); + PrintExpr(FromExpr); } else if (!PrintTree) { OS << (FromDefault ? "(default) " : ""); Bold(); - PrintExpr(FromExpr, FromNullPtr); + PrintExpr(FromExpr); Unbold(); } else { OS << (FromDefault ? "[(default) " : "["); Bold(); - PrintExpr(FromExpr, FromNullPtr); + PrintExpr(FromExpr); Unbold(); OS << " != " << (ToDefault ? "(default) " : ""); Bold(); - PrintExpr(ToExpr, ToNullPtr); + PrintExpr(ToExpr); Unbold(); OS << ']'; } } /// PrintExpr - Actual formatting and printing of expressions. - void PrintExpr(const Expr *E, bool NullPtr = false) { + void PrintExpr(const Expr *E) { if (E) { E->printPretty(OS, nullptr, Policy); return; } - if (NullPtr) { - OS << "nullptr"; - return; - } OS << "(no argument)"; } @@ -1677,28 +1696,40 @@ class TemplateDiff { /// PrintAPSInt - Handles printing of integral arguments, highlighting /// argument differences. void PrintAPSInt(llvm::APSInt FromInt, llvm::APSInt ToInt, - bool IsValidFromInt, bool IsValidToInt, Expr *FromExpr, - Expr *ToExpr, bool FromDefault, bool ToDefault, bool Same) { + bool IsValidFromInt, bool IsValidToInt, QualType FromIntType, + QualType ToIntType, Expr *FromExpr, Expr *ToExpr, + bool FromDefault, bool ToDefault, bool Same) { assert((IsValidFromInt || IsValidToInt) && "Only one integral argument may be missing."); if (Same) { - OS << FromInt.toString(10); - } else if (!PrintTree) { + if (FromIntType->isBooleanType()) { + OS << ((FromInt == 0) ? "false" : "true"); + } else { + OS << FromInt.toString(10); + } + return; + } + + bool PrintType = IsValidFromInt && IsValidToInt && + !Context.hasSameType(FromIntType, ToIntType); + + if (!PrintTree) { OS << (FromDefault ? "(default) " : ""); - PrintAPSInt(FromInt, FromExpr, IsValidFromInt); + PrintAPSInt(FromInt, FromExpr, IsValidFromInt, FromIntType, PrintType); } else { OS << (FromDefault ? "[(default) " : "["); - PrintAPSInt(FromInt, FromExpr, IsValidFromInt); + PrintAPSInt(FromInt, FromExpr, IsValidFromInt, FromIntType, PrintType); OS << " != " << (ToDefault ? "(default) " : ""); - PrintAPSInt(ToInt, ToExpr, IsValidToInt); + PrintAPSInt(ToInt, ToExpr, IsValidToInt, ToIntType, PrintType); OS << ']'; } } /// PrintAPSInt - If valid, print the APSInt. If the expression is /// gives more information, print it too. - void PrintAPSInt(llvm::APSInt Val, Expr *E, bool Valid) { + void PrintAPSInt(llvm::APSInt Val, Expr *E, bool Valid, QualType IntType, + bool PrintType) { Bold(); if (Valid) { if (HasExtraInfo(E)) { @@ -1707,7 +1738,20 @@ class TemplateDiff { OS << " aka "; Bold(); } - OS << Val.toString(10); + if (PrintType) { + Unbold(); + OS << "("; + Bold(); + IntType.print(OS, Context.getPrintingPolicy()); + Unbold(); + OS << ") "; + Bold(); + } + if (IntType->isBooleanType()) { + OS << ((Val == 0) ? "false" : "true"); + } else { + OS << Val.toString(10); + } } else if (E) { PrintExpr(E); } else { @@ -1716,8 +1760,8 @@ class TemplateDiff { Unbold(); } - /// HasExtraInfo - Returns true if E is not an integer literal or the - /// negation of an integer literal + /// HasExtraInfo - Returns true if E is not an integer literal, the + /// negation of an integer literal, or a boolean literal. bool HasExtraInfo(Expr *E) { if (!E) return false; @@ -1730,10 +1774,13 @@ class TemplateDiff { if (isa<IntegerLiteral>(UO->getSubExpr())) return false; + if (isa<CXXBoolLiteralExpr>(E)) + return false; + return true; } - void PrintValueDecl(ValueDecl *VD, bool AddressOf, bool NullPtr) { + void PrintValueDecl(ValueDecl *VD, bool AddressOf, Expr *E, bool NullPtr) { if (VD) { if (AddressOf) OS << "&"; @@ -1742,6 +1789,17 @@ class TemplateDiff { } if (NullPtr) { + if (E && !isa<CXXNullPtrLiteralExpr>(E)) { + PrintExpr(E); + if (IsBold) { + Unbold(); + OS << " aka "; + Bold(); + } else { + OS << " aka "; + } + } + OS << "nullptr"; return; } @@ -1753,30 +1811,72 @@ class TemplateDiff { /// argument differences. void PrintValueDecl(ValueDecl *FromValueDecl, ValueDecl *ToValueDecl, bool FromAddressOf, bool ToAddressOf, bool FromNullPtr, - bool ToNullPtr, bool FromDefault, bool ToDefault, - bool Same) { + bool ToNullPtr, Expr *FromExpr, Expr *ToExpr, + bool FromDefault, bool ToDefault, bool Same) { assert((FromValueDecl || FromNullPtr || ToValueDecl || ToNullPtr) && "Only one Decl argument may be NULL"); if (Same) { - PrintValueDecl(FromValueDecl, FromAddressOf, FromNullPtr); + PrintValueDecl(FromValueDecl, FromAddressOf, FromExpr, FromNullPtr); } else if (!PrintTree) { OS << (FromDefault ? "(default) " : ""); Bold(); - PrintValueDecl(FromValueDecl, FromAddressOf, FromNullPtr); + PrintValueDecl(FromValueDecl, FromAddressOf, FromExpr, FromNullPtr); Unbold(); } else { OS << (FromDefault ? "[(default) " : "["); Bold(); - PrintValueDecl(FromValueDecl, FromAddressOf, FromNullPtr); + PrintValueDecl(FromValueDecl, FromAddressOf, FromExpr, FromNullPtr); Unbold(); OS << " != " << (ToDefault ? "(default) " : ""); Bold(); - PrintValueDecl(ToValueDecl, ToAddressOf, ToNullPtr); + PrintValueDecl(ToValueDecl, ToAddressOf, ToExpr, ToNullPtr); + Unbold(); + OS << ']'; + } + + } + + /// PrintValueDeclAndInteger - Uses the print functions for ValueDecl and + /// APSInt to print a mixed difference. + void PrintValueDeclAndInteger(ValueDecl *VD, bool NeedAddressOf, + bool IsNullPtr, Expr *VDExpr, bool DefaultDecl, + llvm::APSInt Val, QualType IntType, + Expr *IntExpr, bool DefaultInt) { + if (!PrintTree) { + OS << (DefaultDecl ? "(default) " : ""); + Bold(); + PrintValueDecl(VD, NeedAddressOf, VDExpr, IsNullPtr); Unbold(); + } else { + OS << (DefaultDecl ? "[(default) " : "["); + Bold(); + PrintValueDecl(VD, NeedAddressOf, VDExpr, IsNullPtr); + Unbold(); + OS << " != " << (DefaultInt ? "(default) " : ""); + PrintAPSInt(Val, IntExpr, true /*Valid*/, IntType, false /*PrintType*/); OS << ']'; } + } + /// PrintIntegerAndValueDecl - Uses the print functions for APSInt and + /// ValueDecl to print a mixed difference. + void PrintIntegerAndValueDecl(llvm::APSInt Val, QualType IntType, + Expr *IntExpr, bool DefaultInt, ValueDecl *VD, + bool NeedAddressOf, bool IsNullPtr, + Expr *VDExpr, bool DefaultDecl) { + if (!PrintTree) { + OS << (DefaultInt ? "(default) " : ""); + PrintAPSInt(Val, IntExpr, true /*Valid*/, IntType, false /*PrintType*/); + } else { + OS << (DefaultInt ? "[(default) " : "["); + PrintAPSInt(Val, IntExpr, true /*Valid*/, IntType, false /*PrintType*/); + OS << " != " << (DefaultDecl ? "(default) " : ""); + Bold(); + PrintValueDecl(VD, NeedAddressOf, VDExpr, IsNullPtr); + Unbold(); + OS << ']'; + } } // Prints the appropriate placeholder for elided template arguments. @@ -1866,21 +1966,21 @@ public: PrintTree(PrintTree), ShowColor(ShowColor), // When printing a single type, the FromType is the one printed. - FromType(PrintFromType ? FromType : ToType), - ToType(PrintFromType ? ToType : FromType), + FromTemplateType(PrintFromType ? FromType : ToType), + ToTemplateType(PrintFromType ? ToType : FromType), OS(OS), IsBold(false) { } /// DiffTemplate - Start the template type diffing. void DiffTemplate() { - Qualifiers FromQual = FromType.getQualifiers(), - ToQual = ToType.getQualifiers(); + Qualifiers FromQual = FromTemplateType.getQualifiers(), + ToQual = ToTemplateType.getQualifiers(); const TemplateSpecializationType *FromOrigTST = - GetTemplateSpecializationType(Context, FromType); + GetTemplateSpecializationType(Context, FromTemplateType); const TemplateSpecializationType *ToOrigTST = - GetTemplateSpecializationType(Context, ToType); + GetTemplateSpecializationType(Context, ToTemplateType); // Only checking templates. if (!FromOrigTST || !ToOrigTST) @@ -1893,13 +1993,12 @@ public: FromQual -= QualType(FromOrigTST, 0).getQualifiers(); ToQual -= QualType(ToOrigTST, 0).getQualifiers(); - Tree.SetNode(FromType, ToType); - Tree.SetNode(FromQual, ToQual); - Tree.SetKind(DiffTree::Template); // Same base template, but different arguments. - Tree.SetNode(FromOrigTST->getTemplateName().getAsTemplateDecl(), - ToOrigTST->getTemplateName().getAsTemplateDecl()); + Tree.SetTemplateDiff(FromOrigTST->getTemplateName().getAsTemplateDecl(), + ToOrigTST->getTemplateName().getAsTemplateDecl(), + FromQual, ToQual, false /*FromDefault*/, + false /*ToDefault*/); DiffTemplate(FromOrigTST, ToOrigTST); } |