#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
#include "clang/AST/PrettyDeclStackTrace.h"
-#include "clang/AST/TypeVisitor.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/Stack.h"
#include "clang/Sema/DeclSpec.h"
UpdateExceptionSpec(New, ESI);
}
-namespace {
-
- struct GetContainedInventedTypeParmVisitor :
- public TypeVisitor<GetContainedInventedTypeParmVisitor,
- TemplateTypeParmDecl *> {
- using TypeVisitor<GetContainedInventedTypeParmVisitor,
- TemplateTypeParmDecl *>::Visit;
-
- TemplateTypeParmDecl *Visit(QualType T) {
- if (T.isNull())
- return nullptr;
- return Visit(T.getTypePtr());
- }
- // The deduced type itself.
- TemplateTypeParmDecl *VisitTemplateTypeParmType(
- const TemplateTypeParmType *T) {
- if (!T->getDecl()->isImplicit())
- return nullptr;
- return T->getDecl();
- }
-
- // Only these types can contain 'auto' types, and subsequently be replaced
- // by references to invented parameters.
-
- TemplateTypeParmDecl *VisitElaboratedType(const ElaboratedType *T) {
- return Visit(T->getNamedType());
- }
-
- TemplateTypeParmDecl *VisitPointerType(const PointerType *T) {
- return Visit(T->getPointeeType());
- }
-
- TemplateTypeParmDecl *VisitBlockPointerType(const BlockPointerType *T) {
- return Visit(T->getPointeeType());
- }
-
- TemplateTypeParmDecl *VisitReferenceType(const ReferenceType *T) {
- return Visit(T->getPointeeTypeAsWritten());
- }
-
- TemplateTypeParmDecl *VisitMemberPointerType(const MemberPointerType *T) {
- return Visit(T->getPointeeType());
- }
-
- TemplateTypeParmDecl *VisitArrayType(const ArrayType *T) {
- return Visit(T->getElementType());
- }
-
- TemplateTypeParmDecl *VisitDependentSizedExtVectorType(
- const DependentSizedExtVectorType *T) {
- return Visit(T->getElementType());
- }
-
- TemplateTypeParmDecl *VisitVectorType(const VectorType *T) {
- return Visit(T->getElementType());
- }
-
- TemplateTypeParmDecl *VisitFunctionProtoType(const FunctionProtoType *T) {
- return VisitFunctionType(T);
- }
-
- TemplateTypeParmDecl *VisitFunctionType(const FunctionType *T) {
- return Visit(T->getReturnType());
- }
-
- TemplateTypeParmDecl *VisitParenType(const ParenType *T) {
- return Visit(T->getInnerType());
- }
-
- TemplateTypeParmDecl *VisitAttributedType(const AttributedType *T) {
- return Visit(T->getModifiedType());
- }
-
- TemplateTypeParmDecl *VisitMacroQualifiedType(const MacroQualifiedType *T) {
- return Visit(T->getUnderlyingType());
- }
-
- TemplateTypeParmDecl *VisitAdjustedType(const AdjustedType *T) {
- return Visit(T->getOriginalType());
- }
-
- TemplateTypeParmDecl *VisitPackExpansionType(const PackExpansionType *T) {
- return Visit(T->getPattern());
- }
- };
-
-} // namespace
-
ParmVarDecl *Sema::SubstParmVarDecl(ParmVarDecl *OldParm,
const MultiLevelTemplateArgumentList &TemplateArgs,
int indexAdjustment,
return nullptr;
}
- // In abbreviated templates, TemplateTypeParmDecls with possible
- // TypeConstraints are created when the parameter list is originally parsed.
- // The TypeConstraints can therefore reference other functions parameters in
- // the abbreviated function template, which is why we must instantiate them
- // here, when the instantiated versions of those referenced parameters are in
- // scope.
- if (TemplateTypeParmDecl *TTP =
- GetContainedInventedTypeParmVisitor().Visit(OldDI->getType())) {
- if (const TypeConstraint *TC = TTP->getTypeConstraint()) {
- // TODO: Concepts: do not instantiate the constraint (delayed constraint
- // substitution)
- const ASTTemplateArgumentListInfo *TemplArgInfo
- = TC->getTemplateArgsAsWritten();
- TemplateArgumentListInfo InstArgs;
-
- if (TemplArgInfo) {
- InstArgs.setLAngleLoc(TemplArgInfo->LAngleLoc);
- InstArgs.setRAngleLoc(TemplArgInfo->RAngleLoc);
- if (Subst(TemplArgInfo->getTemplateArgs(),
- TemplArgInfo->NumTemplateArgs, InstArgs, TemplateArgs))
- return nullptr;
- }
- auto *Inst = cast<TemplateTypeParmDecl>(
- FindInstantiatedDecl(TTP->getLocation(), TTP, TemplateArgs));
- if (AttachTypeConstraint(
- TC->getNestedNameSpecifierLoc(), TC->getConceptNameInfo(),
- TC->getNamedConcept(), &InstArgs, Inst,
- TTP->isParameterPack()
- ? cast<CXXFoldExpr>(TC->getImmediatelyDeclaredConstraint())
- ->getEllipsisLoc()
- : SourceLocation()))
- return nullptr;
- }
- }
-
ParmVarDecl *NewParm = CheckParameter(Context.getTranslationUnitDecl(),
OldParm->getInnerLocStart(),
OldParm->getLocation(),
Inst->setAccess(AS_public);
Inst->setImplicit(D->isImplicit());
if (auto *TC = D->getTypeConstraint()) {
- if (!D->isImplicit()) {
- // Invented template parameter type constraints will be instantiated with
- // the corresponding auto-typed parameter as it might reference other
- // parameters.
-
- // TODO: Concepts: do not instantiate the constraint (delayed constraint
- // substitution)
- const ASTTemplateArgumentListInfo *TemplArgInfo
- = TC->getTemplateArgsAsWritten();
- TemplateArgumentListInfo InstArgs;
-
- if (TemplArgInfo) {
- InstArgs.setLAngleLoc(TemplArgInfo->LAngleLoc);
- InstArgs.setRAngleLoc(TemplArgInfo->RAngleLoc);
- if (SemaRef.Subst(TemplArgInfo->getTemplateArgs(),
- TemplArgInfo->NumTemplateArgs,
- InstArgs, TemplateArgs))
- return nullptr;
- }
- if (SemaRef.AttachTypeConstraint(
- TC->getNestedNameSpecifierLoc(), TC->getConceptNameInfo(),
- TC->getNamedConcept(), &InstArgs, Inst,
- D->isParameterPack()
- ? cast<CXXFoldExpr>(TC->getImmediatelyDeclaredConstraint())
- ->getEllipsisLoc()
- : SourceLocation()))
+ // TODO: Concepts: do not instantiate the constraint (delayed constraint
+ // substitution)
+ const ASTTemplateArgumentListInfo *TemplArgInfo
+ = TC->getTemplateArgsAsWritten();
+ TemplateArgumentListInfo InstArgs;
+
+ if (TemplArgInfo) {
+ InstArgs.setLAngleLoc(TemplArgInfo->LAngleLoc);
+ InstArgs.setRAngleLoc(TemplArgInfo->RAngleLoc);
+ if (SemaRef.Subst(TemplArgInfo->getTemplateArgs(),
+ TemplArgInfo->NumTemplateArgs,
+ InstArgs, TemplateArgs))
return nullptr;
}
+ if (SemaRef.AttachTypeConstraint(
+ TC->getNestedNameSpecifierLoc(), TC->getConceptNameInfo(),
+ TC->getNamedConcept(), &InstArgs, Inst,
+ D->isParameterPack()
+ ? cast<CXXFoldExpr>(TC->getImmediatelyDeclaredConstraint())
+ ->getEllipsisLoc()
+ : SourceLocation()))
+ return nullptr;
}
if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited()) {
TypeSourceInfo *InstantiatedDefaultArg =
+++ /dev/null
-// RUN: %clang_cc1 -std=c++2a -x c++ %s -verify
-// expected-no-diagnostics
-
-template<typename...>
-concept C = true;
-
-template<typename T>
-struct S {
- template<typename U>
- static void foo1(U a, auto b);
- static void foo2(T a, C<T> auto b);
- static void foo3(T a, C<decltype(a)> auto b);
- static void foo4(T a, C<decltype(a)> auto b, const C<decltype(b)> auto &&c);
-};
-
-using sf1 = decltype(S<int>::foo1(1, 2));
-using sf2 = decltype(S<int>::foo2(1, 2));
-using sf3 = decltype(S<int>::foo3(1, 2));
-using sf4 = decltype(S<int>::foo4(1, 2, 3));
-
-
-template<typename... T>
-struct G {
- static void foo1(auto a, const C<decltype(a)> auto &&... b);
- static void foo2(auto a, const C<decltype(a), T> auto &&... b);
-};
-
-using gf1 = decltype(G<int, char>::foo1('a', 1, 2, 3, 4));
-using gf2 = decltype(G<int, char>::foo2('a', 1, 2));