diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Parse/DeclSpec.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 11 | ||||
-rw-r--r-- | clang/lib/Parse/ParseExpr.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Sema/SemaType.cpp | 14 |
5 files changed, 22 insertions, 11 deletions
diff --git a/clang/lib/Parse/DeclSpec.cpp b/clang/lib/Parse/DeclSpec.cpp index f3ff0c63797..d8c6986f9ea 100644 --- a/clang/lib/Parse/DeclSpec.cpp +++ b/clang/lib/Parse/DeclSpec.cpp @@ -33,6 +33,7 @@ DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, bool isVariadic, unsigned NumArgs, unsigned TypeQuals, bool hasExceptionSpec, + SourceLocation ThrowLoc, bool hasAnyExceptionSpec, ActionBase::TypeTy **Exceptions, SourceRange *ExceptionRanges, @@ -50,6 +51,7 @@ DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, bool isVariadic, I.Fun.NumArgs = NumArgs; I.Fun.ArgInfo = 0; I.Fun.hasExceptionSpec = hasExceptionSpec; + I.Fun.ThrowLoc = ThrowLoc.getRawEncoding(); I.Fun.hasAnyExceptionSpec = hasAnyExceptionSpec; I.Fun.NumExceptions = NumExceptions; I.Fun.Exceptions = 0; diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 4fc713c8853..39eaf36c957 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -2274,6 +2274,7 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D, // cv-qualifier-seq[opt]. DeclSpec DS; bool hasExceptionSpec = false; + SourceLocation ThrowLoc; bool hasAnyExceptionSpec = false; llvm::SmallVector<TypeTy*, 2> Exceptions; llvm::SmallVector<SourceRange, 2> ExceptionRanges; @@ -2285,6 +2286,7 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D, // Parse exception-specification[opt]. if (Tok.is(tok::kw_throw)) { hasExceptionSpec = true; + ThrowLoc = Tok.getLocation(); ParseExceptionSpecification(Loc, Exceptions, ExceptionRanges, hasAnyExceptionSpec); assert(Exceptions.size() == ExceptionRanges.size() && @@ -2299,7 +2301,7 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D, SourceLocation(), /*arglist*/ 0, 0, DS.getTypeQualifiers(), - hasExceptionSpec, + hasExceptionSpec, ThrowLoc, hasAnyExceptionSpec, Exceptions.data(), ExceptionRanges.data(), @@ -2448,6 +2450,7 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D, DeclSpec DS; bool hasExceptionSpec = false; + SourceLocation ThrowLoc; bool hasAnyExceptionSpec = false; llvm::SmallVector<TypeTy*, 2> Exceptions; llvm::SmallVector<SourceRange, 2> ExceptionRanges; @@ -2460,6 +2463,7 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D, // Parse exception-specification[opt]. if (Tok.is(tok::kw_throw)) { hasExceptionSpec = true; + ThrowLoc = Tok.getLocation(); ParseExceptionSpecification(Loc, Exceptions, ExceptionRanges, hasAnyExceptionSpec); assert(Exceptions.size() == ExceptionRanges.size() && @@ -2472,7 +2476,7 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D, EllipsisLoc, ParamInfo.data(), ParamInfo.size(), DS.getTypeQualifiers(), - hasExceptionSpec, + hasExceptionSpec, ThrowLoc, hasAnyExceptionSpec, Exceptions.data(), ExceptionRanges.data(), @@ -2551,7 +2555,8 @@ void Parser::ParseFunctionDeclaratorIdentifierList(SourceLocation LParenLoc, SourceLocation(), &ParamInfo[0], ParamInfo.size(), /*TypeQuals*/0, - /*exception*/false, false, 0, 0, 0, + /*exception*/false, + SourceLocation(), false, 0, 0, 0, LParenLoc, D), RLoc); } diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index 8b8d4e19249..cd62c64276b 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -1481,7 +1481,8 @@ Parser::OwningExprResult Parser::ParseBlockLiteralExpression() { ParamInfo.AddTypeInfo(DeclaratorChunk::getFunction(true, false, SourceLocation(), 0, 0, 0, - false, false, 0, 0, 0, + false, SourceLocation(), + false, 0, 0, 0, CaretLoc, ParamInfo), CaretLoc); diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 09ec071bb1b..9c650e61e7c 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -3164,7 +3164,8 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc, assert(!Error && "Error setting up implicit decl!"); Declarator D(DS, Declarator::BlockContext); D.AddTypeInfo(DeclaratorChunk::getFunction(false, false, SourceLocation(), 0, - 0, 0, false, false, 0,0,0, Loc, D), + 0, 0, false, SourceLocation(), + false, 0,0,0, Loc, D), SourceLocation()); D.SetIdentifier(&II, Loc); diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 833620b5cfb..81ac21123e9 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -737,7 +737,7 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, unsigned Skip, // does not have a K&R-style identifier list), then the arguments are part // of the type, otherwise the argument list is (). const DeclaratorChunk::FunctionTypeInfo &FTI = DeclType.Fun; - + // C99 6.7.5.3p1: The return type may not be a function or array type. if (T->isArrayType() || T->isFunctionType()) { Diag(DeclType.Loc, diag::err_func_returning_array_function) << T; @@ -754,6 +754,12 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, unsigned Skip, << Context.getTypeDeclType(Tag); } + // Exception specs are not allowed in typedefs. Complain, but add it + // anyway. + if (FTI.hasExceptionSpec && + D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef) + Diag(FTI.getThrowLoc(), diag::err_exception_spec_in_typedef); + if (FTI.NumArgs == 0) { if (getLangOptions().CPlusPlus) { // C++ 8.3.5p2: If the parameter-declaration-clause is empty, the @@ -978,17 +984,13 @@ bool Sema::CheckSpecifiedExceptionType(QualType T, const SourceRange &Range) { // C++ 15.4p2: A type denoted in an exception-specification shall not denote // an incomplete type a pointer or reference to an incomplete type, other // than (cv) void*. - // The standard does not mention member pointers, but it has to mean them too. int kind; if (const PointerType* IT = T->getAsPointerType()) { T = IT->getPointeeType(); kind = 1; - } else if (const MemberPointerType* IT = T->getAsMemberPointerType()) { - T = IT->getPointeeType(); - kind = 2; } else if (const ReferenceType* IT = T->getAsReferenceType()) { T = IT->getPointeeType(); - kind = 3; + kind = 2; } else return false; |