diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-03-26 01:15:19 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-03-26 01:15:19 +0000 |
commit | 2db075b1d3b16f0100fe06408dfb4ab7d50700a4 (patch) | |
tree | eb14674e7e49bbf59405881541c6518a9a0ddad4 /lib/Parse/ParseDeclCXX.cpp | |
parent | c2e935f28079862b212f6b2af3057a5f203dcbc0 (diff) |
Implement special-case name lookup for inheriting constructors: member
using-declarations with names which look constructor-like are interpreted as
constructor names.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@177957 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/ParseDeclCXX.cpp')
-rw-r--r-- | lib/Parse/ParseDeclCXX.cpp | 36 |
1 files changed, 26 insertions, 10 deletions
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index aa2c0f512a..d7f8e982aa 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -468,7 +468,10 @@ Decl *Parser::ParseUsingDeclaration(unsigned Context, } // Parse nested-name-specifier. - ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false); + IdentifierInfo *LastII = 0; + ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false, + /*MayBePseudoDtor=*/0, /*IsTypename=*/false, + /*LastII=*/&LastII); // Check nested-name specifier. if (SS.isInvalid()) { @@ -476,18 +479,31 @@ Decl *Parser::ParseUsingDeclaration(unsigned Context, return 0; } + SourceLocation TemplateKWLoc; + UnqualifiedId Name; + // Parse the unqualified-id. We allow parsing of both constructor and // destructor names and allow the action module to diagnose any semantic // errors. - SourceLocation TemplateKWLoc; - UnqualifiedId Name; - if (ParseUnqualifiedId(SS, - /*EnteringContext=*/false, - /*AllowDestructorName=*/true, - /*AllowConstructorName=*/true, - ParsedType(), - TemplateKWLoc, - Name)) { + // + // C++11 [class.qual]p2: + // [...] in a using-declaration that is a member-declaration, if the name + // specified after the nested-name-specifier is the same as the identifier + // or the simple-template-id's template-name in the last component of the + // nested-name-specifier, the name is [...] considered to name the + // constructor. + if (getLangOpts().CPlusPlus11 && Context == Declarator::MemberContext && + Tok.is(tok::identifier) && NextToken().is(tok::semi) && + SS.isNotEmpty() && LastII == Tok.getIdentifierInfo() && + !SS.getScopeRep()->getAsNamespace() && + !SS.getScopeRep()->getAsNamespaceAlias()) { + SourceLocation IdLoc = ConsumeToken(); + ParsedType Type = Actions.getInheritingConstructorName(SS, IdLoc, *LastII); + Name.setConstructorName(Type, IdLoc, IdLoc); + } else if (ParseUnqualifiedId(SS, /*EnteringContext=*/ false, + /*AllowDestructorName=*/ true, + /*AllowConstructorName=*/ true, ParsedType(), + TemplateKWLoc, Name)) { SkipUntil(tok::semi); return 0; } |