@@ -85,12 +85,14 @@ class RefParser
8585 }
8686 MRDOCS_CHECK_OR (parseComponents (), false );
8787 skipWhitespace ();
88- if (peek (' (' ))
88+ result_.HasFunctionParameters = peek (' (' , ' ' );
89+ if (result_.HasFunctionParameters )
8990 {
9091 ParsedMemberFunctionSuffix functionParameters;
9192 MRDOCS_CHECK_OR (parseFunctionSuffix (functionParameters), false );
9293 result_.FunctionParameters = std::move (functionParameters.Params );
9394 result_.IsVariadic = functionParameters.IsVariadic ;
95+ result_.ExceptionSpec = std::move (functionParameters.ExceptionSpec );
9496 result_.IsConst = functionParameters.IsConst ;
9597 result_.IsVolatile = functionParameters.IsVolatile ;
9698 result_.Kind = functionParameters.Kind ;
@@ -647,6 +649,7 @@ class RefParser
647649 // this? decl-specifier-seq
648650
649651 char const * start = ptr_;
652+ skipWhitespace ();
650653 if (!parseLiteral (' (' ))
651654 {
652655 ptr_ = start;
@@ -934,6 +937,8 @@ class RefParser
934937 if (contains_any (specifiers, {" signed" , " unsigned" }))
935938 {
936939 bool explicitlySigned = contains (specifiers, " signed" );
940+ std::string_view signStr = explicitlySigned ? " signed" : " unsigned" ;
941+ // Infer basic fundamental type from "signed" or "unsigned"
937942 if (!dest)
938943 {
939944 NamedTypeInfo NTI;
@@ -942,42 +947,29 @@ class RefParser
942947 NTI.Name = NI;
943948 dest = NTI;
944949 }
945- else
950+ // Check if the type is named
951+ if (!dest->isNamed ())
946952 {
947- if (!dest->isNamed ())
948- {
949- if (explicitlySigned)
950- {
951- setError (" expected type for 'signed' specifier" );
952- }
953- else
954- {
955- setError (" expected type for 'unsigned' specifier" );
956- }
957- ptr_ = start;
958- return false ;
959- }
960- if (auto & namedParam = dynamic_cast <NamedTypeInfo&>(*dest);
961- namedParam.Name ->Name != " int" &&
962- namedParam.Name ->Name != " char" )
963- {
964- if (explicitlySigned)
965- {
966- setError (start, " expected 'int' or 'char' for 'signed' specifier" );
967- }
968- else
969- {
970- setError (start, " expected 'int' or 'char' for 'unsigned' specifier" );
971- }
972- ptr_ = start;
973- return false ;
974- }
953+ setError (fmt::format (" expected named type for '{}' specifier" , signStr));
954+ ptr_ = start;
955+ return false ;
975956 }
957+ // Check if the type is "int" or "char"
958+ auto & namedParam = dynamic_cast <NamedTypeInfo&>(*dest);
959+ if (!contains ({" int" , " char" }, namedParam.Name ->Name ))
960+ {
961+ setError (fmt::format (" expected 'int' or 'char' for '{}' specifier" , signStr));
962+ ptr_ = start;
963+ return false ;
964+ }
965+ // Add the specifier to the type name
966+ namedParam.Name ->Name = fmt::format (" {} {}" , signStr, namedParam.Name ->Name );
976967 }
977968
978969 // - "short" can be combined with int.
979970 if (contains (specifiers, " short" ))
980971 {
972+ // Infer basic fundamental type from "short"
981973 if (!dest)
982974 {
983975 NamedTypeInfo NTI;
@@ -986,27 +978,29 @@ class RefParser
986978 NTI.Name = NI;
987979 dest = NTI;
988980 }
989- else
981+ // Check if the type is named
982+ if (!dest->isNamed ())
990983 {
991- if (!dest->isNamed ())
992- {
993- setError (start, " expected type for 'short' specifier" );
994- ptr_ = start;
995- return false ;
996- }
997- if (auto & namedParam = dynamic_cast <NamedTypeInfo&>(*dest);
998- namedParam.Name ->Name != " int" )
999- {
1000- setError (start, " expected 'int' for 'short' specifier" );
1001- ptr_ = start;
1002- return false ;
1003- }
984+ setError (start, " expected named type for 'short' specifier" );
985+ ptr_ = start;
986+ return false ;
1004987 }
988+ // Check if the type is "int"
989+ auto & namedParam = dynamic_cast <NamedTypeInfo&>(*dest);
990+ if (!contains ({" int" , " signed int" , " unsigned int" }, namedParam.Name ->Name ))
991+ {
992+ setError (start, " expected 'int' for 'short' specifier" );
993+ ptr_ = start;
994+ return false ;
995+ }
996+ // Add the specifier to the type name
997+ namedParam.Name ->Name = fmt::format (" short {}" , namedParam.Name ->Name );
1005998 }
1006999
10071000 // - "long" can be combined with "int", "double" and "long"
10081001 if (contains (specifiers, " long" ))
10091002 {
1003+ // Infer basic fundamental type from "long"
10101004 if (!dest)
10111005 {
10121006 NamedTypeInfo NTI;
@@ -1015,33 +1009,34 @@ class RefParser
10151009 NTI.Name = NI;
10161010 dest = NTI;
10171011 }
1018- else
1012+ // Check if the type is named
1013+ if (!dest->isNamed ())
10191014 {
1020- if (!dest->isNamed ())
1021- {
1022- setError (start, " expected type for 'long' specifier" );
1023- ptr_ = start;
1024- return false ;
1025- }
1026- if (auto & namedParam = dynamic_cast <NamedTypeInfo&>(*dest);
1027- namedParam.Name ->Name != " int" &&
1028- namedParam.Name ->Name != " double" &&
1029- namedParam.Name ->Name != " long" )
1030- {
1031- setError (start, " expected 'int', 'double' or 'long' for 'long' specifier" );
1032- ptr_ = start;
1033- return false ;
1034- }
1015+ setError (start, " expected named type for 'long' specifier" );
1016+ ptr_ = start;
1017+ return false ;
1018+ }
1019+ auto & namedParam = dynamic_cast <NamedTypeInfo&>(*dest);
1020+ if (!contains ({" int" , " signed int" , " unsigned int" , " double" }, namedParam.Name ->Name ))
1021+ {
1022+ setError (start, " expected 'int' or 'double' for 'long' specifier" );
1023+ ptr_ = start;
1024+ return false ;
10351025 }
1026+ // Add the specifier to the type name
1027+ bool const isLongLong = contains_n (specifiers, " long" , 2 );
1028+ namedParam.Name ->Name = fmt::format (" {} {}" , isLongLong ? " long long" : " long" , namedParam.Name ->Name );
10361029 }
10371030
1031+ // Final check: if dest is still empty, we have an error
10381032 if (!dest)
10391033 {
10401034 ptr_ = start;
10411035 setError (" expected parameter type" );
10421036 return false ;
10431037 }
10441038
1039+ // Set cv qualifiers
10451040 dest->IsConst = contains (specifiers, " const" );
10461041 dest->IsVolatile = contains (specifiers, " volatile" );
10471042
0 commit comments