Skip to content

Commit

Permalink
Do not mark anonymous symbols as fields (#566)
Browse files Browse the repository at this point in the history
  • Loading branch information
marcauberer authored May 25, 2024
1 parent ccb3d9d commit 7024379
Show file tree
Hide file tree
Showing 10 changed files with 32 additions and 25 deletions.
16 changes: 8 additions & 8 deletions src/SourceFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,6 @@
#include <string>
#include <utility>

// Ignore some warnings in ANTLR generated code
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Woverloaded-virtual"
#include <SpiceLexer.h>
#include <SpiceParser.h>
#include <Token.h>
#pragma GCC diagnostic pop

#include <ast/ASTNodes.h>
#include <exception/AntlrThrowingErrorListener.h>
#include <global/RuntimeModuleManager.h>
Expand All @@ -26,6 +18,14 @@
#include "../lib/thread-pool/thread-pool-utils.hpp"
#include "../lib/thread-pool/thread-pool.hpp"

// Ignore some warnings in ANTLR generated code
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Woverloaded-virtual"
#include <SpiceLexer.h>
#include <SpiceParser.h>
#include <Token.h>
#pragma GCC diagnostic pop

namespace spice::compiler {

// Forward declarations
Expand Down
2 changes: 1 addition & 1 deletion src/symboltablebuilder/Lifecycle.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ enum LifecycleState : uint8_t {
*/
struct LifecycleEvent {
LifecycleState state;
ASTNode *issuer;
const ASTNode *issuer;
};

/**
Expand Down
2 changes: 2 additions & 0 deletions src/symboltablebuilder/Scope.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,8 @@ size_t Scope::getFieldCount() const {
assert(type == ScopeType::STRUCT);
size_t fieldCount = 0;
for (const auto &symbol : symbolTable.symbols) {
if (symbol.second.anonymous)
continue;
const QualType &symbolType = symbol.second.getQualType();
if (symbolType.is(TY_IMPORT))
continue;
Expand Down
18 changes: 10 additions & 8 deletions src/symboltablebuilder/SymbolTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@ namespace spice::compiler {
* @param declNode AST node where the symbol is declared
* @return Inserted entry
*/
SymbolTableEntry *SymbolTable::insert(const std::string &name, ASTNode *declNode) {
bool isGlobal = parent == nullptr;
size_t orderIndex = symbols.size();
SymbolTableEntry *SymbolTable::insert(const std::string &name, ASTNode *declNode, bool isAnonymousSymbol) {
const bool isGlobal = parent == nullptr;
size_t orderIndex = SIZE_MAX;
if (!isAnonymousSymbol)
orderIndex = std::ranges::count_if(symbols, [](const auto &entry) { return !entry.second.anonymous; });
// Insert into symbols map. The type is 'dyn', because concrete types are determined by the type checker later on
symbols.insert({name, SymbolTableEntry(name, QualType(TY_INVALID), scope, declNode, orderIndex, isGlobal)});
// Set entry to declared
Expand All @@ -40,11 +42,11 @@ SymbolTableEntry *SymbolTable::insert(const std::string &name, ASTNode *declNode
* Insert a new anonymous symbol into the current symbol table.
* The anonymous symbol will be identified via the definition code location
*
* @param type Type of the symbol
* @param qualType Type of the symbol
* @param declNode AST node where the anonymous symbol is declared
* @return Inserted entry
*/
SymbolTableEntry *SymbolTable::insertAnonymous(const QualType &type, ASTNode *declNode, size_t numericSuffix) {
SymbolTableEntry *SymbolTable::insertAnonymous(const QualType &qualType, ASTNode *declNode, size_t numericSuffix) {
// Check if the anonymous entry already exists
if (SymbolTableEntry *anonSymbol = lookupAnonymous(declNode->codeLoc, numericSuffix))
return anonSymbol;
Expand All @@ -53,8 +55,8 @@ SymbolTableEntry *SymbolTable::insertAnonymous(const QualType &type, ASTNode *de
name << "anon." << declNode->codeLoc.toString();
if (numericSuffix > 0)
name << "." << std::to_string(numericSuffix);
SymbolTableEntry *anonSymbol = insert(name.str(), declNode);
anonSymbol->updateType(type, false);
SymbolTableEntry *anonSymbol = insert(name.str(), declNode, true);
anonSymbol->updateType(qualType, false);
anonSymbol->updateState(DECLARED, declNode);
anonSymbol->updateState(INITIALIZED, declNode);
anonSymbol->anonymous = true;
Expand All @@ -67,6 +69,7 @@ SymbolTableEntry *SymbolTable::insertAnonymous(const QualType &type, ASTNode *de
*
* @param originalName Original symbol name
* @param newName New symbol name
* @return Copied entry
*/
SymbolTableEntry *SymbolTable::copySymbol(const std::string &originalName, const std::string &newName) {
SymbolTableEntry *entryToCopy = lookupStrict(originalName);
Expand Down Expand Up @@ -106,7 +109,6 @@ SymbolTableEntry *SymbolTable::lookup(const std::string &name) { // NOLINT(misc-
captures.insert({name, Capture(entry)});
}
}

return entry;
}

Expand Down
6 changes: 3 additions & 3 deletions src/symboltablebuilder/SymbolTable.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class Type;
struct CodeLoc;

using CaptureMap = std::unordered_map<std::string /*name*/, Capture /*capture*/>;
using SymbolMap = std::unordered_map<std::string /*name*/, SymbolTableEntry /*symbol table entry*/>;
using SymbolMap = std::unordered_map<std::string /*name*/, SymbolTableEntry /*entry*/>;

/**
* Class for storing information about symbols of the program.
Expand All @@ -38,8 +38,8 @@ class SymbolTable {
friend class Scope;

// Public methods
SymbolTableEntry *insert(const std::string &name, ASTNode *declNode);
SymbolTableEntry *insertAnonymous(const QualType &type, ASTNode *declNode, size_t numericSuffix = 0);
SymbolTableEntry *insert(const std::string &name, ASTNode *declNode, bool isAnonymousSymbol = false);
SymbolTableEntry *insertAnonymous(const QualType &qualType, ASTNode *declNode, size_t numericSuffix = 0);
SymbolTableEntry *copySymbol(const std::string &originalName, const std::string &newName);
SymbolTableEntry *lookup(const std::string &symbolName);
SymbolTableEntry *lookupStrict(const std::string &symbolName);
Expand Down
6 changes: 4 additions & 2 deletions src/symboltablebuilder/SymbolTableEntry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ void SymbolTableEntry::updateType(const QualType &newType, [[maybe_unused]] bool
* @param node AST node where the update takes place
* @param force Force update. This can only be used compiler-internal
*/
void SymbolTableEntry::updateState(const LifecycleState &newState, ASTNode *node, bool force) {
void SymbolTableEntry::updateState(const LifecycleState &newState, const ASTNode *node, bool force) {
const LifecycleState oldState = lifecycle.getCurrentState();
// Check if this is a constant variable and is already initialized
if (newState != DEAD && oldState != DECLARED && qualType.isConst() && !force) // GCOV_EXCL_LINE
Expand Down Expand Up @@ -102,7 +102,9 @@ void SymbolTableEntry::popAddress() {
*
* @return Struct field or not
*/
bool SymbolTableEntry::isField() const { return scope->type == ScopeType::STRUCT && orderIndex < scope->getFieldCount(); }
bool SymbolTableEntry::isField() const {
return scope->type == ScopeType::STRUCT && orderIndex < scope->getFieldCount() && !anonymous;
}

/**
* Stringify the current symbol to a human-readable form. Used to dump whole symbol tables with their contents.
Expand Down
2 changes: 1 addition & 1 deletion src/symboltablebuilder/SymbolTableEntry.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class SymbolTableEntry {
// Public methods
[[nodiscard]] const QualType &getQualType() const;
void updateType(const QualType &newType, bool overwriteExistingType);
void updateState(const LifecycleState &newState, ASTNode *node, bool force = false);
void updateState(const LifecycleState &newState, const ASTNode *node, bool force = false);
[[nodiscard]] const CodeLoc &getDeclCodeLoc() const;
[[nodiscard]] virtual llvm::Value *getAddress() const;
void updateAddress(llvm::Value *address);
Expand Down
2 changes: 1 addition & 1 deletion src/typechecker/TypeChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1378,7 +1378,7 @@ std::any TypeChecker::visitPostfixUnaryExpr(PostfixUnaryExprNode *node) {
const QualType memberType = memberEntry->getQualType();

// Check for insufficient visibility
if (structScope->isImportedBy(rootScope) && !memberEntry->getQualType().isPublic())
if (structScope->isImportedBy(rootScope) && !memberEntry->getQualType().getBase().isPublic())
SOFT_ERROR_ER(node, INSUFFICIENT_VISIBILITY, "Cannot access field '" + fieldName + "' due to its private visibility")

// Set field to used
Expand Down
1 change: 1 addition & 0 deletions src/typechecker/TypeCheckerImplicit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ void TypeChecker::createDefaultCtorIfRequired(const Struct &spiceStruct, Scope *
bool hasFieldsToConstruct = false;
for (size_t i = 0; i < fieldCount; i++) {
SymbolTableEntry *fieldSymbol = structScope->symbolTable.lookupStrictByIndex(i);
assert(fieldSymbol != nullptr);
const QualType &thisType = fieldSymbol->getQualType();

// Abort if we have a field, that is a reference
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@
"isGlobal": false,
"isVolatile": false,
"name": "anon.L30C24",
"orderIndex": 1,
"orderIndex": 18446744073709551615,
"state": "initialized",
"type": "MockIterator<short>"
},
Expand Down

0 comments on commit 7024379

Please sign in to comment.