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/ParseExprCXX.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/ParseExprCXX.cpp')
-rw-r--r-- | lib/Parse/ParseExprCXX.cpp | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp index 3134ff87b6..5dc43ed34d 100644 --- a/lib/Parse/ParseExprCXX.cpp +++ b/lib/Parse/ParseExprCXX.cpp @@ -292,6 +292,32 @@ void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) { DS.Finish(Diags, PP.getSourceManager(), getLang()); } +/// ParseCXXTypeSpecifierSeq - Parse a C++ type-specifier-seq (C++ +/// [dcl.name]), which is a non-empty sequence of type-specifiers, +/// e.g., "const short int". Note that the DeclSpec is *not* finished +/// by parsing the type-specifier-seq, because these sequences are +/// typically followed by some form of declarator. Returns true and +/// emits diagnostics if this is not a type-specifier-seq, false +/// otherwise. +/// +/// type-specifier-seq: [C++ 8.1] +/// type-specifier type-specifier-seq[opt] +/// +bool Parser::ParseCXXTypeSpecifierSeq(DeclSpec &DS) { + DS.SetRangeStart(Tok.getLocation()); + const char *PrevSpec = 0; + int isInvalid = 0; + + // Parse one or more of the type specifiers. + if (!MaybeParseTypeSpecifier(DS, isInvalid, PrevSpec)) { + Diag(Tok.getLocation(), diag::err_operator_missing_type_specifier); + return true; + } + while (MaybeParseTypeSpecifier(DS, isInvalid, PrevSpec)); + + return false; +} + /// MaybeParseOperatorFunctionId - Attempts to parse a C++ overloaded /// operator name (C++ [over.oper]). If successful, returns the /// predefined identifier that corresponds to that overloaded @@ -365,3 +391,38 @@ IdentifierInfo *Parser::MaybeParseOperatorFunctionId() { return &PP.getIdentifierTable().getOverloadedOperator(Op); } } + +/// ParseConversionFunctionId - Parse a C++ conversion-function-id, +/// which expresses the name of a user-defined conversion operator +/// (C++ [class.conv.fct]p1). Returns the type that this operator is +/// specifying a conversion for, or NULL if there was an error. +/// +/// conversion-function-id: [C++ 12.3.2] +/// operator conversion-type-id +/// +/// conversion-type-id: +/// type-specifier-seq conversion-declarator[opt] +/// +/// conversion-declarator: +/// ptr-operator conversion-declarator[opt] +Parser::TypeTy *Parser::ParseConversionFunctionId() { + assert(Tok.is(tok::kw_operator) && "Expected 'operator' keyword"); + ConsumeToken(); // 'operator' + + // Parse the type-specifier-seq. + DeclSpec DS; + if (ParseCXXTypeSpecifierSeq(DS)) + return 0; + + // Parse the conversion-declarator, which is merely a sequence of + // ptr-operators. + Declarator D(DS, Declarator::TypeNameContext); + ParseDeclaratorInternal(D, /*PtrOperator=*/true); + + // Finish up the type. + Action::TypeResult Result = Actions.ActOnTypeName(CurScope, D); + if (Result.isInvalid) + return 0; + else + return Result.Val; +} |