aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Parse/ParseDecl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Parse/ParseDecl.cpp')
-rw-r--r--clang/lib/Parse/ParseDecl.cpp31
1 files changed, 30 insertions, 1 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 9393235..2b19ade 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -3091,6 +3091,12 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
return true;
};
+ // Turn off usual access checking for template specializations and
+ // instantiations.
+ bool IsTemplateSpecOrInst =
+ (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation ||
+ TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization);
+
switch (Tok.getKind()) {
default:
DoneWithDeclSpec:
@@ -3261,6 +3267,12 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
isConstructorDeclarator(/*Unqualified*/ false))
goto DoneWithDeclSpec;
+ // C++20 [temp.spec] 13.9/6.
+ // This disables the access checking rules for function template explicit
+ // instantiation and explicit specialization:
+ // - `return type`.
+ SuppressAccessChecks SAC(*this, IsTemplateSpecOrInst);
+
ParsedType TypeRep =
Actions.getTypeName(*Next.getIdentifierInfo(), Next.getLocation(),
getCurScope(), &SS, false, false, nullptr,
@@ -3268,6 +3280,9 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
/*WantNontrivialTypeSourceInfo=*/true,
isClassTemplateDeductionContext(DSContext));
+ if (IsTemplateSpecOrInst)
+ SAC.done();
+
// If the referenced identifier is not a type, then this declspec is
// erroneous: We already checked about that it has no type specifier, and
// C++ doesn't have implicit int. Diagnose it as a typo w.r.t. to the
@@ -3377,10 +3392,24 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
// In C++, check to see if this is a scope specifier like foo::bar::, if
// so handle it as such. This is important for ctor parsing.
if (getLangOpts().CPlusPlus) {
- if (TryAnnotateCXXScopeToken(EnteringContext)) {
+ // C++20 [temp.spec] 13.9/6.
+ // This disables the access checking rules for function template
+ // explicit instantiation and explicit specialization:
+ // - `return type`.
+ SuppressAccessChecks SAC(*this, IsTemplateSpecOrInst);
+
+ const bool Success = TryAnnotateCXXScopeToken(EnteringContext);
+
+ if (IsTemplateSpecOrInst)
+ SAC.done();
+
+ if (Success) {
+ if (IsTemplateSpecOrInst)
+ SAC.redelay();
DS.SetTypeSpecError();
goto DoneWithDeclSpec;
}
+
if (!Tok.is(tok::identifier))
continue;
}