diff options
author | Douglas Gregor <dgregor@apple.com> | 2008-10-31 09:07:45 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2008-10-31 09:07:45 +0000 |
commit | b48fe3812047e84164925c8938ce82be0624c40c (patch) | |
tree | 8af13a860c7c055c80382ca3f0b1f9f2db7b7b23 /lib/Parse/ParseDecl.cpp | |
parent | e10b0f236bc8487445bc99b8d14bd40666b1998d (diff) |
Add support for parsing and representing C++ constructor declarations.
Notes:
- Constructors are never found by name lookup, so they'll never get
pushed into any scope. Instead, they are stored as an
OverloadedFunctionDecl in CXXRecordDecl for easy overloading.
- There's a new action isCurrentClassName that determines whether an
identifier is the name of the innermost class currently being defined;
we use this to identify the declarator-id grammar rule that refers to
a type-name.
- MinimalAction does *not* support parsing constructors.
- We now handle virtual and explicit function specifiers.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@58499 91177308-0d34-0410-b5e6-96231b3b80d8
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()) { |