Skip to content

Commit 4b57400

Browse files
committed
[c++20] P1907R1: Support for generalized non-type template arguments of scalar type.
Previously committed as 9e08e51, and reverted because a dependency commit was reverted. This incorporates the following follow-on commits that were also reverted: 7e84aa1 by Simon Pilgrim ed13d8c by me 95c7b6c by Sam McCall 430d5d8 by Dave Zarzycki
1 parent 5a391d3 commit 4b57400

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+632
-191
lines changed

clang-tools-extra/clangd/DumpAST.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ class DumpVisitor : public RecursiveASTVisitor<DumpVisitor> {
143143
TEMPLATE_ARGUMENT_KIND(Declaration);
144144
TEMPLATE_ARGUMENT_KIND(Template);
145145
TEMPLATE_ARGUMENT_KIND(TemplateExpansion);
146+
TEMPLATE_ARGUMENT_KIND(UncommonValue);
146147
#undef TEMPLATE_ARGUMENT_KIND
147148
}
148149
llvm_unreachable("Unhandled ArgKind enum");

clang-tools-extra/clangd/FindTarget.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1079,6 +1079,7 @@ class ExplicitReferenceCollector
10791079
case TemplateArgument::Pack:
10801080
case TemplateArgument::Type:
10811081
case TemplateArgument::Expression:
1082+
case TemplateArgument::UncommonValue:
10821083
break; // Handled by VisitType and VisitExpression.
10831084
};
10841085
return RecursiveASTVisitor::TraverseTemplateArgumentLoc(A);

clang-tools-extra/clangd/index/remote/Client.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,8 @@ class IndexClient : public clangd::SymbolIndex {
152152
});
153153
}
154154

