diff options
author | David Blaikie <dblaikie@gmail.com> | 2011-10-25 15:01:20 +0000 |
---|---|---|
committer | David Blaikie <dblaikie@gmail.com> | 2011-10-25 15:01:20 +0000 |
commit | 09048df0b3f472091b2204e531d6b6019244884b (patch) | |
tree | 6ecd7efd804ffae2d1cc411bf9be636589737cf7 /lib/Parse/ParseDeclCXX.cpp | |
parent | 327a50f46449c946c42d50d97689bcb30e2af7d9 (diff) |
Support the use of decltype for specifying base types. Fixes PR11216.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@142926 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/ParseDeclCXX.cpp')
-rw-r--r-- | lib/Parse/ParseDeclCXX.cpp | 38 |
1 files changed, 27 insertions, 11 deletions
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index 3d3d7c21cb..9d2db2ae1c 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -696,18 +696,23 @@ void Parser::ParseUnderlyingTypeSpecifier(DeclSpec &DS) { Diag(StartLoc, DiagID) << PrevSpec; } -/// ParseClassName - Parse a C++ class-name, which names a class. Note -/// that we only check that the result names a type; semantic analysis -/// will need to verify that the type names a class. The result is -/// either a type or NULL, depending on whether a type name was -/// found. -/// +/// ParseBaseTypeSpecifier - Parse a C++ base-type-specifier which is either a +/// class name or decltype-specifier. Note that we only check that the result +/// names a type; semantic analysis will need to verify that the type names a +/// class. The result is either a type or null, depending on whether a type +/// name was found. +/// +/// base-type-specifier: [C++ 10.1] +/// class-or-decltype +/// class-or-decltype: [C++ 10.1] +/// nested-name-specifier[opt] class-name +/// decltype-specifier /// class-name: [C++ 9.1] /// identifier /// simple-template-id /// -Parser::TypeResult Parser::ParseClassName(SourceLocation &EndLocation, - CXXScopeSpec &SS) { +Parser::TypeResult Parser::ParseBaseTypeSpecifier(SourceLocation &EndLocation, + CXXScopeSpec &SS) { // Check whether we have a template-id that names a type. if (Tok.is(tok::annot_template_id)) { TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok); @@ -728,6 +733,17 @@ Parser::TypeResult Parser::ParseClassName(SourceLocation &EndLocation, // Fall through to produce an error below. } + if (Tok.is(tok::kw_decltype)) { + // Fake up a Declarator to use with ActOnTypeName. + DeclSpec DS(AttrFactory); + + ParseDecltypeSpecifier(DS); + EndLocation = DS.getSourceRange().getEnd(); + + Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); + return Actions.ActOnTypeName(getCurScope(), DeclaratorInfo); + } + if (Tok.isNot(tok::identifier)) { Diag(Tok, diag::err_expected_class_name); return true; @@ -1363,9 +1379,9 @@ void Parser::ParseBaseClause(Decl *ClassDecl) { /// base-specifier: [C++ class.derived] /// ::[opt] nested-name-specifier[opt] class-name /// 'virtual' access-specifier[opt] ::[opt] nested-name-specifier[opt] -/// class-name +/// base-type-specifier /// access-specifier 'virtual'[opt] ::[opt] nested-name-specifier[opt] -/// class-name +/// base-type-specifier Parser::BaseResult Parser::ParseBaseSpecifier(Decl *ClassDecl) { bool IsVirtual = false; SourceLocation StartLoc = Tok.getLocation(); @@ -1403,7 +1419,7 @@ Parser::BaseResult Parser::ParseBaseSpecifier(Decl *ClassDecl) { // Parse the class-name. SourceLocation EndLocation; - TypeResult BaseType = ParseClassName(EndLocation, SS); + TypeResult BaseType = ParseBaseTypeSpecifier(EndLocation, SS); if (BaseType.isInvalid()) return true; |