aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/DeclSpec.cpp3
-rw-r--r--clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp80
-rw-r--r--clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h2
-rw-r--r--clang/lib/Sema/HLSLExternalSemaSource.cpp11
-rw-r--r--clang/lib/Sema/SemaDecl.cpp136
-rw-r--r--clang/lib/Sema/SemaHLSL.cpp18
-rw-r--r--clang/lib/Sema/SemaRISCV.cpp3
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiate.cpp6
8 files changed, 191 insertions, 68 deletions
diff --git a/clang/lib/Sema/DeclSpec.cpp b/clang/lib/Sema/DeclSpec.cpp
index 184d31e..9da3d0d 100644
--- a/clang/lib/Sema/DeclSpec.cpp
+++ b/clang/lib/Sema/DeclSpec.cpp
@@ -1369,7 +1369,8 @@ void DeclSpec::Finish(Sema &S, const PrintingPolicy &Policy) {
if (S.getLangOpts().C23 &&
getConstexprSpecifier() == ConstexprSpecKind::Constexpr &&
- StorageClassSpec == SCS_extern) {
+ getTypeSpecType() != TST_unspecified &&
+ (StorageClassSpec == SCS_extern || StorageClassSpec == SCS_auto)) {
S.Diag(ConstexprLoc, diag::err_invalid_decl_spec_combination)
<< DeclSpec::getSpecifierName(getStorageClassSpec())
<< SourceRange(getStorageClassSpecLoc());
diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
index 40c318a..066acf6 100644
--- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
+++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
@@ -57,6 +57,29 @@ CXXConstructorDecl *lookupCopyConstructor(QualType ResTy) {
return CD;
return nullptr;
}
+
+ParameterABI
+convertParamModifierToParamABI(HLSLParamModifierAttr::Spelling Modifier) {
+ assert(Modifier != HLSLParamModifierAttr::Spelling::Keyword_in &&
+ "HLSL 'in' parameters modifier cannot be converted to ParameterABI");
+ switch (Modifier) {
+ case HLSLParamModifierAttr::Spelling::Keyword_out:
+ return ParameterABI::HLSLOut;
+ case HLSLParamModifierAttr::Spelling::Keyword_inout:
+ return ParameterABI::HLSLInOut;
+ default:
+ llvm_unreachable("Invalid HLSL parameter modifier");
+ }
+}
+
+QualType getInoutParameterType(ASTContext &AST, QualType Ty) {
+ assert(!Ty->isReferenceType() &&
+ "Pointer and reference types cannot be inout or out parameters");
+ Ty = AST.getLValueReferenceType(Ty);
+ Ty.addRestrict();
+ return Ty;
+}
+
} // namespace
// Builder for template arguments of builtin types. Used internally
@@ -430,19 +453,36 @@ BuiltinTypeMethodBuilder::addParam(StringRef Name, QualType Ty,
void BuiltinTypeMethodBuilder::createDecl() {
assert(Method == nullptr && "Method or constructor is already created");
- // create method or constructor type
+ // create function prototype
ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
SmallVector<QualType> ParamTypes;
- for (Param &MP : Params)
+ SmallVector<FunctionType::ExtParameterInfo> ParamExtInfos(Params.size());
+ uint32_t ArgIndex = 0;
+
+ // Create function prototype.
+ bool UseParamExtInfo = false;
+ for (Param &MP : Params) {
+ if (MP.Modifier != HLSLParamModifierAttr::Keyword_in) {
+ UseParamExtInfo = true;
+ FunctionType::ExtParameterInfo &PI = ParamExtInfos[ArgIndex];
+ ParamExtInfos[ArgIndex] =
+ PI.withABI(convertParamModifierToParamABI(MP.Modifier));
+ if (!MP.Ty->isDependentType())
+ MP.Ty = getInoutParameterType(AST, MP.Ty);
+ }
ParamTypes.emplace_back(MP.Ty);
+ ++ArgIndex;
+ }
FunctionProtoType::ExtProtoInfo ExtInfo;
+ if (UseParamExtInfo)
+ ExtInfo.ExtParameterInfos = ParamExtInfos.data();
if (IsConst)
ExtInfo.TypeQuals.addConst();
QualType FuncTy = AST.getFunctionType(ReturnTy, ParamTypes, ExtInfo);
- // create method or constructor decl
+ // Create method or constructor declaration.
auto *TSInfo = AST.getTrivialTypeSourceInfo(FuncTy, SourceLocation());
DeclarationNameInfo NameInfo = DeclarationNameInfo(Name, SourceLocation());
if (IsCtor)
@@ -455,7 +495,7 @@ void BuiltinTypeMethodBuilder::createDecl() {
AST, DeclBuilder.Record, SourceLocation(), NameInfo, FuncTy, TSInfo, SC,
false, false, ConstexprSpecKind::Unspecified, SourceLocation());
- // create params & set them to the function prototype
+ // Create params & set them to the method/constructor and function prototype.
SmallVector<ParmVarDecl *> ParmDecls;
unsigned CurScopeDepth = DeclBuilder.SemaRef.getCurScope()->getDepth();
auto FnProtoLoc =
@@ -1258,5 +1298,37 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addConsumeMethod() {
.finalize();
}
+BuiltinTypeDeclBuilder &
+BuiltinTypeDeclBuilder::addGetDimensionsMethodForBuffer() {
+ using PH = BuiltinTypeMethodBuilder::PlaceHolder;
+ ASTContext &AST = SemaRef.getASTContext();
+ QualType UIntTy = AST.UnsignedIntTy;
+
+ QualType HandleTy = getResourceHandleField()->getType();
+ auto *AttrResTy = cast<HLSLAttributedResourceType>(HandleTy.getTypePtr());
+
+ // Structured buffers except {RW}ByteAddressBuffer have overload
+ // GetDimensions(out uint numStructs, out uint stride).
+ if (AttrResTy->getAttrs().RawBuffer &&
+ AttrResTy->getContainedType() != AST.Char8Ty) {
+ return BuiltinTypeMethodBuilder(*this, "GetDimensions", AST.VoidTy)
+ .addParam("numStructs", UIntTy, HLSLParamModifierAttr::Keyword_out)
+ .addParam("stride", UIntTy, HLSLParamModifierAttr::Keyword_out)
+ .callBuiltin("__builtin_hlsl_resource_getdimensions_x", QualType(),
+ PH::Handle, PH::_0)
+ .callBuiltin("__builtin_hlsl_resource_getstride", QualType(),
+ PH::Handle, PH::_1)
+ .finalize();
+ }
+
+ // Typed buffers and {RW}ByteAddressBuffer have overload
+ // GetDimensions(out uint dim).
+ return BuiltinTypeMethodBuilder(*this, "GetDimensions", AST.VoidTy)
+ .addParam("dim", UIntTy, HLSLParamModifierAttr::Keyword_out)
+ .callBuiltin("__builtin_hlsl_resource_getdimensions_x", QualType(),
+ PH::Handle, PH::_0)
+ .finalize();
+}
+
} // namespace hlsl
} // namespace clang
diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
index 86cbd10..95e3a6c 100644
--- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
+++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
@@ -94,6 +94,8 @@ public:
BuiltinTypeDeclBuilder &addAppendMethod();
BuiltinTypeDeclBuilder &addConsumeMethod();
+ BuiltinTypeDeclBuilder &addGetDimensionsMethodForBuffer();
+
private:
BuiltinTypeDeclBuilder &addCreateFromBinding();
BuiltinTypeDeclBuilder &addCreateFromImplicitBinding();
diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp
index f28a037..6be84f1 100644
--- a/clang/lib/Sema/HLSLExternalSemaSource.cpp
+++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp
@@ -380,6 +380,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
/*RawBuffer=*/false, /*HasCounter=*/false)
.addArraySubscriptOperators()
.addLoadMethods()
+ .addGetDimensionsMethodForBuffer()
.completeDefinition();
});
@@ -392,6 +393,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
/*RawBuffer=*/false, /*HasCounter=*/false)
.addArraySubscriptOperators()
.addLoadMethods()
+ .addGetDimensionsMethodForBuffer()
.completeDefinition();
});
@@ -404,6 +406,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
/*RawBuffer=*/false, /*HasCounter=*/false)
.addArraySubscriptOperators()
.addLoadMethods()
+ .addGetDimensionsMethodForBuffer()
.completeDefinition();
});
@@ -415,6 +418,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
/*RawBuffer=*/true, /*HasCounter=*/false)
.addArraySubscriptOperators()
.addLoadMethods()
+ .addGetDimensionsMethodForBuffer()
.completeDefinition();
});
@@ -428,6 +432,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
.addLoadMethods()
.addIncrementCounterMethod()
.addDecrementCounterMethod()
+ .addGetDimensionsMethodForBuffer()
.completeDefinition();
});
@@ -439,6 +444,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, /*IsROV=*/false,
/*RawBuffer=*/true, /*HasCounter=*/true)
.addAppendMethod()
+ .addGetDimensionsMethodForBuffer()
.completeDefinition();
});
@@ -450,6 +456,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, /*IsROV=*/false,
/*RawBuffer=*/true, /*HasCounter=*/true)
.addConsumeMethod()
+ .addGetDimensionsMethodForBuffer()
.completeDefinition();
});
@@ -464,6 +471,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
.addLoadMethods()
.addIncrementCounterMethod()
.addDecrementCounterMethod()
+ .addGetDimensionsMethodForBuffer()
.completeDefinition();
});
@@ -472,6 +480,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
onCompletion(Decl, [this](CXXRecordDecl *Decl) {
setupBufferType(Decl, *SemaPtr, ResourceClass::SRV, /*IsROV=*/false,
/*RawBuffer=*/true, /*HasCounter=*/false)
+ .addGetDimensionsMethodForBuffer()
.completeDefinition();
});
Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RWByteAddressBuffer")
@@ -479,6 +488,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
onCompletion(Decl, [this](CXXRecordDecl *Decl) {
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, /*IsROV=*/false,
/*RawBuffer=*/true, /*HasCounter=*/false)
+ .addGetDimensionsMethodForBuffer()
.completeDefinition();
});
Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace,
@@ -487,6 +497,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
onCompletion(Decl, [this](CXXRecordDecl *Decl) {
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, /*IsROV=*/true,
/*RawBuffer=*/true, /*HasCounter=*/false)
+ .addGetDimensionsMethodForBuffer()
.completeDefinition();
});
}
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 04d46d6..fc3aabf 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -7640,6 +7640,58 @@ static bool isMainVar(DeclarationName Name, VarDecl *VD) {
VD->isExternC());
}
+void Sema::CheckAsmLabel(Scope *S, Expr *E, StorageClass SC,
+ TypeSourceInfo *TInfo, VarDecl *NewVD) {
+
+ // Quickly return if the function does not have an `asm` attribute.
+ if (E == nullptr)
+ return;
+
+ // The parser guarantees this is a string.
+ StringLiteral *SE = cast<StringLiteral>(E);
+ StringRef Label = SE->getString();
+ QualType R = TInfo->getType();
+ if (S->getFnParent() != nullptr) {
+ switch (SC) {
+ case SC_None:
+ case SC_Auto:
+ Diag(E->getExprLoc(), diag::warn_asm_label_on_auto_decl) << Label;
+ break;
+ case SC_Register:
+ // Local Named register
+ if (!Context.getTargetInfo().isValidGCCRegisterName(Label) &&
+ DeclAttrsMatchCUDAMode(getLangOpts(), getCurFunctionDecl()))
+ Diag(E->getExprLoc(), diag::err_asm_unknown_register_name) << Label;
+ break;
+ case SC_Static:
+ case SC_Extern:
+ case SC_PrivateExtern:
+ break;
+ }
+ } else if (SC == SC_Register) {
+ // Global Named register
+ if (DeclAttrsMatchCUDAMode(getLangOpts(), NewVD)) {
+ const auto &TI = Context.getTargetInfo();
+ bool HasSizeMismatch;
+
+ if (!TI.isValidGCCRegisterName(Label))
+ Diag(E->getExprLoc(), diag::err_asm_unknown_register_name) << Label;
+ else if (!TI.validateGlobalRegisterVariable(Label, Context.getTypeSize(R),
+ HasSizeMismatch))
+ Diag(E->getExprLoc(), diag::err_asm_invalid_global_var_reg) << Label;
+ else if (HasSizeMismatch)
+ Diag(E->getExprLoc(), diag::err_asm_register_size_mismatch) << Label;
+ }
+
+ if (!R->isIntegralType(Context) && !R->isPointerType()) {
+ Diag(TInfo->getTypeLoc().getBeginLoc(),
+ diag::err_asm_unsupported_register_type)
+ << TInfo->getTypeLoc().getSourceRange();
+ NewVD->setInvalidDecl(true);
+ }
+ }
+}
+
NamedDecl *Sema::ActOnVariableDeclarator(
Scope *S, Declarator &D, DeclContext *DC, TypeSourceInfo *TInfo,
LookupResult &Previous, MultiTemplateParamsArg TemplateParamLists,
@@ -8124,6 +8176,26 @@ NamedDecl *Sema::ActOnVariableDeclarator(
}
}
+ if (Expr *E = D.getAsmLabel()) {
+ // The parser guarantees this is a string.
+ StringLiteral *SE = cast<StringLiteral>(E);
+ StringRef Label = SE->getString();
+
+ // Insert the asm attribute.
+ NewVD->addAttr(AsmLabelAttr::Create(Context, Label, SE->getStrTokenLoc(0)));
+ } else if (!ExtnameUndeclaredIdentifiers.empty()) {
+ llvm::DenseMap<IdentifierInfo *, AsmLabelAttr *>::iterator I =
+ ExtnameUndeclaredIdentifiers.find(NewVD->getIdentifier());
+ if (I != ExtnameUndeclaredIdentifiers.end()) {
+ if (isDeclExternC(NewVD)) {
+ NewVD->addAttr(I->second);
+ ExtnameUndeclaredIdentifiers.erase(I);
+ } else
+ Diag(NewVD->getLocation(), diag::warn_redefine_extname_not_applied)
+ << /*Variable*/ 1 << NewVD;
+ }
+ }
+
// Handle attributes prior to checking for duplicates in MergeVarDecl
ProcessDeclAttributes(S, NewVD, D);
@@ -8174,65 +8246,11 @@ NamedDecl *Sema::ActOnVariableDeclarator(
if (getLangOpts().ObjCAutoRefCount && ObjC().inferObjCARCLifetime(NewVD))
NewVD->setInvalidDecl();
- // Handle GNU asm-label extension (encoded as an attribute).
- if (Expr *E = D.getAsmLabel()) {
- // The parser guarantees this is a string.
- StringLiteral *SE = cast<StringLiteral>(E);
- StringRef Label = SE->getString();
- if (S->getFnParent() != nullptr) {
- switch (SC) {
- case SC_None:
- case SC_Auto:
- Diag(E->getExprLoc(), diag::warn_asm_label_on_auto_decl) << Label;
- break;
- case SC_Register:
- // Local Named register
- if (!Context.getTargetInfo().isValidGCCRegisterName(Label) &&
- DeclAttrsMatchCUDAMode(getLangOpts(), getCurFunctionDecl()))
- Diag(E->getExprLoc(), diag::err_asm_unknown_register_name) << Label;
- break;
- case SC_Static:
- case SC_Extern:
- case SC_PrivateExtern:
- break;
- }
- } else if (SC == SC_Register) {
- // Global Named register
- if (DeclAttrsMatchCUDAMode(getLangOpts(), NewVD)) {
- const auto &TI = Context.getTargetInfo();
- bool HasSizeMismatch;
-
- if (!TI.isValidGCCRegisterName(Label))
- Diag(E->getExprLoc(), diag::err_asm_unknown_register_name) << Label;
- else if (!TI.validateGlobalRegisterVariable(Label,
- Context.getTypeSize(R),
- HasSizeMismatch))
- Diag(E->getExprLoc(), diag::err_asm_invalid_global_var_reg) << Label;
- else if (HasSizeMismatch)
- Diag(E->getExprLoc(), diag::err_asm_register_size_mismatch) << Label;
- }
-
- if (!R->isIntegralType(Context) && !R->isPointerType()) {
- Diag(TInfo->getTypeLoc().getBeginLoc(),
- diag::err_asm_unsupported_register_type)
- << TInfo->getTypeLoc().getSourceRange();
- NewVD->setInvalidDecl(true);
- }
- }
-
- NewVD->addAttr(AsmLabelAttr::Create(Context, Label, SE->getStrTokenLoc(0)));
- } else if (!ExtnameUndeclaredIdentifiers.empty()) {
- llvm::DenseMap<IdentifierInfo*,AsmLabelAttr*>::iterator I =
- ExtnameUndeclaredIdentifiers.find(NewVD->getIdentifier());
- if (I != ExtnameUndeclaredIdentifiers.end()) {
- if (isDeclExternC(NewVD)) {
- NewVD->addAttr(I->second);
- ExtnameUndeclaredIdentifiers.erase(I);
- } else
- Diag(NewVD->getLocation(), diag::warn_redefine_extname_not_applied)
- << /*Variable*/1 << NewVD;
- }
- }
+ // Check the ASM label here, as we need to know all other attributes of the
+ // Decl first. Otherwise, we can't know if the asm label refers to the
+ // host or device in a CUDA context. The device has other registers than
+ // host and we must know where the function will be placed.
+ CheckAsmLabel(S, D.getAsmLabel(), SC, TInfo, NewVD);
// Find the shadowed declaration before filtering for scope.
NamedDecl *ShadowedDecl = D.getCXXScopeSpec().isEmpty()
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index f347066..5b3e89f 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -3006,6 +3006,24 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
TheCall->setType(CounterHandleTy);
break;
}
+ case Builtin::BI__builtin_hlsl_resource_getdimensions_x: {
+ ASTContext &AST = SemaRef.getASTContext();
+ if (SemaRef.checkArgCount(TheCall, 2) ||
+ CheckResourceHandle(&SemaRef, TheCall, 0) ||
+ CheckArgTypeMatches(&SemaRef, TheCall->getArg(1), AST.UnsignedIntTy) ||
+ CheckModifiableLValue(&SemaRef, TheCall, 1))
+ return true;
+ break;
+ }
+ case Builtin::BI__builtin_hlsl_resource_getstride: {
+ ASTContext &AST = SemaRef.getASTContext();
+ if (SemaRef.checkArgCount(TheCall, 2) ||
+ CheckResourceHandle(&SemaRef, TheCall, 0) ||
+ CheckArgTypeMatches(&SemaRef, TheCall->getArg(1), AST.UnsignedIntTy) ||
+ CheckModifiableLValue(&SemaRef, TheCall, 1))
+ return true;
+ break;
+ }
case Builtin::BI__builtin_hlsl_and:
case Builtin::BI__builtin_hlsl_or: {
if (SemaRef.checkArgCount(TheCall, 2))
diff --git a/clang/lib/Sema/SemaRISCV.cpp b/clang/lib/Sema/SemaRISCV.cpp
index 3ba93ff9..c5ef0d5 100644
--- a/clang/lib/Sema/SemaRISCV.cpp
+++ b/clang/lib/Sema/SemaRISCV.cpp
@@ -1464,7 +1464,8 @@ void SemaRISCV::checkRVVTypeSupport(QualType Ty, SourceLocation Loc, Decl *D,
}
else if (Info.ElementType->isBFloat16Type() &&
!FeatureMap.lookup("zvfbfmin") &&
- !FeatureMap.lookup("xandesvbfhcvt"))
+ !FeatureMap.lookup("xandesvbfhcvt") &&
+ !FeatureMap.lookup("experimental-zvfbfa"))
if (DeclareAndesVectorBuiltins) {
Diag(Loc, diag::err_riscv_type_requires_extension, D)
<< Ty << "zvfbfmin or xandesvbfhcvt";
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index ca7e3b2..038f396 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -2864,9 +2864,9 @@ TemplateInstantiator::TransformNestedRequirement(
TemplateArgs, Constraint->getSourceRange(), Satisfaction,
/*TopLevelConceptId=*/nullptr, &NewConstraint);
- assert(!Success || !Trap.hasErrorOccurred() &&
- "Substitution failures must be handled "
- "by CheckConstraintSatisfaction.");
+ assert((!Success || !Trap.hasErrorOccurred()) &&
+ "Substitution failures must be handled "
+ "by CheckConstraintSatisfaction.");
}
if (!Success || Satisfaction.HasSubstitutionFailure())