[cfe-commits] r106993 - in /cfe/trunk: include/clang/Parse/Action.h lib/Parse/ParseDeclCXX.cpp lib/Sema/Sema.cpp lib/Sema/Sema.h lib/Sema/SemaAccess.cpp test/CXX/temp/temp.spec/temp.explicit/p11.cpp
Douglas Gregor
dgregor at apple.com
Tue Jun 29 08:13:51 PDT 2010
On Jun 28, 2010, at 1:39 AM, Chandler Carruth wrote:
> Author: chandlerc
> Date: Mon Jun 28 03:39:25 2010
> New Revision: 106993
>
> URL: http://llvm.org/viewvc/llvm-project?rev=106993&view=rev
> Log:
> Partial fix for PR7267 based on comments by John McCall on an earlier patch.
> This is more targeted, as it simply provides toggle actions for the parser to
> turn access checking on and off. We then use these to suppress access checking
> only while we parse the template-id (included scope specifier) of an explicit
> instantiation and explicit specialization of a class template. The
> specialization behavior is an extension, as it seems likely a defect that the
> standard did not exempt them as it does explicit instantiations.
Both EDG and g++ seem to allow this "extension", too.
> Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=106993&r1=106992&r2=106993&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
> +++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Mon Jun 28 03:39:25 2010
> @@ -613,6 +613,20 @@
> 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 @@
> 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
I'd feel a bit more comfortable if this were an RAII object.
- Doug
More information about the cfe-commits
mailing list