diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -5346,11 +5346,11 @@ QualType ASTContext::getDecltypeType(Expr *e, QualType UnderlyingType) const { DecltypeType *dt; - // C++11 [temp.type]p2: - // If an expression e involves a template parameter, decltype(e) denotes a + // C++17 [temp.type]p2: + // If an expression e is type-dependent (17.6.2.2), decltype(e) denotes a // unique dependent type. Two such decltype-specifiers refer to the same - // type only if their expressions are equivalent (14.5.6.1). - if (e->isInstantiationDependent()) { + // type only if their expressions are equivalent (17.5.6.1). + if (e->isTypeDependent()) { llvm::FoldingSetNodeID ID; DependentDecltypeType::Profile(ID, *this, e); diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -3422,18 +3422,17 @@ } DecltypeType::DecltypeType(Expr *E, QualType underlyingType, QualType can) - // C++11 [temp.type]p2: "If an expression e involves a template parameter, - // decltype(e) denotes a unique dependent type." Hence a decltype type is - // type-dependent even if its expression is only instantiation-dependent. + // C++17 [temp.type]p2: "If an expression e is type-dependent, decltype(e) + // denotes a unique dependent type." : Type(Decltype, can, toTypeDependence(E->getDependence()) | - (E->isInstantiationDependent() ? TypeDependence::Dependent - : TypeDependence::None) | + (E->isTypeDependent() ? TypeDependence::Dependent + : TypeDependence::None) | (E->getType()->getDependence() & TypeDependence::VariablyModified)), E(E), UnderlyingType(underlyingType) {} -bool DecltypeType::isSugared() const { return !E->isInstantiationDependent(); } +bool DecltypeType::isSugared() const { return !E->isTypeDependent(); } QualType DecltypeType::desugar() const { if (isSugared()) diff --git a/clang/test/CodeGenCXX/mangle-exprs.cpp b/clang/test/CodeGenCXX/mangle-exprs.cpp --- a/clang/test/CodeGenCXX/mangle-exprs.cpp +++ b/clang/test/CodeGenCXX/mangle-exprs.cpp @@ -215,7 +215,7 @@ namespace test5 { template void a(decltype(noexcept(T()))) {} template void a(decltype(noexcept(int()))); - // CHECK: void @_ZN5test51aIiEEvDTnxcvT__EE( + // CHECK: void @_ZN5test51aIiEEvb } namespace test6 { diff --git a/clang/test/CodeGenCXX/mangle.cpp b/clang/test/CodeGenCXX/mangle.cpp --- a/clang/test/CodeGenCXX/mangle.cpp +++ b/clang/test/CodeGenCXX/mangle.cpp @@ -802,7 +802,7 @@ template void f(decltype(sizeof(decltype(T() + T())))) {} - // CHECK-LABEL: define weak_odr void @_ZN6test341fIiEEvDTstDTplcvT__EcvS1__EEE + // CHECK-LABEL: define weak_odr void @_ZN6test341fIiEEvm template void f(decltype(sizeof(1))); // Mangling for non-instantiation-dependent sizeof expressions. @@ -839,7 +839,7 @@ template void f1(decltype(sizeof(&T::template operator+))) {} - // CHECK-LABEL: define weak_odr void @_ZN6test352f1INS_1AEEEvDTszadsrT_onplIiEE + // CHECK-LABEL: define weak_odr void @_ZN6test352f1INS_1AEEEvm template void f1(__SIZE_TYPE__); } @@ -1116,14 +1116,14 @@ namespace test56 { struct A { A *operator->(); int n; } a; template void f(decltype(a->n + N)) {} - // CHECK-LABEL: @_ZN6test561fILi0EEEvDTplptL_ZNS_1aEE1nT_E + // CHECK-LABEL: @_ZN6test561fILi0EEEvi template void f<0>(int); } namespace test57 { struct X { template int f(); } x; template void f(decltype(x.f<0>() + N)) {} - // CHECK-LABEL: @_ZN6test571fILi0EEEvDTplcldtL_ZNS_1xEE1fIXLi0EEEET_E + // CHECK-LABEL: @_ZN6test571fILi0EEEvi template void f<0>(int); } diff --git a/clang/test/SemaCXX/invalid-template-base-specifier.cpp b/clang/test/SemaCXX/invalid-template-base-specifier.cpp --- a/clang/test/SemaCXX/invalid-template-base-specifier.cpp +++ b/clang/test/SemaCXX/invalid-template-base-specifier.cpp @@ -12,11 +12,12 @@ template using Alias = decltype(Foo(T())); // expected-error {{no matching function for call to 'Foo'}} template -struct Crash2 : decltype(Alias()) { // expected-note {{in instantiation of template type alias 'Alias' requested here}} +struct Crash2 : decltype(Alias()) { // expected-note {{in instantiation of template type alias 'Alias' requested here}} \ + expected-error {{base specifier must name a class}} Crash2(){}; }; -void test2() { Crash2(); } // expected-note {{in instantiation of template class 'Crash2' requested here}} +void test2() { Crash2(); } // expected-note2 {{in instantiation of template class 'Crash2' requested here}} template class Base {}; diff --git a/clang/test/SemaTemplate/dependent-expr.cpp b/clang/test/SemaTemplate/dependent-expr.cpp --- a/clang/test/SemaTemplate/dependent-expr.cpp +++ b/clang/test/SemaTemplate/dependent-expr.cpp @@ -129,7 +129,7 @@ template void f() { decltype(({})) x; // expected-error {{incomplete type}} } - template void f(); // expected-note {{instantiation of}} + template void f(); template auto g() { auto c = [](auto, int) -> decltype(({})) {};