llvm/flang/lib/semantics/attr.h
Tim Keith a3de9d789c [flang] Partial implementation of Symbols and Scopes.
A Symbol consists of a common part (in class Symbol) containing name,
owner, attributes. Information for a specific kind of symbol is in a
variant containing one of the *Details classes. So the kind of symbol is
determined by the type of details class stored in the details_ variant.

For scopes there is a single Scope class with an enum indicating the
kind. So far there isn't a need for extra kind-specific details as with
Symbols but that could change. Symbols defined in a Scope are stored
there in a simple map.

resolve-names.cc is a partial implementation of a parse-tree walker that
resolves names to Symbols. Currently is only handles functions (which
introduce a new Scope) and entity-decls. The test-type executable was
reused as a driver for this to avoid the need for a new one.

Sample output is below. When each "end function" is encountered the
scope is dumped, which shows the symbols defined in it.

$ cat a.f90
pure integer(8) function foo(arg1, arg2) result(res)
  integer :: arg1
  real :: arg2
contains
  function bar(arg1)
    real :: bar
    real :: arg1
  end function
end function

$ Debug/tools/f18/test-type a.f90
Subprogram scope: 0 children
  arg1:  Entity type: REAL
  bar:  Entity type: REAL
Subprogram scope: 1 children
  arg1:  Entity type: INTEGER
  arg2:  Entity type: REAL
  bar:  Subprogram (arg1)
  foo:  Subprogram (arg1, arg2) result(res)
  res:  Entity type: INTEGER(8)

Original-commit: flang-compiler/f18@1cd2fbc04d
Reviewed-on: https://github.com/flang-compiler/f18/pull/30
Tree-same-pre-rewrite: false
2018-03-22 17:25:34 -07:00

70 lines
1.3 KiB
C++

#ifndef FORTRAN_ATTR_H_
#define FORTRAN_ATTR_H_
#include <cinttypes>
#include <iostream>
#include <string>
namespace Fortran {
namespace semantics {
// All available attributes.
enum class Attr {
ABSTRACT,
ALLOCATABLE,
ASYNCHRONOUS,
BIND_C,
CONTIGUOUS,
DEFERRED,
ELEMENTAL,
EXTERNAL,
IMPURE,
INTENT_IN,
INTENT_OUT,
INTRINSIC,
MODULE,
NON_OVERRIDABLE,
NON_RECURSIVE,
NOPASS,
OPTIONAL,
PARAMETER,
PASS,
POINTER,
PRIVATE,
PROTECTED,
PUBLIC,
PURE,
RECURSIVE,
SAVE,
TARGET,
VALUE,
VOLATILE,
};
// Set of attributes
class Attrs {
public:
static const Attrs EMPTY;
Attrs() : bits_{0} {}
Attrs(std::initializer_list<Attr> attrs);
bool empty() const { return bits_ == 0; }
Attrs &Set(Attr attr);
Attrs &Add(const Attrs &attrs);
bool Has(Attr attr) const;
bool HasAny(const Attrs &attrs) const;
bool HasAll(const Attrs &attrs) const;
// Internal error if any of these attributes are not in allowed.
void CheckValid(const Attrs &allowed) const;
private:
std::uint64_t bits_;
friend std::ostream &operator<<(std::ostream &, const Attrs &);
};
std::ostream &operator<<(std::ostream &o, Attr attr);
std::ostream &operator<<(std::ostream &o, const Attrs &attrs);
} // namespace semantics
} // namespace Fortran
#endif