forked from OSchip/llvm-project
Switch parsing of using declarations over to ParseUnqualifiedId.
llvm-svn: 86027
This commit is contained in:
parent
531045d554
commit
220f4277bd
|
@ -166,9 +166,6 @@ def err_use_of_tag_name_without_tag : Error<
|
|||
"use of tagged type %0 without '%1' tag">;
|
||||
def err_expected_ident_in_using : Error<
|
||||
"expected an identifier in using directive">;
|
||||
def err_using_decl_can_not_refer_to_template_spec : Error<
|
||||
"using declaration can not refer to template specialization">;
|
||||
|
||||
|
||||
/// Objective-C parser diagnostics
|
||||
def err_objc_no_attributes_on_category : Error<
|
||||
|
|
|
@ -107,8 +107,14 @@ def err_using_decl_nested_name_specifier_is_not_a_base_class : Error<
|
|||
"using declaration refers into '%0', which is not a base class of %1">;
|
||||
def err_using_decl_can_not_refer_to_class_member : Error<
|
||||
"using declaration can not refer to class member">;
|
||||
def err_using_decl_can_not_refer_to_namespace : Error<
|
||||
def err_using_decl_can_not_refer_to_namespace : Error<
|
||||
"using declaration can not refer to namespace">;
|
||||
def err_using_decl_constructor : Error<
|
||||
"using declaration can not refer to a constructor">;
|
||||
def err_using_decl_destructor : Error<
|
||||
"using declaration can not refer to a destructor">;
|
||||
def err_using_decl_template_id : Error<
|
||||
"using declaration can not refer to a template specialization">;
|
||||
|
||||
def err_invalid_thread : Error<
|
||||
"'__thread' is only allowed on variable declarations">;
|
||||
|
|
|
@ -1174,14 +1174,41 @@ public:
|
|||
return DeclPtrTy();
|
||||
}
|
||||
|
||||
/// ActOnUsingDirective - This is called when using-directive is parsed.
|
||||
/// \brief Parsed a C++ using-declaration.
|
||||
///
|
||||
/// This callback will be invoked when the parser has parsed a C++
|
||||
/// using-declaration, e.g.,
|
||||
///
|
||||
/// \code
|
||||
/// namespace std {
|
||||
/// template<typename T, typename Alloc> class vector;
|
||||
/// }
|
||||
///
|
||||
/// using std::vector; // using-declaration here
|
||||
/// \endcode
|
||||
///
|
||||
/// \param CurScope the scope in which this using declaration was parsed.
|
||||
///
|
||||
/// \param AS the currently-active access specifier.
|
||||
///
|
||||
/// \param UsingLoc the location of the 'using' keyword.
|
||||
///
|
||||
/// \param SS the nested-name-specifier that precedes the name.
|
||||
///
|
||||
/// \param Name the name to which the using declaration refers.
|
||||
///
|
||||
/// \param AttrList attributes applied to this using declaration, if any.
|
||||
///
|
||||
/// \param IsTypeName whether this using declaration started with the
|
||||
/// 'typename' keyword. FIXME: This will eventually be split into a
|
||||
/// separate action.
|
||||
///
|
||||
/// \returns a representation of the using declaration.
|
||||
virtual DeclPtrTy ActOnUsingDeclaration(Scope *CurScope,
|
||||
AccessSpecifier AS,
|
||||
SourceLocation UsingLoc,
|
||||
const CXXScopeSpec &SS,
|
||||
SourceLocation IdentLoc,
|
||||
IdentifierInfo *TargetName,
|
||||
OverloadedOperatorKind Op,
|
||||
UnqualifiedId &Name,
|
||||
AttributeList *AttrList,
|
||||
bool IsTypeName);
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
// 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();
|
||||
}
|
||||
|
||||
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 ';'.
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -1893,9 +1893,7 @@ public:
|
|||
AccessSpecifier AS,
|
||||
SourceLocation UsingLoc,
|
||||
const CXXScopeSpec &SS,
|
||||
SourceLocation IdentLoc,
|
||||
IdentifierInfo *TargetName,
|
||||
OverloadedOperatorKind Op,
|
||||
UnqualifiedId &Name,
|
||||
AttributeList *AttrList,
|
||||
bool IsTypeName);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -7,6 +7,6 @@ struct A {
|
|||
};
|
||||
|
||||
struct B : A {
|
||||
using A::f<double>; // expected-error{{using declaration can not refer to template specialization}}
|
||||
using A::X<int>; // expected-error{{using declaration can not refer to template specialization}}
|
||||
};
|
||||
using A::f<double>; // expected-error{{using declaration can not refer to a template specialization}}
|
||||
using A::X<int>; // expected-error{{using declaration can not refer to a template specialization}}
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue