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 {
}
} 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);
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());
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,
}
}
+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.