From 4ccf10f3fa43f28555168b9b7730deb73a7aaa6a Mon Sep 17 00:00:00 2001 From: acqn Date: Sun, 2 Aug 2020 21:51:26 +0800 Subject: [PATCH] Utility to get full type names. --- src/cc65/datatype.c | 233 ++++++++++++++++++++++++++++++++++++++++++++ src/cc65/datatype.h | 16 +++ 2 files changed, 249 insertions(+) diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index 5ac2ec4b4..2c2167188 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -78,6 +78,144 @@ Type type_double[] = { TYPE(T_DOUBLE), TYPE(T_END) }; +static struct StrBuf* GetFullTypeNameWestEast (struct StrBuf* West, struct StrBuf* East, const Type* T) +/* Return the name string of the given type split into a western part and an +** eastern part. +*/ +{ + struct StrBuf Buf = STATIC_STRBUF_INITIALIZER; + + if (IsTypeArray (T)) { + + long Count = GetElementCount (T); + if (!SB_IsEmpty (East)) { + if (Count > 0) { + SB_Printf (&Buf, "[%ld]", Count); + } else { + SB_Printf (&Buf, "[]"); + } + SB_Append (East, &Buf); + SB_Terminate (East); + + } else { + if (Count > 0) { + SB_Printf (East, "[%ld]", Count); + } else { + SB_Printf (East, "[]"); + } + + if (!SB_IsEmpty (West)) { + /* Add parentheses to West */ + SB_Printf (&Buf, "(%s)", SB_GetConstBuf (West)); + SB_Copy (West, &Buf); + SB_Terminate (West); + } + } + + /* Get element type */ + GetFullTypeNameWestEast (West, East, T + 1); + + } else if (IsTypeFunc (T)) { + + FuncDesc* F = GetFuncDesc (T); + struct StrBuf ParamList = STATIC_STRBUF_INITIALIZER; + + /* First argument */ + SymEntry* Param = F->SymTab->SymHead; + for (unsigned I = 1; I < F->ParamCount; ++I) { + CHECK (Param->NextSym != 0 && (Param->Flags & SC_PARAM) != 0); + SB_AppendStr (&ParamList, SB_GetConstBuf (GetFullTypeNameBuf (&Buf, Param->Type))); + SB_AppendStr (&ParamList, ", "); + SB_Clear (&Buf); + /* Next argument */ + Param = Param->NextSym; + } + if ((F->Flags & FD_VARIADIC) == 0) { + if (F->ParamCount > 0) { + SB_AppendStr (&ParamList, SB_GetConstBuf (GetFullTypeNameBuf (&Buf, Param->Type))); + } else { + SB_AppendStr (&ParamList, "void"); + } + } else { + if (F->ParamCount > 0) { + SB_AppendStr (&ParamList, SB_GetConstBuf (GetFullTypeNameBuf (&Buf, Param->Type))); + SB_AppendStr (&ParamList, ", ..."); + } else { + SB_AppendStr (&ParamList, "..."); + } + } + SB_Terminate (&ParamList); + + /* Join the existing West and East together */ + if (!SB_IsEmpty (East)) { + SB_Append (West, East); + SB_Terminate (West); + SB_Clear (East); + } + + if (SB_IsEmpty (West)) { + /* Just use the param list */ + SB_Printf (West, "(%s)", SB_GetConstBuf (&ParamList)); + } else { + /* Append the param list to the existing West */ + SB_Printf (&Buf, "(%s)(%s)", SB_GetConstBuf (West), SB_GetConstBuf (&ParamList)); + SB_Printf (West, "%s", SB_GetConstBuf (&Buf)); + } + SB_Done (&ParamList); + + /* Return type */ + GetFullTypeNameWestEast (West, East, T + 1); + + } else if (IsTypePtr (T)) { + + int QualCount = 0; + + SB_Printf (&Buf, "*"); + + /* Add qualifiers */ + if ((GetQualifier (T) & ~T_QUAL_NEAR) != T_QUAL_NONE) { + QualCount = GetQualifierTypeCodeNameBuf (&Buf, T->C, T_QUAL_NEAR); + } + + if (!SB_IsEmpty (West)) { + if (QualCount > 0) { + SB_AppendChar (&Buf, ' '); + } + SB_Append (&Buf, West); + } + + SB_Copy (West, &Buf); + SB_Terminate (West); + + /* Get indirection type */ + GetFullTypeNameWestEast (West, East, T + 1); + + } else { + + /* Add qualifiers */ + if ((GetQualifier (T) & ~T_QUAL_NEAR) != 0) { + if (GetQualifierTypeCodeNameBuf (&Buf, T->C, T_QUAL_NEAR) > 0) { + SB_AppendChar (&Buf, ' '); + } + } + + SB_AppendStr (&Buf, GetSymTypeName (T)); + + if (!SB_IsEmpty (West)) { + SB_AppendChar (&Buf, ' '); + SB_Append (&Buf, West); + } + + SB_Copy (West, &Buf); + SB_Terminate (West); + } + + SB_Done (&Buf); + return West; +} + + + const char* GetBasicTypeName (const Type* T) /* Return a const name string of the basic type. ** Return "type" for unknown basic types. @@ -134,6 +272,101 @@ const char* GetBasicTypeName (const Type* T) +const char* GetFullTypeName (const Type* T) +/* Return the full name string of the given type. +** Note: This may use a static buffer that could be overwritten by other calls. +*/ +{ + static struct StrBuf Buf = STATIC_STRBUF_INITIALIZER; + SB_Clear (&Buf); + GetFullTypeNameBuf (&Buf, T); + + return SB_GetConstBuf (&Buf); +} + + + +struct StrBuf* GetFullTypeNameBuf (struct StrBuf* S, const Type* T) +/* Return the full name string of the given type */ +{ + struct StrBuf East = STATIC_STRBUF_INITIALIZER; + GetFullTypeNameWestEast (S, &East, T); + + /* Join West and East */ + SB_Append (S, &East); + SB_Terminate (S); + SB_Done (&East); + + return S; +} + + + +int GetQualifierTypeCodeNameBuf (struct StrBuf* S, TypeCode Qual, TypeCode IgnoredQual) +/* Return the names of the qualifiers of the type. +** Qualifiers to be ignored can be specified with the IgnoredQual flags. +** Return the count of added qualifier names. +*/ +{ + int Count = 0; + + Qual &= T_MASK_QUAL & ~IgnoredQual; + if (Qual & T_QUAL_CONST) { + if (!SB_IsEmpty (S)) { + SB_AppendChar (S, ' '); + } + SB_AppendStr (S, "const"); + ++Count; + } + if (Qual & T_QUAL_VOLATILE) { + if (Count > 0) { + SB_AppendChar (S, ' '); + } + SB_AppendStr (S, "volatile"); + ++Count; + } + if (Qual & T_QUAL_RESTRICT) { + if (Count > 0) { + SB_AppendChar (S, ' '); + } + SB_AppendStr (S, "restrict"); + ++Count; + } + if (Qual & T_QUAL_NEAR) { + if (Count > 0) { + SB_AppendChar (S, ' '); + } + SB_AppendStr (S, "__near__"); + ++Count; + } + if (Qual & T_QUAL_FAR) { + SB_AppendStr (S, "__far__"); + ++Count; + } + if (Qual & T_QUAL_FASTCALL) { + if (Count > 0) { + SB_AppendChar (S, ' '); + } + SB_AppendStr (S, "__fastcall__"); + ++Count; + } + if (Qual & T_QUAL_CDECL) { + if (Count > 0) { + SB_AppendChar (S, ' '); + } + SB_AppendStr (S, "__cdecl__"); + ++Count; + } + + if (Count > 0) { + SB_Terminate (S); + } + + return Count; +} + + + unsigned TypeLen (const Type* T) /* Return the length of the type string */ { diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index 4839be5d2..8e32d6404 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -203,6 +203,8 @@ extern Type type_double[]; /* Forward for the SymEntry struct */ struct SymEntry; +/* Forward for the StrBuf struct */ +struct StrBuf; /*****************************************************************************/ @@ -216,6 +218,20 @@ const char* GetBasicTypeName (const Type* T); ** Return "type" for unknown basic types. */ +const char* GetFullTypeName (const Type* T); +/* Return the full name string of the given type. +** Note: This may use a static buffer that could be overwritten by other calls. +*/ + +struct StrBuf* GetFullTypeNameBuf (struct StrBuf* S, const Type* T); +/* Return the full name string of the given type */ + +int GetQualifierTypeCodeNameBuf (struct StrBuf* S, TypeCode Qual, TypeCode IgnoredQual); +/* Return the names of the qualifiers of the type. +** Qualifiers to be ignored can be specified with the IgnoredQual flags. +** Return the count of added qualifier names. +*/ + unsigned TypeLen (const Type* T); /* Return the length of the type string */