diff options
Diffstat (limited to 'lib/Parse/ParseDecl.cpp')
| -rw-r--r-- | lib/Parse/ParseDecl.cpp | 60 | 
1 files changed, 55 insertions, 5 deletions
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 426f56f4380e5..ff602e8ba79b0 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -149,13 +149,35 @@ AttributeList *Parser::ParseAttributes(SourceLocation *EndLoc) {              }            }          } else { // not an identifier +          switch (Tok.getKind()) { +          case tok::r_paren:            // parse a possibly empty comma separated list of expressions -          if (Tok.is(tok::r_paren)) {               // __attribute__(( nonnull() ))              ConsumeParen(); // ignore the right paren loc for now              CurrAttr = new AttributeList(AttrName, AttrNameLoc,                                            0, SourceLocation(), 0, 0, CurrAttr); -          } else {  +            break; +          case tok::kw_char: +          case tok::kw_wchar_t: +          case tok::kw_bool: +          case tok::kw_short: +          case tok::kw_int: +          case tok::kw_long: +          case tok::kw_signed: +          case tok::kw_unsigned: +          case tok::kw_float: +          case tok::kw_double: +          case tok::kw_void: +          case tok::kw_typeof: +            // If it's a builtin type name, eat it and expect a rparen +            // __attribute__(( vec_type_hint(char) )) +            ConsumeToken(); +            CurrAttr = new AttributeList(AttrName, AttrNameLoc,  +                                         0, SourceLocation(), 0, 0, CurrAttr); +            if (Tok.is(tok::r_paren)) +              ConsumeParen(); +            break; +          default:              // __attribute__(( aligned(16) ))              ExprVector ArgExprs(Actions);              bool ArgExprsOk = true; @@ -181,6 +203,7 @@ AttributeList *Parser::ParseAttributes(SourceLocation *EndLoc) {                             SourceLocation(), ArgExprs.take(), ArgExprs.size(),                             CurrAttr);              } +            break;            }          }        } else { @@ -371,7 +394,8 @@ Parser::DeclGroupPtrTy Parser::ParseSimpleDeclaration(unsigned Context,  /// According to the standard grammar, =default and =delete are function  /// definitions, but that definitely doesn't fit with the parser here.  /// -Parser::DeclPtrTy Parser::ParseDeclarationAfterDeclarator(Declarator &D) { +Parser::DeclPtrTy Parser::ParseDeclarationAfterDeclarator(Declarator &D, +                                     const ParsedTemplateInfo &TemplateInfo) {    // If a simple-asm-expr is present, parse it.    if (Tok.is(tok::kw_asm)) {      SourceLocation Loc; @@ -393,7 +417,13 @@ Parser::DeclPtrTy Parser::ParseDeclarationAfterDeclarator(Declarator &D) {    }    // Inform the current actions module that we just parsed this declarator. -  DeclPtrTy ThisDecl = Actions.ActOnDeclarator(CurScope, D); +  DeclPtrTy ThisDecl = TemplateInfo.TemplateParams?  +      Actions.ActOnTemplateDeclarator(CurScope, +                             Action::MultiTemplateParamsArg(Actions, +                                          TemplateInfo.TemplateParams->data(), +                                          TemplateInfo.TemplateParams->size()), +                                    D) +    : Actions.ActOnDeclarator(CurScope, D);    // Parse declarator '=' initializer.    if (Tok.is(tok::equal)) { @@ -896,7 +926,10 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,        isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_static, Loc, PrevSpec);        break;      case tok::kw_auto: -      isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_auto, Loc, PrevSpec); +      if (getLang().CPlusPlus0x) +        isInvalid = DS.SetTypeSpecType(DeclSpec::TST_auto, Loc, PrevSpec); +      else +        isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_auto, Loc, PrevSpec);        break;      case tok::kw_register:        isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_register, Loc, PrevSpec); @@ -1018,6 +1051,10 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,        ParseTypeofSpecifier(DS);        continue; +    case tok::kw_decltype: +      ParseDecltypeSpecifier(DS); +      continue; +      case tok::less:        // GCC ObjC supports types like "<SomeProtocol>" as a synonym for        // "id<SomeProtocol>".  This is hopelessly old fashioned and dangerous, @@ -1095,6 +1132,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,  /// [GNU]   typeof-specifier  /// [OBJC]  class-name objc-protocol-refs[opt]    [TODO]  /// [OBJC]  typedef-name objc-protocol-refs[opt]  [TODO] +/// [C++0x] 'decltype' ( expression )  bool Parser::ParseOptionalTypeSpecifier(DeclSpec &DS, int& isInvalid,                                          const char *&PrevSpec,                                        const ParsedTemplateInfo &TemplateInfo) { @@ -1235,6 +1273,18 @@ bool Parser::ParseOptionalTypeSpecifier(DeclSpec &DS, int& isInvalid,      ParseTypeofSpecifier(DS);      return true; +  // C++0x decltype support. +  case tok::kw_decltype: +    ParseDecltypeSpecifier(DS); +    return true; +       +  // C++0x auto support. +  case tok::kw_auto: +    if (!getLang().CPlusPlus0x) +      return false; + +    isInvalid = DS.SetTypeSpecType(DeclSpec::TST_auto, Loc, PrevSpec); +    break;    case tok::kw___ptr64:    case tok::kw___w64:    case tok::kw___cdecl:  | 
