coan  6.0.1
A C/C++ Configuration Analyzer
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
symbol.h
Go to the documentation of this file.
1 #ifndef symbol_H
2 #define symbol_H
3 #pragma once
4 /***************************************************************************
5  * Copyright (C) 2007-2013 Mike Kinghan, imk@burroingroingjoing.com *
6  * All rights reserved. *
7  * *
8  * Contributed originally by Mike Kinghan, imk@burroingroingjoing.com *
9  * *
10  * Redistribution and use in source and binary forms, with or without *
11  * modification, are permitted provided that the following conditions *
12  * are met: *
13  * *
14  * Redistributions of source code must retain the above copyright *
15  * notice, this list of conditions and the following disclaimer. *
16  * *
17  * Redistributions in binary form must reproduce the above copyright *
18  * notice, this list of conditions and the following disclaimer in the *
19  * documentation and/or other materials provided with the distribution. *
20  * *
21  * Neither the name of Mike Kinghan nor the names of its contributors *
22  * may be used to endorse or promote products derived from this software *
23  * without specific prior written permission. *
24  * *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
26  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT *
27  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS *
28  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE *
29  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, *
30  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, *
31  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS *
32  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED *
33  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,*
34  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF *
35  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
36  * DAMAGE. *
37  * *
38  **************************************************************************/
39 
40 #include "identifier.h"
41 #include "formal_parameter_list.h"
42 #include "line_type.h"
43 #include "parameter_substitution.h"
44 #include <string>
45 #include <set>
46 #include <map>
47 
48 
54 // Forward decl
55 struct reference;
56 
58 struct symbol
59 {
61  friend reference;
62 
64  enum class provenance {
68  global,
70  transient
71  };
72 
74  using symbol_table = std::map<std::string,symbol>;
76  using table_entry = symbol_table::value_type;
77 
79  struct locator
80  {
82  locator();
83 
85  explicit locator(symbol_table::iterator iter)
86  : _loc(iter) {}
87 
89  explicit locator(std::string const & id);
90 
95  locator(std::string const & id,
96  provenance source)
97  : _loc(insert(id,source)) {}
98 
109  template<class CharSeq>
110  explicit locator(chewer<CharSeq> & chew);
111 
113  bool operator==(locator other) const {
114  return _loc == other._loc;
115  }
116 
118  bool operator!=(locator & other) const {
119  return !operator==(other);
120  }
121 
123  bool null() const;
124 
126  explicit operator bool() const {
127  return !null();
128  }
129 
133  return _loc->second;
134  }
135  symbol const & operator*() const {
136  return _loc->second;
137  }
139 
143  return &_loc->second;
144  }
145  symbol const * operator->() const {
146  return &_loc->second;
147  }
149 
151  std::string const & id() const {
152  return _loc->first;
153  }
154 
155  private:
156 
158  symbol_table::iterator _loc;
159  };
160 
162  bool operator==(symbol const & other) const {
163  return id() == other.id();
164  }
165 
167  bool operator!=(symbol const & other) const {
168  return !operator==(other);
169  }
170 
172  std::string const & id() const {
173  return _loc.id();
174  }
175 
177  provenance origin() const {
178  return _provenance;
179  }
180 
184  }
185 
189  unsigned line() const {
190  return _line;
191  }
192 
194  std::shared_ptr<std::string const> defn() const {
195  return _defn;
196  }
197 
208  std::shared_ptr<parameter_substitution::format const> format() const {
209  return _format;
210  }
211 
213  bool defined() const {
214  return _defn.get();
215  }
216 
218  void set_definition(std::string const & defn);
219 
221  void set_parameters(formal_parameter_list const & params) {
222  _params = params;
223  if (_defn && !_defn->empty()) {
224  _format.reset(new parameter_substitution::format(*this));
225  } else {
226  _format.reset();
227  }
228  }
229 
231  void set_parameters(size_t n) {
233  }
234 
244  void define(std::string const & defn, formal_parameter_list const & params);
245 
249  }
250 
252  void undef();
253 
255  void report() const;
256 
258  bool configured() const {
259  return _provenance == provenance::global ||
261  }
262 
264  bool deselected() const {
265  return _deselected;
266  }
267 
274  bool invoked() const {
275  return _invoked;
276  }
277 
279  bool self_referential() const {
280  return _snapshot == int(pseudo_snapshot::infinite);
281  }
282 
287  bool dirty() const {
288  return !self_referential() && (!clean() || _snapshot < snapshot_max());
289  }
290 
292  bool clean() const {
293  return _snapshot > int(pseudo_snapshot::pristine);
294  }
295 
297  bool in_progress() const {
300  }
301 
306  std::string signature() const {
307  return id() + _params.str();
308  }
309 
312  return _params;
313  }
314 
316  size_t which_parameter(std::string const & str) const {
317  return _params.which(str);
318  }
319 
321  bool variadic() const {
322  return _params.variadic();
323  }
324 
339 
352  line_type
354  std::string const & definition);
355 
369 
381 
383  static size_t count(provenance source);
384 
386  static size_t count() {
387  return _sym_tab_.size() - 1;
388  }
389 
396  static locator lookup(std::string const & id) {
397  symbol_table::iterator result = table().find(id);
398  return result == table().end() ?
399  locator() : locator(result);
400  }
401 
419  template<class CharSeq>
420  static locator find_any_in(chewer<CharSeq> & chew, size_t & off);
421 
427  static void set_selection(char const *optarg);
428 
430  static void per_file_init();
431 
433  static void report_global_config();
434 
435 private:
436 
438  enum class pseudo_snapshot {
440  pristine = -1,
442  define_in_progress = -2,
444  undef_in_progress = -3,
446  infinite = -4
447 
448  };
449 
452  _snapshot = int(n);
453  }
454 
460  void report_premiere();
461 
463  void set_invoked(bool value = true) {
464  _invoked = value;
465  }
466 
471  void subscribe_to(locator other);
472 
476  bool subscribes_to(locator other) const;
477 
483  void subscribe();
484 
486  void unsubscribe();
487 
492  void make_clean() {
496  }
497  }
498 
504 
511  }
512 
518 
522  int snapshot_max() const;
523 
525  static bool selected(std::string const & id);
526 
530  static bool deselected(std::string const & id);
531 
542  static bool add_pattern(std::string const & pattern) {
543  return _selected_symbols_set_.insert(pattern).second;
544  }
545 
547  static bool
548  wildcard_match(std::string const & wildcard, std::string const & name);
549 
551  static symbol_table & table() {
552  return symbol::_sym_tab_;
553  }
554 
563  static symbol_table::iterator
565  std::string const & id,
566  provenance source,
567  symbol_table::iterator hint = table().end()) {
568  auto where =
569  table().insert(hint,table_entry(id,symbol(source)));
570  where->second._provenance = source;
571  where->second._loc = locator(where);
572  where->second._deselected = deselected(id);
573  return where;
574  }
575 
579  explicit symbol(provenance source)
580  : _provenance(source),
581  _line(0),
582  _deselected(false),
583  _invoked(false),
584  _snapshot(int(pseudo_snapshot::pristine)){}
585 
589  std::shared_ptr<std::string> _defn;
595  unsigned _line;
599  bool _invoked;
603  std::shared_ptr<parameter_substitution::format> _format;
608  mutable int _snapshot;
612  std::vector<symbol::locator> _contributors;
614  std::vector<symbol::locator> _subscribers;
618  std::vector<bool> _no_expand_pararms;
620  static int _current_snapshot_;
624  static std::set<std::string> _selected_symbols_set_;
629 };
630 
632 : _loc(symbol::table().begin()) {}
633 
634 inline symbol::locator::locator(std::string const & id)
635 : _loc(symbol::table().lower_bound(id)) {
636  if (_loc == symbol::table().end() || _loc->first != id) {
638  }
639 }
640 
641 template<class CharSeq>
643  std::string id = identifier::read(chew);
644  _loc = symbol::table().lower_bound(id);
645  if (_loc == symbol::table().end() || _loc->first != id) {
647  }
648 }
649 
650 inline bool symbol::locator::null() const {
651  return _loc == symbol::table().begin();
652 }
653 
654 #endif //EOF
symbol * operator->()
Point.
Definition: symbol.h:142
locator _loc
Locator of this symbol in the symbol table.
Definition: symbol.h:587
static int _last_global_snapshot_
The last snapshot number consumed by the global configuration.
Definition: symbol.h:622
std::string signature() const
Get the symbol's reference signature as string.
Definition: symbol.h:306
void undef()
Undefine thesymbol.
std::string str() const
Cast the parameter list to its canonical string representation.
void clear_parameters()
Remove any macro parameter list.
Definition: symbol.h:247
void subscribe_to(locator other)
Record the symbol's definition as referring to another another symbol, and recursively as referring t...
static bool add_pattern(std::string const &pattern)
Add a symbol name pattern for reporting.
Definition: symbol.h:542
locator(symbol_table::iterator iter)
Construct from a symbol table iterator.
Definition: symbol.h:85
static bool selected(std::string const &id)
Say whether a symbol name matches a selection pattern for reporting.
The symbol is globally configured by a commandline option.
std::shared_ptr< std::string const > defn() const
Get a pointer to the symbol's definition; null if undefined.
Definition: symbol.h:194
int _snapshot
Definition: symbol.h:608
bool invoked() const
Say whether the symbol has been invoked.
Definition: symbol.h:274
locator(std::string const &id, provenance source)
Construct given a name and a provenance.
Definition: symbol.h:95
struct symbol::locator encapsulates a symbol table entry.
Definition: symbol.h:79
bool in_progress() const
Say whether a determination the symbol's state is in progress.
Definition: symbol.h:297
bool null() const
Say whether this locator is null.
Definition: symbol.h:650
static locator find_any_in(chewer< CharSeq > &chew, size_t &off)
Search a terminal portion of a CharSeq for any known symbol name.
symbol & operator*()
Defeference.
Definition: symbol.h:132
symbol(provenance source)
Explicitly construct given a provenance.
Definition: symbol.h:579
bool operator!=(symbol const &other) const
Inequality.
Definition: symbol.h:167
void make_clean()
Assign the symbol state the current sequential snapshot number, signifying that it is up-to-date...
Definition: symbol.h:492
std::string const & id() const
Get the name of the symbol.
Definition: symbol.h:172
void set_definition(std::string const &defn)
Set the definition of the symbol.
void set_pseudo_snapshot(pseudo_snapshot n=pseudo_snapshot::pristine)
Prime the symbol with a pseudo snapshot.
Definition: symbol.h:451
bool configured() const
Say whether the symbol is configured.
Definition: symbol.h:258
static bool wildcard_match(std::string const &wildcard, std::string const &name)
Say whether a symbol name matches a *-terminated wildcard prefix.
static symbol_table _sym_tab_
The symbol table.
Definition: symbol.h:626
The symbol is not configured.
line_type digest_transient_define(formal_parameter_list const &params, std::string const &definition)
Analyse and handle an in-source define directive for this symbol.
struct parameter_substitution::format encapsulates a parameter substitution format.
formal_parameter_list _params
List of the symbol's macro arguments, if any.
Definition: symbol.h:591
static size_t count()
Get the number of symbols in the symbol table.
Definition: symbol.h:386
static void set_selection(char const *optarg)
void define(std::string const &defn, formal_parameter_list const &params)
Define symbol.
std::vector< symbol::locator > _contributors
Definition: symbol.h:612
static locator lookup(std::string const &id)
Lookup an identifier in the symbol table.
Definition: symbol.h:396
std::string const & id() const
Get the name of the symbol.
Definition: symbol.h:151
unsigned _line
Source line-number where symbol last defined or undefined, or 0.
Definition: symbol.h:595
bool variadic() const
Say whether this symbol is a variadic macro.
Definition: symbol.h:321
void set_invoked(bool value=true)
Mark the symbol as invoked, or not.
Definition: symbol.h:463
void make_dirty(pseudo_snapshot n=pseudo_snapshot::pristine)
Assign the symbol state a pseudo snapshot number, signifying that it is out of date, and recursively to all its subscribers.
std::vector< bool > _no_expand_pararms
Definition: symbol.h:618
static void report_global_config()
Report the global configuration, according to options.
static symbol_table & table()
Get a reference to the symbol table.
Definition: symbol.h:551
std::shared_ptr< parameter_substitution::format > _format
Definition: symbol.h:603
line_type digest_transient_undef()
Analyse and handle an in-source undef directive for this symbol.
provenance
Symbolic constants denoting the provenance of a symbol.
Definition: symbol.h:64
formal_parameter_list const & parameters() const
Get the symbol's formal parameter list.
Definition: symbol.h:311
std::string read(chewer< CharSeq > &chew)
Read an identifier from an chewer<CharSeq>
bool defined() const
Is the symbol defined.
Definition: symbol.h:213
bool operator==(symbol const &other) const
Equality.
Definition: symbol.h:162
static symbol_table::iterator insert(std::string const &id, provenance source, symbol_table::iterator hint=table().end())
Insert the symbol into the symbol table with a specified provenance.
Definition: symbol.h:564
void report() const
Report a reference to this symbol.
Symbol is in the process of being undefined.
chew_mode::name const name
An exemplar chew_mode::name
Definition: chew.h:229
static int _current_snapshot_
The current sequential snapshot number.
Definition: symbol.h:620
void report_premiere()
Report a symbol as resolved from the global configuration. The method invokes itself recursively on a...
provenance origin() const
Get the provenance of the symbol.
Definition: symbol.h:177
void diagnose_retrospective_redefinition() const
Diagnose the case in which defining or undefining the symbol retrospectively changes the expansion of...
bool subscribes_to(locator other) const
Say whether the symbol's definition refers to another another symbol, directly or indirectly...
static void per_file_init()
Delete all transient symbols from the symbol table.
static std::set< std::string > _selected_symbols_set_
The set of symbols selected for reporting, if any.
Definition: symbol.h:624
void subscribe()
Acquire all the symbol's contributors.
std::shared_ptr< parameter_substitution::format const > format() const
Get a pointer to the symbol's substitution format; null if none.
Definition: symbol.h:208
bool operator==(locator other) const
Equality.
Definition: symbol.h:113
The symbol is transiently configured by an in-source directive.
std::shared_ptr< std::string > _defn
Pointer to the symbol's definition, if any.
Definition: symbol.h:589
symbol_table::value_type table_entry
Type of entry in the symbol table.
Definition: symbol.h:76
void set_parameters(formal_parameter_list const &params)
Set a macro parameter list for the symbol.
Definition: symbol.h:221
`template struct chewer<CharSeq> is a cursor-like type that is associated with a character-sequence t...
Definition: chew.h:248
provenance _provenance
The provenance of the symbol.
Definition: symbol.h:593
void digest_global_define(chewer< std::string > &chew)
Analyse and handle a -D option for this symbol.
bool dirty() const
Say whether cached references of this symbol are out of date, due to configuration changes of this sy...
Definition: symbol.h:287
bool _deselected
Is the symbol deselected?
Definition: symbol.h:597
References of the symbol are by definition insoluble.
pseudo_snapshot
Pseudo snapshot numbers for symbols in indeterminate states.
Definition: symbol.h:438
std::map< std::string, symbol > symbol_table
Type of map implementing the symbol tbale.
Definition: symbol.h:74
static table_entry _null_
The table entry of the null symbol.
Definition: symbol.h:628
bool deselected() const
Say whether the symbol is deselected per the --select option.
Definition: symbol.h:264
friend reference
Friendship to struct reference
Definition: symbol.h:61
Symbol is in the process of being defined.
void set_parameters(size_t n)
Impute n parameters of the symbol.
Definition: symbol.h:231
bool variadic() const
Say whether the parameter_list_base is variadic.
line_type
Enumeration of types of input lines.
Definition: line_type.h:52
std::vector< symbol::locator > _subscribers
List of locators of the symbols to which this one contributes.
Definition: symbol.h:614
Symbol has merely be constructed.
struct symbol encapsulates a preprocessor symbol's state
Definition: symbol.h:58
bool operator!=(locator &other) const
Inequality.
Definition: symbol.h:118
void make_self_referential()
Assign the symbol state a pseudo snapshot number, signifying that its definition involves an infinite...
Definition: symbol.h:509
size_t which_parameter(std::string const &str) const
Say whether a string is a parameter of the symbol.
Definition: symbol.h:316
void originate(provenance origin)
Set the symbol's provenance.
Definition: symbol.h:182
symbol_table::iterator _loc
Locator of the symbol in the symbol table.
Definition: symbol.h:158
size_t which(std::string const &str) const
Get the index of the parameter that matches a string, if any, else -1.
bool self_referential() const
Say whether the symbol's definition is infinitely regressive.
Definition: symbol.h:279
struct formal_parameter_list encapsulates a list of formal macro parameters.
bool clean() const
Say whether the symbol's state has been determined.
Definition: symbol.h:292
char * optarg
Argument to an option parsed by getopt_long()
Definition: get_options.cpp:49
locator()
The default constructor locates the null symbol.
Definition: symbol.h:631
void unsubscribe()
Forget all the symbol's contributors.
void digest_global_undef(chewer< std::string > &chew)
Analyse and handle a -U option for this symbol.
bool _invoked
Has the symbol been invoked?
Definition: symbol.h:599
unsigned line() const
Get the source line-number at which this symbol was last defined or undefined.
Definition: symbol.h:189
int snapshot_max() const
Get the maximum sequential snapshot number in the the recursive closure of this symbol its contributo...