diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Parse/MinimalAction.cpp | 6 | ||||
-rw-r--r-- | lib/Parse/ParseDeclCXX.cpp | 49 | ||||
-rw-r--r-- | lib/Sema/Sema.h | 4 | ||||
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 39 |
4 files changed, 45 insertions, 53 deletions
diff --git a/lib/Parse/MinimalAction.cpp b/lib/Parse/MinimalAction.cpp index 1e7d397fdf..bf05b2bacc 100644 --- a/lib/Parse/MinimalAction.cpp +++ b/lib/Parse/MinimalAction.cpp @@ -42,14 +42,12 @@ Action::DeclPtrTy Action::ActOnUsingDirective(Scope *CurScope, return DeclPtrTy(); } -// Defined out-of-line here because of dependecy on AttributeList +// Defined out-of-line here because of dependency on AttributeList Action::DeclPtrTy Action::ActOnUsingDeclaration(Scope *CurScope, AccessSpecifier AS, SourceLocation UsingLoc, const CXXScopeSpec &SS, - SourceLocation IdentLoc, - IdentifierInfo *TargetName, - OverloadedOperatorKind Op, + UnqualifiedId &Name, AttributeList *AttrList, bool IsTypeName) { diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index 91f86864f8..154c292348 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -285,6 +285,7 @@ Parser::DeclPtrTy Parser::ParseUsingDeclaration(unsigned Context, bool IsTypeName; // Ignore optional 'typename'. + // FIXME: This is wrong; we should parse this as a typename-specifier. if (Tok.is(tok::kw_typename)) { ConsumeToken(); IsTypeName = true; @@ -302,41 +303,21 @@ Parser::DeclPtrTy Parser::ParseUsingDeclaration(unsigned Context, SkipUntil(tok::semi); return DeclPtrTy(); } - if (Tok.is(tok::annot_template_id)) { - // C++0x N2914 [namespace.udecl]p5: - // A using-declaration shall not name a template-id. - Diag(Tok, diag::err_using_decl_can_not_refer_to_template_spec); - SkipUntil(tok::semi); - return DeclPtrTy(); - } - - IdentifierInfo *TargetName = 0; - OverloadedOperatorKind Op = OO_None; - SourceLocation IdentLoc; - if (Tok.is(tok::kw_operator)) { - IdentLoc = Tok.getLocation(); - - Op = TryParseOperatorFunctionId(); - if (!Op) { - // If there was an invalid operator, skip to end of decl, and eat ';'. - SkipUntil(tok::semi); - return DeclPtrTy(); - } - // FIXME: what about conversion functions? - } else if (Tok.is(tok::identifier)) { - // Parse identifier. - TargetName = Tok.getIdentifierInfo(); - IdentLoc = ConsumeToken(); - } else { - // FIXME: Use a better diagnostic here. - Diag(Tok, diag::err_expected_ident_in_using); - - // If there was invalid identifier, skip to end of decl, and eat ';'. + // Parse the unqualified-id. We allow parsing of both constructor and + // destructor names and allow the action module to diagnose any semantic + // errors. + UnqualifiedId Name; + if (ParseUnqualifiedId(SS, + /*EnteringContext=*/false, + /*AllowDestructorName=*/true, + /*AllowConstructorName=*/true, + /*ObjectType=*/0, + Name)) { SkipUntil(tok::semi); return DeclPtrTy(); } - + // Parse (optional) attributes (most likely GNU strong-using extension). if (Tok.is(tok::kw___attribute)) AttrList = ParseAttributes(); @@ -344,10 +325,10 @@ Parser::DeclPtrTy Parser::ParseUsingDeclaration(unsigned Context, // Eat ';'. DeclEnd = Tok.getLocation(); ExpectAndConsume(tok::semi, diag::err_expected_semi_after, - AttrList ? "attributes list" : "namespace name", tok::semi); + AttrList ? "attributes list" : "using declaration", + tok::semi); - return Actions.ActOnUsingDeclaration(CurScope, AS, UsingLoc, SS, - IdentLoc, TargetName, Op, + return Actions.ActOnUsingDeclaration(CurScope, AS, UsingLoc, SS, Name, AttrList, IsTypeName); } diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 0f84b46ed4..b0aa7b7473 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -1893,9 +1893,7 @@ public: AccessSpecifier AS, SourceLocation UsingLoc, const CXXScopeSpec &SS, - SourceLocation IdentLoc, - IdentifierInfo *TargetName, - OverloadedOperatorKind Op, + UnqualifiedId &Name, AttributeList *AttrList, bool IsTypeName); diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index bc255137fc..3314ee26cb 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -2700,22 +2700,37 @@ Sema::DeclPtrTy Sema::ActOnUsingDeclaration(Scope *S, AccessSpecifier AS, SourceLocation UsingLoc, const CXXScopeSpec &SS, - SourceLocation IdentLoc, - IdentifierInfo *TargetName, - OverloadedOperatorKind Op, + UnqualifiedId &Name, AttributeList *AttrList, bool IsTypeName) { - assert((TargetName || Op) && "Invalid TargetName."); assert(S->getFlags() & Scope::DeclScope && "Invalid Scope."); - DeclarationName Name; - if (TargetName) - Name = TargetName; - else - Name = Context.DeclarationNames.getCXXOperatorName(Op); - - NamedDecl *UD = BuildUsingDeclaration(UsingLoc, SS, IdentLoc, - Name, AttrList, IsTypeName); + switch (Name.getKind()) { + case UnqualifiedId::IK_Identifier: + case UnqualifiedId::IK_OperatorFunctionId: + case UnqualifiedId::IK_ConversionFunctionId: + break; + + case UnqualifiedId::IK_ConstructorName: + Diag(Name.getSourceRange().getBegin(), diag::err_using_decl_constructor) + << SS.getRange(); + return DeclPtrTy(); + + case UnqualifiedId::IK_DestructorName: + Diag(Name.getSourceRange().getBegin(), diag::err_using_decl_destructor) + << SS.getRange(); + return DeclPtrTy(); + + case UnqualifiedId::IK_TemplateId: + Diag(Name.getSourceRange().getBegin(), diag::err_using_decl_template_id) + << SourceRange(Name.TemplateId->LAngleLoc, Name.TemplateId->RAngleLoc); + return DeclPtrTy(); + } + + DeclarationName TargetName = GetNameFromUnqualifiedId(Name); + NamedDecl *UD = BuildUsingDeclaration(UsingLoc, SS, + Name.getSourceRange().getBegin(), + TargetName, AttrList, IsTypeName); if (UD) { PushOnScopeChains(UD, S); UD->setAccess(AS); |