-
Notifications
You must be signed in to change notification settings - Fork 217
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[SymbolTable]: initial support for implicit declarations #746
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -161,6 +161,9 @@ static absl::Status DiagnoseMemberSymbolResolutionFailure( | |
context_name, ".")); | ||
} | ||
|
||
static const SymbolTableNode* LookupSymbolUpwards( | ||
const SymbolTableNode& context, absl::string_view symbol); | ||
|
||
class SymbolTable::Builder : public TreeContextVisitor { | ||
public: | ||
Builder(const VerilogSourceFile& source, SymbolTable* symbol_table, | ||
|
@@ -266,6 +269,9 @@ class SymbolTable::Builder : public TreeContextVisitor { | |
case NodeEnum::kEnumType: | ||
DescendEnumType(node); | ||
break; | ||
case NodeEnum::kLPValue: | ||
HandlePossibleImplicitDeclaration(node); | ||
break; | ||
default: | ||
Descend(node); | ||
break; | ||
|
@@ -521,6 +527,26 @@ class SymbolTable::Builder : public TreeContextVisitor { | |
} | ||
} | ||
|
||
void HandlePossibleImplicitDeclaration(const SyntaxTreeNode& node) { | ||
VLOG(2) << __FUNCTION__; | ||
|
||
// Only left-hand side of continuous assignment statements are allowed to | ||
// implicitly declare nets (LRM 6.10: Implicit declarations). | ||
if (Context().DirectParentsAre( | ||
{NodeEnum::kNetVariableAssignment, NodeEnum::kAssignmentList, | ||
NodeEnum::kContinuousAssignmentStatement})) { | ||
CHECK(node.MatchesTag(NodeEnum::kLPValue)); | ||
|
||
DeclarationTypeInfo decl_type_info; | ||
const ValueSaver<DeclarationTypeInfo*> save_type(&declaration_type_info_, | ||
&decl_type_info); | ||
declaration_type_info_->implicit = true; | ||
Descend(node); | ||
} else { | ||
Descend(node); | ||
} | ||
} | ||
|
||
void HandleIdentifier(const SyntaxTreeLeaf& leaf) { | ||
const absl::string_view text = leaf.get().text(); | ||
VLOG(2) << __FUNCTION__ << ": " << text; | ||
|
@@ -655,6 +681,29 @@ class SymbolTable::Builder : public TreeContextVisitor { | |
return; | ||
} | ||
|
||
// Handle possible implicit declarations here | ||
if (declaration_type_info_ != nullptr && declaration_type_info_->implicit) { | ||
const SymbolTableNode* resolved = | ||
LookupSymbolUpwards(*ABSL_DIE_IF_NULL(current_scope_), text); | ||
if (resolved == nullptr) { | ||
// No explicit declaration found, declare here | ||
SymbolTableNode& implicit_declaration = | ||
EmplaceTypedElementInCurrentScope( | ||
leaf, text, SymbolMetaType::kDataNetVariableInstance); | ||
|
||
const ReferenceComponent implicit_ref{ | ||
.identifier = text, | ||
.ref_type = InferReferenceType(), | ||
.required_metatype = InferMetaType(), | ||
// pre-resolve | ||
.resolved_symbol = &implicit_declaration, | ||
}; | ||
|
||
ref.PushReferenceComponent(implicit_ref); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this push needed? When a symbol is implicitly declared, do we ever need to build a hierarchical reference from it with the net/variable as a parent? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we do. Implicit declaration is also an reference to that symbol and we want to keep that reference. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, sounds good. |
||
return; | ||
} | ||
} | ||
|
||
// For all other cases, grow the reference chain deeper. | ||
// For type references, which may contained named parameters, | ||
// when encountering the first unqualified reference, establish its | ||
|
@@ -1770,6 +1819,10 @@ std::ostream& operator<<(std::ostream& stream, | |
stream << "(primitive)"; | ||
} | ||
|
||
if (decl_type_info.implicit) { | ||
stream << ", implicit"; | ||
} | ||
|
||
return stream << " }"; | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you like, you may move the below definition earlier in the file.