diff options
Diffstat (limited to 'clang/lib/Parse')
| -rw-r--r-- | clang/lib/Parse/DeclSpec.cpp | 34 | ||||
| -rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 37 | ||||
| -rw-r--r-- | clang/lib/Parse/ParseDeclCXX.cpp | 11 | ||||
| -rw-r--r-- | clang/lib/Parse/ParseExpr.cpp | 5 | 
4 files changed, 66 insertions, 21 deletions
| diff --git a/clang/lib/Parse/DeclSpec.cpp b/clang/lib/Parse/DeclSpec.cpp index bcf14d916cb..d742ef2ed09 100644 --- a/clang/lib/Parse/DeclSpec.cpp +++ b/clang/lib/Parse/DeclSpec.cpp @@ -32,19 +32,27 @@ DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, bool isVariadic,                                               ParamInfo *ArgInfo,                                               unsigned NumArgs,                                               unsigned TypeQuals, +                                             bool hasExceptionSpec, +                                             bool hasAnyExceptionSpec, +                                             ActionBase::TypeTy **Exceptions, +                                             unsigned NumExceptions,                                               SourceLocation Loc,                                               Declarator &TheDeclarator) {    DeclaratorChunk I; -  I.Kind             = Function; -  I.Loc              = Loc; -  I.Fun.hasPrototype = hasProto; -  I.Fun.isVariadic   = isVariadic; -  I.Fun.EllipsisLoc  = EllipsisLoc.getRawEncoding(); -  I.Fun.DeleteArgInfo = false; -  I.Fun.TypeQuals    = TypeQuals; -  I.Fun.NumArgs      = NumArgs; -  I.Fun.ArgInfo      = 0; -   +  I.Kind                 = Function; +  I.Loc                  = Loc; +  I.Fun.hasPrototype     = hasProto; +  I.Fun.isVariadic       = isVariadic; +  I.Fun.EllipsisLoc      = EllipsisLoc.getRawEncoding(); +  I.Fun.DeleteArgInfo    = false; +  I.Fun.TypeQuals        = TypeQuals; +  I.Fun.NumArgs          = NumArgs; +  I.Fun.ArgInfo          = 0; +  I.Fun.hasExceptionSpec = hasExceptionSpec; +  I.Fun.hasAnyExceptionSpec = hasAnyExceptionSpec; +  I.Fun.NumExceptions    = NumExceptions; +  I.Fun.Exceptions       = 0; +    // new[] an argument array if needed.    if (NumArgs) {      // If the 'InlineParams' in Declarator is unused and big enough, put our @@ -62,6 +70,12 @@ DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, bool isVariadic,      }      memcpy(I.Fun.ArgInfo, ArgInfo, sizeof(ArgInfo[0])*NumArgs);    } +  // new[] an exception array if needed +  if (NumExceptions) { +    I.Fun.Exceptions = new ActionBase::TypeTy*[NumExceptions]; +    memcpy(I.Fun.Exceptions, Exceptions, +           sizeof(ActionBase::TypeTy*)*NumExceptions); +  }    return I;  } diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index f02b8a06825..ec8923a23b2 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -2246,14 +2246,21 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,      // cv-qualifier-seq[opt].      DeclSpec DS; +    bool hasExceptionSpec = false; +    bool hasAnyExceptionSpec = false; +    // FIXME: Does an empty vector ever allocate? Exception specifications are +    // extremely rare, so we want something like a SmallVector<TypeTy*, 0>. :-) +    std::vector<TypeTy*> Exceptions;      if (getLang().CPlusPlus) {        ParseTypeQualifierListOpt(DS, false /*no attributes*/);        if (!DS.getSourceRange().getEnd().isInvalid())          Loc = DS.getSourceRange().getEnd();        // Parse exception-specification[opt]. -      if (Tok.is(tok::kw_throw)) -        ParseExceptionSpecification(Loc); +      if (Tok.is(tok::kw_throw)) { +        hasExceptionSpec = true; +        ParseExceptionSpecification(Loc, Exceptions, hasAnyExceptionSpec); +      }      }      // Remember that we parsed a function type, and remember the attributes. @@ -2263,6 +2270,11 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,                                                 SourceLocation(),                                                 /*arglist*/ 0, 0,                                                 DS.getTypeQualifiers(), +                                               hasExceptionSpec, +                                               hasAnyExceptionSpec, +                                               Exceptions.empty() ? 0 : +                                                 &Exceptions[0], +                                               Exceptions.size(),                                                 LParenLoc, D),                    Loc);      return; @@ -2406,6 +2418,11 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,    SourceLocation Loc = MatchRHSPunctuation(tok::r_paren, LParenLoc);    DeclSpec DS; +  bool hasExceptionSpec = false; +  bool hasAnyExceptionSpec = false; +  // FIXME: Does an empty vector ever allocate? Exception specifications are +  // extremely rare, so we want something like a SmallVector<TypeTy*, 0>. :-) +  std::vector<TypeTy*> Exceptions;    if (getLang().CPlusPlus) {      // Parse cv-qualifier-seq[opt].      ParseTypeQualifierListOpt(DS, false /*no attributes*/); @@ -2413,8 +2430,10 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,          Loc = DS.getSourceRange().getEnd();      // Parse exception-specification[opt]. -    if (Tok.is(tok::kw_throw)) -      ParseExceptionSpecification(Loc); +    if (Tok.is(tok::kw_throw)) { +      hasExceptionSpec = true; +      ParseExceptionSpecification(Loc, Exceptions, hasAnyExceptionSpec); +    }    }    // Remember that we parsed a function type, and remember the attributes. @@ -2422,7 +2441,11 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,                                               EllipsisLoc,                                               &ParamInfo[0], ParamInfo.size(),                                               DS.getTypeQualifiers(), -                                             LParenLoc, D), +                                             hasExceptionSpec, +                                             hasAnyExceptionSpec, +                                             Exceptions.empty() ? 0 : +                                               &Exceptions[0], +                                             Exceptions.size(), LParenLoc, D),                  Loc);  } @@ -2496,7 +2519,9 @@ void Parser::ParseFunctionDeclaratorIdentifierList(SourceLocation LParenLoc,    D.AddTypeInfo(DeclaratorChunk::getFunction(/*proto*/false, /*varargs*/false,                                               SourceLocation(),                                               &ParamInfo[0], ParamInfo.size(), -                                             /*TypeQuals*/0, LParenLoc, D), +                                             /*TypeQuals*/0, +                                             /*exception*/false, false, 0, 0, +                                             LParenLoc, D),                  RLoc);  } diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index c6a373dc5c4..f684649f858 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -1112,7 +1112,9 @@ Parser::MemInitResult Parser::ParseMemInitializer(DeclPtrTy ConstructorDecl) {  ///         type-id  ///         type-id-list ',' type-id  /// -bool Parser::ParseExceptionSpecification(SourceLocation &EndLoc) { +bool Parser::ParseExceptionSpecification(SourceLocation &EndLoc, +                                         std::vector<TypeTy*> &Exceptions, +                                         bool &hasAnyExceptionSpec) {    assert(Tok.is(tok::kw_throw) && "expected throw");    SourceLocation ThrowLoc = ConsumeToken(); @@ -1125,6 +1127,7 @@ bool Parser::ParseExceptionSpecification(SourceLocation &EndLoc) {    // Parse throw(...), a Microsoft extension that means "this function    // can throw anything".    if (Tok.is(tok::ellipsis)) { +    hasAnyExceptionSpec = true;      SourceLocation EllipsisLoc = ConsumeToken();      if (!getLang().Microsoft)        Diag(EllipsisLoc, diag::ext_ellipsis_exception_spec); @@ -1134,10 +1137,12 @@ bool Parser::ParseExceptionSpecification(SourceLocation &EndLoc) {    // Parse the sequence of type-ids.    while (Tok.isNot(tok::r_paren)) { -    ParseTypeName(); +    TypeResult Res(ParseTypeName()); +    if (!Res.isInvalid()) +      Exceptions.push_back(Res.get());      if (Tok.is(tok::comma))        ConsumeToken(); -    else  +    else        break;    } diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index 55bc1862f56..f299c5246ec 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -1353,8 +1353,9 @@ Parser::OwningExprResult Parser::ParseBlockLiteralExpression() {      // Otherwise, pretend we saw (void).      ParamInfo.AddTypeInfo(DeclaratorChunk::getFunction(true, false,                                                          SourceLocation(), -                                                       0, 0, 0, CaretLoc, -                                                       ParamInfo), +                                                       0, 0, 0, +                                                       false, false, 0, 0, +                                                       CaretLoc, ParamInfo),                            CaretLoc);      // Inform sema that we are starting a block.      Actions.ActOnBlockArguments(ParamInfo, CurScope); | 

