aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Parse/Action.h1
-rw-r--r--lib/Parse/ParseDeclCXX.cpp8
-rw-r--r--lib/Sema/Sema.h1
-rw-r--r--lib/Sema/SemaDeclCXX.cpp32
-rw-r--r--test/SemaCXX/constructor-initializer.cpp19
5 files changed, 43 insertions, 18 deletions
diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h
index 04acbc4be9..a8e52b2a86 100644
--- a/include/clang/Parse/Action.h
+++ b/include/clang/Parse/Action.h
@@ -1203,6 +1203,7 @@ public:
virtual MemInitResult ActOnMemInitializer(DeclPtrTy ConstructorDecl,
Scope *S,
+ const CXXScopeSpec &SS,
IdentifierInfo *MemberOrBase,
SourceLocation IdLoc,
SourceLocation LParenLoc,
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp
index 225f9261ef..44cd5e6bc0 100644
--- a/lib/Parse/ParseDeclCXX.cpp
+++ b/lib/Parse/ParseDeclCXX.cpp
@@ -1277,8 +1277,10 @@ void Parser::ParseConstructorInitializer(DeclPtrTy ConstructorDecl) {
/// '::'[opt] nested-name-specifier[opt] class-name
/// identifier
Parser::MemInitResult Parser::ParseMemInitializer(DeclPtrTy ConstructorDecl) {
- // FIXME: parse '::'[opt] nested-name-specifier[opt]
-
+ // parse '::'[opt] nested-name-specifier[opt]
+ CXXScopeSpec SS;
+ ParseOptionalCXXScopeSpecifier(SS);
+
if (Tok.isNot(tok::identifier)) {
Diag(Tok, diag::err_expected_member_or_base_name);
return true;
@@ -1306,7 +1308,7 @@ Parser::MemInitResult Parser::ParseMemInitializer(DeclPtrTy ConstructorDecl) {
SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
- return Actions.ActOnMemInitializer(ConstructorDecl, CurScope, II, IdLoc,
+ return Actions.ActOnMemInitializer(ConstructorDecl, CurScope, SS, II, IdLoc,
LParenLoc, ArgExprs.take(),
ArgExprs.size(), CommaLocs.data(),
RParenLoc);
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 65b5f25029..2379a17964 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -1891,6 +1891,7 @@ public:
virtual MemInitResult ActOnMemInitializer(DeclPtrTy ConstructorD,
Scope *S,
+ const CXXScopeSpec &SS,
IdentifierInfo *MemberOrBase,
SourceLocation IdLoc,
SourceLocation LParenLoc,
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 8c3a0bf158..a0bc94808b 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -646,6 +646,7 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
Sema::MemInitResult
Sema::ActOnMemInitializer(DeclPtrTy ConstructorD,
Scope *S,
+ const CXXScopeSpec &SS,
IdentifierInfo *MemberOrBase,
SourceLocation IdLoc,
SourceLocation LParenLoc,
@@ -677,23 +678,24 @@ Sema::ActOnMemInitializer(DeclPtrTy ConstructorD,
// composed of a single identifier refers to the class member. A
// mem-initializer-id for the hidden base class may be specified
// using a qualified name. ]
- // Look for a member, first.
- FieldDecl *Member = 0;
- DeclContext::lookup_result Result
- = ClassDecl->lookup(MemberOrBase);
- if (Result.first != Result.second)
- Member = dyn_cast<FieldDecl>(*Result.first);
-
- // FIXME: Handle members of an anonymous union.
-
- if (Member) {
- // FIXME: Perform direct initialization of the member.
- return new CXXBaseOrMemberInitializer(Member, (Expr **)Args, NumArgs,
- IdLoc);
+ if (!SS.getScopeRep()) {
+ // Look for a member, first.
+ FieldDecl *Member = 0;
+ DeclContext::lookup_result Result
+ = ClassDecl->lookup(MemberOrBase);
+ if (Result.first != Result.second)
+ Member = dyn_cast<FieldDecl>(*Result.first);
+
+ // FIXME: Handle members of an anonymous union.
+
+ if (Member) {
+ // FIXME: Perform direct initialization of the member.
+ return new CXXBaseOrMemberInitializer(Member, (Expr **)Args, NumArgs,
+ IdLoc);
+ }
}
-
// It didn't name a member, so see if it names a class.
- TypeTy *BaseTy = getTypeName(*MemberOrBase, IdLoc, S, 0/*SS*/);
+ TypeTy *BaseTy = getTypeName(*MemberOrBase, IdLoc, S, &SS);
if (!BaseTy)
return Diag(IdLoc, diag::err_mem_init_not_member_or_class)
<< MemberOrBase << SourceRange(IdLoc, RParenLoc);
diff --git a/test/SemaCXX/constructor-initializer.cpp b/test/SemaCXX/constructor-initializer.cpp
index 7fd748b8d3..a180d907f1 100644
--- a/test/SemaCXX/constructor-initializer.cpp
+++ b/test/SemaCXX/constructor-initializer.cpp
@@ -1,6 +1,7 @@
// RUN: clang-cc -fsyntax-only -verify %s
class A {
int m;
+ A() : A::m(17) { } // expected-error {{member initializer 'm' does not name a non-static data member or base class}}
};
class B : public A {
@@ -74,3 +75,21 @@ class U {
// expected-note {{previous initialization is here}}
};
+struct V {};
+struct Base {};
+struct Base1 {};
+
+struct Derived : Base, Base1, virtual V {
+ Derived ();
+};
+
+struct Current : Derived {
+ int Derived;
+ Current() : Derived(1), ::Derived(),
+ ::Derived::Base(), // expected-error {{type '::Derived::Base' is not a direct or virtual base of 'Current'}}
+ Derived::Base1(), // expected-error {{type 'Derived::Base1' is not a direct or virtual base of 'Current'}}
+ Derived::V(),
+ ::NonExisting(), // expected-error {{member initializer 'NonExisting' does not name a non-static data member or}}
+ INT::NonExisting() {} // expected-error {{expected a class or namespace}} \
+ // expected-error {{member initializer 'NonExisting' does not name a non-static data member or}}
+};