diff options
author | Sebastian Redl <sebastian.redl@getdesigned.at> | 2009-01-24 21:16:55 +0000 |
---|---|---|
committer | Sebastian Redl <sebastian.redl@getdesigned.at> | 2009-01-24 21:16:55 +0000 |
commit | f30208ad5b334e93582e846a2a0c92f38a607b8a (patch) | |
tree | 1fba65ee5418c5bcb3eeb1265aae50cffd6474f4 /lib/Parse/ParseDecl.cpp | |
parent | 91daf4da934e10dcbf22697d59e2791420b1507a (diff) |
Add support for declaring pointers to members.
Add serialization support for ReferenceType.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@62934 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/ParseDecl.cpp')
-rw-r--r-- | lib/Parse/ParseDecl.cpp | 52 |
1 files changed, 42 insertions, 10 deletions
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 7f5c0988ed..0ac9e08982 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -1550,10 +1550,10 @@ void Parser::ParseDeclarator(Declarator &D) { /// isn't parsed at all, making this function effectively parse the C++ /// ptr-operator production. /// -/// declarator: [C99 6.7.5] -/// pointer[opt] direct-declarator -/// [C++] '&' declarator [C++ 8p4, dcl.decl] -/// [GNU] '&' restrict[opt] attributes[opt] declarator +/// declarator: [C99 6.7.5] [C++ 8p4, dcl.decl] +/// [C] pointer[opt] direct-declarator +/// [C++] direct-declarator +/// [C++] ptr-operator declarator /// /// pointer: [C99 6.7.5] /// '*' type-qualifier-list[opt] @@ -1563,11 +1563,41 @@ void Parser::ParseDeclarator(Declarator &D) { /// '*' cv-qualifier-seq[opt] /// '&' /// [GNU] '&' restrict[opt] attributes[opt] -/// '::'[opt] nested-name-specifier '*' cv-qualifier-seq[opt] [TODO] +/// '::'[opt] nested-name-specifier '*' cv-qualifier-seq[opt] void Parser::ParseDeclaratorInternal(Declarator &D, DirectDeclParseFunction DirectDeclParser) { - tok::TokenKind Kind = Tok.getKind(); + // C++ member pointers start with a '::' or a nested-name. + // Member pointers get special handling, since there's no place for the + // scope spec in the generic path below. + if ((Tok.is(tok::coloncolon) || Tok.is(tok::identifier) || + Tok.is(tok::annot_cxxscope)) && getLang().CPlusPlus) { + CXXScopeSpec SS; + if (ParseOptionalCXXScopeSpecifier(SS)) { + if(Tok.isNot(tok::star)) { + // The scope spec really belongs to the direct-declarator. + D.getCXXScopeSpec() = SS; + if (DirectDeclParser) + (this->*DirectDeclParser)(D); + return; + } + + SourceLocation Loc = ConsumeToken(); + DeclSpec DS; + ParseTypeQualifierListOpt(DS); + + // Recurse to parse whatever is left. + ParseDeclaratorInternal(D, DirectDeclParser); + + // Sema will have to catch (syntactically invalid) pointers into global + // scope. It has to catch pointers into namespace scope anyway. + D.AddTypeInfo(DeclaratorChunk::getMemberPointer(SS,DS.getTypeQualifiers(), + Loc,DS.TakeAttributes())); + return; + } + } + + tok::TokenKind Kind = Tok.getKind(); // Not a pointer, C++ reference, or block. if (Kind != tok::star && (Kind != tok::amp || !getLang().CPlusPlus) && (Kind != tok::caret || !getLang().Blocks)) { @@ -1575,16 +1605,16 @@ void Parser::ParseDeclaratorInternal(Declarator &D, (this->*DirectDeclParser)(D); return; } - + // Otherwise, '*' -> pointer, '^' -> block, '&' -> reference. SourceLocation Loc = ConsumeToken(); // Eat the * or &. if (Kind == tok::star || (Kind == tok::caret && getLang().Blocks)) { // Is a pointer. DeclSpec DS; - + ParseTypeQualifierListOpt(DS); - + // Recursively parse the declarator. ParseDeclaratorInternal(D, DirectDeclParser); if (Kind == tok::star) @@ -1680,7 +1710,9 @@ void Parser::ParseDirectDeclarator(Declarator &D) { if (getLang().CPlusPlus) { if (D.mayHaveIdentifier()) { - bool afterCXXScope = ParseOptionalCXXScopeSpecifier(D.getCXXScopeSpec()); + // ParseDeclaratorInternal might already have parsed the scope. + bool afterCXXScope = D.getCXXScopeSpec().isSet() || + ParseOptionalCXXScopeSpecifier(D.getCXXScopeSpec()); if (afterCXXScope) { // Change the declaration context for name lookup, until this function // is exited (and the declarator has been parsed). |