15#include "clang/AST/Attrs.inc"
38#include "llvm/ADT/ArrayRef.h"
39#include "llvm/ADT/STLExtras.h"
40#include "llvm/ADT/SmallVector.h"
41#include "llvm/ADT/StringExtras.h"
42#include "llvm/ADT/StringRef.h"
43#include "llvm/ADT/Twine.h"
44#include "llvm/Frontend/HLSL/HLSLBinding.h"
45#include "llvm/Frontend/HLSL/RootSignatureValidations.h"
46#include "llvm/Support/Casting.h"
47#include "llvm/Support/DXILABI.h"
48#include "llvm/Support/ErrorHandling.h"
49#include "llvm/Support/FormatVariadic.h"
50#include "llvm/TargetParser/Triple.h"
65 case ResourceClass::SRV:
66 return RegisterType::SRV;
67 case ResourceClass::UAV:
68 return RegisterType::UAV;
69 case ResourceClass::CBuffer:
70 return RegisterType::CBuffer;
71 case ResourceClass::Sampler:
72 return RegisterType::Sampler;
74 llvm_unreachable(
"unexpected ResourceClass value");
84 assert(RT !=
nullptr);
88 *RT = RegisterType::SRV;
92 *RT = RegisterType::UAV;
96 *RT = RegisterType::CBuffer;
100 *RT = RegisterType::Sampler;
104 *RT = RegisterType::C;
108 *RT = RegisterType::I;
117 case RegisterType::SRV:
118 return ResourceClass::SRV;
119 case RegisterType::UAV:
120 return ResourceClass::UAV;
121 case RegisterType::CBuffer:
122 return ResourceClass::CBuffer;
123 case RegisterType::Sampler:
124 return ResourceClass::Sampler;
125 case RegisterType::C:
126 case RegisterType::I:
130 llvm_unreachable(
"unexpected RegisterType value");
134 const auto *BT = dyn_cast<BuiltinType>(
Type);
138 return Builtin::BI__builtin_get_spirv_spec_constant_int;
141 switch (BT->getKind()) {
142 case BuiltinType::Bool:
143 return Builtin::BI__builtin_get_spirv_spec_constant_bool;
144 case BuiltinType::Short:
145 return Builtin::BI__builtin_get_spirv_spec_constant_short;
146 case BuiltinType::Int:
147 return Builtin::BI__builtin_get_spirv_spec_constant_int;
148 case BuiltinType::LongLong:
149 return Builtin::BI__builtin_get_spirv_spec_constant_longlong;
150 case BuiltinType::UShort:
151 return Builtin::BI__builtin_get_spirv_spec_constant_ushort;
152 case BuiltinType::UInt:
153 return Builtin::BI__builtin_get_spirv_spec_constant_uint;
154 case BuiltinType::ULongLong:
155 return Builtin::BI__builtin_get_spirv_spec_constant_ulonglong;
156 case BuiltinType::Half:
157 return Builtin::BI__builtin_get_spirv_spec_constant_half;
158 case BuiltinType::Float:
159 return Builtin::BI__builtin_get_spirv_spec_constant_float;
160 case BuiltinType::Double:
161 return Builtin::BI__builtin_get_spirv_spec_constant_double;
168 ResourceClass ResClass) {
170 "DeclBindingInfo already added");
176 DeclToBindingListIndex.try_emplace(VD, BindingsList.size());
177 return &BindingsList.emplace_back(VD, ResClass);
181 ResourceClass ResClass) {
182 auto Entry = DeclToBindingListIndex.find(VD);
183 if (Entry != DeclToBindingListIndex.end()) {
184 for (
unsigned Index = Entry->getSecond();
185 Index < BindingsList.size() && BindingsList[Index].Decl == VD;
187 if (BindingsList[Index].ResClass == ResClass)
188 return &BindingsList[Index];
195 return DeclToBindingListIndex.contains(VD);
207 getASTContext(), LexicalParent, CBuffer, KwLoc, Ident, IdentLoc, LBrace);
210 auto RC = CBuffer ? llvm::hlsl::ResourceClass::CBuffer
211 : llvm::hlsl::ResourceClass::SRV;
223 if (
T->isArrayType() ||
T->isStructureType())
230 assert(Context.getTypeSize(
T) <= 64 &&
231 "Scalar bit widths larger than 64 not supported");
234 return Context.getTypeSize(
T) / 8;
241 constexpr unsigned CBufferAlign = 16;
242 if (
const auto *RD =
T->getAsRecordDecl()) {
244 for (
const FieldDecl *Field : RD->fields()) {
251 unsigned AlignSize = llvm::alignTo(Size, FieldAlign);
252 if ((AlignSize % CBufferAlign) + FieldSize > CBufferAlign) {
253 FieldAlign = CBufferAlign;
256 Size = llvm::alignTo(Size, FieldAlign);
263 unsigned ElementCount = AT->getSize().getZExtValue();
264 if (ElementCount == 0)
267 unsigned ElementSize =
269 unsigned AlignedElementSize = llvm::alignTo(ElementSize, CBufferAlign);
270 return AlignedElementSize * (ElementCount - 1) + ElementSize;
274 unsigned ElementCount = VT->getNumElements();
275 unsigned ElementSize =
277 return ElementSize * ElementCount;
280 return Context.getTypeSize(
T) / 8;
291 bool HasPackOffset =
false;
292 bool HasNonPackOffset =
false;
294 VarDecl *Var = dyn_cast<VarDecl>(Field);
297 if (Field->hasAttr<HLSLPackOffsetAttr>()) {
298 PackOffsetVec.emplace_back(Var, Field->
getAttr<HLSLPackOffsetAttr>());
299 HasPackOffset =
true;
301 HasNonPackOffset =
true;
308 if (HasNonPackOffset)
315 std::sort(PackOffsetVec.begin(), PackOffsetVec.end(),
316 [](
const std::pair<VarDecl *, HLSLPackOffsetAttr *> &LHS,
317 const std::pair<VarDecl *, HLSLPackOffsetAttr *> &RHS) {
318 return LHS.second->getOffsetInBytes() <
319 RHS.second->getOffsetInBytes();
321 for (
unsigned i = 0; i < PackOffsetVec.size() - 1; i++) {
322 VarDecl *Var = PackOffsetVec[i].first;
323 HLSLPackOffsetAttr *
Attr = PackOffsetVec[i].second;
325 unsigned Begin =
Attr->getOffsetInBytes();
326 unsigned End = Begin + Size;
327 unsigned NextBegin = PackOffsetVec[i + 1].second->getOffsetInBytes();
328 if (End > NextBegin) {
329 VarDecl *NextVar = PackOffsetVec[i + 1].first;
341 CAT = dyn_cast<ConstantArrayType>(
343 return CAT !=
nullptr;
351static const HLSLAttributedResourceType *
354 "expected array of resource records");
356 while (
const ArrayType *AT = dyn_cast<ArrayType>(Ty))
358 return HLSLAttributedResourceType::findHandleTypeOnResource(Ty);
370 return RD->isEmpty();
399 Base.getType()->castAsCXXRecordDecl()))
410 assert(RD ==
nullptr &&
411 "there should be at most 1 record by a given name in a scope");
428 Name.append(NameBaseII->
getName());
435 size_t NameLength = Name.size();
444 Name.append(llvm::Twine(suffix).str());
445 II = &AST.
Idents.
get(Name, tok::TokenKind::identifier);
452 Name.truncate(NameLength);
493 "struct is already HLSL buffer compatible");
507 LS->
addAttr(PackedAttr::CreateImplicit(AST));
511 if (
unsigned NumBases = StructDecl->
getNumBases()) {
512 assert(NumBases == 1 &&
"HLSL supports only one base type");
562 LS->
addAttr(PackedAttr::CreateImplicit(AST));
567 VarDecl *VD = dyn_cast<VarDecl>(D);
587 uint32_t ImplicitBindingOrderID) {
589 HLSLResourceBindingAttr::CreateImplicit(S.
getASTContext(),
"",
"0", {});
590 Attr->setBinding(RT, std::nullopt, 0);
591 Attr->setImplicitBindingOrderID(ImplicitBindingOrderID);
598 BufDecl->setRBraceLoc(RBrace);
610 uint32_t OrderID = getNextImplicitBindingOrderID();
615 BufDecl->isCBuffer() ? RegisterType::CBuffer
625 int X,
int Y,
int Z) {
626 if (HLSLNumThreadsAttr *NT = D->
getAttr<HLSLNumThreadsAttr>()) {
627 if (NT->getX() !=
X || NT->getY() != Y || NT->getZ() != Z) {
628 Diag(NT->getLocation(), diag::err_hlsl_attribute_param_mismatch) << AL;
629 Diag(AL.
getLoc(), diag::note_conflicting_attribute);
639 int Min,
int Max,
int Preferred,
640 int SpelledArgsCount) {
641 if (HLSLWaveSizeAttr *WS = D->
getAttr<HLSLWaveSizeAttr>()) {
642 if (WS->getMin() !=
Min || WS->getMax() !=
Max ||
643 WS->getPreferred() != Preferred ||
644 WS->getSpelledArgsCount() != SpelledArgsCount) {
645 Diag(WS->getLocation(), diag::err_hlsl_attribute_param_mismatch) << AL;
646 Diag(AL.
getLoc(), diag::note_conflicting_attribute);
652 Result->setSpelledArgsCount(SpelledArgsCount);
656HLSLVkConstantIdAttr *
662 Diag(AL.
getLoc(), diag::warn_attribute_ignored) << AL;
670 Diag(VD->getLocation(), diag::err_specialization_const);
674 if (!VD->getType().isConstQualified()) {
675 Diag(VD->getLocation(), diag::err_specialization_const);
679 if (HLSLVkConstantIdAttr *CI = D->
getAttr<HLSLVkConstantIdAttr>()) {
680 if (CI->getId() != Id) {
681 Diag(CI->getLocation(), diag::err_hlsl_attribute_param_mismatch) << AL;
682 Diag(AL.
getLoc(), diag::note_conflicting_attribute);
687 HLSLVkConstantIdAttr *
Result =
694 llvm::Triple::EnvironmentType ShaderType) {
695 if (HLSLShaderAttr *NT = D->
getAttr<HLSLShaderAttr>()) {
696 if (NT->getType() != ShaderType) {
697 Diag(NT->getLocation(), diag::err_hlsl_attribute_param_mismatch) << AL;
698 Diag(AL.
getLoc(), diag::note_conflicting_attribute);
702 return HLSLShaderAttr::Create(
getASTContext(), ShaderType, AL);
705HLSLParamModifierAttr *
707 HLSLParamModifierAttr::Spelling Spelling) {
710 if (HLSLParamModifierAttr *PA = D->
getAttr<HLSLParamModifierAttr>()) {
711 if ((PA->isIn() && Spelling == HLSLParamModifierAttr::Keyword_out) ||
712 (PA->isOut() && Spelling == HLSLParamModifierAttr::Keyword_in)) {
713 D->
dropAttr<HLSLParamModifierAttr>();
715 return HLSLParamModifierAttr::Create(
717 HLSLParamModifierAttr::Keyword_inout);
719 Diag(AL.
getLoc(), diag::err_hlsl_duplicate_parameter_modifier) << AL;
720 Diag(PA->getLocation(), diag::note_conflicting_attribute);
746 if (HLSLShaderAttr::isValidShaderType(Env) && Env != llvm::Triple::Library) {
747 if (
const auto *Shader = FD->
getAttr<HLSLShaderAttr>()) {
750 if (Shader->getType() != Env) {
751 Diag(Shader->getLocation(), diag::err_hlsl_entry_shader_attr_mismatch)
763 case llvm::Triple::UnknownEnvironment:
764 case llvm::Triple::Library:
766 case llvm::Triple::RootSignature:
767 llvm_unreachable(
"rootsig environment has no functions");
769 llvm_unreachable(
"Unhandled environment in triple");
775 HLSLAppliedSemanticAttr *Semantic,
780 const auto *ShaderAttr = FD->
getAttr<HLSLShaderAttr>();
781 assert(ShaderAttr &&
"Entry point has no shader attribute");
782 llvm::Triple::EnvironmentType ST = ShaderAttr->getType();
783 auto SemanticName = Semantic->getSemanticName().upper();
788 if (SemanticName ==
"SV_POSITION") {
789 return (ST == llvm::Triple::Vertex && !IsInput) ||
790 (ST == llvm::Triple::Pixel && IsInput);
796bool SemaHLSL::determineActiveSemanticOnScalar(
FunctionDecl *FD,
799 SemanticInfo &ActiveSemantic,
800 SemaHLSL::SemanticContext &SC) {
801 if (ActiveSemantic.Semantic ==
nullptr) {
802 ActiveSemantic.Semantic = D->
getAttr<HLSLParsedSemanticAttr>();
803 if (ActiveSemantic.Semantic)
804 ActiveSemantic.Index = ActiveSemantic.Semantic->getSemanticIndex();
807 if (!ActiveSemantic.Semantic) {
813 HLSLAppliedSemanticAttr(
getASTContext(), *ActiveSemantic.Semantic,
814 ActiveSemantic.Semantic->getAttrName()->getName(),
815 ActiveSemantic.Index.value_or(0));
819 checkSemanticAnnotation(FD, D, A, SC);
820 OutputDecl->addAttr(A);
822 unsigned Location = ActiveSemantic.Index.value_or(0);
825 SC.CurrentIOType & IOType::In)) {
826 bool HasVkLocation =
false;
827 if (
auto *A = D->getAttr<HLSLVkLocationAttr>()) {
828 HasVkLocation = true;
829 Location = A->getLocation();
832 if (SC.UsesExplicitVkLocations.value_or(HasVkLocation) != HasVkLocation) {
833 Diag(D->getLocation(), diag::err_hlsl_semantic_partial_explicit_indexing);
836 SC.UsesExplicitVkLocations = HasVkLocation;
839 const ConstantArrayType *AT = dyn_cast<ConstantArrayType>(D->getType());
840 unsigned ElementCount = AT ? AT->
getZExtSize() : 1;
841 ActiveSemantic.Index = Location + ElementCount;
843 Twine BaseName = Twine(ActiveSemantic.Semantic->getAttrName()->getName());
844 for (
unsigned I = 0; I < ElementCount; ++I) {
845 Twine VariableName = BaseName.concat(Twine(Location + I));
847 auto [_, Inserted] = SC.ActiveSemantics.insert(VariableName.str());
849 Diag(D->getLocation(), diag::err_hlsl_semantic_index_overlap)
850 << VariableName.str();
861 SemanticInfo &ActiveSemantic,
862 SemaHLSL::SemanticContext &SC) {
863 if (ActiveSemantic.Semantic ==
nullptr) {
864 ActiveSemantic.Semantic = D->
getAttr<HLSLParsedSemanticAttr>();
865 if (ActiveSemantic.Semantic)
866 ActiveSemantic.Index = ActiveSemantic.Semantic->getSemanticIndex();
872 const RecordType *RT = dyn_cast<RecordType>(
T);
874 return determineActiveSemanticOnScalar(FD, OutputDecl, D, ActiveSemantic,
877 const RecordDecl *RD = RT->getDecl();
878 for (FieldDecl *Field : RD->
fields()) {
879 SemanticInfo Info = ActiveSemantic;
880 if (!determineActiveSemantic(FD, OutputDecl, Field, Info, SC)) {
881 Diag(
Field->getLocation(), diag::note_hlsl_semantic_used_here) <<
Field;
884 if (ActiveSemantic.Semantic)
885 ActiveSemantic = Info;
892 const auto *ShaderAttr = FD->
getAttr<HLSLShaderAttr>();
893 assert(ShaderAttr &&
"Entry point has no shader attribute");
894 llvm::Triple::EnvironmentType ST = ShaderAttr->getType();
898 case llvm::Triple::Pixel:
899 case llvm::Triple::Vertex:
900 case llvm::Triple::Geometry:
901 case llvm::Triple::Hull:
902 case llvm::Triple::Domain:
903 case llvm::Triple::RayGeneration:
904 case llvm::Triple::Intersection:
905 case llvm::Triple::AnyHit:
906 case llvm::Triple::ClosestHit:
907 case llvm::Triple::Miss:
908 case llvm::Triple::Callable:
909 if (
const auto *NT = FD->
getAttr<HLSLNumThreadsAttr>()) {
910 diagnoseAttrStageMismatch(NT, ST,
911 {llvm::Triple::Compute,
912 llvm::Triple::Amplification,
913 llvm::Triple::Mesh});
916 if (
const auto *WS = FD->
getAttr<HLSLWaveSizeAttr>()) {
917 diagnoseAttrStageMismatch(WS, ST,
918 {llvm::Triple::Compute,
919 llvm::Triple::Amplification,
920 llvm::Triple::Mesh});
925 case llvm::Triple::Compute:
926 case llvm::Triple::Amplification:
927 case llvm::Triple::Mesh:
928 if (!FD->
hasAttr<HLSLNumThreadsAttr>()) {
930 << llvm::Triple::getEnvironmentTypeName(ST);
933 if (
const auto *WS = FD->
getAttr<HLSLWaveSizeAttr>()) {
934 if (Ver < VersionTuple(6, 6)) {
935 Diag(WS->getLocation(), diag::err_hlsl_attribute_in_wrong_shader_model)
938 }
else if (WS->getSpelledArgsCount() > 1 && Ver < VersionTuple(6, 8)) {
941 diag::err_hlsl_attribute_number_arguments_insufficient_shader_model)
942 << WS << WS->getSpelledArgsCount() <<
"6.8";
947 case llvm::Triple::RootSignature:
948 llvm_unreachable(
"rootsig environment has no function entry point");
950 llvm_unreachable(
"Unhandled environment in triple");
953 SemaHLSL::SemanticContext InputSC = {};
954 InputSC.CurrentIOType = IOType::In;
957 SemanticInfo ActiveSemantic;
958 ActiveSemantic.Semantic = Param->getAttr<HLSLParsedSemanticAttr>();
959 if (ActiveSemantic.Semantic)
960 ActiveSemantic.Index = ActiveSemantic.Semantic->getSemanticIndex();
963 if (!determineActiveSemantic(FD, Param, Param, ActiveSemantic, InputSC)) {
964 Diag(Param->getLocation(), diag::note_previous_decl) << Param;
969 SemanticInfo ActiveSemantic;
970 SemaHLSL::SemanticContext OutputSC = {};
971 OutputSC.CurrentIOType = IOType::Out;
972 ActiveSemantic.Semantic = FD->
getAttr<HLSLParsedSemanticAttr>();
973 if (ActiveSemantic.Semantic)
974 ActiveSemantic.Index = ActiveSemantic.Semantic->getSemanticIndex();
976 determineActiveSemantic(FD, FD, FD, ActiveSemantic, OutputSC);
979void SemaHLSL::checkSemanticAnnotation(
981 const HLSLAppliedSemanticAttr *SemanticAttr,
const SemanticContext &SC) {
982 auto *ShaderAttr = EntryPoint->
getAttr<HLSLShaderAttr>();
983 assert(ShaderAttr &&
"Entry point has no shader attribute");
984 llvm::Triple::EnvironmentType ST = ShaderAttr->getType();
986 auto SemanticName = SemanticAttr->getSemanticName().upper();
987 if (SemanticName ==
"SV_DISPATCHTHREADID" ||
988 SemanticName ==
"SV_GROUPINDEX" || SemanticName ==
"SV_GROUPTHREADID" ||
989 SemanticName ==
"SV_GROUPID") {
991 if (ST != llvm::Triple::Compute)
992 diagnoseSemanticStageMismatch(SemanticAttr, ST, SC.CurrentIOType,
993 {{llvm::Triple::Compute, IOType::In}});
995 if (SemanticAttr->getSemanticIndex() != 0) {
996 std::string PrettyName =
997 "'" + SemanticAttr->getSemanticName().str() +
"'";
998 Diag(SemanticAttr->getLoc(),
999 diag::err_hlsl_semantic_indexing_not_supported)
1005 if (SemanticName ==
"SV_POSITION") {
1008 diagnoseSemanticStageMismatch(SemanticAttr, ST, SC.CurrentIOType,
1009 {{llvm::Triple::Vertex, IOType::InOut},
1010 {llvm::Triple::Pixel, IOType::In}});
1014 if (SemanticName ==
"SV_TARGET") {
1015 diagnoseSemanticStageMismatch(SemanticAttr, ST, SC.CurrentIOType,
1016 {{llvm::Triple::Pixel, IOType::Out}});
1022 if (SemanticAttr->getAttrName()->getName().starts_with_insensitive(
"SV_"))
1023 llvm_unreachable(
"Unknown SemanticAttr");
1026void SemaHLSL::diagnoseAttrStageMismatch(
1027 const Attr *A, llvm::Triple::EnvironmentType Stage,
1028 std::initializer_list<llvm::Triple::EnvironmentType> AllowedStages) {
1029 SmallVector<StringRef, 8> StageStrings;
1030 llvm::transform(AllowedStages, std::back_inserter(StageStrings),
1031 [](llvm::Triple::EnvironmentType ST) {
1033 HLSLShaderAttr::ConvertEnvironmentTypeToStr(ST));
1035 Diag(A->
getLoc(), diag::err_hlsl_attr_unsupported_in_stage)
1036 << A->
getAttrName() << llvm::Triple::getEnvironmentTypeName(Stage)
1037 << (AllowedStages.size() != 1) << join(StageStrings,
", ");
1040void SemaHLSL::diagnoseSemanticStageMismatch(
1041 const Attr *A, llvm::Triple::EnvironmentType Stage, IOType CurrentIOType,
1042 std::initializer_list<SemanticStageInfo> Allowed) {
1044 for (
auto &Case : Allowed) {
1045 if (Case.Stage != Stage)
1048 if (CurrentIOType & Case.AllowedIOTypesMask)
1051 SmallVector<std::string, 8> ValidCases;
1053 Allowed, std::back_inserter(ValidCases), [](SemanticStageInfo Case) {
1054 SmallVector<std::string, 2> ValidType;
1055 if (Case.AllowedIOTypesMask & IOType::In)
1056 ValidType.push_back(
"input");
1057 if (Case.AllowedIOTypesMask & IOType::Out)
1058 ValidType.push_back(
"output");
1060 HLSLShaderAttr::ConvertEnvironmentTypeToStr(Case.Stage)) +
1061 " " + join(ValidType,
"/");
1063 Diag(A->
getLoc(), diag::err_hlsl_semantic_unsupported_iotype_for_stage)
1064 << A->
getAttrName() << (CurrentIOType & IOType::In ?
"input" :
"output")
1065 << llvm::Triple::getEnvironmentTypeName(Case.Stage)
1066 << join(ValidCases,
", ");
1070 SmallVector<StringRef, 8> StageStrings;
1072 Allowed, std::back_inserter(StageStrings), [](SemanticStageInfo Case) {
1074 HLSLShaderAttr::ConvertEnvironmentTypeToStr(Case.Stage));
1077 Diag(A->
getLoc(), diag::err_hlsl_attr_unsupported_in_stage)
1078 << A->
getAttrName() << llvm::Triple::getEnvironmentTypeName(Stage)
1079 << (Allowed.size() != 1) << join(StageStrings,
", ");
1082template <CastKind Kind>
1085 Ty = VTy->getElementType();
1090template <CastKind Kind>
1102 if (LHSFloat && RHSFloat) {
1130 if (LHSSigned == RHSSigned) {
1131 if (IsCompAssign || IntOrder >= 0)
1139 if (IntOrder != (LHSSigned ? 1 : -1)) {
1140 if (IsCompAssign || RHSSigned)
1148 if (Ctx.getIntWidth(LElTy) != Ctx.getIntWidth(RElTy)) {
1149 if (IsCompAssign || LHSSigned)
1165 QualType ElTy = Ctx.getCorrespondingUnsignedType(LHSSigned ? LElTy : RElTy);
1166 QualType NewTy = Ctx.getExtVectorType(
1176 return CK_FloatingCast;
1178 return CK_IntegralCast;
1180 return CK_IntegralToFloating;
1182 return CK_FloatingToIntegral;
1188 bool IsCompAssign) {
1195 if (!LVecTy && IsCompAssign) {
1197 RHS =
SemaRef.ImpCastExprToType(RHS.
get(), RElTy, CK_HLSLVectorTruncation);
1199 if (Ctx.hasSameUnqualifiedType(LHSType, RHSType))
1201 RHS =
SemaRef.ImpCastExprToType(RHS.
get(), LHSType,
1206 unsigned EndSz = std::numeric_limits<unsigned>::max();
1209 LSz = EndSz = LVecTy->getNumElements();
1212 assert(EndSz != std::numeric_limits<unsigned>::max() &&
1213 "one of the above should have had a value");
1217 if (IsCompAssign && LSz != EndSz) {
1219 diag::err_hlsl_vector_compound_assignment_truncation)
1220 << LHSType << RHSType;
1226 if (!IsCompAssign && LVecTy && LVecTy->getNumElements() > EndSz)
1231 if (!IsCompAssign && !LVecTy)
1235 if (Ctx.hasSameUnqualifiedType(LHSType, RHSType))
1236 return Ctx.getCommonSugaredType(LHSType, RHSType);
1244 LElTy, RElTy, IsCompAssign);
1247 "HLSL Vectors can only contain integer or floating point types");
1249 LElTy, RElTy, IsCompAssign);
1254 assert((Opc == BO_LOr || Opc == BO_LAnd) &&
1255 "Called with non-logical operator");
1257 llvm::raw_svector_ostream OS(Buff);
1259 StringRef NewFnName = Opc == BO_LOr ?
"or" :
"and";
1260 OS << NewFnName <<
"(";
1270std::pair<IdentifierInfo *, bool>
1273 std::string IdStr =
"__hlsl_rootsig_decl_" + std::to_string(Hash);
1280 return {DeclIdent,
Found};
1291 for (
auto &RootSigElement : RootElements)
1292 Elements.push_back(RootSigElement.getElement());
1296 DeclIdent,
SemaRef.getLangOpts().HLSLRootSigVer, Elements);
1298 SignatureDecl->setImplicit();
1304 if (RootSigOverrideIdent) {
1307 if (
SemaRef.LookupQualifiedName(R, DC))
1308 return dyn_cast<HLSLRootSignatureDecl>(R.
getFoundDecl());
1316struct PerVisibilityBindingChecker {
1319 std::array<llvm::hlsl::BindingInfoBuilder, 8> Builders;
1323 llvm::dxbc::ShaderVisibility Vis;
1328 PerVisibilityBindingChecker(
SemaHLSL *S) : S(S) {}
1330 void trackBinding(llvm::dxbc::ShaderVisibility
Visibility,
1331 llvm::dxil::ResourceClass RC, uint32_t Space,
1332 uint32_t LowerBound, uint32_t UpperBound,
1333 const hlsl::RootSignatureElement *Elem) {
1335 assert(BuilderIndex < Builders.size() &&
1336 "Not enough builders for visibility type");
1337 Builders[BuilderIndex].trackBinding(RC, Space, LowerBound, UpperBound,
1338 static_cast<const void *
>(Elem));
1340 static_assert(llvm::to_underlying(llvm::dxbc::ShaderVisibility::All) == 0,
1341 "'All' visibility must come first");
1342 if (
Visibility == llvm::dxbc::ShaderVisibility::All)
1343 for (
size_t I = 1, E = Builders.size(); I < E; ++I)
1344 Builders[I].trackBinding(RC, Space, LowerBound, UpperBound,
1345 static_cast<const void *
>(Elem));
1347 ElemInfoMap.push_back({Elem,
Visibility,
false});
1350 ElemInfo &
getInfo(
const hlsl::RootSignatureElement *Elem) {
1351 auto It = llvm::lower_bound(
1353 [](
const auto &LHS,
const auto &RHS) {
return LHS.Elem < RHS; });
1354 assert(It->Elem == Elem &&
"Element not in map");
1358 bool checkOverlap() {
1359 llvm::sort(ElemInfoMap, [](
const auto &LHS,
const auto &RHS) {
1360 return LHS.Elem < RHS.Elem;
1363 bool HadOverlap =
false;
1365 using llvm::hlsl::BindingInfoBuilder;
1366 auto ReportOverlap = [
this,
1367 &HadOverlap](
const BindingInfoBuilder &Builder,
1368 const llvm::hlsl::Binding &Reported) {
1372 static_cast<const hlsl::RootSignatureElement *
>(Reported.Cookie);
1373 const llvm::hlsl::Binding &
Previous = Builder.findOverlapping(Reported);
1374 const auto *PrevElem =
1375 static_cast<const hlsl::RootSignatureElement *
>(
Previous.Cookie);
1377 ElemInfo &Info =
getInfo(Elem);
1382 Info.Diagnosed =
true;
1384 ElemInfo &PrevInfo =
getInfo(PrevElem);
1385 llvm::dxbc::ShaderVisibility CommonVis =
1386 Info.Vis == llvm::dxbc::ShaderVisibility::All ? PrevInfo.Vis
1389 this->S->
Diag(Elem->
getLocation(), diag::err_hlsl_resource_range_overlap)
1390 << llvm::to_underlying(Reported.RC) << Reported.LowerBound
1391 << Reported.isUnbounded() << Reported.UpperBound
1396 this->S->
Diag(PrevElem->getLocation(),
1397 diag::note_hlsl_resource_range_here);
1400 for (BindingInfoBuilder &Builder : Builders)
1401 Builder.calculateBindingInfo(ReportOverlap);
1425 if (
const auto *ResTy =
1426 SecondField->
getType()->
getAs<HLSLAttributedResourceType>()) {
1427 return ResTy->getAttrs().IsCounter;
1435 bool HadError =
false;
1436 auto ReportError = [
this, &HadError](
SourceLocation Loc, uint32_t LowerBound,
1437 uint32_t UpperBound) {
1439 this->
Diag(Loc, diag::err_hlsl_invalid_rootsig_value)
1440 << LowerBound << UpperBound;
1447 this->
Diag(Loc, diag::err_hlsl_invalid_rootsig_value)
1448 << llvm::formatv(
"{0:f}", LowerBound).sstr<6>()
1449 << llvm::formatv(
"{0:f}", UpperBound).sstr<6>();
1452 auto VerifyRegister = [ReportError](
SourceLocation Loc, uint32_t Register) {
1453 if (!llvm::hlsl::rootsig::verifyRegisterValue(Register))
1454 ReportError(Loc, 0, 0xfffffffe);
1457 auto VerifySpace = [ReportError](
SourceLocation Loc, uint32_t Space) {
1458 if (!llvm::hlsl::rootsig::verifyRegisterSpace(Space))
1459 ReportError(Loc, 0, 0xffffffef);
1462 const uint32_t Version =
1463 llvm::to_underlying(
SemaRef.getLangOpts().HLSLRootSigVer);
1464 const uint32_t VersionEnum = Version - 1;
1465 auto ReportFlagError = [
this, &HadError, VersionEnum](
SourceLocation Loc) {
1467 this->
Diag(Loc, diag::err_hlsl_invalid_rootsig_flag)
1474 const llvm::hlsl::rootsig::RootElement &Elem = RootSigElem.
getElement();
1475 if (
const auto *Descriptor =
1476 std::get_if<llvm::hlsl::rootsig::RootDescriptor>(&Elem)) {
1477 VerifyRegister(Loc, Descriptor->Reg.Number);
1478 VerifySpace(Loc, Descriptor->Space);
1480 if (!llvm::hlsl::rootsig::verifyRootDescriptorFlag(Version,
1482 ReportFlagError(Loc);
1483 }
else if (
const auto *Constants =
1484 std::get_if<llvm::hlsl::rootsig::RootConstants>(&Elem)) {
1485 VerifyRegister(Loc, Constants->Reg.Number);
1486 VerifySpace(Loc, Constants->Space);
1487 }
else if (
const auto *Sampler =
1488 std::get_if<llvm::hlsl::rootsig::StaticSampler>(&Elem)) {
1489 VerifyRegister(Loc, Sampler->Reg.Number);
1490 VerifySpace(Loc, Sampler->Space);
1493 "By construction, parseFloatParam can't produce a NaN from a "
1494 "float_literal token");
1496 if (!llvm::hlsl::rootsig::verifyMaxAnisotropy(Sampler->MaxAnisotropy))
1497 ReportError(Loc, 0, 16);
1498 if (!llvm::hlsl::rootsig::verifyMipLODBias(Sampler->MipLODBias))
1499 ReportFloatError(Loc, -16.f, 15.99f);
1500 }
else if (
const auto *Clause =
1501 std::get_if<llvm::hlsl::rootsig::DescriptorTableClause>(
1503 VerifyRegister(Loc, Clause->Reg.Number);
1504 VerifySpace(Loc, Clause->Space);
1506 if (!llvm::hlsl::rootsig::verifyNumDescriptors(Clause->NumDescriptors)) {
1510 ReportError(Loc, 1, 0xfffffffe);
1513 if (!llvm::hlsl::rootsig::verifyDescriptorRangeFlag(Version, Clause->Type,
1515 ReportFlagError(Loc);
1519 PerVisibilityBindingChecker BindingChecker(
this);
1520 SmallVector<std::pair<
const llvm::hlsl::rootsig::DescriptorTableClause *,
1525 const llvm::hlsl::rootsig::RootElement &Elem = RootSigElem.
getElement();
1526 if (
const auto *Descriptor =
1527 std::get_if<llvm::hlsl::rootsig::RootDescriptor>(&Elem)) {
1528 uint32_t LowerBound(Descriptor->Reg.Number);
1529 uint32_t UpperBound(LowerBound);
1531 BindingChecker.trackBinding(
1532 Descriptor->Visibility,
1533 static_cast<llvm::dxil::ResourceClass
>(Descriptor->Type),
1534 Descriptor->Space, LowerBound, UpperBound, &RootSigElem);
1535 }
else if (
const auto *Constants =
1536 std::get_if<llvm::hlsl::rootsig::RootConstants>(&Elem)) {
1537 uint32_t LowerBound(Constants->Reg.Number);
1538 uint32_t UpperBound(LowerBound);
1540 BindingChecker.trackBinding(
1541 Constants->Visibility, llvm::dxil::ResourceClass::CBuffer,
1542 Constants->Space, LowerBound, UpperBound, &RootSigElem);
1543 }
else if (
const auto *Sampler =
1544 std::get_if<llvm::hlsl::rootsig::StaticSampler>(&Elem)) {
1545 uint32_t LowerBound(Sampler->Reg.Number);
1546 uint32_t UpperBound(LowerBound);
1548 BindingChecker.trackBinding(
1549 Sampler->Visibility, llvm::dxil::ResourceClass::Sampler,
1550 Sampler->Space, LowerBound, UpperBound, &RootSigElem);
1551 }
else if (
const auto *Clause =
1552 std::get_if<llvm::hlsl::rootsig::DescriptorTableClause>(
1555 UnboundClauses.emplace_back(Clause, &RootSigElem);
1556 }
else if (
const auto *Table =
1557 std::get_if<llvm::hlsl::rootsig::DescriptorTable>(&Elem)) {
1558 assert(UnboundClauses.size() == Table->NumClauses &&
1559 "Number of unbound elements must match the number of clauses");
1560 bool HasAnySampler =
false;
1561 bool HasAnyNonSampler =
false;
1562 uint64_t Offset = 0;
1563 bool IsPrevUnbound =
false;
1564 for (
const auto &[Clause, ClauseElem] : UnboundClauses) {
1566 if (Clause->Type == llvm::dxil::ResourceClass::Sampler)
1567 HasAnySampler =
true;
1569 HasAnyNonSampler =
true;
1571 if (HasAnySampler && HasAnyNonSampler)
1572 Diag(Loc, diag::err_hlsl_invalid_mixed_resources);
1577 if (Clause->NumDescriptors == 0)
1581 Clause->Offset == llvm::hlsl::rootsig::DescriptorTableOffsetAppend;
1583 Offset = Clause->Offset;
1585 uint64_t RangeBound = llvm::hlsl::rootsig::computeRangeBound(
1586 Offset, Clause->NumDescriptors);
1588 if (IsPrevUnbound && IsAppending)
1589 Diag(Loc, diag::err_hlsl_appending_onto_unbound);
1590 else if (!llvm::hlsl::rootsig::verifyNoOverflowedOffset(RangeBound))
1591 Diag(Loc, diag::err_hlsl_offset_overflow) << Offset << RangeBound;
1594 Offset = RangeBound + 1;
1595 IsPrevUnbound = Clause->NumDescriptors ==
1596 llvm::hlsl::rootsig::NumDescriptorsUnbounded;
1599 uint32_t LowerBound(Clause->Reg.Number);
1600 uint32_t UpperBound = llvm::hlsl::rootsig::computeRangeBound(
1601 LowerBound, Clause->NumDescriptors);
1603 BindingChecker.trackBinding(
1605 static_cast<llvm::dxil::ResourceClass
>(Clause->Type), Clause->Space,
1606 LowerBound, UpperBound, ClauseElem);
1608 UnboundClauses.clear();
1612 return BindingChecker.checkOverlap();
1617 Diag(AL.
getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1;
1622 if (
auto *RS = D->
getAttr<RootSignatureAttr>()) {
1623 if (RS->getSignatureIdent() != Ident) {
1624 Diag(AL.
getLoc(), diag::err_disallowed_duplicate_attribute) << RS;
1628 Diag(AL.
getLoc(), diag::warn_duplicate_attribute_exact) << RS;
1634 if (
auto *SignatureDecl =
1642 llvm::VersionTuple SMVersion =
1647 uint32_t ZMax = 1024;
1648 uint32_t ThreadMax = 1024;
1649 if (IsDXIL && SMVersion.getMajor() <= 4) {
1652 }
else if (IsDXIL && SMVersion.getMajor() == 5) {
1662 diag::err_hlsl_numthreads_argument_oor)
1671 diag::err_hlsl_numthreads_argument_oor)
1680 diag::err_hlsl_numthreads_argument_oor)
1685 if (
X * Y * Z > ThreadMax) {
1686 Diag(AL.
getLoc(), diag::err_hlsl_numthreads_invalid) << ThreadMax;
1703 if (SpelledArgsCount == 0 || SpelledArgsCount > 3)
1711 if (SpelledArgsCount > 1 &&
1715 uint32_t Preferred = 0;
1716 if (SpelledArgsCount > 2 &&
1720 if (SpelledArgsCount > 2) {
1723 diag::err_attribute_power_of_two_in_range)
1724 << AL << llvm::dxil::MinWaveSize << llvm::dxil::MaxWaveSize
1729 if (Preferred < Min || Preferred >
Max) {
1731 diag::err_attribute_power_of_two_in_range)
1732 << AL <<
Min <<
Max << Preferred;
1735 }
else if (SpelledArgsCount > 1) {
1738 diag::err_attribute_power_of_two_in_range)
1739 << AL << llvm::dxil::MinWaveSize << llvm::dxil::MaxWaveSize <<
Max;
1743 Diag(AL.
getLoc(), diag::err_attribute_argument_invalid) << AL << 1;
1746 Diag(AL.
getLoc(), diag::warn_attr_min_eq_max) << AL;
1751 diag::err_attribute_power_of_two_in_range)
1752 << AL << llvm::dxil::MinWaveSize << llvm::dxil::MaxWaveSize <<
Min;
1757 HLSLWaveSizeAttr *NewAttr =
1786 uint32_t Binding = 0;
1810 if (!
T->hasUnsignedIntegerRepresentation() ||
1811 (VT && VT->getNumElements() > 3)) {
1812 Diag(AL.
getLoc(), diag::err_hlsl_attr_invalid_type)
1813 << AL <<
"uint/uint2/uint3";
1822 if (!
T->hasFloatingRepresentation() || (VT && VT->getNumElements() > 4)) {
1823 Diag(AL.
getLoc(), diag::err_hlsl_attr_invalid_type)
1824 << AL <<
"float/float1/float2/float3/float4";
1832 std::optional<unsigned> Index) {
1836 QualType ValueType = VD->getType();
1837 if (
auto *FD = dyn_cast<FunctionDecl>(D))
1840 bool IsOutput =
false;
1841 if (HLSLParamModifierAttr *MA = D->
getAttr<HLSLParamModifierAttr>()) {
1848 if (SemanticName ==
"SV_DISPATCHTHREADID") {
1851 Diag(AL.
getLoc(), diag::err_hlsl_semantic_output_not_supported) << AL;
1852 if (Index.has_value())
1853 Diag(AL.
getLoc(), diag::err_hlsl_semantic_indexing_not_supported) << AL;
1858 if (SemanticName ==
"SV_GROUPINDEX") {
1860 Diag(AL.
getLoc(), diag::err_hlsl_semantic_output_not_supported) << AL;
1861 if (Index.has_value())
1862 Diag(AL.
getLoc(), diag::err_hlsl_semantic_indexing_not_supported) << AL;
1867 if (SemanticName ==
"SV_GROUPTHREADID") {
1870 Diag(AL.
getLoc(), diag::err_hlsl_semantic_output_not_supported) << AL;
1871 if (Index.has_value())
1872 Diag(AL.
getLoc(), diag::err_hlsl_semantic_indexing_not_supported) << AL;
1877 if (SemanticName ==
"SV_GROUPID") {
1880 Diag(AL.
getLoc(), diag::err_hlsl_semantic_output_not_supported) << AL;
1881 if (Index.has_value())
1882 Diag(AL.
getLoc(), diag::err_hlsl_semantic_indexing_not_supported) << AL;
1887 if (SemanticName ==
"SV_POSITION") {
1888 const auto *VT = ValueType->getAs<
VectorType>();
1889 if (!ValueType->hasFloatingRepresentation() ||
1890 (VT && VT->getNumElements() > 4))
1891 Diag(AL.
getLoc(), diag::err_hlsl_attr_invalid_type)
1892 << AL <<
"float/float1/float2/float3/float4";
1897 if (SemanticName ==
"SV_TARGET") {
1898 const auto *VT = ValueType->getAs<
VectorType>();
1899 if (!ValueType->hasFloatingRepresentation() ||
1900 (VT && VT->getNumElements() > 4))
1901 Diag(AL.
getLoc(), diag::err_hlsl_attr_invalid_type)
1902 << AL <<
"float/float1/float2/float3/float4";
1907 Diag(AL.
getLoc(), diag::err_hlsl_unknown_semantic) << AL;
1911 uint32_t IndexValue(0), ExplicitIndex(0);
1914 assert(0 &&
"HLSLUnparsedSemantic is expected to have 2 int arguments.");
1916 assert(IndexValue > 0 ? ExplicitIndex :
true);
1917 std::optional<unsigned> Index =
1918 ExplicitIndex ? std::optional<unsigned>(IndexValue) : std::nullopt;
1928 Diag(AL.
getLoc(), diag::err_hlsl_attr_invalid_ast_node)
1929 << AL <<
"shader constant in a constant buffer";
1933 uint32_t SubComponent;
1943 bool IsAggregateTy = (
T->isArrayType() ||
T->isStructureType());
1948 if (IsAggregateTy) {
1949 Diag(AL.
getLoc(), diag::err_hlsl_invalid_register_or_packoffset);
1953 if ((Component * 32 + Size) > 128) {
1954 Diag(AL.
getLoc(), diag::err_hlsl_packoffset_cross_reg_boundary);
1959 EltTy = VT->getElementType();
1961 if (Align > 32 && Component == 1) {
1964 Diag(AL.
getLoc(), diag::err_hlsl_packoffset_alignment_mismatch)
1978 if (!
SemaRef.checkStringLiteralArgumentAttr(AL, 0, Str, &ArgLoc))
1981 llvm::Triple::EnvironmentType ShaderType;
1982 if (!HLSLShaderAttr::ConvertStrToEnvironmentType(Str, ShaderType)) {
1983 Diag(AL.
getLoc(), diag::warn_attribute_type_not_supported)
1984 << AL << Str << ArgLoc;
1998 assert(AttrList.size() &&
"expected list of resource attributes");
2005 HLSLAttributedResourceType::Attributes ResAttrs;
2007 bool HasResourceClass =
false;
2008 bool HasResourceDimension =
false;
2009 for (
const Attr *A : AttrList) {
2014 case attr::HLSLResourceClass: {
2016 if (HasResourceClass) {
2018 ? diag::warn_duplicate_attribute_exact
2019 : diag::warn_duplicate_attribute)
2023 ResAttrs.ResourceClass = RC;
2024 HasResourceClass =
true;
2027 case attr::HLSLResourceDimension: {
2028 llvm::dxil::ResourceDimension RD =
2030 if (HasResourceDimension) {
2032 ? diag::warn_duplicate_attribute_exact
2033 : diag::warn_duplicate_attribute)
2037 ResAttrs.ResourceDimension = RD;
2038 HasResourceDimension =
true;
2042 if (ResAttrs.IsROV) {
2046 ResAttrs.IsROV =
true;
2048 case attr::HLSLRawBuffer:
2049 if (ResAttrs.RawBuffer) {
2053 ResAttrs.RawBuffer =
true;
2055 case attr::HLSLIsCounter:
2056 if (ResAttrs.IsCounter) {
2060 ResAttrs.IsCounter =
true;
2062 case attr::HLSLContainedType: {
2065 if (!ContainedTy.
isNull()) {
2067 ? diag::warn_duplicate_attribute_exact
2068 : diag::warn_duplicate_attribute)
2077 llvm_unreachable(
"unhandled resource attribute type");
2081 if (!HasResourceClass) {
2082 S.
Diag(AttrList.back()->getRange().getEnd(),
2083 diag::err_hlsl_missing_resource_class);
2088 Wrapped, ContainedTy, ResAttrs);
2090 if (LocInfo && ContainedTyInfo) {
2103 if (!
T->isHLSLResourceType()) {
2104 Diag(AL.
getLoc(), diag::err_hlsl_attribute_needs_intangible_type)
2119 AttributeCommonInfo::AS_CXX11, 0, false ,
2124 case ParsedAttr::AT_HLSLResourceClass: {
2126 Diag(AL.
getLoc(), diag::err_attribute_argument_type)
2137 if (!HLSLResourceClassAttr::ConvertStrToResourceClass(Identifier, RC)) {
2138 Diag(ArgLoc, diag::warn_attribute_type_not_supported)
2139 <<
"ResourceClass" << Identifier;
2142 A = HLSLResourceClassAttr::Create(
getASTContext(), RC, ACI);
2146 case ParsedAttr::AT_HLSLROV:
2150 case ParsedAttr::AT_HLSLRawBuffer:
2154 case ParsedAttr::AT_HLSLIsCounter:
2158 case ParsedAttr::AT_HLSLContainedType: {
2160 Diag(AL.
getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1;
2166 assert(TSI &&
"no type source info for attribute argument");
2168 diag::err_incomplete_type))
2170 A = HLSLContainedTypeAttr::Create(
getASTContext(), TSI, ACI);
2175 llvm_unreachable(
"unhandled HLSL attribute");
2178 HLSLResourcesTypeAttrs.emplace_back(A);
2184 if (!HLSLResourcesTypeAttrs.size())
2190 HLSLResourcesTypeAttrs, QT, &LocInfo)) {
2191 const HLSLAttributedResourceType *RT =
2198 LocsForHLSLAttributedResources.insert(std::pair(RT, LocInfo));
2200 HLSLResourcesTypeAttrs.clear();
2208 auto I = LocsForHLSLAttributedResources.find(RT);
2209 if (I != LocsForHLSLAttributedResources.end()) {
2210 LocInfo = I->second;
2211 LocsForHLSLAttributedResources.erase(I);
2220void SemaHLSL::collectResourceBindingsOnUserRecordDecl(
const VarDecl *VD,
2221 const RecordType *RT) {
2222 const RecordDecl *RD = RT->getDecl()->getDefinitionOrSelf();
2229 "incomplete arrays inside user defined types are not supported");
2238 if (
const HLSLAttributedResourceType *AttrResType =
2239 HLSLAttributedResourceType::findHandleTypeOnResource(Ty)) {
2244 Bindings.addDeclBindingInfo(VD, RC);
2245 }
else if (
const RecordType *RT = dyn_cast<RecordType>(Ty)) {
2251 collectResourceBindingsOnUserRecordDecl(VD, RT);
2263 bool SpecifiedSpace) {
2264 int RegTypeNum =
static_cast<int>(RegType);
2267 if (D->
hasAttr<HLSLGroupSharedAddressSpaceAttr>()) {
2268 S.
Diag(ArgLoc, diag::err_hlsl_binding_type_mismatch) << RegTypeNum;
2273 if (
HLSLBufferDecl *CBufferOrTBuffer = dyn_cast<HLSLBufferDecl>(D)) {
2274 ResourceClass RC = CBufferOrTBuffer->isCBuffer() ? ResourceClass::CBuffer
2275 : ResourceClass::SRV;
2285 assert(
isa<VarDecl>(D) &&
"D is expected to be VarDecl or HLSLBufferDecl");
2289 if (
const HLSLAttributedResourceType *AttrResType =
2290 HLSLAttributedResourceType::findHandleTypeOnResource(
2307 if (SpecifiedSpace && !DeclaredInCOrTBuffer)
2308 S.
Diag(ArgLoc, diag::err_hlsl_space_on_global_constant);
2313 if (RegType == RegisterType::CBuffer)
2314 S.
Diag(ArgLoc, diag::warn_hlsl_deprecated_register_type_b);
2315 else if (RegType != RegisterType::C)
2316 S.
Diag(ArgLoc, diag::err_hlsl_binding_type_mismatch) << RegTypeNum;
2320 if (RegType == RegisterType::C)
2321 S.
Diag(ArgLoc, diag::warn_hlsl_register_type_c_packoffset);
2323 S.
Diag(ArgLoc, diag::err_hlsl_binding_type_mismatch) << RegTypeNum;
2333 S.
Diag(ArgLoc, diag::err_hlsl_binding_type_mismatch) << RegTypeNum;
2341 bool RegisterTypesDetected[5] = {
false};
2342 RegisterTypesDetected[
static_cast<int>(regType)] =
true;
2345 if (HLSLResourceBindingAttr *
attr =
2346 dyn_cast<HLSLResourceBindingAttr>(*it)) {
2349 if (RegisterTypesDetected[
static_cast<int>(otherRegType)]) {
2350 int otherRegTypeNum =
static_cast<int>(otherRegType);
2352 diag::err_hlsl_duplicate_register_annotation)
2356 RegisterTypesDetected[
static_cast<int>(otherRegType)] =
true;
2364 bool SpecifiedSpace) {
2369 "expecting VarDecl or HLSLBufferDecl");
2381 const uint64_t &Limit,
2384 uint64_t ArrayCount = 1) {
2389 if (StartSlot > Limit)
2393 if (
const auto *AT = dyn_cast<ArrayType>(
T)) {
2396 if (
const auto *CAT = dyn_cast<ConstantArrayType>(AT))
2397 Count = CAT->
getSize().getZExtValue();
2401 ArrayCount * Count);
2405 if (
auto ResTy = dyn_cast<HLSLAttributedResourceType>(
T)) {
2408 if (ResTy->getAttrs().ResourceClass != ResClass)
2412 uint64_t EndSlot = StartSlot + ArrayCount - 1;
2413 if (EndSlot > Limit)
2417 StartSlot = EndSlot + 1;
2422 if (
const auto *RT = dyn_cast<RecordType>(
T)) {
2425 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
2428 ResClass, Ctx, ArrayCount))
2435 ResClass, Ctx, ArrayCount))
2449 const uint64_t Limit = UINT32_MAX;
2450 if (SlotNum > Limit)
2455 if (RegTy == RegisterType::C || RegTy == RegisterType::I)
2458 if (
VarDecl *VD = dyn_cast<VarDecl>(TheDecl)) {
2459 uint64_t BaseSlot = SlotNum;
2467 return (BaseSlot > Limit);
2474 return (SlotNum > Limit);
2477 llvm_unreachable(
"unexpected decl type");
2481 if (
VarDecl *VD = dyn_cast<VarDecl>(TheDecl)) {
2483 if (
const auto *IAT = dyn_cast<IncompleteArrayType>(Ty))
2484 Ty = IAT->getElementType();
2486 diag::err_incomplete_type))
2490 StringRef Slot =
"";
2491 StringRef Space =
"";
2495 Diag(AL.
getLoc(), diag::err_attribute_argument_type)
2505 Diag(AL.
getLoc(), diag::err_attribute_argument_type)
2511 SpaceLoc = Loc->
getLoc();
2514 if (Str.starts_with(
"space")) {
2516 SpaceLoc = Loc->
getLoc();
2525 std::optional<unsigned> SlotNum;
2526 unsigned SpaceNum = 0;
2529 if (!Slot.empty()) {
2531 Diag(SlotLoc, diag::err_hlsl_binding_type_invalid) << Slot.substr(0, 1);
2534 if (RegType == RegisterType::I) {
2535 Diag(SlotLoc, diag::warn_hlsl_deprecated_register_type_i);
2538 const StringRef SlotNumStr = Slot.substr(1);
2543 if (SlotNumStr.getAsInteger(10, N)) {
2544 Diag(SlotLoc, diag::err_hlsl_unsupported_register_number);
2552 Diag(SlotLoc, diag::err_hlsl_register_number_too_large);
2561 if (!Space.starts_with(
"space")) {
2562 Diag(SpaceLoc, diag::err_hlsl_expected_space) << Space;
2565 StringRef SpaceNumStr = Space.substr(5);
2566 if (SpaceNumStr.getAsInteger(10, SpaceNum)) {
2567 Diag(SpaceLoc, diag::err_hlsl_expected_space) << Space;
2572 if (SlotNum.has_value())
2577 HLSLResourceBindingAttr *NewAttr =
2578 HLSLResourceBindingAttr::Create(
getASTContext(), Slot, Space, AL);
2580 NewAttr->setBinding(RegType, SlotNum, SpaceNum);
2635 llvm::DenseMap<const FunctionDecl *, unsigned> ScannedDecls;
2639 llvm::Triple::EnvironmentType CurrentShaderEnvironment;
2640 unsigned CurrentShaderStageBit;
2645 bool ReportOnlyShaderStageIssues;
2648 void SetShaderStageContext(llvm::Triple::EnvironmentType ShaderType) {
2649 static_assert(
sizeof(
unsigned) >= 4);
2650 assert(HLSLShaderAttr::isValidShaderType(ShaderType));
2651 assert((
unsigned)(ShaderType - llvm::Triple::Pixel) < 31 &&
2652 "ShaderType is too big for this bitmap");
2655 unsigned bitmapIndex = ShaderType - llvm::Triple::Pixel;
2656 CurrentShaderEnvironment = ShaderType;
2657 CurrentShaderStageBit = (1 << bitmapIndex);
2660 void SetUnknownShaderStageContext() {
2661 CurrentShaderEnvironment = llvm::Triple::UnknownEnvironment;
2662 CurrentShaderStageBit = (1 << 31);
2665 llvm::Triple::EnvironmentType GetCurrentShaderEnvironment()
const {
2666 return CurrentShaderEnvironment;
2669 bool InUnknownShaderStageContext()
const {
2670 return CurrentShaderEnvironment == llvm::Triple::UnknownEnvironment;
2674 void AddToScannedFunctions(
const FunctionDecl *FD) {
2675 unsigned &ScannedStages = ScannedDecls[FD];
2676 ScannedStages |= CurrentShaderStageBit;
2679 unsigned GetScannedStages(
const FunctionDecl *FD) {
return ScannedDecls[FD]; }
2681 bool WasAlreadyScannedInCurrentStage(
const FunctionDecl *FD) {
2682 return WasAlreadyScannedInCurrentStage(GetScannedStages(FD));
2685 bool WasAlreadyScannedInCurrentStage(
unsigned ScannerStages) {
2686 return ScannerStages & CurrentShaderStageBit;
2689 static bool NeverBeenScanned(
unsigned ScannedStages) {
2690 return ScannedStages == 0;
2694 void HandleFunctionOrMethodRef(FunctionDecl *FD, Expr *RefExpr);
2695 void CheckDeclAvailability(NamedDecl *D,
const AvailabilityAttr *AA,
2697 const AvailabilityAttr *FindAvailabilityAttr(
const Decl *D);
2698 bool HasMatchingEnvironmentOrNone(
const AvailabilityAttr *AA);
2701 DiagnoseHLSLAvailability(Sema &SemaRef)
2703 CurrentShaderEnvironment(llvm::Triple::UnknownEnvironment),
2704 CurrentShaderStageBit(0), ReportOnlyShaderStageIssues(
false) {}
2707 void RunOnTranslationUnit(
const TranslationUnitDecl *TU);
2708 void RunOnFunction(
const FunctionDecl *FD);
2710 bool VisitDeclRefExpr(DeclRefExpr *DRE)
override {
2711 FunctionDecl *FD = llvm::dyn_cast<FunctionDecl>(DRE->
getDecl());
2713 HandleFunctionOrMethodRef(FD, DRE);
2717 bool VisitMemberExpr(MemberExpr *ME)
override {
2718 FunctionDecl *FD = llvm::dyn_cast<FunctionDecl>(ME->
getMemberDecl());
2720 HandleFunctionOrMethodRef(FD, ME);
2725void DiagnoseHLSLAvailability::HandleFunctionOrMethodRef(
FunctionDecl *FD,
2728 "expected DeclRefExpr or MemberExpr");
2732 if (FD->
hasBody(FDWithBody)) {
2733 if (!WasAlreadyScannedInCurrentStage(FDWithBody))
2734 DeclsToScan.push_back(FDWithBody);
2739 const AvailabilityAttr *AA = FindAvailabilityAttr(FD);
2741 CheckDeclAvailability(
2745void DiagnoseHLSLAvailability::RunOnTranslationUnit(
2754 DeclContextsToScan.push_back(TU);
2756 while (!DeclContextsToScan.empty()) {
2757 const DeclContext *DC = DeclContextsToScan.pop_back_val();
2758 for (
auto &D : DC->
decls()) {
2765 if (llvm::dyn_cast<NamespaceDecl>(D) || llvm::dyn_cast<ExportDecl>(D)) {
2766 DeclContextsToScan.push_back(llvm::dyn_cast<DeclContext>(D));
2771 const FunctionDecl *FD = llvm::dyn_cast<FunctionDecl>(D);
2776 if (HLSLShaderAttr *ShaderAttr = FD->
getAttr<HLSLShaderAttr>()) {
2777 SetShaderStageContext(ShaderAttr->getType());
2786 for (
const auto *Redecl : FD->
redecls()) {
2787 if (Redecl->isInExportDeclContext()) {
2794 SetUnknownShaderStageContext();
2802void DiagnoseHLSLAvailability::RunOnFunction(
const FunctionDecl *FD) {
2803 assert(DeclsToScan.empty() &&
"DeclsToScan should be empty");
2804 DeclsToScan.push_back(FD);
2806 while (!DeclsToScan.empty()) {
2814 const unsigned ScannedStages = GetScannedStages(FD);
2815 if (WasAlreadyScannedInCurrentStage(ScannedStages))
2818 ReportOnlyShaderStageIssues = !NeverBeenScanned(ScannedStages);
2820 AddToScannedFunctions(FD);
2825bool DiagnoseHLSLAvailability::HasMatchingEnvironmentOrNone(
2826 const AvailabilityAttr *AA) {
2831 llvm::Triple::EnvironmentType CurrentEnv = GetCurrentShaderEnvironment();
2832 if (CurrentEnv == llvm::Triple::UnknownEnvironment)
2835 llvm::Triple::EnvironmentType AttrEnv =
2836 AvailabilityAttr::getEnvironmentType(IIEnvironment->
getName());
2838 return CurrentEnv == AttrEnv;
2841const AvailabilityAttr *
2842DiagnoseHLSLAvailability::FindAvailabilityAttr(
const Decl *D) {
2843 AvailabilityAttr
const *PartialMatch =
nullptr;
2847 for (
const auto *A : D->
attrs()) {
2848 if (
const auto *Avail = dyn_cast<AvailabilityAttr>(A)) {
2849 StringRef AttrPlatform = Avail->getPlatform()->getName();
2850 StringRef TargetPlatform =
2854 if (AttrPlatform == TargetPlatform) {
2856 if (HasMatchingEnvironmentOrNone(Avail))
2858 PartialMatch = Avail;
2862 return PartialMatch;
2867void DiagnoseHLSLAvailability::CheckDeclAvailability(
NamedDecl *D,
2868 const AvailabilityAttr *AA,
2887 if (ReportOnlyShaderStageIssues)
2893 if (InUnknownShaderStageContext())
2898 bool EnvironmentMatches = HasMatchingEnvironmentOrNone(AA);
2899 VersionTuple Introduced = AA->getIntroduced();
2908 llvm::StringRef PlatformName(
2911 llvm::StringRef CurrentEnvStr =
2912 llvm::Triple::getEnvironmentTypeName(GetCurrentShaderEnvironment());
2914 llvm::StringRef AttrEnvStr =
2915 AA->getEnvironment() ? AA->getEnvironment()->getName() :
"";
2916 bool UseEnvironment = !AttrEnvStr.empty();
2918 if (EnvironmentMatches) {
2919 SemaRef.
Diag(
Range.getBegin(), diag::warn_hlsl_availability)
2920 <<
Range << D << PlatformName << Introduced.getAsString()
2921 << UseEnvironment << CurrentEnvStr;
2923 SemaRef.
Diag(
Range.getBegin(), diag::warn_hlsl_availability_unavailable)
2927 SemaRef.
Diag(D->
getLocation(), diag::note_partial_availability_specified_here)
2928 << D << PlatformName << Introduced.getAsString()
2930 << UseEnvironment << AttrEnvStr << CurrentEnvStr;
2937 if (!DefaultCBufferDecls.empty()) {
2940 DefaultCBufferDecls);
2942 getNextImplicitBindingOrderID());
2943 SemaRef.getCurLexicalContext()->addDecl(DefaultCBuffer);
2947 for (
const Decl *VD : DefaultCBufferDecls) {
2948 const HLSLResourceBindingAttr *RBA =
2949 VD->
getAttr<HLSLResourceBindingAttr>();
2950 if (RBA && RBA->hasRegisterSlot() &&
2951 RBA->getRegisterType() == HLSLResourceBindingAttr::RegisterType::C) {
2958 SemaRef.Consumer.HandleTopLevelDecl(DG);
2960 diagnoseAvailabilityViolations(TU);
2970 TI.
getTriple().getEnvironment() != llvm::Triple::EnvironmentType::Library)
2973 DiagnoseHLSLAvailability(
SemaRef).RunOnTranslationUnit(TU);
2980 for (
unsigned I = 1, N = TheCall->
getNumArgs(); I < N; ++I) {
2983 S->
Diag(TheCall->
getBeginLoc(), diag::err_vec_builtin_incompatible_vector)
3008 for (
unsigned I = 0; I < TheCall->
getNumArgs(); ++I) {
3023 if (!BaseType->isFloat32Type())
3024 return S->
Diag(Loc, diag::err_builtin_invalid_arg_type)
3025 << ArgOrdinal << 5 << 0
3037 if (!BaseType->isHalfType() && !BaseType->isFloat32Type())
3038 return S->
Diag(Loc, diag::err_builtin_invalid_arg_type)
3039 << ArgOrdinal << 5 << 0
3045 unsigned ArgIndex) {
3046 auto *Arg = TheCall->
getArg(ArgIndex);
3048 if (Arg->IgnoreCasts()->isModifiableLvalue(S->
Context, &OrigLoc) ==
3051 S->
Diag(OrigLoc, diag::error_hlsl_inout_lvalue) << Arg << 0;
3061 if (VecTy->getElementType()->isDoubleType())
3062 return S->
Diag(Loc, diag::err_builtin_invalid_arg_type)
3063 << ArgOrdinal << 1 << 0 << 1
3073 return S->
Diag(Loc, diag::err_builtin_invalid_arg_type)
3074 << ArgOrdinal << 5 << 1
3083 if (VecTy->getElementType()->isUnsignedIntegerType())
3086 return S->
Diag(Loc, diag::err_builtin_invalid_arg_type)
3087 << ArgOrdinal << 4 << 3 << 0
3096 return S->
Diag(Loc, diag::err_builtin_invalid_arg_type)
3097 << ArgOrdinal << 5 << 3
3103 unsigned ArgOrdinal,
unsigned Width) {
3106 ArgTy = VTy->getElementType();
3108 uint64_t ElementBitCount =
3110 if (ElementBitCount != Width) {
3112 diag::err_integer_incorrect_bit_count)
3113 << Width << ElementBitCount;
3130 unsigned ArgIndex) {
3139 diag::err_typecheck_expect_scalar_or_vector)
3140 << ArgType << Scalar;
3147 QualType Scalar,
unsigned ArgIndex) {
3158 if (
const auto *VTy = ArgType->getAs<
VectorType>()) {
3171 diag::err_typecheck_expect_scalar_or_vector_or_matrix)
3172 << ArgType << Scalar;
3177 unsigned ArgIndex) {
3182 if (!(ArgType->isScalarType() ||
3183 (VTy && VTy->getElementType()->isScalarType()))) {
3185 diag::err_typecheck_expect_any_scalar_or_vector)
3202 diag::err_typecheck_expect_any_scalar_or_vector)
3215 diag::err_typecheck_call_different_arg_types)
3234 Arg1ScalarTy = VTy->getElementType();
3238 Arg2ScalarTy = VTy->getElementType();
3241 S->
Diag(Arg1->
getBeginLoc(), diag::err_hlsl_builtin_scalar_vector_mismatch)
3242 << 1 << TheCall->
getCallee() << Arg1Ty << Arg2Ty;
3252 if (Arg1Length > 0 && Arg0Length != Arg1Length) {
3254 diag::err_typecheck_vector_lengths_not_equal)
3260 if (Arg2Length > 0 && Arg0Length != Arg2Length) {
3262 diag::err_typecheck_vector_lengths_not_equal)
3275 llvm::function_ref<
bool(
const HLSLAttributedResourceType *ResType)> Check =
3279 const HLSLAttributedResourceType *ResTy =
3283 diag::err_typecheck_expect_hlsl_resource)
3287 if (Check && Check(ResTy)) {
3289 diag::err_invalid_hlsl_resource_type)
3297 QualType BaseType,
unsigned ExpectedCount,
3299 unsigned PassedCount = 1;
3301 PassedCount = VecTy->getNumElements();
3303 if (PassedCount != ExpectedCount) {
3306 S->
Diag(Loc, diag::err_typecheck_convert_incompatible)
3316 switch (BuiltinID) {
3317 case Builtin::BI__builtin_hlsl_adduint64: {
3318 if (
SemaRef.checkArgCount(TheCall, 2))
3332 if (NumElementsArg != 2 && NumElementsArg != 4) {
3334 << 1 << 64 << NumElementsArg * 32;
3348 case Builtin::BI__builtin_hlsl_resource_getpointer: {
3349 if (
SemaRef.checkArgCount(TheCall, 2) ||
3352 SemaRef.getASTContext().UnsignedIntTy))
3357 QualType ContainedTy = ResourceTy->getContainedType();
3360 ReturnType =
SemaRef.Context.getPointerType(ReturnType);
3366 case Builtin::BI__builtin_hlsl_resource_load_with_status: {
3367 if (
SemaRef.checkArgCount(TheCall, 3) ||
3370 SemaRef.getASTContext().UnsignedIntTy) ||
3372 SemaRef.getASTContext().UnsignedIntTy) ||
3378 QualType ReturnType = ResourceTy->getContainedType();
3383 case Builtin::BI__builtin_hlsl_resource_sample: {
3384 if (
SemaRef.checkArgCountRange(TheCall, 3, 5))
3388 [](
const HLSLAttributedResourceType *ResType) {
3389 return ResType->getAttrs().ResourceDimension ==
3390 llvm::dxil::ResourceDimension::Unknown;
3395 [](
const HLSLAttributedResourceType *ResType) {
3396 return ResType->getAttrs().ResourceClass !=
3397 llvm::hlsl::ResourceClass::Sampler;
3404 unsigned ExpectedDim =
3407 SemaRef.Context.FloatTy, ExpectedDim,
3413 SemaRef.Context.IntTy, ExpectedDim,
3422 diag::err_typecheck_convert_incompatible)
3423 << ClampTy <<
SemaRef.Context.FloatTy << 1 << 0 << 0;
3428 assert(ResourceTy->hasContainedType() &&
3429 "Expecting a contained type for resource with a dimension "
3431 QualType ReturnType = ResourceTy->getContainedType();
3436 case Builtin::BI__builtin_hlsl_resource_uninitializedhandle: {
3437 assert(TheCall->
getNumArgs() == 1 &&
"expected 1 arg");
3443 case Builtin::BI__builtin_hlsl_resource_handlefrombinding: {
3444 assert(TheCall->
getNumArgs() == 6 &&
"expected 6 args");
3450 case Builtin::BI__builtin_hlsl_resource_handlefromimplicitbinding: {
3451 assert(TheCall->
getNumArgs() == 6 &&
"expected 6 args");
3457 case Builtin::BI__builtin_hlsl_resource_counterhandlefromimplicitbinding: {
3458 assert(TheCall->
getNumArgs() == 3 &&
"expected 3 args");
3461 auto *MainResType = MainHandleTy->
getAs<HLSLAttributedResourceType>();
3462 auto MainAttrs = MainResType->getAttrs();
3463 assert(!MainAttrs.IsCounter &&
"cannot create a counter from a counter");
3464 MainAttrs.IsCounter =
true;
3466 MainResType->getWrappedType(), MainResType->getContainedType(),
3470 TheCall->
setType(CounterHandleTy);
3473 case Builtin::BI__builtin_hlsl_and:
3474 case Builtin::BI__builtin_hlsl_or: {
3475 if (
SemaRef.checkArgCount(TheCall, 2))
3489 case Builtin::BI__builtin_hlsl_all:
3490 case Builtin::BI__builtin_hlsl_any: {
3491 if (
SemaRef.checkArgCount(TheCall, 1))
3497 case Builtin::BI__builtin_hlsl_asdouble: {
3498 if (
SemaRef.checkArgCount(TheCall, 2))
3502 SemaRef.Context.UnsignedIntTy,
3507 SemaRef.Context.UnsignedIntTy,
3516 case Builtin::BI__builtin_hlsl_elementwise_clamp: {
3517 if (
SemaRef.BuiltinElementwiseTernaryMath(
3523 case Builtin::BI__builtin_hlsl_dot: {
3525 if (
SemaRef.BuiltinVectorToScalarMath(TheCall))
3531 case Builtin::BI__builtin_hlsl_elementwise_firstbithigh:
3532 case Builtin::BI__builtin_hlsl_elementwise_firstbitlow: {
3533 if (
SemaRef.PrepareBuiltinElementwiseMathOneArgCall(TheCall))
3543 EltTy = VecTy->getElementType();
3544 ResTy =
SemaRef.Context.getExtVectorType(ResTy, VecTy->getNumElements());
3557 case Builtin::BI__builtin_hlsl_select: {
3558 if (
SemaRef.checkArgCount(TheCall, 3))
3566 if (VTy && VTy->getElementType()->isBooleanType() &&
3571 case Builtin::BI__builtin_hlsl_elementwise_saturate:
3572 case Builtin::BI__builtin_hlsl_elementwise_rcp: {
3573 if (
SemaRef.checkArgCount(TheCall, 1))
3579 diag::err_builtin_invalid_arg_type)
3582 if (
SemaRef.PrepareBuiltinElementwiseMathOneArgCall(TheCall))
3586 case Builtin::BI__builtin_hlsl_elementwise_degrees:
3587 case Builtin::BI__builtin_hlsl_elementwise_radians:
3588 case Builtin::BI__builtin_hlsl_elementwise_rsqrt:
3589 case Builtin::BI__builtin_hlsl_elementwise_frac:
3590 case Builtin::BI__builtin_hlsl_elementwise_ddx_coarse:
3591 case Builtin::BI__builtin_hlsl_elementwise_ddy_coarse:
3592 case Builtin::BI__builtin_hlsl_elementwise_ddx_fine:
3593 case Builtin::BI__builtin_hlsl_elementwise_ddy_fine: {
3594 if (
SemaRef.checkArgCount(TheCall, 1))
3599 if (
SemaRef.PrepareBuiltinElementwiseMathOneArgCall(TheCall))
3603 case Builtin::BI__builtin_hlsl_elementwise_isinf:
3604 case Builtin::BI__builtin_hlsl_elementwise_isnan: {
3605 if (
SemaRef.checkArgCount(TheCall, 1))
3610 if (
SemaRef.PrepareBuiltinElementwiseMathOneArgCall(TheCall))
3615 case Builtin::BI__builtin_hlsl_lerp: {
3616 if (
SemaRef.checkArgCount(TheCall, 3))
3623 if (
SemaRef.BuiltinElementwiseTernaryMath(TheCall))
3627 case Builtin::BI__builtin_hlsl_mad: {
3628 if (
SemaRef.BuiltinElementwiseTernaryMath(
3634 case Builtin::BI__builtin_hlsl_normalize: {
3635 if (
SemaRef.checkArgCount(TheCall, 1))
3646 case Builtin::BI__builtin_hlsl_elementwise_sign: {
3647 if (
SemaRef.PrepareBuiltinElementwiseMathOneArgCall(TheCall))
3655 case Builtin::BI__builtin_hlsl_step: {
3656 if (
SemaRef.checkArgCount(TheCall, 2))
3668 case Builtin::BI__builtin_hlsl_wave_active_max:
3669 case Builtin::BI__builtin_hlsl_wave_active_min:
3670 case Builtin::BI__builtin_hlsl_wave_active_sum: {
3671 if (
SemaRef.checkArgCount(TheCall, 1))
3686 case Builtin::BI__builtin_elementwise_bitreverse: {
3694 case Builtin::BI__builtin_hlsl_wave_prefix_count_bits: {
3695 if (
SemaRef.checkArgCount(TheCall, 1))
3700 if (!(
ArgType->isScalarType())) {
3702 diag::err_typecheck_expect_any_scalar_or_vector)
3707 if (!(
ArgType->isBooleanType())) {
3709 diag::err_typecheck_expect_any_scalar_or_vector)
3716 case Builtin::BI__builtin_hlsl_wave_read_lane_at: {
3717 if (
SemaRef.checkArgCount(TheCall, 2))
3725 diag::err_typecheck_convert_incompatible)
3726 << ArgTyIndex <<
SemaRef.Context.UnsignedIntTy << 1 << 0 << 0;
3739 case Builtin::BI__builtin_hlsl_wave_get_lane_index: {
3740 if (
SemaRef.checkArgCount(TheCall, 0))
3744 case Builtin::BI__builtin_hlsl_elementwise_splitdouble: {
3745 if (
SemaRef.checkArgCount(TheCall, 3))
3760 case Builtin::BI__builtin_hlsl_elementwise_clip: {
3761 if (
SemaRef.checkArgCount(TheCall, 1))
3768 case Builtin::BI__builtin_elementwise_acos:
3769 case Builtin::BI__builtin_elementwise_asin:
3770 case Builtin::BI__builtin_elementwise_atan:
3771 case Builtin::BI__builtin_elementwise_atan2:
3772 case Builtin::BI__builtin_elementwise_ceil:
3773 case Builtin::BI__builtin_elementwise_cos:
3774 case Builtin::BI__builtin_elementwise_cosh:
3775 case Builtin::BI__builtin_elementwise_exp:
3776 case Builtin::BI__builtin_elementwise_exp2:
3777 case Builtin::BI__builtin_elementwise_exp10:
3778 case Builtin::BI__builtin_elementwise_floor:
3779 case Builtin::BI__builtin_elementwise_fmod:
3780 case Builtin::BI__builtin_elementwise_log:
3781 case Builtin::BI__builtin_elementwise_log2:
3782 case Builtin::BI__builtin_elementwise_log10:
3783 case Builtin::BI__builtin_elementwise_pow:
3784 case Builtin::BI__builtin_elementwise_roundeven:
3785 case Builtin::BI__builtin_elementwise_sin:
3786 case Builtin::BI__builtin_elementwise_sinh:
3787 case Builtin::BI__builtin_elementwise_sqrt:
3788 case Builtin::BI__builtin_elementwise_tan:
3789 case Builtin::BI__builtin_elementwise_tanh:
3790 case Builtin::BI__builtin_elementwise_trunc: {
3796 case Builtin::BI__builtin_hlsl_buffer_update_counter: {
3797 assert(TheCall->
getNumArgs() == 2 &&
"expected 2 args");
3798 auto checkResTy = [](
const HLSLAttributedResourceType *ResTy) ->
bool {
3799 return !(ResTy->getAttrs().ResourceClass == ResourceClass::UAV &&
3800 ResTy->getAttrs().RawBuffer && ResTy->hasContainedType());
3805 std::optional<llvm::APSInt> Offset =
3807 if (!Offset.has_value() ||
std::abs(Offset->getExtValue()) != 1) {
3809 diag::err_hlsl_expect_arg_const_int_one_or_neg_one)
3815 case Builtin::BI__builtin_hlsl_elementwise_f16tof32: {
3816 if (
SemaRef.checkArgCount(TheCall, 1))
3827 ArgTy = VTy->getElementType();
3830 diag::err_builtin_invalid_arg_type)
3839 case Builtin::BI__builtin_hlsl_elementwise_f32tof16: {
3840 if (
SemaRef.checkArgCount(TheCall, 1))
3855 WorkList.push_back(BaseTy);
3856 while (!WorkList.empty()) {
3858 T =
T.getCanonicalType().getUnqualifiedType();
3859 if (
const auto *AT = dyn_cast<ConstantArrayType>(
T)) {
3867 for (uint64_t Ct = 0; Ct < AT->
getZExtSize(); ++Ct)
3868 llvm::append_range(List, ElementFields);
3873 if (
const auto *VT = dyn_cast<VectorType>(
T)) {
3874 List.insert(List.end(), VT->getNumElements(), VT->getElementType());
3877 if (
const auto *MT = dyn_cast<ConstantMatrixType>(
T)) {
3878 List.insert(List.end(), MT->getNumElementsFlattened(),
3879 MT->getElementType());
3882 if (
const auto *RD =
T->getAsCXXRecordDecl()) {
3883 if (RD->isStandardLayout())
3884 RD = RD->getStandardLayoutBaseWithFields();
3888 if (RD->
isUnion() || !RD->isAggregate()) {
3894 for (
const auto *FD : RD->
fields())
3895 if (!FD->isUnnamedBitField())
3896 FieldTypes.push_back(FD->
getType());
3898 std::reverse(FieldTypes.begin(), FieldTypes.end());
3899 llvm::append_range(WorkList, FieldTypes);
3903 if (!RD->isStandardLayout()) {
3905 for (
const auto &
Base : RD->bases())
3906 FieldTypes.push_back(
Base.getType());
3907 std::reverse(FieldTypes.begin(), FieldTypes.end());
3908 llvm::append_range(WorkList, FieldTypes);
3930 if (
SemaRef.Context.getTypeSize(QT) / 8 > 16)
3936 int ArraySize = VT->getNumElements();
3941 QualType ElTy = VT->getElementType();
3945 if (
SemaRef.Context.getTypeSize(QT) / 8 > 16)
3961 if (
SemaRef.getASTContext().hasSameType(T1, T2))
3970 return llvm::equal(T1Types, T2Types,
3972 return SemaRef.IsLayoutCompatible(LHS, RHS);
3981 bool HadError =
false;
3983 for (
unsigned i = 0, e =
New->getNumParams(); i != e; ++i) {
3991 const auto *NDAttr = NewParam->
getAttr<HLSLParamModifierAttr>();
3992 unsigned NSpellingIdx = (NDAttr ? NDAttr->getSpellingListIndex() : 0);
3993 const auto *ODAttr = OldParam->
getAttr<HLSLParamModifierAttr>();
3994 unsigned OSpellingIdx = (ODAttr ? ODAttr->getSpellingListIndex() : 0);
3996 if (NSpellingIdx != OSpellingIdx) {
3998 diag::err_hlsl_param_qualifier_mismatch)
3999 << NDAttr << NewParam;
4015 if (
SemaRef.getASTContext().hasSameUnqualifiedType(SrcTy, DestTy))
4030 llvm_unreachable(
"HLSL doesn't support pointers.");
4033 llvm_unreachable(
"HLSL doesn't support complex types.");
4035 llvm_unreachable(
"HLSL doesn't support fixed point types.");
4037 llvm_unreachable(
"Should have returned before this");
4047 llvm_unreachable(
"HLSL doesn't support complex types.");
4049 llvm_unreachable(
"HLSL doesn't support fixed point types.");
4054 llvm_unreachable(
"HLSL doesn't support pointers.");
4056 llvm_unreachable(
"Should have returned before this");
4062 llvm_unreachable(
"HLSL doesn't support pointers.");
4065 llvm_unreachable(
"HLSL doesn't support fixed point types.");
4069 llvm_unreachable(
"HLSL doesn't support complex types.");
4072 llvm_unreachable(
"Unhandled scalar cast");
4099 for (
unsigned I = 0, Size = DestTypes.size(); I < Size; ++I) {
4100 if (DestTypes[I]->isUnionType())
4132 if (SrcTypes.size() < DestTypes.size())
4135 unsigned SrcSize = SrcTypes.size();
4136 unsigned DstSize = DestTypes.size();
4138 for (I = 0; I < DstSize && I < SrcSize; I++) {
4139 if (SrcTypes[I]->isUnionType() || DestTypes[I]->isUnionType())
4147 for (; I < SrcSize; I++) {
4148 if (SrcTypes[I]->isUnionType())
4155 assert(Param->hasAttr<HLSLParamModifierAttr>() &&
4156 "We should not get here without a parameter modifier expression");
4157 const auto *
Attr = Param->getAttr<HLSLParamModifierAttr>();
4164 << Arg << (IsInOut ? 1 : 0);
4170 QualType Ty = Param->getType().getNonLValueExprType(Ctx);
4177 << Arg << (IsInOut ? 1 : 0);
4189 SemaRef.PerformCopyInitialization(Entity, Param->getBeginLoc(), ArgOpV);
4195 auto *OpV =
new (Ctx)
4200 Res =
SemaRef.ActOnBinOp(
SemaRef.getCurScope(), Param->getBeginLoc(),
4201 tok::equal, ArgOpV, OpV);
4217 "Pointer and reference types cannot be inout or out parameters");
4218 Ty =
SemaRef.getASTContext().getLValueReferenceType(Ty);
4226 bool IsVKPushConstant = IsVulkan && VD->
hasAttr<HLSLVkPushConstantAttr>();
4231 !VD->
hasAttr<HLSLVkConstantIdAttr>() && !IsVKPushConstant &&
4237 if (
Decl->getType().hasAddressSpace())
4240 if (
Decl->getType()->isDependentType())
4253 llvm::Triple::Vulkan;
4254 if (IsVulkan &&
Decl->
hasAttr<HLSLVkPushConstantAttr>()) {
4255 if (HasDeclaredAPushConstant)
4261 HasDeclaredAPushConstant =
true;
4285 if (
SemaRef.RequireCompleteType(
4288 diag::err_typecheck_decl_incomplete_type)) {
4302 DefaultCBufferDecls.push_back(VD);
4307 collectResourceBindingsOnVarDecl(VD);
4309 if (VD->
hasAttr<HLSLVkConstantIdAttr>())
4321 processExplicitBindingsOnDecl(VD);
4331 uint32_t OrderID = getNextImplicitBindingOrderID();
4349 uint32_t OrderID = getNextImplicitBindingOrderID();
4359bool SemaHLSL::initGlobalResourceDecl(
VarDecl *VD) {
4361 "expected resource record type");
4377 const char *CreateMethodName;
4378 if (Binding.isExplicit())
4379 CreateMethodName = HasCounter ?
"__createFromBindingWithImplicitCounter"
4380 :
"__createFromBinding";
4382 CreateMethodName = HasCounter
4383 ?
"__createFromImplicitBindingWithImplicitCounter"
4384 :
"__createFromImplicitBinding";
4395 if (Binding.isExplicit()) {
4399 Args.push_back(RegSlot);
4401 uint32_t OrderID = (Binding.hasImplicitOrderID())
4402 ? Binding.getImplicitOrderID()
4403 : getNextImplicitBindingOrderID();
4407 Args.push_back(OrderId);
4410 IntegerLiteral *Space =
4413 Args.push_back(Space);
4416 AST, llvm::APInt(IntTySize, 1), AST.
IntTy, SourceLocation());
4417 Args.push_back(RangeSize);
4420 AST, llvm::APInt(UIntTySize, 0), AST.
UnsignedIntTy, SourceLocation());
4421 Args.push_back(Index);
4423 StringRef VarName = VD->
getName();
4430 Name,
nullptr,
VK_PRValue, FPOptionsOverride());
4431 Args.push_back(NameCast);
4435 uint32_t CounterOrderID = getNextImplicitBindingOrderID();
4436 IntegerLiteral *CounterId =
4439 Args.push_back(CounterId);
4450 AST, NestedNameSpecifierLoc(), SourceLocation(), CreateMethod,
false,
4455 CK_FunctionToPointerDecay, DRE,
nullptr,
VK_PRValue, FPOptionsOverride());
4457 CallExpr *InitExpr =
4459 SourceLocation(), FPOptionsOverride());
4462 SemaRef.CheckCompleteVariableDeclaration(VD);
4466bool SemaHLSL::initGlobalResourceArrayDecl(
VarDecl *VD) {
4468 "expected array of resource records");
4479 ASTContext &AST =
SemaRef.getASTContext();
4482 CXXMethodDecl *CreateMethod =
nullptr;
4485 ResourceBindingAttrs ResourceAttrs(VD);
4486 if (ResourceAttrs.isExplicit())
4489 lookupMethod(
SemaRef, ResourceDecl,
4490 HasCounter ?
"__createFromBindingWithImplicitCounter"
4491 :
"__createFromBinding",
4495 CreateMethod = lookupMethod(
4497 HasCounter ?
"__createFromImplicitBindingWithImplicitCounter"
4498 :
"__createFromImplicitBinding",
4523 return initGlobalResourceDecl(VD);
4525 return initGlobalResourceArrayDecl(VD);
4535 "expected LHS to be a resource record or array of resource records");
4536 if (Opc != BO_Assign)
4541 while (
auto *ASE = dyn_cast<ArraySubscriptExpr>(E))
4549 SemaRef.Diag(Loc, diag::err_hlsl_assign_to_global_resource) << VD;
4560void SemaHLSL::collectResourceBindingsOnVarDecl(
VarDecl *VD) {
4562 "expected global variable that contains HLSL resource");
4565 if (
const HLSLBufferDecl *CBufferOrTBuffer = dyn_cast<HLSLBufferDecl>(VD)) {
4566 Bindings.addDeclBindingInfo(VD, CBufferOrTBuffer->isCBuffer()
4567 ? ResourceClass::CBuffer
4568 : ResourceClass::SRV);
4581 if (
const HLSLAttributedResourceType *AttrResType =
4582 HLSLAttributedResourceType::findHandleTypeOnResource(Ty)) {
4583 Bindings.addDeclBindingInfo(VD, AttrResType->getAttrs().ResourceClass);
4588 if (
const RecordType *RT = dyn_cast<RecordType>(Ty))
4589 collectResourceBindingsOnUserRecordDecl(VD, RT);
4595void SemaHLSL::processExplicitBindingsOnDecl(
VarDecl *VD) {
4598 bool HasBinding =
false;
4599 for (Attr *A : VD->
attrs()) {
4602 if (
auto PA = VD->
getAttr<HLSLVkPushConstantAttr>())
4603 Diag(PA->getLoc(), diag::err_hlsl_attr_incompatible) << A << PA;
4606 HLSLResourceBindingAttr *RBA = dyn_cast<HLSLResourceBindingAttr>(A);
4607 if (!RBA || !RBA->hasRegisterSlot())
4612 assert(RT != RegisterType::I &&
"invalid or obsolete register type should "
4613 "never have an attribute created");
4615 if (RT == RegisterType::C) {
4616 if (Bindings.hasBindingInfoForDecl(VD))
4618 diag::warn_hlsl_user_defined_type_missing_member)
4619 <<
static_cast<int>(RT);
4627 if (DeclBindingInfo *BI = Bindings.getDeclBindingInfo(VD, RC)) {
4632 diag::warn_hlsl_user_defined_type_missing_member)
4633 <<
static_cast<int>(RT);
4641class InitListTransformer {
4645 QualType *DstIt =
nullptr;
4646 Expr **ArgIt =
nullptr;
4652 bool castInitializer(Expr *E) {
4653 assert(DstIt &&
"This should always be something!");
4654 if (DstIt == DestTypes.end()) {
4656 ArgExprs.push_back(E);
4661 DstIt = DestTypes.begin();
4664 Ctx, *DstIt,
false);
4669 ArgExprs.push_back(
Init);
4674 bool buildInitializerListImpl(Expr *E) {
4676 if (
auto *
Init = dyn_cast<InitListExpr>(E)) {
4677 for (
auto *SubInit :
Init->inits())
4678 if (!buildInitializerListImpl(SubInit))
4687 return castInitializer(E);
4689 if (
auto *VecTy = Ty->
getAs<VectorType>()) {
4694 for (uint64_t I = 0; I <
Size; ++I) {
4696 SizeTy, SourceLocation());
4702 if (!castInitializer(ElExpr.
get()))
4707 if (
auto *MTy = Ty->
getAs<ConstantMatrixType>()) {
4708 unsigned Rows = MTy->getNumRows();
4709 unsigned Cols = MTy->getNumColumns();
4710 QualType ElemTy = MTy->getElementType();
4712 for (
unsigned R = 0; R < Rows; ++R) {
4713 for (
unsigned C = 0;
C < Cols; ++
C) {
4726 if (!castInitializer(ElExpr.
get()))
4734 if (
auto *ArrTy = dyn_cast<ConstantArrayType>(Ty.
getTypePtr())) {
4738 for (uint64_t I = 0; I <
Size; ++I) {
4740 SizeTy, SourceLocation());
4745 if (!buildInitializerListImpl(ElExpr.
get()))
4752 llvm::SmallVector<CXXRecordDecl *> RecordDecls;
4753 RecordDecls.push_back(RD);
4754 while (RecordDecls.back()->getNumBases()) {
4755 CXXRecordDecl *D = RecordDecls.back();
4757 "HLSL doesn't support multiple inheritance");
4758 RecordDecls.push_back(
4761 while (!RecordDecls.empty()) {
4762 CXXRecordDecl *RD = RecordDecls.pop_back_val();
4763 for (
auto *FD : RD->
fields()) {
4764 if (FD->isUnnamedBitField())
4772 if (!buildInitializerListImpl(Res.
get()))
4780 Expr *generateInitListsImpl(QualType Ty) {
4781 assert(ArgIt != ArgExprs.end() &&
"Something is off in iteration!");
4785 llvm::SmallVector<Expr *>
Inits;
4791 if (
auto *ATy = Ty->
getAs<VectorType>()) {
4792 ElTy = ATy->getElementType();
4793 Size = ATy->getNumElements();
4794 }
else if (
auto *CMTy = Ty->
getAs<ConstantMatrixType>()) {
4795 ElTy = CMTy->getElementType();
4796 Size = CMTy->getNumElementsFlattened();
4799 ElTy = VTy->getElementType();
4800 Size = VTy->getZExtSize();
4802 for (uint64_t I = 0; I <
Size; ++I)
4803 Inits.push_back(generateInitListsImpl(ElTy));
4806 llvm::SmallVector<CXXRecordDecl *> RecordDecls;
4807 RecordDecls.push_back(RD);
4808 while (RecordDecls.back()->getNumBases()) {
4809 CXXRecordDecl *D = RecordDecls.back();
4811 "HLSL doesn't support multiple inheritance");
4812 RecordDecls.push_back(
4815 while (!RecordDecls.empty()) {
4816 CXXRecordDecl *RD = RecordDecls.pop_back_val();
4817 for (
auto *FD : RD->
fields())
4818 if (!FD->isUnnamedBitField())
4822 auto *NewInit =
new (Ctx) InitListExpr(Ctx,
Inits.front()->getBeginLoc(),
4824 NewInit->setType(Ty);
4829 llvm::SmallVector<QualType, 16> DestTypes;
4830 llvm::SmallVector<Expr *, 16> ArgExprs;
4831 InitListTransformer(Sema &SemaRef,
const InitializedEntity &Entity)
4832 : S(SemaRef), Ctx(SemaRef.getASTContext()),
4833 Wrap(Entity.
getType()->isIncompleteArrayType()) {
4834 InitTy = Entity.
getType().getNonReferenceType();
4844 DstIt = DestTypes.begin();
4847 bool buildInitializerList(Expr *E) {
return buildInitializerListImpl(E); }
4849 Expr *generateInitLists() {
4850 assert(!ArgExprs.empty() &&
4851 "Call buildInitializerList to generate argument expressions.");
4852 ArgIt = ArgExprs.begin();
4854 return generateInitListsImpl(InitTy);
4855 llvm::SmallVector<Expr *>
Inits;
4856 while (ArgIt != ArgExprs.end())
4857 Inits.push_back(generateInitListsImpl(InitTy));
4859 auto *NewInit =
new (Ctx) InitListExpr(Ctx,
Inits.front()->getBeginLoc(),
4861 llvm::APInt ArySize(64,
Inits.size());
4863 ArraySizeModifier::Normal, 0));
4875 if (
const ArrayType *AT = dyn_cast<ArrayType>(Ty)) {
4882 if (
const auto *RT = Ty->
getAs<RecordType>()) {
4886 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
4906 if (
Init->getType()->isScalarType())
4909 InitListTransformer ILT(
SemaRef, Entity);
4911 for (
unsigned I = 0; I <
Init->getNumInits(); ++I) {
4919 Init->setInit(I, E);
4921 if (!ILT.buildInitializerList(E))
4924 size_t ExpectedSize = ILT.DestTypes.size();
4925 size_t ActualSize = ILT.ArgExprs.size();
4926 if (ExpectedSize == 0 && ActualSize == 0)
4933 InitTy =
SemaRef.getASTContext().removeAddrSpaceQualType(InitTy);
4935 SemaRef.Diag(
Init->getBeginLoc(), diag::err_hlsl_incorrect_num_initializers)
4936 << (int)(ExpectedSize < ActualSize) << InitTy
4937 << ExpectedSize << ActualSize;
4947 assert(ExpectedSize > 0 &&
4948 "The expected size of an incomplete array type must be at least 1.");
4950 ((ActualSize + ExpectedSize - 1) / ExpectedSize) * ExpectedSize;
4958 InitTy =
SemaRef.getASTContext().removeAddrSpaceQualType(InitTy);
4959 if (ExpectedSize != ActualSize) {
4960 int TooManyOrFew = ActualSize > ExpectedSize ? 1 : 0;
4961 SemaRef.Diag(
Init->getBeginLoc(), diag::err_hlsl_incorrect_num_initializers)
4962 << TooManyOrFew << InitTy << ExpectedSize << ActualSize;
4969 Init->resizeInits(Ctx, NewInit->getNumInits());
4970 for (
unsigned I = 0; I < NewInit->getNumInits(); ++I)
4971 Init->updateInit(Ctx, I, NewInit->getInit(I));
4976 const HLSLVkConstantIdAttr *ConstIdAttr =
4977 VDecl->
getAttr<HLSLVkConstantIdAttr>();
4984 if (!
Init->isCXX11ConstantExpr(Context, &InitValue)) {
4994 int ConstantID = ConstIdAttr->getId();
4995 llvm::APInt IDVal(Context.getIntWidth(Context.IntTy), ConstantID);
4997 ConstIdAttr->getLocation());
5001 if (
C->getType()->getCanonicalTypeUnqualified() !=
5005 Context.getTrivialTypeSourceInfo(
5006 Init->getType(),
Init->getExprLoc()),
Defines the clang::ASTContext interface.
Defines enum values for all the target-independent builtin functions.
llvm::dxil::ResourceClass ResourceClass
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
llvm::SmallVector< std::pair< const MemRegion *, SVal >, 4 > Bindings
static bool CheckArgTypeMatches(Sema *S, Expr *Arg, QualType ExpectedType)
static void BuildFlattenedTypeList(QualType BaseTy, llvm::SmallVectorImpl< QualType > &List)
static bool CheckUnsignedIntRepresentation(Sema *S, SourceLocation Loc, int ArgOrdinal, clang::QualType PassedType)
static bool containsIncompleteArrayType(QualType Ty)
static QualType handleIntegerVectorBinOpConversion(Sema &SemaRef, ExprResult &LHS, ExprResult &RHS, QualType LHSType, QualType RHSType, QualType LElTy, QualType RElTy, bool IsCompAssign)
static bool convertToRegisterType(StringRef Slot, RegisterType *RT)
static bool CheckWaveActive(Sema *S, CallExpr *TheCall)
static void castVector(Sema &S, ExprResult &E, QualType &Ty, unsigned Sz)
static bool CheckBoolSelect(Sema *S, CallExpr *TheCall)
static unsigned calculateLegacyCbufferFieldAlign(const ASTContext &Context, QualType T)
static bool isZeroSizedArray(const ConstantArrayType *CAT)
static bool DiagnoseHLSLRegisterAttribute(Sema &S, SourceLocation &ArgLoc, Decl *D, RegisterType RegType, bool SpecifiedSpace)
static FieldDecl * createFieldForHostLayoutStruct(Sema &S, const Type *Ty, IdentifierInfo *II, CXXRecordDecl *LayoutStruct)
static bool CheckUnsignedIntVecRepresentation(Sema *S, SourceLocation Loc, int ArgOrdinal, clang::QualType PassedType)
static bool isInvalidConstantBufferLeafElementType(const Type *Ty)
static Builtin::ID getSpecConstBuiltinId(const Type *Type)
static bool CheckFloatingOrIntRepresentation(Sema *S, SourceLocation Loc, int ArgOrdinal, clang::QualType PassedType)
static bool CheckAnyScalarOrVector(Sema *S, CallExpr *TheCall, unsigned ArgIndex)
static IdentifierInfo * getHostLayoutStructName(Sema &S, NamedDecl *BaseDecl, bool MustBeUnique)
static void addImplicitBindingAttrToDecl(Sema &S, Decl *D, RegisterType RT, uint32_t ImplicitBindingOrderID)
static void SetElementTypeAsReturnType(Sema *S, CallExpr *TheCall, QualType ReturnType)
static bool isResourceRecordTypeOrArrayOf(VarDecl *VD)
static unsigned calculateLegacyCbufferSize(const ASTContext &Context, QualType T)
static const HLSLAttributedResourceType * getResourceArrayHandleType(VarDecl *VD)
static RegisterType getRegisterType(ResourceClass RC)
static bool ValidateRegisterNumber(uint64_t SlotNum, Decl *TheDecl, ASTContext &Ctx, RegisterType RegTy)
static bool isVkPipelineBuiltin(const ASTContext &AstContext, FunctionDecl *FD, HLSLAppliedSemanticAttr *Semantic, bool IsInput)
static bool CheckVectorElementCount(Sema *S, QualType PassedType, QualType BaseType, unsigned ExpectedCount, SourceLocation Loc)
static bool CheckModifiableLValue(Sema *S, CallExpr *TheCall, unsigned ArgIndex)
static QualType castElement(Sema &S, ExprResult &E, QualType Ty)
static CXXRecordDecl * findRecordDeclInContext(IdentifierInfo *II, DeclContext *DC)
static bool CheckExpectedBitWidth(Sema *S, CallExpr *TheCall, unsigned ArgOrdinal, unsigned Width)
static bool hasCounterHandle(const CXXRecordDecl *RD)
static bool CheckVectorSelect(Sema *S, CallExpr *TheCall)
static QualType handleFloatVectorBinOpConversion(Sema &SemaRef, ExprResult &LHS, ExprResult &RHS, QualType LHSType, QualType RHSType, QualType LElTy, QualType RElTy, bool IsCompAssign)
static ResourceClass getResourceClass(RegisterType RT)
static CXXRecordDecl * createHostLayoutStruct(Sema &S, CXXRecordDecl *StructDecl)
static bool CheckScalarOrVector(Sema *S, CallExpr *TheCall, QualType Scalar, unsigned ArgIndex)
static bool CheckScalarOrVectorOrMatrix(Sema *S, CallExpr *TheCall, QualType Scalar, unsigned ArgIndex)
static bool CheckFloatRepresentation(Sema *S, SourceLocation Loc, int ArgOrdinal, clang::QualType PassedType)
void createHostLayoutStructForBuffer(Sema &S, HLSLBufferDecl *BufDecl)
static bool requiresImplicitBufferLayoutStructure(const CXXRecordDecl *RD)
static bool CheckResourceHandle(Sema *S, CallExpr *TheCall, unsigned ArgIndex, llvm::function_ref< bool(const HLSLAttributedResourceType *ResType)> Check=nullptr)
static void validatePackoffset(Sema &S, HLSLBufferDecl *BufDecl)
static bool IsDefaultBufferConstantDecl(const ASTContext &Ctx, VarDecl *VD)
HLSLResourceBindingAttr::RegisterType RegisterType
static CastKind getScalarCastKind(ASTContext &Ctx, QualType DestTy, QualType SrcTy)
static bool isValidWaveSizeValue(unsigned Value)
static bool AccumulateHLSLResourceSlots(QualType Ty, uint64_t &StartSlot, const uint64_t &Limit, const ResourceClass ResClass, ASTContext &Ctx, uint64_t ArrayCount=1)
static bool CheckNoDoubleVectors(Sema *S, SourceLocation Loc, int ArgOrdinal, clang::QualType PassedType)
static bool ValidateMultipleRegisterAnnotations(Sema &S, Decl *TheDecl, RegisterType regType)
static bool DiagnoseLocalRegisterBinding(Sema &S, SourceLocation &ArgLoc, Decl *D, RegisterType RegType, bool SpecifiedSpace)
This file declares semantic analysis for HLSL constructs.
Defines the clang::SourceLocation class and associated facilities.
Defines various enumerations that describe declaration and type specifiers.
C Language Family Type Representation.
Defines the clang::TypeLoc interface and its subclasses.
C Language Family Type Representation.
static const TypeInfo & getInfo(unsigned id)
return(__x > > __y)|(__x<<(32 - __y))
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
unsigned getIntWidth(QualType T) const
int getIntegerTypeOrder(QualType LHS, QualType RHS) const
Return the highest ranked integer type, see C99 6.3.1.8p1.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
const IncompleteArrayType * getAsIncompleteArrayType(QualType T) const
QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize, const Expr *SizeExpr, ArraySizeModifier ASM, unsigned IndexTypeQuals) const
Return the unique reference to the type for a constant array of the specified element type.
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
int getFloatingTypeOrder(QualType LHS, QualType RHS) const
Compare the rank of the two specified floating point types, ignoring the domain of the type (i....
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
QualType getStringLiteralArrayType(QualType EltTy, unsigned Length) const
Return a type for a constant array for a string literal of the specified element type and length.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
CanQualType UnsignedIntTy
QualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
QualType getExtVectorType(QualType VectorType, unsigned NumElts) const
Return the unique reference to an extended vector type of the specified element type and size.
const TargetInfo & getTargetInfo() const
QualType getHLSLAttributedResourceType(QualType Wrapped, QualType Contained, const HLSLAttributedResourceType::Attributes &Attrs)
QualType getAddrSpaceQualType(QualType T, LangAS AddressSpace) const
Return the uniqued reference to the type for an address space qualified type with the specified type ...
CanQualType getCanonicalTagType(const TagDecl *TD) const
static bool hasSameUnqualifiedType(QualType T1, QualType T2)
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
unsigned getTypeAlign(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in bits.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
QualType getElementType() const
Attr - This represents one attribute.
attr::Kind getKind() const
SourceLocation getLocation() const
SourceLocation getScopeLoc() const
SourceRange getRange() const
const IdentifierInfo * getScopeName() const
SourceLocation getLoc() const
const IdentifierInfo * getAttrName() const
Represents a base class of a C++ class.
QualType getType() const
Retrieves the type of the base class.
Represents a static or instance method of a struct/union/class.
Represents a C++ struct/union/class.
bool isHLSLIntangible() const
Returns true if the class contains HLSL intangible type, either as a field or in base class.
static CXXRecordDecl * Create(const ASTContext &C, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, CXXRecordDecl *PrevDecl=nullptr)
void setBases(CXXBaseSpecifier const *const *Bases, unsigned NumBases)
Sets the base classes of this struct or class.
void completeDefinition() override
Indicates that the definition of this class is now complete.
unsigned getNumBases() const
Retrieves the number of base classes of this class.
base_class_iterator bases_begin()
bool isEmpty() const
Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
SourceLocation getBeginLoc() const
static CallExpr * Create(const ASTContext &Ctx, Expr *Fn, ArrayRef< Expr * > Args, QualType Ty, ExprValueKind VK, SourceLocation RParenLoc, FPOptionsOverride FPFeatures, unsigned MinNumArgs=0, ADLCallKind UsesADL=NotADL)
Create a call expression.
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
QualType withConst() const
Retrieves a version of this type with const applied.
const T * getTypePtr() const
Retrieve the underlying type pointer, which refers to a canonical type.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
Represents the canonical version of C arrays with a specified constant size.
bool isZeroSize() const
Return true if the size is zero.
llvm::APInt getSize() const
Return the constant array size as an APInt.
uint64_t getZExtSize() const
Return the size zero-extended as a uint64_t.
Represents a concrete matrix type with constant number of rows and columns.
static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS)
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
bool isTranslationUnit() const
void addDecl(Decl *D)
Add the declaration D into this context.
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
DeclContext * getNonTransparentContext()
A reference to a declared variable, function, enum, etc.
static DeclRefExpr * Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *D, bool RefersToEnclosingVariableOrCapture, SourceLocation NameLoc, QualType T, ExprValueKind VK, NamedDecl *FoundD=nullptr, const TemplateArgumentListInfo *TemplateArgs=nullptr, NonOdrUseReason NOUR=NOUR_None)
Decl - This represents one declaration (or definition), e.g.
attr_iterator attr_end() const
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
void setInvalidDecl(bool Invalid=true)
setInvalidDecl - Indicates the Decl had a semantic error.
bool isInExportDeclContext() const
Whether this declaration was exported in a lexical context.
attr_iterator attr_begin() const
SourceLocation getLocation() const
void setImplicit(bool I=true)
DeclContext * getDeclContext()
AccessSpecifier getAccess() const
SourceLocation getBeginLoc() const LLVM_READONLY
The name of a declaration.
Represents a ValueDecl that came out of a declarator.
SourceLocation getBeginLoc() const LLVM_READONLY
This represents one expression.
ExprValueKind getValueKind() const
getValueKind - The value kind that this expression produces.
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language.
ExprObjectKind getObjectKind() const
getObjectKind - The object kind that this expression produces.
bool HasSideEffects(const ASTContext &Ctx, bool IncludePossibleEffects=true) const
HasSideEffects - This routine returns true for all those expressions which have any effect other than...
void setValueKind(ExprValueKind Cat)
setValueKind - Set the value kind produced by this expression.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Represents a member of a struct/union/class.
static FieldDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, Expr *BW, bool Mutable, InClassInitStyle InitStyle)
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
Represents a function declaration or definition.
const ParmVarDecl * getParamDecl(unsigned i) const
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
bool isThisDeclarationADefinition() const
Returns whether this specific declaration of the function is also a definition that does not contain ...
QualType getReturnType() const
ArrayRef< ParmVarDecl * > parameters() const
bool isTemplateInstantiation() const
Determines if the given function was instantiated from a function template.
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
DeclarationNameInfo getNameInfo() const
bool hasBody(const FunctionDecl *&Definition) const
Returns true if the function has a body.
bool isDefined(const FunctionDecl *&Definition, bool CheckForPendingFriendDefinition=false) const
Returns true if the function has a definition that does not need to be instantiated.
HLSLBufferDecl - Represent a cbuffer or tbuffer declaration.
static HLSLBufferDecl * Create(ASTContext &C, DeclContext *LexicalParent, bool CBuffer, SourceLocation KwLoc, IdentifierInfo *ID, SourceLocation IDLoc, SourceLocation LBrace)
void addLayoutStruct(CXXRecordDecl *LS)
void setHasValidPackoffset(bool PO)
static HLSLBufferDecl * CreateDefaultCBuffer(ASTContext &C, DeclContext *LexicalParent, ArrayRef< Decl * > DefaultCBufferDecls)
buffer_decl_range buffer_decls() const
static HLSLOutArgExpr * Create(const ASTContext &C, QualType Ty, OpaqueValueExpr *Base, OpaqueValueExpr *OpV, Expr *WB, bool IsInOut)
static HLSLRootSignatureDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation Loc, IdentifierInfo *ID, llvm::dxbc::RootSignatureVersion Version, ArrayRef< llvm::hlsl::rootsig::RootElement > RootElements)
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
A simple pair of identifier info and location.
SourceLocation getLoc() const
IdentifierInfo * getIdentifierInfo() const
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
static ImplicitCastExpr * Create(const ASTContext &Context, QualType T, CastKind Kind, Expr *Operand, const CXXCastPath *BasePath, ExprValueKind Cat, FPOptionsOverride FPO)
Describes an C or C++ initializer list.
Describes an entity that is being initialized.
QualType getType() const
Retrieve type being initialized.
static InitializedEntity InitializeParameter(ASTContext &Context, ParmVarDecl *Parm)
Create the initialization entity for a parameter.
static IntegerLiteral * Create(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l)
Returns a new integer literal with value 'V' and type 'type'.
Represents the results of name lookup.
NamedDecl * getFoundDecl() const
Fetch the unique decl found by this lookup.
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Represents a parameter to a function.
ParsedAttr - Represents a syntactic attribute.
unsigned getSemanticSpelling() const
If the parsed attribute has a semantic equivalent, and it would have a semantic Spelling enumeration ...
unsigned getMinArgs() const
bool checkExactlyNumArgs(class Sema &S, unsigned Num) const
Check if the attribute has exactly as many args as Num.
IdentifierLoc * getArgAsIdent(unsigned Arg) const
bool hasParsedType() const
const ParsedType & getTypeArg() const
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this attribute.
bool isArgIdent(unsigned Arg) const
Expr * getArgAsExpr(unsigned Arg) const
AttributeCommonInfo::Kind getKind() const
A (possibly-)qualified type.
void addRestrict()
Add the restrict qualifier to this QualType.
QualType getNonLValueExprType(const ASTContext &Context) const
Determine the type of a (typically non-lvalue) expression with the specified result type.
QualType getDesugaredType(const ASTContext &Context) const
Return the specified type with any "sugar" removed from the type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
LangAS getAddressSpace() const
Return the address space of this type.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
bool hasAddressSpace() const
Check if this type has any address space qualifier.
Represents a struct/union/class.
field_iterator field_end() const
field_range fields() const
field_iterator field_begin() const
bool hasBindingInfoForDecl(const VarDecl *VD) const
DeclBindingInfo * getDeclBindingInfo(const VarDecl *VD, ResourceClass ResClass)
DeclBindingInfo * addDeclBindingInfo(const VarDecl *VD, ResourceClass ResClass)
Scope - A scope is a transient data structure that is used while parsing the program.
ASTContext & getASTContext() const
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
ExprResult ActOnOutParamExpr(ParmVarDecl *Param, Expr *Arg)
HLSLRootSignatureDecl * lookupRootSignatureOverrideDecl(DeclContext *DC) const
bool CanPerformElementwiseCast(Expr *Src, QualType DestType)
void handleWaveSizeAttr(Decl *D, const ParsedAttr &AL)
void handleVkLocationAttr(Decl *D, const ParsedAttr &AL)
HLSLAttributedResourceLocInfo TakeLocForHLSLAttribute(const HLSLAttributedResourceType *RT)
void handleSemanticAttr(Decl *D, const ParsedAttr &AL)
bool CanPerformScalarCast(QualType SrcTy, QualType DestTy)
QualType ProcessResourceTypeAttributes(QualType Wrapped)
void handleShaderAttr(Decl *D, const ParsedAttr &AL)
void CheckEntryPoint(FunctionDecl *FD)
void emitLogicalOperatorFixIt(Expr *LHS, Expr *RHS, BinaryOperatorKind Opc)
T * createSemanticAttr(const AttributeCommonInfo &ACI, std::optional< unsigned > Location)
void ActOnEndOfTranslationUnit(TranslationUnitDecl *TU)
HLSLVkConstantIdAttr * mergeVkConstantIdAttr(Decl *D, const AttributeCommonInfo &AL, int Id)
HLSLNumThreadsAttr * mergeNumThreadsAttr(Decl *D, const AttributeCommonInfo &AL, int X, int Y, int Z)
void deduceAddressSpace(VarDecl *Decl)
std::pair< IdentifierInfo *, bool > ActOnStartRootSignatureDecl(StringRef Signature)
Computes the unique Root Signature identifier from the given signature, then lookup if there is a pre...
void handlePackOffsetAttr(Decl *D, const ParsedAttr &AL)
bool diagnosePositionType(QualType T, const ParsedAttr &AL)
bool handleInitialization(VarDecl *VDecl, Expr *&Init)
bool diagnoseInputIDType(QualType T, const ParsedAttr &AL)
void handleParamModifierAttr(Decl *D, const ParsedAttr &AL)
bool CheckResourceBinOp(BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr, SourceLocation Loc)
bool CanPerformAggregateSplatCast(Expr *Src, QualType DestType)
bool IsScalarizedLayoutCompatible(QualType T1, QualType T2) const
void diagnoseSystemSemanticAttr(Decl *D, const ParsedAttr &AL, std::optional< unsigned > Index)
void handleRootSignatureAttr(Decl *D, const ParsedAttr &AL)
bool CheckCompatibleParameterABI(FunctionDecl *New, FunctionDecl *Old)
QualType handleVectorBinOpConversion(ExprResult &LHS, ExprResult &RHS, QualType LHSType, QualType RHSType, bool IsCompAssign)
void handleResourceBindingAttr(Decl *D, const ParsedAttr &AL)
bool IsTypedResourceElementCompatible(QualType T1)
bool transformInitList(const InitializedEntity &Entity, InitListExpr *Init)
void handleNumThreadsAttr(Decl *D, const ParsedAttr &AL)
bool ActOnUninitializedVarDecl(VarDecl *D)
void handleVkExtBuiltinInputAttr(Decl *D, const ParsedAttr &AL)
void ActOnTopLevelFunction(FunctionDecl *FD)
bool handleResourceTypeAttr(QualType T, const ParsedAttr &AL)
void handleVkPushConstantAttr(Decl *D, const ParsedAttr &AL)
HLSLShaderAttr * mergeShaderAttr(Decl *D, const AttributeCommonInfo &AL, llvm::Triple::EnvironmentType ShaderType)
void ActOnFinishBuffer(Decl *Dcl, SourceLocation RBrace)
void handleVkBindingAttr(Decl *D, const ParsedAttr &AL)
HLSLParamModifierAttr * mergeParamModifierAttr(Decl *D, const AttributeCommonInfo &AL, HLSLParamModifierAttr::Spelling Spelling)
QualType getInoutParameterType(QualType Ty)
void handleVkConstantIdAttr(Decl *D, const ParsedAttr &AL)
Decl * ActOnStartBuffer(Scope *BufferScope, bool CBuffer, SourceLocation KwLoc, IdentifierInfo *Ident, SourceLocation IdentLoc, SourceLocation LBrace)
HLSLWaveSizeAttr * mergeWaveSizeAttr(Decl *D, const AttributeCommonInfo &AL, int Min, int Max, int Preferred, int SpelledArgsCount)
bool handleRootSignatureElements(ArrayRef< hlsl::RootSignatureElement > Elements)
void ActOnFinishRootSignatureDecl(SourceLocation Loc, IdentifierInfo *DeclIdent, ArrayRef< hlsl::RootSignatureElement > Elements)
Creates the Root Signature decl of the parsed Root Signature elements onto the AST and push it onto c...
void ActOnVariableDeclarator(VarDecl *VD)
bool CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
Sema - This implements semantic analysis and AST building for C.
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
@ LookupMemberName
Member name lookup, which finds the names of class/struct/union members.
ASTContext & getASTContext() const
ExprResult ImpCastExprToType(Expr *E, QualType Type, CastKind CK, ExprValueKind VK=VK_PRValue, const CXXCastPath *BasePath=nullptr, CheckedConversionKind CCK=CheckedConversionKind::Implicit)
ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast.
const LangOptions & getLangOpts() const
ExprResult BuildFieldReferenceExpr(Expr *BaseExpr, bool IsArrow, SourceLocation OpLoc, const CXXScopeSpec &SS, FieldDecl *Field, DeclAccessPair FoundDecl, const DeclarationNameInfo &MemberNameInfo)
ExprResult CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc, Expr *Idx, SourceLocation RLoc)
bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, bool InUnqualifiedLookup=false)
Perform qualified name lookup into a given context.
ExprResult PerformCopyInitialization(const InitializedEntity &Entity, SourceLocation EqualLoc, ExprResult Init, bool TopLevelOfInitList=false, bool AllowExplicit=false)
ExprResult CreateBuiltinMatrixSubscriptExpr(Expr *Base, Expr *RowIdx, Expr *ColumnIdx, SourceLocation RBLoc)
Encodes a location in the source.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getEndLoc() const LLVM_READONLY
void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\n", const ASTContext *Context=nullptr) const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
SourceLocation getBeginLoc() const LLVM_READONLY
static StringLiteral * Create(const ASTContext &Ctx, StringRef Str, StringLiteralKind Kind, bool Pascal, QualType Ty, ArrayRef< SourceLocation > Locs)
This is the "fully general" constructor that allows representation of strings formed from one or more...
void startDefinition()
Starts the definition of this tag declaration.
Exposes information about the current target.
TargetOptions & getTargetOpts() const
Retrieve the target options.
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
StringRef getPlatformName() const
Retrieve the name of the platform as it is used in the availability attribute.
VersionTuple getPlatformMinVersion() const
Retrieve the minimum desired version of the platform, to which the program should be compiled.
std::string HLSLEntry
The entry point name for HLSL shader being compiled as specified by -E.
The top declaration context.
SourceLocation getBeginLoc() const
Get the begin source location.
A container of type source information.
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
The base class of the type hierarchy.
bool isBooleanType() const
bool isIncompleteArrayType() const
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isConstantArrayType() const
bool hasIntegerRepresentation() const
Determine whether this type has an integer representation of some sort, e.g., it is an integer type o...
CXXRecordDecl * castAsCXXRecordDecl() const
bool isArithmeticType() const
bool isConstantMatrixType() const
bool isHLSLBuiltinIntangibleType() const
CanQualType getCanonicalTypeUnqualified() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
bool isHLSLIntangibleType() const
bool isEnumeralType() const
bool isScalarType() const
bool isIntegralType(const ASTContext &Ctx) const
Determine whether this type is an integral type.
const Type * getArrayElementTypeNoTypeQual() const
If this is an array type, return the element type of the array, potentially with type qualifiers miss...
bool hasUnsignedIntegerRepresentation() const
Determine whether this type has an unsigned integer representation of some sort, e....
bool isAggregateType() const
Determines whether the type is a C++ aggregate type or C aggregate or union type.
ScalarTypeKind getScalarTypeKind() const
Given that this is a scalar type, classify it.
bool hasSignedIntegerRepresentation() const
Determine whether this type has an signed integer representation of some sort, e.g....
bool isHLSLResourceRecord() const
bool hasFloatingRepresentation() const
Determine whether this type has a floating-point representation of some sort, e.g....
bool isVectorType() const
bool isRealFloatingType() const
Floating point categories.
bool isHLSLAttributedResourceType() const
bool isFloatingType() const
const T * getAs() const
Member-template getAs<specific type>'.
const Type * getUnqualifiedDesugaredType() const
Return the specified type with any "sugar" removed from the type, removing any typedefs,...
bool isRecordType() const
bool isHLSLResourceRecordArray() const
void setType(QualType newType)
Represents a variable declaration or definition.
void setInitStyle(InitializationStyle Style)
@ CallInit
Call-style initialization (C++98)
void setStorageClass(StorageClass SC)
bool hasGlobalStorage() const
Returns true for all variables that do not have local storage.
StorageClass getStorageClass() const
Returns the storage class as written in the source.
Represents a GCC generic vector type.
unsigned getNumElements() const
QualType getElementType() const
Defines the clang::TargetInfo interface.
uint32_t getResourceDimensions(llvm::dxil::ResourceDimension Dim)
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
static bool CheckFloatOrHalfRepresentation(Sema *S, SourceLocation Loc, int ArgOrdinal, clang::QualType PassedType)
@ ICIS_NoInit
No in-class initializer.
@ OK_Ordinary
An ordinary object is located at an address in memory.
static bool CheckAllArgTypesAreCorrect(Sema *S, CallExpr *TheCall, llvm::ArrayRef< llvm::function_ref< bool(Sema *, SourceLocation, int, QualType)> > Checks)
@ AANT_ArgumentIdentifier
@ Result
The result type of a method or function.
@ Ordinary
This parameter uses ordinary ABI rules for its type.
const FunctionProtoType * T
llvm::Expected< QualType > ExpectedType
static bool CheckAllArgsHaveSameType(Sema *S, CallExpr *TheCall)
@ Type
The name was classified as a type.
LangAS
Defines the address space values used by the address space qualifier of QualType.
bool CreateHLSLAttributedResourceType(Sema &S, QualType Wrapped, ArrayRef< const Attr * > AttrList, QualType &ResType, HLSLAttributedResourceLocInfo *LocInfo=nullptr)
CastKind
CastKind - The kind of operation required for a conversion.
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
DynamicRecursiveASTVisitorBase< false > DynamicRecursiveASTVisitor
U cast(CodeGen::Address addr)
ActionResult< Expr * > ExprResult
Visibility
Describes the different kinds of visibility that a declaration may have.
hash_code hash_value(const clang::dependencies::ModuleID &ID)
__DEVICE__ bool isnan(float __x)
__DEVICE__ _Tp abs(const std::complex< _Tp > &__c)
TypeSourceInfo * ContainedTyInfo
Describes how types, statements, expressions, and declarations should be printed.
void setCounterImplicitOrderID(unsigned Value) const
bool hasCounterImplicitOrderID() const
void setImplicitOrderID(unsigned Value) const
const SourceLocation & getLocation() const
const llvm::hlsl::rootsig::RootElement & getElement() const