155-
llvm::unique_function<bool(llvm::StringRef) const> indexedFiles() const {
155+
llvm::unique_function<bool(llvm::StringRef) const>
156+
indexedFiles() const override {
156157
// FIXME: For now we always return "false" regardless of whether the file
157158
// was indexed or not. A possible implementation could be based on
158159
// the idea that we do not want to send a request at every

clang/include/clang/AST/ASTContext.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2818,8 +2818,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
28182818
/// for destruction.
28192819
template <typename T> void addDestruction(T *Ptr) const {
28202820
if (!std::is_trivially_destructible<T>::value) {
2821-
auto DestroyPtr = [](void *V) { static_cast<T *>(V)->~T(); };
2822-
AddDeallocation(DestroyPtr, Ptr);
2821+
auto DestroyPtr = [](void *V) { ((T*)V)->~T(); };
2822+
AddDeallocation(DestroyPtr, (void*)Ptr);
28232823
}
28242824
}
28252825

clang/include/clang/AST/PropertiesBase.td

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -758,6 +758,17 @@ let Class = PropertyTypeCase<TemplateArgument, "Integral"> in {
758758
return TemplateArgument(ctx, value, type);
759759
}]>;
760760
}
761+
let Class = PropertyTypeCase<TemplateArgument, "UncommonValue"> in {
762+
def : Property<"value", APValue> {
763+
let Read = [{ node.getAsUncommonValue() }];
764+
}
765+
def : Property<"type", QualType> {
766+
let Read = [{ node.getUncommonValueType() }];
767+
}
768+
def : Creator<[{
769+
return TemplateArgument(ctx, type, value);
770+
}]>;
771+
}
761772
let Class = PropertyTypeCase<TemplateArgument, "Template"> in {
762773
def : Property<"name", TemplateName> {
763774
let Read = [{ node.getAsTemplateOrTemplatePattern() }];

clang/include/clang/AST/RecursiveASTVisitor.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -768,6 +768,7 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateArgument(
768768
case TemplateArgument::Declaration:
769769
case TemplateArgument::Integral:
770770
case TemplateArgument::NullPtr:
771+
case TemplateArgument::UncommonValue:
771772
return true;
772773

773774
case TemplateArgument::Type:
@@ -801,6 +802,7 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLoc(
801802
case TemplateArgument::Declaration:
802803
case TemplateArgument::Integral:
803804
case TemplateArgument::NullPtr:
805+
case TemplateArgument::UncommonValue:
804806
return true;
805807

806808
case TemplateArgument::Type: {

clang/include/clang/AST/TemplateArgumentVisitor.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class Base {
3737
DISPATCH(Declaration);
3838
DISPATCH(NullPtr);
3939
DISPATCH(Integral);
40+
DISPATCH(UncommonValue);
4041
DISPATCH(Template);
4142
DISPATCH(TemplateExpansion);
4243
DISPATCH(Expression);
@@ -59,6 +60,7 @@ class Base {
5960
VISIT_METHOD(Declaration);
6061
VISIT_METHOD(NullPtr);
6162
VISIT_METHOD(Integral);
63+
VISIT_METHOD(UncommonValue);
6264
VISIT_METHOD(Template);
6365
VISIT_METHOD(TemplateExpansion);
6466
VISIT_METHOD(Expression);

clang/include/clang/AST/TemplateBase.h

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ template <> struct PointerLikeTypeTraits<clang::Expr *> {
5151

5252
namespace clang {
5353

54+
class APValue;
5455
class ASTContext;
5556
class DiagnosticBuilder;
5657
class Expr;
@@ -82,6 +83,12 @@ class TemplateArgument {
8283
/// that was provided for an integral non-type template parameter.
8384
Integral,
8485

86+
/// The template argument is a non-type template argument that can't be
87+
/// represented by the special-case Declaration, NullPtr, or Integral
88+
/// forms. These values are only ever produced by constant evaluation,
89+
/// so cannot be dependent.
90+
UncommonValue,
91+
8592
/// The template argument is a template name that was provided for a
8693
/// template template parameter.
8794
Template,
@@ -125,6 +132,11 @@ class TemplateArgument {
125132
};
126133
void *Type;
127134
};
135+
struct V {
136+
unsigned Kind;
137+
const APValue *Value;
138+
void *Type;
139+
};
128140
struct A {
129141
unsigned Kind;
130142
unsigned NumArgs;
@@ -142,6 +154,7 @@ class TemplateArgument {
142154
union {
143155
struct DA DeclArg;
144156
struct I Integer;
157+
struct V Value;
145158
struct A Args;
146159
struct TA TemplateArg;
147160
struct TV TypeOrValue;
@@ -157,9 +170,8 @@ class TemplateArgument {
157170
TypeOrValue.V = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
158171
}
159172

160-
/// Construct a template argument that refers to a
161-
/// declaration, which is either an external declaration or a
162-
/// template declaration.
173+
/// Construct a template argument that refers to a (non-dependent)
174+
/// declaration.
163175
TemplateArgument(ValueDecl *D, QualType QT) {
164176
assert(D && "Expected decl");
165177
DeclArg.Kind = Declaration;
@@ -169,7 +181,11 @@ class TemplateArgument {
169181

170182
/// Construct an integral constant template argument. The memory to
171183
/// store the value is allocated with Ctx.
172-
TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value, QualType Type);
184+
TemplateArgument(const ASTContext &Ctx, const llvm::APSInt &Value,
185+
QualType Type);
186+
187+
/// Construct a template argument from an arbitrary constant value.
188+
TemplateArgument(const ASTContext &Ctx, QualType Type, const APValue &Value);
173189

174190
/// Construct an integral constant template argument with the same
175191
/// value as Other but a different type.
@@ -340,6 +356,16 @@ class TemplateArgument {
340356
Integer.Type = T.getAsOpaquePtr();
341357
}
342358

359+
/// Get the value of an UncommonValue.
360+
const APValue &getAsUncommonValue() const {
361+
return *Value.Value;
362+
}
363+
364+
/// Get the type of an UncommonValue.
365+
QualType getUncommonValueType() const {
366+
return QualType::getFromOpaquePtr(Value.Type);
367+
}
368+
343369
/// If this is a non-type template argument, get its type. Otherwise,
344370
/// returns a null QualType.
345371
QualType getNonTypeTemplateArgumentType() const;
@@ -484,6 +510,7 @@ class TemplateArgumentLoc {
484510
assert(Argument.getKind() == TemplateArgument::NullPtr ||
485511
Argument.getKind() == TemplateArgument::Integral ||
486512
Argument.getKind() == TemplateArgument::Declaration ||
513+
Argument.getKind() == TemplateArgument::UncommonValue ||
487514
Argument.getKind() == TemplateArgument::Expression);
488515
}
489516

@@ -542,6 +569,11 @@ class TemplateArgumentLoc {
542569
return LocInfo.getAsExpr();
543570
}
544571

572+
Expr *getSourceUncommonValueExpression() const {
573+
assert(Argument.getKind() == TemplateArgument::UncommonValue);
574+
return LocInfo.getAsExpr();
575+
}
576+
545577
NestedNameSpecifierLoc getTemplateQualifierLoc() const {
546578
if (Argument.getKind() != TemplateArgument::Template &&
547579
Argument.getKind() != TemplateArgument::TemplateExpansion)

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4695,8 +4695,6 @@ def err_non_type_template_arg_subobject : Error<
46954695
"non-type template argument refers to subobject '%0'">;
46964696
def err_non_type_template_arg_addr_label_diff : Error<
46974697
"template argument / label address difference / what did you expect?">;
4698-
def err_non_type_template_arg_unsupported : Error<
4699-
"sorry, non-type template argument of type %0 is not yet supported">;
47004698
def err_template_arg_not_convertible : Error<
47014699
"non-type template argument of type %0 cannot be converted to a value "
47024700
"of type %1">;
@@ -4748,9 +4746,6 @@ def err_template_arg_not_object_or_func : Error<
47484746
"non-type template argument does not refer to an object or function">;
47494747
def err_template_arg_not_pointer_to_member_form : Error<
47504748
"non-type template argument is not a pointer to member constant">;
4751-
def err_template_arg_member_ptr_base_derived_not_supported : Error<
4752-
"sorry, non-type template argument of pointer-to-member type %1 that refers "
4753-
"to member %q0 of a different class is not supported yet">;
47544749
def ext_template_arg_extra_parens : ExtWarn<
47554750
"address non-type template argument cannot be surrounded by parentheses">;
47564751
def warn_cxx98_compat_template_arg_extra_parens : Warning<

clang/include/clang/Sema/Sema.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7735,8 +7735,8 @@ class Sema final {
77357735
QualType ParamType,
77367736
SourceLocation Loc);
77377737
ExprResult
7738-
BuildExpressionFromIntegralTemplateArgument(const TemplateArgument &Arg,
7739-
SourceLocation Loc);
7738+
BuildExpressionFromNonTypeTemplateArgument(const TemplateArgument &Arg,
7739+
SourceLocation Loc);
77407740

77417741
/// Enumeration describing how template parameter lists are compared
77427742
/// for equality.

0 commit comments

Comments
 (0)