@@ -1085,9 +1085,10 @@ bool SemaHLSL::handleRootSignatureElements(
1085
1085
ArrayRef<hlsl::RootSignatureElement> Elements) {
1086
1086
using RangeInfo = llvm::hlsl::rootsig::RangeInfo;
1087
1087
using OverlappingRanges = llvm::hlsl::rootsig::OverlappingRanges;
1088
+ using InfoPair = std::pair<RangeInfo, const hlsl::RootSignatureElement *>;
1088
1089
1089
1090
// 1. Collect RangeInfos
1090
- llvm::SmallVector<RangeInfo> Infos ;
1091
+ llvm::SmallVector<InfoPair> InfoPairs ;
1091
1092
for (const hlsl::RootSignatureElement &RootSigElem : Elements) {
1092
1093
const llvm::hlsl::rootsig::RootElement &Elem = RootSigElem.getElement ();
1093
1094
if (const auto *Descriptor =
@@ -1101,8 +1102,7 @@ bool SemaHLSL::handleRootSignatureElements(
1101
1102
Info.Space = Descriptor->Space ;
1102
1103
Info.Visibility = Descriptor->Visibility ;
1103
1104
1104
- Info.Cookie = static_cast <void *>(&RootSigElem);
1105
- Infos.push_back (Info);
1105
+ InfoPairs.push_back ({Info, &RootSigElem});
1106
1106
} else if (const auto *Constants =
1107
1107
std::get_if<llvm::hlsl::rootsig::RootConstants>(&Elem)) {
1108
1108
RangeInfo Info;
@@ -1113,8 +1113,7 @@ bool SemaHLSL::handleRootSignatureElements(
1113
1113
Info.Space = Constants->Space ;
1114
1114
Info.Visibility = Constants->Visibility ;
1115
1115
1116
- Info.Cookie = static_cast <void *>(&RootSigElem);
1117
- Infos.push_back (Info);
1116
+ InfoPairs.push_back ({Info, &RootSigElem});
1118
1117
} else if (const auto *Sampler =
1119
1118
std::get_if<llvm::hlsl::rootsig::StaticSampler>(&Elem)) {
1120
1119
RangeInfo Info;
@@ -1125,8 +1124,7 @@ bool SemaHLSL::handleRootSignatureElements(
1125
1124
Info.Space = Sampler->Space ;
1126
1125
Info.Visibility = Sampler->Visibility ;
1127
1126
1128
- Info.Cookie = static_cast <void *>(&RootSigElem);
1129
- Infos.push_back (Info);
1127
+ InfoPairs.push_back ({Info, &RootSigElem});
1130
1128
} else if (const auto *Clause =
1131
1129
std::get_if<llvm::hlsl::rootsig::DescriptorTableClause>(
1132
1130
&Elem)) {
@@ -1142,30 +1140,59 @@ bool SemaHLSL::handleRootSignatureElements(
1142
1140
Info.Space = Clause->Space ;
1143
1141
1144
1142
// Note: Clause does not hold the visibility this will need to
1145
- Info.Cookie = static_cast <void *>(&RootSigElem);
1146
- Infos.push_back (Info);
1143
+ InfoPairs.push_back ({Info, &RootSigElem});
1147
1144
} else if (const auto *Table =
1148
1145
std::get_if<llvm::hlsl::rootsig::DescriptorTable>(&Elem)) {
1149
1146
// Table holds the Visibility of all owned Clauses in Table, so iterate
1150
1147
// owned Clauses and update their corresponding RangeInfo
1151
- assert (Table->NumClauses <= Infos .size () && " RootElement" );
1148
+ assert (Table->NumClauses <= InfoPairs .size () && " RootElement" );
1152
1149
// The last Table->NumClauses elements of Infos are the owned Clauses
1153
1150
// generated RangeInfo
1154
1151
auto TableInfos =
1155
- MutableArrayRef<RangeInfo>(Infos ).take_back (Table->NumClauses );
1156
- for (RangeInfo &Info : TableInfos)
1157
- Info .Visibility = Table->Visibility ;
1152
+ MutableArrayRef<InfoPair>(InfoPairs ).take_back (Table->NumClauses );
1153
+ for (InfoPair &Pair : TableInfos)
1154
+ Pair. first .Visibility = Table->Visibility ;
1158
1155
}
1159
1156
}
1160
1157
1161
- // Helper to report diagnostics
1162
- auto ReportOverlap = [this ](OverlappingRanges Overlap) {
1158
+ // Sort as specified
1159
+ auto ComparePairs = [](InfoPair A, InfoPair B) { return A.first < B.first ; };
1160
+
1161
+ std::sort (InfoPairs.begin (), InfoPairs.end (), ComparePairs);
1162
+
1163
+ llvm::SmallVector<RangeInfo> Infos;
1164
+ for (const InfoPair &Pair : InfoPairs)
1165
+ Infos.push_back (Pair.first );
1166
+
1167
+ // Helpers to report diagnostics
1168
+ using ElemPair = std::pair<const hlsl::RootSignatureElement *,
1169
+ const hlsl::RootSignatureElement *>;
1170
+ auto GetElemPair = [&Infos, &InfoPairs](
1171
+ OverlappingRanges Overlap) -> ElemPair {
1172
+ auto InfoB = std::lower_bound (Infos.begin (), Infos.end (), *Overlap.B );
1173
+ auto DistB = std::distance (Infos.begin (), InfoB);
1174
+ auto PairB = InfoPairs.begin ();
1175
+ std::advance (PairB, DistB);
1176
+
1177
+ auto InfoA = std::lower_bound (InfoB, Infos.end (), *Overlap.A );
1178
+ if (InfoA == InfoB)
1179
+ InfoA++;
1180
+ auto DistA = std::distance (InfoB, InfoA);
1181
+ auto PairA = PairB;
1182
+ std::advance (PairA, DistA);
1183
+
1184
+ return {PairA->second , PairB->second };
1185
+ };
1186
+
1187
+ auto ReportOverlap = [this , &GetElemPair](OverlappingRanges Overlap) {
1188
+ auto Pair = GetElemPair (Overlap);
1163
1189
const RangeInfo *Info = Overlap.A ;
1190
+ const hlsl::RootSignatureElement *Elem = Pair.first ;
1164
1191
const RangeInfo *OInfo = Overlap.B ;
1192
+
1165
1193
auto CommonVis = Info->Visibility == llvm::dxbc::ShaderVisibility::All
1166
1194
? OInfo->Visibility
1167
1195
: Info->Visibility ;
1168
- auto Elem = static_cast <const hlsl::RootSignatureElement *>(Info->Cookie );
1169
1196
this ->Diag (Elem->getLocation (), diag::err_hlsl_resource_range_overlap)
1170
1197
<< llvm::to_underlying (Info->Class ) << Info->LowerBound
1171
1198
<< /* unbounded=*/ (Info->UpperBound == RangeInfo::Unbounded)
@@ -1174,7 +1201,7 @@ bool SemaHLSL::handleRootSignatureElements(
1174
1201
<< /* unbounded=*/ (OInfo->UpperBound == RangeInfo::Unbounded)
1175
1202
<< OInfo->UpperBound << Info->Space << CommonVis;
1176
1203
1177
- auto OElem = static_cast < const hlsl::RootSignatureElement *>(OInfo-> Cookie ) ;
1204
+ const hlsl::RootSignatureElement *OElem = Pair. second ;
1178
1205
this ->Diag (OElem->getLocation (), diag::note_hlsl_resource_range_here);
1179
1206
};
1180
1207
0 commit comments