aboutsummaryrefslogtreecommitdiff
path: root/lib/Parse/ParseDecl.cpp
diff options
context:
space:
mode:
authorSebastian Redl <sebastian.redl@getdesigned.at>2009-01-24 21:16:55 +0000
committerSebastian Redl <sebastian.redl@getdesigned.at>2009-01-24 21:16:55 +0000
commitf30208ad5b334e93582e846a2a0c92f38a607b8a (patch)
tree1fba65ee5418c5bcb3eeb1265aae50cffd6474f4 /lib/Parse/ParseDecl.cpp
parent91daf4da934e10dcbf22697d59e2791420b1507a (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.cpp52
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).