aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Parse/Action.h13
-rw-r--r--lib/Parse/MinimalAction.cpp1
-rw-r--r--lib/Parse/ParseDeclCXX.cpp32
-rw-r--r--lib/Sema/Sema.h1
-rw-r--r--lib/Sema/SemaDeclCXX.cpp12
-rw-r--r--test/SemaCXX/using-decl-pr4441.cpp8
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+;