Index: include/clang/AST/Decl.h =================================================================== --- include/clang/AST/Decl.h +++ include/clang/AST/Decl.h @@ -3799,18 +3799,38 @@ static bool classofKind(Kind K) { return K == Empty; } }; + + +// Helper function that checks to see if the NamedDecl Node is am unnamed +// TypeDecl (such as a lambda, or anonymous union or struct etc.) and if so adds +// its type to the diagnostic instead of the Decl. + +template +void addNamedDeclOrItsTypeToDiagnostic(const DiagnosticTy &DT, + const NamedDecl *ND) { + if (ND && isa(ND) && !ND->getIdentifier()) { + extern QualType getTypeDeclTypeFromASTContext(const TypeDecl *T, + ASTContext &Ctx); + QualType Ty( + getTypeDeclTypeFromASTContext(cast(ND), ND->getASTContext())); + DT.AddTaggedVal(reinterpret_cast(Ty.getAsOpaquePtr()), + DiagnosticsEngine::ak_qualtype); + } else { + DT.AddTaggedVal(reinterpret_cast(ND), + DiagnosticsEngine::ak_nameddecl); + } +} + /// Insertion operator for diagnostics. This allows sending NamedDecl's /// into a diagnostic with <<. inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, const NamedDecl* ND) { - DB.AddTaggedVal(reinterpret_cast(ND), - DiagnosticsEngine::ak_nameddecl); + addNamedDeclOrItsTypeToDiagnostic(DB, ND); return DB; } inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD, const NamedDecl* ND) { - PD.AddTaggedVal(reinterpret_cast(ND), - DiagnosticsEngine::ak_nameddecl); + addNamedDeclOrItsTypeToDiagnostic(PD, ND); return PD; } Index: lib/AST/ASTContext.cpp =================================================================== --- lib/AST/ASTContext.cpp +++ lib/AST/ASTContext.cpp @@ -3276,7 +3276,12 @@ return QualType(Decl->TypeForDecl, 0); } - +namespace clang { + QualType getTypeDeclTypeFromASTContext(const TypeDecl *T, + ASTContext &Ctx) { + return Ctx.getTypeDeclType(T); + } +} /// getTypedefType - Return the unique reference to the type for the /// specified typedef name decl. QualType Index: test/SemaCXX/constant-expression-cxx11.cpp =================================================================== --- test/SemaCXX/constant-expression-cxx11.cpp +++ test/SemaCXX/constant-expression-cxx11.cpp @@ -1137,7 +1137,22 @@ return B().x == k; // expected-note {{non-literal type 'PR11595::B' cannot be used in a constant expression}} } } +namespace NonLiteralTypes { +auto L = [] { + return []{}; //expected-note{{lambda at}} +}; + +constexpr int f(decltype(L()) l) { return 0; } //expected-error{{not a literal type}} + +auto U = [] { + union { volatile int I; } obj; //expected-note{{anonymous union at}} + return obj; +}; +constexpr int f(decltype(U()) l) { return 0; } //expected-error{{not a literal type}} + +} + namespace ExprWithCleanups { struct A { A(); ~A(); int get(); }; constexpr int get(bool FromA) { return FromA ? A().get() : 1; }