aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/AnalysisBasedWarnings.cpp11
-rw-r--r--clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp141
-rw-r--r--clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h7
-rw-r--r--clang/lib/Sema/HLSLExternalSemaSource.cpp3
-rw-r--r--clang/lib/Sema/SemaARM.cpp4
-rw-r--r--clang/lib/Sema/SemaExpr.cpp63
-rw-r--r--clang/lib/Sema/SemaHLSL.cpp112
-rw-r--r--clang/lib/Sema/SemaOpenACC.cpp2
-rw-r--r--clang/lib/Sema/SemaOverload.cpp32
-rw-r--r--clang/lib/Sema/SemaTemplate.cpp2
-rw-r--r--clang/lib/Sema/TreeTransform.h17
11 files changed, 297 insertions, 97 deletions
diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp
index 8606227..e9ca8ce 100644
--- a/clang/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp
@@ -2605,6 +2605,17 @@ public:
#endif
}
+ void handleUnsafeUniquePtrArrayAccess(const DynTypedNode &Node,
+ bool IsRelatedToDecl,
+ ASTContext &Ctx) override {
+ SourceLocation Loc;
+ std::string Message;
+
+ Loc = Node.get<Stmt>()->getBeginLoc();
+ S.Diag(Loc, diag::warn_unsafe_buffer_usage_unique_ptr_array_access)
+ << Node.getSourceRange();
+ }
+
bool isSafeBufferOptOut(const SourceLocation &Loc) const override {
return S.PP.isSafeBufferOptOut(S.getSourceManager(), Loc);
}
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/SemaARM.cpp b/clang/lib/Sema/SemaARM.cpp
index e09c352..1c7c832d 100644
--- a/clang/lib/Sema/SemaARM.cpp
+++ b/clang/lib/Sema/SemaARM.cpp
@@ -603,8 +603,8 @@ static bool checkArmStreamingBuiltin(Sema &S, CallExpr *TheCall,
bool SatisfiesSME = Builtin::evaluateRequiredTargetFeatures(
StreamingBuiltinGuard, CallerFeatures);
- if ((SatisfiesSVE && SatisfiesSME) ||
- (SatisfiesSVE && FnType == SemaARM::ArmStreamingCompatible))
+ if (SatisfiesSVE && SatisfiesSME)
+ // Function type is irrelevant for streaming-agnostic builtins.
return false;
else if (SatisfiesSVE)
BuiltinType = SemaARM::ArmNonStreaming;
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
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 419f3e1..3a6ff99 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -318,7 +318,7 @@ TemplateNameKind Sema::isTemplateName(Scope *S,
}
}
- if (isPackProducingBuiltinTemplateName(Template) &&
+ if (isPackProducingBuiltinTemplateName(Template) && S &&
S->getTemplateParamParent() == nullptr)
Diag(Name.getBeginLoc(), diag::err_builtin_pack_outside_template) << TName;
// Recover by returning the template, even though we would never be able to
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 51b55b8..940324b 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -16364,16 +16364,21 @@ ExprResult TreeTransform<Derived>::TransformSubstNonTypeTemplateParmExpr(
AssociatedDecl == E->getAssociatedDecl())
return E;
+ auto getParamAndType = [Index = E->getIndex()](Decl *AssociatedDecl)
+ -> std::tuple<NonTypeTemplateParmDecl *, QualType> {
+ auto [PDecl, Arg] = getReplacedTemplateParameter(AssociatedDecl, Index);
+ auto *Param = cast<NonTypeTemplateParmDecl>(PDecl);
+ return {Param, Arg.isNull() ? Param->getType()
+ : Arg.getNonTypeTemplateArgumentType()};
+ };
+
// If the replacement expression did not change, and the parameter type
// did not change, we can skip the semantic action because it would
// produce the same result anyway.
- auto *Param = cast<NonTypeTemplateParmDecl>(
- getReplacedTemplateParameterList(AssociatedDecl)
- ->asArray()[E->getIndex()]);
- if (QualType ParamType = Param->getType();
- !SemaRef.Context.hasSameType(ParamType, E->getParameter()->getType()) ||
+ if (auto [Param, ParamType] = getParamAndType(AssociatedDecl);
+ !SemaRef.Context.hasSameType(
+ ParamType, std::get<1>(getParamAndType(E->getAssociatedDecl()))) ||
Replacement.get() != OrigReplacement) {
-
// When transforming the replacement expression previously, all Sema
// specific annotations, such as implicit casts, are discarded. Calling the
// corresponding sema action is necessary to recover those. Otherwise,