Skip to content

Commit f5e3421

Browse files
committed
TypeInfo identifies fundamental types
#feat
1 parent 4a40e18 commit f5e3421

File tree

4 files changed

+520
-2
lines changed

4 files changed

+520
-2
lines changed

include/mrdocs/Metadata/Type.hpp

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,11 +208,185 @@ struct TypeInfoCommonBase : TypeInfo
208208
}
209209
};
210210

211+
/** Categorically describes a fundamental type.
212+
213+
@see https://en.cppreference.com/w/cpp/language/types
214+
*/
215+
enum class FundamentalTypeKind
216+
{
217+
// void
218+
Void,
219+
// std::nullptr_t
220+
Nullptr,
221+
// bool
222+
Bool,
223+
// char
224+
Char,
225+
// signed char
226+
SignedChar,
227+
// unsigned char
228+
UnsignedChar,
229+
// char8_t
230+
Char8,
231+
// char16_t
232+
Char16,
233+
// char32_t
234+
Char32,
235+
// wchar_t
236+
WChar,
237+
// short / short int / signed short / signed short int
238+
Short,
239+
// unsigned short / unsigned short int
240+
UnsignedShort,
241+
// int / signed / signed int
242+
Int,
243+
// unsigned / unsigned int
244+
UnsignedInt,
245+
// long / long int / signed long / signed long int
246+
Long,
247+
// unsigned long / unsigned long int
248+
UnsignedLong,
249+
// long long / long long int / signed long long / signed long long int
250+
LongLong,
251+
// unsigned long long / unsigned long long int
252+
UnsignedLongLong,
253+
// float
254+
Float,
255+
// double
256+
Double,
257+
// long double
258+
LongDouble
259+
};
260+
261+
/** Convert a FundamentalTypeKind to a string.
262+
263+
This function converts a FundamentalTypeKind to
264+
the shortest canonical string representing the type.
265+
266+
@return The string representation of the kind
267+
*/
268+
MRDOCS_DECL
269+
std::string_view
270+
toString(FundamentalTypeKind kind) noexcept;
271+
272+
/** Convert a string to a FundamentalTypeKind.
273+
274+
This function converts a string to a FundamentalTypeKind.
275+
276+
All variations of the type specifiers are supported.
277+
278+
However, the "long long" specifier cannot be split
279+
into two separate specifiers.
280+
281+
@return true if the string was successfully converted
282+
*/
283+
MRDOCS_DECL
284+
bool
285+
fromString(std::string_view str, FundamentalTypeKind& kind) noexcept;
286+
287+
/** Apply the "long" specifier to the type
288+
289+
If applying "long" the specifier is a valid operation
290+
the function changes the type and returns true.
291+
292+
For instance, applying "long" to
293+
`FundamentalTypeKind::Int` ("int") results in
294+
`FundamentalTypeKind::Long` ("long int").
295+
296+
@param[in/out] kind The type to modify
297+
@return Whether the operation was successful
298+
*/
299+
MRDOCS_DECL
300+
bool
301+
makeLong(FundamentalTypeKind& kind) noexcept;
302+
303+
/** Apply the "short" specifier to the type
304+
305+
If applying "short" the specifier is a valid operation
306+
the function changes the type and returns true.
307+
308+
For instance, applying "short" to
309+
`FundamentalTypeKind::Int` ("int") results in
310+
`FundamentalTypeKind::Short` ("short int").
311+
312+
@param[in/out] kind The type to modify
313+
@return Whether the operation was successful
314+
*/
315+
MRDOCS_DECL
316+
bool
317+
makeShort(FundamentalTypeKind& kind) noexcept;
318+
319+
/** Apply the "signed" specifier to the type
320+
321+
If applying the "signed" specifier is a valid operation
322+
the function changes the type and returns true.
323+
324+
For instance, applying "signed" to
325+
`FundamentalTypeKind::Char` ("char") results in
326+
`FundamentalTypeKind::SignedChar` ("signed char").
327+
328+
It also returns true if applying the "signed" specifier
329+
is a valid operation but doesn't affect the
330+
type.
331+
332+
For instance, applying "signed" to
333+
`FundamentalTypeKind::Int` ("int") doesn't change the type
334+
but returns `true`, even though `FundamentalTypeKind::Int`
335+
could be declared as "int" or "signed" and multiple
336+
"signed" specifiers are not allowed.
337+
338+
@param[in/out] kind The type to modify
339+
@return Whether the operation was successful
340+
*/
341+
MRDOCS_DECL
342+
bool
343+
makeSigned(FundamentalTypeKind& kind) noexcept;
344+
345+
/** Apply the "unsigned" specifier to the type
346+
347+
If applying the "unsigned" specifier is a valid operation
348+
the function changes the type and returns true.
349+
350+
For instance, applying "unsigned" to
351+
`FundamentalTypeKind::Char` ("char") results in
352+
`FundamentalTypeKind::UnsignedChar` ("unsigned char")
353+
and applying "unsigned" to
354+
`FundamentalTypeKind::Int` ("int") results in
355+
`FundamentalTypeKind::UnsignedInt` ("unsigned int").
356+
357+
@param[in/out] kind The type to modify
358+
@return Whether the operation was successful
359+
*/
360+
MRDOCS_DECL
361+
bool
362+
makeUnsigned(FundamentalTypeKind& kind) noexcept;
363+
364+
/** Apply the "char" specifier to the type
365+
366+
If applying the "char" specifier to a type
367+
that might have been declared only with "signed/unsigned"
368+
or "short/long" specifiers, the function changes the type
369+
and returns true.
370+
371+
For instance, applying "char" to
372+
`FundamentalTypeKind::Int` ("int", which could be declared
373+
as "signed") results in
374+
`FundamentalTypeKind::SignedChar` ("signed char").
375+
376+
@param[in/out] kind The type to modify
377+
@return Whether the operation was successful
378+
*/
379+
MRDOCS_DECL
380+
bool
381+
makeChar(FundamentalTypeKind& kind) noexcept;
382+
211383
struct NamedTypeInfo final
212384
: TypeInfoCommonBase<TypeKind::Named>
213385
{
214386
Polymorphic<NameInfo> Name;
215387

388+
std::optional<FundamentalTypeKind> FundamentalType;
389+
216390
std::strong_ordering
217391
operator<=>(NamedTypeInfo const& other) const;
218392
};

