diff options
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/DeclSpec.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp | 141 | ||||
-rw-r--r-- | clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h | 7 | ||||
-rw-r--r-- | clang/lib/Sema/HLSLExternalSemaSource.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Sema/ParsedAttr.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 63 | ||||
-rw-r--r-- | clang/lib/Sema/SemaHLSL.cpp | 112 | ||||
-rw-r--r-- | clang/lib/Sema/SemaOpenACC.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 32 |
10 files changed, 275 insertions, 91 deletions
diff --git a/clang/lib/Sema/DeclSpec.cpp b/clang/lib/Sema/DeclSpec.cpp index 8756ce5..184d31e 100644 --- a/clang/lib/Sema/DeclSpec.cpp +++ b/clang/lib/Sema/DeclSpec.cpp @@ -197,7 +197,7 @@ DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, [&](DeclSpec::TQ TypeQual, StringRef PrintName, SourceLocation SL) { I.Fun.MethodQualifiers->SetTypeQual(TypeQual, SL); }); - I.Fun.MethodQualifiers->getAttributes().takeAllFrom(attrs); + I.Fun.MethodQualifiers->getAttributes().takeAllPrependingFrom(attrs); I.Fun.MethodQualifiers->getAttributePool().takeAllFrom(attrs.getPool()); } diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp index 3c20ccd..40c318a 100644 --- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp +++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp @@ -144,6 +144,7 @@ private: _2, _3, _4, + _5, Handle = 128, CounterHandle, LastStmt @@ -190,6 +191,9 @@ public: template <typename T> BuiltinTypeMethodBuilder & accessCounterHandleFieldOnResource(T ResourceRecord); + template <typename ResourceT, typename ValueT> + BuiltinTypeMethodBuilder & + setCounterHandleFieldOnResource(ResourceT ResourceRecord, ValueT HandleValue); template <typename T> BuiltinTypeMethodBuilder &returnValue(T ReturnValue); BuiltinTypeMethodBuilder &returnThis(); BuiltinTypeDeclBuilder &finalize(); @@ -205,6 +209,11 @@ private: if (!Method) createDecl(); } + + template <typename ResourceT, typename ValueT> + BuiltinTypeMethodBuilder &setFieldOnResource(ResourceT ResourceRecord, + ValueT HandleValue, + FieldDecl *HandleField); }; TemplateParameterListBuilder::~TemplateParameterListBuilder() { @@ -592,13 +601,27 @@ template <typename ResourceT, typename ValueT> BuiltinTypeMethodBuilder & BuiltinTypeMethodBuilder::setHandleFieldOnResource(ResourceT ResourceRecord, ValueT HandleValue) { + return setFieldOnResource(ResourceRecord, HandleValue, + DeclBuilder.getResourceHandleField()); +} + +template <typename ResourceT, typename ValueT> +BuiltinTypeMethodBuilder & +BuiltinTypeMethodBuilder::setCounterHandleFieldOnResource( + ResourceT ResourceRecord, ValueT HandleValue) { + return setFieldOnResource(ResourceRecord, HandleValue, + DeclBuilder.getResourceCounterHandleField()); +} + +template <typename ResourceT, typename ValueT> +BuiltinTypeMethodBuilder &BuiltinTypeMethodBuilder::setFieldOnResource( + ResourceT ResourceRecord, ValueT HandleValue, FieldDecl *HandleField) { ensureCompleteDecl(); Expr *ResourceExpr = convertPlaceholder(ResourceRecord); Expr *HandleValueExpr = convertPlaceholder(HandleValue); ASTContext &AST = DeclBuilder.SemaRef.getASTContext(); - FieldDecl *HandleField = DeclBuilder.getResourceHandleField(); MemberExpr *HandleMemberExpr = MemberExpr::CreateImplicit( AST, ResourceExpr, false, HandleField, HandleField->getType(), VK_LValue, OK_Ordinary); @@ -829,6 +852,18 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addDefaultHandleConstructor() { .finalize(); } +BuiltinTypeDeclBuilder & +BuiltinTypeDeclBuilder::addStaticInitializationFunctions(bool HasCounter) { + if (HasCounter) { + addCreateFromBindingWithImplicitCounter(); + addCreateFromImplicitBindingWithImplicitCounter(); + } else { + addCreateFromBinding(); + addCreateFromImplicitBinding(); + } + return *this; +} + // Adds static method that initializes resource from binding: // // static Resource<T> __createFromBinding(unsigned registerNo, @@ -903,6 +938,102 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addCreateFromImplicitBinding() { .finalize(); } +// Adds static method that initializes resource from binding: +// +// static Resource<T> +// __createFromBindingWithImplicitCounter(unsigned registerNo, +// unsigned spaceNo, int range, +// unsigned index, const char *name, +// unsigned counterOrderId) { +// Resource<T> tmp; +// tmp.__handle = __builtin_hlsl_resource_handlefrombinding( +// tmp.__handle, registerNo, spaceNo, range, index, name); +// tmp.__counter_handle = +// __builtin_hlsl_resource_counterhandlefromimplicitbinding( +// tmp.__handle, counterOrderId, spaceNo); +// return tmp; +// } +BuiltinTypeDeclBuilder & +BuiltinTypeDeclBuilder::addCreateFromBindingWithImplicitCounter() { + assert(!Record->isCompleteDefinition() && "record is already complete"); + + using PH = BuiltinTypeMethodBuilder::PlaceHolder; + ASTContext &AST = SemaRef.getASTContext(); + QualType HandleType = getResourceHandleField()->getType(); + QualType RecordType = AST.getTypeDeclType(cast<TypeDecl>(Record)); + BuiltinTypeMethodBuilder::LocalVar TmpVar("tmp", RecordType); + + return BuiltinTypeMethodBuilder(*this, + "__createFromBindingWithImplicitCounter", + RecordType, false, false, SC_Static) + .addParam("registerNo", AST.UnsignedIntTy) + .addParam("spaceNo", AST.UnsignedIntTy) + .addParam("range", AST.IntTy) + .addParam("index", AST.UnsignedIntTy) + .addParam("name", AST.getPointerType(AST.CharTy.withConst())) + .addParam("counterOrderId", AST.UnsignedIntTy) + .declareLocalVar(TmpVar) + .accessHandleFieldOnResource(TmpVar) + .callBuiltin("__builtin_hlsl_resource_handlefrombinding", HandleType, + PH::LastStmt, PH::_0, PH::_1, PH::_2, PH::_3, PH::_4) + .setHandleFieldOnResource(TmpVar, PH::LastStmt) + .accessHandleFieldOnResource(TmpVar) + .callBuiltin("__builtin_hlsl_resource_counterhandlefromimplicitbinding", + HandleType, PH::LastStmt, PH::_5, PH::_1) + .setCounterHandleFieldOnResource(TmpVar, PH::LastStmt) + .returnValue(TmpVar) + .finalize(); +} + +// Adds static method that initializes resource from binding: +// +// static Resource<T> +// __createFromImplicitBindingWithImplicitCounter(unsigned orderId, +// unsigned spaceNo, int range, +// unsigned index, +// const char *name, +// unsigned counterOrderId) { +// Resource<T> tmp; +// tmp.__handle = __builtin_hlsl_resource_handlefromimplicitbinding( +// tmp.__handle, orderId, spaceNo, range, index, name); +// tmp.__counter_handle = +// __builtin_hlsl_resource_counterhandlefromimplicitbinding( +// tmp.__handle, counterOrderId, spaceNo); +// return tmp; +// } +BuiltinTypeDeclBuilder & +BuiltinTypeDeclBuilder::addCreateFromImplicitBindingWithImplicitCounter() { + assert(!Record->isCompleteDefinition() && "record is already complete"); + + using PH = BuiltinTypeMethodBuilder::PlaceHolder; + ASTContext &AST = SemaRef.getASTContext(); + QualType HandleType = getResourceHandleField()->getType(); + QualType RecordType = AST.getTypeDeclType(cast<TypeDecl>(Record)); + BuiltinTypeMethodBuilder::LocalVar TmpVar("tmp", RecordType); + + return BuiltinTypeMethodBuilder( + *this, "__createFromImplicitBindingWithImplicitCounter", + RecordType, false, false, SC_Static) + .addParam("orderId", AST.UnsignedIntTy) + .addParam("spaceNo", AST.UnsignedIntTy) + .addParam("range", AST.IntTy) + .addParam("index", AST.UnsignedIntTy) + .addParam("name", AST.getPointerType(AST.CharTy.withConst())) + .addParam("counterOrderId", AST.UnsignedIntTy) + .declareLocalVar(TmpVar) + .accessHandleFieldOnResource(TmpVar) + .callBuiltin("__builtin_hlsl_resource_handlefromimplicitbinding", + HandleType, PH::LastStmt, PH::_0, PH::_1, PH::_2, PH::_3, + PH::_4) + .setHandleFieldOnResource(TmpVar, PH::LastStmt) + .accessHandleFieldOnResource(TmpVar) + .callBuiltin("__builtin_hlsl_resource_counterhandlefromimplicitbinding", + HandleType, PH::LastStmt, PH::_5, PH::_1) + .setCounterHandleFieldOnResource(TmpVar, PH::LastStmt) + .returnValue(TmpVar) + .finalize(); +} + BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addCopyConstructor() { assert(!Record->isCompleteDefinition() && "record is already complete"); @@ -1048,7 +1179,7 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addIncrementCounterMethod() { return BuiltinTypeMethodBuilder(*this, "IncrementCounter", SemaRef.getASTContext().UnsignedIntTy) .callBuiltin("__builtin_hlsl_buffer_update_counter", QualType(), - PH::Handle, getConstantIntExpr(1)) + PH::CounterHandle, getConstantIntExpr(1)) .finalize(); } @@ -1057,7 +1188,7 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addDecrementCounterMethod() { return BuiltinTypeMethodBuilder(*this, "DecrementCounter", SemaRef.getASTContext().UnsignedIntTy) .callBuiltin("__builtin_hlsl_buffer_update_counter", QualType(), - PH::Handle, getConstantIntExpr(-1)) + PH::CounterHandle, getConstantIntExpr(-1)) .finalize(); } @@ -1102,7 +1233,7 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addAppendMethod() { return BuiltinTypeMethodBuilder(*this, "Append", AST.VoidTy) .addParam("value", ElemTy) .callBuiltin("__builtin_hlsl_buffer_update_counter", AST.UnsignedIntTy, - PH::Handle, getConstantIntExpr(1)) + PH::CounterHandle, getConstantIntExpr(1)) .callBuiltin("__builtin_hlsl_resource_getpointer", AST.getPointerType(AddrSpaceElemTy), PH::Handle, PH::LastStmt) @@ -1119,7 +1250,7 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addConsumeMethod() { AST.getAddrSpaceQualType(ElemTy, LangAS::hlsl_device); return BuiltinTypeMethodBuilder(*this, "Consume", ElemTy) .callBuiltin("__builtin_hlsl_buffer_update_counter", AST.UnsignedIntTy, - PH::Handle, getConstantIntExpr(-1)) + PH::CounterHandle, getConstantIntExpr(-1)) .callBuiltin("__builtin_hlsl_resource_getpointer", AST.getPointerType(AddrSpaceElemTy), PH::Handle, PH::LastStmt) diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h index a981602..86cbd10 100644 --- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h +++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h @@ -83,8 +83,7 @@ public: BuiltinTypeDeclBuilder &addCopyAssignmentOperator(); // Static create methods - BuiltinTypeDeclBuilder &addCreateFromBinding(); - BuiltinTypeDeclBuilder &addCreateFromImplicitBinding(); + BuiltinTypeDeclBuilder &addStaticInitializationFunctions(bool HasCounter); // Builtin types methods BuiltinTypeDeclBuilder &addLoadMethods(); @@ -96,6 +95,10 @@ public: BuiltinTypeDeclBuilder &addConsumeMethod(); private: + BuiltinTypeDeclBuilder &addCreateFromBinding(); + BuiltinTypeDeclBuilder &addCreateFromImplicitBinding(); + BuiltinTypeDeclBuilder &addCreateFromBindingWithImplicitCounter(); + BuiltinTypeDeclBuilder &addCreateFromImplicitBindingWithImplicitCounter(); BuiltinTypeDeclBuilder &addResourceMember(StringRef MemberName, ResourceClass RC, bool IsROV, bool RawBuffer, bool IsCounter, diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp index cc43e94..e118dda 100644 --- a/clang/lib/Sema/HLSLExternalSemaSource.cpp +++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp @@ -236,8 +236,7 @@ static BuiltinTypeDeclBuilder setupBufferType(CXXRecordDecl *Decl, Sema &S, .addDefaultHandleConstructor() .addCopyConstructor() .addCopyAssignmentOperator() - .addCreateFromBinding() - .addCreateFromImplicitBinding(); + .addStaticInitializationFunctions(HasCounter); } // This function is responsible for constructing the constraint expression for diff --git a/clang/lib/Sema/ParsedAttr.cpp b/clang/lib/Sema/ParsedAttr.cpp index 294f88e..2b5ad33 100644 --- a/clang/lib/Sema/ParsedAttr.cpp +++ b/clang/lib/Sema/ParsedAttr.cpp @@ -304,7 +304,7 @@ bool ParsedAttr::checkAtMostNumArgs(Sema &S, unsigned Num) const { void clang::takeAndConcatenateAttrs(ParsedAttributes &First, ParsedAttributes &&Second) { - First.takeAllAtEndFrom(Second); + First.takeAllAppendingFrom(Second); if (!First.Range.getBegin().isValid()) First.Range.setBegin(Second.Range.getBegin()); diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 6eaf7b9..0e83c20 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -14637,7 +14637,7 @@ StmtResult Sema::ActOnCXXForRangeIdentifier(Scope *S, SourceLocation IdentLoc, Declarator D(DS, ParsedAttributesView::none(), DeclaratorContext::ForInit); D.SetIdentifier(Ident, IdentLoc); - D.takeAttributes(Attrs); + D.takeAttributesAppending(Attrs); D.AddTypeInfo(DeclaratorChunk::getReference(0, IdentLoc, /*lvalue*/ false), IdentLoc); diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 4d3c7d6..4230ea7 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -9014,24 +9014,6 @@ bool Sema::IsInvalidSMECallConversion(QualType FromType, QualType ToType) { return FromAttributes != ToAttributes; } -// Check if we have a conversion between incompatible cmse function pointer -// types, that is, a conversion between a function pointer with the -// cmse_nonsecure_call attribute and one without. -static bool IsInvalidCmseNSCallConversion(Sema &S, QualType FromType, - QualType ToType) { - if (const auto *ToFn = - dyn_cast<FunctionType>(S.Context.getCanonicalType(ToType))) { - if (const auto *FromFn = - dyn_cast<FunctionType>(S.Context.getCanonicalType(FromType))) { - FunctionType::ExtInfo ToEInfo = ToFn->getExtInfo(); - FunctionType::ExtInfo FromEInfo = FromFn->getExtInfo(); - - return ToEInfo.getCmseNSCall() != FromEInfo.getCmseNSCall(); - } - } - return false; -} - // checkPointerTypesForAssignment - This is a very tricky routine (despite // being closely modeled after the C99 spec:-). The odd characteristic of this // routine is it effectively iqnores the qualifiers on the top level pointee. @@ -9187,18 +9169,43 @@ static AssignConvertType checkPointerTypesForAssignment(Sema &S, return AssignConvertType::IncompatibleFunctionPointer; return AssignConvertType::IncompatiblePointer; } - bool DiscardingCFIUncheckedCallee, AddingCFIUncheckedCallee; - if (!S.getLangOpts().CPlusPlus && - S.IsFunctionConversion(ltrans, rtrans, &DiscardingCFIUncheckedCallee, - &AddingCFIUncheckedCallee)) { - // Allow conversions between CFIUncheckedCallee-ness. - if (!DiscardingCFIUncheckedCallee && !AddingCFIUncheckedCallee) + // Note: in C++, typesAreCompatible(ltrans, rtrans) will have guaranteed + // hasSameType, so we can skip further checks. + const auto *LFT = ltrans->getAs<FunctionType>(); + const auto *RFT = rtrans->getAs<FunctionType>(); + if (!S.getLangOpts().CPlusPlus && LFT && RFT) { + // The invocation of IsFunctionConversion below will try to transform rtrans + // to obtain an exact match for ltrans. This should not fail because of + // mismatches in result type and parameter types, they were already checked + // by typesAreCompatible above. So we will recreate rtrans (or where + // appropriate ltrans) using the result type and parameter types from ltrans + // (respectively rtrans), but keeping its ExtInfo/ExtProtoInfo. + const auto *LFPT = dyn_cast<FunctionProtoType>(LFT); + const auto *RFPT = dyn_cast<FunctionProtoType>(RFT); + if (LFPT && RFPT) { + rtrans = S.Context.getFunctionType(LFPT->getReturnType(), + LFPT->getParamTypes(), + RFPT->getExtProtoInfo()); + } else if (LFPT) { + FunctionProtoType::ExtProtoInfo EPI; + EPI.ExtInfo = RFT->getExtInfo(); + rtrans = S.Context.getFunctionType(LFPT->getReturnType(), + LFPT->getParamTypes(), EPI); + } else if (RFPT) { + // In this case, we want to retain rtrans as a FunctionProtoType, to keep + // all of its ExtProtoInfo. Transform ltrans instead. + FunctionProtoType::ExtProtoInfo EPI; + EPI.ExtInfo = LFT->getExtInfo(); + ltrans = S.Context.getFunctionType(RFPT->getReturnType(), + RFPT->getParamTypes(), EPI); + } else { + rtrans = S.Context.getFunctionNoProtoType(LFT->getReturnType(), + RFT->getExtInfo()); + } + if (!S.Context.hasSameUnqualifiedType(rtrans, ltrans) && + !S.IsFunctionConversion(rtrans, ltrans)) return AssignConvertType::IncompatibleFunctionPointer; } - if (IsInvalidCmseNSCallConversion(S, ltrans, rtrans)) - return AssignConvertType::IncompatibleFunctionPointer; - if (S.IsInvalidSMECallConversion(rtrans, ltrans)) - return AssignConvertType::IncompatibleFunctionPointer; return ConvTy; } diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index 09e5d69..17cb1e4 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -1240,6 +1240,20 @@ static CXXMethodDecl *lookupMethod(Sema &S, CXXRecordDecl *RecordDecl, } // end anonymous namespace +static bool hasCounterHandle(const CXXRecordDecl *RD) { + if (RD->field_empty()) + return false; + auto It = std::next(RD->field_begin()); + if (It == RD->field_end()) + return false; + const FieldDecl *SecondField = *It; + if (const auto *ResTy = + SecondField->getType()->getAs<HLSLAttributedResourceType>()) { + return ResTy->getAttrs().IsCounter; + } + return false; +} + bool SemaHLSL::handleRootSignatureElements( ArrayRef<hlsl::RootSignatureElement> Elements) { // Define some common error handling functions @@ -2973,6 +2987,25 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { TheCall->setType(ResourceTy); break; } + case Builtin::BI__builtin_hlsl_resource_counterhandlefromimplicitbinding: { + ASTContext &AST = SemaRef.getASTContext(); + if (SemaRef.checkArgCount(TheCall, 3) || + CheckResourceHandle(&SemaRef, TheCall, 0) || + CheckArgTypeMatches(&SemaRef, TheCall->getArg(1), AST.UnsignedIntTy) || + CheckArgTypeMatches(&SemaRef, TheCall->getArg(2), AST.UnsignedIntTy)) + return true; + + QualType MainHandleTy = TheCall->getArg(0)->getType(); + auto *MainResType = MainHandleTy->getAs<HLSLAttributedResourceType>(); + auto MainAttrs = MainResType->getAttrs(); + assert(!MainAttrs.IsCounter && "cannot create a counter from a counter"); + MainAttrs.IsCounter = true; + QualType CounterHandleTy = AST.getHLSLAttributedResourceType( + MainResType->getWrappedType(), MainResType->getContainedType(), + MainAttrs); + TheCall->setType(CounterHandleTy); + break; + } case Builtin::BI__builtin_hlsl_and: case Builtin::BI__builtin_hlsl_or: { if (SemaRef.checkArgCount(TheCall, 2)) @@ -3780,10 +3813,24 @@ void SemaHLSL::ActOnVariableDeclarator(VarDecl *VD) { uint32_t OrderID = getNextImplicitBindingOrderID(); if (Binding.hasBinding()) Binding.setImplicitOrderID(OrderID); - else + else { addImplicitBindingAttrToDecl( SemaRef, VD, getRegisterType(getResourceArrayHandleType(VD)), OrderID); + // Re-create the binding object to pick up the new attribute. + Binding = ResourceBindingAttrs(VD); + } + } + + // Get to the base type of a potentially multi-dimensional array. + QualType Ty = getASTContext().getBaseElementType(VD->getType()); + + const CXXRecordDecl *RD = Ty->getAsCXXRecordDecl(); + if (hasCounterHandle(RD)) { + if (!Binding.hasCounterImplicitOrderID()) { + uint32_t OrderID = getNextImplicitBindingOrderID(); + Binding.setCounterImplicitOrderID(OrderID); + } } } } @@ -3808,19 +3855,31 @@ bool SemaHLSL::initGlobalResourceDecl(VarDecl *VD) { CXXMethodDecl *CreateMethod = nullptr; llvm::SmallVector<Expr *> Args; + bool HasCounter = hasCounterHandle(ResourceDecl); + const char *CreateMethodName; + if (Binding.isExplicit()) + CreateMethodName = HasCounter ? "__createFromBindingWithImplicitCounter" + : "__createFromBinding"; + else + CreateMethodName = HasCounter + ? "__createFromImplicitBindingWithImplicitCounter" + : "__createFromImplicitBinding"; + + CreateMethod = + lookupMethod(SemaRef, ResourceDecl, CreateMethodName, VD->getLocation()); + + if (!CreateMethod) + // This can happen if someone creates a struct that looks like an HLSL + // resource record but does not have the required static create method. + // No binding will be generated for it. + return false; + if (Binding.isExplicit()) { - // The resource has explicit binding. - CreateMethod = lookupMethod(SemaRef, ResourceDecl, "__createFromBinding", - VD->getLocation()); IntegerLiteral *RegSlot = IntegerLiteral::Create(AST, llvm::APInt(UIntTySize, Binding.getSlot()), AST.UnsignedIntTy, SourceLocation()); Args.push_back(RegSlot); } else { - // The resource has implicit binding. - CreateMethod = - lookupMethod(SemaRef, ResourceDecl, "__createFromImplicitBinding", - VD->getLocation()); uint32_t OrderID = (Binding.hasImplicitOrderID()) ? Binding.getImplicitOrderID() : getNextImplicitBindingOrderID(); @@ -3830,12 +3889,6 @@ bool SemaHLSL::initGlobalResourceDecl(VarDecl *VD) { Args.push_back(OrderId); } - if (!CreateMethod) - // This can happen if someone creates a struct that looks like an HLSL - // resource record but does not have the required static create method. - // No binding will be generated for it. - return false; - IntegerLiteral *Space = IntegerLiteral::Create(AST, llvm::APInt(UIntTySize, Binding.getSpace()), AST.UnsignedIntTy, SourceLocation()); @@ -3859,6 +3912,15 @@ bool SemaHLSL::initGlobalResourceDecl(VarDecl *VD) { Name, nullptr, VK_PRValue, FPOptionsOverride()); Args.push_back(NameCast); + if (HasCounter) { + // Will this be in the correct order? + uint32_t CounterOrderID = getNextImplicitBindingOrderID(); + IntegerLiteral *CounterId = + IntegerLiteral::Create(AST, llvm::APInt(UIntTySize, CounterOrderID), + AST.UnsignedIntTy, SourceLocation()); + Args.push_back(CounterId); + } + // Make sure the create method template is instantiated and emitted. if (!CreateMethod->isDefined() && CreateMethod->isTemplateInstantiation()) SemaRef.InstantiateFunctionDefinition(VD->getLocation(), CreateMethod, @@ -3899,20 +3961,24 @@ bool SemaHLSL::initGlobalResourceArrayDecl(VarDecl *VD) { ASTContext &AST = SemaRef.getASTContext(); QualType ResElementTy = AST.getBaseElementType(VD->getType()); CXXRecordDecl *ResourceDecl = ResElementTy->getAsCXXRecordDecl(); - - HLSLResourceBindingAttr *RBA = VD->getAttr<HLSLResourceBindingAttr>(); - HLSLVkBindingAttr *VkBinding = VD->getAttr<HLSLVkBindingAttr>(); CXXMethodDecl *CreateMethod = nullptr; - if (VkBinding || (RBA && RBA->hasRegisterSlot())) + bool HasCounter = hasCounterHandle(ResourceDecl); + ResourceBindingAttrs ResourceAttrs(VD); + if (ResourceAttrs.isExplicit()) // Resource has explicit binding. - CreateMethod = lookupMethod(SemaRef, ResourceDecl, "__createFromBinding", - VD->getLocation()); - else - // Resource has implicit binding. CreateMethod = - lookupMethod(SemaRef, ResourceDecl, "__createFromImplicitBinding", + lookupMethod(SemaRef, ResourceDecl, + HasCounter ? "__createFromBindingWithImplicitCounter" + : "__createFromBinding", VD->getLocation()); + else + // Resource has implicit binding. + CreateMethod = lookupMethod( + SemaRef, ResourceDecl, + HasCounter ? "__createFromImplicitBindingWithImplicitCounter" + : "__createFromImplicitBinding", + VD->getLocation()); if (!CreateMethod) return false; diff --git a/clang/lib/Sema/SemaOpenACC.cpp b/clang/lib/Sema/SemaOpenACC.cpp index 8471f02..4824b5a 100644 --- a/clang/lib/Sema/SemaOpenACC.cpp +++ b/clang/lib/Sema/SemaOpenACC.cpp @@ -2946,5 +2946,5 @@ OpenACCReductionRecipe SemaOpenACC::CreateReductionInitRecipe( AllocaDecl->setInit(Init.get()); AllocaDecl->setInitStyle(VarDecl::CallInit); } - return OpenACCReductionRecipe(AllocaDecl); + return OpenACCReductionRecipe(AllocaDecl, {}); } diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 8d32ef6..8339bb1 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -1892,14 +1892,7 @@ bool Sema::TryFunctionConversion(QualType FromType, QualType ToType, return Changed; } -bool Sema::IsFunctionConversion(QualType FromType, QualType ToType, - bool *DiscardingCFIUncheckedCallee, - bool *AddingCFIUncheckedCallee) const { - if (DiscardingCFIUncheckedCallee) - *DiscardingCFIUncheckedCallee = false; - if (AddingCFIUncheckedCallee) - *AddingCFIUncheckedCallee = false; - +bool Sema::IsFunctionConversion(QualType FromType, QualType ToType) const { if (Context.hasSameUnqualifiedType(FromType, ToType)) return false; @@ -1958,25 +1951,14 @@ bool Sema::IsFunctionConversion(QualType FromType, QualType ToType, const auto *ToFPT = dyn_cast<FunctionProtoType>(ToFn); if (FromFPT && ToFPT) { - if (FromFPT->hasCFIUncheckedCallee() && !ToFPT->hasCFIUncheckedCallee()) { - QualType NewTy = Context.getFunctionType( - FromFPT->getReturnType(), FromFPT->getParamTypes(), - FromFPT->getExtProtoInfo().withCFIUncheckedCallee(false)); - FromFPT = cast<FunctionProtoType>(NewTy.getTypePtr()); - FromFn = FromFPT; - Changed = true; - if (DiscardingCFIUncheckedCallee) - *DiscardingCFIUncheckedCallee = true; - } else if (!FromFPT->hasCFIUncheckedCallee() && - ToFPT->hasCFIUncheckedCallee()) { + if (FromFPT->hasCFIUncheckedCallee() != ToFPT->hasCFIUncheckedCallee()) { QualType NewTy = Context.getFunctionType( FromFPT->getReturnType(), FromFPT->getParamTypes(), - FromFPT->getExtProtoInfo().withCFIUncheckedCallee(true)); + FromFPT->getExtProtoInfo().withCFIUncheckedCallee( + ToFPT->hasCFIUncheckedCallee())); FromFPT = cast<FunctionProtoType>(NewTy.getTypePtr()); FromFn = FromFPT; Changed = true; - if (AddingCFIUncheckedCallee) - *AddingCFIUncheckedCallee = true; } } @@ -2007,11 +1989,7 @@ bool Sema::IsFunctionConversion(QualType FromType, QualType ToType, Changed = true; } - // For C, when called from checkPointerTypesForAssignment, - // we need to not alter FromFn, or else even an innocuous cast - // like dropping effects will fail. In C++ however we do want to - // alter FromFn (because of the way PerformImplicitConversion works). - if (Context.hasAnyFunctionEffects() && getLangOpts().CPlusPlus) { + if (Context.hasAnyFunctionEffects()) { FromFPT = cast<FunctionProtoType>(FromFn); // in case FromFn changed above // Transparently add/drop effects; here we are concerned with |