summaryrefslogtreecommitdiffstats
path: root/lib/Parse/ParseDeclCXX.cpp
diff options
context:
space:
mode:
authorDavid Blaikie <dblaikie@gmail.com>2011-10-25 15:01:20 +0000
committerDavid Blaikie <dblaikie@gmail.com>2011-10-25 15:01:20 +0000
commit09048df0b3f472091b2204e531d6b6019244884b (patch)
tree6ecd7efd804ffae2d1cc411bf9be636589737cf7 /lib/Parse/ParseDeclCXX.cpp
parent327a50f46449c946c42d50d97689bcb30e2af7d9 (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.cpp38
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;