src/lib/AST/ClangHelpers.hpp

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -500,7 +500,7 @@ toFunctionClass(Decl::Kind const kind)
500500
*/
501501
inline
502502
AutoKind
503-
convertToAutoKind(AutoTypeKeyword const kind)
503+
toAutoKind(AutoTypeKeyword const kind)
504504
{
505505
switch(kind)
506506
{
@@ -514,6 +514,63 @@ convertToAutoKind(AutoTypeKeyword const kind)
514514
}
515515
}
516516

517+
/** Convert a Clang AutoTypeKeyword into a MrDocs AutoKind
518+
*/
519+
inline
520+
std::optional<FundamentalTypeKind>
521+
toFundamentalTypeKind(BuiltinType::Kind const kind)
522+
{
523+
switch(kind)
524+
{
525+
case BuiltinType::Kind::Void:
526+
return FundamentalTypeKind::Void;
527+
case BuiltinType::Kind::NullPtr:
528+
return FundamentalTypeKind::Nullptr;
529+
case BuiltinType::Kind::Bool:
530+
return FundamentalTypeKind::Bool;
531+
case BuiltinType::Kind::Char_U:
532+
case BuiltinType::Kind::Char_S:
533+
return FundamentalTypeKind::Char;
534+
case BuiltinType::Kind::SChar:
535+
return FundamentalTypeKind::SignedChar;
536+
case BuiltinType::Kind::UChar:
537+
return FundamentalTypeKind::UnsignedChar;
538+
case BuiltinType::Kind::Char8:
539+
return FundamentalTypeKind::Char8;
540+
case BuiltinType::Kind::Char16:
541+
return FundamentalTypeKind::Char16;
542+
case BuiltinType::Kind::Char32:
543+
return FundamentalTypeKind::Char32;
544+
case BuiltinType::Kind::WChar_S:
545+
case BuiltinType::Kind::WChar_U:
546+
return FundamentalTypeKind::WChar;
547+
case BuiltinType::Kind::Short:
548+
return FundamentalTypeKind::Short;
549+
case BuiltinType::Kind::UShort:
550+
return FundamentalTypeKind::UnsignedShort;
551+
case BuiltinType::Kind::Int:
552+
return FundamentalTypeKind::Int;
553+
case BuiltinType::Kind::UInt:
554+
return FundamentalTypeKind::UnsignedInt;
555+
case BuiltinType::Kind::Long:
556+
return FundamentalTypeKind::Long;
557+
case BuiltinType::Kind::ULong:
558+
return FundamentalTypeKind::UnsignedLong;
559+
case BuiltinType::Kind::LongLong:
560+
return FundamentalTypeKind::LongLong;
561+
case BuiltinType::Kind::ULongLong:
562+
return FundamentalTypeKind::UnsignedLongLong;
563+
case BuiltinType::Kind::Float:
564+
return FundamentalTypeKind::Float;
565+
case BuiltinType::Kind::Double:
566+
return FundamentalTypeKind::Double;
567+
case BuiltinType::Kind::LongDouble:
568+
return FundamentalTypeKind::LongDouble;
569+
default:
570+
return std::nullopt;
571+
}
572+
}
573+
517574
// ----------------------------------------------------------------
518575

519576
/** Visit a Decl and call the appropriate visitor function.

src/lib/AST/TypeInfoBuilder.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ buildAuto(
126126
AutoTypeInfo I;
127127
I.IsConst = quals & Qualifiers::Const;
128128
I.IsVolatile = quals & Qualifiers::Volatile;
129-
I.Keyword = convertToAutoKind(T->getKeyword());
129+
I.Keyword = toAutoKind(T->getKeyword());
130130
if(T->isConstrained())
131131
{
132132
std::optional<ArrayRef<TemplateArgument>> TArgs;
@@ -153,12 +153,18 @@ buildTerminal(
153153
unsigned quals,
154154
bool pack)
155155
{
156+
MRDOCS_SYMBOL_TRACE(T, getASTVisitor().context_);
156157
NamedTypeInfo TI;
157158
TI.IsConst = quals & Qualifiers::Const;
158159
TI.IsVolatile = quals & Qualifiers::Volatile;
159160
TI.Name = MakePolymorphic<NameInfo>();
160161
TI.Name->Name = getASTVisitor().toString(T);
161162
TI.Name->Prefix = getASTVisitor().toNameInfo(NNS);
163+
if (isa<BuiltinType>(T))
164+
{
165+
auto const* FT = cast<BuiltinType>(T);
166+
TI.FundamentalType = toFundamentalTypeKind(FT->getKind());
167+
}
162168
TI.Constraints = this->Constraints;
163169
*Inner = std::move(TI);
164170
Result->Constraints = this->Constraints;

0 commit comments

Comments
 (0)