@@ -988,7 +988,6 @@ visitInlineCommandComment(
988
988
{
989
989
MRDOCS_CHECK_OR (goodArgCount (1 , *C));
990
990
std::string ref = C->getArgText (0 ).str ();
991
- std::string originalRef = ref;
992
991
std::string leftOver = fixReference (ref);
993
992
bool const hasExtra = !leftOver.empty ();
994
993
emplaceText<doc::Copied>(
@@ -1140,24 +1139,131 @@ fixReference(std::string& ref)
1140
1139
// a function, and we need to merge the next text comments
1141
1140
// until we find a balanced ')'.
1142
1141
bool const isFunction = contains (ref, ' (' );
1143
- while ( std::ranges::count (ref, ' ( ' ) != std::ranges::count (ref, ' ) ' ) )
1142
+ if (isFunction )
1144
1143
{
1145
- ++it_;
1146
- if (it_ == end_)
1147
- {
1148
- break ;
1149
- }
1150
- Comment const * c = *it_;
1151
- if (c->getCommentKind () == CommentKind::TextComment)
1144
+ while (std::ranges::count (ref, ' (' ) != std::ranges::count (ref, ' )' ))
1152
1145
{
1153
- ref += static_cast <TextComment const *>(c)->getText ();
1146
+ ++it_;
1147
+ if (it_ == end_)
1148
+ {
1149
+ break ;
1150
+ }
1151
+ Comment const * c = *it_;
1152
+ if (c->getCommentKind () == CommentKind::TextComment)
1153
+ {
1154
+ ref += static_cast <TextComment const *>(c)->getText ();
1155
+ }
1156
+ else
1157
+ {
1158
+ break ;
1159
+ }
1154
1160
}
1155
- else
1161
+ if ( rtrim (ref). ends_with ( ' ) ' ))
1156
1162
{
1157
- break ;
1163
+ static constexpr std::array<std::string_view, 5 > qualifiers = {
1164
+ " const" ,
1165
+ " volatile" ,
1166
+ " noexcept" ,
1167
+ " &&" ,
1168
+ " &" ,
1169
+ };
1170
+ auto isQualifiersOnly = [](std::string_view str)
1171
+ {
1172
+ // Iterate all words between spaces and check if
1173
+ // they are qualifiers
1174
+ std::size_t pos = 0 ;
1175
+ while (pos < str.size ())
1176
+ {
1177
+ std::size_t const start = str.find_first_not_of (' ' , pos);
1178
+ if (start == std::string::npos)
1179
+ {
1180
+ break ;
1181
+ }
1182
+ std::size_t const end = str.find_first_of (' ' , start);
1183
+ std::string_view word = str.substr (start, end - start);
1184
+ if (std::ranges::find (qualifiers, word) == qualifiers.end ())
1185
+ {
1186
+ return false ;
1187
+ }
1188
+ pos = end;
1189
+ }
1190
+ return true ;
1191
+ };
1192
+ auto isWhitespaceOnly = [](std::string_view str)
1193
+ {
1194
+ return str.empty () || str.find_first_not_of (' ' ) == std::string::npos;
1195
+ };
1196
+
1197
+ // peek next comment
1198
+ std::string functionContinuation;
1199
+ auto originalIt = it_;
1200
+ ++it_;
1201
+ while (
1202
+ it_ != end_ &&
1203
+ (isWhitespaceOnly (functionContinuation) ||
1204
+ isQualifiersOnly (functionContinuation)))
1205
+ {
1206
+ Comment const * c = *it_;
1207
+ if (c->getCommentKind () != CommentKind::TextComment)
1208
+ {
1209
+ break ;
1210
+ }
1211
+ functionContinuation += static_cast <TextComment const *>(c)->getText ();
1212
+ ++it_;
1213
+ }
1214
+ if (isWhitespaceOnly (functionContinuation))
1215
+ {
1216
+ it_ = originalIt;
1217
+ }
1218
+ else /* if (!functionContinuation.empty()) */
1219
+ {
1220
+ --it_;
1221
+ std::string_view suffix = functionContinuation;
1222
+ std::string_view leftover = functionContinuation;
1223
+ bool foundAny = false ;
1224
+ std::size_t totalRemoved = 0 ;
1225
+ while (!suffix.empty ())
1226
+ {
1227
+ bool found = false ;
1228
+ std::size_t const initialWhitespace = std::min (
1229
+ suffix.find_first_not_of (" " ), suffix.size ());
1230
+ for (auto const & q : qualifiers)
1231
+ {
1232
+ if (suffix.substr (initialWhitespace).starts_with (q))
1233
+ {
1234
+ std::size_t const toRemove = initialWhitespace + q.size ();
1235
+ if (
1236
+ contains (idChars, q.back ()) &&
1237
+ suffix.size () > toRemove &&
1238
+ contains (idChars, suffix[toRemove]))
1239
+ {
1240
+ // This is not a qualifier, but part of
1241
+ // an identifier
1242
+ continue ;
1243
+ }
1244
+ suffix.remove_prefix (toRemove);
1245
+ totalRemoved += toRemove;
1246
+ found = true ;
1247
+ foundAny = true ;
1248
+ break ;
1249
+ }
1250
+ }
1251
+ if (!found)
1252
+ {
1253
+ break ;
1254
+ }
1255
+ }
1256
+ if (foundAny)
1257
+ {
1258
+ leftover = leftover.substr (0 , totalRemoved);
1259
+ ref += leftover;
1260
+ return std::string (suffix);
1261
+ }
1262
+ }
1158
1263
}
1159
1264
}
1160
1265
1266
+
1161
1267
// Clang refs can also contain invalid characters
1162
1268
// at the end, especially punctuation. We need to
1163
1269
// truncate the ref at the last valid identifier
0 commit comments