[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