diff options
-rw-r--r-- | include/clang/Parse/Action.h | 13 | ||||
-rw-r--r-- | lib/Parse/MinimalAction.cpp | 1 | ||||
-rw-r--r-- | lib/Parse/ParseDeclCXX.cpp | 32 | ||||
-rw-r--r-- | lib/Sema/Sema.h | 1 | ||||
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 12 | ||||
-rw-r--r-- | test/SemaCXX/using-decl-pr4441.cpp | 8 |
6 files changed, 50 insertions, 17 deletions
diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h index fa3160468e..bfb74748c5 100644 --- a/include/clang/Parse/Action.h +++ b/include/clang/Parse/Action.h @@ -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, diff --git a/lib/Parse/MinimalAction.cpp b/lib/Parse/MinimalAction.cpp index 9ded366b29..648e2da54b 100644 --- a/lib/Parse/MinimalAction.cpp +++ b/lib/Parse/MinimalAction.cpp @@ -48,6 +48,7 @@ Action::DeclPtrTy Action::ActOnUsingDeclaration(Scope *CurScope, const CXXScopeSpec &SS, SourceLocation IdentLoc, IdentifierInfo *TargetName, + OverloadedOperatorKind Op, AttributeList *AttrList, bool IsTypeName) { diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index fed03a8c34..225f9261ef 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -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. diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index cbe0ad7161..2d27ccc778 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -1574,6 +1574,7 @@ public: const CXXScopeSpec &SS, SourceLocation IdentLoc, IdentifierInfo *TargetName, + OverloadedOperatorKind Op, AttributeList *AttrList, bool IsTypeName); diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index b238318533..b7a429991f 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -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)) { diff --git a/test/SemaCXX/using-decl-pr4441.cpp b/test/SemaCXX/using-decl-pr4441.cpp new file mode 100644 index 0000000000..6aa2b261e4 --- /dev/null +++ b/test/SemaCXX/using-decl-pr4441.cpp @@ -0,0 +1,8 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +namespace A { + struct B { }; + void operator+(B,B); +} + +using A::operator+; |