https://github.com/Lambo-IITian updated https://github.com/llvm/llvm-project/pull/180175
>From 31e6ffdd6275caacb8c03a890c607377c5b66dbe Mon Sep 17 00:00:00 2001 From: Mohit Gunani <[email protected]> Date: Fri, 6 Feb 2026 17:10:56 +0530 Subject: [PATCH 1/5] [Clang] Improve template diffing to show qualifiers in elided types This change ensures that template diagnostics like Dual<int, [...]> vs Dual<const int, [...]> correctly display the differing qualifiers instead of hiding the entire type. --- clang/lib/AST/ASTDiagnostic.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/clang/lib/AST/ASTDiagnostic.cpp b/clang/lib/AST/ASTDiagnostic.cpp index b8023cb6fa10f..44983edbf870a 100644 --- a/clang/lib/AST/ASTDiagnostic.cpp +++ b/clang/lib/AST/ASTDiagnostic.cpp @@ -1205,8 +1205,16 @@ class TemplateDiff { "Both template specializations need to be valid."); Qualifiers FromQual = FromType.getQualifiers(), ToQual = ToType.getQualifiers(); - FromQual -= QualType(FromArgTST, 0).getQualifiers(); - ToQual -= QualType(ToArgTST, 0).getQualifiers(); + // FromQual -= QualType(FromArgTST, 0).getQualifiers(); + // ToQual -= QualType(ToArgTST, 0).getQualifiers(); + // ... your commented out lines ... + bool Same = false; + if (FromArgTST->getTemplateName().getAsTemplateDecl() == + ToArgTST->getTemplateName().getAsTemplateDecl()) { + // If the names match, the ONLY thing that makes them different is the Qualifiers + Same = (FromQual == ToQual); + } + Tree.SetSame(Same); Tree.SetTemplateDiff(FromArgTST->getTemplateName().getAsTemplateDecl(), ToArgTST->getTemplateName().getAsTemplateDecl(), FromQual, ToQual, FromDefault, ToDefault); >From 8d3fc9c6664480844a46ddd5cf4658add10ee7b9 Mon Sep 17 00:00:00 2001 From: lambo <[email protected]> Date: Fri, 6 Feb 2026 17:28:26 +0530 Subject: [PATCH 2/5] Clean up commented code in ASTDiagnostic.cpp Removed commented out lines in ASTDiagnostic.cpp. --- clang/lib/AST/ASTDiagnostic.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/clang/lib/AST/ASTDiagnostic.cpp b/clang/lib/AST/ASTDiagnostic.cpp index 44983edbf870a..7c498bc9b8e8a 100644 --- a/clang/lib/AST/ASTDiagnostic.cpp +++ b/clang/lib/AST/ASTDiagnostic.cpp @@ -1207,7 +1207,6 @@ class TemplateDiff { ToQual = ToType.getQualifiers(); // FromQual -= QualType(FromArgTST, 0).getQualifiers(); // ToQual -= QualType(ToArgTST, 0).getQualifiers(); - // ... your commented out lines ... bool Same = false; if (FromArgTST->getTemplateName().getAsTemplateDecl() == ToArgTST->getTemplateName().getAsTemplateDecl()) { >From e05df0304fbcc827d705b7b0405392cc388fe1a4 Mon Sep 17 00:00:00 2001 From: lambo <[email protected]> Date: Sat, 7 Feb 2026 13:34:38 +0530 Subject: [PATCH 3/5] Apply suggestion from @cor3ntin Removed the comment out code lines Co-authored-by: Corentin Jabot <[email protected]> --- clang/lib/AST/ASTDiagnostic.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/clang/lib/AST/ASTDiagnostic.cpp b/clang/lib/AST/ASTDiagnostic.cpp index 7c498bc9b8e8a..25d6a0c9c0f43 100644 --- a/clang/lib/AST/ASTDiagnostic.cpp +++ b/clang/lib/AST/ASTDiagnostic.cpp @@ -1205,8 +1205,6 @@ class TemplateDiff { "Both template specializations need to be valid."); Qualifiers FromQual = FromType.getQualifiers(), ToQual = ToType.getQualifiers(); - // FromQual -= QualType(FromArgTST, 0).getQualifiers(); - // ToQual -= QualType(ToArgTST, 0).getQualifiers(); bool Same = false; if (FromArgTST->getTemplateName().getAsTemplateDecl() == ToArgTST->getTemplateName().getAsTemplateDecl()) { >From 16e35e7d8235d4eb3da89c4d8bd949c87aff7bbd Mon Sep 17 00:00:00 2001 From: lambo <[email protected]> Date: Sat, 7 Feb 2026 13:36:09 +0530 Subject: [PATCH 4/5] Apply suggestion from @cor3ntin Simplified the code and comment Co-authored-by: Corentin Jabot <[email protected]> --- clang/lib/AST/ASTDiagnostic.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/AST/ASTDiagnostic.cpp b/clang/lib/AST/ASTDiagnostic.cpp index 25d6a0c9c0f43..0095b765cee28 100644 --- a/clang/lib/AST/ASTDiagnostic.cpp +++ b/clang/lib/AST/ASTDiagnostic.cpp @@ -1208,7 +1208,7 @@ class TemplateDiff { bool Same = false; if (FromArgTST->getTemplateName().getAsTemplateDecl() == ToArgTST->getTemplateName().getAsTemplateDecl()) { - // If the names match, the ONLY thing that makes them different is the Qualifiers + // If the template are the same, the types might still differ by their qualification. Same = (FromQual == ToQual); } Tree.SetSame(Same); >From 0bbaf57423447c0afdf8378f16705842f511b51b Mon Sep 17 00:00:00 2001 From: Mohit Gunani <[email protected]> Date: Sat, 7 Feb 2026 14:30:34 +0530 Subject: [PATCH 5/5] Final fix --- clang/lib/AST/ASTDiagnostic.cpp | 784 +++++++++++++++----------------- 1 file changed, 379 insertions(+), 405 deletions(-) diff --git a/clang/lib/AST/ASTDiagnostic.cpp b/clang/lib/AST/ASTDiagnostic.cpp index 0095b765cee28..009326522a42d 100644 --- a/clang/lib/AST/ASTDiagnostic.cpp +++ b/clang/lib/AST/ASTDiagnostic.cpp @@ -53,7 +53,7 @@ QualType clang::desugarForDiagnostic(ASTContext &Context, QualType QT, } // ...or a substituted template type parameter ... if (const SubstTemplateTypeParmType *ST = - dyn_cast<SubstTemplateTypeParmType>(Ty)) { + dyn_cast<SubstTemplateTypeParmType>(Ty)) { QT = ST->desugar(); continue; } @@ -156,10 +156,10 @@ QualType clang::desugarForDiagnostic(ASTContext &Context, QualType QT, } // Don't desugar magic Objective-C types. - if (QualType(Ty,0) == Context.getObjCIdType() || - QualType(Ty,0) == Context.getObjCClassType() || - QualType(Ty,0) == Context.getObjCSelType() || - QualType(Ty,0) == Context.getObjCProtoType()) + if (QualType(Ty, 0) == Context.getObjCIdType() || + QualType(Ty, 0) == Context.getObjCClassType() || + QualType(Ty, 0) == Context.getObjCSelType() || + QualType(Ty, 0) == Context.getObjCProtoType()) break; // Don't desugar va_list. @@ -172,15 +172,15 @@ QualType clang::desugarForDiagnostic(ASTContext &Context, QualType QT, bool IsSugar = false; switch (Ty->getTypeClass()) { #define ABSTRACT_TYPE(Class, Base) -#define TYPE(Class, Base) \ -case Type::Class: { \ -const Class##Type *CTy = cast<Class##Type>(Ty); \ -if (CTy->isSugared()) { \ -IsSugar = true; \ -Underlying = CTy->desugar(); \ -} \ -break; \ -} +#define TYPE(Class, Base) \ + case Type::Class: { \ + const Class##Type *CTy = cast<Class##Type>(Ty); \ + if (CTy->isSugared()) { \ + IsSugar = true; \ + Underlying = CTy->desugar(); \ + } \ + break; \ + } #include "clang/AST/TypeNodes.inc" } @@ -256,10 +256,10 @@ break; \ /// \param Ty the type to print /// \param QualTypeVals pointer values to QualTypes which are used in the /// diagnostic message -static std::string -ConvertTypeToDiagnosticString(ASTContext &Context, QualType Ty, - ArrayRef<DiagnosticsEngine::ArgumentValue> PrevArgs, - ArrayRef<intptr_t> QualTypeVals) { +static std::string ConvertTypeToDiagnosticString( + ASTContext &Context, QualType Ty, + ArrayRef<DiagnosticsEngine::ArgumentValue> PrevArgs, + ArrayRef<intptr_t> QualTypeVals) { // FIXME: Playing with std::string is really slow. bool ForceAKA = false; QualType CanTy = Ty.getCanonicalType(); @@ -272,10 +272,10 @@ ConvertTypeToDiagnosticString(ASTContext &Context, QualType Ty, if (CompareTy.isNull()) continue; if (CompareTy == Ty) - continue; // Same types + continue; // Same types QualType CompareCanTy = CompareTy.getCanonicalType(); if (CompareCanTy == CanTy) - continue; // Same canonical types + continue; // Same canonical types std::string CompareS = CompareTy.getAsString(Context.getPrintingPolicy()); bool ShouldAKA = false; QualType CompareDesugar = @@ -283,13 +283,13 @@ ConvertTypeToDiagnosticString(ASTContext &Context, QualType Ty, std::string CompareDesugarStr = CompareDesugar.getAsString(Context.getPrintingPolicy()); if (CompareS != S && CompareDesugarStr != S) - continue; // The type string is different than the comparison string - // and the desugared comparison string. + continue; // The type string is different than the comparison string + // and the desugared comparison string. std::string CompareCanS = CompareCanTy.getAsString(Context.getPrintingPolicy()); if (CompareCanS == CanS) - continue; // No new info from canonical type + continue; // No new info from canonical type ForceAKA = true; break; @@ -350,192 +350,189 @@ static bool FormatTemplateTypeDiff(ASTContext &Context, QualType FromType, bool ShowColors, raw_ostream &OS); void clang::FormatASTNodeDiagnosticArgument( - DiagnosticsEngine::ArgumentKind Kind, - intptr_t Val, - StringRef Modifier, - StringRef Argument, - ArrayRef<DiagnosticsEngine::ArgumentValue> PrevArgs, - SmallVectorImpl<char> &Output, - void *Cookie, + DiagnosticsEngine::ArgumentKind Kind, intptr_t Val, StringRef Modifier, + StringRef Argument, ArrayRef<DiagnosticsEngine::ArgumentValue> PrevArgs, + SmallVectorImpl<char> &Output, void *Cookie, ArrayRef<intptr_t> QualTypeVals) { - ASTContext &Context = *static_cast<ASTContext*>(Cookie); + ASTContext &Context = *static_cast<ASTContext *>(Cookie); size_t OldEnd = Output.size(); llvm::raw_svector_ostream OS(Output); bool NeedQuotes = true; switch (Kind) { - default: llvm_unreachable("unknown ArgumentKind"); - case DiagnosticsEngine::ak_addrspace: { - assert(Modifier.empty() && Argument.empty() && - "Invalid modifier for Qualifiers argument"); - - auto S = Qualifiers::getAddrSpaceAsString(static_cast<LangAS>(Val)); - if (S.empty()) { - OS << (Context.getLangOpts().OpenCL ? "default" : "generic"); - OS << " address space"; - } else { - OS << "address space"; - OS << " '" << S << "'"; - } + default: + llvm_unreachable("unknown ArgumentKind"); + case DiagnosticsEngine::ak_addrspace: { + assert(Modifier.empty() && Argument.empty() && + "Invalid modifier for Qualifiers argument"); + + auto S = Qualifiers::getAddrSpaceAsString(static_cast<LangAS>(Val)); + if (S.empty()) { + OS << (Context.getLangOpts().OpenCL ? "default" : "generic"); + OS << " address space"; + } else { + OS << "address space"; + OS << " '" << S << "'"; + } + NeedQuotes = false; + break; + } + case DiagnosticsEngine::ak_qual: { + assert(Modifier.empty() && Argument.empty() && + "Invalid modifier for Qualifiers argument"); + + Qualifiers Q(Qualifiers::fromOpaqueValue(Val)); + auto S = Q.getAsString(); + if (S.empty()) { + OS << "unqualified"; NeedQuotes = false; - break; + } else { + OS << S; } - case DiagnosticsEngine::ak_qual: { - assert(Modifier.empty() && Argument.empty() && - "Invalid modifier for Qualifiers argument"); - - Qualifiers Q(Qualifiers::fromOpaqueValue(Val)); - auto S = Q.getAsString(); - if (S.empty()) { - OS << "unqualified"; - NeedQuotes = false; - } else { - OS << S; - } + break; + } + case DiagnosticsEngine::ak_qualtype_pair: { + TemplateDiffTypes &TDT = *reinterpret_cast<TemplateDiffTypes *>(Val); + QualType FromType = + QualType::getFromOpaquePtr(reinterpret_cast<void *>(TDT.FromType)); + QualType ToType = + QualType::getFromOpaquePtr(reinterpret_cast<void *>(TDT.ToType)); + + if (FormatTemplateTypeDiff(Context, FromType, ToType, TDT.PrintTree, + TDT.PrintFromType, TDT.ElideType, TDT.ShowColors, + OS)) { + NeedQuotes = !TDT.PrintTree; + TDT.TemplateDiffUsed = true; break; } - case DiagnosticsEngine::ak_qualtype_pair: { - TemplateDiffTypes &TDT = *reinterpret_cast<TemplateDiffTypes*>(Val); - QualType FromType = - QualType::getFromOpaquePtr(reinterpret_cast<void*>(TDT.FromType)); - QualType ToType = - QualType::getFromOpaquePtr(reinterpret_cast<void*>(TDT.ToType)); - - if (FormatTemplateTypeDiff(Context, FromType, ToType, TDT.PrintTree, - TDT.PrintFromType, TDT.ElideType, - TDT.ShowColors, OS)) { - NeedQuotes = !TDT.PrintTree; - TDT.TemplateDiffUsed = true; - break; - } - // Don't fall-back during tree printing. The caller will handle - // this case. - if (TDT.PrintTree) - return; + // Don't fall-back during tree printing. The caller will handle + // this case. + if (TDT.PrintTree) + return; - // Attempting to do a template diff on non-templates. Set the variables - // and continue with regular type printing of the appropriate type. - Val = TDT.PrintFromType ? TDT.FromType : TDT.ToType; - Modifier = StringRef(); - Argument = StringRef(); - // Fall through - [[fallthrough]]; - } - case DiagnosticsEngine::ak_qualtype: { + // Attempting to do a template diff on non-templates. Set the variables + // and continue with regular type printing of the appropriate type. + Val = TDT.PrintFromType ? TDT.FromType : TDT.ToType; + Modifier = StringRef(); + Argument = StringRef(); + // Fall through + [[fallthrough]]; + } + case DiagnosticsEngine::ak_qualtype: { + assert(Modifier.empty() && Argument.empty() && + "Invalid modifier for QualType argument"); + + QualType Ty(QualType::getFromOpaquePtr(reinterpret_cast<void *>(Val))); + OS << ConvertTypeToDiagnosticString(Context, Ty, PrevArgs, QualTypeVals); + NeedQuotes = false; + break; + } + case DiagnosticsEngine::ak_declarationname: { + if (Modifier == "objcclass" && Argument.empty()) + OS << '+'; + else if (Modifier == "objcinstance" && Argument.empty()) + OS << '-'; + else assert(Modifier.empty() && Argument.empty() && - "Invalid modifier for QualType argument"); + "Invalid modifier for DeclarationName argument"); - QualType Ty(QualType::getFromOpaquePtr(reinterpret_cast<void*>(Val))); - OS << ConvertTypeToDiagnosticString(Context, Ty, PrevArgs, QualTypeVals); - NeedQuotes = false; - break; + OS << DeclarationName::getFromOpaqueInteger(Val); + break; + } + case DiagnosticsEngine::ak_nameddecl: { + bool Qualified; + if (Modifier == "q" && Argument.empty()) + Qualified = true; + else { + assert(Modifier.empty() && Argument.empty() && + "Invalid modifier for NamedDecl* argument"); + Qualified = false; } - case DiagnosticsEngine::ak_declarationname: { - if (Modifier == "objcclass" && Argument.empty()) - OS << '+'; - else if (Modifier == "objcinstance" && Argument.empty()) - OS << '-'; + const NamedDecl *ND = reinterpret_cast<const NamedDecl *>(Val); + ND->getNameForDiagnostic(OS, Context.getPrintingPolicy(), Qualified); + break; + } + case DiagnosticsEngine::ak_nestednamespec: + NestedNameSpecifier::getFromVoidPointer(reinterpret_cast<void *>(Val)) + .print(OS, Context.getPrintingPolicy(), + /*ResolveTemplateArguments=*/false, + /*PrintFinalScopeResOp=*/false); + break; + case DiagnosticsEngine::ak_declcontext: { + DeclContext *DC = reinterpret_cast<DeclContext *>(Val); + assert(DC && "Should never have a null declaration context"); + NeedQuotes = false; + + // FIXME: Get the strings for DeclContext from some localized place + if (DC->isTranslationUnit()) { + if (Context.getLangOpts().CPlusPlus) + OS << "the global namespace"; else - assert(Modifier.empty() && Argument.empty() && - "Invalid modifier for DeclarationName argument"); - - OS << DeclarationName::getFromOpaqueInteger(Val); - break; - } - case DiagnosticsEngine::ak_nameddecl: { - bool Qualified; - if (Modifier == "q" && Argument.empty()) - Qualified = true; - else { - assert(Modifier.empty() && Argument.empty() && - "Invalid modifier for NamedDecl* argument"); - Qualified = false; - } - const NamedDecl *ND = reinterpret_cast<const NamedDecl*>(Val); - ND->getNameForDiagnostic(OS, Context.getPrintingPolicy(), Qualified); - break; - } - case DiagnosticsEngine::ak_nestednamespec: - NestedNameSpecifier::getFromVoidPointer(reinterpret_cast<void *>(Val)) - .print(OS, Context.getPrintingPolicy(), - /*ResolveTemplateArguments=*/false, - /*PrintFinalScopeResOp=*/false); - break; - case DiagnosticsEngine::ak_declcontext: { - DeclContext *DC = reinterpret_cast<DeclContext *> (Val); - assert(DC && "Should never have a null declaration context"); - NeedQuotes = false; - - // FIXME: Get the strings for DeclContext from some localized place - if (DC->isTranslationUnit()) { - if (Context.getLangOpts().CPlusPlus) - OS << "the global namespace"; - else - OS << "the global scope"; - } else if (DC->isClosure()) { - OS << "block literal"; - } else if (isLambdaCallOperator(DC)) { - OS << "lambda expression"; - } else if (TypeDecl *Type = dyn_cast<TypeDecl>(DC)) { - OS << ConvertTypeToDiagnosticString( - Context, Context.getTypeDeclType(Type), PrevArgs, QualTypeVals); - } else { - assert(isa<NamedDecl>(DC) && "Expected a NamedDecl"); - NamedDecl *ND = cast<NamedDecl>(DC); - if (isa<NamespaceDecl>(ND)) - OS << "namespace "; - else if (isa<ObjCMethodDecl>(ND)) - OS << "method "; - else if (isa<FunctionDecl>(ND)) - OS << "function "; - - OS << '\''; - ND->getNameForDiagnostic(OS, Context.getPrintingPolicy(), true); - OS << '\''; - } - break; - } - case DiagnosticsEngine::ak_attr: { - const Attr *At = reinterpret_cast<Attr *>(Val); - assert(At && "Received null Attr object!"); + OS << "the global scope"; + } else if (DC->isClosure()) { + OS << "block literal"; + } else if (isLambdaCallOperator(DC)) { + OS << "lambda expression"; + } else if (TypeDecl *Type = dyn_cast<TypeDecl>(DC)) { + OS << ConvertTypeToDiagnosticString( + Context, Context.getTypeDeclType(Type), PrevArgs, QualTypeVals); + } else { + assert(isa<NamedDecl>(DC) && "Expected a NamedDecl"); + NamedDecl *ND = cast<NamedDecl>(DC); + if (isa<NamespaceDecl>(ND)) + OS << "namespace "; + else if (isa<ObjCMethodDecl>(ND)) + OS << "method "; + else if (isa<FunctionDecl>(ND)) + OS << "function "; OS << '\''; - if (At->hasScope()) { - OS << At->getNormalizedFullName(At->getScopeName()->getName(), - At->getSpelling()); - } else { - OS << At->getSpelling(); - } + ND->getNameForDiagnostic(OS, Context.getPrintingPolicy(), true); OS << '\''; - NeedQuotes = false; - break; } - case DiagnosticsEngine::ak_expr: { - const Expr *E = reinterpret_cast<Expr *>(Val); - assert(E && "Received null Expr!"); - E->printPretty(OS, /*Helper=*/nullptr, Context.getPrintingPolicy()); - break; + break; + } + case DiagnosticsEngine::ak_attr: { + const Attr *At = reinterpret_cast<Attr *>(Val); + assert(At && "Received null Attr object!"); + + OS << '\''; + if (At->hasScope()) { + OS << At->getNormalizedFullName(At->getScopeName()->getName(), + At->getSpelling()); + } else { + OS << At->getSpelling(); } - case DiagnosticsEngine::ak_attr_info: { - AttributeCommonInfo *AT = reinterpret_cast<AttributeCommonInfo *>(Val); - assert(AT && "Received null AttributeCommonInfo object!"); + OS << '\''; + NeedQuotes = false; + break; + } + case DiagnosticsEngine::ak_expr: { + const Expr *E = reinterpret_cast<Expr *>(Val); + assert(E && "Received null Expr!"); + E->printPretty(OS, /*Helper=*/nullptr, Context.getPrintingPolicy()); + break; + } + case DiagnosticsEngine::ak_attr_info: { + AttributeCommonInfo *AT = reinterpret_cast<AttributeCommonInfo *>(Val); + assert(AT && "Received null AttributeCommonInfo object!"); - OS << '\''; - if (AT->isStandardAttributeSyntax()) { - OS << AT->getNormalizedFullName(); - } else { - OS << AT->getAttrName()->getName(); - } - OS << '\''; - NeedQuotes = false; - break; + OS << '\''; + if (AT->isStandardAttributeSyntax()) { + OS << AT->getNormalizedFullName(); + } else { + OS << AT->getAttrName()->getName(); } + OS << '\''; + NeedQuotes = false; + break; + } } if (NeedQuotes) { - Output.insert(Output.begin()+OldEnd, '\''); + Output.insert(Output.begin() + OldEnd, '\''); Output.push_back('\''); } } @@ -774,20 +771,17 @@ class TemplateDiff { /// SetDefault - Sets FromDefault and ToDefault flags of the current node. void SetDefault(bool FromDefault, bool ToDefault) { - assert((!FromDefault || !ToDefault) && "Both arguments cannot be default."); + 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. - void SetSame(bool Same) { - FlatTree[CurrentNode].Same = Same; - } + void SetSame(bool Same) { FlatTree[CurrentNode].Same = Same; } /// SetKind - Sets the current node's type. - void SetKind(DiffKind Kind) { - FlatTree[CurrentNode].Kind = Kind; - } + void SetKind(DiffKind Kind) { FlatTree[CurrentNode].Kind = Kind; } /// Up - Changes the node to the parent of the current node. void Up() { @@ -828,9 +822,7 @@ class TemplateDiff { } /// Parent - Move the current read node to its parent. - void Parent() { - ReadNode = FlatTree[ReadNode].ParentNode; - } + void Parent() { ReadNode = FlatTree[ReadNode].ParentNode; } void GetTemplateDiff(TemplateDecl *&FromTD, TemplateDecl *&ToTD, Qualifiers &FromQual, Qualifiers &ToQual) { @@ -922,29 +914,19 @@ class TemplateDiff { } /// FromDefault - Return true if the from argument is the default. - bool FromDefault() { - return FlatTree[ReadNode].FromArgInfo.IsDefault; - } + bool FromDefault() { return FlatTree[ReadNode].FromArgInfo.IsDefault; } /// ToDefault - Return true if the to argument is the default. - bool ToDefault() { - return FlatTree[ReadNode].ToArgInfo.IsDefault; - } + bool ToDefault() { return FlatTree[ReadNode].ToArgInfo.IsDefault; } /// NodeIsSame - Returns true if the arguments are the same. - bool NodeIsSame() { - return FlatTree[ReadNode].Same; - } + bool NodeIsSame() { return FlatTree[ReadNode].Same; } /// HasChildren - Returns true if the node has children. - bool HasChildren() { - return FlatTree[ReadNode].ChildNode != 0; - } + bool HasChildren() { return FlatTree[ReadNode].ChildNode != 0; } /// MoveToChild - Moves from the current node to its child. - void MoveToChild() { - ReadNode = FlatTree[ReadNode].ChildNode; - } + void MoveToChild() { ReadNode = FlatTree[ReadNode].ChildNode; } /// AdvanceSibling - If there is a next sibling, advance to it and return /// true. Otherwise, return false. @@ -957,19 +939,13 @@ class TemplateDiff { } /// HasNextSibling - Return true if the node has a next sibling. - bool HasNextSibling() { - return FlatTree[ReadNode].NextNode != 0; - } + bool HasNextSibling() { return FlatTree[ReadNode].NextNode != 0; } /// Empty - Returns true if the tree has no information. - bool Empty() { - return GetKind() == Invalid; - } + bool Empty() { return GetKind() == Invalid; } /// GetKind - Returns the current node's type. - DiffKind GetKind() { - return FlatTree[ReadNode].Kind; - } + DiffKind GetKind() { return FlatTree[ReadNode].Kind; } }; DiffTree Tree; @@ -979,8 +955,8 @@ class TemplateDiff { /// The desugared TemplateArgument should provide the canonical argument /// for comparisons. class TSTiterator { - typedef const TemplateArgument& reference; - typedef const TemplateArgument* pointer; + typedef const TemplateArgument &reference; + typedef const TemplateArgument *pointer; /// InternalIterator - an iterator that is used to enter a /// TemplateSpecializationType and read TemplateArguments inside template @@ -1004,20 +980,24 @@ class TemplateDiff { /// template argument. InternalIterator(const TemplateSpecializationType *TST) : TST(TST), Index(0), CurrentTA(nullptr), EndTA(nullptr) { - if (!TST) return; + if (!TST) + return; - if (isEnd()) return; + if (isEnd()) + return; // Set to first template argument. If not a parameter pack, done. TemplateArgument TA = TST->template_arguments()[0]; - if (TA.getKind() != TemplateArgument::Pack) return; + if (TA.getKind() != TemplateArgument::Pack) + return; // Start looking into the parameter pack. CurrentTA = TA.pack_begin(); EndTA = TA.pack_end(); // Found a valid template argument. - if (CurrentTA != EndTA) return; + if (CurrentTA != EndTA) + return; // Parameter pack is empty, use the increment to get to a valid // template argument. @@ -1106,19 +1086,13 @@ class TemplateDiff { } /// operator* - Returns the appropriate TemplateArgument. - reference operator*() const { - return *SugaredIterator; - } + reference operator*() const { return *SugaredIterator; } /// operator-> - Allow access to the underlying TemplateArgument. - pointer operator->() const { - return &operator*(); - } + pointer operator->() const { return &operator*(); } /// isEnd - Returns true if no more TemplateArguments are available. - bool isEnd() const { - return SugaredIterator.isEnd(); - } + bool isEnd() const { return SugaredIterator.isEnd(); } /// hasDesugaredTA - Returns true if there is another TemplateArgument /// available. @@ -1143,7 +1117,7 @@ class TemplateDiff { Ty->getAs<TemplateSpecializationType>()) return TST; - if (const auto* SubstType = Ty->getAs<SubstTemplateTypeParmType>()) + if (const auto *SubstType = Ty->getAs<SubstTemplateTypeParmType>()) Ty = SubstType->getReplacementType(); const auto *RT = Ty->getAs<RecordType>(); @@ -1205,12 +1179,12 @@ class TemplateDiff { "Both template specializations need to be valid."); Qualifiers FromQual = FromType.getQualifiers(), ToQual = ToType.getQualifiers(); - bool Same = false; - if (FromArgTST->getTemplateName().getAsTemplateDecl() == - ToArgTST->getTemplateName().getAsTemplateDecl()) { - // If the template are the same, the types might still differ by their qualification. - Same = (FromQual == ToQual); - } + + // If the names match, the ONLY thing that makes them different is the + // Qualifiers + bool Same=((FromArgTST->getTemplateName().getAsTemplateDecl() == + ToArgTST->getTemplateName().getAsTemplateDecl())&&(FromQual == ToQual)); + Tree.SetSame(Same); Tree.SetTemplateDiff(FromArgTST->getTemplateName().getAsTemplateDecl(), ToArgTST->getTemplateName().getAsTemplateDecl(), @@ -1342,8 +1316,8 @@ class TemplateDiff { bool FromDefault = FromIter.isEnd() && (FromExpr || FromValueDecl || HasFromInt || FromNullPtr); - bool ToDefault = ToIter.isEnd() && - (ToExpr || ToValueDecl || HasToInt || ToNullPtr); + bool ToDefault = + ToIter.isEnd() && (ToExpr || ToValueDecl || HasToInt || ToNullPtr); bool FromDeclaration = FromValueDecl || FromNullPtr; bool ToDeclaration = ToValueDecl || ToNullPtr; @@ -1354,7 +1328,6 @@ class TemplateDiff { HasToInt, ToIntType, ToExpr, FromDefault, ToDefault); Tree.SetSame(false); return; - } if (HasFromInt && ToDeclaration) { @@ -1480,15 +1453,16 @@ class TemplateDiff { return true; // Create vectors of template aliases. - SmallVector<const TemplateSpecializationType*, 1> FromTemplateList, - ToTemplateList; + SmallVector<const TemplateSpecializationType *, 1> FromTemplateList, + ToTemplateList; makeTemplateList(FromTemplateList, FromTST); makeTemplateList(ToTemplateList, ToTST); SmallVectorImpl<const TemplateSpecializationType *>::reverse_iterator - FromIter = FromTemplateList.rbegin(), FromEnd = FromTemplateList.rend(), - ToIter = ToTemplateList.rbegin(), ToEnd = ToTemplateList.rend(); + FromIter = FromTemplateList.rbegin(), + FromEnd = FromTemplateList.rend(), ToIter = ToTemplateList.rbegin(), + ToEnd = ToTemplateList.rend(); // Check if the lowest template types are the same. If not, return. if (!hasSameBaseTemplate(Context, *FromIter, *ToIter)) @@ -1559,137 +1533,137 @@ class TemplateDiff { // Handle cases where the difference is not templates with different // arguments. switch (Tree.GetKind()) { - case DiffTree::Invalid: - llvm_unreachable("Template diffing failed with bad DiffNode"); - case DiffTree::Type: { - QualType FromType, ToType; - Tree.GetTypeDiff(FromType, ToType); - PrintTypeNames(FromType, ToType, Tree.FromDefault(), Tree.ToDefault(), - Tree.NodeIsSame()); - return; - } - case DiffTree::Expression: { - Expr *FromExpr, *ToExpr; - Tree.GetExpressionDiff(FromExpr, ToExpr); - PrintExpr(FromExpr, ToExpr, Tree.FromDefault(), Tree.ToDefault(), - Tree.NodeIsSame()); - return; - } - case DiffTree::TemplateTemplate: { - TemplateDecl *FromTD, *ToTD; - Tree.GetTemplateTemplateDiff(FromTD, ToTD); - PrintTemplateTemplate(FromTD, ToTD, Tree.FromDefault(), - Tree.ToDefault(), Tree.NodeIsSame()); - return; - } - case DiffTree::Integer: { - llvm::APSInt FromInt, ToInt; - Expr *FromExpr, *ToExpr; - bool IsValidFromInt, IsValidToInt; - 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; - bool FromNullPtr, ToNullPtr; - Expr *FromExpr, *ToExpr; - Tree.GetDeclarationDiff(FromValueDecl, ToValueDecl, FromAddressOf, - ToAddressOf, FromNullPtr, ToNullPtr, FromExpr, - ToExpr); - PrintValueDecl(FromValueDecl, ToValueDecl, FromAddressOf, ToAddressOf, - 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()); + case DiffTree::Invalid: + llvm_unreachable("Template diffing failed with bad DiffNode"); + case DiffTree::Type: { + QualType FromType, ToType; + Tree.GetTypeDiff(FromType, ToType); + PrintTypeNames(FromType, ToType, Tree.FromDefault(), Tree.ToDefault(), + Tree.NodeIsSame()); + return; + } + case DiffTree::Expression: { + Expr *FromExpr, *ToExpr; + Tree.GetExpressionDiff(FromExpr, ToExpr); + PrintExpr(FromExpr, ToExpr, Tree.FromDefault(), Tree.ToDefault(), + Tree.NodeIsSame()); + return; + } + case DiffTree::TemplateTemplate: { + TemplateDecl *FromTD, *ToTD; + Tree.GetTemplateTemplateDiff(FromTD, ToTD); + PrintTemplateTemplate(FromTD, ToTD, Tree.FromDefault(), Tree.ToDefault(), + Tree.NodeIsSame()); + return; + } + case DiffTree::Integer: { + llvm::APSInt FromInt, ToInt; + Expr *FromExpr, *ToExpr; + bool IsValidFromInt, IsValidToInt; + 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; + bool FromNullPtr, ToNullPtr; + Expr *FromExpr, *ToExpr; + Tree.GetDeclarationDiff(FromValueDecl, ToValueDecl, FromAddressOf, + ToAddressOf, FromNullPtr, ToNullPtr, FromExpr, + ToExpr); + PrintValueDecl(FromValueDecl, ToValueDecl, FromAddressOf, ToAddressOf, + 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; + 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 + // arguments, there are no children; special-case this. + OS << FromTD->getDeclName() << "<>"; return; } - case DiffTree::Template: { - // Node is root of template. Recurse on children. - TemplateDecl *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 - // arguments, there are no children; special-case this. - OS << FromTD->getDeclName() << "<>"; - return; - } - OS << FromTD->getDeclName() << '<'; - Tree.MoveToChild(); - unsigned NumElideArgs = 0; - bool AllArgsElided = true; - do { - if (ElideType) { - if (Tree.NodeIsSame()) { - ++NumElideArgs; - continue; - } - AllArgsElided = false; - if (NumElideArgs > 0) { - PrintElideArgs(NumElideArgs, Indent); - NumElideArgs = 0; - OS << ", "; - } + OS << FromTD->getDeclName() << '<'; + Tree.MoveToChild(); + unsigned NumElideArgs = 0; + bool AllArgsElided = true; + do { + if (ElideType) { + if (Tree.NodeIsSame()) { + ++NumElideArgs; + continue; } - TreeToString(Indent); - if (Tree.HasNextSibling()) - OS << ", "; - } while (Tree.AdvanceSibling()); - if (NumElideArgs > 0) { - if (AllArgsElided) - OS << "..."; - else + AllArgsElided = false; + if (NumElideArgs > 0) { PrintElideArgs(NumElideArgs, Indent); + NumElideArgs = 0; + OS << ", "; + } } - - Tree.Parent(); - OS << ">"; - return; + TreeToString(Indent); + if (Tree.HasNextSibling()) + OS << ", "; + } while (Tree.AdvanceSibling()); + if (NumElideArgs > 0) { + if (AllArgsElided) + OS << "..."; + else + PrintElideArgs(NumElideArgs, Indent); } + + Tree.Parent(); + OS << ">"; + return; + } } } @@ -1718,8 +1692,8 @@ class TemplateDiff { /// PrintTypeNames - prints the typenames, bolding differences. Will detect /// typenames that are the same and attempt to disambiguate them by using /// canonical typenames. - void PrintTypeNames(QualType FromType, QualType ToType, - bool FromDefault, bool ToDefault, bool Same) { + void PrintTypeNames(QualType FromType, QualType ToType, bool FromDefault, + bool ToDefault, bool Same) { assert((!FromType.isNull() || !ToType.isNull()) && "Only one template argument may be missing."); @@ -1730,7 +1704,7 @@ class TemplateDiff { if (!FromType.isNull() && !ToType.isNull() && FromType.getLocalUnqualifiedType() == - ToType.getLocalUnqualifiedType()) { + ToType.getLocalUnqualifiedType()) { Qualifiers FromQual = FromType.getLocalQualifiers(), ToQual = ToType.getLocalQualifiers(); PrintQualifiers(FromQual, ToQual); @@ -1738,8 +1712,8 @@ class TemplateDiff { return; } - std::string FromTypeStr = FromType.isNull() ? "(no argument)" - : FromType.getAsString(Policy); + std::string FromTypeStr = + FromType.isNull() ? "(no argument)" : FromType.getAsString(Policy); std::string ToTypeStr = ToType.isNull() ? "(no argument)" : ToType.getAsString(Policy); // TODO: merge this with other aka printing above. @@ -1774,7 +1748,7 @@ class TemplateDiff { void PrintExpr(const Expr *FromExpr, const Expr *ToExpr, bool FromDefault, bool ToDefault, bool Same) { assert((FromExpr || ToExpr) && - "Only one template argument may be missing."); + "Only one template argument may be missing."); if (Same) { PrintExpr(FromExpr); } else if (!PrintTree) { @@ -1908,7 +1882,8 @@ class TemplateDiff { /// 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; + if (!E) + return false; E = E->IgnoreImpCasts(); @@ -1918,7 +1893,8 @@ class TemplateDiff { return isa<IntegerLiteral>(E); }; - if (CheckIntegerLiteral(E)) return false; + if (CheckIntegerLiteral(E)) + return false; if (UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) if (UO->getOpcode() == UO_Minus) @@ -2049,7 +2025,8 @@ class TemplateDiff { for (unsigned i = 0; i < Indent; ++i) OS << " "; } - if (NumElideArgs == 0) return; + if (NumElideArgs == 0) + return; if (NumElideArgs == 1) OS << "[...]"; else @@ -2064,13 +2041,13 @@ class TemplateDiff { // Both types have same qualifiers if (FromQual == ToQual) { - PrintQualifier(FromQual, /*ApplyBold*/false); + PrintQualifier(FromQual, /*ApplyBold*/ false); return; } // Find common qualifiers and strip them from FromQual and ToQual. - Qualifiers CommonQual = Qualifiers::removeCommonQualifiers(FromQual, - ToQual); + Qualifiers CommonQual = + Qualifiers::removeCommonQualifiers(FromQual, ToQual); // The qualifiers are printed before the template name. // Inline printing: @@ -2089,8 +2066,8 @@ class TemplateDiff { OS << "(no qualifiers) "; Unbold(); } else { - PrintQualifier(CommonQual, /*ApplyBold*/false); - PrintQualifier(FromQual, /*ApplyBold*/true); + PrintQualifier(CommonQual, /*ApplyBold*/ false); + PrintQualifier(FromQual, /*ApplyBold*/ true); } OS << "!= "; if (CommonQual.empty() && ToQual.empty()) { @@ -2098,42 +2075,39 @@ class TemplateDiff { OS << "(no qualifiers)"; Unbold(); } else { - PrintQualifier(CommonQual, /*ApplyBold*/false, - /*appendSpaceIfNonEmpty*/!ToQual.empty()); - PrintQualifier(ToQual, /*ApplyBold*/true, - /*appendSpaceIfNonEmpty*/false); + PrintQualifier(CommonQual, /*ApplyBold*/ false, + /*appendSpaceIfNonEmpty*/ !ToQual.empty()); + PrintQualifier(ToQual, /*ApplyBold*/ true, + /*appendSpaceIfNonEmpty*/ false); } OS << "] "; } else { - PrintQualifier(CommonQual, /*ApplyBold*/false); - PrintQualifier(FromQual, /*ApplyBold*/true); + PrintQualifier(CommonQual, /*ApplyBold*/ false); + PrintQualifier(FromQual, /*ApplyBold*/ true); } } void PrintQualifier(Qualifiers Q, bool ApplyBold, bool AppendSpaceIfNonEmpty = true) { - if (Q.empty()) return; - if (ApplyBold) Bold(); + if (Q.empty()) + return; + if (ApplyBold) + Bold(); Q.print(OS, Policy, AppendSpaceIfNonEmpty); - if (ApplyBold) Unbold(); + if (ApplyBold) + Unbold(); } public: - TemplateDiff(raw_ostream &OS, ASTContext &Context, QualType FromType, QualType ToType, bool PrintTree, bool PrintFromType, bool ElideType, bool ShowColor) - : Context(Context), - Policy(Context.getLangOpts()), - ElideType(ElideType), - PrintTree(PrintTree), - ShowColor(ShowColor), - // When printing a single type, the FromType is the one printed. - FromTemplateType(PrintFromType ? FromType : ToType), - ToTemplateType(PrintFromType ? ToType : FromType), - OS(OS), - IsBold(false) { - } + : Context(Context), Policy(Context.getLangOpts()), ElideType(ElideType), + PrintTree(PrintTree), ShowColor(ShowColor), + // When printing a single type, the FromType is the one printed. + FromTemplateType(PrintFromType ? FromType : ToType), + ToTemplateType(PrintFromType ? ToType : FromType), OS(OS), + IsBold(false) {} /// DiffTemplate - Start the template type diffing. void DiffTemplate() { @@ -2180,7 +2154,7 @@ class TemplateDiff { return true; } }; // end class TemplateDiff -} // end anonymous namespace +} // end anonymous namespace /// FormatTemplateTypeDiff - A helper static function to start the template /// diff and return the properly formatted string. Returns true if the diff _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
