Fixed visibility of undeclared functions and objects.

This commit is contained in:
acqn
2024-01-13 00:46:14 +08:00
parent a173428fab
commit 3d0dc58153
6 changed files with 78 additions and 21 deletions

View File

@@ -163,19 +163,19 @@ static void Parse (void)
break;
}
/* Check if we must reserve storage for the variable. We do this,
**
** - if it is not a typedef or function,
** - if we don't had a storage class given ("int i")
** - if the storage class is explicitly specified as static,
** - or if there is an initialization.
**
** This means that "extern int i;" will not get storage allocated
** in this translation unit.
*/
/* The symbol is now visible in the file scope */
if ((Decl.StorageClass & SC_TYPEMASK) != SC_FUNC &&
(Decl.StorageClass & SC_TYPEMASK) != SC_TYPEDEF) {
/* The variable is visible in the file scope */
/* Check if we must reserve storage for the variable. We do this,
**
** - if it is not a typedef or function,
** - if we don't had a storage class given ("int i")
** - if the storage class is explicitly specified as static,
** - or if there is an initialization.
**
** This means that "extern int i;" will not get storage allocated
** in this translation unit.
*/
if ((Decl.StorageClass & SC_STORAGEMASK) == SC_NONE ||
(Decl.StorageClass & SC_STORAGEMASK) == SC_STATIC ||
((Decl.StorageClass & SC_STORAGEMASK) == SC_EXTERN &&
@@ -189,7 +189,6 @@ static void Parse (void)
** or semicolon, it must be followed by a function body.
*/
if ((Decl.StorageClass & SC_TYPEMASK) == SC_FUNC) {
/* The function is now visible in the file scope */
if (CurTok.Tok == TOK_LCURLY) {
/* A definition */
Decl.StorageClass |= SC_DEF;

View File

@@ -557,8 +557,10 @@ static SymEntry* FindSymInTable (const SymTable* T, const char* Name, unsigned H
static SymEntry* FindSymInTree (const SymTable* Tab, const char* Name)
/* Find the symbol with the given name in the table tree that starts with T */
static SymEntry* FindVisibleSymInTree (const SymTable* Tab, const char* Name)
/* Find the visible symbol with the given name in the table tree that starts
** with Tab.
*/
{
/* Get the hash over the name */
unsigned Hash = HashStr (Name);
@@ -574,7 +576,7 @@ static SymEntry* FindSymInTree (const SymTable* Tab, const char* Name)
}
/* Bail out if we found it */
if (E != 0) {
if (E != 0 && (Tab != SymTab0 || (E->Flags & SC_LOCALSCOPE) == 0)) {
return E;
}
@@ -589,9 +591,9 @@ static SymEntry* FindSymInTree (const SymTable* Tab, const char* Name)
SymEntry* FindSym (const char* Name)
/* Find the symbol with the given name */
/* Find with the given name the symbol visible in the current scope */
{
return FindSymInTree (SymTab, Name);
return FindVisibleSymInTree (SymTab, Name);
}
@@ -613,9 +615,9 @@ SymEntry* FindLocalSym (const char* Name)
SymEntry* FindTagSym (const char* Name)
/* Find the symbol with the given name in the tag table */
/* Find with the given name the tag symbol visible in the current scope */
{
return FindSymInTree (TagTab, Name);
return FindVisibleSymInTree (TagTab, Name);
}
@@ -1356,6 +1358,13 @@ SymEntry* AddGlobalSym (const char* Name, const Type* T, unsigned Flags)
Name);
Entry = 0;
} else if ((Flags & SC_TYPEMASK) != SC_TYPEDEF) {
/* If we are adding the symbol in the file scope, it is now
** visible there.
*/
if (SymTab == SymTab0) {
Entry->Flags &= ~SC_LOCALSCOPE;
}
/* The C standard specifies that the result is undefined if the
** same thing has both internal and external linkage. Most
** compilers choose to either give an error at compile time, or
@@ -1415,6 +1424,13 @@ SymEntry* AddGlobalSym (const char* Name, const Type* T, unsigned Flags)
}
if (Entry == 0) {
/* Hide the symbol in the file scope if we are declaring it in a
** local scope.
*/
if (Tab == SymTab0 && SymTab != SymTab0) {
Flags |= SC_LOCALSCOPE;
}
/* Create a new entry */
Entry = NewSymEntry (Name, Flags);

View File

@@ -142,7 +142,7 @@ void LeaveStructLevel (void);
SymEntry* FindSym (const char* Name);
/* Find the symbol with the given name */
/* Find with the given name the symbol visible in the current scope */
SymEntry* FindGlobalSym (const char* Name);
/* Find the symbol with the given name in the global symbol table only */
@@ -151,7 +151,7 @@ SymEntry* FindLocalSym (const char* Name);
/* Find the symbol with the given name in the current symbol table only */
SymEntry* FindTagSym (const char* Name);
/* Find the symbol with the given name in the tag table */
/* Find with the given name the tag symbol visible in the current scope */
SymEntry FindStructField (const Type* TypeArray, const char* Name);
/* Find a struct/union field in the fields list.