From 14f78f4a11df4c06667e2cbb87eeb179e4cb46fe Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Sat, 4 May 2013 01:26:46 +0000 Subject: [PATCH] Separate out and special-case the diagnostic for 'auto' in a conversion-type-id, in preparation for this becoming valid in c++1y mode. No functionality change; small diagnostic improvement. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@181089 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticSemaKinds.td | 2 +- include/clang/Sema/DeclSpec.h | 7 ++++++- lib/Parse/ParseExprCXX.cpp | 2 +- lib/Sema/SemaType.cpp | 21 +++++++++++++------ .../dcl.spec/dcl.type/dcl.spec.auto/p2.cpp | 2 +- .../dcl.spec/dcl.type/dcl.spec.auto/p5.cpp | 2 +- 6 files changed, 25 insertions(+), 11 deletions(-) diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index bfbbb91be9..f43a7d1338 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -1428,7 +1428,7 @@ def err_auto_not_allowed : Error< "|in non-static union member|in non-static class member|in interface member" "|in exception declaration|in template parameter|in block literal" "|in template argument|in typedef|in type alias|in function return type" - "|here}0">; + "|in conversion function type|here}0">; def err_auto_var_requires_init : Error< "declaration of variable %0 with type %1 requires an initializer">; def err_auto_new_requires_ctor_arg : Error< diff --git a/include/clang/Sema/DeclSpec.h b/include/clang/Sema/DeclSpec.h index 1c0a8e4d11..fc818953d8 100644 --- a/include/clang/Sema/DeclSpec.h +++ b/include/clang/Sema/DeclSpec.h @@ -1503,8 +1503,9 @@ public: CXXNewContext, // C++ new-expression. CXXCatchContext, // C++ catch exception-declaration ObjCCatchContext, // Objective-C catch exception-declaration - BlockLiteralContext, // Block literal declarator. + BlockLiteralContext, // Block literal declarator. LambdaExprContext, // Lambda-expression declarator. + ConversionIdContext, // C++ conversion-type-id. TrailingReturnContext, // C++11 trailing-type-specifier. TemplateTypeArgContext, // Template type argument. AliasDeclContext, // C++11 alias-declaration. @@ -1680,6 +1681,7 @@ public: case ObjCCatchContext: case BlockLiteralContext: case LambdaExprContext: + case ConversionIdContext: case TemplateTypeArgContext: case TrailingReturnContext: return true; @@ -1712,6 +1714,7 @@ public: case ObjCResultContext: case BlockLiteralContext: case LambdaExprContext: + case ConversionIdContext: case TemplateTypeArgContext: case TrailingReturnContext: return false; @@ -1761,6 +1764,7 @@ public: case AliasTemplateContext: case BlockLiteralContext: case LambdaExprContext: + case ConversionIdContext: case TemplateTypeArgContext: case TrailingReturnContext: return false; @@ -1943,6 +1947,7 @@ public: case ObjCCatchContext: case BlockLiteralContext: case LambdaExprContext: + case ConversionIdContext: case TemplateTypeArgContext: case TrailingReturnContext: return false; diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp index 181deb6cfc..f259d5f59b 100644 --- a/lib/Parse/ParseExprCXX.cpp +++ b/lib/Parse/ParseExprCXX.cpp @@ -2035,7 +2035,7 @@ bool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext, // Parse the conversion-declarator, which is merely a sequence of // ptr-operators. - Declarator D(DS, Declarator::TypeNameContext); + Declarator D(DS, Declarator::ConversionIdContext); ParseDeclaratorInternal(D, /*DirectDeclParser=*/0); // Finish up the type. diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index 2503b49a61..4bf15f0360 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -2103,8 +2103,11 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state, case Declarator::TrailingReturnContext: Error = 11; // Function return type break; + case Declarator::ConversionIdContext: + Error = 12; // conversion-type-id + break; case Declarator::TypeNameContext: - Error = 12; // Generic + Error = 13; // Generic break; case Declarator::FileContext: case Declarator::BlockContext: @@ -2140,15 +2143,19 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state, } } + SourceRange AutoRange = D.getDeclSpec().getTypeSpecTypeLoc(); + if (D.getName().getKind() == UnqualifiedId::IK_ConversionFunctionId) + AutoRange = D.getName().getSourceRange(); + if (Error != -1) { - SemaRef.Diag(D.getDeclSpec().getTypeSpecTypeLoc(), - diag::err_auto_not_allowed) - << Error; + SemaRef.Diag(AutoRange.getBegin(), diag::err_auto_not_allowed) + << Error << AutoRange; T = SemaRef.Context.IntTy; D.setInvalidType(true); } else - SemaRef.Diag(D.getDeclSpec().getTypeSpecTypeLoc(), - diag::warn_cxx98_compat_auto_type_specifier); + SemaRef.Diag(AutoRange.getBegin(), + diag::warn_cxx98_compat_auto_type_specifier) + << AutoRange; } if (SemaRef.getLangOpts().CPlusPlus && @@ -2180,6 +2187,7 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state, D.setInvalidType(true); break; case Declarator::TypeNameContext: + case Declarator::ConversionIdContext: case Declarator::TemplateParamContext: case Declarator::CXXNewContext: case Declarator::CXXCatchContext: @@ -3092,6 +3100,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, case Declarator::ObjCCatchContext: case Declarator::BlockLiteralContext: case Declarator::LambdaExprContext: + case Declarator::ConversionIdContext: case Declarator::TrailingReturnContext: case Declarator::TemplateTypeArgContext: // FIXME: We may want to allow parameter packs in block-literal contexts diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p2.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p2.cpp index a385aa9132..83b12d4b25 100644 --- a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p2.cpp +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p2.cpp @@ -7,7 +7,7 @@ struct S { // Note, this is not permitted: conversion-declarator cannot have a trailing return type. // FIXME: don't issue the second diagnostic for this. - operator auto(*)()->int(); // expected-error{{'auto' not allowed here}} expected-error {{C++ requires a type specifier}} + operator auto(*)()->int(); // expected-error{{'auto' not allowed in conversion function type}} expected-error {{C++ requires a type specifier}} }; typedef auto Fun(int a) -> decltype(a + a); diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp index 7499829185..0cdf3c6e05 100644 --- a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp @@ -11,7 +11,7 @@ struct S { friend auto; // expected-error{{'auto' not allowed in non-static struct member}} - operator auto(); // expected-error{{'auto' not allowed here}} + operator auto(); // expected-error{{'auto' not allowed in conversion function type}} }; // PR 9278: auto is not allowed in typedefs, except with a trailing return type. -- 2.40.0