diff options
Diffstat (limited to 'lib/Parse/ParseDecl.cpp')
-rw-r--r-- | lib/Parse/ParseDecl.cpp | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 243a15f3db..7a84171a05 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -383,7 +383,12 @@ void Parser::ParseSpecifierQualifierList(DeclSpec &DS) { // Issue diagnostic and remove function specfier if present. if (Specs & DeclSpec::PQ_FunctionSpecifier) { - Diag(DS.getInlineSpecLoc(), diag::err_typename_invalid_functionspec); + if (DS.isInlineSpecified()) + Diag(DS.getInlineSpecLoc(), diag::err_typename_invalid_functionspec); + if (DS.isVirtualSpecified()) + Diag(DS.getVirtualSpecLoc(), diag::err_typename_invalid_functionspec); + if (DS.isExplicitSpecified()) + Diag(DS.getExplicitSpecLoc(), diag::err_typename_invalid_functionspec); DS.ClearFunctionSpecs(); } } @@ -433,6 +438,8 @@ void Parser::ParseSpecifierQualifierList(DeclSpec &DS) { /// [C99] 'restrict' /// function-specifier: [C99 6.7.4] /// [C99] 'inline' +/// [C++] 'virtual' +/// [C++] 'explicit' /// void Parser::ParseDeclarationSpecifiers(DeclSpec &DS) { DS.SetRangeStart(Tok.getLocation()); @@ -462,6 +469,16 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS) { if (TypeRep == 0) goto DoneWithDeclSpec; + // C++: If the identifier is actually the name of the class type + // being defined and the next token is a '(', then this is a + // constructor declaration. We're done with the decl-specifiers + // and will treat this token as an identifier. + if (getLang().CPlusPlus && + CurScope->isCXXClassScope() && + Actions.isCurrentClassName(*Tok.getIdentifierInfo(), CurScope) && + NextToken().getKind() == tok::l_paren) + goto DoneWithDeclSpec; + isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typedef, Loc, PrevSpec, TypeRep); if (isInvalid) @@ -607,6 +624,14 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS) { case tok::kw_inline: isInvalid = DS.SetFunctionSpecInline(Loc, PrevSpec); break; + + case tok::kw_virtual: + isInvalid = DS.SetFunctionSpecVirtual(Loc, PrevSpec); + break; + + case tok::kw_explicit: + isInvalid = DS.SetFunctionSpecExplicit(Loc, PrevSpec); + break; case tok::less: // GCC ObjC supports types like "<SomeProtocol>" as a synonym for @@ -1056,6 +1081,8 @@ bool Parser::isDeclarationSpecifier() const { // function-specifier case tok::kw_inline: + case tok::kw_virtual: + case tok::kw_explicit: // GNU typeof support. case tok::kw_typeof: @@ -1217,7 +1244,11 @@ void Parser::ParseDeclaratorInternal(Declarator &D) { /// parameter-type-list[opt] ')' /// [C++] direct-declarator '(' parameter-declaration-clause ')' /// cv-qualifier-seq[opt] exception-specification[opt] -/// +/// [C++] declarator-id +// +// declarator-id: [C++ 8] +// id-expression +// '::'[opt] nested-name-specifier[opt] type-name void Parser::ParseDirectDeclarator(Declarator &D) { // Parse the first direct-declarator seen. if (Tok.is(tok::identifier) && D.mayHaveIdentifier()) { |