Skip to content

Commit a3389a2

Browse files
committed
feat: info name improvements
closes #352
1 parent 5aa45a6 commit a3389a2

File tree

5 files changed

+167
-82
lines changed

5 files changed

+167
-82
lines changed

source/AST/ASTVisitor.cpp

Lines changed: 136 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,38 @@ getTypeAsString(
147147
return T.getAsString(astContext_->getPrintingPolicy());
148148
}
149149

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+
150182
std::unique_ptr<TypeInfo>
151183
ASTVisitor::
152184
buildTypeInfoForType(
@@ -170,38 +202,38 @@ buildTypeInfoForType(
170202
std::unique_ptr<TypeInfo>
171203
ASTVisitor::
172204
buildTypeInfoForType(
173-
QualType qt)
205+
QualType qt,
206+
unsigned quals)
174207
{
208+
qt.addFastQualifiers(quals);
175209
// should never be called for a QualType
176210
// that has no Type pointer
177211
MRDOX_ASSERT(! qt.isNull());
178212
const Type* type = qt.getTypePtr();
213+
quals = qt.getLocalFastQualifiers();
179214
switch(qt->getTypeClass())
180215
{
181216
// parenthesized types
182217
case Type::Paren:
183218
{
184219
auto* T = cast<ParenType>(type);
185220
return buildTypeInfoForType(
186-
T->getInnerType().withFastQualifiers(
187-
qt.getLocalFastQualifiers()));
221+
T->getInnerType(), quals);
188222
}
189223
// type with __atribute__
190224
case Type::Attributed:
191225
{
192226
auto* T = cast<AttributedType>(type);
193227
return buildTypeInfoForType(
194-
T->getModifiedType().withFastQualifiers(
195-
qt.getLocalFastQualifiers()));
228+
T->getModifiedType(), quals);
196229
}
197230
// adjusted and decayed types
198231
case Type::Decayed:
199232
case Type::Adjusted:
200233
{
201234
auto* T = cast<AdjustedType>(type);
202235
return buildTypeInfoForType(
203-
T->getOriginalType().withFastQualifiers(
204-
qt.getLocalFastQualifiers()));
236+
T->getOriginalType(), quals);
205237
}
206238
// using declarations
207239
case Type::Using:
@@ -210,8 +242,7 @@ buildTypeInfoForType(
210242
// look through the using declaration and
211243
// use the the type from the referenced declaration
212244
return buildTypeInfoForType(
213-
T->getUnderlyingType().withFastQualifiers(
214-
qt.getLocalFastQualifiers()));
245+
T->getUnderlyingType(), quals);
215246
}
216247
// pointers
217248
case Type::Pointer:
@@ -220,8 +251,7 @@ buildTypeInfoForType(
220251
auto I = std::make_unique<PointerTypeInfo>();
221252
I->PointeeType = buildTypeInfoForType(
222253
T->getPointeeType());
223-
I->CVQualifiers = convertToQualifierKind(
224-
qt.getLocalQualifiers());
254+
I->CVQualifiers = convertToQualifierKind(quals);
225255
return I;
226256
}
227257
// references
@@ -250,6 +280,7 @@ buildTypeInfoForType(
250280
T->getPointeeType());
251281
I->ParentType = buildTypeInfoForType(
252282
QualType(T->getClass(), 0));
283+
I->CVQualifiers = convertToQualifierKind(quals);
253284
return I;
254285
}
255286
// pack expansion
@@ -276,7 +307,7 @@ buildTypeInfoForType(
276307
I->RefQualifier = convertToReferenceKind(
277308
T->getRefQualifier());
278309
I->CVQualifiers = convertToQualifierKind(
279-
T->getMethodQuals());
310+
T->getMethodQuals().getFastQualifiers());
280311
I->ExceptionSpec = convertToNoexceptKind(
281312
T->getExceptionSpecType());
282313
return I;
@@ -325,23 +356,16 @@ buildTypeInfoForType(
325356
auto I = std::make_unique<BuiltinTypeInfo>();
326357
I->Name = getTypeAsString(
327358
qt.withoutLocalFastQualifiers());
328-
I->CVQualifiers = convertToQualifierKind(
329-
qt.getLocalQualifiers());
359+
I->CVQualifiers = convertToQualifierKind(quals);
330360
return I;
331361
}
332362
case Type::DeducedTemplateSpecialization:
333363
{
334364
auto* T = cast<DeducedTemplateSpecializationType>(type);
335365
if(T->isDeduced())
336366
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);
345369
return I;
346370
}
347371
// elaborated type specifier or
@@ -350,8 +374,7 @@ buildTypeInfoForType(
350374
{
351375
auto* T = cast<ElaboratedType>(type);
352376
auto I = buildTypeInfoForType(
353-
T->getNamedType().withFastQualifiers(
354-
qt.getLocalFastQualifiers()));
377+
T->getNamedType(), quals);
355378
// ignore elaborated-type-specifiers
356379
if(auto kw = T->getKeyword();
357380
kw != ElaboratedTypeKeyword::ETK_Typename &&
@@ -376,79 +399,65 @@ buildTypeInfoForType(
376399
case Type::DependentTemplateSpecialization:
377400
{
378401
auto* T = cast<DependentTemplateSpecializationType>(type);
379-
auto I = std::make_unique<SpecializationTypeInfo>();
402+
auto I = makeTypeInfo<SpecializationTypeInfo>(
403+
T->getIdentifier(), quals);
380404
I->ParentType = buildTypeInfoForType(
381405
T->getQualifier());
382-
I->Name = T->getIdentifier()->getName();
383406
buildTemplateArgs(I->TemplateArgs, T->template_arguments());
384-
I->CVQualifiers = convertToQualifierKind(
385-
qt.getLocalQualifiers());
386407
return I;
387408
}
388409
// specialization of a class/alias template or
389410
// template template parameter
390411
case Type::TemplateSpecialization:
391412
{
392413
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);
400416
buildTemplateArgs(I->TemplateArgs, T->template_arguments());
401-
I->CVQualifiers = convertToQualifierKind(
402-
qt.getLocalQualifiers());
403417
return I;
404418
}
405419
// dependent typename-specifier
406420
case Type::DependentName:
407421
{
408422
auto* T = cast<DependentNameType>(type);
409-
auto I = std::make_unique<TagTypeInfo>();
423+
auto I = makeTypeInfo<TagTypeInfo>(
424+
T->getIdentifier(), quals);
410425
I->ParentType = buildTypeInfoForType(
411426
T->getQualifier());
412-
I->Name = T->getIdentifier()->getName();
413-
I->CVQualifiers = convertToQualifierKind(
414-
qt.getLocalQualifiers());
415427
return I;
416428
}
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)
419431
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
432432
case Type::Record:
433433
case Type::Enum:
434434
{
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);
441437
return I;
442438
}
443439
// typedef/alias type
444440
case Type::Typedef:
445441
{
446442
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);
452461
return I;
453462
}
454463
// builtin/unhandled type
@@ -457,8 +466,7 @@ buildTypeInfoForType(
457466
auto I = std::make_unique<BuiltinTypeInfo>();
458467
I->Name = getTypeAsString(
459468
qt.withoutLocalFastQualifiers());
460-
I->CVQualifiers = convertToQualifierKind(
461-
qt.getLocalQualifiers());
469+
I->CVQualifiers = convertToQualifierKind(quals);
462470
return I;
463471
}
464472
}
@@ -611,6 +619,9 @@ buildTemplateArgs(
611619
if(arg.getKind() == TemplateArgument::Type)
612620
{
613621
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.
614625
arg_str = toString(*buildTypeInfoForType(qt));
615626
}
616627
else
@@ -880,13 +891,69 @@ extractInfo(
880891
return false;
881892
if(! extractSymbolID(D, I.id))
882893
return false;
883-
I.Name = D->getNameAsString();
894+
I.Name = extractName(D);
884895
// do not extract javadocs for namespaces
885896
if(! I.isNamespace())
886897
parseRawComment(I.javadoc, D);
887898
return true;
888899
}
889900

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+
890957
//------------------------------------------------
891958

892959
bool

0 commit comments

Comments
 (0)