Files
carbon-lang/executable_semantics/ast/static_scope.h
T
Geoff RomerandJon Meow 17e0a1afb9 Implement static name resolution (#958)
This doesn't actually use the results of name resolution, but it does verify that they are present.
Also ensures that name resolution and type checking are applied to deduced function parameters and the implicit call to `Main()`.

Co-authored-by: Jon Meow <46229924+jonmeow@users.noreply.github.com>
2021-11-30 13:33:54 -08:00

69 lines
2.3 KiB
C++

// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#ifndef EXECUTABLE_SEMANTICS_AST_STATIC_SCOPE_H_
#define EXECUTABLE_SEMANTICS_AST_STATIC_SCOPE_H_
#include <string>
#include <unordered_map>
#include <variant>
#include <vector>
#include "executable_semantics/ast/ast_node.h"
#include "executable_semantics/ast/source_location.h"
#include "executable_semantics/common/nonnull.h"
namespace Carbon {
class NamedEntity : public virtual AstNode {
public:
virtual ~NamedEntity() = 0;
NamedEntity() = default;
// TODO: This is unused, but is intended for casts after lookup.
auto kind() const -> NamedEntityKind {
return static_cast<NamedEntityKind>(root_kind());
}
};
// Maps the names visible in a given scope to the entities they name.
// A scope may have parent scopes, whose names will also be visible in the
// child scope.
class StaticScope {
public:
// Defines `name` to be `entity` in this scope, or reports a compilation error
// if `name` is already defined in this scope.
void Add(std::string name, Nonnull<const NamedEntity*> entity);
// Make `parent` a parent of this scope.
// REQUIRES: `parent` is not already a parent of this scope.
void AddParent(Nonnull<StaticScope*> parent) {
parent_scopes_.push_back(parent);
}
// Returns the nearest definition of `name` in the ancestor graph of this
// scope, or reports a compilation error at `source_loc` there isn't exactly
// one such definition.
auto Resolve(const std::string& name, SourceLocation source_loc) const
-> Nonnull<const NamedEntity*>;
private:
// Equivalent to Resolve, but returns `nullopt` instead of raising an error
// if no definition can be found. Still raises a compilation error if more
// than one definition is found.
auto TryResolve(const std::string& name, SourceLocation source_loc) const
-> std::optional<Nonnull<const NamedEntity*>>;
// Maps locally declared names to their entities.
std::unordered_map<std::string, Nonnull<const NamedEntity*>> declared_names_;
// A list of scopes used for name lookup within this scope.
std::vector<Nonnull<StaticScope*>> parent_scopes_;
};
} // namespace Carbon
#endif // EXECUTABLE_SEMANTICS_AST_STATIC_SCOPE_H_