aboutsummaryrefslogtreecommitdiff
path: root/odb/pragma.hxx
blob: ac643466e777bfc4011d31ebd1582a8ba1a913e6 (plain)
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
// file      : odb/pragma.hxx
// copyright : Copyright (c) 2009-2012 Code Synthesis Tools CC
// license   : GNU GPL v3; see accompanying LICENSE file

#ifndef ODB_PRAGMA_HXX
#define ODB_PRAGMA_HXX

#include <odb/gcc.hxx>

#include <map>
#include <set>
#include <vector>
#include <string>

#include <cutl/container/any.hxx>
#include <cutl/compiler/context.hxx>

struct pragma
{
  // Check that the pragma is applicable to the declaration. Return true
  // on success, complain and return false otherwise.
  //
  typedef bool (*check_func) (tree decl,
                              std::string const& decl_name,
                              std::string const& prag_name,
                              location_t);

  // Add the pragma value to the context.
  //
  typedef void (*add_func) (cutl::compiler::context&,
                            std::string const& key,
                            cutl::container::any const& value,
                            location_t);

  pragma (std::string const& pn,
          std::string const& cn,
          cutl::container::any const& v,
          location_t l,
          check_func c,
          add_func a)
    : pragma_name (pn),
      context_name (cn),
      value (v),
      loc (l),
      check (c),
      add (a)
  {
  }

  bool
  operator< (pragma const& y) const
  {
    if (add == 0)
      return context_name < y.context_name;
    else
      return context_name < y.context_name ||
        (context_name == y.context_name && loc < y.loc);
  }

  std::string pragma_name;  // Actual pragma name for diagnostics.
  std::string context_name; // Context entry name.
  cutl::container::any value;
  location_t loc;
  check_func check;
  add_func add;
};

typedef std::vector<pragma> pragma_list;

// A set of pragmas. Insertion of a pragma with the same name and no
// custom add function overrides the old value.
//
struct pragma_set: std::set<pragma>
{
  typedef std::set<pragma> base;

  pragma&
  insert (pragma const& p)
  {
    std::pair<iterator, bool> r (base::insert (p));

    pragma& x (const_cast<pragma&> (*r.first));

    if (!r.second)
      x = p;

    return x;
  }

  template <typename I>
  void
  insert (I begin, I end)
  {
    for (; begin != end; ++begin)
      insert (*begin);
  }
};


// Position pragmas inside a class or namespace. The key for the
// namespace case is the global_namespace node.
//
typedef std::map<tree, pragma_list> loc_pragmas;
extern loc_pragmas loc_pragmas_;

// Position pragmas for namespaces. Because re-opened namespaces do
// not have any representation in the GCC tree, these are handled in
// a special way. They are stored as a list of pragmas and their outer
// namespaces.
//
struct ns_loc_pragma
{
  typedef ::pragma pragma_type;
  ns_loc_pragma (tree n, pragma_type const& p): ns (n), pragma (p) {}

  tree ns;
  pragma_type pragma;
};

typedef std::vector<ns_loc_pragma> ns_loc_pragmas;
extern ns_loc_pragmas ns_loc_pragmas_;

// Pragmas associated with this declaration.
//
typedef std::map<tree, pragma_set> decl_pragmas;
extern decl_pragmas decl_pragmas_;

// List of pragma names (in context name form) that disqualify a value
// type from being treated as composite (i.e., simple value pragmas).
//
typedef std::set<std::string> pragma_name_set;
extern pragma_name_set simple_value_pragmas_;

extern "C" void
register_odb_pragmas (void*, void*);

struct pragmas_failed {};

void
post_process_pragmas ();

#endif // ODB_PRAGMA_HXX