diff options
Diffstat (limited to 'lib/Parse/ParseDeclCXX.cpp')
-rw-r--r-- | lib/Parse/ParseDeclCXX.cpp | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index 53fc3405bb..ffef288e71 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -613,6 +613,20 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, ConsumeCodeCompletionToken(); } + // C++03 [temp.explicit] 14.7.2/8: + // The usual access checking rules do not apply to names used to specify + // explicit instantiations. + // + // As an extension we do not perform access checking on the names used to + // specify explicit specializations either. This is important to allow + // specializing traits classes for private types. + bool SuppressingAccessChecks = false; + if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation || + TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization) { + Actions.ActOnStartSuppressingAccessChecks(); + SuppressingAccessChecks = true; + } + AttributeList *AttrList = 0; // If attributes exist after tag, parse them. if (Tok.is(tok::kw___attribute)) @@ -732,10 +746,18 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, DS.SetTypeSpecError(); SkipUntil(tok::semi, false, true); TemplateId->Destroy(); + if (SuppressingAccessChecks) + Actions.ActOnStopSuppressingAccessChecks(); + return; } } + // As soon as we're finished parsing the class's template-id, turn access + // checking back on. + if (SuppressingAccessChecks) + Actions.ActOnStopSuppressingAccessChecks(); + // There are four options here. If we have 'struct foo;', then this // is either a forward declaration or a friend declaration, which // have to be treated differently. If we have 'struct foo {...' or |