diff options
Diffstat (limited to 'clang/include')
24 files changed, 540 insertions, 185 deletions
diff --git a/clang/include/clang/AST/ASTConcept.h b/clang/include/clang/AST/ASTConcept.h index 72da005..f362f24 100644 --- a/clang/include/clang/AST/ASTConcept.h +++ b/clang/include/clang/AST/ASTConcept.h @@ -28,10 +28,20 @@ namespace clang { class ConceptDecl; class TemplateDecl; +class ConceptReference; class Expr; class NamedDecl; struct PrintingPolicy; +/// Unsatisfied constraint expressions if the template arguments could be +/// substituted into them, or a diagnostic if substitution resulted in +/// an invalid expression. +/// +using ConstraintSubstitutionDiagnostic = std::pair<SourceLocation, StringRef>; +using UnsatisfiedConstraintRecord = + llvm::PointerUnion<const Expr *, const ConceptReference *, + const ConstraintSubstitutionDiagnostic *>; + /// The result of a constraint satisfaction check, containing the necessary /// information to diagnose an unsatisfied constraint. class ConstraintSatisfaction : public llvm::FoldingSetNode { @@ -48,16 +58,13 @@ public: ArrayRef<TemplateArgument> TemplateArgs) : ConstraintOwner(ConstraintOwner), TemplateArgs(TemplateArgs) {} - using SubstitutionDiagnostic = std::pair<SourceLocation, StringRef>; - using Detail = llvm::PointerUnion<Expr *, SubstitutionDiagnostic *>; - bool IsSatisfied = false; bool ContainsErrors = false; /// \brief The substituted constraint expr, if the template arguments could be /// substituted into them, or a diagnostic if substitution resulted in an /// invalid expression. - llvm::SmallVector<Detail, 4> Details; + llvm::SmallVector<UnsatisfiedConstraintRecord, 4> Details; void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C) { Profile(ID, C, ConstraintOwner, TemplateArgs); @@ -69,19 +76,12 @@ public: bool HasSubstitutionFailure() { for (const auto &Detail : Details) - if (Detail.dyn_cast<SubstitutionDiagnostic *>()) + if (Detail.dyn_cast<const ConstraintSubstitutionDiagnostic *>()) return true; return false; } }; -/// Pairs of unsatisfied atomic constraint expressions along with the -/// substituted constraint expr, if the template arguments could be -/// substituted into them, or a diagnostic if substitution resulted in -/// an invalid expression. -using UnsatisfiedConstraintRecord = - llvm::PointerUnion<Expr *, std::pair<SourceLocation, StringRef> *>; - /// \brief The result of a constraint satisfaction check, containing the /// necessary information to diagnose an unsatisfied constraint. /// @@ -101,6 +101,10 @@ struct ASTConstraintSatisfaction final : return getTrailingObjects() + NumRecords; } + ArrayRef<UnsatisfiedConstraintRecord> records() const { + return {begin(), end()}; + } + ASTConstraintSatisfaction(const ASTContext &C, const ConstraintSatisfaction &Satisfaction); ASTConstraintSatisfaction(const ASTContext &C, @@ -282,6 +286,11 @@ public: } }; +/// Insertion operator for diagnostics. This allows sending ConceptReferences's +/// into a diagnostic with <<. +const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB, + const ConceptReference *C); + } // clang #endif // LLVM_CLANG_AST_ASTCONCEPT_H diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 12351e9..78220d4 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -3877,7 +3877,6 @@ typename clang::LazyGenerationalUpdatePtr<Owner, T, Update>::ValueType return new (Ctx) LazyData(Source, Value); return Value; } - template <> struct llvm::DenseMapInfo<llvm::FoldingSetNodeID> { static FoldingSetNodeID getEmptyKey() { return FoldingSetNodeID{}; } diff --git a/clang/include/clang/AST/CharUnits.h b/clang/include/clang/AST/CharUnits.h index c06354451..e570bfa 100644 --- a/clang/include/clang/AST/CharUnits.h +++ b/clang/include/clang/AST/CharUnits.h @@ -141,7 +141,7 @@ namespace clang { /// Among other things, this promises that /// self.alignTo(N) will just return self. bool isMultipleOf(CharUnits N) const { - return (*this % N) == 0; + return (*this % N) == CharUnits::Zero(); } // Arithmetic operators. @@ -165,8 +165,8 @@ namespace clang { CharUnits operator% (QuantityType N) const { return CharUnits(Quantity % N); } - QuantityType operator% (const CharUnits &Other) const { - return Quantity % Other.Quantity; + CharUnits operator%(const CharUnits &Other) const { + return CharUnits(Quantity % Other.Quantity); } CharUnits operator+ (const CharUnits &Other) const { return CharUnits(Quantity + Other.Quantity); diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index d85d04d..406d79e 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -80,6 +80,7 @@ class TypeAliasTemplateDecl; class UnresolvedSetImpl; class VarTemplateDecl; enum class ImplicitParamKind; +struct UsualDeleteParams; // Holds a constraint expression along with a pack expansion index, if // expanded. @@ -2646,6 +2647,8 @@ public: bool isTypeAwareOperatorNewOrDelete() const; void setIsTypeAwareOperatorNewOrDelete(bool IsTypeAwareOperator = true); + UsualDeleteParams getUsualDeleteParams() const; + /// Compute the language linkage. LanguageLinkage getLanguageLinkage() const; diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h index 5f16bac..d78c7b6 100644 --- a/clang/include/clang/AST/ExprCXX.h +++ b/clang/include/clang/AST/ExprCXX.h @@ -2342,6 +2342,14 @@ struct ImplicitDeallocationParameters { SizedDeallocationMode PassSize; }; +/// The parameters to pass to a usual operator delete. +struct UsualDeleteParams { + TypeAwareAllocationMode TypeAwareDelete = TypeAwareAllocationMode::No; + bool DestroyingDelete = false; + bool Size = false; + AlignedAllocationMode Alignment = AlignedAllocationMode::No; +}; + /// Represents a new-expression for memory allocation and constructor /// calls, e.g: "new CXXNewExpr(foo)". class CXXNewExpr final diff --git a/clang/include/clang/AST/OpenACCClause.h b/clang/include/clang/AST/OpenACCClause.h index 5f06117..58ba8d91 100644 --- a/clang/include/clang/AST/OpenACCClause.h +++ b/clang/include/clang/AST/OpenACCClause.h @@ -840,14 +840,13 @@ public: // alloca at the level of the base, and the init at the element level. struct OpenACCPrivateRecipe { VarDecl *AllocaDecl; - Expr *InitExpr; - OpenACCPrivateRecipe(VarDecl *A, Expr *I) : AllocaDecl(A), InitExpr(I) {} + OpenACCPrivateRecipe(VarDecl *A) : AllocaDecl(A) {} bool isSet() const { return AllocaDecl; } static OpenACCPrivateRecipe Empty() { - return OpenACCPrivateRecipe(nullptr, nullptr); + return OpenACCPrivateRecipe(/*AllocaDecl=*/nullptr); } }; @@ -899,18 +898,17 @@ public: // InitFromTemporary is the 'temp' declaration we put in to be 'copied from'. struct OpenACCFirstPrivateRecipe { VarDecl *AllocaDecl; - Expr *InitExpr; VarDecl *InitFromTemporary; - OpenACCFirstPrivateRecipe(VarDecl *A, Expr *I, VarDecl *T) - : AllocaDecl(A), InitExpr(I), InitFromTemporary(T) { - assert(!AllocaDecl || AllocaDecl->getInit() == nullptr); + OpenACCFirstPrivateRecipe(VarDecl *A, VarDecl *T) + : AllocaDecl(A), InitFromTemporary(T) { assert(!InitFromTemporary || InitFromTemporary->getInit() == nullptr); } bool isSet() const { return AllocaDecl; } static OpenACCFirstPrivateRecipe Empty() { - return OpenACCFirstPrivateRecipe(nullptr, nullptr, nullptr); + return OpenACCFirstPrivateRecipe(/*AllocaDecl=*/nullptr, + /*InitFromTemporary=*/nullptr); } }; @@ -1282,16 +1280,13 @@ public: // 'main' declaration used for initializaiton, which is fixed. struct OpenACCReductionRecipe { VarDecl *AllocaDecl; - Expr *InitExpr; // TODO: OpenACC: this should eventually have the operations here too. - OpenACCReductionRecipe(VarDecl *A, Expr *I) : AllocaDecl(A), InitExpr(I) { - assert(!AllocaDecl || AllocaDecl->getInit() == nullptr); - } + OpenACCReductionRecipe(VarDecl *A) : AllocaDecl(A) {} bool isSet() const { return AllocaDecl; } static OpenACCReductionRecipe Empty() { - return OpenACCReductionRecipe(nullptr, nullptr); + return OpenACCReductionRecipe(/*AllocaDecl=*/nullptr); } }; diff --git a/clang/include/clang/AST/TypeBase.h b/clang/include/clang/AST/TypeBase.h index e0d00b8..6786b2f 100644 --- a/clang/include/clang/AST/TypeBase.h +++ b/clang/include/clang/AST/TypeBase.h @@ -6702,15 +6702,21 @@ public: LLVM_PREFERRED_TYPE(bool) uint8_t RawBuffer : 1; + LLVM_PREFERRED_TYPE(bool) + uint8_t IsCounter : 1; + Attributes(llvm::dxil::ResourceClass ResourceClass, bool IsROV = false, - bool RawBuffer = false) - : ResourceClass(ResourceClass), IsROV(IsROV), RawBuffer(RawBuffer) {} + bool RawBuffer = false, bool IsCounter = false) + : ResourceClass(ResourceClass), IsROV(IsROV), RawBuffer(RawBuffer), + IsCounter(IsCounter) {} - Attributes() : Attributes(llvm::dxil::ResourceClass::UAV, false, false) {} + Attributes() + : Attributes(llvm::dxil::ResourceClass::UAV, false, false, false) {} friend bool operator==(const Attributes &LHS, const Attributes &RHS) { - return std::tie(LHS.ResourceClass, LHS.IsROV, LHS.RawBuffer) == - std::tie(RHS.ResourceClass, RHS.IsROV, RHS.RawBuffer); + return std::tie(LHS.ResourceClass, LHS.IsROV, LHS.RawBuffer, + LHS.IsCounter) == std::tie(RHS.ResourceClass, RHS.IsROV, + RHS.RawBuffer, RHS.IsCounter); } friend bool operator!=(const Attributes &LHS, const Attributes &RHS) { return !(LHS == RHS); @@ -6751,6 +6757,7 @@ public: ID.AddInteger(static_cast<uint32_t>(Attrs.ResourceClass)); ID.AddBoolean(Attrs.IsROV); ID.AddBoolean(Attrs.RawBuffer); + ID.AddBoolean(Attrs.IsCounter); } static bool classof(const Type *T) { diff --git a/clang/include/clang/AST/TypeProperties.td b/clang/include/clang/AST/TypeProperties.td index b3932a6..9dc85fb 100644 --- a/clang/include/clang/AST/TypeProperties.td +++ b/clang/include/clang/AST/TypeProperties.td @@ -662,6 +662,9 @@ let Class = HLSLAttributedResourceType in { def : Property<"rawBuffer", Bool> { let Read = [{ node->getAttrs().RawBuffer }]; } + def : Property<"isCounter", Bool> { + let Read = [{ node->getAttrs().IsCounter }]; + } def : Property<"wrappedTy", QualType> { let Read = [{ node->getWrappedType() }]; } @@ -669,7 +672,7 @@ let Class = HLSLAttributedResourceType in { let Read = [{ node->getContainedType() }]; } def : Creator<[{ - HLSLAttributedResourceType::Attributes attrs(static_cast<llvm::dxil::ResourceClass>(resClass), isROV, rawBuffer); + HLSLAttributedResourceType::Attributes attrs(static_cast<llvm::dxil::ResourceClass>(resClass), isROV, rawBuffer, isCounter); return ctx.getHLSLAttributedResourceType(wrappedTy, containedTy, attrs); }]>; } diff --git a/clang/include/clang/Analysis/CFG.h b/clang/include/clang/Analysis/CFG.h index 1b1ff5e..6dd7d13 100644 --- a/clang/include/clang/Analysis/CFG.h +++ b/clang/include/clang/Analysis/CFG.h @@ -1251,6 +1251,7 @@ public: bool MarkElidedCXXConstructors = false; bool AddVirtualBaseBranches = false; bool OmitImplicitValueInitializers = false; + bool AssumeReachableDefaultInSwitchStatements = false; BuildOptions() = default; diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index fe3ca70..3c697ed 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -5074,6 +5074,12 @@ def HLSLRawBuffer : TypeAttr { let Documentation = [InternalOnly]; } +def HLSLIsCounter : TypeAttr { + let Spellings = [CXX11<"hlsl", "is_counter">]; + let LangOpts = [HLSL]; + let Documentation = [InternalOnly]; +} + def HLSLGroupSharedAddressSpace : TypeAttr { let Spellings = [CustomKeyword<"groupshared">]; let Subjects = SubjectList<[Var]>; diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h index a8943df..41595ec 100644 --- a/clang/include/clang/Basic/LangOptions.h +++ b/clang/include/clang/Basic/LangOptions.h @@ -549,8 +549,7 @@ public: bool CheckNew = false; /// The HLSL root signature version for dxil. - llvm::dxbc::RootSignatureVersion HLSLRootSigVer = - llvm::dxbc::RootSignatureVersion::V1_1; + llvm::dxbc::RootSignatureVersion HLSLRootSigVer; /// The HLSL root signature that will be used to overide the root signature /// used for the shader entry point. diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h index 3f83c30..8a5bf03 100644 --- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h +++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h @@ -148,9 +148,10 @@ public: } mlir::Value createComplexReal(mlir::Location loc, mlir::Value operand) { - auto operandTy = mlir::cast<cir::ComplexType>(operand.getType()); - return cir::ComplexRealOp::create(*this, loc, operandTy.getElementType(), - operand); + auto resultType = operand.getType(); + if (auto complexResultType = mlir::dyn_cast<cir::ComplexType>(resultType)) + resultType = complexResultType.getElementType(); + return cir::ComplexRealOp::create(*this, loc, resultType, operand); } mlir::Value createComplexImag(mlir::Location loc, mlir::Value operand) { diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index f857cf8..0a78492 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -3260,18 +3260,20 @@ def CIR_ComplexCreateOp : CIR_Op<"complex.create", [Pure, SameTypeOperands]> { def CIR_ComplexRealOp : CIR_Op<"complex.real", [Pure]> { let summary = "Extract the real part of a complex value"; let description = [{ - `cir.complex.real` operation takes an operand of `!cir.complex` type and - yields the real part of it. + `cir.complex.real` operation takes an operand of `!cir.complex`, `!cir.int` + or `!cir.float`. If the operand is `!cir.complex`, the real part of it will + be returned, otherwise the value returned unmodified. Example: ```mlir - %1 = cir.complex.real %0 : !cir.complex<!cir.float> -> !cir.float + %real = cir.complex.real %complex : !cir.complex<!cir.float> -> !cir.float + %real = cir.complex.real %scalar : !cir.float -> !cir.float ``` }]; let results = (outs CIR_AnyIntOrFloatType:$result); - let arguments = (ins CIR_ComplexType:$operand); + let arguments = (ins CIR_AnyComplexOrIntOrFloatType:$operand); let assemblyFormat = [{ $operand `:` qualified(type($operand)) `->` qualified(type($result)) diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td b/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td index 82f6e1d..da03a29 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td @@ -165,6 +165,12 @@ def CIR_AnyIntOrFloatType : AnyTypeOf<[CIR_AnyFloatType, CIR_AnyIntType], def CIR_AnyComplexType : CIR_TypeBase<"::cir::ComplexType", "complex type">; +def CIR_AnyComplexOrIntOrFloatType : AnyTypeOf<[ + CIR_AnyComplexType, CIR_AnyFloatType, CIR_AnyIntType +], "complex, integer or floating point type"> { + let cppFunctionName = "isComplexOrIntegerOrFloatingPointType"; +} + //===----------------------------------------------------------------------===// // Array Type predicates //===----------------------------------------------------------------------===// diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h index 7a6c084..3dfcafc 100644 --- a/clang/include/clang/CIR/MissingFeatures.h +++ b/clang/include/clang/CIR/MissingFeatures.h @@ -133,7 +133,6 @@ struct MissingFeatures { // RecordType static bool skippedLayout() { return false; } static bool astRecordDeclAttr() { return false; } - static bool recordZeroInit() { return false; } static bool recordZeroInitPadding() { return false; } static bool zeroSizeRecordMembers() { return false; } @@ -192,6 +191,7 @@ struct MissingFeatures { static bool builtinCheckKind() { return false; } static bool cgCapturedStmtInfo() { return false; } static bool cgFPOptionsRAII() { return false; } + static bool checkBitfieldClipping() { return false; } static bool cirgenABIInfo() { return false; } static bool cleanupAfterErrorDiags() { return false; } static bool cleanupsToDeactivate() { return false; } diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 6245cf33..2ef6098 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -2750,6 +2750,9 @@ def fno_unsafe_math_optimizations : Flag<["-"], "fno-unsafe-math-optimizations"> Group<f_Group>; def fassociative_math : Flag<["-"], "fassociative-math">, Visibility<[ClangOption, FlangOption]>, Group<f_Group>; def fno_associative_math : Flag<["-"], "fno-associative-math">, Visibility<[ClangOption, FlangOption]>, Group<f_Group>; +def fno_fast_real_mod : Flag<["-"], "fno-fast-real-mod">, + Group<f_Group>, Visibility<[FlangOption, FC1Option]>, + HelpText<"Disable optimization of MOD for REAL types in presence of -ffast-math">; defm reciprocal_math : BoolFOption<"reciprocal-math", LangOpts<"AllowRecip">, DefaultFalse, PosFlag<SetTrue, [], [ClangOption, CC1Option, FC1Option, FlangOption], @@ -9473,7 +9476,7 @@ def target_profile : DXCJoinedOrSeparate<"T">, MetaVarName<"<profile>">, "lib_6_3, lib_6_4, lib_6_5, lib_6_6, lib_6_7, lib_6_x," "ms_6_5, ms_6_6, ms_6_7," "as_6_5, as_6_6, as_6_7," - "rootsig_1_0, rootsig_1_1">; + "rootsig_1_0, rootsig_1_1, rootsig_1_2">; def emit_pristine_llvm : DXCFlag<"emit-pristine-llvm">, HelpText<"Emit pristine LLVM IR from the frontend by not running any LLVM passes at all." "Same as -S + -emit-llvm + -disable-llvm-passes.">; @@ -9486,9 +9489,9 @@ def fdx_rootsignature_version : Group<dxc_Group>, Visibility<[ClangOption, CC1Option]>, HelpText<"Root Signature Version">, - Values<"rootsig_1_0,rootsig_1_1">, + Values<"rootsig_1_0,rootsig_1_1,rootsig_1_2">, NormalizedValuesScope<"llvm::dxbc::RootSignatureVersion">, - NormalizedValues<["V1_0", "V1_1"]>, + NormalizedValues<["V1_0", "V1_1", "V1_2"]>, MarshallingInfoEnum<LangOpts<"HLSLRootSigVer">, "V1_1">; def dxc_rootsig_ver : Separate<["/", "-"], "force-rootsig-ver">, diff --git a/clang/include/clang/Frontend/CompilerInstance.h b/clang/include/clang/Frontend/CompilerInstance.h index a6b6993..44fff69 100644 --- a/clang/include/clang/Frontend/CompilerInstance.h +++ b/clang/include/clang/Frontend/CompilerInstance.h @@ -712,12 +712,10 @@ public: const CodeGenOptions *CodeGenOpts = nullptr); /// Create the file manager and replace any existing one with it. - /// - /// \return The new file manager on success, or null on failure. - FileManager *createFileManager(); + void createFileManager(); /// Create the source manager and replace any existing one with it. - void createSourceManager(FileManager &FileMgr); + void createSourceManager(); /// Create the preprocessor, using the invocation, file, and source managers, /// and replace any existing one with it. diff --git a/clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def b/clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def index a5cfeb3..1d7f7ad 100644 --- a/clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def +++ b/clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def @@ -65,6 +65,9 @@ #ifndef STATIC_BORDER_COLOR_ENUM #define STATIC_BORDER_COLOR_ENUM(NAME, LIT) ENUM(NAME, LIT) #endif +#ifndef STATIC_SAMPLER_FLAG_ENUM +#define STATIC_SAMPLER_FLAG_ENUM(NAME, LIT) ENUM(NAME, LIT) +#endif // General Tokens: TOK(invalid, "invalid identifier") @@ -228,6 +231,10 @@ STATIC_BORDER_COLOR_ENUM(OpaqueWhite, "STATIC_BORDER_COLOR_OPAQUE_WHITE") STATIC_BORDER_COLOR_ENUM(OpaqueBlackUint, "STATIC_BORDER_COLOR_OPAQUE_BLACK_UINT") STATIC_BORDER_COLOR_ENUM(OpaqueWhiteUint, "STATIC_BORDER_COLOR_OPAQUE_WHITE_UINT") +// Root Descriptor Flag Enums: +STATIC_SAMPLER_FLAG_ENUM(UintBorderColor, "UINT_BORDER_COLOR") +STATIC_SAMPLER_FLAG_ENUM(NonNormalizedCoordinates, "NON_NORMALIZED_COORDINATES") + #undef STATIC_BORDER_COLOR_ENUM #undef COMPARISON_FUNC_ENUM #undef TEXTURE_ADDRESS_MODE_ENUM @@ -237,6 +244,7 @@ STATIC_BORDER_COLOR_ENUM(OpaqueWhiteUint, "STATIC_BORDER_COLOR_OPAQUE_WHITE_UINT #undef DESCRIPTOR_RANGE_FLAG_ENUM_OFF #undef DESCRIPTOR_RANGE_FLAG_ENUM_ON #undef ROOT_DESCRIPTOR_FLAG_ENUM +#undef STATIC_SAMPLER_FLAG_ENUM #undef ROOT_FLAG_ENUM #undef DESCRIPTOR_RANGE_OFFSET_ENUM #undef UNBOUNDED_ENUM diff --git a/clang/include/clang/Parse/ParseHLSLRootSignature.h b/clang/include/clang/Parse/ParseHLSLRootSignature.h index b06846f..8f91d7c 100644 --- a/clang/include/clang/Parse/ParseHLSLRootSignature.h +++ b/clang/include/clang/Parse/ParseHLSLRootSignature.h @@ -130,6 +130,7 @@ private: std::optional<float> MaxLOD; std::optional<uint32_t> Space; std::optional<llvm::dxbc::ShaderVisibility> Visibility; + std::optional<llvm::dxbc::StaticSamplerFlags> Flags; }; std::optional<ParsedStaticSamplerParams> parseStaticSamplerParams(); @@ -153,6 +154,8 @@ private: parseRootDescriptorFlags(RootSignatureToken::Kind Context); std::optional<llvm::dxbc::DescriptorRangeFlags> parseDescriptorRangeFlags(RootSignatureToken::Kind Context); + std::optional<llvm::dxbc::StaticSamplerFlags> + parseStaticSamplerFlags(RootSignatureToken::Kind Context); /// Use NumericLiteralParser to convert CurToken.NumSpelling into a unsigned /// 32-bit integer diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index f53aafd..265462a 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -65,6 +65,7 @@ #include "clang/Sema/Redeclaration.h" #include "clang/Sema/Scope.h" #include "clang/Sema/SemaBase.h" +#include "clang/Sema/SemaConcept.h" #include "clang/Sema/TypoCorrection.h" #include "clang/Sema/Weak.h" #include "llvm/ADT/APInt.h" @@ -11694,8 +11695,9 @@ public: ExprResult CheckConceptTemplateId(const CXXScopeSpec &SS, SourceLocation TemplateKWLoc, const DeclarationNameInfo &ConceptNameInfo, - NamedDecl *FoundDecl, ConceptDecl *NamedConcept, - const TemplateArgumentListInfo *TemplateArgs); + NamedDecl *FoundDecl, TemplateDecl *NamedConcept, + const TemplateArgumentListInfo *TemplateArgs, + bool DoCheckConstraintSatisfaction = true); void diagnoseMissingTemplateArguments(TemplateName Name, SourceLocation Loc); void diagnoseMissingTemplateArguments(const CXXScopeSpec &SS, @@ -12025,6 +12027,13 @@ public: bool UpdateArgsWithConversions = true, bool *ConstraintsNotSatisfied = nullptr); + bool CheckTemplateArgumentList( + TemplateDecl *Template, TemplateParameterList *Params, + SourceLocation TemplateLoc, TemplateArgumentListInfo &TemplateArgs, + const DefaultArguments &DefaultArgs, bool PartialTemplateArgs, + CheckTemplateArgumentInfo &CTAI, bool UpdateArgsWithConversions = true, + bool *ConstraintsNotSatisfied = nullptr); + bool CheckTemplateTypeArgument( TemplateTypeParmDecl *Param, TemplateArgumentLoc &Arg, SmallVectorImpl<TemplateArgument> &SugaredConverted, @@ -12783,6 +12792,18 @@ public: void MarkUsedTemplateParameters(const Expr *E, bool OnlyDeduced, unsigned Depth, llvm::SmallBitVector &Used); + /// Mark which template parameters are named in a given expression. + /// + /// Unlike MarkUsedTemplateParameters, this excludes parameter that + /// are used but not directly named by an expression - i.e. it excludes + /// any template parameter that denotes the type of a referenced NTTP. + /// + /// \param Used a bit vector whose elements will be set to \c true + /// to indicate when the corresponding template parameter will be + /// deduced. + void MarkUsedTemplateParametersForSubsumptionParameterMapping( + const Expr *E, unsigned Depth, llvm::SmallBitVector &Used); + /// Mark which template parameters can be deduced from a given /// template argument list. /// @@ -12799,6 +12820,9 @@ public: void MarkUsedTemplateParameters(ArrayRef<TemplateArgument> TemplateArgs, unsigned Depth, llvm::SmallBitVector &Used); + void MarkUsedTemplateParameters(ArrayRef<TemplateArgumentLoc> TemplateArgs, + unsigned Depth, llvm::SmallBitVector &Used); + void MarkDeducedTemplateParameters(const FunctionTemplateDecl *FunctionTemplate, llvm::SmallBitVector &Deduced) { @@ -13096,6 +13120,9 @@ public: /// Whether we're substituting into constraints. bool InConstraintSubstitution; + /// Whether we're substituting into the parameter mapping of a constraint. + bool InParameterMappingSubstitution; + /// The point of instantiation or synthesis within the source code. SourceLocation PointOfInstantiation; @@ -13146,8 +13173,10 @@ public: CodeSynthesisContext() : Kind(TemplateInstantiation), SavedInNonInstantiationSFINAEContext(false), - InConstraintSubstitution(false), Entity(nullptr), Template(nullptr), - TemplateArgs(nullptr), NumTemplateArgs(0), DeductionInfo(nullptr) {} + InConstraintSubstitution(false), + InParameterMappingSubstitution(false), Entity(nullptr), + Template(nullptr), TemplateArgs(nullptr), NumTemplateArgs(0), + DeductionInfo(nullptr) {} /// Determines whether this template is an actual instantiation /// that should be counted toward the maximum instantiation depth. @@ -13359,6 +13388,11 @@ public: const MultiLevelTemplateArgumentList &TemplateArgs, TemplateArgumentListInfo &Outputs); + bool SubstTemplateArgumentsInParameterMapping( + ArrayRef<TemplateArgumentLoc> Args, SourceLocation BaseLoc, + const MultiLevelTemplateArgumentList &TemplateArgs, + TemplateArgumentListInfo &Out, bool BuildPackExpansionTypes); + /// Retrieve the template argument list(s) that should be used to /// instantiate the definition of the given declaration. /// @@ -13820,6 +13854,12 @@ public: CodeSynthesisContexts.back().InConstraintSubstitution; } + bool inParameterMappingSubstitution() const { + return !CodeSynthesisContexts.empty() && + CodeSynthesisContexts.back().InParameterMappingSubstitution && + !inConstraintSubstitution(); + } + using EntityPrinter = llvm::function_ref<void(llvm::raw_ostream &)>; /// \brief create a Requirement::SubstitutionDiagnostic with only a @@ -14704,6 +14744,10 @@ public: SatisfactionStack.swap(NewSS); } + using ConstrainedDeclOrNestedRequirement = + llvm::PointerUnion<const NamedDecl *, + const concepts::NestedRequirement *>; + /// Check whether the given expression is a valid constraint expression. /// A diagnostic is emitted if it is not, false is returned, and /// PossibleNonPrimary will be set to true if the failure might be due to a @@ -14728,44 +14772,12 @@ public: /// \returns true if an error occurred and satisfaction could not be checked, /// false otherwise. bool CheckConstraintSatisfaction( - const NamedDecl *Template, + ConstrainedDeclOrNestedRequirement Entity, ArrayRef<AssociatedConstraint> AssociatedConstraints, const MultiLevelTemplateArgumentList &TemplateArgLists, - SourceRange TemplateIDRange, ConstraintSatisfaction &Satisfaction) { - llvm::SmallVector<Expr *, 4> Converted; - return CheckConstraintSatisfaction(Template, AssociatedConstraints, - Converted, TemplateArgLists, - TemplateIDRange, Satisfaction); - } - - /// \brief Check whether the given list of constraint expressions are - /// satisfied (as if in a 'conjunction') given template arguments. - /// Additionally, takes an empty list of Expressions which is populated with - /// the instantiated versions of the ConstraintExprs. - /// \param Template the template-like entity that triggered the constraints - /// check (either a concept or a constrained entity). - /// \param ConstraintExprs a list of constraint expressions, treated as if - /// they were 'AND'ed together. - /// \param ConvertedConstraints a out parameter that will get populated with - /// the instantiated version of the ConstraintExprs if we successfully checked - /// satisfaction. - /// \param TemplateArgList the multi-level list of template arguments to - /// substitute into the constraint expression. This should be relative to the - /// top-level (hence multi-level), since we need to instantiate fully at the - /// time of checking. - /// \param TemplateIDRange The source range of the template id that - /// caused the constraints check. - /// \param Satisfaction if true is returned, will contain details of the - /// satisfaction, with enough information to diagnose an unsatisfied - /// expression. - /// \returns true if an error occurred and satisfaction could not be checked, - /// false otherwise. - bool CheckConstraintSatisfaction( - const NamedDecl *Template, - ArrayRef<AssociatedConstraint> AssociatedConstraints, - llvm::SmallVectorImpl<Expr *> &ConvertedConstraints, - const MultiLevelTemplateArgumentList &TemplateArgList, - SourceRange TemplateIDRange, ConstraintSatisfaction &Satisfaction); + SourceRange TemplateIDRange, ConstraintSatisfaction &Satisfaction, + const ConceptReference *TopLevelConceptId = nullptr, + Expr **ConvertedExpr = nullptr); /// \brief Check whether the given non-dependent constraint expression is /// satisfied. Returns false and updates Satisfaction with the satisfaction @@ -14831,16 +14843,17 @@ public: /// \param First whether this is the first time an unsatisfied constraint is /// diagnosed for this error. void DiagnoseUnsatisfiedConstraint(const ConstraintSatisfaction &Satisfaction, + SourceLocation Loc = {}, bool First = true); /// \brief Emit diagnostics explaining why a constraint expression was deemed /// unsatisfied. void - DiagnoseUnsatisfiedConstraint(const ASTConstraintSatisfaction &Satisfaction, + DiagnoseUnsatisfiedConstraint(const ConceptSpecializationExpr *ConstraintExpr, bool First = true); const NormalizedConstraint *getNormalizedAssociatedConstraints( - const NamedDecl *ConstrainedDecl, + ConstrainedDeclOrNestedRequirement Entity, ArrayRef<AssociatedConstraint> AssociatedConstraints); /// \brief Check whether the given declaration's associated constraints are @@ -14865,6 +14878,15 @@ public: const NamedDecl *D1, ArrayRef<AssociatedConstraint> AC1, const NamedDecl *D2, ArrayRef<AssociatedConstraint> AC2); + /// Cache the satisfaction of an atomic constraint. + /// The key is based on the unsubstituted expression and the parameter + /// mapping. This lets us not substituting the mapping more than once, + /// which is (very!) expensive. + /// FIXME: this should be private. + llvm::DenseMap<llvm::FoldingSetNodeID, + UnsubstitutedConstraintSatisfactionCacheResult> + UnsubstitutedConstraintSatisfactionCache; + private: /// Caches pairs of template-like decls whose associated constraints were /// checked for subsumption and whether or not the first's constraints did in @@ -14875,8 +14897,11 @@ private: /// constrained declarations). If an error occurred while normalizing the /// associated constraints of the template or concept, nullptr will be cached /// here. - llvm::DenseMap<const NamedDecl *, NormalizedConstraint *> NormalizationCache; + llvm::DenseMap<ConstrainedDeclOrNestedRequirement, NormalizedConstraint *> + NormalizationCache; + /// Cache whether the associated constraint of a declaration + /// is satisfied. llvm::ContextualFoldingSet<ConstraintSatisfaction, const ASTContext &> SatisfactionCache; diff --git a/clang/include/clang/Sema/SemaConcept.h b/clang/include/clang/Sema/SemaConcept.h index 648a9c5..51ca1e1 100644 --- a/clang/include/clang/Sema/SemaConcept.h +++ b/clang/include/clang/Sema/SemaConcept.h @@ -16,130 +16,406 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" +#include "clang/AST/ExprConcepts.h" #include "clang/Basic/SourceLocation.h" +#include "clang/Sema/Ownership.h" #include "llvm/ADT/FoldingSet.h" -#include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/STLFunctionalExtras.h" +#include "llvm/ADT/SmallBitVector.h" #include "llvm/ADT/SmallVector.h" #include <optional> #include <utility> namespace clang { class Sema; +class MultiLevelTemplateArgumentList; -enum { ConstraintAlignment = 8 }; +/// \brief A normalized constraint, as defined in C++ [temp.constr.normal], is +/// either an atomic constraint, a conjunction of normalized constraints or a +/// disjunction of normalized constraints. +struct NormalizedConstraint { + + enum class ConstraintKind : unsigned char { + Atomic = 0, + ConceptId, + FoldExpanded, + Compound, + }; + + enum CompoundConstraintKind : unsigned char { + CCK_Conjunction, + CCK_Disjunction + }; + enum class FoldOperatorKind : unsigned char { And, Or }; + + using OccurenceList = llvm::SmallBitVector; + +protected: + using ExprOrConcept = + llvm::PointerUnion<const Expr *, const ConceptReference *>; + + struct AtomicConstraintBits { + // Kind is the first member of all union members, + // as we rely on their initial common sequence. + LLVM_PREFERRED_TYPE(ConstraintKind) + unsigned Kind : 5; + unsigned Placeholder : 1; + unsigned PackSubstitutionIndex : 26; + // Indexes, IndexesForSubsumption, and Args are part of the common initial + // sequences of constraints that do have a mapping. + + // Indexes of the parameters used in a constraint expression. + OccurenceList Indexes; + // Indexes of the parameters named directly in a constraint expression. + // FIXME: we should try to reduce the size of this struct? + OccurenceList IndexesForSubsumption; + + TemplateArgumentLoc *Args; + TemplateParameterList *ParamList; + ExprOrConcept ConstraintExpr; + const NamedDecl *ConstraintDecl; + }; + + struct FoldExpandedConstraintBits { + LLVM_PREFERRED_TYPE(ConstraintKind) + unsigned Kind : 5; + LLVM_PREFERRED_TYPE(FoldOperatorKind) + unsigned FoldOperator : 1; + unsigned Placeholder : 26; + OccurenceList Indexes; + OccurenceList IndexesForSubsumption; + TemplateArgumentLoc *Args; + TemplateParameterList *ParamList; + const Expr *Pattern; + const NamedDecl *ConstraintDecl; + NormalizedConstraint *Constraint; + }; + + struct ConceptIdBits : AtomicConstraintBits { + NormalizedConstraint *Sub; + + // Only used for parameter mapping. + const ConceptSpecializationExpr *CSE; + }; + + struct CompoundConstraintBits { + LLVM_PREFERRED_TYPE(ConstraintKind) + unsigned Kind : 5; + LLVM_PREFERRED_TYPE(CompoundConstraintKind) + unsigned CCK : 1; + NormalizedConstraint *LHS; + NormalizedConstraint *RHS; + }; + + union { + AtomicConstraintBits Atomic; + FoldExpandedConstraintBits FoldExpanded; + ConceptIdBits ConceptId; + CompoundConstraintBits Compound; + }; + + ~NormalizedConstraint() { + if (getKind() != ConstraintKind::Compound) + Atomic.Indexes.llvm::SmallBitVector::~SmallBitVector(); + } + + NormalizedConstraint(const Expr *ConstraintExpr, + const NamedDecl *ConstraintDecl, + UnsignedOrNone PackIndex) + : Atomic{llvm::to_underlying(ConstraintKind::Atomic), + /*Placeholder=*/0, + PackIndex.toInternalRepresentation(), + /*Indexes=*/{}, + /*IndexesForSubsumption=*/{}, + /*Args=*/nullptr, + /*ParamList=*/nullptr, + ConstraintExpr, + ConstraintDecl} {} + + NormalizedConstraint(const Expr *Pattern, FoldOperatorKind OpKind, + NormalizedConstraint *Constraint, + const NamedDecl *ConstraintDecl) + : FoldExpanded{llvm::to_underlying(ConstraintKind::FoldExpanded), + llvm::to_underlying(OpKind), + /*Placeholder=*/0, + /*Indexes=*/{}, + /*IndexesForSubsumption=*/{}, + /*Args=*/nullptr, + /*ParamList=*/nullptr, + Pattern, + ConstraintDecl, + Constraint} {} + + NormalizedConstraint(const ConceptReference *ConceptId, + const NamedDecl *ConstraintDecl, + NormalizedConstraint *SubConstraint, + const ConceptSpecializationExpr *CSE, + UnsignedOrNone PackIndex) + : ConceptId{{llvm::to_underlying(ConstraintKind::ConceptId), + /*Placeholder=*/0, PackIndex.toInternalRepresentation(), + /*Indexes=*/{}, + /*IndexesForSubsumption=*/{}, + /*Args=*/nullptr, /*ParamList=*/nullptr, ConceptId, + ConstraintDecl}, + SubConstraint, + CSE} {} + + NormalizedConstraint(NormalizedConstraint *LHS, CompoundConstraintKind CCK, + NormalizedConstraint *RHS) + : Compound{llvm::to_underlying(ConstraintKind::Compound), + llvm::to_underlying(CCK), LHS, RHS} {} + + bool hasParameterMapping() const { + // compound constraints do not have a mapping + // and Args is not part of their common initial sequence. + return getKind() != ConstraintKind::Compound && Atomic.Args != nullptr; + } + + const OccurenceList &mappingOccurenceList() const { + assert(hasParameterMapping() && "This constraint has no parameter mapping"); + return Atomic.Indexes; + } + + const OccurenceList &mappingOccurenceListForSubsumption() const { + assert(hasParameterMapping() && "This constraint has no parameter mapping"); + return Atomic.IndexesForSubsumption; + } -struct alignas(ConstraintAlignment) AtomicConstraint { - const Expr *ConstraintExpr; - const NamedDecl *ConstraintDecl; - std::optional<ArrayRef<TemplateArgumentLoc>> ParameterMapping; + llvm::MutableArrayRef<TemplateArgumentLoc> getParameterMapping() const { + return {Atomic.Args, Atomic.Indexes.count()}; + } + + TemplateParameterList *getUsedTemplateParamList() const { + return Atomic.ParamList; + } - AtomicConstraint(const Expr *ConstraintExpr, const NamedDecl *ConstraintDecl) - : ConstraintExpr(ConstraintExpr), ConstraintDecl(ConstraintDecl) {}; + void updateParameterMapping(OccurenceList Indexes, + OccurenceList IndexesForSubsumption, + llvm::MutableArrayRef<TemplateArgumentLoc> Args, + TemplateParameterList *ParamList) { + assert(getKind() != ConstraintKind::Compound); + assert(Indexes.count() == Args.size()); + assert(IndexesForSubsumption.size() == Indexes.size()); + assert((Indexes | IndexesForSubsumption) == Indexes); + + Atomic.IndexesForSubsumption = std::move(IndexesForSubsumption); + Atomic.Indexes = std::move(Indexes); + Atomic.Args = Args.data(); + Atomic.ParamList = ParamList; + } bool hasMatchingParameterMapping(ASTContext &C, - const AtomicConstraint &Other) const { - if (!ParameterMapping != !Other.ParameterMapping) + const NormalizedConstraint &Other) const { + assert(getKind() != ConstraintKind::Compound); + + if (hasParameterMapping() != Other.hasParameterMapping()) return false; - if (!ParameterMapping) + if (!hasParameterMapping()) return true; - if (ParameterMapping->size() != Other.ParameterMapping->size()) - return false; - for (unsigned I = 0, S = ParameterMapping->size(); I < S; ++I) { + llvm::ArrayRef<TemplateArgumentLoc> ParameterMapping = + getParameterMapping(); + llvm::ArrayRef<TemplateArgumentLoc> OtherParameterMapping = + Other.getParameterMapping(); + + const OccurenceList &Indexes = mappingOccurenceListForSubsumption(); + const OccurenceList &OtherIndexes = + Other.mappingOccurenceListForSubsumption(); + + if (ParameterMapping.size() != OtherParameterMapping.size()) + return false; + for (unsigned I = 0, S = ParameterMapping.size(); I < S; ++I) { + if (Indexes[I] != OtherIndexes[I]) + return false; + if (!Indexes[I]) + continue; llvm::FoldingSetNodeID IDA, IDB; - C.getCanonicalTemplateArgument((*ParameterMapping)[I].getArgument()) + C.getCanonicalTemplateArgument(ParameterMapping[I].getArgument()) .Profile(IDA, C); - C.getCanonicalTemplateArgument((*Other.ParameterMapping)[I].getArgument()) + C.getCanonicalTemplateArgument(OtherParameterMapping[I].getArgument()) .Profile(IDB, C); if (IDA != IDB) return false; } return true; } -}; -struct alignas(ConstraintAlignment) NormalizedConstraintPair; -struct alignas(ConstraintAlignment) FoldExpandedConstraint; +public: + ConstraintKind getKind() const { + return static_cast<ConstraintKind>(Atomic.Kind); + } -/// \brief A normalized constraint, as defined in C++ [temp.constr.normal], is -/// either an atomic constraint, a conjunction of normalized constraints or a -/// disjunction of normalized constraints. -struct NormalizedConstraint { + SourceLocation getBeginLoc() const { + switch (getKind()) { + case ConstraintKind::Atomic: + return cast<const Expr *>(Atomic.ConstraintExpr)->getBeginLoc(); + case ConstraintKind::ConceptId: + return cast<const ConceptReference *>(Atomic.ConstraintExpr) + ->getBeginLoc(); + case ConstraintKind::Compound: + return Compound.LHS->getBeginLoc(); + case ConstraintKind::FoldExpanded: + return FoldExpanded.Pattern->getBeginLoc(); + } + } + + SourceLocation getEndLoc() const { + switch (getKind()) { + case ConstraintKind::Atomic: + return cast<const Expr *>(Atomic.ConstraintExpr)->getEndLoc(); + case ConstraintKind::ConceptId: + return cast<const ConceptReference *>(Atomic.ConstraintExpr)->getEndLoc(); + case ConstraintKind::Compound: + return Compound.RHS->getEndLoc(); + case ConstraintKind::FoldExpanded: + return FoldExpanded.Pattern->getEndLoc(); + } + } + + SourceRange getSourceRange() const { return {getBeginLoc(), getEndLoc()}; } + +private: friend class Sema; + static NormalizedConstraint * + fromAssociatedConstraints(Sema &S, const NamedDecl *D, + ArrayRef<AssociatedConstraint> ACs); + static NormalizedConstraint *fromConstraintExpr(Sema &S, const NamedDecl *D, + const Expr *E, + UnsignedOrNone SubstIndex); +}; + +class CompoundConstraint : public NormalizedConstraint { + using NormalizedConstraint::NormalizedConstraint; - enum CompoundConstraintKind { CCK_Conjunction, CCK_Disjunction }; +public: + static CompoundConstraint *Create(ASTContext &Ctx, NormalizedConstraint *LHS, + CompoundConstraintKind CCK, + NormalizedConstraint *RHS) { + return new (Ctx) CompoundConstraint(LHS, CCK, RHS); + } - using CompoundConstraint = llvm::PointerIntPair<NormalizedConstraintPair *, 1, - CompoundConstraintKind>; + static CompoundConstraint *CreateConjunction(ASTContext &Ctx, + NormalizedConstraint *LHS, + NormalizedConstraint *RHS) { + return new (Ctx) CompoundConstraint(LHS, CCK_Conjunction, RHS); + } - llvm::PointerUnion<AtomicConstraint *, FoldExpandedConstraint *, - CompoundConstraint> - Constraint; + const NormalizedConstraint &getLHS() const { return *Compound.LHS; } - NormalizedConstraint(AtomicConstraint *C): Constraint{C} { }; - NormalizedConstraint(FoldExpandedConstraint *C) : Constraint{C} {}; + NormalizedConstraint &getLHS() { return *Compound.LHS; } - NormalizedConstraint(ASTContext &C, NormalizedConstraint LHS, - NormalizedConstraint RHS, CompoundConstraintKind Kind); + const NormalizedConstraint &getRHS() const { return *Compound.RHS; } - NormalizedConstraint(ASTContext &C, const NormalizedConstraint &Other); - NormalizedConstraint(NormalizedConstraint &&Other): - Constraint(Other.Constraint) { - Other.Constraint = nullptr; + NormalizedConstraint &getRHS() { return *Compound.RHS; } + + CompoundConstraintKind getCompoundKind() const { + return static_cast<CompoundConstraintKind>(Compound.CCK); } - NormalizedConstraint &operator=(const NormalizedConstraint &Other) = delete; - NormalizedConstraint &operator=(NormalizedConstraint &&Other) { - if (&Other != this) { - NormalizedConstraint Temp(std::move(Other)); - std::swap(Constraint, Temp.Constraint); - } - return *this; +}; + +class NormalizedConstraintWithParamMapping : public NormalizedConstraint { +protected: + using NormalizedConstraint::NormalizedConstraint; + +public: + using NormalizedConstraint::getParameterMapping; + using NormalizedConstraint::getUsedTemplateParamList; + using NormalizedConstraint::hasMatchingParameterMapping; + using NormalizedConstraint::hasParameterMapping; + using NormalizedConstraint::mappingOccurenceList; + using NormalizedConstraint::mappingOccurenceListForSubsumption; + using NormalizedConstraint::updateParameterMapping; + + const NamedDecl *getConstraintDecl() const { return Atomic.ConstraintDecl; } + + UnsignedOrNone getPackSubstitutionIndex() const { + return UnsignedOrNone::fromInternalRepresentation( + Atomic.PackSubstitutionIndex); } +}; + +class AtomicConstraint : public NormalizedConstraintWithParamMapping { + using NormalizedConstraintWithParamMapping:: + NormalizedConstraintWithParamMapping; - bool isAtomic() const { return llvm::isa<AtomicConstraint *>(Constraint); } - bool isFoldExpanded() const { - return llvm::isa<FoldExpandedConstraint *>(Constraint); +public: + static AtomicConstraint *Create(ASTContext &Ctx, const Expr *ConstraintExpr, + const NamedDecl *ConstraintDecl, + UnsignedOrNone PackIndex) { + return new (Ctx) + AtomicConstraint(ConstraintExpr, ConstraintDecl, PackIndex); } - bool isCompound() const { return llvm::isa<CompoundConstraint>(Constraint); } - CompoundConstraintKind getCompoundKind() const; + const Expr *getConstraintExpr() const { + return cast<const Expr *>(Atomic.ConstraintExpr); + } +}; - NormalizedConstraint &getLHS() const; - NormalizedConstraint &getRHS() const; +class FoldExpandedConstraint : public NormalizedConstraintWithParamMapping { + using NormalizedConstraintWithParamMapping:: + NormalizedConstraintWithParamMapping; - AtomicConstraint *getAtomicConstraint() const; +public: + static FoldExpandedConstraint *Create(ASTContext &Ctx, const Expr *Pattern, + const NamedDecl *ConstraintDecl, + FoldOperatorKind OpKind, + NormalizedConstraint *Constraint) { + return new (Ctx) + FoldExpandedConstraint(Pattern, OpKind, Constraint, ConstraintDecl); + } - FoldExpandedConstraint *getFoldExpandedConstraint() const; + using NormalizedConstraint::hasMatchingParameterMapping; -private: - static std::optional<NormalizedConstraint> - fromAssociatedConstraints(Sema &S, const NamedDecl *D, - ArrayRef<AssociatedConstraint> ACs); - static std::optional<NormalizedConstraint> - fromConstraintExpr(Sema &S, const NamedDecl *D, const Expr *E); -}; + FoldOperatorKind getFoldOperator() const { + return static_cast<FoldOperatorKind>(FoldExpanded.FoldOperator); + } -struct alignas(ConstraintAlignment) NormalizedConstraintPair { - NormalizedConstraint LHS, RHS; -}; + const Expr *getPattern() const { return FoldExpanded.Pattern; } -struct alignas(ConstraintAlignment) FoldExpandedConstraint { - enum class FoldOperatorKind { And, Or } Kind; - NormalizedConstraint Constraint; - const Expr *Pattern; + const NormalizedConstraint &getNormalizedPattern() const { + return *FoldExpanded.Constraint; + } - FoldExpandedConstraint(FoldOperatorKind K, NormalizedConstraint C, - const Expr *Pattern) - : Kind(K), Constraint(std::move(C)), Pattern(Pattern) {}; + NormalizedConstraint &getNormalizedPattern() { + return *FoldExpanded.Constraint; + } static bool AreCompatibleForSubsumption(const FoldExpandedConstraint &A, const FoldExpandedConstraint &B); }; -const NormalizedConstraint *getNormalizedAssociatedConstraints( - Sema &S, const NamedDecl *ConstrainedDecl, - ArrayRef<AssociatedConstraint> AssociatedConstraints); +class ConceptIdConstraint : public NormalizedConstraintWithParamMapping { + using NormalizedConstraintWithParamMapping:: + NormalizedConstraintWithParamMapping; + +public: + static ConceptIdConstraint * + Create(ASTContext &Ctx, const ConceptReference *ConceptId, + NormalizedConstraint *SubConstraint, const NamedDecl *ConstraintDecl, + const ConceptSpecializationExpr *CSE, UnsignedOrNone PackIndex) { + return new (Ctx) ConceptIdConstraint(ConceptId, ConstraintDecl, + SubConstraint, CSE, PackIndex); + } + + const ConceptSpecializationExpr *getConceptSpecializationExpr() const { + return ConceptId.CSE; + } + + const ConceptReference *getConceptId() const { + return cast<const ConceptReference *>(ConceptId.ConstraintExpr); + } + + const NormalizedConstraint &getNormalizedConstraint() const { + return *ConceptId.Sub; + } + + NormalizedConstraint &getNormalizedConstraint() { return *ConceptId.Sub; } +}; + +struct UnsubstitutedConstraintSatisfactionCacheResult { + ExprResult SubstExpr; + ConstraintSatisfaction Satisfaction; +}; /// \brief SubsumptionChecker establishes subsumption /// between two set of constraints. @@ -189,13 +465,13 @@ private: }; struct MappedAtomicConstraint { - AtomicConstraint *Constraint; + const AtomicConstraint *Constraint; Literal ID; }; struct FoldExpendedConstraintKey { FoldExpandedConstraint::FoldOperatorKind Kind; - AtomicConstraint *Constraint; + const AtomicConstraint *Constraint; Literal ID; }; @@ -207,7 +483,7 @@ private: // A map from a literal to a corresponding associated constraint. // We do not have enough bits left for a pointer union here :( - llvm::DenseMap<uint16_t, void *> ReverseMap; + llvm::DenseMap<uint16_t, const void *> ReverseMap; // Fold expanded constraints ask us to recursively establish subsumption. // This caches the result. @@ -234,12 +510,12 @@ private: FormulaType Normalize(const NormalizedConstraint &C); void AddUniqueClauseToFormula(Formula &F, Clause C); - Literal find(AtomicConstraint *); - Literal find(FoldExpandedConstraint *); + Literal find(const AtomicConstraint *); + Literal find(const FoldExpandedConstraint *); uint16_t getNewLiteralId(); }; -} // clang +} // namespace clang #endif // LLVM_CLANG_SEMA_SEMACONCEPT_H diff --git a/clang/include/clang/Sema/Template.h b/clang/include/clang/Sema/Template.h index 115c19d..60c7d27 100644 --- a/clang/include/clang/Sema/Template.h +++ b/clang/include/clang/Sema/Template.h @@ -234,21 +234,25 @@ enum class TemplateSubstitutionKind : char { /// Replaces the current 'innermost' level with the provided argument list. /// This is useful for type deduction cases where we need to get the entire /// list from the AST, but then add the deduced innermost list. - void replaceInnermostTemplateArguments(Decl *AssociatedDecl, ArgList Args) { + void replaceInnermostTemplateArguments(Decl *AssociatedDecl, ArgList Args, + bool Final = false) { assert((!TemplateArgumentLists.empty() || NumRetainedOuterLevels) && "Replacing in an empty list?"); if (!TemplateArgumentLists.empty()) { - assert((TemplateArgumentLists[0].AssociatedDeclAndFinal.getPointer() || - TemplateArgumentLists[0].AssociatedDeclAndFinal.getPointer() == - AssociatedDecl) && - "Trying to change incorrect declaration?"); TemplateArgumentLists[0].Args = Args; - } else { - --NumRetainedOuterLevels; - TemplateArgumentLists.push_back( - {{AssociatedDecl, /*Final=*/false}, Args}); + return; } + --NumRetainedOuterLevels; + TemplateArgumentLists.push_back( + {{AssociatedDecl, /*Final=*/Final}, Args}); + } + + void replaceOutermostTemplateArguments(Decl *AssociatedDecl, ArgList Args) { + assert((!TemplateArgumentLists.empty()) && "Replacing in an empty list?"); + TemplateArgumentLists.back().AssociatedDeclAndFinal.setPointer( + AssociatedDecl); + TemplateArgumentLists.back().Args = Args; } /// Add an outermost level that we are not substituting. We have no diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h index 5dcf03f7..c233ca1 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h @@ -1414,7 +1414,7 @@ class CallEventManager { } public: - CallEventManager(llvm::BumpPtrAllocator &alloc) : Alloc(alloc) {} + CallEventManager(llvm::BumpPtrAllocator &alloc); /// Gets an outside caller given a callee context. CallEventRef<> getCaller(const StackFrameContext *CalleeCtx, diff --git a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h index c3601a4..f222ded 100644 --- a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h +++ b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h @@ -220,7 +220,6 @@ private: std::vector<std::string> VisibleModules; std::vector<Command> Commands; std::string ContextHash; - std::vector<std::string> OutputPaths; const llvm::DenseSet<ModuleID> &AlreadySeen; }; |