diff options
-rw-r--r-- | include/clang/Parse/Action.h | 1 | ||||
-rw-r--r-- | lib/Parse/ParseDeclCXX.cpp | 8 | ||||
-rw-r--r-- | lib/Sema/Sema.h | 1 | ||||
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 32 | ||||
-rw-r--r-- | test/SemaCXX/constructor-initializer.cpp | 19 |
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}} +}; |