[llvm-branch-commits] [clang-tools-extra] 8ba442b - Revert "Following up on PR48517, fix handling of template arguments that refer"
Hans Wennborg via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Wed Jan 20 07:05:59 PST 2021
Author: Hans Wennborg
Date: 2021-01-20T15:55:35+01:00
New Revision: 8ba442bc2136c9ab91c74826db7195e406b94fb7
URL: https://github.com/llvm/llvm-project/commit/8ba442bc2136c9ab91c74826db7195e406b94fb7
DIFF: https://github.com/llvm/llvm-project/commit/8ba442bc2136c9ab91c74826db7195e406b94fb7.diff
LOG: Revert "Following up on PR48517, fix handling of template arguments that refer"
Combined with 'da98651 - Revert "DR2064:
decltype(E) is only a dependent', this change (5a391d3) caused verifier
errors when building Chromium. See https://crbug.com/1168494#c1 for a
reproducer.
Additionally it reverts changes that were dependent on this one, see
below.
> Following up on PR48517, fix handling of template arguments that refer
> to dependent declarations.
>
> Treat an id-expression that names a local variable in a templated
> function as being instantiation-dependent.
>
> This addresses a language defect whereby a reference to a dependent
> declaration can be formed without any construct being value-dependent.
> Fixing that through value-dependence turns out to be problematic, so
> instead this patch takes the approach (proposed on the core reflector)
> of allowing the use of pointers or references to (but not values of)
> dependent declarations inside value-dependent expressions, and instead
> treating template arguments as dependent if they evaluate to a constant
> involving such dependent declarations.
>
> This ends up affecting a bunch of OpenMP tests, due to OpenMP
> imprecisely handling instantiation-dependent constructs, bailing out
> early instead of processing dependent constructs to the extent possible
> when handling the template.
>
> Previously committed as 8c1f2d15b826591cdf6bd6b468b8a7d23377b29e, and
> reverted because a dependency commit was reverted.
This reverts commit 5a391d38ac6c561ba908334d427f26124ed9132e.
It also restores clang/test/SemaCXX/coroutines.cpp to its state before
da986511fb9da1a46a0ca4dba2e49e2426036303.
Revert "[c++20] P1907R1: Support for generalized non-type template arguments of scalar type."
> Previously committed as 9e08e51a20d0d2b1c5724bb17e969d036fced4cd, and
> reverted because a dependency commit was reverted. This incorporates the
> following follow-on commits that were also reverted:
>
> 7e84aa1b81e72d44bcc58ffe1731bfc7abb73ce0 by Simon Pilgrim
> ed13d8c66781b50ff007cb089c5905f9bb9e8af2 by me
> 95c7b6cadbc9a3d4376ef44edbeb3c8bb5b8d7fc by Sam McCall
> 430d5d8429473c2b10b109991d7577a3cea41140 by Dave Zarzycki
This reverts commit 4b574008aef5a7235c1f894ab065fe300d26e786.
Revert "[msabi] Mangle a template argument referring to array-to-pointer decay"
> [msabi] Mangle a template argument referring to array-to-pointer decay
> applied to an array the same as the array itself.
>
> This follows MS ABI, and corrects a regression from the implementation
> of generalized non-type template parameters, where we "forgot" how to
> mangle this case.
This reverts commit 18e093faf726d15f210ab4917142beec51848258.
Added:
clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp
Modified:
clang-tools-extra/clangd/DumpAST.cpp
clang-tools-extra/clangd/FindTarget.cpp
clang-tools-extra/clangd/index/remote/Client.cpp
clang/include/clang/AST/ASTContext.h
clang/include/clang/AST/Expr.h
clang/include/clang/AST/PropertiesBase.td
clang/include/clang/AST/RecursiveASTVisitor.h
clang/include/clang/AST/TemplateArgumentVisitor.h
clang/include/clang/AST/TemplateBase.h
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/include/clang/Sema/Sema.h
clang/lib/AST/ASTContext.cpp
clang/lib/AST/ASTImporter.cpp
clang/lib/AST/ASTStructuralEquivalence.cpp
clang/lib/AST/ComputeDependence.cpp
clang/lib/AST/Decl.cpp
clang/lib/AST/Expr.cpp
clang/lib/AST/ExprCXX.cpp
clang/lib/AST/ExprConstant.cpp
clang/lib/AST/ItaniumMangle.cpp
clang/lib/AST/MicrosoftMangle.cpp
clang/lib/AST/ODRHash.cpp
clang/lib/AST/StmtProfile.cpp
clang/lib/AST/TemplateBase.cpp
clang/lib/AST/TypeLoc.cpp
clang/lib/CodeGen/CGDebugInfo.cpp
clang/lib/CodeGen/CGExprConstant.cpp
clang/lib/Index/USRGeneration.cpp
clang/lib/Sema/SemaLookup.cpp
clang/lib/Sema/SemaOverload.cpp
clang/lib/Sema/SemaTemplate.cpp
clang/lib/Sema/SemaTemplateDeduction.cpp
clang/lib/Sema/SemaTemplateInstantiate.cpp
clang/lib/Sema/SemaTemplateVariadic.cpp
clang/lib/Sema/TreeTransform.h
clang/lib/Serialization/ASTReader.cpp
clang/lib/Serialization/ASTWriter.cpp
clang/test/CodeGenCXX/mangle-ms-templates.cpp
clang/test/CodeGenCXX/mangle-template.cpp
clang/test/OpenMP/distribute_dist_schedule_messages.cpp
clang/test/OpenMP/distribute_parallel_for_dist_schedule_messages.cpp
clang/test/OpenMP/distribute_parallel_for_simd_dist_schedule_messages.cpp
clang/test/OpenMP/distribute_simd_dist_schedule_messages.cpp
clang/test/OpenMP/target_parallel_for_simd_collapse_messages.cpp
clang/test/OpenMP/target_parallel_for_simd_ordered_messages.cpp
clang/test/OpenMP/target_simd_collapse_messages.cpp
clang/test/OpenMP/target_teams_distribute_dist_schedule_messages.cpp
clang/test/OpenMP/target_teams_distribute_parallel_for_dist_schedule_messages.cpp
clang/test/OpenMP/target_teams_distribute_parallel_for_simd_dist_schedule_messages.cpp
clang/test/OpenMP/target_teams_distribute_simd_dist_schedule_messages.cpp
clang/test/OpenMP/target_update_from_messages.cpp
clang/test/OpenMP/target_update_to_messages.cpp
clang/test/OpenMP/task_messages.cpp
clang/test/OpenMP/teams_distribute_dist_schedule_messages.cpp
clang/test/OpenMP/teams_distribute_parallel_for_dist_schedule_messages.cpp
clang/test/OpenMP/teams_distribute_parallel_for_simd_dist_schedule_messages.cpp
clang/test/OpenMP/teams_distribute_simd_dist_schedule_messages.cpp
clang/test/SemaCXX/coroutines.cpp
clang/test/SemaCXX/warn-unused-lambda-capture.cpp
clang/test/SemaTemplate/temp_arg_nontype_cxx20.cpp
clang/tools/libclang/CIndex.cpp
clang/tools/libclang/CXCursor.cpp
lldb/include/lldb/lldb-enumerations.h
lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
Removed:
clang/test/CodeGenCXX/template-arguments.cpp
clang/test/SemaTemplate/temp_arg_nontype_cxx17.cpp
################################################################################
diff --git a/clang-tools-extra/clangd/DumpAST.cpp b/clang-tools-extra/clangd/DumpAST.cpp
index bf7675e7d949..588bcfcf2424 100644
--- a/clang-tools-extra/clangd/DumpAST.cpp
+++ b/clang-tools-extra/clangd/DumpAST.cpp
@@ -143,7 +143,6 @@ class DumpVisitor : public RecursiveASTVisitor<DumpVisitor> {
TEMPLATE_ARGUMENT_KIND(Declaration);
TEMPLATE_ARGUMENT_KIND(Template);
TEMPLATE_ARGUMENT_KIND(TemplateExpansion);
- TEMPLATE_ARGUMENT_KIND(UncommonValue);
#undef TEMPLATE_ARGUMENT_KIND
}
llvm_unreachable("Unhandled ArgKind enum");
diff --git a/clang-tools-extra/clangd/FindTarget.cpp b/clang-tools-extra/clangd/FindTarget.cpp
index 98ef8b3b6d76..84316659daad 100644
--- a/clang-tools-extra/clangd/FindTarget.cpp
+++ b/clang-tools-extra/clangd/FindTarget.cpp
@@ -1079,7 +1079,6 @@ class ExplicitReferenceCollector
case TemplateArgument::Pack:
case TemplateArgument::Type:
case TemplateArgument::Expression:
- case TemplateArgument::UncommonValue:
break; // Handled by VisitType and VisitExpression.
};
return RecursiveASTVisitor::TraverseTemplateArgumentLoc(A);
diff --git a/clang-tools-extra/clangd/index/remote/Client.cpp b/clang-tools-extra/clangd/index/remote/Client.cpp
index a153a8812baf..b09dbf915e46 100644
--- a/clang-tools-extra/clangd/index/remote/Client.cpp
+++ b/clang-tools-extra/clangd/index/remote/Client.cpp
@@ -152,8 +152,7 @@ class IndexClient : public clangd::SymbolIndex {
});
}
- llvm::unique_function<bool(llvm::StringRef) const>
- indexedFiles() const override {
+ llvm::unique_function<bool(llvm::StringRef) const> indexedFiles() const {
// FIXME: For now we always return "false" regardless of whether the file
// was indexed or not. A possible implementation could be based on
// the idea that we do not want to send a request at every
diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
index a9bfdb4d5fa5..0c5d82b3e9aa 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -2818,8 +2818,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// for destruction.
template <typename T> void addDestruction(T *Ptr) const {
if (!std::is_trivially_destructible<T>::value) {
- auto DestroyPtr = [](void *V) { ((T*)V)->~T(); };
- AddDeallocation(DestroyPtr, (void*)Ptr);
+ auto DestroyPtr = [](void *V) { static_cast<T *>(V)->~T(); };
+ AddDeallocation(DestroyPtr, Ptr);
}
}
diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index c963be98d3cb..a44d06967431 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -578,12 +578,12 @@ class Expr : public ValueStmt {
struct EvalStatus {
/// Whether the evaluated expression has side effects.
/// For example, (f() && 0) can be folded, but it still has side effects.
- bool HasSideEffects = false;
+ bool HasSideEffects;
/// Whether the evaluation hit undefined behavior.
/// For example, 1.0 / 0.0 can be folded to Inf, but has undefined behavior.
/// Likewise, INT_MAX + 1 can be folded to INT_MIN, but has UB.
- bool HasUndefinedBehavior = false;
+ bool HasUndefinedBehavior;
/// Diag - If this is non-null, it will be filled in with a stack of notes
/// indicating why evaluation failed (or why it failed to produce a constant
@@ -592,7 +592,10 @@ class Expr : public ValueStmt {
/// foldable. If the expression is foldable, but not a constant expression,
/// the notes will describes why it isn't a constant expression. If the
/// expression *is* a constant expression, no notes will be produced.
- SmallVectorImpl<PartialDiagnosticAt> *Diag = nullptr;
+ SmallVectorImpl<PartialDiagnosticAt> *Diag;
+
+ EvalStatus()
+ : HasSideEffects(false), HasUndefinedBehavior(false), Diag(nullptr) {}
// hasSideEffects - Return true if the evaluated expression has
// side effects.
@@ -603,11 +606,8 @@ class Expr : public ValueStmt {
/// EvalResult is a struct with detailed info about an evaluated expression.
struct EvalResult : EvalStatus {
- /// This is the value the expression can be folded to.
+ /// Val - This is the value the expression can be folded to.
APValue Val;
- /// Indicates whether Val contains a pointer or reference or pointer to
- /// member naming a templated entity, and thus the value is dependent.
- bool Dependent = false;
// isGlobalLValue - Return true if the evaluated lvalue expression
// is global.
diff --git a/clang/include/clang/AST/PropertiesBase.td b/clang/include/clang/AST/PropertiesBase.td
index 98229eeedaa5..a087cb406b29 100644
--- a/clang/include/clang/AST/PropertiesBase.td
+++ b/clang/include/clang/AST/PropertiesBase.td
@@ -758,17 +758,6 @@ let Class = PropertyTypeCase<TemplateArgument, "Integral"> in {
return TemplateArgument(ctx, value, type);
}]>;
}
-let Class = PropertyTypeCase<TemplateArgument, "UncommonValue"> in {
- def : Property<"value", APValue> {
- let Read = [{ node.getAsUncommonValue() }];
- }
- def : Property<"type", QualType> {
- let Read = [{ node.getUncommonValueType() }];
- }
- def : Creator<[{
- return TemplateArgument(ctx, type, value);
- }]>;
-}
let Class = PropertyTypeCase<TemplateArgument, "Template"> in {
def : Property<"name", TemplateName> {
let Read = [{ node.getAsTemplateOrTemplatePattern() }];
diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h
index 1426e569eabe..505ea700fd0e 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -768,7 +768,6 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateArgument(
case TemplateArgument::Declaration:
case TemplateArgument::Integral:
case TemplateArgument::NullPtr:
- case TemplateArgument::UncommonValue:
return true;
case TemplateArgument::Type:
@@ -802,7 +801,6 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLoc(
case TemplateArgument::Declaration:
case TemplateArgument::Integral:
case TemplateArgument::NullPtr:
- case TemplateArgument::UncommonValue:
return true;
case TemplateArgument::Type: {
diff --git a/clang/include/clang/AST/TemplateArgumentVisitor.h b/clang/include/clang/AST/TemplateArgumentVisitor.h
index 8c0da70b25eb..190aa97adf45 100644
--- a/clang/include/clang/AST/TemplateArgumentVisitor.h
+++ b/clang/include/clang/AST/TemplateArgumentVisitor.h
@@ -37,7 +37,6 @@ class Base {
DISPATCH(Declaration);
DISPATCH(NullPtr);
DISPATCH(Integral);
- DISPATCH(UncommonValue);
DISPATCH(Template);
DISPATCH(TemplateExpansion);
DISPATCH(Expression);
@@ -60,7 +59,6 @@ class Base {
VISIT_METHOD(Declaration);
VISIT_METHOD(NullPtr);
VISIT_METHOD(Integral);
- VISIT_METHOD(UncommonValue);
VISIT_METHOD(Template);
VISIT_METHOD(TemplateExpansion);
VISIT_METHOD(Expression);
diff --git a/clang/include/clang/AST/TemplateBase.h b/clang/include/clang/AST/TemplateBase.h
index d2a24da3c842..1671637521e2 100644
--- a/clang/include/clang/AST/TemplateBase.h
+++ b/clang/include/clang/AST/TemplateBase.h
@@ -51,7 +51,6 @@ template <> struct PointerLikeTypeTraits<clang::Expr *> {
namespace clang {
-class APValue;
class ASTContext;
class DiagnosticBuilder;
class Expr;
@@ -83,12 +82,6 @@ class TemplateArgument {
/// that was provided for an integral non-type template parameter.
Integral,
- /// The template argument is a non-type template argument that can't be
- /// represented by the special-case Declaration, NullPtr, or Integral
- /// forms. These values are only ever produced by constant evaluation,
- /// so cannot be dependent.
- UncommonValue,
-
/// The template argument is a template name that was provided for a
/// template template parameter.
Template,
@@ -132,11 +125,6 @@ class TemplateArgument {
};
void *Type;
};
- struct V {
- unsigned Kind;
- const APValue *Value;
- void *Type;
- };
struct A {
unsigned Kind;
unsigned NumArgs;
@@ -154,7 +142,6 @@ class TemplateArgument {
union {
struct DA DeclArg;
struct I Integer;
- struct V Value;
struct A Args;
struct TA TemplateArg;
struct TV TypeOrValue;
@@ -170,8 +157,9 @@ class TemplateArgument {
TypeOrValue.V = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
}
- /// Construct a template argument that refers to a (non-dependent)
- /// declaration.
+ /// Construct a template argument that refers to a
+ /// declaration, which is either an external declaration or a
+ /// template declaration.
TemplateArgument(ValueDecl *D, QualType QT) {
assert(D && "Expected decl");
DeclArg.Kind = Declaration;
@@ -181,11 +169,7 @@ class TemplateArgument {
/// Construct an integral constant template argument. The memory to
/// store the value is allocated with Ctx.
- TemplateArgument(const ASTContext &Ctx, const llvm::APSInt &Value,
- QualType Type);
-
- /// Construct a template argument from an arbitrary constant value.
- TemplateArgument(const ASTContext &Ctx, QualType Type, const APValue &Value);
+ TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value, QualType Type);
/// Construct an integral constant template argument with the same
/// value as Other but a
diff erent type.
@@ -268,12 +252,6 @@ class TemplateArgument {
/// Whether this template argument is dependent on a template
/// parameter such that its result can change from one instantiation to
/// another.
- ///
- /// It's not always meaningful to ask whether a template argument is
- /// dependent before it's been converted to match a template parameter;
- /// whether a non-type template argument is dependent depends on the
- /// corresponding parameter. For an unconverted template argument, this
- /// returns true if the argument *might* be dependent.
bool isDependent() const;
/// Whether this template argument is dependent on a template
@@ -356,16 +334,6 @@ class TemplateArgument {
Integer.Type = T.getAsOpaquePtr();
}
- /// Get the value of an UncommonValue.
- const APValue &getAsUncommonValue() const {
- return *Value.Value;
- }
-
- /// Get the type of an UncommonValue.
- QualType getUncommonValueType() const {
- return QualType::getFromOpaquePtr(Value.Type);
- }
-
/// If this is a non-type template argument, get its type. Otherwise,
/// returns a null QualType.
QualType getNonTypeTemplateArgumentType() const;
@@ -510,7 +478,6 @@ class TemplateArgumentLoc {
assert(Argument.getKind() == TemplateArgument::NullPtr ||
Argument.getKind() == TemplateArgument::Integral ||
Argument.getKind() == TemplateArgument::Declaration ||
- Argument.getKind() == TemplateArgument::UncommonValue ||
Argument.getKind() == TemplateArgument::Expression);
}
@@ -569,11 +536,6 @@ class TemplateArgumentLoc {
return LocInfo.getAsExpr();
}
- Expr *getSourceUncommonValueExpression() const {
- assert(Argument.getKind() == TemplateArgument::UncommonValue);
- return LocInfo.getAsExpr();
- }
-
NestedNameSpecifierLoc getTemplateQualifierLoc() const {
if (Argument.getKind() != TemplateArgument::Template &&
Argument.getKind() != TemplateArgument::TemplateExpansion)
@@ -712,6 +674,13 @@ struct alignas(void *) ASTTemplateKWAndArgsInfo {
void initializeFrom(SourceLocation TemplateKWLoc,
const TemplateArgumentListInfo &List,
TemplateArgumentLoc *OutArgArray);
+ // FIXME: The parameter Deps is the result populated by this method, the
+ // caller doesn't need it since it is populated by computeDependence. remove
+ // it.
+ void initializeFrom(SourceLocation TemplateKWLoc,
+ const TemplateArgumentListInfo &List,
+ TemplateArgumentLoc *OutArgArray,
+ TemplateArgumentDependence &Deps);
void initializeFrom(SourceLocation TemplateKWLoc);
void copyInto(const TemplateArgumentLoc *ArgArray,
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 1fb8dbd32bad..e93657898f58 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -4695,6 +4695,8 @@ def err_non_type_template_arg_subobject : Error<
"non-type template argument refers to subobject '%0'">;
def err_non_type_template_arg_addr_label_
diff : Error<
"template argument / label address
diff erence / what did you expect?">;
+def err_non_type_template_arg_unsupported : Error<
+ "sorry, non-type template argument of type %0 is not yet supported">;
def err_template_arg_not_convertible : Error<
"non-type template argument of type %0 cannot be converted to a value "
"of type %1">;
@@ -4746,6 +4748,9 @@ def err_template_arg_not_object_or_func : Error<
"non-type template argument does not refer to an object or function">;
def err_template_arg_not_pointer_to_member_form : Error<
"non-type template argument is not a pointer to member constant">;
+def err_template_arg_member_ptr_base_derived_not_supported : Error<
+ "sorry, non-type template argument of pointer-to-member type %1 that refers "
+ "to member %q0 of a
diff erent class is not supported yet">;
def ext_template_arg_extra_parens : ExtWarn<
"address non-type template argument cannot be surrounded by parentheses">;
def warn_cxx98_compat_template_arg_extra_parens : Warning<
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 4e93361ba6f7..7f7c84eb1b1d 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -3465,8 +3465,7 @@ class Sema final {
llvm::APSInt &Value, CCEKind CCE);
ExprResult CheckConvertedConstantExpression(Expr *From, QualType T,
APValue &Value, CCEKind CCE,
- NamedDecl *Dest = nullptr,
- bool *ValueDependent = nullptr);
+ NamedDecl *Dest = nullptr);
/// Abstract base class used to perform a contextual implicit
/// conversion from an expression to any type passing a filter.
@@ -7735,8 +7734,8 @@ class Sema final {
QualType ParamType,
SourceLocation Loc);
ExprResult
- BuildExpressionFromNonTypeTemplateArgument(const TemplateArgument &Arg,
- SourceLocation Loc);
+ BuildExpressionFromIntegralTemplateArgument(const TemplateArgument &Arg,
+ SourceLocation Loc);
/// Enumeration describing how template parameter lists are compared
/// for equality.
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index c482235caaed..44545f00b146 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -5941,11 +5941,6 @@ ASTContext::getCanonicalTemplateArgument(const TemplateArgument &Arg) const {
case TemplateArgument::Integral:
return TemplateArgument(Arg, getCanonicalType(Arg.getIntegralType()));
- case TemplateArgument::UncommonValue:
- return TemplateArgument(*this,
- getCanonicalType(Arg.getUncommonValueType()),
- Arg.getAsUncommonValue());
-
case TemplateArgument::Type:
return TemplateArgument(getCanonicalType(Arg.getAsType()));
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 416764d48543..5c6aa5d3c015 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -808,17 +808,6 @@ ASTNodeImporter::import(const TemplateArgument &From) {
return TemplateArgument(*ToTypeOrErr, /*isNullPtr*/true);
}
- case TemplateArgument::UncommonValue: {
- ExpectedType ToTypeOrErr = import(From.getUncommonValueType());
- if (!ToTypeOrErr)
- return ToTypeOrErr.takeError();
- Expected<APValue> ToValueOrErr = import(From.getAsUncommonValue());
- if (!ToValueOrErr)
- return ToValueOrErr.takeError();
- return TemplateArgument(Importer.getToContext(), *ToTypeOrErr,
- *ToValueOrErr);
- }
-
case TemplateArgument::Template: {
Expected<TemplateName> ToTemplateOrErr = import(From.getAsTemplate());
if (!ToTemplateOrErr)
diff --git a/clang/lib/AST/ASTStructuralEquivalence.cpp b/clang/lib/AST/ASTStructuralEquivalence.cpp
index f7696bc7c921..d004e443ae06 100644
--- a/clang/lib/AST/ASTStructuralEquivalence.cpp
+++ b/clang/lib/AST/ASTStructuralEquivalence.cpp
@@ -565,10 +565,6 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
return IsStructurallyEquivalent(Context, Arg1.getAsExpr(),
Arg2.getAsExpr());
- case TemplateArgument::UncommonValue:
- // FIXME: Do we need to customize the comparison?
- return Arg1.structurallyEquals(Arg2);
-
case TemplateArgument::Pack:
if (Arg1.pack_size() != Arg2.pack_size())
return false;
diff --git a/clang/lib/AST/ComputeDependence.cpp b/clang/lib/AST/ComputeDependence.cpp
index 5262e3cbe233..4026fdc76fd6 100644
--- a/clang/lib/AST/ComputeDependence.cpp
+++ b/clang/lib/AST/ComputeDependence.cpp
@@ -64,7 +64,7 @@ ExprDependence clang::computeDependence(UnaryOperator *E,
if (VD && VD->isTemplated()) {
auto *VarD = dyn_cast<VarDecl>(VD);
if (!VarD || !VarD->hasLocalStorage())
- Dep |= ExprDependence::ValueInstantiation;
+ Dep |= ExprDependence::Value;
}
}
}
@@ -443,21 +443,12 @@ ExprDependence clang::computeDependence(DeclRefExpr *E, const ASTContext &Ctx) {
if (auto *FirstArg = E->getTemplateArgs()) {
unsigned NumArgs = E->getNumTemplateArgs();
for (auto *Arg = FirstArg, *End = FirstArg + NumArgs; Arg < End; ++Arg)
- Deps |= toExprDependence(Arg->getArgument().getDependence() &
- ~TemplateArgumentDependence::Dependent);
+ Deps |= toExprDependence(Arg->getArgument().getDependence());
}
auto *Decl = E->getDecl();
- auto *Found = E->getFoundDecl();
auto Type = E->getType();
- // FIXME: For a ParmVarDecl referenced in a function signature, we don't know
- // its dependence yet!
- if (!isa<ParmVarDecl>(Decl)) {
- if (Decl->getDeclContext()->isDependentContext() ||
- (Found && Found->getDeclContext()->isDependentContext()))
- Deps |= ExprDependence::Instantiation;
- }
if (Decl->isParameterPack())
Deps |= ExprDependence::UnexpandedPack;
Deps |= toExprDependence(Type->getDependence()) & ExprDependence::Error;
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index d636d0e430d3..3cea3c23b527 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -342,10 +342,6 @@ LinkageComputer::getLVForTemplateArgumentList(ArrayRef<TemplateArgument> Args,
LV.merge(getTypeLinkageAndVisibility(Arg.getNullPtrType()));
continue;
- case TemplateArgument::UncommonValue:
- LV.merge(getLVForValue(Arg.getAsUncommonValue(), computation));
- continue;
-
case TemplateArgument::Template:
case TemplateArgument::TemplateExpansion:
if (TemplateDecl *Template =
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index 6e12b3be01b2..5d7066cc2699 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -416,9 +416,12 @@ DeclRefExpr::DeclRefExpr(const ASTContext &Ctx,
RefersToEnclosingVariableOrCapture;
DeclRefExprBits.NonOdrUseReason = NOUR;
if (TemplateArgs) {
+ auto Deps = TemplateArgumentDependence::None;
getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
- TemplateKWLoc, *TemplateArgs,
- getTrailingObjects<TemplateArgumentLoc>());
+ TemplateKWLoc, *TemplateArgs, getTrailingObjects<TemplateArgumentLoc>(),
+ Deps);
+ assert(!(Deps & TemplateArgumentDependence::Dependent) &&
+ "built a DeclRefExpr with dependent template args");
} else if (TemplateKWLoc.isValid()) {
getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
TemplateKWLoc);
@@ -1521,8 +1524,16 @@ MemberExpr *MemberExpr::Create(
MemberExpr *E = new (Mem) MemberExpr(Base, IsArrow, OperatorLoc, MemberDecl,
NameInfo, T, VK, OK, NOUR);
- // FIXME: Move this into the constructor.
+ // FIXME: remove remaining dependence computation to computeDependence().
+ auto Deps = E->getDependence();
if (HasQualOrFound) {
+ // FIXME: Wrong. We should be looking at the member declaration we found.
+ if (QualifierLoc && QualifierLoc.getNestedNameSpecifier()->isDependent())
+ Deps |= ExprDependence::TypeValueInstantiation;
+ else if (QualifierLoc &&
+ QualifierLoc.getNestedNameSpecifier()->isInstantiationDependent())
+ Deps |= ExprDependence::Instantiation;
+
E->MemberExprBits.HasQualifierOrFoundDecl = true;
MemberExprNameQualifier *NQ =
@@ -1535,26 +1546,16 @@ MemberExpr *MemberExpr::Create(
TemplateArgs || TemplateKWLoc.isValid();
if (TemplateArgs) {
+ auto TemplateArgDeps = TemplateArgumentDependence::None;
E->getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
TemplateKWLoc, *TemplateArgs,
- E->getTrailingObjects<TemplateArgumentLoc>());
+ E->getTrailingObjects<TemplateArgumentLoc>(), TemplateArgDeps);
+ if (TemplateArgDeps & TemplateArgumentDependence::Instantiation)
+ Deps |= ExprDependence::Instantiation;
} else if (TemplateKWLoc.isValid()) {
E->getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
TemplateKWLoc);
}
-
- // FIXME: remove remaining dependence computation to computeDependence().
- auto Deps = E->getDependence();
- if (NestedNameSpecifier *Qual = E->getQualifier()) {
- // FIXME: Wrong. We should be looking at the member declaration we found.
- if (Qual->isDependent())
- Deps |= ExprDependence::TypeValueInstantiation;
- else if (Qual->isInstantiationDependent())
- Deps |= ExprDependence::Instantiation;
- }
- if (TemplateSpecializationType::anyInstantiationDependentTemplateArguments(
- E->template_arguments()))
- Deps |= ExprDependence::Instantiation;
E->setDependence(Deps);
return E;
diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp
index e1f658923519..8dc9d4296e14 100644
--- a/clang/lib/AST/ExprCXX.cpp
+++ b/clang/lib/AST/ExprCXX.cpp
@@ -433,8 +433,9 @@ OverloadExpr::OverloadExpr(StmtClass SC, const ASTContext &Context,
}
if (TemplateArgs) {
+ auto Deps = TemplateArgumentDependence::None;
getTrailingASTTemplateKWAndArgsInfo()->initializeFrom(
- TemplateKWLoc, *TemplateArgs, getTrailingTemplateArgumentLoc());
+ TemplateKWLoc, *TemplateArgs, getTrailingTemplateArgumentLoc(), Deps);
} else if (TemplateKWLoc.isValid()) {
getTrailingASTTemplateKWAndArgsInfo()->initializeFrom(TemplateKWLoc);
}
@@ -463,8 +464,9 @@ DependentScopeDeclRefExpr::DependentScopeDeclRefExpr(
DependentScopeDeclRefExprBits.HasTemplateKWAndArgsInfo =
(Args != nullptr) || TemplateKWLoc.isValid();
if (Args) {
+ auto Deps = TemplateArgumentDependence::None;
getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
- TemplateKWLoc, *Args, getTrailingObjects<TemplateArgumentLoc>());
+ TemplateKWLoc, *Args, getTrailingObjects<TemplateArgumentLoc>(), Deps);
} else if (TemplateKWLoc.isValid()) {
getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
TemplateKWLoc);
@@ -1374,9 +1376,10 @@ CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(
CXXDependentScopeMemberExprBits.OperatorLoc = OperatorLoc;
if (TemplateArgs) {
+ auto Deps = TemplateArgumentDependence::None;
getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
- TemplateKWLoc, *TemplateArgs,
- getTrailingObjects<TemplateArgumentLoc>());
+ TemplateKWLoc, *TemplateArgs, getTrailingObjects<TemplateArgumentLoc>(),
+ Deps);
} else if (TemplateKWLoc.isValid()) {
getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
TemplateKWLoc);
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 6ec6df09c83f..b153e22259f7 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -1819,8 +1819,7 @@ static bool EvaluateFloat(const Expr *E, APFloat &Result, EvalInfo &Info);
static bool EvaluateComplex(const Expr *E, ComplexValue &Res, EvalInfo &Info);
static bool EvaluateAtomic(const Expr *E, const LValue *This, APValue &Result,
EvalInfo &Info);
-static bool EvaluateAsRValue(EvalInfo &Info, const Expr *E, APValue &Result,
- bool &Dependent);
+static bool EvaluateAsRValue(EvalInfo &Info, const Expr *E, APValue &Result);
/// Evaluate an integer or fixed point expression into an APResult.
static bool EvaluateFixedPointOrInteger(const Expr *E, APFixedPoint &Result,
@@ -2108,8 +2107,7 @@ static bool CheckEvaluationResult(CheckEvaluationResultKind CERK,
QualType Type, const APValue &Value,
ConstantExprKind Kind,
SourceLocation SubobjectLoc,
- CheckedTemporaries &CheckedTemps,
- bool &Dependent);
+ CheckedTemporaries &CheckedTemps);
/// Check that this reference or pointer core constant expression is a valid
/// value for an address or reference constant expression. Return true if we
@@ -2117,8 +2115,7 @@ static bool CheckEvaluationResult(CheckEvaluationResultKind CERK,
static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc,
QualType Type, const LValue &LVal,
ConstantExprKind Kind,
- CheckedTemporaries &CheckedTemps,
- bool &Dependent) {
+ CheckedTemporaries &CheckedTemps) {
bool IsReferenceType = Type->isReferenceType();
APValue::LValueBase Base = LVal.getLValueBase();
@@ -2203,8 +2200,6 @@ static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc,
}
if (BaseVD) {
- Dependent |= BaseVD->isTemplated();
-
if (const VarDecl *Var = dyn_cast<const VarDecl>(BaseVD)) {
// Check if this is a thread-local variable.
if (Var->getTLSKind())
@@ -2235,9 +2230,6 @@ static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc,
}
} else if (const auto *MTE =
dyn_cast_or_null<MaterializeTemporaryExpr>(BaseE)) {
- if (auto *Extending = MTE->getExtendingDecl())
- Dependent |= Extending->isTemplated();
-
if (CheckedTemps.insert(MTE).second) {
QualType TempType = getType(Base);
if (TempType.isDestructedType()) {
@@ -2250,8 +2242,8 @@ static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc,
APValue *V = MTE->getOrCreateValue(false);
assert(V && "evasluation result refers to uninitialised temporary");
if (!CheckEvaluationResult(CheckEvaluationResultKind::ConstantExpression,
- Info, MTE->getExprLoc(), TempType, *V, Kind,
- SourceLocation(), CheckedTemps, Dependent))
+ Info, MTE->getExprLoc(), TempType, *V,
+ Kind, SourceLocation(), CheckedTemps))
return false;
}
}
@@ -2280,15 +2272,13 @@ static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc,
/// Member pointers are constant expressions unless they point to a
/// non-virtual dllimport member function.
-static bool
-CheckMemberPointerConstantExpression(EvalInfo &Info, SourceLocation Loc,
- QualType Type, const APValue &Value,
- ConstantExprKind Kind, bool &Dependent) {
+static bool CheckMemberPointerConstantExpression(EvalInfo &Info,
+ SourceLocation Loc,
+ QualType Type,
+ const APValue &Value,
+ ConstantExprKind Kind) {
const ValueDecl *Member = Value.getMemberPointerDecl();
- if (!Member)
- return true;
- Dependent |= Member->isTemplated();
- const auto *FD = dyn_cast<CXXMethodDecl>(Member);
+ const auto *FD = dyn_cast_or_null<CXXMethodDecl>(Member);
if (!FD)
return true;
if (FD->isConsteval()) {
@@ -2337,8 +2327,7 @@ static bool CheckEvaluationResult(CheckEvaluationResultKind CERK,
QualType Type, const APValue &Value,
ConstantExprKind Kind,
SourceLocation SubobjectLoc,
- CheckedTemporaries &CheckedTemps,
- bool &Dependent) {
+ CheckedTemporaries &CheckedTemps) {
if (!Value.hasValue()) {
Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
<< true << Type;
@@ -2360,20 +2349,20 @@ static bool CheckEvaluationResult(CheckEvaluationResultKind CERK,
for (unsigned I = 0, N = Value.getArrayInitializedElts(); I != N; ++I) {
if (!CheckEvaluationResult(CERK, Info, DiagLoc, EltTy,
Value.getArrayInitializedElt(I), Kind,
- SubobjectLoc, CheckedTemps, Dependent))
+ SubobjectLoc, CheckedTemps))
return false;
}
if (!Value.hasArrayFiller())
return true;
return CheckEvaluationResult(CERK, Info, DiagLoc, EltTy,
Value.getArrayFiller(), Kind, SubobjectLoc,
- CheckedTemps, Dependent);
+ CheckedTemps);
}
if (Value.isUnion() && Value.getUnionField()) {
return CheckEvaluationResult(
CERK, Info, DiagLoc, Value.getUnionField()->getType(),
Value.getUnionValue(), Kind, Value.getUnionField()->getLocation(),
- CheckedTemps, Dependent);
+ CheckedTemps);
}
if (Value.isStruct()) {
RecordDecl *RD = Type->castAs<RecordType>()->getDecl();
@@ -2382,7 +2371,7 @@ static bool CheckEvaluationResult(CheckEvaluationResultKind CERK,
for (const CXXBaseSpecifier &BS : CD->bases()) {
if (!CheckEvaluationResult(CERK, Info, DiagLoc, BS.getType(),
Value.getStructBase(BaseIndex), Kind,
- BS.getBeginLoc(), CheckedTemps, Dependent))
+ BS.getBeginLoc(), CheckedTemps))
return false;
++BaseIndex;
}
@@ -2392,8 +2381,8 @@ static bool CheckEvaluationResult(CheckEvaluationResultKind CERK,
continue;
if (!CheckEvaluationResult(CERK, Info, DiagLoc, I->getType(),
- Value.getStructField(I->getFieldIndex()), Kind,
- I->getLocation(), CheckedTemps, Dependent))
+ Value.getStructField(I->getFieldIndex()),
+ Kind, I->getLocation(), CheckedTemps))
return false;
}
}
@@ -2403,13 +2392,12 @@ static bool CheckEvaluationResult(CheckEvaluationResultKind CERK,
LValue LVal;
LVal.setFrom(Info.Ctx, Value);
return CheckLValueConstantExpression(Info, DiagLoc, Type, LVal, Kind,
- CheckedTemps, Dependent);
+ CheckedTemps);
}
if (Value.isMemberPointer() &&
CERK == CheckEvaluationResultKind::ConstantExpression)
- return CheckMemberPointerConstantExpression(Info, DiagLoc, Type, Value,
- Kind, Dependent);
+ return CheckMemberPointerConstantExpression(Info, DiagLoc, Type, Value, Kind);
// Everything else is fine.
return true;
@@ -2420,7 +2408,7 @@ static bool CheckEvaluationResult(CheckEvaluationResultKind CERK,
/// check that the expression is of literal type.
static bool CheckConstantExpression(EvalInfo &Info, SourceLocation DiagLoc,
QualType Type, const APValue &Value,
- ConstantExprKind Kind, bool &Dependent) {
+ ConstantExprKind Kind) {
// Nothing to check for a constant expression of type 'cv void'.
if (Type->isVoidType())
return true;
@@ -2428,18 +2416,17 @@ static bool CheckConstantExpression(EvalInfo &Info, SourceLocation DiagLoc,
CheckedTemporaries CheckedTemps;
return CheckEvaluationResult(CheckEvaluationResultKind::ConstantExpression,
Info, DiagLoc, Type, Value, Kind,
- SourceLocation(), CheckedTemps, Dependent);
+ SourceLocation(), CheckedTemps);
}
/// Check that this evaluated value is fully-initialized and can be loaded by
/// an lvalue-to-rvalue conversion.
static bool CheckFullyInitialized(EvalInfo &Info, SourceLocation DiagLoc,
QualType Type, const APValue &Value) {
- bool Dependent = false;
CheckedTemporaries CheckedTemps;
return CheckEvaluationResult(
CheckEvaluationResultKind::FullyInitialized, Info, DiagLoc, Type, Value,
- ConstantExprKind::Normal, SourceLocation(), CheckedTemps, Dependent);
+ ConstantExprKind::Normal, SourceLocation(), CheckedTemps);
}
/// Enforce C++2a [expr.const]/4.17, which disallows new-expressions unless
@@ -11111,9 +11098,7 @@ static bool EvaluateBuiltinConstantP(EvalInfo &Info, const Expr *Arg) {
ArgType->isAnyComplexType() || ArgType->isPointerType() ||
ArgType->isNullPtrType()) {
APValue V;
- bool Dependent = false;
- if (!::EvaluateAsRValue(Info, Arg, V, Dependent) ||
- Info.EvalStatus.HasSideEffects) {
+ if (!::EvaluateAsRValue(Info, Arg, V) || Info.EvalStatus.HasSideEffects) {
Fold.keepDiagnostics();
return false;
}
@@ -11415,8 +11400,7 @@ static bool tryEvaluateBuiltinObjectSize(const Expr *E, unsigned Type,
// It's possible for us to be given GLValues if we're called via
// Expr::tryEvaluateObjectSize.
APValue RVal;
- bool Dependent = false;
- if (!EvaluateAsRValue(Info, E, RVal, Dependent))
+ if (!EvaluateAsRValue(Info, E, RVal))
return false;
LVal.setFrom(Info.Ctx, RVal);
} else if (!EvaluatePointer(ignorePointerCastsAndParens(E), LVal, Info,
@@ -12845,9 +12829,8 @@ bool RecordExprEvaluator::VisitBinCmp(const BinaryOperator *E) {
LV.set(VD);
if (!handleLValueToRValueConversion(Info, E, E->getType(), LV, Result))
return false;
- bool Dependent = false;
return CheckConstantExpression(Info, E->getExprLoc(), E->getType(), Result,
- ConstantExprKind::Normal, Dependent);
+ ConstantExprKind::Normal);
};
return EvaluateComparisonBinaryOperator(Info, E, OnSuccess, [&]() {
return ExprEvaluatorBaseTy::VisitBinCmp(E);
@@ -14611,8 +14594,7 @@ static bool EvaluateInPlace(APValue &Result, EvalInfo &Info, const LValue &This,
/// EvaluateAsRValue - Try to evaluate this expression, performing an implicit
/// lvalue-to-rvalue cast if it is an lvalue.
-static bool EvaluateAsRValue(EvalInfo &Info, const Expr *E, APValue &Result,
- bool &Dependent) {
+static bool EvaluateAsRValue(EvalInfo &Info, const Expr *E, APValue &Result) {
assert(!E->isValueDependent());
if (Info.EnableNewConstInterp) {
if (!Info.Ctx.getInterpContext().evaluateAsRValue(Info, E, Result))
@@ -14637,7 +14619,7 @@ static bool EvaluateAsRValue(EvalInfo &Info, const Expr *E, APValue &Result,
// Check this core constant expression is a constant expression.
return CheckConstantExpression(Info, E->getExprLoc(), E->getType(), Result,
- ConstantExprKind::Normal, Dependent) &&
+ ConstantExprKind::Normal) &&
CheckMemoryLeaks(Info);
}
@@ -14683,7 +14665,7 @@ static bool EvaluateAsRValue(const Expr *E, Expr::EvalResult &Result,
if (FastEvaluateAsRValue(E, Result, Ctx, IsConst))
return IsConst;
- return EvaluateAsRValue(Info, E, Result.Val, Result.Dependent);
+ return EvaluateAsRValue(Info, E, Result.Val);
}
static bool EvaluateAsInt(const Expr *E, Expr::EvalResult &ExprResult,
@@ -14793,9 +14775,9 @@ bool Expr::EvaluateAsLValue(EvalResult &Result, const ASTContext &Ctx,
CheckedTemporaries CheckedTemps;
if (!EvaluateLValue(this, LV, Info) || !Info.discardCleanups() ||
Result.HasSideEffects ||
- !CheckLValueConstantExpression(
- Info, getExprLoc(), Ctx.getLValueReferenceType(getType()), LV,
- ConstantExprKind::Normal, CheckedTemps, Result.Dependent))
+ !CheckLValueConstantExpression(Info, getExprLoc(),
+ Ctx.getLValueReferenceType(getType()), LV,
+ ConstantExprKind::Normal, CheckedTemps))
return false;
LV.moveInto(Result.Val);
@@ -14854,7 +14836,7 @@ bool Expr::EvaluateAsConstantExpr(EvalResult &Result, const ASTContext &Ctx,
llvm_unreachable("Unhandled cleanup; missing full expression marker?");
if (!CheckConstantExpression(Info, getExprLoc(), getStorageType(Ctx, this),
- Result.Val, Kind, Result.Dependent))
+ Result.Val, Kind))
return false;
if (!CheckMemoryLeaks(Info))
return false;
@@ -14918,9 +14900,8 @@ bool Expr::EvaluateAsInitializer(APValue &Value, const ASTContext &Ctx,
if (!Info.discardCleanups())
llvm_unreachable("Unhandled cleanup; missing full expression marker?");
}
- bool Dependent = false;
return CheckConstantExpression(Info, DeclLoc, DeclTy, Value,
- ConstantExprKind::Normal, Dependent) &&
+ ConstantExprKind::Normal) &&
CheckMemoryLeaks(Info);
}
@@ -14987,7 +14968,7 @@ APSInt Expr::EvaluateKnownConstIntCheckOverflow(
Info.InConstantContext = true;
Info.CheckingForUndefinedBehavior = true;
- bool Result = ::EvaluateAsRValue(this, EVResult, Ctx, Info);
+ bool Result = ::EvaluateAsRValue(Info, this, EVResult.Val);
(void)Result;
assert(Result && "Could not evaluate expression");
assert(EVResult.Val.isInt() && "Expression did not evaluate to integer");
@@ -14999,10 +14980,13 @@ void Expr::EvaluateForOverflow(const ASTContext &Ctx) const {
assert(!isValueDependent() &&
"Expression evaluator can't be called on a dependent expression.");
+ bool IsConst;
EvalResult EVResult;
- EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects);
- Info.CheckingForUndefinedBehavior = true;
- (void)::EvaluateAsRValue(this, EVResult, Ctx, Info);
+ if (!FastEvaluateAsRValue(this, EVResult, Ctx, IsConst)) {
+ EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects);
+ Info.CheckingForUndefinedBehavior = true;
+ (void)::EvaluateAsRValue(Info, this, EVResult.Val);
+ }
}
bool Expr::EvalResult::isGlobalLValue() const {
@@ -15552,9 +15536,8 @@ bool Expr::isCXX11ConstantExpr(const ASTContext &Ctx, APValue *Result,
EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
APValue Scratch;
- bool Dependent = false;
bool IsConstExpr =
- ::EvaluateAsRValue(Info, this, Result ? *Result : Scratch, Dependent) &&
+ ::EvaluateAsRValue(Info, this, Result ? *Result : Scratch) &&
// FIXME: We don't produce a diagnostic for this, but the callers that
// call us on arbitrary full-expressions should generally not care.
Info.discardCleanups() && !Status.HasSideEffects;
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index 27aa622e00e9..6c8d5687c64a 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -4074,28 +4074,10 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity) {
mangleExpression(cast<CXXStdInitializerListExpr>(E)->getSubExpr(), Arity);
break;
- case Expr::SubstNonTypeTemplateParmExprClass: {
- // Mangle a substituted parameter the same way we mangle the template
- // argument.
- // As proposed in https://github.com/itanium-cxx-abi/cxx-abi/issues/111.
- auto *SNTTPE = cast<SubstNonTypeTemplateParmExpr>(E);
- if (auto *CE = dyn_cast<ConstantExpr>(SNTTPE->getReplacement())) {
- // Pull out the constant value and mangle it as a template argument.
- QualType ParamType = SNTTPE->getParameterType(Context.getASTContext());
- if (CE->hasAPValueResult())
- mangleValueInTemplateArg(ParamType, CE->getResultAsAPValue(), false,
- /*NeedExactType=*/true);
- else
- mangleValueInTemplateArg(ParamType, CE->getAPValueResult(), false,
- /*NeedExactType=*/true);
- } else {
- // The remaining cases all happen to be substituted with expressions that
- // mangle the same as a corresponding template argument anyway.
- mangleExpression(cast<SubstNonTypeTemplateParmExpr>(E)->getReplacement(),
- Arity);
- }
+ case Expr::SubstNonTypeTemplateParmExprClass:
+ mangleExpression(cast<SubstNonTypeTemplateParmExpr>(E)->getReplacement(),
+ Arity);
break;
- }
case Expr::UserDefinedLiteralClass:
// We follow g++'s approach of mangling a UDL as a call to the literal
@@ -5052,10 +5034,6 @@ void CXXNameMangler::mangleTemplateArg(TemplateArgument A, bool NeedExactType) {
mangleNullPointer(A.getNullPtrType());
break;
}
- case TemplateArgument::UncommonValue:
- mangleValueInTemplateArg(A.getUncommonValueType(), A.getAsUncommonValue(),
- /*TopLevel=*/true, NeedExactType);
- break;
case TemplateArgument::Pack: {
// <template-arg> ::= J <template-arg>* E
Out << 'J';
@@ -5390,20 +5368,7 @@ void CXXNameMangler::mangleValueInTemplateArg(QualType T, const APValue &V,
Out << "plcvPcad";
Kind = Offset;
} else {
- // Clang 11 and before mangled an array subject to array-to-pointer decay
- // as if it were the declaration itself.
- bool IsArrayToPointerDecayMangledAsDecl = false;
- if (TopLevel && Ctx.getLangOpts().getClangABICompat() <=
- LangOptions::ClangABI::Ver11) {
- QualType BType = B.getType();
- IsArrayToPointerDecayMangledAsDecl =
- BType->isArrayType() && V.getLValuePath().size() == 1 &&
- V.getLValuePath()[0].getAsArrayIndex() == 0 &&
- Ctx.hasSimilarType(T, Ctx.getDecayedType(BType));
- }
-
- if ((!V.getLValuePath().empty() || V.isLValueOnePastTheEnd()) &&
- !IsArrayToPointerDecayMangledAsDecl) {
+ if (!V.getLValuePath().empty() || V.isLValueOnePastTheEnd()) {
NotPrimaryExpr();
// A final conversion to the template parameter's type is usually
// folded into the 'so' mangling, but we can't do that for 'void*'
diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp
index b9c289b6497a..df6c566abc7d 100644
--- a/clang/lib/AST/MicrosoftMangle.cpp
+++ b/clang/lib/AST/MicrosoftMangle.cpp
@@ -1466,21 +1466,6 @@ void MicrosoftCXXNameMangler::mangleTemplateArgs(
}
}
-/// If value V (with type T) represents a decayed pointer to the first element
-/// of an array, return that array.
-static ValueDecl *getAsArrayToPointerDecayedDecl(QualType T, const APValue &V) {
- // Must be a pointer...
- if (!T->isPointerType() || !V.isLValue() || !V.hasLValuePath() ||
- !V.getLValueBase())
- return nullptr;
- // ... to element 0 of an array.
- QualType BaseT = V.getLValueBase().getType();
- if (!BaseT->isArrayType() || V.getLValuePath().size() != 1 ||
- V.getLValuePath()[0].getAsArrayIndex() != 0)
- return nullptr;
- return const_cast<ValueDecl*>(V.getLValueBase().dyn_cast<const ValueDecl*>());
-}
-
void MicrosoftCXXNameMangler::mangleTemplateArg(const TemplateDecl *TD,
const TemplateArgument &TA,
const NamedDecl *Parm) {
@@ -1590,25 +1575,6 @@ void MicrosoftCXXNameMangler::mangleTemplateArg(const TemplateDecl *TD,
cast<NonTypeTemplateParmDecl>(Parm), T);
break;
}
- case TemplateArgument::UncommonValue:
- if (ValueDecl *D = getAsArrayToPointerDecayedDecl(
- TA.getUncommonValueType(), TA.getAsUncommonValue())) {
- // Mangle the result of array-to-pointer decay as if it were a reference
- // to the original declaration, to match MSVC's behavior. This can result
- // in mangling collisions in some cases!
- return mangleTemplateArg(
- TD, TemplateArgument(D, TA.getUncommonValueType()), Parm);
- }
- Out << "$";
- if (cast<NonTypeTemplateParmDecl>(Parm)
- ->getType()
- ->getContainedDeducedType()) {
- Out << "M";
- mangleType(TA.getNonTypeTemplateArgumentType(), SourceRange(), QMM_Drop);
- }
- mangleTemplateArgValue(TA.getUncommonValueType(), TA.getAsUncommonValue(),
- /*WithScalarType=*/false);
- break;
case TemplateArgument::Expression:
mangleExpression(TA.getAsExpr(), cast<NonTypeTemplateParmDecl>(Parm));
break;
diff --git a/clang/lib/AST/ODRHash.cpp b/clang/lib/AST/ODRHash.cpp
index 92e3bc27fca0..735bcff8f113 100644
--- a/clang/lib/AST/ODRHash.cpp
+++ b/clang/lib/AST/ODRHash.cpp
@@ -169,8 +169,6 @@ void ODRHash::AddTemplateArgument(TemplateArgument TA) {
break;
case TemplateArgument::NullPtr:
case TemplateArgument::Integral:
- case TemplateArgument::UncommonValue:
- // FIXME: Include a representation of these arguments.
break;
case TemplateArgument::Template:
case TemplateArgument::TemplateExpansion:
diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp
index 569e3b06f3b2..de9de6ff463c 100644
--- a/clang/lib/AST/StmtProfile.cpp
+++ b/clang/lib/AST/StmtProfile.cpp
@@ -2208,12 +2208,6 @@ void StmtProfiler::VisitTemplateArgument(const TemplateArgument &Arg) {
Arg.getAsIntegral().Profile(ID);
break;
- case TemplateArgument::UncommonValue:
- VisitType(Arg.getUncommonValueType());
- // FIXME: Do we need to recursively decompose this ourselves?
- Arg.getAsUncommonValue().Profile(ID);
- break;
-
case TemplateArgument::Expression:
Visit(Arg.getAsExpr());
break;
diff --git a/clang/lib/AST/TemplateBase.cpp b/clang/lib/AST/TemplateBase.cpp
index 85caee1a4911..baf62bd115a8 100644
--- a/clang/lib/AST/TemplateBase.cpp
+++ b/clang/lib/AST/TemplateBase.cpp
@@ -84,8 +84,8 @@ static void printIntegral(const TemplateArgument &TemplArg,
// TemplateArgument Implementation
//===----------------------------------------------------------------------===//
-TemplateArgument::TemplateArgument(const ASTContext &Ctx,
- const llvm::APSInt &Value, QualType Type) {
+TemplateArgument::TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value,
+ QualType Type) {
Integer.Kind = Integral;
// Copy the APSInt value into our decomposed form.
Integer.BitWidth = Value.getBitWidth();
@@ -103,45 +103,6 @@ TemplateArgument::TemplateArgument(const ASTContext &Ctx,
Integer.Type = Type.getAsOpaquePtr();
}
-static const ValueDecl *getAsSimpleValueDeclRef(const ASTContext &Ctx,
- QualType T, const APValue &V) {
- // Pointers to members are relatively easy.
- if (V.isMemberPointer() && V.getMemberPointerPath().empty())
- return V.getMemberPointerDecl();
-
- // We model class non-type template parameters as their template parameter
- // object declaration.
- if (V.isStruct() || V.isUnion())
- return Ctx.getTemplateParamObjectDecl(T, V);
-
- // Pointers and references with an empty path use the special 'Declaration'
- // representation.
- if (V.isLValue() && V.hasLValuePath() &&
- V.getLValuePath().empty() && !V.isLValueOnePastTheEnd())
- return V.getLValueBase().dyn_cast<const ValueDecl *>();
-
- // Everything else uses the 'uncommon' representation.
- return nullptr;
-}
-
-TemplateArgument::TemplateArgument(const ASTContext &Ctx, QualType Type,
- const APValue &V) {
- if (Type->isIntegralOrEnumerationType() && V.isInt())
- *this = TemplateArgument(Ctx, V.getInt(), Type);
- else if ((V.isLValue() && V.isNullPointer()) ||
- (V.isMemberPointer() && !V.getMemberPointerDecl()))
- *this = TemplateArgument(Type, /*isNullPtr=*/true);
- else if (const ValueDecl *VD = getAsSimpleValueDeclRef(Ctx, Type, V))
- // FIXME: The Declaration form should expose a const ValueDecl*.
- *this = TemplateArgument(const_cast<ValueDecl*>(VD), Type);
- else {
- Value.Kind = UncommonValue;
- Value.Value = new (Ctx) APValue(V);
- Ctx.addDestruction(Value.Value);
- Value.Type = Type.getAsOpaquePtr();
- }
-}
-
TemplateArgument
TemplateArgument::CreatePackCopy(ASTContext &Context,
ArrayRef<TemplateArgument> Args) {
@@ -170,18 +131,25 @@ TemplateArgumentDependence TemplateArgument::getDependence() const {
return TemplateArgumentDependence::Dependent |
TemplateArgumentDependence::Instantiation;
+ case Declaration: {
+ auto *DC = dyn_cast<DeclContext>(getAsDecl());
+ if (!DC)
+ DC = getAsDecl()->getDeclContext();
+ if (DC->isDependentContext())
+ Deps = TemplateArgumentDependence::Dependent |
+ TemplateArgumentDependence::Instantiation;
+ return Deps;
+ }
+
case NullPtr:
case Integral:
- case Declaration:
- case UncommonValue:
return TemplateArgumentDependence::None;
case Expression:
Deps = toTemplateArgumentDependence(getAsExpr()->getDependence());
- // Instantiation-dependent expression arguments are considered dependent
- // until they're resolved to another form.
- if (Deps & TemplateArgumentDependence::Instantiation)
- Deps |= TemplateArgumentDependence::Dependent;
+ if (isa<PackExpansionExpr>(getAsExpr()))
+ Deps |= TemplateArgumentDependence::Dependent |
+ TemplateArgumentDependence::Instantiation;
return Deps;
case Pack:
@@ -205,7 +173,6 @@ bool TemplateArgument::isPackExpansion() const {
case Null:
case Declaration:
case Integral:
- case UncommonValue:
case Pack:
case Template:
case NullPtr:
@@ -256,9 +223,6 @@ QualType TemplateArgument::getNonTypeTemplateArgumentType() const {
case TemplateArgument::NullPtr:
return getNullPtrType();
-
- case TemplateArgument::UncommonValue:
- return getUncommonValueType();
}
llvm_unreachable("Invalid TemplateArgument Kind!");
@@ -303,13 +267,8 @@ void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID,
}
case Integral:
- getIntegralType().Profile(ID);
getAsIntegral().Profile(ID);
- break;
-
- case UncommonValue:
- getUncommonValueType().Profile(ID);
- getAsUncommonValue().Profile(ID);
+ getIntegralType().Profile(ID);
break;
case Expression:
@@ -345,16 +304,6 @@ bool TemplateArgument::structurallyEquals(const TemplateArgument &Other) const {
return getIntegralType() == Other.getIntegralType() &&
getAsIntegral() == Other.getAsIntegral();
- case UncommonValue: {
- if (getUncommonValueType() != Other.getUncommonValueType())
- return false;
-
- llvm::FoldingSetNodeID A, B;
- getAsUncommonValue().Profile(A);
- Other.getAsUncommonValue().Profile(B);
- return A == B;
- }
-
case Pack:
if (Args.NumArgs != Other.Args.NumArgs) return false;
for (unsigned I = 0, E = Args.NumArgs; I != E; ++I)
@@ -381,7 +330,6 @@ TemplateArgument TemplateArgument::getPackExpansionPattern() const {
case Declaration:
case Integral:
- case UncommonValue:
case Pack:
case Null:
case Template:
@@ -421,10 +369,6 @@ void TemplateArgument::print(const PrintingPolicy &Policy,
break;
}
- case UncommonValue:
- getAsUncommonValue().printPretty(Out, Policy, getUncommonValueType());
- break;
-
case NullPtr:
Out << "nullptr";
break;
@@ -507,9 +451,6 @@ SourceRange TemplateArgumentLoc::getSourceRange() const {
case TemplateArgument::Integral:
return getSourceIntegralExpression()->getSourceRange();
- case TemplateArgument::UncommonValue:
- return getSourceUncommonValueExpression()->getSourceRange();
-
case TemplateArgument::Pack:
case TemplateArgument::Null:
return SourceRange();
@@ -538,18 +479,6 @@ static const T &DiagTemplateArg(const T &DB, const TemplateArgument &Arg) {
case TemplateArgument::Integral:
return DB << Arg.getAsIntegral().toString(10);
- case TemplateArgument::UncommonValue: {
- // FIXME: We're guessing at LangOptions!
- SmallString<32> Str;
- llvm::raw_svector_ostream OS(Str);
- LangOptions LangOpts;
- LangOpts.CPlusPlus = true;
- PrintingPolicy Policy(LangOpts);
- Arg.getAsUncommonValue().printPretty(OS, Policy,
- Arg.getUncommonValueType());
- return DB << OS.str();
- }
-
case TemplateArgument::Template:
return DB << Arg.getAsTemplate();
@@ -615,8 +544,8 @@ ASTTemplateArgumentListInfo::ASTTemplateArgumentListInfo(
NumTemplateArgs = Info.size();
TemplateArgumentLoc *ArgBuffer = getTrailingObjects<TemplateArgumentLoc>();
- std::uninitialized_copy(Info.arguments().begin(), Info.arguments().end(),
- ArgBuffer);
+ for (unsigned i = 0; i != NumTemplateArgs; ++i)
+ new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]);
}
void ASTTemplateKWAndArgsInfo::initializeFrom(
@@ -626,8 +555,9 @@ void ASTTemplateKWAndArgsInfo::initializeFrom(
LAngleLoc = Info.getLAngleLoc();
RAngleLoc = Info.getRAngleLoc();
NumTemplateArgs = Info.size();
- std::uninitialized_copy(Info.arguments().begin(), Info.arguments().end(),
- OutArgArray);
+
+ for (unsigned i = 0; i != NumTemplateArgs; ++i)
+ new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]);
}
void ASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation TemplateKWLoc) {
@@ -638,6 +568,21 @@ void ASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation TemplateKWLoc) {
NumTemplateArgs = 0;
}
+void ASTTemplateKWAndArgsInfo::initializeFrom(
+ SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info,
+ TemplateArgumentLoc *OutArgArray, TemplateArgumentDependence &Deps) {
+ this->TemplateKWLoc = TemplateKWLoc;
+ LAngleLoc = Info.getLAngleLoc();
+ RAngleLoc = Info.getRAngleLoc();
+ NumTemplateArgs = Info.size();
+
+ for (unsigned i = 0; i != NumTemplateArgs; ++i) {
+ Deps |= Info[i].getArgument().getDependence();
+
+ new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]);
+ }
+}
+
void ASTTemplateKWAndArgsInfo::copyInto(const TemplateArgumentLoc *ArgArray,
TemplateArgumentListInfo &Info) const {
Info.setLAngleLoc(LAngleLoc);
diff --git a/clang/lib/AST/TypeLoc.cpp b/clang/lib/AST/TypeLoc.cpp
index 438b6950890b..222b1abac510 100644
--- a/clang/lib/AST/TypeLoc.cpp
+++ b/clang/lib/AST/TypeLoc.cpp
@@ -562,7 +562,6 @@ void TemplateSpecializationTypeLoc::initializeArgLocs(ASTContext &Context,
case TemplateArgument::Integral:
case TemplateArgument::Declaration:
case TemplateArgument::NullPtr:
- case TemplateArgument::UncommonValue:
ArgInfos[i] = TemplateArgumentLocInfo();
break;
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 46c49e80aae0..00606d3ae507 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -1949,14 +1949,6 @@ CGDebugInfo::CollectTemplateParams(const TemplateParameterList *TPList,
TemplateParams.push_back(DBuilder.createTemplateValueParameter(
TheCU, Name, TTy, defaultParameter, V));
} break;
- case TemplateArgument::UncommonValue: {
- QualType T = TA.getUncommonValueType();
- llvm::DIType *TTy = getOrCreateType(T, Unit);
- llvm::Constant *V = ConstantEmitter(CGM).emitAbstract(
- SourceLocation(), TA.getAsUncommonValue(), T);
- TemplateParams.push_back(DBuilder.createTemplateValueParameter(
- TheCU, Name, TTy, defaultParameter, V));
- } break;
case TemplateArgument::Template:
TemplateParams.push_back(DBuilder.createTemplateTemplateParameter(
TheCU, Name, nullptr,
diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp
index 840541a4af20..ca1d3a937fa8 100644
--- a/clang/lib/CodeGen/CGExprConstant.cpp
+++ b/clang/lib/CodeGen/CGExprConstant.cpp
@@ -1366,11 +1366,11 @@ llvm::Constant *ConstantEmitter::tryEmitConstantExpr(const ConstantExpr *CE) {
if (!CE->hasAPValueResult())
return nullptr;
const Expr *Inner = CE->getSubExpr()->IgnoreImplicit();
- QualType RetType = Inner->getType();
- if (Inner->isLValue())
- RetType = CGF->getContext().getLValueReferenceType(RetType);
- else if (Inner->isXValue())
- RetType = CGF->getContext().getRValueReferenceType(RetType);
+ QualType RetType;
+ if (auto *Call = dyn_cast<CallExpr>(Inner))
+ RetType = Call->getCallReturnType(CGF->getContext());
+ else if (auto *Ctor = dyn_cast<CXXConstructExpr>(Inner))
+ RetType = Ctor->getType();
llvm::Constant *Res =
emitAbstract(CE->getBeginLoc(), CE->getAPValueResult(), RetType);
return Res;
diff --git a/clang/lib/Index/USRGeneration.cpp b/clang/lib/Index/USRGeneration.cpp
index 9ada9ac8c209..abaeb1a4232f 100644
--- a/clang/lib/Index/USRGeneration.cpp
+++ b/clang/lib/Index/USRGeneration.cpp
@@ -983,10 +983,6 @@ void USRGenerator::VisitTemplateArgument(const TemplateArgument &Arg) {
VisitType(Arg.getIntegralType());
Out << Arg.getAsIntegral();
break;
-
- case TemplateArgument::UncommonValue:
- // FIXME: Visit value.
- break;
}
}
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index b1181944c7fd..29038ab9fe1c 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -2657,7 +2657,6 @@ addAssociatedClassesAndNamespaces(AssociatedLookup &Result,
case TemplateArgument::Integral:
case TemplateArgument::Expression:
case TemplateArgument::NullPtr:
- case TemplateArgument::UncommonValue:
// [Note: non-type template arguments do not contribute to the set of
// associated namespaces. ]
break;
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 5f4d5b9632e0..13d2125d1a28 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -5619,8 +5619,7 @@ static ExprResult CheckConvertedConstantExpression(Sema &S, Expr *From,
QualType T, APValue &Value,
Sema::CCEKind CCE,
bool RequireInt,
- NamedDecl *Dest,
- bool *ValueDependent) {
+ NamedDecl *Dest) {
assert(S.getLangOpts().CPlusPlus11 &&
"converted constant expression outside C++11");
@@ -5744,8 +5743,6 @@ static ExprResult CheckConvertedConstantExpression(Sema &S, Expr *From,
if (Result.get()->isValueDependent()) {
Value = APValue();
- if (ValueDependent)
- *ValueDependent = true;
return Result;
}
@@ -5769,14 +5766,10 @@ static ExprResult CheckConvertedConstantExpression(Sema &S, Expr *From,
Result = ExprError();
} else {
Value = Eval.Val;
- if (ValueDependent)
- *ValueDependent = Eval.Dependent;
if (Notes.empty()) {
// It's a constant expression.
- Expr *E = Result.get();
- if (!isa<ConstantExpr>(E))
- E = ConstantExpr::Create(S.Context, Result.get(), Value);
+ Expr *E = ConstantExpr::Create(S.Context, Result.get(), Value);
if (ReturnPreNarrowingValue)
Value = std::move(PreNarrowingValue);
return E;
@@ -5803,10 +5796,9 @@ static ExprResult CheckConvertedConstantExpression(Sema &S, Expr *From,
ExprResult Sema::CheckConvertedConstantExpression(Expr *From, QualType T,
APValue &Value, CCEKind CCE,
- NamedDecl *Dest,
- bool *ValueDependent) {
+ NamedDecl *Dest) {
return ::CheckConvertedConstantExpression(*this, From, T, Value, CCE, false,
- Dest, ValueDependent);
+ Dest);
}
ExprResult Sema::CheckConvertedConstantExpression(Expr *From, QualType T,
@@ -5816,8 +5808,7 @@ ExprResult Sema::CheckConvertedConstantExpression(Expr *From, QualType T,
APValue V;
auto R = ::CheckConvertedConstantExpression(*this, From, T, V, CCE, true,
- /*Dest=*/nullptr,
- /*ValueDependent=*/nullptr);
+ /*Dest=*/nullptr);
if (!R.isInvalid() && !R.get()->isValueDependent())
Value = V.getInt();
return R;
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 34f5e2c4fb67..12880b95b9c6 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -4086,7 +4086,6 @@ static bool isTemplateArgumentTemplateParameter(
case TemplateArgument::NullPtr:
case TemplateArgument::Integral:
case TemplateArgument::Declaration:
- case TemplateArgument::UncommonValue:
case TemplateArgument::Pack:
case TemplateArgument::TemplateExpansion:
return false;
@@ -5420,7 +5419,6 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param,
case TemplateArgument::Declaration:
case TemplateArgument::Integral:
- case TemplateArgument::UncommonValue:
case TemplateArgument::NullPtr:
// We've already checked this template argument, so just copy
// it to the list of converted arguments.
@@ -5567,10 +5565,11 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param,
return true;
case TemplateArgument::Declaration:
+ llvm_unreachable("Declaration argument with template template parameter");
case TemplateArgument::Integral:
- case TemplateArgument::UncommonValue:
+ llvm_unreachable("Integral argument with template template parameter");
case TemplateArgument::NullPtr:
- llvm_unreachable("non-type argument with template template parameter");
+ llvm_unreachable("Null pointer argument with template template parameter");
case TemplateArgument::Pack:
llvm_unreachable("Caller must expand template argument packs");
@@ -6621,12 +6620,6 @@ CheckTemplateArgumentAddressOfObjectOrFunction(Sema &S,
Arg, ArgType))
return true;
- // Don't build a resolved template argument naming a dependent declaration.
- if (Entity->isTemplated()) {
- Converted = TemplateArgument(ArgIn);
- return false;
- }
-
// Create the template argument.
Converted = TemplateArgument(cast<ValueDecl>(Entity->getCanonicalDecl()),
S.Context.getCanonicalType(ParamType));
@@ -6641,6 +6634,8 @@ static bool CheckTemplateArgumentPointerToMember(Sema &S,
QualType ParamType,
Expr *&ResultArg,
TemplateArgument &Converted) {
+ bool Invalid = false;
+
Expr *Arg = ResultArg;
bool ObjCLifetimeConversion;
@@ -6656,7 +6651,7 @@ static bool CheckTemplateArgumentPointerToMember(Sema &S,
// See http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#773
bool ExtraParens = false;
while (ParenExpr *Parens = dyn_cast<ParenExpr>(Arg)) {
- if (!ExtraParens) {
+ if (!Invalid && !ExtraParens) {
S.Diag(Arg->getBeginLoc(),
S.getLangOpts().CPlusPlus11
? diag::warn_cxx98_compat_template_arg_extra_parens
@@ -6685,8 +6680,13 @@ static bool CheckTemplateArgumentPointerToMember(Sema &S,
ValueDecl *VD = DRE->getDecl();
if (VD->getType()->isMemberPointerType()) {
if (isa<NonTypeTemplateParmDecl>(VD)) {
- Converted = TemplateArgument(Arg);
- return false;
+ if (Arg->isTypeDependent() || Arg->isValueDependent()) {
+ Converted = TemplateArgument(Arg);
+ } else {
+ VD = cast<ValueDecl>(VD->getCanonicalDecl());
+ Converted = TemplateArgument(VD, ParamType);
+ }
+ return Invalid;
}
}
@@ -6745,7 +6745,7 @@ static bool CheckTemplateArgumentPointerToMember(Sema &S,
ValueDecl *D = cast<ValueDecl>(DRE->getDecl()->getCanonicalDecl());
Converted = TemplateArgument(D, S.Context.getCanonicalType(ParamType));
}
- return false;
+ return Invalid;
}
// We found something else, but we don't know specifically what it is.
@@ -6922,24 +6922,49 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
// A template-argument for a non-type template parameter shall be
// a converted constant expression of the type of the template-parameter.
APValue Value;
- bool ValueDependent = false;
ExprResult ArgResult = CheckConvertedConstantExpression(
- Arg, ParamType, Value, CCEK_TemplateArg, Param, &ValueDependent);
+ Arg, ParamType, Value, CCEK_TemplateArg, Param);
if (ArgResult.isInvalid())
return ExprError();
// For a value-dependent argument, CheckConvertedConstantExpression is
- // permitted (and expected) to be unable to determine a value. We might find
- // the evaluated result refers to a dependent declaration even though the
- // template argument is not a value-dependent expression.
- if (ValueDependent) {
+ // permitted (and expected) to be unable to determine a value.
+ if (ArgResult.get()->isValueDependent()) {
Converted = TemplateArgument(ArgResult.get());
return ArgResult;
}
- // Prior to C++20, enforce restrictions on possible template argument
- // values.
- if (!getLangOpts().CPlusPlus20 && Value.isLValue()) {
+ // Convert the APValue to a TemplateArgument.
+ switch (Value.getKind()) {
+ case APValue::None:
+ assert(ParamType->isNullPtrType());
+ Converted = TemplateArgument(CanonParamType, /*isNullPtr*/true);
+ break;
+ case APValue::Indeterminate:
+ llvm_unreachable("result of constant evaluation should be initialized");
+ break;
+ case APValue::Int:
+ assert(ParamType->isIntegralOrEnumerationType());
+ Converted = TemplateArgument(Context, Value.getInt(), CanonParamType);
+ break;
+ case APValue::MemberPointer: {
+ assert(ParamType->isMemberPointerType());
+
+ // FIXME: We need TemplateArgument representation and mangling for these.
+ if (!Value.getMemberPointerPath().empty()) {
+ Diag(Arg->getBeginLoc(),
+ diag::err_template_arg_member_ptr_base_derived_not_supported)
+ << Value.getMemberPointerDecl() << ParamType
+ << Arg->getSourceRange();
+ return ExprError();
+ }
+
+ auto *VD = const_cast<ValueDecl*>(Value.getMemberPointerDecl());
+ Converted = VD ? TemplateArgument(VD, CanonParamType)
+ : TemplateArgument(CanonParamType, /*isNullPtr*/true);
+ break;
+ }
+ case APValue::LValue: {
// For a non-type template-parameter of pointer or reference type,
// the value of the constant expression shall not refer to
assert(ParamType->isPointerType() || ParamType->isReferenceType() ||
@@ -6955,7 +6980,8 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
<< Arg->getSourceRange();
return ExprError();
}
- // -- a subobject [until C++20]
+ // -- a subobject
+ // FIXME: Until C++20
if (Value.hasLValuePath() && Value.getLValuePath().size() == 1 &&
VD && VD->getType()->isArrayType() &&
Value.getLValuePath()[0].getAsArrayIndex() == 0 &&
@@ -6973,12 +6999,29 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
"null reference should not be a constant expression");
assert((!VD || !ParamType->isNullPtrType()) &&
"non-null value of type nullptr_t?");
+ Converted = VD ? TemplateArgument(VD, CanonParamType)
+ : TemplateArgument(CanonParamType, /*isNullPtr*/true);
+ break;
}
-
- if (Value.isAddrLabelDiff())
+ case APValue::Struct:
+ case APValue::Union:
+ // Get or create the corresponding template parameter object.
+ Converted = TemplateArgument(
+ Context.getTemplateParamObjectDecl(CanonParamType, Value),
+ CanonParamType);
+ break;
+ case APValue::AddrLabelDiff:
return Diag(StartLoc, diag::err_non_type_template_arg_addr_label_
diff );
+ case APValue::FixedPoint:
+ case APValue::Float:
+ case APValue::ComplexInt:
+ case APValue::ComplexFloat:
+ case APValue::Vector:
+ case APValue::Array:
+ return Diag(StartLoc, diag::err_non_type_template_arg_unsupported)
+ << ParamType;
+ }
- Converted = TemplateArgument(Context, CanonParamType, Value);
return ArgResult.get();
}
@@ -7516,9 +7559,12 @@ Sema::BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg,
/// This routine takes care of the mapping from an integral template
/// argument (which may have any integral type) to the appropriate
/// literal value.
-static Expr *BuildExpressionFromIntegralTemplateArgumentValue(
- Sema &S, QualType OrigT, const llvm::APSInt &Int, SourceLocation Loc) {
- assert(OrigT->isIntegralOrEnumerationType());
+ExprResult
+Sema::BuildExpressionFromIntegralTemplateArgument(const TemplateArgument &Arg,
+ SourceLocation Loc) {
+ assert(Arg.getKind() == TemplateArgument::Integral &&
+ "Operation is only valid for integral template arguments");
+ QualType OrigT = Arg.getIntegralType();
// If this is an enum type that we're instantiating, we need to use an integer
// type the same size as the enumerator. We don't want to build an
@@ -7534,7 +7580,7 @@ static Expr *BuildExpressionFromIntegralTemplateArgumentValue(
CharacterLiteral::CharacterKind Kind;
if (T->isWideCharType())
Kind = CharacterLiteral::Wide;
- else if (T->isChar8Type() && S.getLangOpts().Char8)
+ else if (T->isChar8Type() && getLangOpts().Char8)
Kind = CharacterLiteral::UTF8;
else if (T->isChar16Type())
Kind = CharacterLiteral::UTF16;
@@ -7543,133 +7589,29 @@ static Expr *BuildExpressionFromIntegralTemplateArgumentValue(
else
Kind = CharacterLiteral::Ascii;
- E = new (S.Context) CharacterLiteral(Int.getZExtValue(), Kind, T, Loc);
+ E = new (Context) CharacterLiteral(Arg.getAsIntegral().getZExtValue(),
+ Kind, T, Loc);
} else if (T->isBooleanType()) {
- E = new (S.Context) CXXBoolLiteralExpr(Int.getBoolValue(), T, Loc);
+ E = new (Context) CXXBoolLiteralExpr(Arg.getAsIntegral().getBoolValue(),
+ T, Loc);
+ } else if (T->isNullPtrType()) {
+ E = new (Context) CXXNullPtrLiteralExpr(Context.NullPtrTy, Loc);
} else {
- E = IntegerLiteral::Create(S.Context, Int, T, Loc);
+ E = IntegerLiteral::Create(Context, Arg.getAsIntegral(), T, Loc);
}
if (OrigT->isEnumeralType()) {
// FIXME: This is a hack. We need a better way to handle substituted
// non-type template parameters.
- E = CStyleCastExpr::Create(S.Context, OrigT, VK_RValue, CK_IntegralCast, E,
- nullptr, S.CurFPFeatureOverrides(),
- S.Context.getTrivialTypeSourceInfo(OrigT, Loc),
+ E = CStyleCastExpr::Create(Context, OrigT, VK_RValue, CK_IntegralCast, E,
+ nullptr, CurFPFeatureOverrides(),
+ Context.getTrivialTypeSourceInfo(OrigT, Loc),
Loc, Loc);
}
return E;
}
-static Expr *BuildExpressionFromNonTypeTemplateArgumentValue(
- Sema &S, QualType T, const APValue &Val, SourceLocation Loc) {
- auto MakeInitList = [&] (ArrayRef<Expr*> Elts) -> Expr* {
- auto *ILE = new (S.Context) InitListExpr(S.Context, Loc, Elts, Loc);
- ILE->setType(T);
- return ILE;
- };
-
- switch (Val.getKind()) {
- case APValue::AddrLabelDiff:
- // This cannot occur in a template argument at all.
- case APValue::Array:
- case APValue::Struct:
- case APValue::Union:
- // These can only occur within a template parameter object, which is
- // represented as a TemplateArgument::Declaration.
- llvm_unreachable("unexpected template argument value");
-
- case APValue::Int:
- return BuildExpressionFromIntegralTemplateArgumentValue(S, T, Val.getInt(),
- Loc);
-
- case APValue::Float:
- return FloatingLiteral::Create(S.Context, Val.getFloat(), /*IsExact=*/true,
- T, Loc);
-
- case APValue::FixedPoint:
- return FixedPointLiteral::CreateFromRawInt(
- S.Context, Val.getFixedPoint().getValue(), T, Loc,
- Val.getFixedPoint().getScale());
-
- case APValue::ComplexInt: {
- QualType ElemT = T->castAs<ComplexType>()->getElementType();
- return MakeInitList({BuildExpressionFromIntegralTemplateArgumentValue(
- S, ElemT, Val.getComplexIntReal(), Loc),
- BuildExpressionFromIntegralTemplateArgumentValue(
- S, ElemT, Val.getComplexIntImag(), Loc)});
- }
-
- case APValue::ComplexFloat: {
- QualType ElemT = T->castAs<ComplexType>()->getElementType();
- return MakeInitList(
- {FloatingLiteral::Create(S.Context, Val.getComplexFloatReal(), true,
- ElemT, Loc),
- FloatingLiteral::Create(S.Context, Val.getComplexFloatImag(), true,
- ElemT, Loc)});
- }
-
- case APValue::Vector: {
- QualType ElemT = T->castAs<VectorType>()->getElementType();
- llvm::SmallVector<Expr *, 8> Elts;
- for (unsigned I = 0, N = Val.getVectorLength(); I != N; ++I)
- Elts.push_back(BuildExpressionFromNonTypeTemplateArgumentValue(
- S, ElemT, Val.getVectorElt(I), Loc));
- return MakeInitList(Elts);
- }
-
- case APValue::None:
- case APValue::Indeterminate:
- // FIXME: Are these values possible?
- case APValue::LValue:
- case APValue::MemberPointer:
- // There isn't necessarily a valid equivalent source-level syntax for
- // these; in particular, a naive lowering might violate access control.
- // So for now we lower to a ConstantExpr holding the value, wrapped around
- // an OpaqueValueExpr.
- // FIXME: We should have a better representation for this.
- ExprValueKind VK = VK_RValue;
- if (T->isReferenceType()) {
- T = T->getPointeeType();
- VK = VK_LValue;
- }
- auto *OVE = new (S.Context) OpaqueValueExpr(Loc, T, VK);
- return ConstantExpr::Create(S.Context, OVE, Val);
- }
- llvm_unreachable("Unhandled APValue::ValueKind enum");
-}
-
-ExprResult
-Sema::BuildExpressionFromNonTypeTemplateArgument(const TemplateArgument &Arg,
- SourceLocation Loc) {
- switch (Arg.getKind()) {
- case TemplateArgument::Null:
- case TemplateArgument::Type:
- case TemplateArgument::Template:
- case TemplateArgument::TemplateExpansion:
- case TemplateArgument::Pack:
- llvm_unreachable("not a non-type template argument");
-
- case TemplateArgument::Expression:
- return Arg.getAsExpr();
-
- case TemplateArgument::NullPtr:
- case TemplateArgument::Declaration:
- return BuildExpressionFromDeclTemplateArgument(
- Arg, Arg.getNonTypeTemplateArgumentType(), Loc);
-
- case TemplateArgument::Integral:
- return BuildExpressionFromIntegralTemplateArgumentValue(
- *this, Arg.getIntegralType(), Arg.getAsIntegral(), Loc);
-
- case TemplateArgument::UncommonValue:
- return BuildExpressionFromNonTypeTemplateArgumentValue(
- *this, Arg.getUncommonValueType(), Arg.getAsUncommonValue(), Loc);
- }
- llvm_unreachable("Unhandled TemplateArgument::ArgKind enum");
-}
-
/// Match two template parameters within template parameter lists.
static bool MatchTemplateParameterKind(Sema &S, NamedDecl *New, NamedDecl *Old,
bool Complain,
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 92895e0b3db1..ee4316e7a632 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -276,16 +276,6 @@ checkDeducedTemplateArguments(ASTContext &Context,
// All other combinations are incompatible.
return DeducedTemplateArgument();
- case TemplateArgument::UncommonValue:
- // If we deduced a value and a dependent expression, keep the value.
- if (Y.getKind() == TemplateArgument::Expression ||
- (Y.getKind() == TemplateArgument::UncommonValue &&
- X.structurallyEquals(Y)))
- return X;
-
- // All other combinations are incompatible.
- return DeducedTemplateArgument();
-
case TemplateArgument::Template:
if (Y.getKind() == TemplateArgument::Template &&
Context.hasSameTemplateName(X.getAsTemplate(), Y.getAsTemplate()))
@@ -2371,18 +2361,20 @@ DeduceTemplateArguments(Sema &S,
return Sema::TDK_NonDeducedMismatch;
case TemplateArgument::Integral:
- if (Arg.getKind() == TemplateArgument::Integral &&
- hasSameExtendedValue(Param.getAsIntegral(), Arg.getAsIntegral()))
- return Sema::TDK_Success;
+ if (Arg.getKind() == TemplateArgument::Integral) {
+ if (hasSameExtendedValue(Param.getAsIntegral(), Arg.getAsIntegral()))
+ return Sema::TDK_Success;
- Info.FirstArg = Param;
- Info.SecondArg = Arg;
- return Sema::TDK_NonDeducedMismatch;
+ Info.FirstArg = Param;
+ Info.SecondArg = Arg;
+ return Sema::TDK_NonDeducedMismatch;
+ }
- case TemplateArgument::UncommonValue:
- if (Arg.getKind() == TemplateArgument::UncommonValue &&
- Arg.structurallyEquals(Param))
- return Sema::TDK_Success;
+ if (Arg.getKind() == TemplateArgument::Expression) {
+ Info.FirstArg = Param;
+ Info.SecondArg = Arg;
+ return Sema::TDK_NonDeducedMismatch;
+ }
Info.FirstArg = Param;
Info.SecondArg = Arg;
@@ -2391,34 +2383,28 @@ DeduceTemplateArguments(Sema &S,
case TemplateArgument::Expression:
if (const NonTypeTemplateParmDecl *NTTP =
getDeducedParameterFromExpr(Info, Param.getAsExpr())) {
- switch (Arg.getKind()) {
- case TemplateArgument::Integral:
- case TemplateArgument::Expression:
- case TemplateArgument::UncommonValue:
- return DeduceNonTypeTemplateArgument(
- S, TemplateParams, NTTP, DeducedTemplateArgument(Arg),
- Arg.getNonTypeTemplateArgumentType(), Info, Deduced);
-
- case TemplateArgument::NullPtr:
- return DeduceNullPtrTemplateArgument(
- S, TemplateParams, NTTP, Arg.getNullPtrType(), Info, Deduced);
-
+ if (Arg.getKind() == TemplateArgument::Integral)
+ return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP,
+ Arg.getAsIntegral(),
+ Arg.getIntegralType(),
+ /*ArrayBound=*/false,
+ Info, Deduced);
+ if (Arg.getKind() == TemplateArgument::NullPtr)
+ return DeduceNullPtrTemplateArgument(S, TemplateParams, NTTP,
+ Arg.getNullPtrType(),
+ Info, Deduced);
+ if (Arg.getKind() == TemplateArgument::Expression)
+ return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP,
+ Arg.getAsExpr(), Info, Deduced);
+ if (Arg.getKind() == TemplateArgument::Declaration)
+ return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP,
+ Arg.getAsDecl(),
+ Arg.getParamTypeForDecl(),
+ Info, Deduced);
- case TemplateArgument::Declaration:
- return DeduceNonTypeTemplateArgument(
- S, TemplateParams, NTTP, Arg.getAsDecl(), Arg.getParamTypeForDecl(),
- Info, Deduced);
-
- case TemplateArgument::Null:
- case TemplateArgument::Type:
- case TemplateArgument::Template:
- case TemplateArgument::TemplateExpansion:
- case TemplateArgument::Pack:
- Info.FirstArg = Param;
- Info.SecondArg = Arg;
- return Sema::TDK_NonDeducedMismatch;
- }
- llvm_unreachable("Unknown template argument kind");
+ Info.FirstArg = Param;
+ Info.SecondArg = Arg;
+ return Sema::TDK_NonDeducedMismatch;
}
// Can't deduce anything, but that's okay.
@@ -2606,9 +2592,6 @@ static bool isSameTemplateArg(ASTContext &Context,
case TemplateArgument::Integral:
return hasSameExtendedValue(X.getAsIntegral(), Y.getAsIntegral());
- case TemplateArgument::UncommonValue:
- return X.structurallyEquals(Y);
-
case TemplateArgument::Expression: {
llvm::FoldingSetNodeID XID, YID;
X.getAsExpr()->Profile(XID, Context, true);
@@ -2674,9 +2657,9 @@ Sema::getTrivialTemplateArgumentLoc(const TemplateArgument &Arg,
E);
}
- case TemplateArgument::Integral:
- case TemplateArgument::UncommonValue: {
- Expr *E = BuildExpressionFromNonTypeTemplateArgument(Arg, Loc).get();
+ case TemplateArgument::Integral: {
+ Expr *E =
+ BuildExpressionFromIntegralTemplateArgument(Arg, Loc).getAs<Expr>();
return TemplateArgumentLoc(TemplateArgument(E), E);
}
@@ -6118,8 +6101,11 @@ MarkUsedTemplateParameters(ASTContext &Ctx,
case TemplateArgument::Null:
case TemplateArgument::Integral:
case TemplateArgument::Declaration:
+ break;
+
case TemplateArgument::NullPtr:
- case TemplateArgument::UncommonValue:
+ MarkUsedTemplateParameters(Ctx, TemplateArg.getNullPtrType(), OnlyDeduced,
+ Depth, Used);
break;
case TemplateArgument::Type:
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 7d7591ab669c..8bd812b39de4 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -1556,18 +1556,16 @@ ExprResult TemplateInstantiator::transformNonTypeTemplateParmRef(
VD = nullptr;
}
- QualType paramType = arg.getNonTypeTemplateArgumentType();
+ QualType paramType = VD ? arg.getParamTypeForDecl() : arg.getNullPtrType();
assert(!paramType.isNull() && "type substitution failed for param type");
assert(!paramType->isDependentType() && "param type still dependent");
result = SemaRef.BuildExpressionFromDeclTemplateArgument(arg, paramType, loc);
refParam = paramType->isReferenceType();
} else {
- QualType paramType = arg.getNonTypeTemplateArgumentType();
- result = SemaRef.BuildExpressionFromNonTypeTemplateArgument(arg, loc);
- refParam = paramType->isReferenceType();
+ result = SemaRef.BuildExpressionFromIntegralTemplateArgument(arg, loc);
assert(result.isInvalid() ||
SemaRef.Context.hasSameType(result.get()->getType(),
- paramType.getNonReferenceType()));
+ arg.getIntegralType()));
}
if (result.isInvalid())
@@ -3232,8 +3230,7 @@ Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation,
if (FunctionDecl *Pattern =
Function->getInstantiatedFromMemberFunction()) {
- if (TSK != TSK_ImplicitInstantiation &&
- Function->hasAttr<ExcludeFromExplicitInstantiationAttr>())
+ if (Function->hasAttr<ExcludeFromExplicitInstantiationAttr>())
continue;
MemberSpecializationInfo *MSInfo =
@@ -3278,8 +3275,7 @@ Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation,
continue;
if (Var->isStaticDataMember()) {
- if (TSK != TSK_ImplicitInstantiation &&
- Var->hasAttr<ExcludeFromExplicitInstantiationAttr>())
+ if (Var->hasAttr<ExcludeFromExplicitInstantiationAttr>())
continue;
MemberSpecializationInfo *MSInfo = Var->getMemberSpecializationInfo();
@@ -3296,7 +3292,7 @@ Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation,
SuppressNew)
continue;
- if (TSK != TSK_ExplicitInstantiationDeclaration) {
+ if (TSK == TSK_ExplicitInstantiationDefinition) {
// C++0x [temp.explicit]p8:
// An explicit instantiation definition that names a class template
// specialization explicitly instantiates the class template
diff --git a/clang/lib/Sema/SemaTemplateVariadic.cpp b/clang/lib/Sema/SemaTemplateVariadic.cpp
index 3c6365a075f4..1951aec3d17d 100644
--- a/clang/lib/Sema/SemaTemplateVariadic.cpp
+++ b/clang/lib/Sema/SemaTemplateVariadic.cpp
@@ -1103,7 +1103,6 @@ Sema::getTemplateArgumentPackExpansionPattern(
case TemplateArgument::NullPtr:
case TemplateArgument::Template:
case TemplateArgument::Integral:
- case TemplateArgument::UncommonValue:
case TemplateArgument::Pack:
case TemplateArgument::Null:
return TemplateArgumentLoc();
@@ -1154,7 +1153,6 @@ Optional<unsigned> Sema::getFullyPackExpandedSize(TemplateArgument Arg) {
case TemplateArgument::NullPtr:
case TemplateArgument::TemplateExpansion:
case TemplateArgument::Integral:
- case TemplateArgument::UncommonValue:
case TemplateArgument::Pack:
case TemplateArgument::Null:
return None;
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 0660c824b3cc..0a596e50658b 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -3557,7 +3557,6 @@ class TreeTransform {
case TemplateArgument::Null:
case TemplateArgument::Integral:
case TemplateArgument::Declaration:
- case TemplateArgument::UncommonValue:
case TemplateArgument::Pack:
case TemplateArgument::TemplateExpansion:
case TemplateArgument::NullPtr:
@@ -4230,8 +4229,7 @@ bool TreeTransform<Derived>::TransformTemplateArgument(
case TemplateArgument::Integral:
case TemplateArgument::NullPtr:
- case TemplateArgument::Declaration:
- case TemplateArgument::UncommonValue: {
+ case TemplateArgument::Declaration: {
// Transform a resolved template argument straight to a resolved template
// argument. We get here when substituting into an already-substituted
// template type argument during concept satisfaction checking.
@@ -4258,15 +4256,9 @@ bool TreeTransform<Derived>::TransformTemplateArgument(
else if (Arg.getKind() == TemplateArgument::NullPtr)
Output = TemplateArgumentLoc(TemplateArgument(NewT, /*IsNullPtr=*/true),
TemplateArgumentLocInfo());
- else if (Arg.getKind() == TemplateArgument::Declaration)
+ else
Output = TemplateArgumentLoc(TemplateArgument(NewD, NewT),
TemplateArgumentLocInfo());
- else if (Arg.getKind() == TemplateArgument::UncommonValue)
- Output = TemplateArgumentLoc(
- TemplateArgument(getSema().Context, NewT, Arg.getAsUncommonValue()),
- TemplateArgumentLocInfo());
- else
- llvm_unreachable("unexpected template argument kind");
return false;
}
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 5c7187fd773d..d01e7c69d181 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -7100,7 +7100,6 @@ ASTRecordReader::readTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind) {
case TemplateArgument::Integral:
case TemplateArgument::Declaration:
case TemplateArgument::NullPtr:
- case TemplateArgument::UncommonValue:
case TemplateArgument::Pack:
// FIXME: Is this right?
return TemplateArgumentLocInfo();
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index a5c62e3e6984..9c16ded13cd9 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -5218,7 +5218,6 @@ void ASTRecordWriter::AddTemplateArgumentLocInfo(
case TemplateArgument::Integral:
case TemplateArgument::Declaration:
case TemplateArgument::NullPtr:
- case TemplateArgument::UncommonValue:
case TemplateArgument::Pack:
// FIXME: Is this right?
break;
diff --git a/clang/test/CodeGenCXX/mangle-ms-templates.cpp b/clang/test/CodeGenCXX/mangle-ms-templates.cpp
index a5ddb41461cc..7402d367ae3e 100644
--- a/clang/test/CodeGenCXX/mangle-ms-templates.cpp
+++ b/clang/test/CodeGenCXX/mangle-ms-templates.cpp
@@ -2,21 +2,6 @@
// RUN: %clang_cc1 -std=c++11 -fms-compatibility-version=19 -emit-llvm %s -o - -fms-extensions -fdelayed-template-parsing -triple=x86_64-pc-win32 | FileCheck -check-prefix X64 %s
// RUN: %clang_cc1 -std=c++17 -fms-compatibility-version=19 -emit-llvm %s -o - -fms-extensions -fdelayed-template-parsing -triple=i386-pc-win32 | FileCheck %s
// RUN: %clang_cc1 -std=c++17 -fms-compatibility-version=19 -emit-llvm %s -o - -fms-extensions -fdelayed-template-parsing -triple=x86_64-pc-win32 | FileCheck -check-prefix X64 %s
-// RUN: %clang_cc1 -std=c++20 -fms-compatibility-version=19 -emit-llvm %s -o - -fms-extensions -fdelayed-template-parsing -triple=x86_64-pc-win32 | FileCheck -check-prefix CXX20-X64 %s
-
-// Check that array-to-pointer decay is mangled as the underlying declaration.
-extern const char arr[4] = "foo";
-template<const char*> struct Decay1 {};
-// CHECK: "?decay1@@3U?$Decay1@$1?arr@@3QBDB@@A"
-Decay1<arr> decay1;
-#if __cplusplus >= 201702L
-// Note that this mangling approach can lead to collisions.
-template<const void*> struct Decay2 {};
-// CXX20-X64: "?decay2a@@3U?$Decay2@$1?arr@@3QBDB@@A"
-Decay2<(const void*)arr> decay2a;
-// CXX20-X64: "?decay2b@@3U?$Decay2@$1?arr@@3QBDB@@A"
-Decay2<(const void*)&arr> decay2b;
-#endif
template<typename T>
class Class {
@@ -342,12 +327,3 @@ void fun_uint128(UInt128<(unsigned __int128)-1>) {}
// X64: define {{.*}} @"?fun_uint128@@YAXU?$UInt128@$0DPPPPPPPPPPPPPPPAAAAAAAAAAAAAAAB@@@@Z"(
void fun_uint128(UInt128<(unsigned __int128)9223372036854775807 * (unsigned __int128)9223372036854775807>) {}
#endif
-
-#if __cplusplus >= 202002L
-template<float> struct Float {};
-// CXX20-X64: define {{.*}} @"?f@@YAXU?$Float@$ADPIAAAAA@@@@Z"(
-void f(Float<1.0f>) {}
-template<auto> struct Auto {};
-// CXX20-X64: define {{.*}} @"?f@@YAXU?$Auto@$MMADPIAAAAA@@@@Z"(
-void f(Auto<1.0f>) {}
-#endif
diff --git a/clang/test/CodeGenCXX/mangle-template.cpp b/clang/test/CodeGenCXX/mangle-template.cpp
index 8326bf658f06..40688de7e12e 100644
--- a/clang/test/CodeGenCXX/mangle-template.cpp
+++ b/clang/test/CodeGenCXX/mangle-template.cpp
@@ -226,16 +226,6 @@ namespace test16 {
namespace cxx20 {
template<auto> struct A {};
template<typename T, T V> struct B {};
- // CXX20: define {{.*}} @_ZN5cxx201fENS_1AILf3f800000EEE(
- void f(A<1.0f>) {}
- // CXX20: define {{.*}} @_ZN5cxx201fENS_1AILd3ff0000000000000EEE(
- void f(A<1.0>) {}
- // CXX20: define {{.*}} @_ZN5cxx201fENS_1AILe3fff8000000000000000EEE(
- void f(A<1.0l>) {}
- // CXX20: define {{.*}} @_ZN5cxx201fENS_1AIXtlCiLi0ELi1EEEEE(
- void f(A<1i>) {}
- // CXX20: define {{.*}} @_ZN5cxx201fENS_1AIXtlCdLd0000000000000000ELd3ff0000000000000EEEEE(
- void f(A<1.0i>) {}
int x;
// CXX20: define {{.*}} @_ZN5cxx201fENS_1AIXadL_ZNS_1xEEEEE(
@@ -255,24 +245,7 @@ namespace cxx20 {
// CXX20: define {{.*}} @_ZN5cxx201fENS_1BIPKvXadL_ZNS_1xEEEEE(
void f(B<const void*, (const void*)&x>) {}
- struct Q { int x; } q;
-
- // CXX20: define {{.*}} @_ZN5cxx201fENS_1AIXadsoiL_ZNS_1qEEEEEE(
- void f(A<&q.x>) {}
- // CXX20: define {{.*}} @_ZN5cxx201fENS_1BIPiXadsoiL_ZNS_1qEEEEEE(
- void f(B<int*, &q.x>) {}
- // CXX20: define {{.*}} @_ZN5cxx201fENS_1AIXadsoKiL_ZNS_1qEEEEEE(
- void f(A<(const int*)&q.x>) {}
- // CXX20: define {{.*}} @_ZN5cxx201fENS_1BIPKiXadsoS1_L_ZNS_1qEEEEEE
- void f(B<const int*, (const int*)&q.x>) {}
- // CXX20: define {{.*}} @_ZN5cxx201fENS_1AIXcvPvadsoiL_ZNS_1qEEEEEE(
- void f(A<(void*)&q.x>) {}
- // CXX20: define {{.*}} @_ZN5cxx201fENS_1BIPvXadsoiL_ZNS_1qEEEEEE(
- void f(B<void*, (void*)&q.x>) {}
- // CXX20: define {{.*}} @_ZN5cxx201fENS_1AIXcvPKvadsoiL_ZNS_1qEEEEEE(
- void f(A<(const void*)&q.x>) {}
- // CXX20: define {{.*}} @_ZN5cxx201fENS_1BIPKvXadsoiL_ZNS_1qEEEEEE(
- void f(B<const void*, (const void*)&q.x>) {}
+ struct Q { int x; };
// CXX20: define {{.*}} @_ZN5cxx201fENS_1AIXadL_ZNS_1Q1xEEEEE(
void f(A<&Q::x>) {}
@@ -282,17 +255,6 @@ namespace cxx20 {
void f(A<(const int Q::*)&Q::x>) {}
// CXX20: define {{.*}} @_ZN5cxx201fENS_1BIMNS_1QEKiXadL_ZNS1_1xEEEEE(
void f(B<const int Q::*, (const int Q::*)&Q::x>) {}
-
- struct R : Q {};
-
- // CXX20: define {{.*}} @_ZN5cxx201fENS_1AIXmcMNS_1REiadL_ZNS_1Q1xEEEEEE(
- void f(A<(int R::*)&Q::x>) {}
- // CXX20: define {{.*}} @_ZN5cxx201fENS_1BIMNS_1REiXmcS2_adL_ZNS_1Q1xEEEEEE(
- void f(B<int R::*, (int R::*)&Q::x>) {}
- // CXX20: define {{.*}} @_ZN5cxx201fENS_1AIXmcMNS_1REKiadL_ZNS_1Q1xEEEEEE(
- void f(A<(const int R::*)&Q::x>) {}
- // CXX20: define {{.*}} @_ZN5cxx201fENS_1BIMNS_1REKiXmcS3_adL_ZNS_1Q1xEEEEEE(
- void f(B<const int R::*, (const int R::*)&Q::x>) {}
}
#endif
diff --git a/clang/test/CodeGenCXX/template-arguments.cpp b/clang/test/CodeGenCXX/template-arguments.cpp
deleted file mode 100644
index 289094be7f2b..000000000000
--- a/clang/test/CodeGenCXX/template-arguments.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-// RUN: %clang_cc1 -std=c++20 %s -emit-llvm -o - -triple x86_64-linux -DCONSTEXPR= | FileCheck %s
-// RUN: %clang_cc1 -std=c++20 %s -emit-llvm -o - -triple x86_64-linux -DCONSTEXPR=constexpr | FileCheck %s --check-prefix=CONST
-
-template<typename T> CONSTEXPR T id(T v) { return v; }
-template<auto V> auto value = id(V);
-
-// CHECK: call {{.*}} @_Z2idIiET_S0_(i32 1)
-// CONST: @_Z5valueILi1EE = weak_odr {{.*}} i32 1,
-template int value<1>;
-
-// CHECK: call {{.*}} @_Z2idIyET_S0_(i64 -1)
-// CONST: @_Z5valueILy18446744073709551615EE = weak_odr {{.*}} i64 -1,
-template unsigned long long value<-1ULL>;
-
-// CHECK: call {{.*}} @_Z2idIfET_S0_(float 1.000000e+00)
-// CONST: @_Z5valueILf3f800000EE = weak_odr {{.*}} float 1.000000e+00,
-template float value<1.0f>;
-// CHECK: call {{.*}} @_Z2idIdET_S0_(double 1.000000e+00)
-// CONST: @_Z5valueILd3ff0000000000000EE = weak_odr {{.*}} double 1.000000e+00,
-template double value<1.0>;
-
-int n;
-// CHECK: call {{.*}} @_Z2idIPiET_S1_(i32* @n)
-// CONST: @_Z5valueIXadL_Z1nEEE = weak_odr {{.*}} i32* @n,
-template int *value<&n>;
-
-struct A { int a[3]; } a;
-// CHECK: call {{.*}} @_Z2idIPiET_S1_(i32* getelementptr inbounds (%struct.A, %struct.A* @a, i32 0, i32 0, i32 0))
-// CONST: @_Z5valueIXadsoiL_Z1aEEEE = weak_odr {{.*}} i32* getelementptr inbounds (%struct.A, %struct.A* @a, i32 0, i32 0, i32 0),
-template int *value<&a.a[0]>;
-// CHECK: call {{.*}} @_Z2idIPiET_S1_(i32* bitcast (i8* getelementptr (i8, i8* bitcast (%struct.A* @a to i8*), i64 4) to i32*))
-// CONST: @_Z5valueIXadsoiL_Z1aE4EEE = weak_odr {{.*}} i32* bitcast (i8* getelementptr (i8, i8* bitcast (%struct.A* @a to i8*), i64 4) to i32*),
-template int *value<&a.a[1]>;
-// CHECK: call {{.*}} @_Z2idIPiET_S1_(i32* bitcast (i8* getelementptr (i8, i8* bitcast (%struct.A* @a to i8*), i64 8) to i32*))
-// CONST: @_Z5valueIXadsoiL_Z1aE8EEE = weak_odr {{.*}} i32* bitcast (i8* getelementptr (i8, i8* bitcast (%struct.A* @a to i8*), i64 8) to i32*),
-template int *value<&a.a[2]>;
-// CHECK: call {{.*}} @_Z2idIPiET_S1_(i32* bitcast (i8* getelementptr (i8, i8* bitcast (%struct.A* @a to i8*), i64 12) to i32*))
-// CONST: @_Z5valueIXadsoiL_Z1aE12pEEE = weak_odr {{.*}} i32* bitcast (i8* getelementptr (i8, i8* bitcast (%struct.A* @a to i8*), i64 12) to i32*),
-template int *value<&a.a[3]>;
-
-struct B { int x, y; };
-// CHECK: call {{.*}} @_Z2idIM1BiET_S2_(i64 0)
-// CONST: @_Z5valueIXadL_ZN1B1xEEEE = weak_odr {{.*}} i64 0,
-template int B::*value<&B::x>;
-// CHECK: call {{.*}} @_Z2idIM1BiET_S2_(i64 4)
-// CONST: @_Z5valueIXadL_ZN1B1yEEEE = weak_odr {{.*}} i64 4,
-template int B::*value<&B::y>;
-
-struct C : A, B { int z; };
-// CHECK: call {{.*}} @_Z2idIM1CiET_S2_(i64 12)
-// CONST: @_Z5valueIXmcM1CiadL_ZN1B1xEE12EEE = weak_odr {{.*}} i64 12,
-template int C::*value<(int C::*)&B::x>;
-// CHECK: call {{.*}} @_Z2idIM1BiET_S2_(i64 8)
-// CONST: @_Z5valueIXmcM1BiadL_ZN1C1zEEn12EEE = weak_odr {{.*}} i64 8,
-template int B::*value<(int B::*)&C::z>;
-
-// CHECK: store i32 1, i32*
-// CHECK: store i32 2, i32*
-// CHECK: bitcast { i32, i32 }* %{{.*}} to i64*
-// CHECK: load i64,
-// CHECK: call {{.*}} @_Z2idICiET_S1_(i64 %
-// CONST: @_Z5valueIXtlCiLi1ELi2EEEE = weak_odr {{.*}} { i32, i32 } { i32 1, i32 2 },
-template _Complex int value<1 + 2j>;
-
-// CHECK: store float 1.000000e+00, float*
-// CHECK: store float 2.000000e+00, float*
-// CHECK: bitcast { float, float }* %{{.*}} to <2 x float>*
-// CHECK: load <2 x float>,
-// CHECK: call {{.*}} @_Z2idICfET_S1_(<2 x float> %
-// CONST: @_Z5valueIXtlCfLf3f800000ELf40000000EEEE = weak_odr {{.*}} { float, float } { float 1.000000e+00, float 2.000000e+00 },
-template _Complex float value<1.0f + 2.0fj>;
-
-using V3i __attribute__((ext_vector_type(3))) = int;
-// CHECK: call {{.*}} @_Z2idIDv3_iET_S1_(<3 x i32> <i32 1, i32 2, i32 3>)
-// CONST: @_Z5valueIXtlDv3_iLi1ELi2ELi3EEEE = weak_odr {{.*}} <3 x i32> <i32 1, i32 2, i32 3>
-template V3i value<V3i{1, 2, 3}>;
-
-using V3f [[gnu::vector_size(12)]] = float;
-// CHECK: call {{.*}} @_Z2idIDv3_fET_S1_(<3 x float> <float 1.000000e+00, float 2.000000e+00, float 3.000000e+00>)
-// CONST: @_Z5valueIXtlDv3_fLf3f800000ELf40000000ELf40400000EEEE = weak_odr {{.*}} <3 x float> <float 1.000000e+00, float 2.000000e+00, float 3.000000e+00>
-template V3f value<V3f{1, 2, 3}>;
diff --git a/clang/test/OpenMP/distribute_dist_schedule_messages.cpp b/clang/test/OpenMP/distribute_dist_schedule_messages.cpp
index 0f7b2172f5a5..cd232f40feb4 100644
--- a/clang/test/OpenMP/distribute_dist_schedule_messages.cpp
+++ b/clang/test/OpenMP/distribute_dist_schedule_messages.cpp
@@ -35,7 +35,7 @@ T tmain(T argc) {
for (int i = 0; i < 10; ++i) foo();
#pragma omp distribute dist_schedule (static, S1) // expected-error {{'S1' does not refer to a value}}
for (int i = 0; i < 10; ++i) foo();
- #pragma omp distribute dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error 2{{expression must have integral or unscoped enumeration type, not 'char *'}}
+ #pragma omp distribute dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error3 {{expression must have integral or unscoped enumeration type, not 'char *'}}
for (int i = 0; i < 10; ++i) foo();
return T();
}
diff --git a/clang/test/OpenMP/distribute_parallel_for_dist_schedule_messages.cpp b/clang/test/OpenMP/distribute_parallel_for_dist_schedule_messages.cpp
index 18dcac555f74..07e7704dffde 100644
--- a/clang/test/OpenMP/distribute_parallel_for_dist_schedule_messages.cpp
+++ b/clang/test/OpenMP/distribute_parallel_for_dist_schedule_messages.cpp
@@ -54,7 +54,7 @@ T tmain(T argc) {
for (int i = 0; i < 10; ++i) foo();
#pragma omp target
#pragma omp teams
-#pragma omp distribute parallel for dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error 2{{expression must have integral or unscoped enumeration type, not 'char *'}}
+#pragma omp distribute parallel for dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error3 {{expression must have integral or unscoped enumeration type, not 'char *'}}
for (int i = 0; i < 10; ++i) foo();
return T();
}
diff --git a/clang/test/OpenMP/distribute_parallel_for_simd_dist_schedule_messages.cpp b/clang/test/OpenMP/distribute_parallel_for_simd_dist_schedule_messages.cpp
index 63f8cfe917cd..ed7b19111dee 100644
--- a/clang/test/OpenMP/distribute_parallel_for_simd_dist_schedule_messages.cpp
+++ b/clang/test/OpenMP/distribute_parallel_for_simd_dist_schedule_messages.cpp
@@ -55,7 +55,7 @@ T tmain(T argc) {
for (int i = 0; i < 10; ++i) foo();
#pragma omp target
#pragma omp teams
-#pragma omp distribute parallel for simd dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error 2{{expression must have integral or unscoped enumeration type, not 'char *'}}
+#pragma omp distribute parallel for simd dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error3 {{expression must have integral or unscoped enumeration type, not 'char *'}}
for (int i = 0; i < 10; ++i) foo();
return T();
}
diff --git a/clang/test/OpenMP/distribute_simd_dist_schedule_messages.cpp b/clang/test/OpenMP/distribute_simd_dist_schedule_messages.cpp
index a6593cfbe0d3..794681c02646 100644
--- a/clang/test/OpenMP/distribute_simd_dist_schedule_messages.cpp
+++ b/clang/test/OpenMP/distribute_simd_dist_schedule_messages.cpp
@@ -63,7 +63,7 @@ T tmain(T argc) {
for (int i = 0; i < 10; ++i) foo();
#pragma omp target
#pragma omp teams
-#pragma omp distribute simd dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error 2{{expression must have integral or unscoped enumeration type, not 'char *'}}
+#pragma omp distribute simd dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error3 {{expression must have integral or unscoped enumeration type, not 'char *'}}
for (int i = 0; i < 10; ++i) foo();
return T();
}
diff --git a/clang/test/OpenMP/target_parallel_for_simd_collapse_messages.cpp b/clang/test/OpenMP/target_parallel_for_simd_collapse_messages.cpp
index f829874864da..7acb2587f976 100644
--- a/clang/test/OpenMP/target_parallel_for_simd_collapse_messages.cpp
+++ b/clang/test/OpenMP/target_parallel_for_simd_collapse_messages.cpp
@@ -46,7 +46,7 @@ T tmain(T argc, S **argv) {
#pragma omp target parallel for simd collapse (S) // expected-error {{'S' does not refer to a value}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
- // expected-error at +1 1+{{integral constant expression}} expected-note at +1 0+{{constant expression}}
+ // expected-error at +1 {{integral constant expression}} expected-note at +1 0+{{constant expression}}
#pragma omp target parallel for simd collapse (j=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
#pragma omp target parallel for simd collapse (1)
diff --git a/clang/test/OpenMP/target_parallel_for_simd_ordered_messages.cpp b/clang/test/OpenMP/target_parallel_for_simd_ordered_messages.cpp
index 972aa5753e36..8dd7f68c25fd 100644
--- a/clang/test/OpenMP/target_parallel_for_simd_ordered_messages.cpp
+++ b/clang/test/OpenMP/target_parallel_for_simd_ordered_messages.cpp
@@ -56,7 +56,7 @@ T tmain(T argc, S **argv) {
for (int i = ST; i < N; i++)
argv[0][i] = argv[0][i] - argv[0][i - ST];
-// expected-error at +1 {{'ordered' clause with a parameter can not be specified in '#pragma omp target parallel for simd' directive}}
+// expected-error at +1 {{integral constant expression}} expected-note at +1 0+{{constant expression}}
#pragma omp target parallel for simd ordered(j = 2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int i = ST; i < N; i++)
argv[0][i] = argv[0][i] - argv[0][i - ST];
diff --git a/clang/test/OpenMP/target_simd_collapse_messages.cpp b/clang/test/OpenMP/target_simd_collapse_messages.cpp
index d8b0a91f97d7..00fa3c85279f 100644
--- a/clang/test/OpenMP/target_simd_collapse_messages.cpp
+++ b/clang/test/OpenMP/target_simd_collapse_messages.cpp
@@ -44,7 +44,7 @@ T tmain(T argc, S **argv) {
#pragma omp target simd collapse (S) // expected-error {{'S' does not refer to a value}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
- // expected-error at +1 1+{{integral constant expression}} expected-note at +1 0+{{constant expression}}
+ // expected-error at +1 {{integral constant expression}} expected-note at +1 0+{{constant expression}}
#pragma omp target simd collapse (j=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
#pragma omp target simd collapse (1)
diff --git a/clang/test/OpenMP/target_teams_distribute_dist_schedule_messages.cpp b/clang/test/OpenMP/target_teams_distribute_dist_schedule_messages.cpp
index e31df97ba31c..69c1e55eeaa3 100644
--- a/clang/test/OpenMP/target_teams_distribute_dist_schedule_messages.cpp
+++ b/clang/test/OpenMP/target_teams_distribute_dist_schedule_messages.cpp
@@ -45,7 +45,7 @@ T tmain(T argc) {
#pragma omp target teams distribute dist_schedule (static, S1) // expected-error {{'S1' does not refer to a value}}
for (int i = 0; i < 10; ++i) foo();
-#pragma omp target teams distribute dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error 2{{expression must have integral or unscoped enumeration type, not 'char *'}}
+#pragma omp target teams distribute dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error3 {{expression must have integral or unscoped enumeration type, not 'char *'}}
for (int i = 0; i < 10; ++i) foo();
return T();
diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_dist_schedule_messages.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_dist_schedule_messages.cpp
index 4f3c58125446..a0efad18668e 100644
--- a/clang/test/OpenMP/target_teams_distribute_parallel_for_dist_schedule_messages.cpp
+++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_dist_schedule_messages.cpp
@@ -45,7 +45,7 @@ T tmain(T argc) {
#pragma omp target teams distribute parallel for dist_schedule (static, S1) // expected-error {{'S1' does not refer to a value}}
for (int i = 0; i < 10; ++i) foo();
-#pragma omp target teams distribute parallel for dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error 2{{expression must have integral or unscoped enumeration type, not 'char *'}}
+#pragma omp target teams distribute parallel for dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error3 {{expression must have integral or unscoped enumeration type, not 'char *'}}
for (int i = 0; i < 10; ++i) foo();
return T();
diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_dist_schedule_messages.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_dist_schedule_messages.cpp
index 8b272d4358f6..ec634c8ac01c 100644
--- a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_dist_schedule_messages.cpp
+++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_dist_schedule_messages.cpp
@@ -45,7 +45,7 @@ T tmain(T argc) {
#pragma omp target teams distribute parallel for simd dist_schedule (static, S1) // expected-error {{'S1' does not refer to a value}}
for (int i = 0; i < 10; ++i) foo();
-#pragma omp target teams distribute parallel for simd dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error 2{{expression must have integral or unscoped enumeration type, not 'char *'}}
+#pragma omp target teams distribute parallel for simd dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error3 {{expression must have integral or unscoped enumeration type, not 'char *'}}
for (int i = 0; i < 10; ++i) foo();
return T();
diff --git a/clang/test/OpenMP/target_teams_distribute_simd_dist_schedule_messages.cpp b/clang/test/OpenMP/target_teams_distribute_simd_dist_schedule_messages.cpp
index b583c14831e7..507ddabd2fc2 100644
--- a/clang/test/OpenMP/target_teams_distribute_simd_dist_schedule_messages.cpp
+++ b/clang/test/OpenMP/target_teams_distribute_simd_dist_schedule_messages.cpp
@@ -45,7 +45,7 @@ T tmain(T argc) {
#pragma omp target teams distribute simd dist_schedule (static, S1) // expected-error {{'S1' does not refer to a value}}
for (int i = 0; i < 10; ++i) foo();
-#pragma omp target teams distribute simd dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error 2{{expression must have integral or unscoped enumeration type, not 'char *'}}
+#pragma omp target teams distribute simd dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error3 {{expression must have integral or unscoped enumeration type, not 'char *'}}
for (int i = 0; i < 10; ++i) foo();
return T();
diff --git a/clang/test/OpenMP/target_update_from_messages.cpp b/clang/test/OpenMP/target_update_from_messages.cpp
index 42ecc2814e12..3dc377c4ca4c 100644
--- a/clang/test/OpenMP/target_update_from_messages.cpp
+++ b/clang/test/OpenMP/target_update_from_messages.cpp
@@ -131,7 +131,7 @@ T tmain(T argc) {
#pragma omp target update from(x, s7.s6[:5].aa[6]) // expected-error {{OpenMP array section is not allowed here}}
#pragma omp target update from(x, s7.s6[:5].aa[:6]) // expected-error {{OpenMP array section is not allowed here}}
#pragma omp target update from(s7.p[:10])
-#pragma omp target update from(x, s7.bfa) // expected-error 2{{bit fields cannot be used to specify storage in a 'from' clause}}
+#pragma omp target update from(x, s7.bfa) // expected-error {{bit fields cannot be used to specify storage in a 'from' clause}}
#pragma omp target update from(x, s7.p[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}}
#pragma omp target data map(to: s7.i)
{
diff --git a/clang/test/OpenMP/target_update_to_messages.cpp b/clang/test/OpenMP/target_update_to_messages.cpp
index 941c781119e6..fca4e21304fc 100644
--- a/clang/test/OpenMP/target_update_to_messages.cpp
+++ b/clang/test/OpenMP/target_update_to_messages.cpp
@@ -138,7 +138,7 @@ T tmain(T argc) {
#pragma omp target update to(x, s7.s6[:5].aa[6]) // expected-error {{OpenMP array section is not allowed here}}
#pragma omp target update to(x, s7.s6[:5].aa[:6]) // expected-error {{OpenMP array section is not allowed here}}
#pragma omp target update to(s7.p[:10])
-#pragma omp target update to(x, s7.bfa) // expected-error 2{{bit fields cannot be used to specify storage in a 'to' clause}}
+#pragma omp target update to(x, s7.bfa) // expected-error {{bit fields cannot be used to specify storage in a 'to' clause}}
#pragma omp target update to(x, s7.p[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}}
#pragma omp target data map(to: s7.i)
{
diff --git a/clang/test/OpenMP/task_messages.cpp b/clang/test/OpenMP/task_messages.cpp
index 2f9ee9a44402..13cbfb6c4569 100644
--- a/clang/test/OpenMP/task_messages.cpp
+++ b/clang/test/OpenMP/task_messages.cpp
@@ -156,11 +156,11 @@ int foo() {
#pragma omp task detach(a) // omp45-error {{unexpected OpenMP clause 'detach' in directive '#pragma omp task'}} omp50-error {{expected variable of the 'omp_event_handle_t' type, not 'int'}} omp50-error {{expected variable of the 'omp_event_handle_t' type, not 'S'}}
;
#pragma omp task detach(evt) detach(evt) // omp45-error 2 {{unexpected OpenMP clause 'detach' in directive '#pragma omp task'}} expected-error {{directive '#pragma omp task' cannot contain more than one 'detach' clause}}
-#pragma omp task detach(cevt) detach(revt) // omp45-error 2 {{unexpected OpenMP clause 'detach' in directive '#pragma omp task'}} expected-error {{directive '#pragma omp task' cannot contain more than one 'detach' clause}}
+#pragma omp task detach(cevt) detach(revt) // omp45-error 2 {{unexpected OpenMP clause 'detach' in directive '#pragma omp task'}} expected-error {{directive '#pragma omp task' cannot contain more than one 'detach' clause}} omp50-error {{expected variable of the 'omp_event_handle_t' type, not 'const omp_event_handle_t' (aka 'const unsigned long')}} omp50-error {{expected variable of the 'omp_event_handle_t' type, not 'omp_event_handle_t &' (aka 'unsigned long &')}}
#pragma omp task detach(evt) mergeable // omp45-error {{unexpected OpenMP clause 'detach' in directive '#pragma omp task'}} omp50-error {{'mergeable' and 'detach' clause are mutually exclusive and may not appear on the same directive}} omp50-note {{'detach' clause is specified here}}
;
#pragma omp task mergeable detach(evt) // omp45-error {{unexpected OpenMP clause 'detach' in directive '#pragma omp task'}} omp50-error {{'detach' and 'mergeable' clause are mutually exclusive and may not appear on the same directive}} omp50-note {{'mergeable' clause is specified here}}
-#pragma omp task detach(-evt) // omp45-error {{unexpected OpenMP clause 'detach' in directive '#pragma omp task'}}
+#pragma omp task detach(-evt) // omp45-error {{unexpected OpenMP clause 'detach' in directive '#pragma omp task'}} omp50-error {{expected variable of the 'omp_event_handle_t' type}}
;
#pragma omp task detach(evt) shared(evt) // omp45-error {{unexpected OpenMP clause 'detach' in directive '#pragma omp task'}}
#pragma omp task detach(evt) firstprivate(evt) // omp45-error {{unexpected OpenMP clause 'detach' in directive '#pragma omp task'}}
diff --git a/clang/test/OpenMP/teams_distribute_dist_schedule_messages.cpp b/clang/test/OpenMP/teams_distribute_dist_schedule_messages.cpp
index bd1aaa5c6289..22d2408d3f17 100644
--- a/clang/test/OpenMP/teams_distribute_dist_schedule_messages.cpp
+++ b/clang/test/OpenMP/teams_distribute_dist_schedule_messages.cpp
@@ -55,7 +55,7 @@ T tmain(T argc) {
for (int i = 0; i < 10; ++i) foo();
#pragma omp target
-#pragma omp teams distribute dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error 2{{expression must have integral or unscoped enumeration type, not 'char *'}}
+#pragma omp teams distribute dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error3 {{expression must have integral or unscoped enumeration type, not 'char *'}}
for (int i = 0; i < 10; ++i) foo();
return T();
diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_dist_schedule_messages.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_dist_schedule_messages.cpp
index a70d80ad1251..27ff4125daf7 100644
--- a/clang/test/OpenMP/teams_distribute_parallel_for_dist_schedule_messages.cpp
+++ b/clang/test/OpenMP/teams_distribute_parallel_for_dist_schedule_messages.cpp
@@ -55,7 +55,7 @@ T tmain(T argc) {
for (int i = 0; i < 10; ++i) foo();
#pragma omp target
-#pragma omp teams distribute parallel for dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error 2{{expression must have integral or unscoped enumeration type, not 'char *'}}
+#pragma omp teams distribute parallel for dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error3 {{expression must have integral or unscoped enumeration type, not 'char *'}}
for (int i = 0; i < 10; ++i) foo();
return T();
diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_simd_dist_schedule_messages.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_simd_dist_schedule_messages.cpp
index b87301fa98d8..cbd4ec4ce979 100644
--- a/clang/test/OpenMP/teams_distribute_parallel_for_simd_dist_schedule_messages.cpp
+++ b/clang/test/OpenMP/teams_distribute_parallel_for_simd_dist_schedule_messages.cpp
@@ -55,7 +55,7 @@ T tmain(T argc) {
for (int i = 0; i < 10; ++i) foo();
#pragma omp target
-#pragma omp teams distribute parallel for simd dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error 2{{expression must have integral or unscoped enumeration type, not 'char *'}}
+#pragma omp teams distribute parallel for simd dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error3 {{expression must have integral or unscoped enumeration type, not 'char *'}}
for (int i = 0; i < 10; ++i) foo();
return T();
diff --git a/clang/test/OpenMP/teams_distribute_simd_dist_schedule_messages.cpp b/clang/test/OpenMP/teams_distribute_simd_dist_schedule_messages.cpp
index 6e653fae08c8..424797576837 100644
--- a/clang/test/OpenMP/teams_distribute_simd_dist_schedule_messages.cpp
+++ b/clang/test/OpenMP/teams_distribute_simd_dist_schedule_messages.cpp
@@ -55,7 +55,7 @@ T tmain(T argc) {
for (int i = 0; i < 10; ++i) foo();
#pragma omp target
-#pragma omp teams distribute simd dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error 2{{expression must have integral or unscoped enumeration type, not 'char *'}}
+#pragma omp teams distribute simd dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error3 {{expression must have integral or unscoped enumeration type, not 'char *'}}
for (int i = 0; i < 10; ++i) foo();
return T();
diff --git a/clang/test/SemaCXX/coroutines.cpp b/clang/test/SemaCXX/coroutines.cpp
index d6c67c06fd98..d7208f9a1010 100644
--- a/clang/test/SemaCXX/coroutines.cpp
+++ b/clang/test/SemaCXX/coroutines.cpp
@@ -1179,8 +1179,8 @@ struct TestType {
static CoroMemberTag test_static_template(const char *volatile &, unsigned) {
auto TC = co_yield 0;
using TCT = decltype(TC);
- static_assert(TCT::template MatchesArgs<const char *volatile &, unsigned>, "");
- static_assert(!TCT::template MatchesArgs<TestType &, const char *volatile &, unsigned>, "");
+ static_assert(TCT::MatchesArgs<const char *volatile &, unsigned>, "");
+ static_assert(!TCT::MatchesArgs<TestType &, const char *volatile &, unsigned>, "");
}
BadCoroMemberTag test_diagnostics() {
@@ -1263,31 +1263,31 @@ struct DepTestType {
static CoroMemberTag test_static() {
auto TC = co_yield 0;
using TCT = decltype(TC);
- static_assert(TCT::template MatchesArgs<>, "");
- static_assert(!TCT::template MatchesArgs<DepTestType>, "");
- static_assert(!TCT::template MatchesArgs<DepTestType &>, "");
- static_assert(!TCT::template MatchesArgs<DepTestType *>, "");
+ static_assert(TCT::MatchesArgs<>, "");
+ static_assert(!TCT::MatchesArgs<DepTestType>, "");
+ static_assert(!TCT::MatchesArgs<DepTestType &>, "");
+ static_assert(!TCT::MatchesArgs<DepTestType *>, "");
// Ensure diagnostics are actually being generated here
- static_assert(TCT::template MatchesArgs<int>, ""); // expected-error {{static_assert failed}}
+ static_assert(TCT::MatchesArgs<int>, ""); // expected-error {{static_assert failed}}
}
static CoroMemberTag test_static(volatile void *const, char &&) {
auto TC = co_yield 0;
using TCT = decltype(TC);
- static_assert(TCT::template MatchesArgs<volatile void *const, char &&>, "");
+ static_assert(TCT::MatchesArgs<volatile void *const, char &&>, "");
}
template <class Dummy>
static CoroMemberTag test_static_template(const char *volatile &, unsigned) {
auto TC = co_yield 0;
using TCT = decltype(TC);
- static_assert(TCT::template MatchesArgs<const char *volatile &, unsigned>, "");
- static_assert(!TCT::template MatchesArgs<DepTestType &, const char *volatile &, unsigned>, "");
+ static_assert(TCT::MatchesArgs<const char *volatile &, unsigned>, "");
+ static_assert(!TCT::MatchesArgs<DepTestType &, const char *volatile &, unsigned>, "");
}
};
-template struct DepTestType<int>; // expected-note 2{{requested here}}
+template struct DepTestType<int>; // expected-note {{requested here}}
template CoroMemberTag DepTestType<int>::test_member_template(long, const char *) const &&;
template CoroMemberTag DepTestType<int>::test_static_template<void>(const char *volatile &, unsigned);
diff --git a/clang/test/SemaCXX/warn-unused-lambda-capture.cpp b/clang/test/SemaCXX/warn-unused-lambda-capture.cpp
index 764a4a42a084..52ec390b0bba 100644
--- a/clang/test/SemaCXX/warn-unused-lambda-capture.cpp
+++ b/clang/test/SemaCXX/warn-unused-lambda-capture.cpp
@@ -147,7 +147,7 @@ void test_templated() {
auto explicit_by_value_unused = [i] {}; // expected-warning{{lambda capture 'i' is not used}}
auto explicit_by_value_unused_sizeof = [i] { return sizeof(i); }; // expected-warning{{lambda capture 'i' is not required to be captured for this use}}
- auto explicit_by_value_unused_decltype = [i] { decltype(i) j = 0; }; // expected-warning{{lambda capture 'i' is not required to be captured for this use}}
+ auto explicit_by_value_unused_decltype = [i] { decltype(i) j = 0; }; // expected-warning{{lambda capture 'i' is not used}}
auto explicit_by_value_unused_const = [k] { return k + 1; }; // expected-warning{{lambda capture 'k' is not required to be captured for this use}}
auto explicit_by_value_unused_const_generic = [k](auto c) { return k + 1; }; // expected-warning{{lambda capture 'k' is not required to be captured for this use}}
diff --git a/clang/test/SemaTemplate/temp_arg_nontype_cxx17.cpp b/clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp
similarity index 90%
rename from clang/test/SemaTemplate/temp_arg_nontype_cxx17.cpp
rename to clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp
index 4d61b9c7d937..245504f6a85f 100644
--- a/clang/test/SemaTemplate/temp_arg_nontype_cxx17.cpp
+++ b/clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp
@@ -2,7 +2,7 @@
template<typename T, T val> struct A {};
-template<typename T, typename U> constexpr bool is_same = false;
+template<typename T, typename U> constexpr bool is_same = false; // expected-note +{{here}}
template<typename T> constexpr bool is_same<T, T> = true;
namespace String {
@@ -84,32 +84,34 @@ namespace PtrMem {
constexpr int B::*b = &B::b;
constexpr int C::*cb = b;
constexpr int D::*db = b;
- constexpr int E::*ecb = cb;
- constexpr int E::*edb = db;
+ constexpr int E::*ecb = cb; // expected-note +{{here}}
+ constexpr int E::*edb = db; // expected-note +{{here}}
constexpr int E::*e = &E::e;
constexpr int D::*de = (int D::*)e;
constexpr int C::*ce = (int C::*)e;
- constexpr int B::*bde = (int B::*)de;
- constexpr int B::*bce = (int B::*)ce;
+ constexpr int B::*bde = (int B::*)de; // expected-note +{{here}}
+ constexpr int B::*bce = (int B::*)ce; // expected-note +{{here}}
+ // FIXME: This should all be accepted, but we don't yet have a representation
+ // nor mangling for this form of template argument.
using Ab = A<int B::*, b>;
using Ab = A<int B::*, &B::b>;
- using Abce = A<int B::*, bce>;
- using Abde = A<int B::*, bde>;
- static_assert(!is_same<Ab, Abce>, "");
- static_assert(!is_same<Ab, Abde>, "");
- static_assert(!is_same<Abce, Abde>, "");
- static_assert(is_same<Abce, A<int B::*, (int B::*)(int C::*)&E::e>>, "");
+ using Abce = A<int B::*, bce>; // expected-error {{not supported}}
+ using Abde = A<int B::*, bde>; // expected-error {{not supported}}
+ static_assert(!is_same<Ab, Abce>, ""); // expected-error {{undeclared}} expected-error {{must be a type}}
+ static_assert(!is_same<Ab, Abde>, ""); // expected-error {{undeclared}} expected-error {{must be a type}}
+ static_assert(!is_same<Abce, Abde>, ""); // expected-error 2{{undeclared}} expected-error {{must be a type}}
+ static_assert(is_same<Abce, A<int B::*, (int B::*)(int C::*)&E::e>>, ""); // expected-error {{undeclared}} expected-error {{not supported}}
using Ae = A<int E::*, e>;
using Ae = A<int E::*, &E::e>;
- using Aecb = A<int E::*, ecb>;
- using Aedb = A<int E::*, edb>;
- static_assert(!is_same<Ae, Aecb>, "");
- static_assert(!is_same<Ae, Aedb>, "");
- static_assert(!is_same<Aecb, Aedb>, "");
- static_assert(is_same<Aecb, A<int E::*, (int E::*)(int C::*)&B::b>>, "");
+ using Aecb = A<int E::*, ecb>; // expected-error {{not supported}}
+ using Aedb = A<int E::*, edb>; // expected-error {{not supported}}
+ static_assert(!is_same<Ae, Aecb>, ""); // expected-error {{undeclared}} expected-error {{must be a type}}
+ static_assert(!is_same<Ae, Aedb>, ""); // expected-error {{undeclared}} expected-error {{must be a type}}
+ static_assert(!is_same<Aecb, Aedb>, ""); // expected-error 2{{undeclared}} expected-error {{must be a type}}
+ static_assert(is_same<Aecb, A<int E::*, (int E::*)(int C::*)&B::b>>, ""); // expected-error {{undeclared}} expected-error {{not supported}}
using An = A<int E::*, nullptr>;
using A0 = A<int E::*, (int E::*)0>;
@@ -203,9 +205,9 @@ namespace Auto {
struct Y : X {};
void type_affects_identity(B<&X::n>) {}
- void type_affects_identity(B<(int Y::*)&X::n>) {}
+ void type_affects_identity(B<(int Y::*)&X::n>) {} // FIXME: expected-error {{sorry}}
void type_affects_identity(B<(const int X::*)&X::n>) {}
- void type_affects_identity(B<(const int Y::*)&X::n>) {}
+ void type_affects_identity(B<(const int Y::*)&X::n>) {} // FIXME: expected-error {{sorry}}
// A case where we need to do auto-deduction, and check whether the
// resulting dependent types match during partial ordering. These
diff --git a/clang/test/SemaTemplate/temp_arg_nontype_cxx20.cpp b/clang/test/SemaTemplate/temp_arg_nontype_cxx20.cpp
index 48101cccfce0..c42fda780430 100644
--- a/clang/test/SemaTemplate/temp_arg_nontype_cxx20.cpp
+++ b/clang/test/SemaTemplate/temp_arg_nontype_cxx20.cpp
@@ -8,8 +8,8 @@ namespace std {
// floating-point arguments
template<float> struct Float {};
-using F1 = Float<1.0f>;
-using F1 = Float<2.0f / 2>;
+using F1 = Float<1.0f>; // FIXME expected-error {{sorry}}
+using F1 = Float<2.0f / 2>; // FIXME expected-error {{sorry}}
struct S { int n[3]; } s; // expected-note 1+{{here}}
union U { int a, b; } u;
@@ -17,24 +17,24 @@ int n; // expected-note 1+{{here}}
// pointers to subobjects
template<int *> struct IntPtr {};
-using IPn = IntPtr<&n + 1>;
-using IPn = IntPtr<&n + 1>;
+using IPn = IntPtr<&n + 1>; // FIXME expected-error {{refers to subobject}}
+using IPn = IntPtr<&n + 1>; // FIXME expected-error {{refers to subobject}}
-using IP2 = IntPtr<&s.n[2]>;
-using IP2 = IntPtr<s.n + 2>;
+using IP2 = IntPtr<&s.n[2]>; // FIXME expected-error {{refers to subobject}}
+using IP2 = IntPtr<s.n + 2>; // FIXME expected-error {{refers to subobject}}
-using IP3 = IntPtr<&s.n[3]>;
-using IP3 = IntPtr<s.n + 3>;
+using IP3 = IntPtr<&s.n[3]>; // FIXME expected-error {{refers to subobject}}
+using IP3 = IntPtr<s.n + 3>; // FIXME expected-error {{refers to subobject}}
template<int &> struct IntRef {};
-using IRn = IntRef<*(&n + 1)>; // expected-error {{not a constant expression}} expected-note {{dereferenced pointer past the end of 'n'}}
-using IRn = IntRef<*(&n + 1)>; // expected-error {{not a constant expression}} expected-note {{dereferenced pointer past the end of 'n'}}
+using IPn = IntRef<*(&n + 1)>; // expected-error {{not a constant expression}} expected-note {{dereferenced pointer past the end of 'n'}}
+using IPn = IntRef<*(&n + 1)>; // expected-error {{not a constant expression}} expected-note {{dereferenced pointer past the end of 'n'}}
-using IR2 = IntRef<s.n[2]>;
-using IR2 = IntRef<*(s.n + 2)>;
+using IP2 = IntRef<s.n[2]>; // FIXME expected-error {{refers to subobject}}
+using IP2 = IntRef<*(s.n + 2)>; // FIXME expected-error {{refers to subobject}}
-using IR3 = IntRef<s.n[3]>; // expected-error {{not a constant expression}} expected-note {{dereferenced pointer past the end of subobject of 's'}}
-using IR3 = IntRef<*(s.n + 3)>; // expected-error {{not a constant expression}} expected-note {{dereferenced pointer past the end of subobject of 's'}}
+using IP3 = IntRef<s.n[3]>; // expected-error {{not a constant expression}} expected-note {{dereferenced pointer past the end of subobject of 's'}}
+using IP3 = IntRef<*(s.n + 3)>; // expected-error {{not a constant expression}} expected-note {{dereferenced pointer past the end of subobject of 's'}}
// classes
template<S> struct Struct {};
@@ -48,12 +48,12 @@ using U1 = Union<U{.b = 1}>; // expected-error {{
diff erent types}}
// miscellaneous scalar types
template<_Complex int> struct ComplexInt {};
-using CI = ComplexInt<1 + 3i>;
-using CI = ComplexInt<3i + 1>;
+using CI = ComplexInt<1 + 3i>; // FIXME: expected-error {{sorry}}
+using CI = ComplexInt<1 + 3i>; // FIXME: expected-error {{sorry}}
template<_Complex float> struct ComplexFloat {};
-using CF = ComplexFloat<1.0f + 3.0fi>;
-using CF = ComplexFloat<3.0fi + 1.0f>;
+using CF = ComplexFloat<1.0f + 3.0fi>; // FIXME: expected-error {{sorry}}
+using CF = ComplexFloat<1.0f + 3.0fi>; // FIXME: expected-error {{sorry}}
namespace ClassNTTP {
struct A { // expected-note 2{{candidate}}
@@ -292,47 +292,3 @@ namespace Predefined {
Y<B{__func__[0]}>(); // expected-error {{reference to subobject of predefined '__func__' variable}}
}
}
-
-namespace dependent {
- template<auto &V> struct R { static inline auto &v = V; };
- template<auto &V, auto &W> constexpr bool operator==(R<V>, R<W>) { return &V == &W; }
- template<auto *V> struct S { static inline auto *v = V; };
- template<auto *V, auto *W> constexpr bool operator==(S<V>, S<W>) { return V == W; }
- template<auto V> struct T { static inline const auto &v = V; };
- template<auto V, auto W> constexpr bool operator==(T<V>, T<W>) { return &V == &W; }
- template<typename T> struct V { T v; };
- template<int N> auto f() {
- static int n;
- static V<int> vn;
- if constexpr (N < 10)
- return R<n>();
- else if constexpr (N < 20)
- return R<vn.v>();
- else if constexpr (N < 30)
- return S<&n>();
- else if constexpr (N < 40)
- return S<&vn.v>();
- else if constexpr (N < 50)
- return T<V<int&>{n}>();
- else if constexpr (N < 60)
- return T<V<int*>{&n}>();
- else if constexpr (N < 70)
- return T<V<int&>{vn.v}>();
- else if constexpr (N < 80)
- return T<V<int*>{&vn.v}>();
- }
- template<int Base> void check() {
- auto v = f<Base + 0>();
- auto w = f<Base + 1>();
- static_assert(!__is_same(decltype(v), decltype(w)));
- static_assert(v != w);
- }
- template void check<0>();
- template void check<10>();
- template void check<20>();
- template void check<30>();
- template void check<40>();
- template void check<50>();
- template void check<60>();
- template void check<70>();
-}
diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp
index 8a4d3cbcf939..f1008319ddc7 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -1493,11 +1493,6 @@ bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
return false;
- case TemplateArgument::UncommonValue:
- if (Expr *E = TAL.getSourceUncommonValueExpression())
- return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
- return false;
-
case TemplateArgument::NullPtr:
if (Expr *E = TAL.getSourceNullPtrExpression())
return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
diff --git a/clang/tools/libclang/CXCursor.cpp b/clang/tools/libclang/CXCursor.cpp
index 851b418b6d7b..180cf1858d04 100644
--- a/clang/tools/libclang/CXCursor.cpp
+++ b/clang/tools/libclang/CXCursor.cpp
@@ -1375,9 +1375,6 @@ enum CXTemplateArgumentKind clang_Cursor_getTemplateArgumentKind(CXCursor C,
return CXTemplateArgumentKind_NullPtr;
case TemplateArgument::Integral:
return CXTemplateArgumentKind_Integral;
- case TemplateArgument::UncommonValue:
- // FIXME: Expose these values.
- return CXTemplateArgumentKind_Invalid;
case TemplateArgument::Template:
return CXTemplateArgumentKind_Template;
case TemplateArgument::TemplateExpansion:
diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h
index cb78ff29e557..8283b14cdee5 100644
--- a/lldb/include/lldb/lldb-enumerations.h
+++ b/lldb/include/lldb/lldb-enumerations.h
@@ -816,7 +816,6 @@ enum TemplateArgumentKind {
eTemplateArgumentKindExpression,
eTemplateArgumentKindPack,
eTemplateArgumentKindNullPtr,
- eTemplateArgumentKindUncommonValue,
};
/// Options that can be set for a formatter to alter its behavior. Not
diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
index 4f55cf7cfa79..c15b15e736fb 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -7002,9 +7002,6 @@ TypeSystemClang::GetTemplateArgumentKind(lldb::opaque_compiler_type_t type,
case clang::TemplateArgument::Pack:
return eTemplateArgumentKindPack;
-
- case clang::TemplateArgument::UncommonValue:
- return eTemplateArgumentKindUncommonValue;
}
llvm_unreachable("Unhandled clang::TemplateArgument::ArgKind");
}
More information about the llvm-branch-commits
mailing list