Merge pull request #2370 from acqn/VisibilityFix
[cc65] Fixed visibility of undeclared functions and objects
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user