@@ -147,6 +147,38 @@ getTypeAsString(
147
147
return T.getAsString (astContext_->getPrintingPolicy ());
148
148
}
149
149
150
+ template <typename TypeInfoTy>
151
+ std::unique_ptr<TypeInfoTy>
152
+ ASTVisitor::
153
+ makeTypeInfo (
154
+ const IdentifierInfo* II,
155
+ unsigned quals)
156
+ {
157
+ auto I = std::make_unique<TypeInfoTy>();
158
+ I->CVQualifiers = convertToQualifierKind (quals);
159
+ if (II)
160
+ I->Name = II->getName ();
161
+ return I;
162
+ }
163
+
164
+ template <typename TypeInfoTy>
165
+ std::unique_ptr<TypeInfoTy>
166
+ ASTVisitor::
167
+ makeTypeInfo (
168
+ const NamedDecl* N,
169
+ unsigned quals)
170
+ {
171
+ auto I = std::make_unique<TypeInfoTy>();
172
+ I->CVQualifiers = convertToQualifierKind (quals);
173
+ if (N)
174
+ {
175
+ extractSymbolID (N, I->id );
176
+ if (const auto * II = N->getIdentifier ())
177
+ I->Name = II->getName ();
178
+ }
179
+ return I;
180
+ }
181
+
150
182
std::unique_ptr<TypeInfo>
151
183
ASTVisitor::
152
184
buildTypeInfoForType (
@@ -170,38 +202,38 @@ buildTypeInfoForType(
170
202
std::unique_ptr<TypeInfo>
171
203
ASTVisitor::
172
204
buildTypeInfoForType (
173
- QualType qt)
205
+ QualType qt,
206
+ unsigned quals)
174
207
{
208
+ qt.addFastQualifiers (quals);
175
209
// should never be called for a QualType
176
210
// that has no Type pointer
177
211
MRDOX_ASSERT (! qt.isNull ());
178
212
const Type* type = qt.getTypePtr ();
213
+ quals = qt.getLocalFastQualifiers ();
179
214
switch (qt->getTypeClass ())
180
215
{
181
216
// parenthesized types
182
217
case Type::Paren:
183
218
{
184
219
auto * T = cast<ParenType>(type);
185
220
return buildTypeInfoForType (
186
- T->getInnerType ().withFastQualifiers (
187
- qt.getLocalFastQualifiers ()));
221
+ T->getInnerType (), quals);
188
222
}
189
223
// type with __atribute__
190
224
case Type::Attributed:
191
225
{
192
226
auto * T = cast<AttributedType>(type);
193
227
return buildTypeInfoForType (
194
- T->getModifiedType ().withFastQualifiers (
195
- qt.getLocalFastQualifiers ()));
228
+ T->getModifiedType (), quals);
196
229
}
197
230
// adjusted and decayed types
198
231
case Type::Decayed:
199
232
case Type::Adjusted:
200
233
{
201
234
auto * T = cast<AdjustedType>(type);
202
235
return buildTypeInfoForType (
203
- T->getOriginalType ().withFastQualifiers (
204
- qt.getLocalFastQualifiers ()));
236
+ T->getOriginalType (), quals);
205
237
}
206
238
// using declarations
207
239
case Type::Using:
@@ -210,8 +242,7 @@ buildTypeInfoForType(
210
242
// look through the using declaration and
211
243
// use the the type from the referenced declaration
212
244
return buildTypeInfoForType (
213
- T->getUnderlyingType ().withFastQualifiers (
214
- qt.getLocalFastQualifiers ()));
245
+ T->getUnderlyingType (), quals);
215
246
}
216
247
// pointers
217
248
case Type::Pointer:
@@ -220,8 +251,7 @@ buildTypeInfoForType(
220
251
auto I = std::make_unique<PointerTypeInfo>();
221
252
I->PointeeType = buildTypeInfoForType (
222
253
T->getPointeeType ());
223
- I->CVQualifiers = convertToQualifierKind (
224
- qt.getLocalQualifiers ());
254
+ I->CVQualifiers = convertToQualifierKind (quals);
225
255
return I;
226
256
}
227
257
// references
@@ -250,6 +280,7 @@ buildTypeInfoForType(
250
280
T->getPointeeType ());
251
281
I->ParentType = buildTypeInfoForType (
252
282
QualType (T->getClass (), 0 ));
283
+ I->CVQualifiers = convertToQualifierKind (quals);
253
284
return I;
254
285
}
255
286
// pack expansion
@@ -276,7 +307,7 @@ buildTypeInfoForType(
276
307
I->RefQualifier = convertToReferenceKind (
277
308
T->getRefQualifier ());
278
309
I->CVQualifiers = convertToQualifierKind (
279
- T->getMethodQuals ());
310
+ T->getMethodQuals (). getFastQualifiers () );
280
311
I->ExceptionSpec = convertToNoexceptKind (
281
312
T->getExceptionSpecType ());
282
313
return I;
@@ -325,23 +356,16 @@ buildTypeInfoForType(
325
356
auto I = std::make_unique<BuiltinTypeInfo>();
326
357
I->Name = getTypeAsString (
327
358
qt.withoutLocalFastQualifiers ());
328
- I->CVQualifiers = convertToQualifierKind (
329
- qt.getLocalQualifiers ());
359
+ I->CVQualifiers = convertToQualifierKind (quals);
330
360
return I;
331
361
}
332
362
case Type::DeducedTemplateSpecialization:
333
363
{
334
364
auto * T = cast<DeducedTemplateSpecializationType>(type);
335
365
if (T->isDeduced ())
336
366
return buildTypeInfoForType (T->getDeducedType ());
337
- auto I = std::make_unique<TagTypeInfo>();
338
- if (auto * TD = T->getTemplateName ().getAsTemplateDecl ())
339
- {
340
- extractSymbolID (TD, I->id );
341
- I->Name = TD->getNameAsString ();
342
- }
343
- I->CVQualifiers = convertToQualifierKind (
344
- qt.getLocalQualifiers ());
367
+ auto I = makeTypeInfo<TagTypeInfo>(
368
+ T->getTemplateName ().getAsTemplateDecl (), quals);
345
369
return I;
346
370
}
347
371
// elaborated type specifier or
@@ -350,8 +374,7 @@ buildTypeInfoForType(
350
374
{
351
375
auto * T = cast<ElaboratedType>(type);
352
376
auto I = buildTypeInfoForType (
353
- T->getNamedType ().withFastQualifiers (
354
- qt.getLocalFastQualifiers ()));
377
+ T->getNamedType (), quals);
355
378
// ignore elaborated-type-specifiers
356
379
if (auto kw = T->getKeyword ();
357
380
kw != ElaboratedTypeKeyword::ETK_Typename &&
@@ -376,79 +399,65 @@ buildTypeInfoForType(
376
399
case Type::DependentTemplateSpecialization:
377
400
{
378
401
auto * T = cast<DependentTemplateSpecializationType>(type);
379
- auto I = std::make_unique<SpecializationTypeInfo>();
402
+ auto I = makeTypeInfo<SpecializationTypeInfo>(
403
+ T->getIdentifier (), quals);
380
404
I->ParentType = buildTypeInfoForType (
381
405
T->getQualifier ());
382
- I->Name = T->getIdentifier ()->getName ();
383
406
buildTemplateArgs (I->TemplateArgs , T->template_arguments ());
384
- I->CVQualifiers = convertToQualifierKind (
385
- qt.getLocalQualifiers ());
386
407
return I;
387
408
}
388
409
// specialization of a class/alias template or
389
410
// template template parameter
390
411
case Type::TemplateSpecialization:
391
412
{
392
413
auto * T = cast<TemplateSpecializationType>(type);
393
- auto I = std::make_unique<SpecializationTypeInfo>();
394
- // use the SymbolID of the corresponding template if it is known
395
- if (auto * TD = T->getTemplateName ().getAsTemplateDecl ())
396
- {
397
- extractSymbolID (TD, I->id );
398
- I->Name = TD->getNameAsString ();
399
- }
414
+ auto I = makeTypeInfo<SpecializationTypeInfo>(
415
+ T->getTemplateName ().getAsTemplateDecl (), quals);
400
416
buildTemplateArgs (I->TemplateArgs , T->template_arguments ());
401
- I->CVQualifiers = convertToQualifierKind (
402
- qt.getLocalQualifiers ());
403
417
return I;
404
418
}
405
419
// dependent typename-specifier
406
420
case Type::DependentName:
407
421
{
408
422
auto * T = cast<DependentNameType>(type);
409
- auto I = std::make_unique<TagTypeInfo>();
423
+ auto I = makeTypeInfo<TagTypeInfo>(
424
+ T->getIdentifier (), quals);
410
425
I->ParentType = buildTypeInfoForType (
411
426
T->getQualifier ());
412
- I->Name = T->getIdentifier ()->getName ();
413
- I->CVQualifiers = convertToQualifierKind (
414
- qt.getLocalQualifiers ());
415
427
return I;
416
428
}
417
- // injected class name within a class template
418
- // or a specialization thereof
429
+ // record & enum types, as well as injected class names
430
+ // within a class template (or specializations thereof)
419
431
case Type::InjectedClassName:
420
- {
421
- // we treat the injected class name as a normal CXXRecord,
422
- // and do not store the implicit template argument list
423
- auto * T = cast<InjectedClassNameType>(type);
424
- auto I = std::make_unique<TagTypeInfo>();
425
- extractSymbolID (T->getDecl (), I->id );
426
- I->Name = T->getDecl ()->getNameAsString ();
427
- I->CVQualifiers = convertToQualifierKind (
428
- qt.getLocalQualifiers ());
429
- return I;
430
- }
431
- // record & enum types
432
432
case Type::Record:
433
433
case Type::Enum:
434
434
{
435
- auto * T = cast<TagType>(type);
436
- auto I = std::make_unique<TagTypeInfo>();
437
- extractSymbolID (T->getDecl (), I->id );
438
- I->Name = T->getDecl ()->getNameAsString ();
439
- I->CVQualifiers = convertToQualifierKind (
440
- qt.getLocalQualifiers ());
435
+ auto I = makeTypeInfo<TagTypeInfo>(
436
+ type->getAsTagDecl (), quals);
441
437
return I;
442
438
}
443
439
// typedef/alias type
444
440
case Type::Typedef:
445
441
{
446
442
auto * T = cast<TypedefType>(type);
447
- auto I = std::make_unique<TagTypeInfo>();
448
- extractSymbolID (T->getDecl (), I->id );
449
- I->Name = T->getDecl ()->getNameAsString ();
450
- I->CVQualifiers = convertToQualifierKind (
451
- qt.getLocalQualifiers ());
443
+ auto I = makeTypeInfo<TagTypeInfo>(
444
+ T->getDecl (), quals);
445
+ return I;
446
+ }
447
+ case Type::TemplateTypeParm:
448
+ {
449
+ auto * T = cast<TemplateTypeParmType>(type);
450
+ auto I = std::make_unique<BuiltinTypeInfo>();
451
+ if (auto * D = T->getDecl ())
452
+ {
453
+ // special case for implicit template parameters
454
+ // resulting from abbreviated function templates
455
+ if (D->isImplicit ())
456
+ I->Name = " auto" ;
457
+ else if (auto * II = D->getIdentifier ())
458
+ I->Name = II->getName ();
459
+ }
460
+ I->CVQualifiers = convertToQualifierKind (quals);
452
461
return I;
453
462
}
454
463
// builtin/unhandled type
@@ -457,8 +466,7 @@ buildTypeInfoForType(
457
466
auto I = std::make_unique<BuiltinTypeInfo>();
458
467
I->Name = getTypeAsString (
459
468
qt.withoutLocalFastQualifiers ());
460
- I->CVQualifiers = convertToQualifierKind (
461
- qt.getLocalQualifiers ());
469
+ I->CVQualifiers = convertToQualifierKind (quals);
462
470
return I;
463
471
}
464
472
}
@@ -611,6 +619,9 @@ buildTemplateArgs(
611
619
if (arg.getKind () == TemplateArgument::Type)
612
620
{
613
621
QualType qt = arg.getAsType ();
622
+ // KRYSTIAN FIXME: we *really* should not be
623
+ // converting types to strings like this.
624
+ // TArg needs to be a variant type anyways.
614
625
arg_str = toString (*buildTypeInfoForType (qt));
615
626
}
616
627
else
@@ -880,13 +891,69 @@ extractInfo(
880
891
return false ;
881
892
if (! extractSymbolID (D, I.id ))
882
893
return false ;
883
- I.Name = D-> getNameAsString ( );
894
+ I.Name = extractName (D );
884
895
// do not extract javadocs for namespaces
885
896
if (! I.isNamespace ())
886
897
parseRawComment (I.javadoc , D);
887
898
return true ;
888
899
}
889
900
901
+ std::string
902
+ ASTVisitor::
903
+ extractName (
904
+ const NamedDecl* D)
905
+ {
906
+ std::string result;
907
+ DeclarationName N = D->getDeclName ();
908
+ switch (N.getNameKind ())
909
+ {
910
+ case DeclarationName::Identifier:
911
+ if (const auto * I = N.getAsIdentifierInfo ())
912
+ result.append (I->getName ());
913
+ break ;
914
+ case DeclarationName::CXXDestructorName:
915
+ result.push_back (' ~' );
916
+ [[fallthrough]];
917
+ case DeclarationName::CXXConstructorName:
918
+ if (const auto * R = N.getCXXNameType ()->getAsCXXRecordDecl ())
919
+ result.append (R->getIdentifier ()->getName ());
920
+ break ;
921
+ case DeclarationName::CXXDeductionGuideName:
922
+ if (const auto * T = N.getCXXDeductionGuideTemplate ())
923
+ result.append (T->getIdentifier ()->getName ());
924
+ break ;
925
+ case DeclarationName::CXXConversionFunctionName:
926
+ {
927
+ MRDOX_ASSERT (isa<CXXConversionDecl>(D));
928
+ const auto * CD = cast<CXXConversionDecl>(D);
929
+ result.append (" operator " );
930
+ // KRYSTIAN FIXME: we *really* should not be
931
+ // converting types to strings like this
932
+ result.append (toString (
933
+ *buildTypeInfoForType (
934
+ CD->getReturnType ())));
935
+ break ;
936
+ }
937
+ case DeclarationName::CXXOperatorName:
938
+ {
939
+ OperatorKind K = convertToOperatorKind (
940
+ N.getCXXOverloadedOperator ());
941
+ result.append (" operator" );
942
+ std::string_view name = getOperatorName (K);
943
+ if (std::isalpha (name.front ()))
944
+ result.push_back (' ' );
945
+ result.append (name);
946
+ break ;
947
+ }
948
+ case DeclarationName::CXXLiteralOperatorName:
949
+ case DeclarationName::CXXUsingDirective:
950
+ break ;
951
+ default :
952
+ MRDOX_UNREACHABLE ();
953
+ }
954
+ return result;
955
+ }
956
+
890
957
// ------------------------------------------------
891
958
892
959
bool
0 commit comments