forked from OSchip/llvm-project
Make it possible for using decls to point to operators. Fixes PR4441.
llvm-svn: 74362
This commit is contained in:
parent
8e5f6951eb
commit
74d7f0dd65
|
@ -967,12 +967,13 @@ public:
|
|||
|
||||
/// ActOnUsingDirective - This is called when using-directive is parsed.
|
||||
virtual DeclPtrTy ActOnUsingDeclaration(Scope *CurScope,
|
||||
SourceLocation UsingLoc,
|
||||
const CXXScopeSpec &SS,
|
||||
SourceLocation IdentLoc,
|
||||
IdentifierInfo *TargetName,
|
||||
AttributeList *AttrList,
|
||||
bool IsTypeName);
|
||||
SourceLocation UsingLoc,
|
||||
const CXXScopeSpec &SS,
|
||||
SourceLocation IdentLoc,
|
||||
IdentifierInfo *TargetName,
|
||||
OverloadedOperatorKind Op,
|
||||
AttributeList *AttrList,
|
||||
bool IsTypeName);
|
||||
|
||||
/// ActOnParamDefaultArgument - Parse default argument for function parameter
|
||||
virtual void ActOnParamDefaultArgument(DeclPtrTy param,
|
||||
|
|
|
@ -48,6 +48,7 @@ Action::DeclPtrTy Action::ActOnUsingDeclaration(Scope *CurScope,
|
|||
const CXXScopeSpec &SS,
|
||||
SourceLocation IdentLoc,
|
||||
IdentifierInfo *TargetName,
|
||||
OverloadedOperatorKind Op,
|
||||
AttributeList *AttrList,
|
||||
bool IsTypeName) {
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "clang/Basic/OperatorKinds.h"
|
||||
#include "clang/Parse/Parser.h"
|
||||
#include "clang/Parse/ParseDiagnostic.h"
|
||||
#include "clang/Parse/DeclSpec.h"
|
||||
|
@ -274,8 +275,6 @@ Parser::DeclPtrTy Parser::ParseUsingDeclaration(unsigned Context,
|
|||
ParseOptionalCXXScopeSpecifier(SS);
|
||||
|
||||
AttributeList *AttrList = 0;
|
||||
IdentifierInfo *TargetName = 0;
|
||||
SourceLocation IdentLoc = SourceLocation();
|
||||
|
||||
// Check nested-name specifier.
|
||||
if (SS.isInvalid()) {
|
||||
|
@ -287,17 +286,33 @@ Parser::DeclPtrTy Parser::ParseUsingDeclaration(unsigned Context,
|
|||
SkipUntil(tok::semi);
|
||||
return DeclPtrTy();
|
||||
}
|
||||
if (Tok.isNot(tok::identifier)) {
|
||||
|
||||
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();
|
||||
}
|
||||
} 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 identifier.
|
||||
TargetName = Tok.getIdentifierInfo();
|
||||
IdentLoc = ConsumeToken();
|
||||
|
||||
// Parse (optional) attributes (most likely GNU strong-using extension).
|
||||
if (Tok.is(tok::kw___attribute))
|
||||
AttrList = ParseAttributes();
|
||||
|
@ -308,7 +323,8 @@ Parser::DeclPtrTy Parser::ParseUsingDeclaration(unsigned Context,
|
|||
AttrList ? "attributes list" : "namespace name", tok::semi);
|
||||
|
||||
return Actions.ActOnUsingDeclaration(CurScope, UsingLoc, SS,
|
||||
IdentLoc, TargetName, AttrList, IsTypeName);
|
||||
IdentLoc, TargetName, Op,
|
||||
AttrList, IsTypeName);
|
||||
}
|
||||
|
||||
/// ParseStaticAssertDeclaration - Parse C++0x static_assert-declaratoion.
|
||||
|
|
|
@ -1574,6 +1574,7 @@ public:
|
|||
const CXXScopeSpec &SS,
|
||||
SourceLocation IdentLoc,
|
||||
IdentifierInfo *TargetName,
|
||||
OverloadedOperatorKind Op,
|
||||
AttributeList *AttrList,
|
||||
bool IsTypeName);
|
||||
|
||||
|
|
|
@ -1785,18 +1785,24 @@ Sema::DeclPtrTy Sema::ActOnUsingDeclaration(Scope *S,
|
|||
const CXXScopeSpec &SS,
|
||||
SourceLocation IdentLoc,
|
||||
IdentifierInfo *TargetName,
|
||||
OverloadedOperatorKind Op,
|
||||
AttributeList *AttrList,
|
||||
bool IsTypeName) {
|
||||
assert(!SS.isInvalid() && "Invalid CXXScopeSpec.");
|
||||
assert(TargetName && "Invalid TargetName.");
|
||||
assert(TargetName || Op && "Invalid TargetName.");
|
||||
assert(IdentLoc.isValid() && "Invalid TargetName location.");
|
||||
assert(S->getFlags() & Scope::DeclScope && "Invalid Scope.");
|
||||
|
||||
UsingDecl *UsingAlias = 0;
|
||||
|
||||
DeclarationName Name;
|
||||
if (TargetName)
|
||||
Name = TargetName;
|
||||
else
|
||||
Name = Context.DeclarationNames.getCXXOperatorName(Op);
|
||||
|
||||
// Lookup target name.
|
||||
LookupResult R = LookupParsedName(S, &SS, TargetName,
|
||||
LookupOrdinaryName, false);
|
||||
LookupResult R = LookupParsedName(S, &SS, Name, LookupOrdinaryName, false);
|
||||
|
||||
if (NamedDecl *NS = R) {
|
||||
if (IsTypeName && !isa<TypeDecl>(NS)) {
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
// RUN: clang-cc -fsyntax-only -verify %s
|
||||
|
||||
namespace A {
|
||||
struct B { };
|
||||
void operator+(B,B);
|
||||
}
|
||||
|
||||
using A::operator+;
|
Loading…
Reference in New Issue