1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
|
/* $Id$
* NameLookup: Knows about VHDL names and how/where to look these up in the
* symboltable (i.e. it can e.g. switch the scope for prefixed names etc.)
*
* Copyright (C) 2008-2009 FAUmachine Team <info@faumachine.org>.
* This program is free software. You can redistribute it and/or modify it
* under the terms of the GNU General Public License, either version 2 of
* the License, or (at your option) any later version. See COPYING.
*/
#ifndef __NAME_LOOKUP_HPP_INCLUDED
#define __NAME_LOOKUP_HPP_INCLUDED
#include <list>
#include "frontend/misc/SymbolTable.hpp"
#include "frontend/ast/SimpleName.hpp"
#include "frontend/ast/Callable.hpp"
#include "frontend/ast/NodeFactory.hpp"
#include "frontend/reporting/CompileError.hpp"
namespace ast {
//! Glue class for SymbolTable while parsing.
/** This class is a glue class between SymbolTable and the ParserDriver
* used only for parsing.
*/
class NameLookup {
public:
//! c'tor
/** @param symtab SymbolTable instance.
*/
NameLookup(SymbolTable &symtab);
//! open the region associated with the symbol corresponding to name
/** wrapper for symbol table to open the region associated with
* the symbol name. Will report an error if the symbol doesn't have
* an associated DeclarativeRegion. Will also report an error if the
* name is not a SimpleName.
*
* @param name (Simple)Name with an associated Region.
*/
void openRegion(Name *name) /* throw(CompileError) */;
//! shift the current lookup scope
/** Shift the current lookup scope to the scope defined by prefix.
* This is used to correctly look up the suffices of prefixed names.
* This will only effect the very next symbol lookup via lookup.
* @param prefix which refers to the current scope.
* @param isFunction denotes the prefix a function name?
*/
void
shiftScope(Name &prefix, bool isFunction);
//! shift the current lookup scope to denote an attribute prefix.
/** This function shifts the lookup scope to denote an attribute
* prefix. The following lookups will return attribute names.
* Reset with unshiftScope.
*/
void shiftAttributeScope(void);
//! find or register the callable spec.
/** Resolve the parameter (type) list of spec and look if there
* is a conforming subprogram specification registered in the
* SymbolTable already. If so, open its region, delete spec and
* return the specification. If not, register spec and open its
* region, and register the parameters.
*
* @param spec subprogram specification.
* @return either the conformin specification or spec.
*/
Callable* findOrRegisterSubprog(Callable *spec);
//! lookup the identifier id in the symbol table.
/** @param id identifier to lookup.
* @return list of candidate symbols (might be empty if not
* found).
*/
std::list<Symbol*> lookup(std::string &id) const;
//! force to reset any scope lookups for expanded/selected names.
/** Force undo any effect of shiftScope.
*/
void unshiftScope(void);
//! generate either a selected or an expanded name
/** @param prefix prefix of the selected or expanded name
* @param suffix suffix of the selected or expanded name
* @param candidates candidate symbols of the suffix
* @param loc location of the suffix.
* @return corresponding expanded or selected name
*/
Name* makeSelectedName(
Expression *prefix,
std::string *suffix,
std::list<Symbol*> candidates,
Location loc) const;
//! register lib clauses in symboltable.
/** @param libs list of library clauses
*/
void registerLibClauses(const std::list<SimpleName*> &libs);
//! register use clauses in symboltable.
/** @param usecs list of use clauses.
*/
void registerUseClauses(const std::list<Name*> &usecs);
//! shift candidates by a subsription
/** Shift the candidates cands by a subscription and return all
* valid candidates. Also remove non-fitting candidates from
* cands.
*
* @param cands prefix candidates
* @param loc Location of the subscription (for error reporting only)
* @return all possible shifted candidates
*/
static std::list<Symbol*>
shiftSubscriptCands(std::list<Symbol*> &cands, Location loc);
//! shift scope for a selected name
/** shift scope for a selected name
*
* @param prefix prefix of the name.
*/
void shiftSelectedScope(Name &prefix);
/** is the current resolved symbol an expanded name?
*/
bool isExpanded;
private:
/** shift one candidate by a subscription.
* @param candidate prefix candidate
* @return shifted symbol or NULL if subscription is not possible.
*/
static Symbol*
shiftSubscriptCand(Symbol *candidate);
//! shift scope for one symbol of a selected name
/** shift scope for one candidate symbol of a selected name.
*
* @param prefixSym canidate symbol
*/
void shiftSelectedSym(Symbol *prefixSym);
//! shift current lookup scope to an expanded name.
/** @param sym symbol with a declarative region that gets
* interpreted as an expanded name.
*/
void shiftExpanded(const Symbol &sym);
//! symbol table instance.
SymbolTable &symbolTable;
/** list of possible scopes for which symbols should get looked up.
* For expanded names which are not overloadable, this is the scope
* of the expanded name prefix, for overloadable names it can
* be more than one scope. For normal identifiers, this list should
* be empty.
*/
std::list<DeclarativeRegion*> lookupScopes;
/** Check two subprogram specifications that are procedure
* specifications for conformance.
* @param a first subprogram specification
* @param b second subprogram specification
* @return true if both conform.
*/
static bool
conformProcSig(const Callable *a, const Callable *b);
/** Check two FunctionDeclarations for conformance.
* @param a first FunctionDeclaration
* @param b second FunctionDeclaration
* @return true if they conform, false otherwise.
*/
static bool
conformFuncSig(
const FunctionDeclaration *a,
const FunctionDeclaration *b);
/** check two ValDeclarations as part of subprogram specifications for
* conformance.
*
* @param a first ValDeclaration
* @param b second ValDeclaration
* @return true if they conform.
*/
static bool
conformParameter(const ValDeclaration *a, const ValDeclaration *b);
/** was the scope shifted, and should hence shifted lookups
* instead of regular symbol table lookups be performed?
*/
bool shiftedLookups;
};
}; /* namespace ast */
#endif /* __NAME_LOOKUP_HPP_INCLUDED */
|