Author: Arthur Eubanks Date: 2020-12-22T10:18:08-08:00 New Revision: 208023233398a677cc0aacb8153be9801db03af6
URL: https://github.com/llvm/llvm-project/commit/208023233398a677cc0aacb8153be9801db03af6 DIFF: https://github.com/llvm/llvm-project/commit/208023233398a677cc0aacb8153be9801db03af6.diff LOG: Revert "[c++20] P1907R1: Support for generalized non-type template arguments of scalar type." This reverts commit 9e08e51a20d0d2b1c5724bb17e969d036fced4cd. This is part of 5 commits being reverted due to https://crbug.com/1161059. See bug for repro. Added: Modified: 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/include/clang/Serialization/ASTRecordWriter.h clang/lib/AST/ASTContext.cpp clang/lib/AST/ASTImporter.cpp clang/lib/AST/ASTStructuralEquivalence.cpp clang/lib/AST/Decl.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/SemaTemplate/temp_arg_nontype_cxx17.cpp clang/test/SemaTemplate/temp_arg_nontype_cxx20.cpp clang/tools/libclang/CIndex.cpp clang/tools/libclang/CXCursor.cpp Removed: clang/test/CodeGenCXX/template-arguments.cpp ################################################################################ diff --git a/clang/include/clang/AST/PropertiesBase.td b/clang/include/clang/AST/PropertiesBase.td index dbe75ab9de19..ba0f237a3bc3 100644 --- a/clang/include/clang/AST/PropertiesBase.td +++ b/clang/include/clang/AST/PropertiesBase.td @@ -72,7 +72,6 @@ class CountPropertyType<string typeName = ""> : PropertyType<typeName> { def APInt : PropertyType<"llvm::APInt"> { let PassByReference = 1; } def APSInt : PropertyType<"llvm::APSInt"> { let PassByReference = 1; } -def APValue : PropertyType { let PassByReference = 1; } def ArraySizeModifier : EnumPropertyType<"ArrayType::ArraySizeModifier">; def AttrKind : EnumPropertyType<"attr::Kind">; def AutoTypeKeyword : EnumPropertyType; @@ -451,17 +450,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 9968143e8761..abf873a7ee40 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. @@ -356,16 +340,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 +484,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 +542,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) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index ace3064be7bc..24c2bb57b6f9 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -4656,6 +4656,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">; @@ -4707,6 +4709,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 460d0c961c92..2c781eb88415 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -7623,8 +7623,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/include/clang/Serialization/ASTRecordWriter.h b/clang/include/clang/Serialization/ASTRecordWriter.h index ff654f417dda..e362463b2309 100644 --- a/clang/include/clang/Serialization/ASTRecordWriter.h +++ b/clang/include/clang/Serialization/ASTRecordWriter.h @@ -166,7 +166,6 @@ class ASTRecordWriter /// Emit an APvalue. void AddAPValue(const APValue &Value); - void writeAPValue(const APValue &Value) { AddAPValue(Value); } /// Emit a reference to an identifier. void AddIdentifierRef(const IdentifierInfo *II) { diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index d396f81188df..0190573fe36e 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 456e51ad3db4..54816b721a4a 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/Decl.cpp b/clang/lib/AST/Decl.cpp index fd10ea56f171..f0c925f9cdf9 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/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index 08206c4e1a41..01deb598a078 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -4079,28 +4079,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 @@ -5057,10 +5039,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'; @@ -5395,20 +5373,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 16e0aa2ae466..df6c566abc7d 100644 --- a/clang/lib/AST/MicrosoftMangle.cpp +++ b/clang/lib/AST/MicrosoftMangle.cpp @@ -1575,17 +1575,6 @@ void MicrosoftCXXNameMangler::mangleTemplateArg(const TemplateDecl *TD, cast<NonTypeTemplateParmDecl>(Parm), T); break; } - case TemplateArgument::UncommonValue: - 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 0029c90a0ab6..44d52c56ffbb 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,44 +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); - Value.Type = Type.getAsOpaquePtr(); - } -} - TemplateArgument TemplateArgument::CreatePackCopy(ASTContext &Context, ArrayRef<TemplateArgument> Args) { @@ -172,7 +134,6 @@ TemplateArgumentDependence TemplateArgument::getDependence() const { case NullPtr: case Integral: case Declaration: - case UncommonValue: return TemplateArgumentDependence::None; case Expression: @@ -204,7 +165,6 @@ bool TemplateArgument::isPackExpansion() const { case Null: case Declaration: case Integral: - case UncommonValue: case Pack: case Template: case NullPtr: @@ -255,9 +215,6 @@ QualType TemplateArgument::getNonTypeTemplateArgumentType() const { case TemplateArgument::NullPtr: return getNullPtrType(); - - case TemplateArgument::UncommonValue: - return getUncommonValueType(); } llvm_unreachable("Invalid TemplateArgument Kind!"); @@ -302,13 +259,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: @@ -344,16 +296,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) @@ -380,7 +322,6 @@ TemplateArgument TemplateArgument::getPackExpansionPattern() const { case Declaration: case Integral: - case UncommonValue: case Pack: case Null: case Template: @@ -420,10 +361,6 @@ void TemplateArgument::print(const PrintingPolicy &Policy, break; } - case UncommonValue: - getAsUncommonValue().printPretty(Out, Policy, getUncommonValueType()); - break; - case NullPtr: Out << "nullptr"; break; @@ -506,9 +443,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(); @@ -537,18 +471,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(); 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 ae50f80e6fb5..7b20d43b0f17 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -1953,14 +1953,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 8885e4191987..16dd8f510596 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..ac52612ea3b0 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -5774,9 +5774,7 @@ static ExprResult CheckConvertedConstantExpression(Sema &S, Expr *From, 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; diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 74a31c0a1b65..7ebd9be831ad 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"); @@ -6937,9 +6936,37 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, 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 +6982,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 +7001,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 +7561,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 +7582,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,131 +7591,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); - } -} - -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); - } -} - /// 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 23d4056ce254..4a3b64cf5425 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); } @@ -6120,8 +6103,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 d04ae36360a6..cbf4fb1de465 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()) 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 1695e26c7d5f..2cc8b9c8324f 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 22533527fc61..b48b23ce4a51 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 87160b26d421..3a281e492fde 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -5350,7 +5350,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 c9149a473b6f..7402d367ae3e 100644 --- a/clang/test/CodeGenCXX/mangle-ms-templates.cpp +++ b/clang/test/CodeGenCXX/mangle-ms-templates.cpp @@ -2,7 +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 template<typename T> class Class { @@ -328,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 fd6f469e88fc..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/SemaTemplate/temp_arg_nontype_cxx17.cpp b/clang/test/SemaTemplate/temp_arg_nontype_cxx17.cpp index bc8a22e89041..52cf51719f05 100644 --- a/clang/test/SemaTemplate/temp_arg_nontype_cxx17.cpp +++ b/clang/test/SemaTemplate/temp_arg_nontype_cxx17.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..d514465f7d67 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}} @@ -307,11 +307,11 @@ namespace dependent { if constexpr (N < 10) return R<n>(); else if constexpr (N < 20) - return R<vn.v>(); + return R<vn.v>(); // FIXME: expected-error 2{{refers to subobject}} else if constexpr (N < 30) return S<&n>(); else if constexpr (N < 40) - return S<&vn.v>(); + return S<&vn.v>(); // FIXME: expected-error 2{{refers to subobject}} else if constexpr (N < 50) return T<V<int&>{n}>(); else if constexpr (N < 60) @@ -322,15 +322,15 @@ namespace dependent { return T<V<int*>{&vn.v}>(); } template<int Base> void check() { - auto v = f<Base + 0>(); - auto w = f<Base + 1>(); + auto v = f<Base + 0>(); // FIXME: expected-note 2{{instantiation of}} + auto w = f<Base + 1>(); // FIXME: expected-note 2{{instantiation of}} static_assert(!__is_same(decltype(v), decltype(w))); static_assert(v != w); } template void check<0>(); - template void check<10>(); + template void check<10>(); // FIXME: expected-note 2{{instantiation of}} template void check<20>(); - template void check<30>(); + template void check<30>(); // FIXME: expected-note 2{{instantiation of}} template void check<40>(); template void check<50>(); template void check<60>(); 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: _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits