Author: nwilson Date: Tue Aug 25 23:19:36 2015 New Revision: 246005 URL: http://llvm.org/viewvc/llvm-project?rev=246005&view=rev Log: Modify DeclaratorChuck::getFunction to be passed an Exception Specification SourceRange
Summary: - Store the exception specification range's begin and end SourceLocation in DeclaratorChuck::FunctionTypeInfo. These SourceLocations can be used in a FixItHint Range. - Add diagnostic; function concept having an exception specification. Reviewers: hubert.reinterpretcast, fraggamuffin, faisalv, aaron.ballman, rsmith Subscribers: cfe-commits Differential Revision: http://reviews.llvm.org/D11789 Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td cfe/trunk/include/clang/Sema/DeclSpec.h cfe/trunk/lib/Parse/ParseDecl.cpp cfe/trunk/lib/Parse/ParseExpr.cpp cfe/trunk/lib/Parse/ParseExprCXX.cpp cfe/trunk/lib/Sema/DeclSpec.cpp cfe/trunk/lib/Sema/SemaDecl.cpp cfe/trunk/lib/Sema/SemaType.cpp cfe/trunk/test/SemaCXX/cxx-concept-declaration.cpp Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=246005&r1=246004&r2=246005&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Aug 25 23:19:36 2015 @@ -1977,6 +1977,8 @@ def err_function_concept_not_defined : E "function concept declaration must be a definition">; def err_var_concept_not_initialized : Error< "variable concept declaration must be initialized">; +def err_function_concept_exception_spec : Error< + "function concept cannot have exception specification">; // C++11 char16_t/char32_t def warn_cxx98_compat_unicode_type : Warning< Modified: cfe/trunk/include/clang/Sema/DeclSpec.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/DeclSpec.h?rev=246005&r1=246004&r2=246005&view=diff ============================================================================== --- cfe/trunk/include/clang/Sema/DeclSpec.h (original) +++ cfe/trunk/include/clang/Sema/DeclSpec.h Tue Aug 25 23:19:36 2015 @@ -1255,8 +1255,11 @@ struct DeclaratorChunk { /// any. unsigned MutableLoc; - /// \brief The location of the keyword introducing the spec, if any. - unsigned ExceptionSpecLoc; + /// \brief The beginning location of the exception specification, if any. + unsigned ExceptionSpecLocBeg; + + /// \brief The end location of the exception specification, if any. + unsigned ExceptionSpecLocEnd; /// Params - This is a pointer to a new[]'d array of ParamInfo objects that /// describe the parameters specified by this function declarator. null if @@ -1323,8 +1326,16 @@ struct DeclaratorChunk { return SourceLocation::getFromRawEncoding(RParenLoc); } - SourceLocation getExceptionSpecLoc() const { - return SourceLocation::getFromRawEncoding(ExceptionSpecLoc); + SourceLocation getExceptionSpecLocBeg() const { + return SourceLocation::getFromRawEncoding(ExceptionSpecLocBeg); + } + + SourceLocation getExceptionSpecLocEnd() const { + return SourceLocation::getFromRawEncoding(ExceptionSpecLocEnd); + } + + SourceRange getExceptionSpecRange() const { + return SourceRange(getExceptionSpecLocBeg(), getExceptionSpecLocEnd()); } /// \brief Retrieve the location of the ref-qualifier, if any. @@ -1496,7 +1507,7 @@ struct DeclaratorChunk { SourceLocation RestrictQualifierLoc, SourceLocation MutableLoc, ExceptionSpecificationType ESpecType, - SourceLocation ESpecLoc, + SourceRange ESpecRange, ParsedType *Exceptions, SourceRange *ExceptionRanges, unsigned NumExceptions, Modified: cfe/trunk/lib/Parse/ParseDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=246005&r1=246004&r2=246005&view=diff ============================================================================== --- cfe/trunk/lib/Parse/ParseDecl.cpp (original) +++ cfe/trunk/lib/Parse/ParseDecl.cpp Tue Aug 25 23:19:36 2015 @@ -5620,7 +5620,7 @@ void Parser::ParseFunctionDeclarator(Dec VolatileQualifierLoc, RestrictQualifierLoc, /*MutableLoc=*/SourceLocation(), - ESpecType, ESpecRange.getBegin(), + ESpecType, ESpecRange, DynamicExceptions.data(), DynamicExceptionRanges.data(), DynamicExceptions.size(), Modified: cfe/trunk/lib/Parse/ParseExpr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExpr.cpp?rev=246005&r1=246004&r2=246005&view=diff ============================================================================== --- cfe/trunk/lib/Parse/ParseExpr.cpp (original) +++ cfe/trunk/lib/Parse/ParseExpr.cpp Tue Aug 25 23:19:36 2015 @@ -2768,7 +2768,7 @@ ExprResult Parser::ParseBlockLiteralExpr /*RestrictQualifierLoc=*/NoLoc, /*MutableLoc=*/NoLoc, EST_None, - /*ESpecLoc=*/NoLoc, + /*ESpecRange=*/SourceRange(), /*Exceptions=*/nullptr, /*ExceptionRanges=*/nullptr, /*NumExceptions=*/0, Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=246005&r1=246004&r2=246005&view=diff ============================================================================== --- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original) +++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Tue Aug 25 23:19:36 2015 @@ -1149,7 +1149,7 @@ ExprResult Parser::ParseLambdaExpression /*VolatileQualifierLoc=*/NoLoc, /*RestrictQualifierLoc=*/NoLoc, MutableLoc, - ESpecType, ESpecRange.getBegin(), + ESpecType, ESpecRange, DynamicExceptions.data(), DynamicExceptionRanges.data(), DynamicExceptions.size(), @@ -1217,7 +1217,7 @@ ExprResult Parser::ParseLambdaExpression /*RestrictQualifierLoc=*/NoLoc, MutableLoc, EST_None, - /*ESpecLoc=*/NoLoc, + /*ESpecRange=*/SourceRange(), /*Exceptions=*/nullptr, /*ExceptionRanges=*/nullptr, /*NumExceptions=*/0, Modified: cfe/trunk/lib/Sema/DeclSpec.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/DeclSpec.cpp?rev=246005&r1=246004&r2=246005&view=diff ============================================================================== --- cfe/trunk/lib/Sema/DeclSpec.cpp (original) +++ cfe/trunk/lib/Sema/DeclSpec.cpp Tue Aug 25 23:19:36 2015 @@ -177,7 +177,7 @@ DeclaratorChunk DeclaratorChunk::getFunc SourceLocation MutableLoc, ExceptionSpecificationType ESpecType, - SourceLocation ESpecLoc, + SourceRange ESpecRange, ParsedType *Exceptions, SourceRange *ExceptionRanges, unsigned NumExceptions, @@ -212,7 +212,8 @@ DeclaratorChunk DeclaratorChunk::getFunc I.Fun.RestrictQualifierLoc = RestrictQualifierLoc.getRawEncoding(); I.Fun.MutableLoc = MutableLoc.getRawEncoding(); I.Fun.ExceptionSpecType = ESpecType; - I.Fun.ExceptionSpecLoc = ESpecLoc.getRawEncoding(); + I.Fun.ExceptionSpecLocBeg = ESpecRange.getBegin().getRawEncoding(); + I.Fun.ExceptionSpecLocEnd = ESpecRange.getEnd().getRawEncoding(); I.Fun.NumExceptions = 0; I.Fun.Exceptions = nullptr; I.Fun.NoexceptExpr = nullptr; Modified: cfe/trunk/lib/Sema/SemaDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=246005&r1=246004&r2=246005&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) +++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue Aug 25 23:19:36 2015 @@ -7476,6 +7476,22 @@ Sema::ActOnFunctionDeclarator(Scope *S, NewFD->setInvalidDecl(); } + // C++ Concepts TS [dcl.spec.concept]p1: [...] A function concept shall + // have no exception-specification and is treated as if it were specified + // with noexcept(true) (15.4). [...] + if (const FunctionProtoType *FPT = R->getAs<FunctionProtoType>()) { + if (FPT->hasExceptionSpec()) { + SourceRange Range; + if (D.isFunctionDeclarator()) + Range = D.getFunctionTypeInfo().getExceptionSpecRange(); + Diag(NewFD->getLocation(), diag::err_function_concept_exception_spec) + << FixItHint::CreateRemoval(Range); + NewFD->setInvalidDecl(); + } else { + Context.adjustExceptionSpec(NewFD, EST_BasicNoexcept); + } + } + // C++ Concepts TS [dcl.spec.concept]p2: Every concept definition is // implicity defined to be a constexpr declaration (implicitly inline) NewFD->setImplicitlyInline(); @@ -11123,7 +11139,7 @@ NamedDecl *Sema::ImplicitlyDefineFunctio /*RestrictQualifierLoc=*/NoLoc, /*MutableLoc=*/NoLoc, EST_None, - /*ESpecLoc=*/NoLoc, + /*ESpecRange=*/SourceRange(), /*Exceptions=*/nullptr, /*ExceptionRanges=*/nullptr, /*NumExceptions=*/0, Modified: cfe/trunk/lib/Sema/SemaType.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=246005&r1=246004&r2=246005&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaType.cpp (original) +++ cfe/trunk/lib/Sema/SemaType.cpp Tue Aug 25 23:19:36 2015 @@ -700,7 +700,7 @@ static void maybeSynthesizeBlockSignatur /*VolatileQualifierLoc=*/NoLoc, /*RestrictQualifierLoc=*/NoLoc, /*MutableLoc=*/NoLoc, EST_None, - /*ESpecLoc=*/NoLoc, + /*ESpecRange=*/SourceRange(), /*Exceptions=*/nullptr, /*ExceptionRanges=*/nullptr, /*NumExceptions=*/0, @@ -3833,9 +3833,10 @@ static TypeSourceInfo *GetFullTypeForDec // Exception specs are not allowed in typedefs. Complain, but add it // anyway. if (IsTypedefName && FTI.getExceptionSpecType()) - S.Diag(FTI.getExceptionSpecLoc(), diag::err_exception_spec_in_typedef) - << (D.getContext() == Declarator::AliasDeclContext || - D.getContext() == Declarator::AliasTemplateContext); + S.Diag(FTI.getExceptionSpecLocBeg(), + diag::err_exception_spec_in_typedef) + << (D.getContext() == Declarator::AliasDeclContext || + D.getContext() == Declarator::AliasTemplateContext); // If we see "T var();" or "T var(T());" at block scope, it is probably // an attempt to initialize a variable, not a function declaration. Modified: cfe/trunk/test/SemaCXX/cxx-concept-declaration.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx-concept-declaration.cpp?rev=246005&r1=246004&r2=246005&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/cxx-concept-declaration.cpp (original) +++ cfe/trunk/test/SemaCXX/cxx-concept-declaration.cpp Tue Aug 25 23:19:36 2015 @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++14 -fconcepts-ts -x c++ -verify %s +// RUN: %clang_cc1 -std=c++14 -fconcepts-ts -fcxx-exceptions -x c++ -verify %s namespace A { template<typename T> concept bool C1() { return true; } @@ -6,6 +6,9 @@ namespace A { template<typename T> concept bool C2 = true; } +template<typename T> concept bool C3() { return (throw 0, true); } +static_assert(noexcept(C3<int>()), "function concept should be treated as if noexcept(true) specified"); + template<typename T> concept bool D1(); // expected-error {{function concept declaration must be a definition}} struct B { @@ -23,6 +26,9 @@ concept bool D5 = true; // expected-erro template<typename T> concept bool D6; // expected-error {{variable concept declaration must be initialized}} +template<typename T> +concept bool D7() throw(int) { return true; } // expected-error {{function concept cannot have exception specification}} + // Tag concept class CC1 {}; // expected-error {{'concept' can only appear on the definition of a function template or variable template}} concept struct CS1 {}; // expected-error {{'concept' can only appear on the definition of a function template or variable template}} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits