Warning about ESU types declared inside parameter list as they are invisble outside.

This commit is contained in:
acqn 2020-08-15 06:27:11 +08:00 committed by Oliver Schmidt
parent 33a75e0a73
commit df755df44d
4 changed files with 65 additions and 22 deletions

View file

@ -515,7 +515,7 @@ static void ParseStorageClass (DeclSpec* D, unsigned DefStorage)
static SymEntry* ESUForwardDecl (const char* Name, unsigned Flags) static SymEntry* ESUForwardDecl (const char* Name, unsigned Flags, unsigned* DSFlags)
/* Handle an enum, struct or union forward decl */ /* Handle an enum, struct or union forward decl */
{ {
/* Try to find an enum/struct/union with the given name. If there is none, /* Try to find an enum/struct/union with the given name. If there is none,
@ -524,9 +524,9 @@ static SymEntry* ESUForwardDecl (const char* Name, unsigned Flags)
SymEntry* Entry = FindTagSym (Name); SymEntry* Entry = FindTagSym (Name);
if (Entry == 0) { if (Entry == 0) {
if ((Flags & SC_ESUTYPEMASK) != SC_ENUM) { if ((Flags & SC_ESUTYPEMASK) != SC_ENUM) {
Entry = AddStructSym (Name, Flags, 0, 0); Entry = AddStructSym (Name, Flags, 0, 0, DSFlags);
} else { } else {
Entry = AddEnumSym (Name, Flags, 0, 0); Entry = AddEnumSym (Name, Flags, 0, 0, DSFlags);
} }
} else if ((Entry->Flags & SC_TYPEMASK) != (Flags & SC_ESUTYPEMASK)) { } else if ((Entry->Flags & SC_TYPEMASK) != (Flags & SC_ESUTYPEMASK)) {
/* Already defined, but not the same type class */ /* Already defined, but not the same type class */
@ -575,7 +575,7 @@ static const Type* GetEnumeratorType (long Min, unsigned long Max, int Signed)
static SymEntry* ParseEnumDecl (const char* Name) static SymEntry* ParseEnumDecl (const char* Name, unsigned* DSFlags)
/* Process an enum declaration */ /* Process an enum declaration */
{ {
SymTable* FieldTab; SymTable* FieldTab;
@ -593,11 +593,11 @@ static SymEntry* ParseEnumDecl (const char* Name)
if (CurTok.Tok != TOK_LCURLY) { if (CurTok.Tok != TOK_LCURLY) {
/* Just a forward definition */ /* Just a forward definition */
return ESUForwardDecl (Name, SC_ENUM); return ESUForwardDecl (Name, SC_ENUM, DSFlags);
} }
/* Add a forward declaration for the enum tag in the current lexical level */ /* Add a forward declaration for the enum tag in the current lexical level */
AddEnumSym (Name, 0, 0, 0); AddEnumSym (Name, 0, 0, 0, DSFlags);
/* Skip the opening curly brace */ /* Skip the opening curly brace */
NextToken (); NextToken ();
@ -740,7 +740,7 @@ static SymEntry* ParseEnumDecl (const char* Name)
Flags |= SC_FICTITIOUS; Flags |= SC_FICTITIOUS;
} }
return AddEnumSym (Name, Flags, MemberType, FieldTab); return AddEnumSym (Name, Flags, MemberType, FieldTab, DSFlags);
} }
@ -870,7 +870,7 @@ static unsigned AliasAnonStructFields (const Declaration* Decl, SymEntry* Anon)
static SymEntry* ParseUnionDecl (const char* Name) static SymEntry* ParseUnionDecl (const char* Name, unsigned* DSFlags)
/* Parse a union declaration. */ /* Parse a union declaration. */
{ {
@ -886,11 +886,11 @@ static SymEntry* ParseUnionDecl (const char* Name)
if (CurTok.Tok != TOK_LCURLY) { if (CurTok.Tok != TOK_LCURLY) {
/* Just a forward declaration */ /* Just a forward declaration */
return ESUForwardDecl (Name, SC_UNION); return ESUForwardDecl (Name, SC_UNION, DSFlags);
} }
/* Add a forward declaration for the union tag in the current lexical level */ /* Add a forward declaration for the union tag in the current lexical level */
UnionTagEntry = AddStructSym (Name, SC_UNION, 0, 0); UnionTagEntry = AddStructSym (Name, SC_UNION, 0, 0, DSFlags);
UnionTagEntry->V.S.ACount = 0; UnionTagEntry->V.S.ACount = 0;
@ -1005,12 +1005,12 @@ NextMember: if (CurTok.Tok != TOK_COMMA) {
} }
/* Make a real entry from the forward decl and return it */ /* Make a real entry from the forward decl and return it */
return AddStructSym (Name, SC_UNION | SC_DEF | Flags, UnionSize, FieldTab); return AddStructSym (Name, SC_UNION | SC_DEF | Flags, UnionSize, FieldTab, DSFlags);
} }
static SymEntry* ParseStructDecl (const char* Name) static SymEntry* ParseStructDecl (const char* Name, unsigned* DSFlags)
/* Parse a struct declaration. */ /* Parse a struct declaration. */
{ {
@ -1027,11 +1027,11 @@ static SymEntry* ParseStructDecl (const char* Name)
if (CurTok.Tok != TOK_LCURLY) { if (CurTok.Tok != TOK_LCURLY) {
/* Just a forward declaration */ /* Just a forward declaration */
return ESUForwardDecl (Name, SC_STRUCT); return ESUForwardDecl (Name, SC_STRUCT, DSFlags);
} }
/* Add a forward declaration for the struct tag in the current lexical level */ /* Add a forward declaration for the struct tag in the current lexical level */
StructTagEntry = AddStructSym (Name, SC_STRUCT, 0, 0); StructTagEntry = AddStructSym (Name, SC_STRUCT, 0, 0, DSFlags);
StructTagEntry->V.S.ACount = 0; StructTagEntry->V.S.ACount = 0;
@ -1219,7 +1219,7 @@ NextMember: if (CurTok.Tok != TOK_COMMA) {
} }
/* Make a real entry from the forward decl and return it */ /* Make a real entry from the forward decl and return it */
return AddStructSym (Name, SC_STRUCT | SC_DEF | Flags, StructSize, FieldTab); return AddStructSym (Name, SC_STRUCT | SC_DEF | Flags, StructSize, FieldTab, DSFlags);
} }
@ -1402,7 +1402,7 @@ static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers,
/* Remember we have an extra type decl */ /* Remember we have an extra type decl */
D->Flags |= DS_EXTRA_TYPE; D->Flags |= DS_EXTRA_TYPE;
/* Declare the union in the current scope */ /* Declare the union in the current scope */
Entry = ParseUnionDecl (Ident); Entry = ParseUnionDecl (Ident, &D->Flags);
/* Encode the union entry into the type */ /* Encode the union entry into the type */
D->Type[0].C = T_UNION; D->Type[0].C = T_UNION;
SetESUSymEntry (D->Type, Entry); SetESUSymEntry (D->Type, Entry);
@ -1421,7 +1421,7 @@ static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers,
/* Remember we have an extra type decl */ /* Remember we have an extra type decl */
D->Flags |= DS_EXTRA_TYPE; D->Flags |= DS_EXTRA_TYPE;
/* Declare the struct in the current scope */ /* Declare the struct in the current scope */
Entry = ParseStructDecl (Ident); Entry = ParseStructDecl (Ident, &D->Flags);
/* Encode the struct entry into the type */ /* Encode the struct entry into the type */
D->Type[0].C = T_STRUCT; D->Type[0].C = T_STRUCT;
SetESUSymEntry (D->Type, Entry); SetESUSymEntry (D->Type, Entry);
@ -1444,7 +1444,8 @@ static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers,
/* Remember we have an extra type decl */ /* Remember we have an extra type decl */
D->Flags |= DS_EXTRA_TYPE; D->Flags |= DS_EXTRA_TYPE;
/* Parse the enum decl */ /* Parse the enum decl */
Entry = ParseEnumDecl (Ident); Entry = ParseEnumDecl (Ident, &D->Flags);
/* Encode the enum entry into the type */
D->Type[0].C |= T_ENUM; D->Type[0].C |= T_ENUM;
SetESUSymEntry (D->Type, Entry); SetESUSymEntry (D->Type, Entry);
D->Type[1].C = T_END; D->Type[1].C = T_END;
@ -1583,6 +1584,13 @@ static void ParseOldStyleParamList (FuncDesc* F)
/* Read the parameter */ /* Read the parameter */
ParseDecl (&Spec, &Decl, DM_NEED_IDENT); ParseDecl (&Spec, &Decl, DM_NEED_IDENT);
/* Warn about new local type declaration */
if ((Spec.Flags & DS_NEW_TYPE_DECL) != 0) {
Warning ("'%s' will be invisible out of this function",
GetFullTypeName (Spec.Type));
}
if (Decl.Ident[0] != '\0') { if (Decl.Ident[0] != '\0') {
/* We have a name given. Search for the symbol */ /* We have a name given. Search for the symbol */
@ -1650,6 +1658,12 @@ static void ParseAnsiParamList (FuncDesc* F)
Spec.StorageClass = SC_AUTO | SC_PARAM | SC_DEF; Spec.StorageClass = SC_AUTO | SC_PARAM | SC_DEF;
} }
/* Warn about new local type declaration */
if ((Spec.Flags & DS_NEW_TYPE_DECL) != 0) {
Warning ("'%s' will be invisible out of this function",
GetFullTypeName (Spec.Type));
}
/* Allow parameters without a name, but remember if we had some to /* Allow parameters without a name, but remember if we had some to
** eventually print an error message later. ** eventually print an error message later.
*/ */

View file

@ -57,6 +57,9 @@
#define DS_DEF_STORAGE 0x0001U /* Default storage class used */ #define DS_DEF_STORAGE 0x0001U /* Default storage class used */
#define DS_DEF_TYPE 0x0002U /* Default type used */ #define DS_DEF_TYPE 0x0002U /* Default type used */
#define DS_EXTRA_TYPE 0x0004U /* Extra type declared */ #define DS_EXTRA_TYPE 0x0004U /* Extra type declared */
#define DS_NEW_TYPE_DECL 0x0010U /* New type declared */
#define DS_NEW_TYPE_DEF 0x0020U /* New type defined */
#define DS_NEW_TYPE (DS_NEW_TYPE_DECL | DS_NEW_TYPE_DEF)
/* Result of ParseDeclSpec */ /* Result of ParseDeclSpec */
typedef struct DeclSpec DeclSpec; typedef struct DeclSpec DeclSpec;

View file

@ -686,7 +686,7 @@ static void AddSymEntry (SymTable* T, SymEntry* S)
SymEntry* AddEnumSym (const char* Name, unsigned Flags, const Type* Type, SymTable* Tab) SymEntry* AddEnumSym (const char* Name, unsigned Flags, const Type* Type, SymTable* Tab, unsigned* DSFlags)
/* Add an enum entry and return it */ /* Add an enum entry and return it */
{ {
SymTable* CurTagTab = TagTab; SymTable* CurTagTab = TagTab;
@ -719,6 +719,11 @@ SymEntry* AddEnumSym (const char* Name, unsigned Flags, const Type* Type, SymTab
Entry->V.E.Type = Type; Entry->V.E.Type = Type;
Entry->Flags &= ~SC_DECL; Entry->Flags &= ~SC_DECL;
Entry->Flags |= SC_DEF; Entry->Flags |= SC_DEF;
/* Remember this is the first definition of this type */
if (DSFlags != 0) {
*DSFlags |= DS_NEW_TYPE_DEF;
}
} }
} }
@ -741,6 +746,14 @@ SymEntry* AddEnumSym (const char* Name, unsigned Flags, const Type* Type, SymTab
Entry->Flags |= SC_DEF; Entry->Flags |= SC_DEF;
} }
/* Remember this is the first definition of this type */
if (CurTagTab != FailSafeTab && DSFlags != 0) {
if ((Entry->Flags & SC_DEF) != 0) {
*DSFlags |= DS_NEW_TYPE_DEF;
}
*DSFlags |= DS_NEW_TYPE_DECL;
}
/* Add it to the current table */ /* Add it to the current table */
AddSymEntry (CurTagTab, Entry); AddSymEntry (CurTagTab, Entry);
} }
@ -751,7 +764,7 @@ SymEntry* AddEnumSym (const char* Name, unsigned Flags, const Type* Type, SymTab
SymEntry* AddStructSym (const char* Name, unsigned Flags, unsigned Size, SymTable* Tab) SymEntry* AddStructSym (const char* Name, unsigned Flags, unsigned Size, SymTable* Tab, unsigned* DSFlags)
/* Add a struct/union entry and return it */ /* Add a struct/union entry and return it */
{ {
SymTable* CurTagTab = TagTab; SymTable* CurTagTab = TagTab;
@ -791,6 +804,11 @@ SymEntry* AddStructSym (const char* Name, unsigned Flags, unsigned Size, SymTabl
Entry->Flags = Flags; Entry->Flags = Flags;
Entry->V.S.SymTab = Tab; Entry->V.S.SymTab = Tab;
Entry->V.S.Size = Size; Entry->V.S.Size = Size;
/* Remember this is the first definition of this type */
if (DSFlags != 0) {
*DSFlags |= DS_NEW_TYPE_DEF;
}
} }
} }
@ -809,6 +827,14 @@ SymEntry* AddStructSym (const char* Name, unsigned Flags, unsigned Size, SymTabl
Entry->V.S.SymTab = Tab; Entry->V.S.SymTab = Tab;
Entry->V.S.Size = Size; Entry->V.S.Size = Size;
/* Remember this is the first definition of this type */
if (CurTagTab != FailSafeTab && DSFlags != 0) {
if ((Entry->Flags & SC_DEF) != 0) {
*DSFlags |= DS_NEW_TYPE_DEF;
}
*DSFlags |= DS_NEW_TYPE_DECL;
}
/* Add it to the current tag table */ /* Add it to the current tag table */
AddSymEntry (CurTagTab, Entry); AddSymEntry (CurTagTab, Entry);
} }

View file

@ -149,10 +149,10 @@ unsigned short FindSPAdjustment (const char* Name);
SymEntry* AddEnumSym (const char* Name, unsigned Flags, const Type* Type, SymTable* Tab); SymEntry* AddEnumSym (const char* Name, unsigned Flags, const Type* Type, SymTable* Tab, unsigned* DSFlags);
/* Add an enum entry and return it */ /* Add an enum entry and return it */
SymEntry* AddStructSym (const char* Name, unsigned Flags, unsigned Size, SymTable* Tab); SymEntry* AddStructSym (const char* Name, unsigned Flags, unsigned Size, SymTable* Tab, unsigned* DSFlags);
/* Add a struct/union entry and return it */ /* Add a struct/union entry and return it */
SymEntry* AddBitField (const char* Name, const Type* Type, unsigned Offs, SymEntry* AddBitField (const char* Name, const Type* Type, unsigned Offs,