diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2011-04-15 14:24:37 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2011-04-15 14:24:37 +0000 |
commit | 162e1c1b487352434552147967c3dd296ebee2f7 (patch) | |
tree | 997de42e97482fd054626d9433d6bf766f93b738 /lib/Parse/ParseDeclCXX.cpp | |
parent | 98a57868d696cb5faf6195a609ad084a711c6bbe (diff) |
Support for C++11 (non-template) alias declarations.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@129567 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/ParseDeclCXX.cpp')
-rw-r--r-- | lib/Parse/ParseDeclCXX.cpp | 54 |
1 files changed, 44 insertions, 10 deletions
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index a384fab935..119bf0f762 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -253,7 +253,7 @@ Decl *Parser::ParseUsingDirectiveOrDeclaration(unsigned Context, return ParseUsingDirective(Context, UsingLoc, DeclEnd, attrs); } - // Otherwise, it must be a using-declaration. + // Otherwise, it must be a using-declaration or an alias-declaration. // Using declarations can't have attributes. ProhibitAttributes(attrs); @@ -323,14 +323,17 @@ Decl *Parser::ParseUsingDirective(unsigned Context, IdentLoc, NamespcName, attrs.getList()); } -/// ParseUsingDeclaration - Parse C++ using-declaration. Assumes that -/// 'using' was already seen. +/// ParseUsingDeclaration - Parse C++ using-declaration or alias-declaration. +/// Assumes that 'using' was already seen. /// /// using-declaration: [C++ 7.3.p3: namespace.udecl] /// 'using' 'typename'[opt] ::[opt] nested-name-specifier /// unqualified-id /// 'using' :: unqualified-id /// +/// alias-declaration: C++0x [decl.typedef]p2 +/// 'using' identifier = type-id ; +/// Decl *Parser::ParseUsingDeclaration(unsigned Context, const ParsedTemplateInfo &TemplateInfo, SourceLocation UsingLoc, @@ -340,10 +343,6 @@ Decl *Parser::ParseUsingDeclaration(unsigned Context, SourceLocation TypenameLoc; bool IsTypeName; - // TODO: in C++0x, if we have template parameters this must be a - // template alias: - // template <...> using id = type; - // Ignore optional 'typename'. // FIXME: This is wrong; we should parse this as a typename-specifier. if (Tok.is(tok::kw_typename)) { @@ -377,17 +376,48 @@ Decl *Parser::ParseUsingDeclaration(unsigned Context, return 0; } - // Parse (optional) attributes (most likely GNU strong-using extension). ParsedAttributes attrs(AttrFactory); - MaybeParseGNUAttributes(attrs); + + // Maybe this is an alias-declaration. + bool IsAliasDecl = Tok.is(tok::equal); + TypeResult TypeAlias; + if (IsAliasDecl) { + // TODO: Do we want to support attributes somewhere in an alias declaration? + // Can't follow GCC since it doesn't support them yet! + ConsumeToken(); + + if (!getLang().CPlusPlus0x) + Diag(Tok.getLocation(), diag::ext_alias_declaration); + + // Name must be an identifier. + if (Name.getKind() != UnqualifiedId::IK_Identifier) { + Diag(Name.StartLocation, diag::err_alias_declaration_not_identifier); + // No removal fixit: can't recover from this. + SkipUntil(tok::semi); + return 0; + } else if (IsTypeName) + Diag(TypenameLoc, diag::err_alias_declaration_not_identifier) + << FixItHint::CreateRemoval(SourceRange(TypenameLoc, + SS.isNotEmpty() ? SS.getEndLoc() : TypenameLoc)); + else if (SS.isNotEmpty()) + Diag(SS.getBeginLoc(), diag::err_alias_declaration_not_identifier) + << FixItHint::CreateRemoval(SS.getRange()); + + TypeAlias = ParseTypeName(0, Declarator::AliasDeclContext); + } else + // Parse (optional) attributes (most likely GNU strong-using extension). + MaybeParseGNUAttributes(attrs); // Eat ';'. DeclEnd = Tok.getLocation(); ExpectAndConsume(tok::semi, diag::err_expected_semi_after, - !attrs.empty() ? "attributes list" : "using declaration", + !attrs.empty() ? "attributes list" : + IsAliasDecl ? "alias declaration" : "using declaration", tok::semi); // Diagnose an attempt to declare a templated using-declaration. + // TODO: in C++0x, alias-declarations can be templates: + // template <...> using id = type; if (TemplateInfo.Kind) { SourceRange R = TemplateInfo.getSourceRange(); Diag(UsingLoc, diag::err_templated_using_declaration) @@ -399,6 +429,10 @@ Decl *Parser::ParseUsingDeclaration(unsigned Context, return 0; } + if (IsAliasDecl) + return Actions.ActOnAliasDeclaration(getCurScope(), AS, UsingLoc, Name, + TypeAlias); + return Actions.ActOnUsingDeclaration(getCurScope(), AS, true, UsingLoc, SS, Name, attrs.getList(), IsTypeName, TypenameLoc); |