15#include "clang/AST/Attrs.inc"
36#include "llvm/ADT/ArrayRef.h"
37#include "llvm/ADT/STLExtras.h"
38#include "llvm/ADT/SmallVector.h"
39#include "llvm/ADT/StringExtras.h"
40#include "llvm/ADT/StringRef.h"
41#include "llvm/ADT/Twine.h"
42#include "llvm/Frontend/HLSL/HLSLBinding.h"
43#include "llvm/Frontend/HLSL/RootSignatureValidations.h"
44#include "llvm/Support/Casting.h"
45#include "llvm/Support/DXILABI.h"
46#include "llvm/Support/ErrorHandling.h"
47#include "llvm/Support/FormatVariadic.h"
48#include "llvm/TargetParser/Triple.h"
62 case ResourceClass::SRV:
63 return RegisterType::SRV;
64 case ResourceClass::UAV:
65 return RegisterType::UAV;
66 case ResourceClass::CBuffer:
67 return RegisterType::CBuffer;
68 case ResourceClass::Sampler:
69 return RegisterType::Sampler;
71 llvm_unreachable(
"unexpected ResourceClass value");
81 assert(RT !=
nullptr);
85 *RT = RegisterType::SRV;
89 *RT = RegisterType::UAV;
93 *RT = RegisterType::CBuffer;
97 *RT = RegisterType::Sampler;
101 *RT = RegisterType::C;
105 *RT = RegisterType::I;
114 case RegisterType::SRV:
115 return ResourceClass::SRV;
116 case RegisterType::UAV:
117 return ResourceClass::UAV;
118 case RegisterType::CBuffer:
119 return ResourceClass::CBuffer;
120 case RegisterType::Sampler:
121 return ResourceClass::Sampler;
122 case RegisterType::C:
123 case RegisterType::I:
127 llvm_unreachable(
"unexpected RegisterType value");
131 const auto *BT = dyn_cast<BuiltinType>(
Type);
135 return Builtin::BI__builtin_get_spirv_spec_constant_int;
138 switch (BT->getKind()) {
139 case BuiltinType::Bool:
140 return Builtin::BI__builtin_get_spirv_spec_constant_bool;
141 case BuiltinType::Short:
142 return Builtin::BI__builtin_get_spirv_spec_constant_short;
143 case BuiltinType::Int:
144 return Builtin::BI__builtin_get_spirv_spec_constant_int;
145 case BuiltinType::LongLong:
146 return Builtin::BI__builtin_get_spirv_spec_constant_longlong;
147 case BuiltinType::UShort:
148 return Builtin::BI__builtin_get_spirv_spec_constant_ushort;
149 case BuiltinType::UInt:
150 return Builtin::BI__builtin_get_spirv_spec_constant_uint;
151 case BuiltinType::ULongLong:
152 return Builtin::BI__builtin_get_spirv_spec_constant_ulonglong;
153 case BuiltinType::Half:
154 return Builtin::BI__builtin_get_spirv_spec_constant_half;
155 case BuiltinType::Float:
156 return Builtin::BI__builtin_get_spirv_spec_constant_float;
157 case BuiltinType::Double:
158 return Builtin::BI__builtin_get_spirv_spec_constant_double;
165 ResourceClass ResClass) {
167 "DeclBindingInfo already added");
173 DeclToBindingListIndex.try_emplace(VD, BindingsList.size());
174 return &BindingsList.emplace_back(VD, ResClass);
178 ResourceClass ResClass) {
179 auto Entry = DeclToBindingListIndex.find(VD);
180 if (Entry != DeclToBindingListIndex.end()) {
181 for (
unsigned Index = Entry->getSecond();
182 Index < BindingsList.size() && BindingsList[Index].Decl == VD;
184 if (BindingsList[Index].ResClass == ResClass)
185 return &BindingsList[Index];
192 return DeclToBindingListIndex.contains(VD);
204 getASTContext(), LexicalParent, CBuffer, KwLoc, Ident, IdentLoc, LBrace);
207 auto RC = CBuffer ? llvm::hlsl::ResourceClass::CBuffer
208 : llvm::hlsl::ResourceClass::SRV;
228 "Scalar bit widths larger than 64 not supported");
238 constexpr unsigned CBufferAlign = 16;
241 for (
const FieldDecl *Field : RD->fields()) {
248 unsigned AlignSize = llvm::alignTo(Size, FieldAlign);
249 if ((AlignSize % CBufferAlign) + FieldSize > CBufferAlign) {
250 FieldAlign = CBufferAlign;
253 Size = llvm::alignTo(Size, FieldAlign);
260 unsigned ElementCount = AT->getSize().getZExtValue();
261 if (ElementCount == 0)
264 unsigned ElementSize =
266 unsigned AlignedElementSize = llvm::alignTo(ElementSize, CBufferAlign);
267 return AlignedElementSize * (ElementCount - 1) + ElementSize;
271 unsigned ElementCount = VT->getNumElements();
272 unsigned ElementSize =
274 return ElementSize * ElementCount;
288 bool HasPackOffset =
false;
289 bool HasNonPackOffset =
false;
291 VarDecl *Var = dyn_cast<VarDecl>(Field);
294 if (Field->hasAttr<HLSLPackOffsetAttr>()) {
295 PackOffsetVec.emplace_back(Var, Field->getAttr<HLSLPackOffsetAttr>());
296 HasPackOffset =
true;
298 HasNonPackOffset =
true;
305 if (HasNonPackOffset)
312 std::sort(PackOffsetVec.begin(), PackOffsetVec.end(),
313 [](
const std::pair<VarDecl *, HLSLPackOffsetAttr *> &LHS,
314 const std::pair<VarDecl *, HLSLPackOffsetAttr *> &RHS) {
315 return LHS.second->getOffsetInBytes() <
316 RHS.second->getOffsetInBytes();
318 for (
unsigned i = 0; i < PackOffsetVec.size() - 1; i++) {
319 VarDecl *Var = PackOffsetVec[i].first;
320 HLSLPackOffsetAttr *
Attr = PackOffsetVec[i].second;
322 unsigned Begin =
Attr->getOffsetInBytes();
323 unsigned End =
Begin + Size;
324 unsigned NextBegin = PackOffsetVec[i + 1].second->getOffsetInBytes();
325 if (End > NextBegin) {
326 VarDecl *NextVar = PackOffsetVec[i + 1].first;
338 CAT = dyn_cast<ConstantArrayType>(
340 return CAT !=
nullptr;
351 "expected array of resource records");
367 return RD->isEmpty();
396 Base.getType()->castAsCXXRecordDecl()))
407 assert(RD ==
nullptr &&
408 "there should be at most 1 record by a given name in a scope");
425 Name.append(NameBaseII->
getName());
432 size_t NameLength = Name.size();
441 Name.append(llvm::Twine(suffix).str());
442 II = &AST.
Idents.
get(Name, tok::TokenKind::identifier);
449 Name.truncate(NameLength);
490 "struct is already HLSL buffer compatible");
504 LS->
addAttr(PackedAttr::CreateImplicit(AST));
508 if (
unsigned NumBases = StructDecl->
getNumBases()) {
509 assert(NumBases == 1 &&
"HLSL supports only one base type");
559 LS->
addAttr(PackedAttr::CreateImplicit(AST));
584 uint32_t ImplicitBindingOrderID) {
586 HLSLResourceBindingAttr::CreateImplicit(S.
getASTContext(),
"",
"0", {});
587 Attr->setBinding(RT, std::nullopt, 0);
588 Attr->setImplicitBindingOrderID(ImplicitBindingOrderID);
594 auto *BufDecl = cast<HLSLBufferDecl>(Dcl);
595 BufDecl->setRBraceLoc(RBrace);
602 HLSLVkBindingAttr *VkBinding = Dcl->
getAttr<HLSLVkBindingAttr>();
603 HLSLResourceBindingAttr *RBA = Dcl->
getAttr<HLSLResourceBindingAttr>();
604 if (!VkBinding && (!RBA || !RBA->hasRegisterSlot())) {
608 uint32_t OrderID = getNextImplicitBindingOrderID();
610 RBA->setImplicitBindingOrderID(OrderID);
613 BufDecl->isCBuffer() ? RegisterType::CBuffer
623 int X,
int Y,
int Z) {
624 if (HLSLNumThreadsAttr *NT =
D->
getAttr<HLSLNumThreadsAttr>()) {
625 if (NT->getX() !=
X || NT->getY() != Y || NT->getZ() != Z) {
626 Diag(NT->getLocation(), diag::err_hlsl_attribute_param_mismatch) << AL;
627 Diag(AL.
getLoc(), diag::note_conflicting_attribute);
637 int Min,
int Max,
int Preferred,
638 int SpelledArgsCount) {
639 if (HLSLWaveSizeAttr *WS =
D->
getAttr<HLSLWaveSizeAttr>()) {
640 if (WS->getMin() !=
Min || WS->getMax() !=
Max ||
641 WS->getPreferred() != Preferred ||
642 WS->getSpelledArgsCount() != SpelledArgsCount) {
643 Diag(WS->getLocation(), diag::err_hlsl_attribute_param_mismatch) << AL;
644 Diag(AL.
getLoc(), diag::note_conflicting_attribute);
650 Result->setSpelledArgsCount(SpelledArgsCount);
654HLSLVkConstantIdAttr *
660 Diag(AL.
getLoc(), diag::warn_attribute_ignored) << AL;
664 auto *VD = cast<VarDecl>(
D);
668 Diag(VD->getLocation(), diag::err_specialization_const);
672 if (!VD->getType().isConstQualified()) {
673 Diag(VD->getLocation(), diag::err_specialization_const);
677 if (HLSLVkConstantIdAttr *CI =
D->
getAttr<HLSLVkConstantIdAttr>()) {
678 if (CI->getId() !=
Id) {
679 Diag(CI->getLocation(), diag::err_hlsl_attribute_param_mismatch) << AL;
680 Diag(AL.
getLoc(), diag::note_conflicting_attribute);
685 HLSLVkConstantIdAttr *
Result =
692 llvm::Triple::EnvironmentType ShaderType) {
693 if (HLSLShaderAttr *NT =
D->
getAttr<HLSLShaderAttr>()) {
694 if (NT->getType() != ShaderType) {
695 Diag(NT->getLocation(), diag::err_hlsl_attribute_param_mismatch) << AL;
696 Diag(AL.
getLoc(), diag::note_conflicting_attribute);
700 return HLSLShaderAttr::Create(
getASTContext(), ShaderType, AL);
703HLSLParamModifierAttr *
705 HLSLParamModifierAttr::Spelling Spelling) {
708 if (HLSLParamModifierAttr *PA =
D->
getAttr<HLSLParamModifierAttr>()) {
709 if ((PA->isIn() && Spelling == HLSLParamModifierAttr::Keyword_out) ||
710 (PA->isOut() && Spelling == HLSLParamModifierAttr::Keyword_in)) {
713 return HLSLParamModifierAttr::Create(
715 HLSLParamModifierAttr::Keyword_inout);
717 Diag(AL.
getLoc(), diag::err_hlsl_duplicate_parameter_modifier) << AL;
718 Diag(PA->getLocation(), diag::note_conflicting_attribute);
732 if (RootSigOverrideIdent) {
736 if (
auto *SignatureDecl =
748 if (HLSLShaderAttr::isValidShaderType(
Env) &&
Env != llvm::Triple::Library) {
749 if (
const auto *Shader = FD->
getAttr<HLSLShaderAttr>()) {
752 if (Shader->getType() !=
Env) {
753 Diag(Shader->getLocation(), diag::err_hlsl_entry_shader_attr_mismatch)
765 case llvm::Triple::UnknownEnvironment:
766 case llvm::Triple::Library:
769 llvm_unreachable(
"Unhandled environment in triple");
775 const auto *ShaderAttr = FD->
getAttr<HLSLShaderAttr>();
776 assert(ShaderAttr &&
"Entry point has no shader attribute");
777 llvm::Triple::EnvironmentType ST = ShaderAttr->getType();
781 case llvm::Triple::Pixel:
782 case llvm::Triple::Vertex:
783 case llvm::Triple::Geometry:
784 case llvm::Triple::Hull:
785 case llvm::Triple::Domain:
786 case llvm::Triple::RayGeneration:
787 case llvm::Triple::Intersection:
788 case llvm::Triple::AnyHit:
789 case llvm::Triple::ClosestHit:
790 case llvm::Triple::Miss:
791 case llvm::Triple::Callable:
792 if (
const auto *NT = FD->
getAttr<HLSLNumThreadsAttr>()) {
794 {llvm::Triple::Compute,
795 llvm::Triple::Amplification,
796 llvm::Triple::Mesh});
799 if (
const auto *WS = FD->
getAttr<HLSLWaveSizeAttr>()) {
801 {llvm::Triple::Compute,
802 llvm::Triple::Amplification,
803 llvm::Triple::Mesh});
808 case llvm::Triple::Compute:
809 case llvm::Triple::Amplification:
810 case llvm::Triple::Mesh:
811 if (!FD->
hasAttr<HLSLNumThreadsAttr>()) {
813 << llvm::Triple::getEnvironmentTypeName(ST);
816 if (
const auto *WS = FD->
getAttr<HLSLWaveSizeAttr>()) {
817 if (Ver < VersionTuple(6, 6)) {
818 Diag(WS->getLocation(), diag::err_hlsl_attribute_in_wrong_shader_model)
821 }
else if (WS->getSpelledArgsCount() > 1 && Ver < VersionTuple(6, 8)) {
824 diag::err_hlsl_attribute_number_arguments_insufficient_shader_model)
825 << WS << WS->getSpelledArgsCount() <<
"6.8";
831 llvm_unreachable(
"Unhandled environment in triple");
841 Diag(Param->getLocation(), diag::note_previous_decl) << Param;
851 auto *ShaderAttr = EntryPoint->
getAttr<HLSLShaderAttr>();
852 assert(ShaderAttr &&
"Entry point has no shader attribute");
853 llvm::Triple::EnvironmentType ST = ShaderAttr->getType();
855 switch (AnnotationAttr->
getKind()) {
856 case attr::HLSLSV_DispatchThreadID:
857 case attr::HLSLSV_GroupIndex:
858 case attr::HLSLSV_GroupThreadID:
859 case attr::HLSLSV_GroupID:
860 if (ST == llvm::Triple::Compute)
864 case attr::HLSLSV_Position:
867 if (ST == llvm::Triple::Pixel)
872 llvm_unreachable(
"Unknown HLSLAnnotationAttr");
877 const Attr *A, llvm::Triple::EnvironmentType Stage,
878 std::initializer_list<llvm::Triple::EnvironmentType> AllowedStages) {
880 llvm::transform(AllowedStages, std::back_inserter(StageStrings),
881 [](llvm::Triple::EnvironmentType ST) {
883 HLSLShaderAttr::ConvertEnvironmentTypeToStr(ST));
885 Diag(A->
getLoc(), diag::err_hlsl_attr_unsupported_in_stage)
886 << A->
getAttrName() << llvm::Triple::getEnvironmentTypeName(Stage)
887 << (AllowedStages.size() != 1) << join(StageStrings,
", ");
890template <CastKind Kind>
893 Ty = VTy->getElementType();
898template <CastKind Kind>
910 if (LHSFloat && RHSFloat) {
913 return castElement<CK_FloatingCast>(SemaRef, RHS, LHSType);
915 return castElement<CK_FloatingCast>(SemaRef, LHS, RHSType);
919 return castElement<CK_IntegralToFloating>(SemaRef, RHS, LHSType);
923 return castElement<clang::CK_FloatingToIntegral>(SemaRef, RHS, LHSType);
925 return castElement<CK_IntegralToFloating>(SemaRef, LHS, RHSType);
938 if (LHSSigned == RHSSigned) {
939 if (IsCompAssign || IntOrder >= 0)
940 return castElement<CK_IntegralCast>(SemaRef, RHS, LHSType);
942 return castElement<CK_IntegralCast>(SemaRef, LHS, RHSType);
947 if (IntOrder != (LHSSigned ? 1 : -1)) {
948 if (IsCompAssign || RHSSigned)
949 return castElement<CK_IntegralCast>(SemaRef, RHS, LHSType);
950 return castElement<CK_IntegralCast>(SemaRef, LHS, RHSType);
957 if (IsCompAssign || LHSSigned)
958 return castElement<CK_IntegralCast>(SemaRef, RHS, LHSType);
959 return castElement<CK_IntegralCast>(SemaRef, LHS, RHSType);
970 return castElement<CK_IntegralCast>(SemaRef, RHS, LHSType);
976 (void)castElement<CK_IntegralCast>(SemaRef, RHS, NewTy);
978 return castElement<CK_IntegralCast>(SemaRef, LHS, NewTy);
984 return CK_FloatingCast;
986 return CK_IntegralCast;
988 return CK_IntegralToFloating;
990 return CK_FloatingToIntegral;
1003 if (!LVecTy && IsCompAssign) {
1014 unsigned EndSz = std::numeric_limits<unsigned>::max();
1017 LSz = EndSz = LVecTy->getNumElements();
1020 assert(EndSz != std::numeric_limits<unsigned>::max() &&
1021 "one of the above should have had a value");
1025 if (IsCompAssign && LSz != EndSz) {
1027 diag::err_hlsl_vector_compound_assignment_truncation)
1028 << LHSType << RHSType;
1033 castVector<CK_HLSLVectorTruncation>(
SemaRef, RHS, RHSType, EndSz);
1034 if (!IsCompAssign && LVecTy && LVecTy->getNumElements() > EndSz)
1035 castVector<CK_HLSLVectorTruncation>(
SemaRef, LHS, LHSType, EndSz);
1038 castVector<CK_VectorSplat>(
SemaRef, RHS, RHSType, EndSz);
1039 if (!IsCompAssign && !LVecTy)
1040 castVector<CK_VectorSplat>(
SemaRef, LHS, LHSType, EndSz);
1052 LElTy, RElTy, IsCompAssign);
1055 "HLSL Vectors can only contain integer or floating point types");
1057 LElTy, RElTy, IsCompAssign);
1062 assert((Opc == BO_LOr || Opc == BO_LAnd) &&
1063 "Called with non-logical operator");
1065 llvm::raw_svector_ostream OS(Buff);
1067 StringRef NewFnName = Opc == BO_LOr ?
"or" :
"and";
1068 OS << NewFnName <<
"(";
1078std::pair<IdentifierInfo *, bool>
1081 std::string IdStr =
"__hlsl_rootsig_decl_" + std::to_string(Hash);
1088 return {DeclIdent,
Found};
1099 for (
auto &RootSigElement : RootElements)
1100 Elements.push_back(RootSigElement.getElement());
1106 SignatureDecl->setImplicit();
1112struct PerVisibilityBindingChecker {
1115 std::array<llvm::hlsl::BindingInfoBuilder, 8> Builders;
1119 llvm::dxbc::ShaderVisibility Vis;
1124 PerVisibilityBindingChecker(
SemaHLSL *S) : S(S) {}
1126 void trackBinding(llvm::dxbc::ShaderVisibility
Visibility,
1127 llvm::dxil::ResourceClass RC, uint32_t Space,
1128 uint32_t LowerBound, uint32_t UpperBound,
1131 assert(BuilderIndex < Builders.size() &&
1132 "Not enough builders for visibility type");
1133 Builders[BuilderIndex].trackBinding(RC, Space, LowerBound, UpperBound,
1134 static_cast<const void *
>(Elem));
1136 static_assert(llvm::to_underlying(llvm::dxbc::ShaderVisibility::All) == 0,
1137 "'All' visibility must come first");
1138 if (
Visibility == llvm::dxbc::ShaderVisibility::All)
1139 for (
size_t I = 1,
E = Builders.size(); I <
E; ++I)
1140 Builders[I].trackBinding(RC, Space, LowerBound, UpperBound,
1141 static_cast<const void *
>(Elem));
1143 ElemInfoMap.push_back({Elem,
Visibility,
false});
1147 auto It = llvm::lower_bound(
1149 [](
const auto &LHS,
const auto &RHS) {
return LHS.Elem < RHS; });
1150 assert(It->Elem == Elem &&
"Element not in map");
1154 bool checkOverlap() {
1155 llvm::sort(ElemInfoMap, [](
const auto &LHS,
const auto &RHS) {
1156 return LHS.Elem < RHS.Elem;
1159 bool HadOverlap =
false;
1161 using llvm::hlsl::BindingInfoBuilder;
1162 auto ReportOverlap = [
this,
1163 &HadOverlap](
const BindingInfoBuilder &Builder,
1164 const llvm::hlsl::Binding &Reported) {
1169 const llvm::hlsl::Binding &
Previous = Builder.findOverlapping(Reported);
1170 const auto *PrevElem =
1173 ElemInfo &Info =
getInfo(Elem);
1178 Info.Diagnosed =
true;
1180 ElemInfo &PrevInfo =
getInfo(PrevElem);
1181 llvm::dxbc::ShaderVisibility CommonVis =
1182 Info.Vis == llvm::dxbc::ShaderVisibility::All ? PrevInfo.Vis
1185 this->S->
Diag(Elem->
getLocation(), diag::err_hlsl_resource_range_overlap)
1186 << llvm::to_underlying(Reported.RC) << Reported.LowerBound
1187 << Reported.isUnbounded() << Reported.UpperBound
1192 this->S->
Diag(PrevElem->getLocation(),
1193 diag::note_hlsl_resource_range_here);
1196 for (BindingInfoBuilder &Builder : Builders)
1197 Builder.calculateBindingInfo(ReportOverlap);
1208 bool HadError =
false;
1210 uint32_t UpperBound) {
1212 this->
Diag(Loc, diag::err_hlsl_invalid_rootsig_value)
1213 << LowerBound << UpperBound;
1220 this->
Diag(Loc, diag::err_hlsl_invalid_rootsig_value)
1221 << llvm::formatv(
"{0:f}", LowerBound).sstr<6>()
1222 << llvm::formatv(
"{0:f}", UpperBound).sstr<6>();
1226 if (!llvm::hlsl::rootsig::verifyRegisterValue(Register))
1227 ReportError(
Loc, 0, 0xfffffffe);
1231 if (!llvm::hlsl::rootsig::verifyRegisterSpace(Space))
1232 ReportError(
Loc, 0, 0xffffffef);
1235 const uint32_t Version =
1237 const uint32_t VersionEnum = Version - 1;
1240 this->
Diag(Loc, diag::err_hlsl_invalid_rootsig_flag)
1247 const llvm::hlsl::rootsig::RootElement &Elem = RootSigElem.
getElement();
1248 if (
const auto *Descriptor =
1249 std::get_if<llvm::hlsl::rootsig::RootDescriptor>(&Elem)) {
1250 VerifyRegister(
Loc, Descriptor->Reg.Number);
1251 VerifySpace(
Loc, Descriptor->Space);
1253 if (!llvm::hlsl::rootsig::verifyRootDescriptorFlag(
1254 Version, llvm::to_underlying(Descriptor->Flags)))
1255 ReportFlagError(
Loc);
1256 }
else if (
const auto *Constants =
1257 std::get_if<llvm::hlsl::rootsig::RootConstants>(&Elem)) {
1258 VerifyRegister(
Loc, Constants->Reg.Number);
1259 VerifySpace(
Loc, Constants->Space);
1260 }
else if (
const auto *Sampler =
1261 std::get_if<llvm::hlsl::rootsig::StaticSampler>(&Elem)) {
1262 VerifyRegister(
Loc, Sampler->Reg.Number);
1263 VerifySpace(
Loc, Sampler->Space);
1265 assert(!std::isnan(Sampler->MaxLOD) && !std::isnan(Sampler->MinLOD) &&
1266 "By construction, parseFloatParam can't produce a NaN from a "
1267 "float_literal token");
1269 if (!llvm::hlsl::rootsig::verifyMaxAnisotropy(Sampler->MaxAnisotropy))
1270 ReportError(
Loc, 0, 16);
1271 if (!llvm::hlsl::rootsig::verifyMipLODBias(Sampler->MipLODBias))
1272 ReportFloatError(
Loc, -16.f, 15.99f);
1273 }
else if (
const auto *Clause =
1274 std::get_if<llvm::hlsl::rootsig::DescriptorTableClause>(
1276 VerifyRegister(
Loc, Clause->Reg.Number);
1277 VerifySpace(
Loc, Clause->Space);
1279 if (!llvm::hlsl::rootsig::verifyNumDescriptors(Clause->NumDescriptors)) {
1283 ReportError(
Loc, 1, 0xfffffffe);
1286 if (!llvm::hlsl::rootsig::verifyDescriptorRangeFlag(
1287 Version, llvm::to_underlying(Clause->Type),
1288 llvm::to_underlying(Clause->Flags)))
1289 ReportFlagError(
Loc);
1293 PerVisibilityBindingChecker BindingChecker(
this);
1294 SmallVector<std::pair<
const llvm::hlsl::rootsig::DescriptorTableClause *,
1299 const llvm::hlsl::rootsig::RootElement &Elem = RootSigElem.
getElement();
1300 if (
const auto *Descriptor =
1301 std::get_if<llvm::hlsl::rootsig::RootDescriptor>(&Elem)) {
1302 uint32_t LowerBound(Descriptor->Reg.Number);
1303 uint32_t UpperBound(LowerBound);
1305 BindingChecker.trackBinding(
1306 Descriptor->Visibility,
1307 static_cast<llvm::dxil::ResourceClass
>(Descriptor->Type),
1308 Descriptor->Space, LowerBound, UpperBound, &RootSigElem);
1309 }
else if (
const auto *Constants =
1310 std::get_if<llvm::hlsl::rootsig::RootConstants>(&Elem)) {
1311 uint32_t LowerBound(Constants->Reg.Number);
1312 uint32_t UpperBound(LowerBound);
1314 BindingChecker.trackBinding(
1315 Constants->Visibility, llvm::dxil::ResourceClass::CBuffer,
1316 Constants->Space, LowerBound, UpperBound, &RootSigElem);
1317 }
else if (
const auto *Sampler =
1318 std::get_if<llvm::hlsl::rootsig::StaticSampler>(&Elem)) {
1319 uint32_t LowerBound(Sampler->Reg.Number);
1320 uint32_t UpperBound(LowerBound);
1322 BindingChecker.trackBinding(
1323 Sampler->Visibility, llvm::dxil::ResourceClass::Sampler,
1324 Sampler->Space, LowerBound, UpperBound, &RootSigElem);
1325 }
else if (
const auto *Clause =
1326 std::get_if<llvm::hlsl::rootsig::DescriptorTableClause>(
1329 UnboundClauses.emplace_back(Clause, &RootSigElem);
1330 }
else if (
const auto *Table =
1331 std::get_if<llvm::hlsl::rootsig::DescriptorTable>(&Elem)) {
1332 assert(UnboundClauses.size() == Table->NumClauses &&
1333 "Number of unbound elements must match the number of clauses");
1334 for (
const auto &[Clause, ClauseElem] : UnboundClauses) {
1335 uint32_t LowerBound(Clause->Reg.Number);
1338 if (Clause->NumDescriptors == 0)
1340 uint32_t UpperBound = Clause->NumDescriptors == ~0u
1342 : LowerBound + Clause->NumDescriptors - 1;
1344 BindingChecker.trackBinding(
1346 static_cast<llvm::dxil::ResourceClass
>(Clause->Type), Clause->Space,
1347 LowerBound, UpperBound, ClauseElem);
1349 UnboundClauses.clear();
1353 return BindingChecker.checkOverlap();
1358 Diag(AL.
getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1;
1363 if (
auto *RS =
D->
getAttr<RootSignatureAttr>()) {
1364 if (RS->getSignatureIdent() != Ident) {
1365 Diag(AL.
getLoc(), diag::err_disallowed_duplicate_attribute) << RS;
1369 Diag(AL.
getLoc(), diag::warn_duplicate_attribute_exact) << RS;
1375 if (
auto *SignatureDecl =
1383 llvm::VersionTuple SMVersion =
1388 uint32_t ZMax = 1024;
1389 uint32_t ThreadMax = 1024;
1390 if (IsDXIL && SMVersion.getMajor() <= 4) {
1393 }
else if (IsDXIL && SMVersion.getMajor() == 5) {
1403 diag::err_hlsl_numthreads_argument_oor)
1412 diag::err_hlsl_numthreads_argument_oor)
1421 diag::err_hlsl_numthreads_argument_oor)
1426 if (
X * Y * Z > ThreadMax) {
1427 Diag(AL.
getLoc(), diag::err_hlsl_numthreads_invalid) << ThreadMax;
1444 if (SpelledArgsCount == 0 || SpelledArgsCount > 3)
1452 if (SpelledArgsCount > 1 &&
1456 uint32_t Preferred = 0;
1457 if (SpelledArgsCount > 2 &&
1461 if (SpelledArgsCount > 2) {
1464 diag::err_attribute_power_of_two_in_range)
1465 << AL << llvm::dxil::MinWaveSize << llvm::dxil::MaxWaveSize
1470 if (Preferred < Min || Preferred >
Max) {
1472 diag::err_attribute_power_of_two_in_range)
1473 << AL <<
Min <<
Max << Preferred;
1476 }
else if (SpelledArgsCount > 1) {
1479 diag::err_attribute_power_of_two_in_range)
1480 << AL << llvm::dxil::MinWaveSize << llvm::dxil::MaxWaveSize <<
Max;
1484 Diag(AL.
getLoc(), diag::err_attribute_argument_invalid) << AL << 1;
1487 Diag(AL.
getLoc(), diag::warn_attr_min_eq_max) << AL;
1492 diag::err_attribute_power_of_two_in_range)
1493 << AL << llvm::dxil::MinWaveSize << llvm::dxil::MaxWaveSize <<
Min;
1498 HLSLWaveSizeAttr *NewAttr =
1526 uint32_t Binding = 0;
1542 (VT && VT->getNumElements() > 3)) {
1543 Diag(AL.
getLoc(), diag::err_hlsl_attr_invalid_type)
1544 << AL <<
"uint/uint2/uint3";
1552 auto *VD = cast<ValueDecl>(
D);
1564 Diag(AL.
getLoc(), diag::err_hlsl_attr_invalid_type)
1565 << AL <<
"float/float1/float2/float3/float4";
1573 auto *VD = cast<ValueDecl>(
D);
1581 auto *VD = cast<ValueDecl>(
D);
1590 auto *VD = cast<ValueDecl>(
D);
1599 Diag(AL.
getLoc(), diag::err_hlsl_attr_invalid_ast_node)
1600 << AL <<
"shader constant in a constant buffer";
1604 uint32_t SubComponent;
1611 QualType T = cast<VarDecl>(
D)->getType().getCanonicalType();
1619 if (IsAggregateTy || Size > 128) {
1620 Diag(AL.
getLoc(), diag::err_hlsl_packoffset_cross_reg_boundary);
1624 if ((Component * 32 + Size) > 128) {
1625 Diag(AL.
getLoc(), diag::err_hlsl_packoffset_cross_reg_boundary);
1630 EltTy = VT->getElementType();
1632 if (Align > 32 && Component == 1) {
1635 Diag(AL.
getLoc(), diag::err_hlsl_packoffset_alignment_mismatch)
1652 llvm::Triple::EnvironmentType ShaderType;
1653 if (!HLSLShaderAttr::ConvertStrToEnvironmentType(Str, ShaderType)) {
1654 Diag(AL.
getLoc(), diag::warn_attribute_type_not_supported)
1655 << AL << Str << ArgLoc;
1669 assert(AttrList.size() &&
"expected list of resource attributes");
1678 bool HasResourceClass =
false;
1679 for (
const Attr *A : AttrList) {
1682 LocEnd = A->getRange().getEnd();
1683 switch (A->getKind()) {
1684 case attr::HLSLResourceClass: {
1685 ResourceClass RC = cast<HLSLResourceClassAttr>(A)->getResourceClass();
1686 if (HasResourceClass) {
1688 ? diag::warn_duplicate_attribute_exact
1689 : diag::warn_duplicate_attribute)
1694 HasResourceClass =
true;
1698 if (ResAttrs.
IsROV) {
1699 S.
Diag(A->getLocation(), diag::warn_duplicate_attribute_exact) << A;
1702 ResAttrs.
IsROV =
true;
1704 case attr::HLSLRawBuffer:
1706 S.
Diag(A->getLocation(), diag::warn_duplicate_attribute_exact) << A;
1711 case attr::HLSLContainedType: {
1712 const HLSLContainedTypeAttr *CTAttr = cast<HLSLContainedTypeAttr>(A);
1714 if (!ContainedTy.
isNull()) {
1715 S.
Diag(A->getLocation(), ContainedTy == Ty
1716 ? diag::warn_duplicate_attribute_exact
1717 : diag::warn_duplicate_attribute)
1726 llvm_unreachable(
"unhandled resource attribute type");
1730 if (!HasResourceClass) {
1731 S.
Diag(AttrList.back()->getRange().getEnd(),
1732 diag::err_hlsl_missing_resource_class);
1737 Wrapped, ContainedTy, ResAttrs);
1739 if (LocInfo && ContainedTyInfo) {
1752 if (!
T->isHLSLResourceType()) {
1753 Diag(AL.
getLoc(), diag::err_hlsl_attribute_needs_intangible_type)
1768 AttributeCommonInfo::AS_CXX11, 0, false ,
1773 case ParsedAttr::AT_HLSLResourceClass: {
1775 Diag(AL.
getLoc(), diag::err_attribute_argument_type)
1786 if (!HLSLResourceClassAttr::ConvertStrToResourceClass(
Identifier, RC)) {
1787 Diag(ArgLoc, diag::warn_attribute_type_not_supported)
1791 A = HLSLResourceClassAttr::Create(
getASTContext(), RC, ACI);
1795 case ParsedAttr::AT_HLSLROV:
1799 case ParsedAttr::AT_HLSLRawBuffer:
1803 case ParsedAttr::AT_HLSLContainedType: {
1805 Diag(AL.
getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1;
1811 assert(TSI &&
"no type source info for attribute argument");
1813 diag::err_incomplete_type))
1815 A = HLSLContainedTypeAttr::Create(
getASTContext(), TSI, ACI);
1820 llvm_unreachable(
"unhandled HLSL attribute");
1823 HLSLResourcesTypeAttrs.emplace_back(A);
1829 if (!HLSLResourcesTypeAttrs.size())
1835 HLSLResourcesTypeAttrs, QT, &LocInfo)) {
1837 cast<HLSLAttributedResourceType>(QT.
getTypePtr());
1843 LocsForHLSLAttributedResources.insert(std::pair(RT, LocInfo));
1845 HLSLResourcesTypeAttrs.clear();
1853 auto I = LocsForHLSLAttributedResources.find(RT);
1854 if (I != LocsForHLSLAttributedResources.end()) {
1855 LocInfo = I->second;
1856 LocsForHLSLAttributedResources.erase(I);
1865void SemaHLSL::collectResourceBindingsOnUserRecordDecl(
const VarDecl *VD,
1874 "incomplete arrays inside user defined types are not supported");
1889 Bindings.addDeclBindingInfo(VD, RC);
1890 }
else if (
const RecordType *RT = dyn_cast<RecordType>(Ty)) {
1896 collectResourceBindingsOnUserRecordDecl(VD, RT);
1908 bool SpecifiedSpace) {
1909 int RegTypeNum =
static_cast<int>(RegType);
1912 if (
D->
hasAttr<HLSLGroupSharedAddressSpaceAttr>()) {
1913 S.
Diag(ArgLoc, diag::err_hlsl_binding_type_mismatch) << RegTypeNum;
1919 ResourceClass RC = CBufferOrTBuffer->isCBuffer() ? ResourceClass::CBuffer
1920 : ResourceClass::SRV;
1930 assert(isa<VarDecl>(
D) &&
"D is expected to be VarDecl or HLSLBufferDecl");
1952 if (SpecifiedSpace && !DeclaredInCOrTBuffer)
1953 S.
Diag(ArgLoc, diag::err_hlsl_space_on_global_constant);
1958 if (RegType == RegisterType::CBuffer)
1959 S.
Diag(ArgLoc, diag::warn_hlsl_deprecated_register_type_b);
1960 else if (RegType != RegisterType::C)
1961 S.
Diag(ArgLoc, diag::err_hlsl_binding_type_mismatch) << RegTypeNum;
1965 if (RegType == RegisterType::C)
1966 S.
Diag(ArgLoc, diag::warn_hlsl_register_type_c_packoffset);
1968 S.
Diag(ArgLoc, diag::err_hlsl_binding_type_mismatch) << RegTypeNum;
1978 S.
Diag(ArgLoc, diag::err_hlsl_binding_type_mismatch) << RegTypeNum;
1986 bool RegisterTypesDetected[5] = {
false};
1987 RegisterTypesDetected[
static_cast<int>(regType)] =
true;
1990 if (HLSLResourceBindingAttr *
attr =
1991 dyn_cast<HLSLResourceBindingAttr>(*it)) {
1994 if (RegisterTypesDetected[
static_cast<int>(otherRegType)]) {
1995 int otherRegTypeNum =
static_cast<int>(otherRegType);
1997 diag::err_hlsl_duplicate_register_annotation)
2001 RegisterTypesDetected[
static_cast<int>(otherRegType)] =
true;
2009 bool SpecifiedSpace) {
2012 assert(((isa<VarDecl>(
D) && !isa<HLSLBufferDecl>(
D)) ||
2013 (!isa<VarDecl>(
D) && isa<HLSLBufferDecl>(
D))) &&
2014 "expecting VarDecl or HLSLBufferDecl");
2025 if (isa<VarDecl>(TheDecl)) {
2027 cast<ValueDecl>(TheDecl)->getType(),
2028 diag::err_incomplete_type))
2032 StringRef Slot =
"";
2033 StringRef Space =
"";
2037 Diag(AL.
getLoc(), diag::err_attribute_argument_type)
2044 Slot =
Loc->getIdentifierInfo()->getName();
2045 SlotLoc =
Loc->getLoc();
2047 Diag(AL.
getLoc(), diag::err_attribute_argument_type)
2052 Space =
Loc->getIdentifierInfo()->getName();
2053 SpaceLoc =
Loc->getLoc();
2055 StringRef Str =
Loc->getIdentifierInfo()->getName();
2056 if (Str.starts_with(
"space")) {
2058 SpaceLoc =
Loc->getLoc();
2061 SlotLoc =
Loc->getLoc();
2067 std::optional<unsigned> SlotNum;
2068 unsigned SpaceNum = 0;
2071 if (!Slot.empty()) {
2073 Diag(SlotLoc, diag::err_hlsl_binding_type_invalid) << Slot.substr(0, 1);
2076 if (RegType == RegisterType::I) {
2077 Diag(SlotLoc, diag::warn_hlsl_deprecated_register_type_i);
2080 StringRef SlotNumStr = Slot.substr(1);
2082 if (SlotNumStr.getAsInteger(10, N)) {
2083 Diag(SlotLoc, diag::err_hlsl_unsupported_register_number);
2090 if (!Space.starts_with(
"space")) {
2091 Diag(SpaceLoc, diag::err_hlsl_expected_space) << Space;
2094 StringRef SpaceNumStr = Space.substr(5);
2095 if (SpaceNumStr.getAsInteger(10, SpaceNum)) {
2096 Diag(SpaceLoc, diag::err_hlsl_expected_space) << Space;
2101 if (SlotNum.has_value())
2106 HLSLResourceBindingAttr *NewAttr =
2107 HLSLResourceBindingAttr::Create(
getASTContext(), Slot, Space, AL);
2109 NewAttr->setBinding(RegType, SlotNum, SpaceNum);
2164 llvm::DenseMap<const FunctionDecl *, unsigned> ScannedDecls;
2168 llvm::Triple::EnvironmentType CurrentShaderEnvironment;
2169 unsigned CurrentShaderStageBit;
2174 bool ReportOnlyShaderStageIssues;
2177 void SetShaderStageContext(llvm::Triple::EnvironmentType ShaderType) {
2178 static_assert(
sizeof(
unsigned) >= 4);
2179 assert(HLSLShaderAttr::isValidShaderType(ShaderType));
2180 assert((
unsigned)(ShaderType - llvm::Triple::Pixel) < 31 &&
2181 "ShaderType is too big for this bitmap");
2184 unsigned bitmapIndex = ShaderType - llvm::Triple::Pixel;
2185 CurrentShaderEnvironment = ShaderType;
2186 CurrentShaderStageBit = (1 << bitmapIndex);
2189 void SetUnknownShaderStageContext() {
2190 CurrentShaderEnvironment = llvm::Triple::UnknownEnvironment;
2191 CurrentShaderStageBit = (1 << 31);
2194 llvm::Triple::EnvironmentType GetCurrentShaderEnvironment()
const {
2195 return CurrentShaderEnvironment;
2198 bool InUnknownShaderStageContext()
const {
2199 return CurrentShaderEnvironment == llvm::Triple::UnknownEnvironment;
2204 unsigned &ScannedStages = ScannedDecls[FD];
2205 ScannedStages |= CurrentShaderStageBit;
2208 unsigned GetScannedStages(
const FunctionDecl *FD) {
return ScannedDecls[FD]; }
2210 bool WasAlreadyScannedInCurrentStage(
const FunctionDecl *FD) {
2211 return WasAlreadyScannedInCurrentStage(GetScannedStages(FD));
2214 bool WasAlreadyScannedInCurrentStage(
unsigned ScannerStages) {
2215 return ScannerStages & CurrentShaderStageBit;
2218 static bool NeverBeenScanned(
unsigned ScannedStages) {
2219 return ScannedStages == 0;
2224 void CheckDeclAvailability(
NamedDecl *
D,
const AvailabilityAttr *AA,
2226 const AvailabilityAttr *FindAvailabilityAttr(
const Decl *
D);
2227 bool HasMatchingEnvironmentOrNone(
const AvailabilityAttr *AA);
2230 DiagnoseHLSLAvailability(
Sema &SemaRef)
2232 CurrentShaderEnvironment(
llvm::Triple::UnknownEnvironment),
2233 CurrentShaderStageBit(0), ReportOnlyShaderStageIssues(
false) {}
2239 bool VisitDeclRefExpr(
DeclRefExpr *DRE)
override {
2242 HandleFunctionOrMethodRef(FD, DRE);
2246 bool VisitMemberExpr(
MemberExpr *ME)
override {
2249 HandleFunctionOrMethodRef(FD, ME);
2254void DiagnoseHLSLAvailability::HandleFunctionOrMethodRef(
FunctionDecl *FD,
2256 assert((isa<DeclRefExpr>(RefExpr) || isa<MemberExpr>(RefExpr)) &&
2257 "expected DeclRefExpr or MemberExpr");
2261 if (FD->
hasBody(FDWithBody)) {
2262 if (!WasAlreadyScannedInCurrentStage(FDWithBody))
2263 DeclsToScan.push_back(FDWithBody);
2268 const AvailabilityAttr *AA = FindAvailabilityAttr(FD);
2270 CheckDeclAvailability(
2274void DiagnoseHLSLAvailability::RunOnTranslationUnit(
2283 DeclContextsToScan.push_back(TU);
2285 while (!DeclContextsToScan.empty()) {
2286 const DeclContext *DC = DeclContextsToScan.pop_back_val();
2287 for (
auto &
D : DC->
decls()) {
2294 if (llvm::dyn_cast<NamespaceDecl>(
D) || llvm::dyn_cast<ExportDecl>(
D)) {
2295 DeclContextsToScan.push_back(llvm::dyn_cast<DeclContext>(
D));
2305 if (HLSLShaderAttr *ShaderAttr = FD->
getAttr<HLSLShaderAttr>()) {
2306 SetShaderStageContext(ShaderAttr->getType());
2315 for (
const auto *Redecl : FD->
redecls()) {
2316 if (Redecl->isInExportDeclContext()) {
2323 SetUnknownShaderStageContext();
2331void DiagnoseHLSLAvailability::RunOnFunction(
const FunctionDecl *FD) {
2332 assert(DeclsToScan.empty() &&
"DeclsToScan should be empty");
2333 DeclsToScan.push_back(FD);
2335 while (!DeclsToScan.empty()) {
2343 const unsigned ScannedStages = GetScannedStages(FD);
2344 if (WasAlreadyScannedInCurrentStage(ScannedStages))
2347 ReportOnlyShaderStageIssues = !NeverBeenScanned(ScannedStages);
2349 AddToScannedFunctions(FD);
2354bool DiagnoseHLSLAvailability::HasMatchingEnvironmentOrNone(
2355 const AvailabilityAttr *AA) {
2360 llvm::Triple::EnvironmentType CurrentEnv = GetCurrentShaderEnvironment();
2361 if (CurrentEnv == llvm::Triple::UnknownEnvironment)
2364 llvm::Triple::EnvironmentType AttrEnv =
2365 AvailabilityAttr::getEnvironmentType(IIEnvironment->
getName());
2367 return CurrentEnv == AttrEnv;
2370const AvailabilityAttr *
2371DiagnoseHLSLAvailability::FindAvailabilityAttr(
const Decl *
D) {
2372 AvailabilityAttr
const *PartialMatch =
nullptr;
2376 for (
const auto *A :
D->
attrs()) {
2377 if (
const auto *Avail = dyn_cast<AvailabilityAttr>(A)) {
2378 StringRef AttrPlatform = Avail->getPlatform()->getName();
2379 StringRef TargetPlatform =
2383 if (AttrPlatform == TargetPlatform) {
2385 if (HasMatchingEnvironmentOrNone(Avail))
2387 PartialMatch = Avail;
2391 return PartialMatch;
2396void DiagnoseHLSLAvailability::CheckDeclAvailability(
NamedDecl *
D,
2397 const AvailabilityAttr *AA,
2416 if (ReportOnlyShaderStageIssues)
2422 if (InUnknownShaderStageContext())
2427 bool EnvironmentMatches = HasMatchingEnvironmentOrNone(AA);
2428 VersionTuple Introduced = AA->getIntroduced();
2437 llvm::StringRef PlatformName(
2440 llvm::StringRef CurrentEnvStr =
2441 llvm::Triple::getEnvironmentTypeName(GetCurrentShaderEnvironment());
2443 llvm::StringRef AttrEnvStr =
2444 AA->getEnvironment() ? AA->getEnvironment()->getName() :
"";
2445 bool UseEnvironment = !AttrEnvStr.empty();
2447 if (EnvironmentMatches) {
2449 <<
Range <<
D << PlatformName << Introduced.getAsString()
2450 << UseEnvironment << CurrentEnvStr;
2456 SemaRef.
Diag(
D->
getLocation(), diag::note_partial_availability_specified_here)
2457 <<
D << PlatformName << Introduced.getAsString()
2459 << UseEnvironment << AttrEnvStr << CurrentEnvStr;
2466 if (!DefaultCBufferDecls.empty()) {
2469 DefaultCBufferDecls);
2471 getNextImplicitBindingOrderID());
2476 for (
const Decl *VD : DefaultCBufferDecls) {
2477 const HLSLResourceBindingAttr *RBA =
2478 VD->
getAttr<HLSLResourceBindingAttr>();
2479 if (RBA && RBA->hasRegisterSlot() &&
2480 RBA->getRegisterType() == HLSLResourceBindingAttr::RegisterType::C) {
2489 diagnoseAvailabilityViolations(TU);
2499 TI.
getTriple().getEnvironment() != llvm::Triple::EnvironmentType::Library)
2502 DiagnoseHLSLAvailability(
SemaRef).RunOnTranslationUnit(TU);
2509 for (
unsigned I = 1, N = TheCall->
getNumArgs(); I < N; ++I) {
2512 S->
Diag(TheCall->
getBeginLoc(), diag::err_vec_builtin_incompatible_vector)
2537 for (
unsigned I = 0; I < TheCall->
getNumArgs(); ++I) {
2553 return S->
Diag(
Loc, diag::err_builtin_invalid_arg_type)
2554 << ArgOrdinal << 5 << 0
2560 unsigned ArgIndex) {
2561 auto *Arg = TheCall->
getArg(ArgIndex);
2563 if (Arg->IgnoreCasts()->isModifiableLvalue(S->
Context, &OrigLoc) ==
2566 S->
Diag(OrigLoc, diag::error_hlsl_inout_lvalue) << Arg << 0;
2576 if (VecTy->getElementType()->isDoubleType())
2577 return S->
Diag(
Loc, diag::err_builtin_invalid_arg_type)
2578 << ArgOrdinal << 1 << 0 << 1
2588 return S->
Diag(
Loc, diag::err_builtin_invalid_arg_type)
2589 << ArgOrdinal << 5 << 1
2598 if (VecTy->getElementType()->isUnsignedIntegerType())
2601 return S->
Diag(
Loc, diag::err_builtin_invalid_arg_type)
2602 << ArgOrdinal << 4 << 3 << 0
2611 return S->
Diag(
Loc, diag::err_builtin_invalid_arg_type)
2612 << ArgOrdinal << 5 << 3
2628 unsigned ArgIndex) {
2637 diag::err_typecheck_expect_scalar_or_vector)
2638 << ArgType << Scalar;
2645 unsigned ArgIndex) {
2651 (VTy && VTy->getElementType()->isScalarType()))) {
2653 diag::err_typecheck_expect_any_scalar_or_vector)
2670 diag::err_typecheck_expect_any_scalar_or_vector)
2683 diag::err_typecheck_call_different_arg_types)
2702 Arg1ScalarTy = VTy->getElementType();
2706 Arg2ScalarTy = VTy->getElementType();
2709 S->
Diag(Arg1->
getBeginLoc(), diag::err_hlsl_builtin_scalar_vector_mismatch)
2710 << 1 << TheCall->
getCallee() << Arg1Ty << Arg2Ty;
2720 if (Arg1Length > 0 && Arg0Length != Arg1Length) {
2722 diag::err_typecheck_vector_lengths_not_equal)
2728 if (Arg2Length > 0 && Arg0Length != Arg2Length) {
2730 diag::err_typecheck_vector_lengths_not_equal)
2751 diag::err_typecheck_expect_hlsl_resource)
2755 if (Check && Check(ResTy)) {
2757 diag::err_invalid_hlsl_resource_type)
2767 switch (BuiltinID) {
2768 case Builtin::BI__builtin_hlsl_adduint64: {
2782 if (ElementBitCount != 32) {
2784 diag::err_integer_incorrect_bit_count)
2785 << 32 << ElementBitCount;
2790 int NumElementsArg = VTy->getNumElements();
2791 if (NumElementsArg != 2 && NumElementsArg != 4) {
2793 << 1 << 64 << NumElementsArg * ElementBitCount;
2807 case Builtin::BI__builtin_hlsl_resource_getpointer: {
2816 QualType ContainedTy = ResourceTy->getContainedType();
2825 case Builtin::BI__builtin_hlsl_resource_uninitializedhandle: {
2834 case Builtin::BI__builtin_hlsl_resource_handlefrombinding: {
2850 case Builtin::BI__builtin_hlsl_resource_handlefromimplicitbinding: {
2866 case Builtin::BI__builtin_hlsl_and:
2867 case Builtin::BI__builtin_hlsl_or: {
2881 case Builtin::BI__builtin_hlsl_all:
2882 case Builtin::BI__builtin_hlsl_any: {
2889 case Builtin::BI__builtin_hlsl_asdouble: {
2908 case Builtin::BI__builtin_hlsl_elementwise_clamp: {
2915 case Builtin::BI__builtin_hlsl_dot: {
2923 case Builtin::BI__builtin_hlsl_elementwise_firstbithigh:
2924 case Builtin::BI__builtin_hlsl_elementwise_firstbitlow: {
2935 EltTy = VecTy->getElementType();
2949 case Builtin::BI__builtin_hlsl_select: {
2958 if (VTy && VTy->getElementType()->isBooleanType() &&
2963 case Builtin::BI__builtin_hlsl_elementwise_saturate:
2964 case Builtin::BI__builtin_hlsl_elementwise_rcp: {
2971 diag::err_builtin_invalid_arg_type)
2978 case Builtin::BI__builtin_hlsl_elementwise_degrees:
2979 case Builtin::BI__builtin_hlsl_elementwise_radians:
2980 case Builtin::BI__builtin_hlsl_elementwise_rsqrt:
2981 case Builtin::BI__builtin_hlsl_elementwise_frac: {
2991 case Builtin::BI__builtin_hlsl_elementwise_isinf: {
3002 case Builtin::BI__builtin_hlsl_lerp: {
3014 case Builtin::BI__builtin_hlsl_mad: {
3021 case Builtin::BI__builtin_hlsl_normalize: {
3033 case Builtin::BI__builtin_hlsl_elementwise_sign: {
3042 case Builtin::BI__builtin_hlsl_step: {
3055 case Builtin::BI__builtin_hlsl_wave_active_max:
3056 case Builtin::BI__builtin_hlsl_wave_active_sum: {
3072 case Builtin::BI__builtin_elementwise_bitreverse: {
3080 case Builtin::BI__builtin_hlsl_wave_read_lane_at: {
3086 QualType ArgTyIndex = Index.get()->getType();
3089 diag::err_typecheck_convert_incompatible)
3103 case Builtin::BI__builtin_hlsl_wave_get_lane_index: {
3108 case Builtin::BI__builtin_hlsl_elementwise_splitdouble: {
3124 case Builtin::BI__builtin_hlsl_elementwise_clip: {
3132 case Builtin::BI__builtin_elementwise_acos:
3133 case Builtin::BI__builtin_elementwise_asin:
3134 case Builtin::BI__builtin_elementwise_atan:
3135 case Builtin::BI__builtin_elementwise_atan2:
3136 case Builtin::BI__builtin_elementwise_ceil:
3137 case Builtin::BI__builtin_elementwise_cos:
3138 case Builtin::BI__builtin_elementwise_cosh:
3139 case Builtin::BI__builtin_elementwise_exp:
3140 case Builtin::BI__builtin_elementwise_exp2:
3141 case Builtin::BI__builtin_elementwise_exp10:
3142 case Builtin::BI__builtin_elementwise_floor:
3143 case Builtin::BI__builtin_elementwise_fmod:
3144 case Builtin::BI__builtin_elementwise_log:
3145 case Builtin::BI__builtin_elementwise_log2:
3146 case Builtin::BI__builtin_elementwise_log10:
3147 case Builtin::BI__builtin_elementwise_pow:
3148 case Builtin::BI__builtin_elementwise_roundeven:
3149 case Builtin::BI__builtin_elementwise_sin:
3150 case Builtin::BI__builtin_elementwise_sinh:
3151 case Builtin::BI__builtin_elementwise_sqrt:
3152 case Builtin::BI__builtin_elementwise_tan:
3153 case Builtin::BI__builtin_elementwise_tanh:
3154 case Builtin::BI__builtin_elementwise_trunc: {
3160 case Builtin::BI__builtin_hlsl_buffer_update_counter: {
3162 return !(ResTy->getAttrs().ResourceClass == ResourceClass::UAV &&
3163 ResTy->getAttrs().RawBuffer && ResTy->hasContainedType());
3171 std::optional<llvm::APSInt> Offset =
3173 if (!Offset.has_value() ||
std::abs(Offset->getExtValue()) != 1) {
3175 diag::err_hlsl_expect_arg_const_int_one_or_neg_one)
3188 WorkList.push_back(BaseTy);
3189 while (!WorkList.empty()) {
3191 T =
T.getCanonicalType().getUnqualifiedType();
3192 assert(!isa<MatrixType>(
T) &&
"Matrix types not yet supported in HLSL");
3193 if (
const auto *AT = dyn_cast<ConstantArrayType>(
T)) {
3201 for (uint64_t Ct = 0; Ct < AT->getZExtSize(); ++Ct)
3202 llvm::append_range(List, ElementFields);
3207 if (
const auto *VT = dyn_cast<VectorType>(
T)) {
3208 List.insert(List.end(), VT->getNumElements(), VT->getElementType());
3212 if (RD->isStandardLayout())
3213 RD = RD->getStandardLayoutBaseWithFields();
3217 if (RD->
isUnion() || !RD->isAggregate()) {
3223 for (
const auto *FD : RD->
fields())
3224 FieldTypes.push_back(FD->
getType());
3226 std::reverse(FieldTypes.begin(), FieldTypes.end());
3227 llvm::append_range(WorkList, FieldTypes);
3231 if (!RD->isStandardLayout()) {
3233 for (
const auto &
Base : RD->bases())
3234 FieldTypes.push_back(
Base.getType());
3235 std::reverse(FieldTypes.begin(), FieldTypes.end());
3236 llvm::append_range(WorkList, FieldTypes);
3264 int ArraySize = VT->getNumElements();
3269 QualType ElTy = VT->getElementType();
3298 return llvm::equal(T1Types, T2Types,
3309 bool HadError =
false;
3311 for (
unsigned i = 0, e =
New->getNumParams(); i != e; ++i) {
3319 const auto *NDAttr = NewParam->
getAttr<HLSLParamModifierAttr>();
3320 unsigned NSpellingIdx = (NDAttr ? NDAttr->getSpellingListIndex() : 0);
3321 const auto *ODAttr = OldParam->
getAttr<HLSLParamModifierAttr>();
3322 unsigned OSpellingIdx = (ODAttr ? ODAttr->getSpellingListIndex() : 0);
3324 if (NSpellingIdx != OSpellingIdx) {
3326 diag::err_hlsl_param_qualifier_mismatch)
3327 << NDAttr << NewParam;
3358 llvm_unreachable(
"HLSL doesn't support pointers.");
3361 llvm_unreachable(
"HLSL doesn't support complex types.");
3363 llvm_unreachable(
"HLSL doesn't support fixed point types.");
3365 llvm_unreachable(
"Should have returned before this");
3375 llvm_unreachable(
"HLSL doesn't support complex types.");
3377 llvm_unreachable(
"HLSL doesn't support fixed point types.");
3382 llvm_unreachable(
"HLSL doesn't support pointers.");
3384 llvm_unreachable(
"Should have returned before this");
3390 llvm_unreachable(
"HLSL doesn't support pointers.");
3393 llvm_unreachable(
"HLSL doesn't support fixed point types.");
3397 llvm_unreachable(
"HLSL doesn't support complex types.");
3400 llvm_unreachable(
"Unhandled scalar cast");
3407 WorkList.push_back(BaseTy);
3408 while (!WorkList.empty()) {
3410 T =
T.getCanonicalType().getUnqualifiedType();
3412 if (
const auto *AT = dyn_cast<ConstantArrayType>(
T)) {
3413 WorkList.push_back(AT->getElementType());
3416 if (
const auto *RT = dyn_cast<RecordType>(
T)) {
3426 for (
const auto *FD : RD->
fields()) {
3427 if (FD->isBitField())
3429 WorkList.push_back(FD->
getType());
3464 for (
unsigned I = 0, Size = DestTypes.size(); I < Size; ++I) {
3465 if (DestTypes[I]->isUnionType())
3497 if (SrcTypes.size() < DestTypes.size())
3500 unsigned SrcSize = SrcTypes.size();
3501 unsigned DstSize = DestTypes.size();
3503 for (I = 0; I < DstSize && I < SrcSize; I++) {
3504 if (SrcTypes[I]->isUnionType() || DestTypes[I]->isUnionType())
3512 for (; I < SrcSize; I++) {
3513 if (SrcTypes[I]->isUnionType())
3520 assert(Param->
hasAttr<HLSLParamModifierAttr>() &&
3521 "We should not get here without a parameter modifier expression");
3522 const auto *
Attr = Param->
getAttr<HLSLParamModifierAttr>();
3529 << Arg << (IsInOut ? 1 : 0);
3542 << Arg << (IsInOut ? 1 : 0);
3560 auto *OpV =
new (Ctx)
3566 tok::equal, ArgOpV, OpV);
3582 "Pointer and reference types cannot be inout or out parameters");
3593 !VD->
hasAttr<HLSLVkConstantIdAttr>() &&
3599 if (
Decl->getType().hasAddressSpace())
3602 if (
Decl->getType()->isDependentType())
3637 diag::err_typecheck_decl_incomplete_type)) {
3651 DefaultCBufferDecls.push_back(VD);
3656 collectResourceBindingsOnVarDecl(VD);
3659 VD->
hasAttr<HLSLVkConstantIdAttr>()) {
3667 processExplicitBindingsOnDecl(VD);
3673 if (!VD->
hasAttr<HLSLVkBindingAttr>()) {
3674 HLSLResourceBindingAttr *RBA = VD->
getAttr<HLSLResourceBindingAttr>();
3675 if (!RBA || !RBA->hasRegisterSlot()) {
3676 uint32_t OrderID = getNextImplicitBindingOrderID();
3678 RBA->setImplicitBindingOrderID(OrderID);
3711void SemaHLSL::createResourceRecordCtorArgs(
3712 const Type *ResourceTy, StringRef VarName, HLSLResourceBindingAttr *RBA,
3713 HLSLVkBindingAttr *VkBinding, uint32_t ArrayIndex,
3715 std::optional<uint32_t> RegisterSlot;
3718 RegisterSlot = VkBinding->getBinding();
3719 SpaceNo = VkBinding->getSet();
3721 if (RBA->hasRegisterSlot())
3722 RegisterSlot = RBA->getSlotNumber();
3723 SpaceNo = RBA->getSpaceNumber();
3743 if (RegisterSlot.has_value()) {
3745 AST, llvm::APInt(UIntTySize, RegisterSlot.value()), AST.
UnsignedIntTy,
3747 Args.append({RegSlot, Space, RangeSize, Index, Name});
3750 uint32_t OrderID = (RBA && RBA->hasImplicitBindingOrderID())
3751 ? RBA->getImplicitBindingOrderID()
3752 : getNextImplicitBindingOrderID();
3756 Args.append({Space, RangeSize, Index, OrderId, Name});
3760bool SemaHLSL::initGlobalResourceDecl(
VarDecl *VD) {
3763 VD->
getAttr<HLSLResourceBindingAttr>(),
3764 VD->
getAttr<HLSLVkBindingAttr>(), 0, Args);
3768bool SemaHLSL::initGlobalResourceArrayDecl(
VarDecl *VD) {
3770 "expected array of resource records");
3781 VD->
getAttr<HLSLResourceBindingAttr>(),
3782 VD->
getAttr<HLSLVkBindingAttr>(), 0, Args);
3789 if (InitSeq.Failed())
3810 return initGlobalResourceDecl(VD);
3812 return initGlobalResourceArrayDecl(VD);
3819void SemaHLSL::collectResourceBindingsOnVarDecl(
VarDecl *VD) {
3821 "expected global variable that contains HLSL resource");
3824 if (
const HLSLBufferDecl *CBufferOrTBuffer = dyn_cast<HLSLBufferDecl>(VD)) {
3825 Bindings.addDeclBindingInfo(VD, CBufferOrTBuffer->isCBuffer()
3826 ? ResourceClass::CBuffer
3827 : ResourceClass::SRV);
3842 Bindings.addDeclBindingInfo(VD, AttrResType->getAttrs().ResourceClass);
3847 if (
const RecordType *RT = dyn_cast<RecordType>(Ty))
3848 collectResourceBindingsOnUserRecordDecl(VD, RT);
3854void SemaHLSL::processExplicitBindingsOnDecl(
VarDecl *VD) {
3857 bool HasBinding =
false;
3859 if (isa<HLSLVkBindingAttr>(A))
3862 HLSLResourceBindingAttr *RBA = dyn_cast<HLSLResourceBindingAttr>(A);
3863 if (!RBA || !RBA->hasRegisterSlot())
3868 assert(RT != RegisterType::I &&
"invalid or obsolete register type should "
3869 "never have an attribute created");
3871 if (RT == RegisterType::C) {
3872 if (
Bindings.hasBindingInfoForDecl(VD))
3874 diag::warn_hlsl_user_defined_type_missing_member)
3875 <<
static_cast<int>(RT);
3888 diag::warn_hlsl_user_defined_type_missing_member)
3889 <<
static_cast<int>(RT);
3897class InitListTransformer {
3902 Expr **ArgIt =
nullptr;
3908 bool castInitializer(
Expr *
E) {
3909 assert(DstIt &&
"This should always be something!");
3910 if (DstIt == DestTypes.end()) {
3912 ArgExprs.push_back(
E);
3917 DstIt = DestTypes.begin();
3920 Ctx, *DstIt,
false);
3925 ArgExprs.push_back(
Init);
3930 bool buildInitializerListImpl(
Expr *
E) {
3932 if (
auto *
Init = dyn_cast<InitListExpr>(
E)) {
3933 for (
auto *SubInit :
Init->inits())
3934 if (!buildInitializerListImpl(SubInit))
3943 return castInitializer(
E);
3950 for (uint64_t I = 0; I <
Size; ++I) {
3958 if (!castInitializer(ElExpr.
get()))
3964 if (
auto *ArrTy = dyn_cast<ConstantArrayType>(Ty.
getTypePtr())) {
3968 for (uint64_t I = 0; I <
Size; ++I) {
3975 if (!buildInitializerListImpl(ElExpr.
get()))
3983 RecordDecls.push_back(RD);
3984 while (RecordDecls.back()->getNumBases()) {
3986 assert(
D->getNumBases() == 1 &&
3987 "HLSL doesn't support multiple inheritance");
3988 RecordDecls.push_back(
3989 D->bases_begin()->getType()->castAsCXXRecordDecl());
3991 while (!RecordDecls.empty()) {
3993 for (
auto *FD : RD->
fields()) {
4000 if (!buildInitializerListImpl(Res.
get()))
4009 assert(ArgIt != ArgExprs.end() &&
"Something is off in iteration!");
4014 assert(!isa<MatrixType>(Ty) &&
"Matrix types not yet supported in HLSL");
4020 ElTy = ATy->getElementType();
4021 Size = ATy->getNumElements();
4023 auto *VTy = cast<ConstantArrayType>(Ty.
getTypePtr());
4024 ElTy = VTy->getElementType();
4025 Size = VTy->getZExtSize();
4027 for (uint64_t I = 0; I <
Size; ++I)
4028 Inits.push_back(generateInitListsImpl(ElTy));
4032 RecordDecls.push_back(RD);
4033 while (RecordDecls.back()->getNumBases()) {
4035 assert(
D->getNumBases() == 1 &&
4036 "HLSL doesn't support multiple inheritance");
4037 RecordDecls.push_back(
4038 D->bases_begin()->getType()->castAsCXXRecordDecl());
4040 while (!RecordDecls.empty()) {
4042 for (
auto *FD : RD->
fields())
4043 Inits.push_back(generateInitListsImpl(FD->
getType()));
4046 auto *NewInit =
new (Ctx)
InitListExpr(Ctx, Inits.front()->getBeginLoc(),
4047 Inits, Inits.back()->getEndLoc());
4056 : S(SemaRef), Ctx(SemaRef.getASTContext()),
4057 Wrap(Entity.getType()->isIncompleteArrayType()) {
4068 DstIt = DestTypes.begin();
4071 bool buildInitializerList(
Expr *
E) {
return buildInitializerListImpl(
E); }
4073 Expr *generateInitLists() {
4074 assert(!ArgExprs.empty() &&
4075 "Call buildInitializerList to generate argument expressions.");
4076 ArgIt = ArgExprs.begin();
4078 return generateInitListsImpl(InitTy);
4080 while (ArgIt != ArgExprs.end())
4081 Inits.push_back(generateInitListsImpl(InitTy));
4083 auto *NewInit =
new (Ctx)
InitListExpr(Ctx, Inits.front()->getBeginLoc(),
4084 Inits, Inits.back()->getEndLoc());
4085 llvm::APInt ArySize(64, Inits.size());
4087 ArraySizeModifier::Normal, 0));
4096 if (
Init->getType()->isScalarType())
4099 InitListTransformer ILT(
SemaRef, Entity);
4101 for (
unsigned I = 0; I <
Init->getNumInits(); ++I) {
4109 Init->setInit(I,
E);
4111 if (!ILT.buildInitializerList(
E))
4114 size_t ExpectedSize = ILT.DestTypes.size();
4115 size_t ActualSize = ILT.ArgExprs.size();
4122 ((ActualSize + ExpectedSize - 1) / ExpectedSize) * ExpectedSize;
4130 if (ExpectedSize != ActualSize) {
4131 int TooManyOrFew = ActualSize > ExpectedSize ? 1 : 0;
4132 SemaRef.
Diag(
Init->getBeginLoc(), diag::err_hlsl_incorrect_num_initializers)
4133 << TooManyOrFew << InitTy << ExpectedSize << ActualSize;
4139 auto *NewInit = cast<InitListExpr>(ILT.generateInitLists());
4140 Init->resizeInits(Ctx, NewInit->getNumInits());
4141 for (
unsigned I = 0; I < NewInit->getNumInits(); ++I)
4142 Init->updateInit(Ctx, I, NewInit->getInit(I));
4147 const HLSLVkConstantIdAttr *ConstIdAttr =
4148 VDecl->
getAttr<HLSLVkConstantIdAttr>();
4155 if (!
Init->isCXX11ConstantExpr(Context, &InitValue)) {
4165 int ConstantID = ConstIdAttr->getId();
4168 ConstIdAttr->getLocation());
4172 if (
C->getType()->getCanonicalTypeUnqualified() !=
4177 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.
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 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 bool initVarDeclWithCtor(Sema &S, VarDecl *VD, MutableArrayRef< Expr * > Args)
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 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 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)
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)
HLSLResourceBindingAttr::RegisterType RegisterType
static CastKind getScalarCastKind(ASTContext &Ctx, QualType DestTy, QualType SrcTy)
static bool isValidWaveSizeValue(unsigned Value)
static bool IsDefaultBufferConstantDecl(VarDecl *VD)
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.
Defines the clang::TypeLoc interface and its subclasses.
C Language Family Type Representation.
static const TypeInfo & getInfo(unsigned id)
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
virtual bool HandleTopLevelDecl(DeclGroupRef D)
HandleTopLevelDecl - Handle the specified top-level declaration.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const ConstantArrayType * getAsConstantArrayType(QualType T) const
unsigned getIntWidth(QualType T) const
int getIntegerTypeOrder(QualType LHS, QualType RHS) const
Return the highest ranked integer type, see C99 6.3.1.8p1.
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
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 getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
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.
QualType removeAddrSpaceQualType(QualType T) const
Remove any existing address space on the type and returns the type with qualifiers intact (or that's ...
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
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 getCorrespondingUnsignedType(QualType T) 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
QualType getCommonSugaredType(QualType X, QualType Y, bool Unqualified=false) const
unsigned getTypeAlign(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in bits.
QualType getElementType() const
Attr - This represents one attribute.
attr::Kind getKind() 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.
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.
bool isStandardLayout() const
Determine whether this class is standard-layout per C++ [class]p7.
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]).
const CXXRecordDecl * getStandardLayoutBaseWithFields() const
If this is a standard-layout class or union, any and all data members will be declared in the same ty...
Represents a C++ nested-name-specifier or a global scope specifier.
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
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.
A POD class for pairing a NamedDecl* with an access specifier.
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.
Decl - This represents one declaration (or definition), e.g.
ASTContext & getASTContext() const LLVM_READONLY
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.
SourceLocation getBeginLoc() const LLVM_READONLY
Recursive AST visitor that supports extension via dynamic dispatch.
This represents one expression.
ExprValueKind getValueKind() const
getValueKind - The value kind that this expression produces.
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 ...
ArrayRef< ParmVarDecl * > parameters() const
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
bool hasBody(const FunctionDecl *&Definition) const
Returns true if the function has a body.
const Attributes & getAttrs() const
static const HLSLAttributedResourceType * findHandleTypeOnResource(const Type *RT)
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.
IdentifierInfo * getIdentifierInfo() const
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
Represents a C array with an unspecified size.
Describes an C or C++ initializer list.
Describes the kind of initialization being performed, along with location information for tokens rela...
static InitializationKind CreateDirect(SourceLocation InitLoc, SourceLocation LParenLoc, SourceLocation RParenLoc)
Create a direct initialization.
Describes the sequence of initializations required to initialize a given object or reference with a s...
ExprResult Perform(Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind, MultiExprArg Args, QualType *ResultType=nullptr)
Perform the actual initialization of the given entity based on the computed initialization sequence.
bool Failed() const
Determine whether the initialization sequence is invalid.
Describes an entity that is being initialized.
QualType getType() const
Retrieve type being initialized.
static InitializedEntity InitializeTemporary(QualType Type)
Create the initialization entity for a temporary.
static InitializedEntity InitializeVariable(VarDecl *Var)
Create the initialization entity for a variable.
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'.
llvm::dxbc::RootSignatureVersion HLSLRootSigVer
The HLSL root signature version for dxil.
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.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
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_range fields() const
RecordDecl * getDefinitionOrSelf() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
RecordDecl * getOriginalDecl() const
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
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.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
ASTContext & getASTContext() const
ExprResult ActOnOutParamExpr(ParmVarDecl *Param, Expr *Arg)
bool CanPerformElementwiseCast(Expr *Src, QualType DestType)
void DiagnoseAttrStageMismatch(const Attr *A, llvm::Triple::EnvironmentType Stage, std::initializer_list< llvm::Triple::EnvironmentType > AllowedStages)
void handleWaveSizeAttr(Decl *D, const ParsedAttr &AL)
HLSLAttributedResourceLocInfo TakeLocForHLSLAttribute(const HLSLAttributedResourceType *RT)
bool CanPerformScalarCast(QualType SrcTy, QualType DestTy)
QualType ProcessResourceTypeAttributes(QualType Wrapped)
void handleSV_GroupThreadIDAttr(Decl *D, const ParsedAttr &AL)
void handleShaderAttr(Decl *D, const ParsedAttr &AL)
void handleSV_DispatchThreadIDAttr(Decl *D, const ParsedAttr &AL)
void CheckEntryPoint(FunctionDecl *FD)
void emitLogicalOperatorFixIt(Expr *LHS, Expr *RHS, BinaryOperatorKind Opc)
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)
void CheckSemanticAnnotation(FunctionDecl *EntryPoint, const Decl *Param, const HLSLAnnotationAttr *AnnotationAttr)
bool diagnosePositionType(QualType T, const ParsedAttr &AL)
bool ContainsBitField(QualType BaseTy)
bool handleInitialization(VarDecl *VDecl, Expr *&Init)
bool diagnoseInputIDType(QualType T, const ParsedAttr &AL)
void handleParamModifierAttr(Decl *D, const ParsedAttr &AL)
bool CanPerformAggregateSplatCast(Expr *Src, QualType DestType)
void handleSV_PositionAttr(Decl *D, const ParsedAttr &AL)
bool IsScalarizedLayoutCompatible(QualType T1, QualType T2) const
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)
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 handleSV_GroupIDAttr(Decl *D, const ParsedAttr &AL)
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.
Scope * getCurScope() const
Retrieve the parser's current scope.
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
Expr * BuildBuiltinCallExpr(SourceLocation Loc, Builtin::ID Id, MultiExprArg CallArgs)
BuildBuiltinCallExpr - Create a call to a builtin function specified by Id.
void PushOnScopeChains(NamedDecl *D, Scope *S, bool AddToContext=true)
Add this decl to the scope shadowed decl chains.
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.
bool BuiltinVectorToScalarMath(CallExpr *TheCall)
bool IsLayoutCompatible(QualType T1, QualType T2) const
const LangOptions & getLangOpts() const
DeclContext * getCurLexicalContext() const
ExprResult BuildCStyleCastExpr(SourceLocation LParenLoc, TypeSourceInfo *Ty, SourceLocation RParenLoc, Expr *Op)
bool checkUInt32Argument(const AttrInfo &AI, const Expr *Expr, uint32_t &Val, unsigned Idx=UINT_MAX, bool StrictlyUnsigned=false)
If Expr is a valid integer constant, get the value of the integer expression and return success or fa...
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
ExprResult BuildFieldReferenceExpr(Expr *BaseExpr, bool IsArrow, SourceLocation OpLoc, const CXXScopeSpec &SS, FieldDecl *Field, DeclAccessPair FoundDecl, const DeclarationNameInfo &MemberNameInfo)
bool PrepareBuiltinElementwiseMathOneArgCall(CallExpr *TheCall, EltwiseBuiltinArgTyRestriction ArgTyRestr=EltwiseBuiltinArgTyRestriction::None)
ExprResult ActOnBinOp(Scope *S, SourceLocation TokLoc, tok::TokenKind Kind, Expr *LHSExpr, Expr *RHSExpr)
Binary Operators. 'Tok' is the token for the operator.
void CheckCompleteVariableDeclaration(VarDecl *VD)
bool BuiltinElementwiseTernaryMath(CallExpr *TheCall, EltwiseBuiltinArgTyRestriction ArgTyRestr=EltwiseBuiltinArgTyRestriction::FloatTy)
bool checkArgCount(CallExpr *Call, unsigned DesiredArgCount)
Checks that a call expression's argument count is the desired number.
ExprResult CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc, Expr *Idx, SourceLocation RLoc)
bool RequireCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, bool InUnqualifiedLookup=false)
Perform qualified name lookup into a given context.
Expr * MaybeCreateExprWithCleanups(Expr *SubExpr)
MaybeCreateExprWithCleanups - If the current full-expression requires any cleanups,...
void PushDeclContext(Scope *S, DeclContext *DC)
Set the current declaration context until it gets popped.
ExprResult PerformCopyInitialization(const InitializedEntity &Entity, SourceLocation EqualLoc, ExprResult Init, bool TopLevelOfInitList=false, bool AllowExplicit=false)
static QualType GetTypeFromParser(ParsedType Ty, TypeSourceInfo **TInfo=nullptr)
bool checkStringLiteralArgumentAttr(const AttributeCommonInfo &CI, const Expr *E, StringRef &Str, SourceLocation *ArgLocation=nullptr)
Check if the argument E is a ASCII string literal.
Encodes a location in the source.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() 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
StringLiteral - This represents a string literal expression, e.g.
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 isStructureType() const
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
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool hasIntegerRepresentation() const
Determine whether this type has an integer representation of some sort, e.g., it is an integer type o...
bool isArithmeticType() 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.
bool isFloat32Type() const
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.
const internal::VariadicAllOfMatcher< Attr > attr
Matches attributes.
The JSON file list parser is used to communicate input to InstallAPI.
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.
ActionResult< Expr * > ExprResult
static bool CheckAllArgsHaveSameType(Sema *S, CallExpr *TheCall)
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_LValue
An l-value expression is a reference to an object with independent storage.
const FunctionProtoType * T
Visibility
Describes the different kinds of visibility that a declaration may have.
Diagnostic wrappers for TextAPI types for error reporting.
hash_code hash_value(const clang::tooling::dependencies::ModuleID &ID)
__DEVICE__ _Tp abs(const std::complex< _Tp > &__c)
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...
TypeSourceInfo * ContainedTyInfo
llvm::dxil::ResourceClass ResourceClass
Describes how types, statements, expressions, and declarations should be printed.
const SourceLocation & getLocation() const
const llvm::hlsl::rootsig::RootElement & getElement() const