[cfe-commits] r108521 - in /cfe/trunk: include/clang/Parse/Parser.h lib/Parse/ParseDeclCXX.cpp lib/Parse/ParseTemplate.cpp lib/Sema/SemaDecl.cpp test/CXX/class.access/p6.cpp

John McCall rjmccall at apple.com
Fri Jul 16 01:13:16 PDT 2010


Author: rjmccall
Date: Fri Jul 16 03:13:16 2010
New Revision: 108521

URL: http://llvm.org/viewvc/llvm-project?rev=108521&view=rev
Log:
Treat template parameters as part of the declaration-specifiers for the
purpose of access control.  Fixes PR7644.

I can't actually find anything directly justifying this, but it seems obvious.


Modified:
    cfe/trunk/include/clang/Parse/Parser.h
    cfe/trunk/lib/Parse/ParseDeclCXX.cpp
    cfe/trunk/lib/Parse/ParseTemplate.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/test/CXX/class.access/p6.cpp

Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=108521&r1=108520&r2=108521&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Fri Jul 16 03:13:16 2010
@@ -654,12 +654,25 @@
     Action &Actions;
     Action::ParsingDeclStackState State;
     bool Popped;
-    
+
   public:
     ParsingDeclRAIIObject(Parser &P) : Actions(P.Actions) {
       push();
     }
 
+    ParsingDeclRAIIObject(Parser &P, ParsingDeclRAIIObject *Other)
+        : Actions(P.Actions) {
+      if (Other) steal(*Other);
+      else push();
+    }
+
+    /// Creates a RAII object which steals the state from a different
+    /// object instead of pushing.
+    ParsingDeclRAIIObject(ParsingDeclRAIIObject &Other)
+        : Actions(Other.Actions) {
+      steal(Other);
+    }
+
     ~ParsingDeclRAIIObject() {
       abort();
     }
@@ -682,6 +695,12 @@
     }
 
   private:
+    void steal(ParsingDeclRAIIObject &Other) {
+      State = Other.State;
+      Popped = Other.Popped;
+      Other.Popped = true;
+    }
+    
     void push() {
       State = Actions.PushParsingDeclaration();
       Popped = false;
@@ -700,8 +719,10 @@
     ParsingDeclRAIIObject ParsingRAII;
 
   public:
-    ParsingDeclSpec(Parser &P) : ParsingRAII(P) {
-    }
+    ParsingDeclSpec(Parser &P) : ParsingRAII(P) {}
+    ParsingDeclSpec(ParsingDeclRAIIObject &RAII) : ParsingRAII(RAII) {}
+    ParsingDeclSpec(Parser &P, ParsingDeclRAIIObject *RAII)
+      : ParsingRAII(P, RAII) {}
 
     void complete(DeclPtrTy D) {
       ParsingRAII.complete(D);
@@ -1414,7 +1435,8 @@
   void ParseCXXMemberSpecification(SourceLocation StartLoc, unsigned TagType,
                                    DeclPtrTy TagDecl);
   void ParseCXXClassMemberDeclaration(AccessSpecifier AS,
-                const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo());
+                const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
+                                 ParsingDeclRAIIObject *DiagsFromTParams = 0);
   void ParseConstructorInitializer(DeclPtrTy ConstructorDecl);
   MemInitResult ParseMemInitializer(DeclPtrTy ConstructorDecl);
   void HandleMemberFunctionDefaultArgs(Declarator& DeclaratorInfo,
@@ -1457,6 +1479,7 @@
   DeclPtrTy ParseSingleDeclarationAfterTemplate(
                                        unsigned Context,
                                        const ParsedTemplateInfo &TemplateInfo,
+                                       ParsingDeclRAIIObject &DiagsFromParams,
                                        SourceLocation &DeclEnd,
                                        AccessSpecifier AS=AS_none);
   bool ParseTemplateParameters(unsigned Depth,

Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=108521&r1=108520&r2=108521&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Fri Jul 16 03:13:16 2010
@@ -1218,7 +1218,8 @@
 ///         '=' constant-expression
 ///
 void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
-                                       const ParsedTemplateInfo &TemplateInfo) {
+                                       const ParsedTemplateInfo &TemplateInfo,
+                                       ParsingDeclRAIIObject *TemplateDiags) {
   // Access declarations.
   if (!TemplateInfo.Kind &&
       (Tok.is(tok::identifier) || Tok.is(tok::coloncolon)) &&
@@ -1281,7 +1282,7 @@
     // __extension__ silences extension warnings in the subexpression.
     ExtensionRAIIObject O(Diags);  // Use RAII to do this.
     ConsumeToken();
-    return ParseCXXClassMemberDeclaration(AS, TemplateInfo);
+    return ParseCXXClassMemberDeclaration(AS, TemplateInfo, TemplateDiags);
   }
 
   // Don't parse FOO:BAR as if it were a typo for FOO::BAR, in this context it
@@ -1317,7 +1318,7 @@
   SourceLocation DSStart = Tok.getLocation();
   // decl-specifier-seq:
   // Parse the common declaration-specifiers piece.
-  ParsingDeclSpec DS(*this);
+  ParsingDeclSpec DS(*this, TemplateDiags);
   DS.AddAttributes(AttrList.AttrList);
   ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DSC_class);
 
@@ -1327,7 +1328,9 @@
 
   if (Tok.is(tok::semi)) {
     ConsumeToken();
-    Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS, DS);
+    DeclPtrTy TheDecl =
+      Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS, DS);
+    DS.complete(TheDecl);
     return;
   }
 

