]> granicus.if.org Git - clang/commitdiff
Patch to support optional nested-name-specifier in in ctor-initializer
authorFariborz Jahanian <fjahanian@apple.com>
Tue, 30 Jun 2009 23:26:25 +0000 (23:26 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Tue, 30 Jun 2009 23:26:25 +0000 (23:26 +0000)
list.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@74571 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Parse/Action.h
lib/Parse/ParseDeclCXX.cpp
lib/Sema/Sema.h
lib/Sema/SemaDeclCXX.cpp
test/SemaCXX/constructor-initializer.cpp

index 04acbc4be9dadb5cce920e699ebf4633a4c5b4e7..a8e52b2a86eba63434d535833016ad9046310500 100644 (file)
@@ -1203,6 +1203,7 @@ public:
 
   virtual MemInitResult ActOnMemInitializer(DeclPtrTy ConstructorDecl,
                                             Scope *S,
+                                            const CXXScopeSpec &SS,
                                             IdentifierInfo *MemberOrBase,
                                             SourceLocation IdLoc,
                                             SourceLocation LParenLoc,
index 225f9261ef8fb34e25964f98b067b8e3a31352fc..44cd5e6bc0c05f7649d60be316a7c5cdafda63d0 100644 (file)
@@ -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);
index 65b5f250295b16b237944843b8c4c3bc7b4c2060..2379a1796406db3d462aea8a5d0707e569fac4df 100644 (file)
@@ -1891,6 +1891,7 @@ public:
 
   virtual MemInitResult ActOnMemInitializer(DeclPtrTy ConstructorD,
                                             Scope *S,
+                                            const CXXScopeSpec &SS,
                                             IdentifierInfo *MemberOrBase,
                                             SourceLocation IdLoc,
                                             SourceLocation LParenLoc,
index 8c3a0bf1584123350aa07945f645303e4925c12a..a0bc94808bbed297263772c166c1ac8355072cda 100644 (file)
@@ -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);
index 7fd748b8d34b2cfffc5e08dbf1ba4ef1cc626853..a180d907f1b7669a1fd1315d9c8b20529ca6bfb7 100644 (file)
@@ -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}}
+};