diff options
author | Douglas Gregor <dgregor@apple.com> | 2008-11-07 20:08:42 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2008-11-07 20:08:42 +0000 |
commit | 2f1bc5285ccd40f411af5f5993f013e27e74ab78 (patch) | |
tree | 13b6547acb399a89753f742a0595aea613cecc36 /lib/Parse/ParseDecl.cpp | |
parent | 9057a81efaf15c543aab1c5c8488e8a9ed2c0ff4 (diff) |
Parsing, ASTs, and semantic analysis for the declaration of conversion
functions in C++, e.g.,
struct X {
operator bool() const;
};
Note that these conversions don't actually do anything, since we don't
yet have the ability to use them for implicit or explicit conversions.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@58860 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/ParseDecl.cpp')
-rw-r--r-- | lib/Parse/ParseDecl.cpp | 32 |
1 files changed, 25 insertions, 7 deletions
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index d82658825a..58cc9e2c6b 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -1229,7 +1229,11 @@ void Parser::ParseDeclarator(Declarator &D) { ParseDeclaratorInternal(D); } -/// ParseDeclaratorInternal +/// ParseDeclaratorInternal - Parse a C or C++ declarator. If +/// PtrOperator is true, then this routine won't parse the final +/// direct-declarator; therefore, it effectively parses the C++ +/// ptr-operator production. +/// /// declarator: [C99 6.7.5] /// pointer[opt] direct-declarator /// [C++] '&' declarator [C++ 8p4, dcl.decl] @@ -1239,13 +1243,21 @@ void Parser::ParseDeclarator(Declarator &D) { /// '*' type-qualifier-list[opt] /// '*' type-qualifier-list[opt] pointer /// -void Parser::ParseDeclaratorInternal(Declarator &D) { +/// ptr-operator: +/// '*' cv-qualifier-seq[opt] +/// '&' +/// [GNU] '&' restrict[opt] attributes[opt] +/// '::'[opt] nested-name-specifier '*' cv-qualifier-seq[opt] [TODO] +void Parser::ParseDeclaratorInternal(Declarator &D, bool PtrOperator) { 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)) - return ParseDirectDeclarator(D); + (Kind != tok::caret || !getLang().Blocks)) { + if (!PtrOperator) + ParseDirectDeclarator(D); + return; + } // Otherwise, '*' -> pointer, '^' -> block, '&' -> reference. SourceLocation Loc = ConsumeToken(); // Eat the * or &. @@ -1257,7 +1269,7 @@ void Parser::ParseDeclaratorInternal(Declarator &D) { ParseTypeQualifierListOpt(DS); // Recursively parse the declarator. - ParseDeclaratorInternal(D); + ParseDeclaratorInternal(D, PtrOperator); if (Kind == tok::star) // Remember that we parsed a pointer type, and remember the type-quals. D.AddTypeInfo(DeclaratorChunk::getPointer(DS.getTypeQualifiers(), Loc, @@ -1290,7 +1302,7 @@ void Parser::ParseDeclaratorInternal(Declarator &D) { } // Recursively parse the declarator. - ParseDeclaratorInternal(D); + ParseDeclaratorInternal(D, PtrOperator); if (D.getNumTypeObjects() > 0) { // C++ [dcl.ref]p4: There shall be no references to references. @@ -1382,7 +1394,13 @@ void Parser::ParseDirectDeclarator(Declarator &D) { if (IdentifierInfo *II = MaybeParseOperatorFunctionId()) { D.SetIdentifier(II, OperatorLoc); } else { - // This must be a user-defined conversion. + // This must be a conversion function (C++ [class.conv.fct]). + if (TypeTy *ConvType = ParseConversionFunctionId()) { + IdentifierInfo *II + = &PP.getIdentifierTable().get(std::string("operator ") + + Actions.getTypeAsString(ConvType)); + D.SetConversionFunction(ConvType, II, OperatorLoc); + } } } else if (Tok.is(tok::l_paren)) { // direct-declarator: '(' declarator ')' |