]> granicus.if.org Git - clang/commitdiff
Tighten the setAccess assert. We now allow AS_none if the decl contex is not a C...
authorAnders Carlsson <andersca@mac.com>
Wed, 25 Mar 2009 23:38:06 +0000 (23:38 +0000)
committerAnders Carlsson <andersca@mac.com>
Wed, 25 Mar 2009 23:38:06 +0000 (23:38 +0000)
Also, fix fallout from the change.

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

include/clang/AST/DeclBase.h
lib/AST/DeclBase.cpp
lib/Sema/SemaDecl.cpp
test/SemaCXX/nested-name-spec.cpp

index a53b459c99038372679ce0c8bc43a00a5575dab8..5ee607b88e5d74cc19afa5b64dec5e89b2b6f81e 100644 (file)
@@ -138,6 +138,12 @@ private:
   /// the implementation rather than explicitly written by the user.
   bool Implicit : 1;
 
+#ifndef NDEBUG
+  void CheckAccessDeclContext() const;
+#else
+  void CheckAccessDeclContext() const { }
+#endif
+  
 protected:
   /// Access - Used by C++ decls for the access specifier.
   // NOTE: VC++ treats enums as signed, avoid using the AccessSpecifier enum
@@ -148,7 +154,7 @@ protected:
     : NextDeclarator(0), NextDeclInScope(0), 
       DeclCtx(reinterpret_cast<uintptr_t>(DC)), 
       Loc(L), DeclKind(DK), InvalidDecl(0),
-      HasAttrs(false), Implicit(false) {
+      HasAttrs(false), Implicit(false), Access(AS_none) {
     if (Decl::CollectingStats()) addDeclKind(DK);
   }
 
@@ -175,11 +181,15 @@ public:
                          const_cast<const Decl*>(this)->getDeclContext());
   }
 
-  void setAccess(AccessSpecifier AS) { 
-    assert(AS != AS_none && "Can't set access to none");
+  void setAccess(AccessSpecifier AS) {
     Access = AS; 
+    CheckAccessDeclContext();
+  }
+  
+  AccessSpecifier getAccess() const { 
+    CheckAccessDeclContext();
+    return AccessSpecifier(Access); 
   }
-  AccessSpecifier getAccess() const { return AccessSpecifier(Access); }
 
   bool hasAttrs() const { return HasAttrs; }
   void addAttr(Attr *attr);
index 812c362acd37f1dd082839a2c1223f8d7b408c49..cb12618443506bca5e0322bb9eacf10491036ab0 100644 (file)
@@ -272,6 +272,14 @@ DeclContext *Decl::castToDeclContext(const Decl *D) {
   }
 }
 
+#ifndef NDEBUG
+void Decl::CheckAccessDeclContext() const {
+  assert((Access != AS_none || !isa<CXXRecordDecl>(getDeclContext())) &&
+         "Access specifier is AS_none inside a record decl");
+}
+
+#endif
+
 //===----------------------------------------------------------------------===//
 // DeclContext Implementation
 //===----------------------------------------------------------------------===//
index 220113734f096ffa264f6d03ed55f9907a78f6a2..835792ee2db1625f777231e2cd3bf3e8d3f21521 100644 (file)
@@ -3384,7 +3384,9 @@ CreateNewDecl:
   // lexical context will be different from the semantic context.
   New->setLexicalDeclContext(CurContext);
 
-  if (AS != AS_none)
+  if (PrevDecl)
+    New->setAccess(PrevDecl->getAccess());
+  else
     New->setAccess(AS);
 
   if (TK == TK_Definition)
index f575fb82b41e3a5a341494ca5eea7e54fb90e5fe..07fd5a9bf85f7afbdb6589b67de72ef49bc428a8 100644 (file)
@@ -170,4 +170,3 @@ Y::foo y; // expected-error{{incomplete type 'struct Y' named in nested name spe
 X::X() : a(5) { } // expected-error{{use of undeclared identifier 'X'}} \
       // expected-error{{C++ requires a type specifier for all declarations}} \
       // expected-error{{only constructors take base initializers}}
-