Modified: cfe/trunk/lib/Parse/ParseTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTemplate.cpp?rev=108521&r1=108520&r2=108521&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseTemplate.cpp (original)
+++ cfe/trunk/lib/Parse/ParseTemplate.cpp Fri Jul 16 03:13:16 2010
@@ -80,6 +80,10 @@
   // Enter template-parameter scope.
   ParseScope TemplateParmScope(this, Scope::TemplateParamScope);
 
+  // Tell the action that names should be checked in the context of
+  // the declaration to come.
+  ParsingDeclRAIIObject ParsingTemplateParams(*this);
+
   // Parse multiple levels of template headers within this template
   // parameter scope, e.g.,
   //
@@ -152,6 +156,7 @@
                                              ParsedTemplateInfo(&ParamLists,
                                                              isSpecialization,
                                                          LastParamListWasEmpty),
+                                             ParsingTemplateParams,
                                              DeclEnd, AS);
 }
 
@@ -179,6 +184,7 @@
 Parser::ParseSingleDeclarationAfterTemplate(
                                        unsigned Context,
                                        const ParsedTemplateInfo &TemplateInfo,
+                                       ParsingDeclRAIIObject &DiagsFromTParams,
                                        SourceLocation &DeclEnd,
                                        AccessSpecifier AS) {
   assert(TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate &&
@@ -186,12 +192,13 @@
 
   if (Context == Declarator::MemberContext) {
     // We are parsing a member template.
-    ParseCXXClassMemberDeclaration(AS, TemplateInfo);
+    ParseCXXClassMemberDeclaration(AS, TemplateInfo, &DiagsFromTParams);
     return DeclPtrTy::make((void*)0);
   }
 
-  // Parse the declaration specifiers.
-  ParsingDeclSpec DS(*this);
+  // Parse the declaration specifiers, stealing the accumulated
+  // diagnostics from the template parameters.
+  ParsingDeclSpec DS(DiagsFromTParams);
 
   if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
     DS.AddAttributes(ParseCXX0XAttributes().AttrList);
@@ -1057,8 +1064,12 @@
 Parser::ParseExplicitInstantiation(SourceLocation ExternLoc,
                                    SourceLocation TemplateLoc,
                                    SourceLocation &DeclEnd) {
+  // This isn't really required here.
+  ParsingDeclRAIIObject ParsingTemplateParams(*this);
+
   return ParseSingleDeclarationAfterTemplate(Declarator::FileContext,
                                              ParsedTemplateInfo(ExternLoc,
                                                                 TemplateLoc),
+                                             ParsingTemplateParams,
                                              DeclEnd, AS_none);
 }

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=108521&r1=108520&r2=108521&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Fri Jul 16 03:13:16 2010
@@ -1562,7 +1562,7 @@
       << DS.getSourceRange();
   }
 
-  return DeclPtrTy::make(Tag);
+  return DeclPtrTy::make(TagD);
 }
 
 /// We are trying to inject an anonymous member into the given scope;

Modified: cfe/trunk/test/CXX/class.access/p6.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/class.access/p6.cpp?rev=108521&r1=108520&r2=108521&view=diff
==============================================================================
--- cfe/trunk/test/CXX/class.access/p6.cpp (original)
+++ cfe/trunk/test/CXX/class.access/p6.cpp Fri Jul 16 03:13:16 2010
@@ -119,3 +119,23 @@
     foo(a, 0);
   }
 }
+
+// PR7644
+namespace test5 {
+  class A {
+    enum Enum { E0, E1, E2 }; // expected-note 4 {{declared private here}}
+    template <Enum> void foo();
+    template <Enum> class bar;
+  };
+
+  template <A::Enum en> void A::foo() {}
+  template <A::Enum en> class A::bar {};
+
+  template <A::Enum en> void foo() {} // expected-error {{'Enum' is a private member of 'test5::A'}}
+  template <A::Enum en> class bar {}; // expected-error {{'Enum' is a private member of 'test5::A'}}
+
+  class B {
+    template <A::Enum en> void foo() {} // expected-error {{'Enum' is a private member of 'test5::A'}}
+    template <A::Enum en> class bar {}; // expected-error {{'Enum' is a private member of 'test5::A'}}
+  };
+}





More information about the cfe-commits mailing list