diff options
-rw-r--r-- | lib/AST/ASTDiagnostic.cpp | 98 | ||||
-rw-r--r-- | test/Misc/diag-template-diffing.cpp | 55 |
2 files changed, 102 insertions, 51 deletions
diff --git a/lib/AST/ASTDiagnostic.cpp b/lib/AST/ASTDiagnostic.cpp index b9c57ab2e9..419152de04 100644 --- a/lib/AST/ASTDiagnostic.cpp +++ b/lib/AST/ASTDiagnostic.cpp @@ -913,47 +913,11 @@ class TemplateDiff { ToIter.isEnd() && ToExpr); if ((FromExpr && FromExpr->getType()->isIntegerType()) || (ToExpr && ToExpr->getType()->isIntegerType())) { - HasFromInt = FromExpr; - HasToInt = ToExpr; - if (FromExpr) { - // Getting the integer value from the expression. - // Default, value-depenedent expressions require fetching - // from the desugared TemplateArgument - if (FromIter.isEnd() && FromExpr->isValueDependent()) - switch (FromIter.getDesugar().getKind()) { - case TemplateArgument::Integral: - FromInt = FromIter.getDesugar().getAsIntegral(); - break; - case TemplateArgument::Expression: - FromExpr = FromIter.getDesugar().getAsExpr(); - FromInt = FromExpr->EvaluateKnownConstInt(Context); - break; - default: - assert(0 && "Unexpected template argument kind"); - } - else - FromInt = FromExpr->EvaluateKnownConstInt(Context); - } - if (ToExpr) { - // Getting the integer value from the expression. - // Default, value-depenedent expressions require fetching - // from the desugared TemplateArgument - if (ToIter.isEnd() && ToExpr->isValueDependent()) - switch (ToIter.getDesugar().getKind()) { - case TemplateArgument::Integral: - ToInt = ToIter.getDesugar().getAsIntegral(); - break; - case TemplateArgument::Expression: - ToExpr = ToIter.getDesugar().getAsExpr(); - ToInt = ToExpr->EvaluateKnownConstInt(Context); - break; - default: - assert(0 && "Unexpected template argument kind"); - } - else - ToInt = ToExpr->EvaluateKnownConstInt(Context); - } - Tree.SetNode(FromInt, ToInt, HasFromInt, HasToInt); + if (FromExpr) + FromInt = GetInt(FromIter, FromExpr); + if (ToExpr) + ToInt = GetInt(ToIter, ToExpr); + Tree.SetNode(FromInt, ToInt, FromExpr, ToExpr); Tree.SetSame(IsSameConvertedInt(ParamWidth, FromInt, ToInt)); Tree.SetKind(DiffTree::Integer); } else { @@ -962,11 +926,11 @@ class TemplateDiff { } } else if (HasFromInt || HasToInt) { if (!HasFromInt && FromExpr) { - FromInt = FromExpr->EvaluateKnownConstInt(Context); + FromInt = GetInt(FromIter, FromExpr); HasFromInt = true; } if (!HasToInt && ToExpr) { - ToInt = ToExpr->EvaluateKnownConstInt(Context); + ToInt = GetInt(ToIter, ToExpr); HasToInt = true; } Tree.SetNode(FromInt, ToInt, HasFromInt, HasToInt); @@ -975,14 +939,10 @@ class TemplateDiff { ToIter.isEnd() && HasToInt); Tree.SetKind(DiffTree::Integer); } else { - if (!HasFromValueDecl && FromExpr) { - DeclRefExpr *DRE = cast<DeclRefExpr>(FromExpr); - FromValueDecl = cast<ValueDecl>(DRE->getDecl()); - } - if (!HasToValueDecl && ToExpr) { - DeclRefExpr *DRE = cast<DeclRefExpr>(ToExpr); - ToValueDecl = cast<ValueDecl>(DRE->getDecl()); - } + if (!HasFromValueDecl && FromExpr) + FromValueDecl = GetValueDecl(FromIter, FromExpr); + if (!HasToValueDecl && ToExpr) + ToValueDecl = GetValueDecl(ToIter, ToExpr); Tree.SetNode(FromValueDecl, ToValueDecl); Tree.SetSame(FromValueDecl->getCanonicalDecl() == ToValueDecl->getCanonicalDecl()); @@ -1101,6 +1061,42 @@ class TemplateDiff { ArgExpr = SNTTPE->getReplacement(); } + /// GetInt - Retrieves the template integer argument, including evaluating + /// default arguments. + llvm::APInt GetInt(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::Integral: + return Iter.getDesugar().getAsIntegral(); + case TemplateArgument::Expression: + ArgExpr = Iter.getDesugar().getAsExpr(); + return ArgExpr->EvaluateKnownConstInt(Context); + default: + assert(0 && "Unexpected template argument kind"); + } + return ArgExpr->EvaluateKnownConstInt(Context); + } + + /// GetValueDecl - Retrieves the template integer argument, including + /// default expression argument. + 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: + assert(0 && "Unexpected template argument kind"); + } + return cast<DeclRefExpr>(ArgExpr)->getDecl(); + } + /// GetTemplateDecl - Retrieves the template template arguments, including /// default arguments. void GetTemplateDecl(const TSTiterator &Iter, diff --git a/test/Misc/diag-template-diffing.cpp b/test/Misc/diag-template-diffing.cpp index 823bad2798..fd331139a8 100644 --- a/test/Misc/diag-template-diffing.cpp +++ b/test/Misc/diag-template-diffing.cpp @@ -903,6 +903,61 @@ namespace ValueDecl { } } +namespace DependentDefault { + template <typename> struct Trait { + enum { V = 40 }; + typedef int Ty; + static int I; + }; + int other; + + template <typename T, int = Trait<T>::V > struct A {}; + template <typename T, typename = Trait<T>::Ty > struct B {}; + template <typename T, int& = Trait<T>::I > struct C {}; + + void test() { + + A<int> a1; + A<char> a2; + A<int, 10> a3; + a1 = a2; + // CHECK-ELIDE-NOTREE: no viable overloaded '=' + // CHECK-ELIDE-NOTREE: no known conversion from 'A<char, [...]>' to 'A<int, [...]>' + a3 = a1; + // CHECK-ELIDE-NOTREE: no viable overloaded '=' + // CHECK-ELIDE-NOTREE: no known conversion from 'A<[...], (default) 40>' to 'A<[...], 10>' + a2 = a3; + // CHECK-ELIDE-NOTREE: no viable overloaded '=' + // CHECK-ELIDE-NOTREE: no known conversion from 'A<int, 10>' to 'A<char, 40>' + + B<int> b1; + B<char> b2; + B<int, char> b3; + b1 = b2; + // CHECK-ELIDE-NOTREE: no viable overloaded '=' + // CHECK-ELIDE-NOTREE: no known conversion from 'B<char, (default) Trait<T>::Ty>' to 'B<int, int>' + b3 = b1; + // CHECK-ELIDE-NOTREE: no viable overloaded '=' + // CHECK-ELIDE-NOTREE: no known conversion from 'B<[...], (default) Trait<T>::Ty>' to 'B<[...], char>' + b2 = b3; + // CHECK-ELIDE-NOTREE: no viable overloaded '=' + // CHECK-ELIDE-NOTREE: no known conversion from 'B<int, char>' to 'B<char, int>' + + C<int> c1; + C<char> c2; + C<int, other> c3; + c1 = c2; + // CHECK-ELIDE-NOTREE: no viable overloaded '=' + // CHECK-ELIDE-NOTREE: no known conversion from 'C<char, (default) I>' to 'C<int, I>' + c3 = c1; + // CHECK-ELIDE-NOTREE: no viable overloaded '=' + // CHECK-ELIDE-NOTREE: no known conversion from 'C<[...], (default) I>' to 'C<[...], other>' + c2 = c3; + // CHECK-ELIDE-NOTREE: no viable overloaded '=' + // CHECK-ELIDE-NOTREE: no known conversion from 'C<int, other>' to 'C<char, I>' + } +} + // CHECK-ELIDE-NOTREE: {{[0-9]*}} errors generated. // CHECK-NOELIDE-NOTREE: {{[0-9]*}} errors generated. // CHECK-ELIDE-TREE: {{[0-9]*}} errors generated. |