diff options
author | Richard Smith <richard@metafoo.co.uk> | 2020-09-20 23:16:08 -0700 |
---|---|---|
committer | Richard Smith <richard@metafoo.co.uk> | 2020-10-21 13:21:41 -0700 |
commit | ba4768c966581658465f7366df9b0811f468a2d7 (patch) | |
tree | edf8c81d55613e4493f7793f0c8138b57c08580d /clang/lib/Sema/SemaInit.cpp | |
parent | 1d1217c4ea115ac204f666a31686787503623dfa (diff) | |
download | llvm-ba4768c966581658465f7366df9b0811f468a2d7.zip llvm-ba4768c966581658465f7366df9b0811f468a2d7.tar.gz llvm-ba4768c966581658465f7366df9b0811f468a2d7.tar.bz2 |
[c++20] For P0732R2 / P1907R1: Basic frontend support for class types as
non-type template parameters.
Create a unique TemplateParamObjectDecl instance for each such value,
representing the globally unique template parameter object to which the
template parameter refers.
No IR generation support yet; that will follow in a separate patch.
Diffstat (limited to 'clang/lib/Sema/SemaInit.cpp')
-rw-r--r-- | clang/lib/Sema/SemaInit.cpp | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 485cb85..419b25d 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -1123,6 +1123,7 @@ static void warnBracedScalarInit(Sema &S, const InitializedEntity &Entity, case InitializedEntity::EK_ArrayElement: case InitializedEntity::EK_Parameter: case InitializedEntity::EK_Parameter_CF_Audited: + case InitializedEntity::EK_TemplateParameter: case InitializedEntity::EK_Result: // Extra braces here are suspicious. DiagID = diag::warn_braces_around_init; @@ -3283,6 +3284,7 @@ DeclarationName InitializedEntity::getName() const { case EK_Variable: case EK_Member: case EK_Binding: + case EK_TemplateParameter: return Variable.VariableOrMember->getDeclName(); case EK_LambdaCapture: @@ -3313,6 +3315,7 @@ ValueDecl *InitializedEntity::getDecl() const { case EK_Variable: case EK_Member: case EK_Binding: + case EK_TemplateParameter: return Variable.VariableOrMember; case EK_Parameter: @@ -3350,6 +3353,7 @@ bool InitializedEntity::allowsNRVO() const { case EK_Variable: case EK_Parameter: case EK_Parameter_CF_Audited: + case EK_TemplateParameter: case EK_Member: case EK_Binding: case EK_New: @@ -3381,6 +3385,7 @@ unsigned InitializedEntity::dumpImpl(raw_ostream &OS) const { case EK_Parameter: OS << "Parameter"; break; case EK_Parameter_CF_Audited: OS << "CF audited function Parameter"; break; + case EK_TemplateParameter: OS << "TemplateParameter"; break; case EK_Result: OS << "Result"; break; case EK_StmtExprResult: OS << "StmtExprResult"; break; case EK_Exception: OS << "Exception"; break; @@ -6001,6 +6006,11 @@ getAssignmentAction(const InitializedEntity &Entity, bool Diagnose = false) { // FIXME: Can we tell apart casting vs. converting? return Sema::AA_Casting; + case InitializedEntity::EK_TemplateParameter: + // This is really initialization, but refer to it as conversion for + // consistency with CheckConvertedConstantExpression. + return Sema::AA_Converting; + case InitializedEntity::EK_Member: case InitializedEntity::EK_Binding: case InitializedEntity::EK_ArrayElement: @@ -6035,6 +6045,7 @@ static bool shouldBindAsTemporary(const InitializedEntity &Entity) { case InitializedEntity::EK_LambdaToBlockConversionBlockElement: case InitializedEntity::EK_LambdaCapture: case InitializedEntity::EK_CompoundLiteralInit: + case InitializedEntity::EK_TemplateParameter: return false; case InitializedEntity::EK_Parameter: @@ -6069,6 +6080,7 @@ static bool shouldDestroyEntity(const InitializedEntity &Entity) { case InitializedEntity::EK_Variable: case InitializedEntity::EK_Parameter: case InitializedEntity::EK_Parameter_CF_Audited: + case InitializedEntity::EK_TemplateParameter: case InitializedEntity::EK_Temporary: case InitializedEntity::EK_ArrayElement: case InitializedEntity::EK_Exception: @@ -6102,6 +6114,7 @@ static SourceLocation getInitializationLoc(const InitializedEntity &Entity, case InitializedEntity::EK_Member: case InitializedEntity::EK_Parameter: case InitializedEntity::EK_Parameter_CF_Audited: + case InitializedEntity::EK_TemplateParameter: case InitializedEntity::EK_Temporary: case InitializedEntity::EK_New: case InitializedEntity::EK_Base: @@ -6345,7 +6358,7 @@ static void CheckCXX98CompatAccessibleCopy(Sema &S, void InitializationSequence::PrintInitLocationNote(Sema &S, const InitializedEntity &Entity) { - if (Entity.isParameterKind() && Entity.getDecl()) { + if (Entity.isParamOrTemplateParamKind() && Entity.getDecl()) { if (Entity.getDecl()->getLocation().isInvalid()) return; @@ -6611,6 +6624,10 @@ static LifetimeResult getEntityLifetime( // the call. return {nullptr, LK_FullExpression}; + case InitializedEntity::EK_TemplateParameter: + // FIXME: This will always be ill-formed; should we eagerly diagnose it here? + return {nullptr, LK_FullExpression}; + case InitializedEntity::EK_Result: // -- The lifetime of a temporary bound to the returned value in a // function return statement is not extended; the temporary is @@ -7882,7 +7899,7 @@ ExprResult InitializationSequence::Perform(Sema &S, if (S.getLangOpts().CPlusPlus11 && Entity.getType()->isReferenceType() && Args.size() == 1 && isa<InitListExpr>(Args[0]) && - !Entity.isParameterKind()) { + !Entity.isParamOrTemplateParamKind()) { // Produce a C++98 compatibility warning if we are initializing a reference // from an initializer list. For parameters, we produce a better warning // elsewhere. |