aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/Sema
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/clang/lib/Sema')
-rw-r--r--contrib/llvm-project/clang/lib/Sema/SemaExpr.cpp1
-rw-r--r--contrib/llvm-project/clang/lib/Sema/SemaLambda.cpp3
-rw-r--r--contrib/llvm-project/clang/lib/Sema/SemaTemplateDeduction.cpp7
-rw-r--r--contrib/llvm-project/clang/lib/Sema/SemaTemplateVariadic.cpp3
-rw-r--r--contrib/llvm-project/clang/lib/Sema/SemaType.cpp119
5 files changed, 73 insertions, 60 deletions
diff --git a/contrib/llvm-project/clang/lib/Sema/SemaExpr.cpp b/contrib/llvm-project/clang/lib/Sema/SemaExpr.cpp
index d301e6c732ab..610a77c0e6f2 100644
--- a/contrib/llvm-project/clang/lib/Sema/SemaExpr.cpp
+++ b/contrib/llvm-project/clang/lib/Sema/SemaExpr.cpp
@@ -4345,7 +4345,6 @@ static void captureVariablyModifiedType(ASTContext &Context, QualType T,
case Type::UnaryTransform:
case Type::Attributed:
case Type::SubstTemplateTypeParm:
- case Type::PackExpansion:
case Type::MacroQualified:
// Keep walking after single level desugaring.
T = T.getSingleStepDesugaredType(Context);
diff --git a/contrib/llvm-project/clang/lib/Sema/SemaLambda.cpp b/contrib/llvm-project/clang/lib/Sema/SemaLambda.cpp
index 657ed13f207a..dc74f6e2f7dc 100644
--- a/contrib/llvm-project/clang/lib/Sema/SemaLambda.cpp
+++ b/contrib/llvm-project/clang/lib/Sema/SemaLambda.cpp
@@ -803,7 +803,8 @@ QualType Sema::buildLambdaInitCaptureInitialization(
Diag(EllipsisLoc, getLangOpts().CPlusPlus20
? diag::warn_cxx17_compat_init_capture_pack
: diag::ext_init_capture_pack);
- DeductType = Context.getPackExpansionType(DeductType, NumExpansions);
+ DeductType = Context.getPackExpansionType(DeductType, NumExpansions,
+ /*ExpectPackInType=*/false);
TLB.push<PackExpansionTypeLoc>(DeductType).setEllipsisLoc(EllipsisLoc);
} else {
// Just ignore the ellipsis for now and form a non-pack variable. We'll
diff --git a/contrib/llvm-project/clang/lib/Sema/SemaTemplateDeduction.cpp b/contrib/llvm-project/clang/lib/Sema/SemaTemplateDeduction.cpp
index 5392be57a3aa..eb8677d0e481 100644
--- a/contrib/llvm-project/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/contrib/llvm-project/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -4894,6 +4894,13 @@ QualType Sema::ReplaceAutoType(QualType TypeWithAuto,
.TransformType(TypeWithAuto);
}
+TypeSourceInfo *Sema::ReplaceAutoTypeSourceInfo(TypeSourceInfo *TypeWithAuto,
+ QualType TypeToReplaceAuto) {
+ return SubstituteDeducedTypeTransform(*this, TypeToReplaceAuto,
+ /*UseTypeSugar*/ false)
+ .TransformType(TypeWithAuto);
+}
+
void Sema::DiagnoseAutoDeductionFailure(VarDecl *VDecl, Expr *Init) {
if (isa<InitListExpr>(Init))
Diag(VDecl->getLocation(),
diff --git a/contrib/llvm-project/clang/lib/Sema/SemaTemplateVariadic.cpp b/contrib/llvm-project/clang/lib/Sema/SemaTemplateVariadic.cpp
index 7b77d1cb482a..259cc5165776 100644
--- a/contrib/llvm-project/clang/lib/Sema/SemaTemplateVariadic.cpp
+++ b/contrib/llvm-project/clang/lib/Sema/SemaTemplateVariadic.cpp
@@ -614,7 +614,8 @@ QualType Sema::CheckPackExpansion(QualType Pattern, SourceRange PatternRange,
return QualType();
}
- return Context.getPackExpansionType(Pattern, NumExpansions);
+ return Context.getPackExpansionType(Pattern, NumExpansions,
+ /*ExpectPackInType=*/false);
}
ExprResult Sema::ActOnPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc) {
diff --git a/contrib/llvm-project/clang/lib/Sema/SemaType.cpp b/contrib/llvm-project/clang/lib/Sema/SemaType.cpp
index cc151a048b98..f2c3c6373948 100644
--- a/contrib/llvm-project/clang/lib/Sema/SemaType.cpp
+++ b/contrib/llvm-project/clang/lib/Sema/SemaType.cpp
@@ -3101,24 +3101,10 @@ static void diagnoseRedundantReturnTypeQualifiers(Sema &S, QualType RetTy,
D.getDeclSpec().getUnalignedSpecLoc());
}
-static void CopyTypeConstraintFromAutoType(Sema &SemaRef, const AutoType *Auto,
- AutoTypeLoc AutoLoc,
- TemplateTypeParmDecl *TP,
- SourceLocation EllipsisLoc) {
-
- TemplateArgumentListInfo TAL(AutoLoc.getLAngleLoc(), AutoLoc.getRAngleLoc());
- for (unsigned Idx = 0; Idx < AutoLoc.getNumArgs(); ++Idx)
- TAL.addArgument(AutoLoc.getArgLoc(Idx));
-
- SemaRef.AttachTypeConstraint(
- AutoLoc.getNestedNameSpecifierLoc(), AutoLoc.getConceptNameInfo(),
- AutoLoc.getNamedConcept(),
- AutoLoc.hasExplicitTemplateArgs() ? &TAL : nullptr, TP, EllipsisLoc);
-}
-
-static QualType InventTemplateParameter(
- TypeProcessingState &state, QualType T, TypeSourceInfo *TSI, AutoType *Auto,
- InventedTemplateParameterInfo &Info) {
+static std::pair<QualType, TypeSourceInfo *>
+InventTemplateParameter(TypeProcessingState &state, QualType T,
+ TypeSourceInfo *TrailingTSI, AutoType *Auto,
+ InventedTemplateParameterInfo &Info) {
Sema &S = state.getSema();
Declarator &D = state.getDeclarator();
@@ -3143,13 +3129,25 @@ static QualType InventTemplateParameter(
IsParameterPack, /*HasTypeConstraint=*/Auto->isConstrained());
InventedTemplateParam->setImplicit();
Info.TemplateParams.push_back(InventedTemplateParam);
- // Attach type constraints
+
+ // Attach type constraints to the new parameter.
if (Auto->isConstrained()) {
- if (TSI) {
- CopyTypeConstraintFromAutoType(
- S, Auto, TSI->getTypeLoc().getContainedAutoTypeLoc(),
- InventedTemplateParam, D.getEllipsisLoc());
+ if (TrailingTSI) {
+ // The 'auto' appears in a trailing return type we've already built;
+ // extract its type constraints to attach to the template parameter.
+ AutoTypeLoc AutoLoc = TrailingTSI->getTypeLoc().getContainedAutoTypeLoc();
+ TemplateArgumentListInfo TAL(AutoLoc.getLAngleLoc(), AutoLoc.getRAngleLoc());
+ for (unsigned Idx = 0; Idx < AutoLoc.getNumArgs(); ++Idx)
+ TAL.addArgument(AutoLoc.getArgLoc(Idx));
+
+ S.AttachTypeConstraint(AutoLoc.getNestedNameSpecifierLoc(),
+ AutoLoc.getConceptNameInfo(),
+ AutoLoc.getNamedConcept(),
+ AutoLoc.hasExplicitTemplateArgs() ? &TAL : nullptr,
+ InventedTemplateParam, D.getEllipsisLoc());
} else {
+ // The 'auto' appears in the decl-specifiers; we've not finished forming
+ // TypeSourceInfo for it yet.
TemplateIdAnnotation *TemplateId = D.getDeclSpec().getRepAsTemplateId();
TemplateArgumentListInfo TemplateArgsInfo;
if (TemplateId->LAngleLoc.isValid()) {
@@ -3167,15 +3165,16 @@ static QualType InventTemplateParameter(
}
}
- // If TSI is nullptr, this is a constrained declspec auto and the type
- // constraint will be attached later in TypeSpecLocFiller
-
// Replace the 'auto' in the function parameter with this invented
// template type parameter.
// FIXME: Retain some type sugar to indicate that this was written
// as 'auto'?
- return state.ReplaceAutoType(
- T, QualType(InventedTemplateParam->getTypeForDecl(), 0));
+ QualType Replacement(InventedTemplateParam->getTypeForDecl(), 0);
+ QualType NewT = state.ReplaceAutoType(T, Replacement);
+ TypeSourceInfo *NewTSI =
+ TrailingTSI ? S.ReplaceAutoTypeSourceInfo(TrailingTSI, Replacement)
+ : nullptr;
+ return {NewT, NewTSI};
}
static TypeSourceInfo *
@@ -3234,8 +3233,19 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state,
if (!D.getAttributes().empty())
distributeTypeAttrsFromDeclarator(state, T);
+ // Find the deduced type in this type. Look in the trailing return type if we
+ // have one, otherwise in the DeclSpec type.
+ // FIXME: The standard wording doesn't currently describe this.
+ DeducedType *Deduced = T->getContainedDeducedType();
+ bool DeducedIsTrailingReturnType = false;
+ if (Deduced && isa<AutoType>(Deduced) && D.hasTrailingReturnType()) {
+ QualType T = SemaRef.GetTypeFromParser(D.getTrailingReturnType());
+ Deduced = T.isNull() ? nullptr : T->getContainedDeducedType();
+ DeducedIsTrailingReturnType = true;
+ }
+
// C++11 [dcl.spec.auto]p5: reject 'auto' if it is not in an allowed context.
- if (DeducedType *Deduced = T->getContainedDeducedType()) {
+ if (Deduced) {
AutoType *Auto = dyn_cast<AutoType>(Deduced);
int Error = -1;
@@ -3269,10 +3279,6 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state,
} else if (!SemaRef.getCurScope()->isFunctionDeclarationScope()) {
Error = 21;
break;
- } else if (D.hasTrailingReturnType()) {
- // This might be OK, but we'll need to convert the trailing return
- // type later.
- break;
}
Info = &SemaRef.InventedParameterInfos.back();
@@ -3286,7 +3292,12 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state,
Info = SemaRef.getCurLambda();
assert(Info && "No LambdaScopeInfo on the stack!");
}
- T = InventTemplateParameter(state, T, nullptr, Auto, *Info);
+
+ // We'll deal with inventing template parameters for 'auto' in trailing
+ // return types when we pick up the trailing return type when processing
+ // the function chunk.
+ if (!DeducedIsTrailingReturnType)
+ T = InventTemplateParameter(state, T, nullptr, Auto, *Info).first;
break;
}
case DeclaratorContext::MemberContext: {
@@ -3384,20 +3395,6 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state,
(!SemaRef.getLangOpts().CPlusPlus11 || !IsCXXAutoType))
Error = 13;
- bool HaveTrailing = false;
-
- // C++11 [dcl.spec.auto]p2: 'auto' is always fine if the declarator
- // contains a trailing return type. That is only legal at the outermost
- // level. Check all declarator chunks (outermost first) anyway, to give
- // better diagnostics.
- // We don't support '__auto_type' with trailing return types.
- // FIXME: Should we only do this for 'auto' and not 'decltype(auto)'?
- if (SemaRef.getLangOpts().CPlusPlus11 && IsCXXAutoType &&
- D.hasTrailingReturnType()) {
- HaveTrailing = true;
- Error = -1;
- }
-
SourceRange AutoRange = D.getDeclSpec().getTypeSpecTypeLoc();
if (D.getName().getKind() == UnqualifiedIdKind::IK_ConversionFunctionId)
AutoRange = D.getName().getSourceRange();
@@ -3427,8 +3424,7 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state,
T = SemaRef.Context.IntTy;
D.setInvalidType(true);
- } else if (Auto && !HaveTrailing &&
- D.getContext() != DeclaratorContext::LambdaExprContext) {
+ } else if (Auto && D.getContext() != DeclaratorContext::LambdaExprContext) {
// If there was a trailing return type, we already got
// warn_cxx98_compat_trailing_return_type in the parser.
SemaRef.Diag(AutoRange.getBegin(),
@@ -4881,12 +4877,21 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
// An error occurred parsing the trailing return type.
T = Context.IntTy;
D.setInvalidType(true);
- } else if (S.getLangOpts().CPlusPlus20)
- // Handle cases like: `auto f() -> auto` or `auto f() -> C auto`.
- if (AutoType *Auto = T->getContainedAutoType())
- if (S.getCurScope()->isFunctionDeclarationScope())
- T = InventTemplateParameter(state, T, TInfo, Auto,
- S.InventedParameterInfos.back());
+ } else if (AutoType *Auto = T->getContainedAutoType()) {
+ // If the trailing return type contains an `auto`, we may need to
+ // invent a template parameter for it, for cases like
+ // `auto f() -> C auto` or `[](auto (*p) -> auto) {}`.
+ InventedTemplateParameterInfo *InventedParamInfo = nullptr;
+ if (D.getContext() == DeclaratorContext::PrototypeContext)
+ InventedParamInfo = &S.InventedParameterInfos.back();
+ else if (D.getContext() ==
+ DeclaratorContext::LambdaExprParameterContext)
+ InventedParamInfo = S.getCurLambda();
+ if (InventedParamInfo) {
+ std::tie(T, TInfo) = InventTemplateParameter(
+ state, T, TInfo, Auto, *InventedParamInfo);
+ }
+ }
} else {
// This function type is not the type of the entity being declared,
// so checking the 'auto' is not the responsibility of this chunk.
@@ -5518,7 +5523,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
<< T << D.getSourceRange();
D.setEllipsisLoc(SourceLocation());
} else {
- T = Context.getPackExpansionType(T, None);
+ T = Context.getPackExpansionType(T, None, /*ExpectPackInType=*/false);
}
break;
case DeclaratorContext::TemplateParamContext: