IDL compiler front-end library
Loading...
Searching...
No Matches
Builder.h
1// \file
2/*
3* Nirvana IDL front-end library.
4*
5* This is a part of the Nirvana project.
6*
7* Author: Igor Popov
8*
9* Copyright (c) 2021 Igor Popov.
10*
11* This program is free software; you can redistribute it and/or modify
12* it under the terms of the GNU Lesser General Public License as published by
13* the Free Software Foundation; either version 3 of the License, or
14* (at your option) any later version.
15*
16* This program is distributed in the hope that it will be useful,
17* but WITHOUT ANY WARRANTY; without even the implied warranty of
18* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19* GNU General Public License for more details.
20*
21* You should have received a copy of the GNU Lesser General Public
22* License along with this library. If not, see <http://www.gnu.org/licenses/>.
23*
24* Send comments and/or bug reports to:
25* popov.nirvana@gmail.com
26*/
27#ifndef IDLFE_AST_BUILDER_H_
28#define IDLFE_AST_BUILDER_H_
29#pragma once
30
31#include "../IDL_FrontEnd.h"
32#include "Root.h"
33#include "ValueType.h"
34#include "Parameter.h"
35#include "ScopedName.h"
36#include "Exception.h"
37#include "Declarators.h"
38#include "Variant.h"
39#include "../BE/MessageOut.h"
40#include <ostream>
41#include <stack>
42#include <unordered_map>
43#include <unordered_set>
44
45namespace AST {
46
47namespace Build {
48class Eval;
49class EvalEnum;
50}
51
52class OperationBase;
53class Attribute;
54class StructBase;
55class Union;
56class Module;
57
59class Builder : public BE::MessageOut
60{
61public:
63 const std::filesystem::path* file () const noexcept
64 {
65 return cur_file_;
66 }
67
70
75 bool is_main_file () const noexcept
76 {
77 return cur_file_ == &tree_->file ();
78 }
79
81 const std::string& prefix () const;
82
88 void type_prefix (const ScopedName& name, const Variant& s, const Location& id_loc);
89
95 void type_id (const ScopedName& name, const Variant& id, const Location& id_loc)
96 {
97 if (!id.empty ())
98 type_id (name, id.as_string (), id_loc);
99 }
100
105 void pragma_version (const ScopedName& name, const Version& ver, const Location& loc)
106 {
107 ItemWithId* rep_id = lookup_rep_id (name);
108 if (rep_id)
109 rep_id->pragma_version (*this, ver, loc);
110 }
111
113 const Item* cur_parent () const;
114
118 void native (const SimpleDeclarator& name);
119
124 void module_begin (const SimpleDeclarator& name);
125
128 {
129 assert (!scope_stack_.empty ());
130 assert (scope_stack_.back ()->kind () == Item::Kind::MODULE);
131 scope_end ();
132 }
133
139
145
149 void interface_bases (const ScopedNames& bases);
150
156 void operation_begin (bool oneway, Type&& type, const SimpleDeclarator& name);
157
163 void parameter (Parameter::Attribute att, Type&& type, const SimpleDeclarator& name);
164
168 void raises (const ScopedNames& names);
169
173 void operation_context (const Variants& strings);
174
177 {
178 operation_.clear ();
179 }
180
186 void attribute (bool readonly, Type&& type, const SimpleDeclarators& declarators);
187
193 void attribute_begin (bool readonly, Type&& type, const SimpleDeclarator& name);
194
198 void getraises (const ScopedNames& names);
199
203 void setraises (const ScopedNames& names);
204
207 {
208 attribute_.clear ();
209 }
210
213 {
214 iv_end (Item::Kind::INTERFACE);
215 }
216
221 void type_def (Type&& type, const Declarators& declarators);
222
226 void struct_decl (const SimpleDeclarator& name);
227
231 void struct_begin (const SimpleDeclarator& name);
232
236 {
237 return constr_type_end ();
238 }
239
244
247 {
248 constr_type_end ();
249 }
250
255 void member (Type&& type, const Declarators& names);
256
260 void union_decl (const SimpleDeclarator& name);
261
267 void union_begin (const SimpleDeclarator& name, const Type& switch_type, const Location& type_loc);
268
273 void union_label (const Variant& label, const Location& loc);
274
278 void union_default (const Location& loc);
279
284 void union_element (Type&& type, const Declarator& decl);
285
289
295 const NamedItem* enum_type (const SimpleDeclarator& name, const SimpleDeclarators& items);
296
301 void valuetype_decl (const SimpleDeclarator& name, bool is_abstract = false);
302
307 void valuetype_begin (const SimpleDeclarator& name, ValueType::Modifier mod = ValueType::Modifier::NONE);
308
313 void valuetype_bases (bool truncatable, const ScopedNames& bases);
314
318 void valuetype_supports (const ScopedNames& interfaces);
319
325 void state_member (bool is_public, Type&& type, const Declarators& names);
326
331
336 {
337 operation_end ();
338 }
339
342 {
343 iv_end (Item::Kind::VALUE_TYPE);
344 }
345
350 void valuetype_box (const SimpleDeclarator& name, Type&& type);
351
358 void constant (Type&& t, const SimpleDeclarator& name, Variant&& val, const Location& loc);
359
363 void constant (Type&& t, const SimpleDeclarator& name);
364
369 Type lookup_type (const ScopedName& scoped_name);
370
371 void see_prev_declaration (const Location& loc);
372 void see_declaration_of (const Location& loc, const std::string& name);
373
374 void check_anonymous (const Type& type, const SimpleDeclarator& name);
375
376 void validate_id (const Identifier& name, const Location& loc);
377
378protected:
379 Builder () = delete;
380 Builder (const Builder&) = delete;
381 Builder& operator = (const Builder&) = delete;
382
383 Builder (IDL_FrontEnd& compiler, const std::string& file);
384 ~Builder ();
385
386 static const int FILE_FLAG_START = 0x1;
387 static const int FILE_FLAG_SYSTEM = 0x2;
388 void linemarker (const std::string& name, const Location& loc, int flags);
389 void line (const std::string& filename);
390 void pragma (const char* s, const Location& loc);
391 Ptr <Root> finalize ();
392
393 void eval_push (const Type& t, const Location& loc);
394 void eval_pop ();
395 Build::Eval& eval () const;
396
397 unsigned positive_int (const Variant& v, const Location& loc);
398
399 Type fixed_pt_type (unsigned digits, unsigned scale, const Location& loc)
400 {
401 if (digits > 31 || scale > digits) {
402 message (loc, MessageType::ERROR, std::string ("fixed <") + std::to_string (digits) + ", " + std::to_string (scale) + "> type specification is invalid.");
403 return Type ();
404 } else
405 return Type::make_fixed (digits, scale);
406 }
407
408private:
409 friend class NamedItem;
410 friend class Build::Eval;
411 friend class Build::EvalEnum;
412
413 const NamedItem* lookup (const ScopedName& scoped_name);
414 bool prefix_valid (const std::string& pref, const Location& loc);
415 void prefix (const std::string& pref, const Location& loc);
416 bool get_quoted_string (const char*& s, std::string& qs, const Location& loc);
417 static bool get_scoped_name (const char*& s, ScopedName& name);
418 ItemWithId* lookup_rep_id (const ScopedName& name);
419 void type_id (const ScopedName& name, const std::string& id, const Location& id_loc);
420
421 Symbols* cur_scope () const;
422 Symbols* scope_begin ();
423 void scope_push (IV_Base* scope);
424 void scope_end ();
425 void iv_end (Item::Kind kind);
426
427 const NamedItem* constr_type_end ();
428
429 Raises lookup_exceptions (const ScopedNames& names);
430
431 std::pair <bool, const NamedItem*> lookup (const ItemScope& scope, const Identifier& name, const Location& loc);
432 std::pair <bool, const NamedItem*> lookup (const IV_Bases& containers, const Identifier& name, const Location& loc);
433
434 static const NamedItem* find (const Symbols& symbols, const Identifier& name)
435 {
436 return symbols.find (name);
437 }
438
439 void error_name_collision (const SimpleDeclarator& name, const Location& prev_loc);
440 void error_interface_kind (const SimpleDeclarator& name, InterfaceKind new_kind, InterfaceKind prev_kind, const Location& prev_loc);
441 void error_valuetype_mod (const SimpleDeclarator& name, bool is_abstract, const Location& prev_loc);
442
443 void add_base_members (const Location& loc, const IV_Bases& bases);
444 bool check_member_name (const NamedItem& item);
445
446 bool check_complete (const Type& type, const Location& loc);
447 bool check_complete_or_ref (const Type& type, const Location& loc);
448 bool check_complete_or_seq (const Type& type, const Location& loc);
449
450 typedef std::unordered_map <std::string, const NamedItem&> RepIdMap;
451 void check_rep_ids_unique (RepIdMap& ids, const Symbols& sym);
452 void check_unique (RepIdMap& ids, const ItemWithId& rid);
453
454 static bool is_base_of (const Interface& base, const Interface& derived);
455 static void collect_concrete_interfaces (const ValueType& vt, std::unordered_map <const Interface*, const ValueType*>& interfaces);
456
457 void check_complete (const Symbols& symbols);
458
459 static Type make_type (Type&& t, const Declarator& decl);
460
461 void check_pseudo (const SimpleDeclarator& name, InterfaceKind::Kind ik);
462
463protected:
464 IDL_FrontEnd& compiler_;
465 Ptr <Root> tree_;
466
467private:
468 typedef std::vector <ItemScope*> ScopeStack;
469 ScopeStack scope_stack_;
470 std::stack <Container*> container_stack_;
471 std::stack <std::unique_ptr <Build::Eval> > eval_stack_;
472
473 struct File
474 {
475 std::string file;
476 std::string prefix;
477
478 File (const std::string& f) :
479 file (f)
480 {}
481 };
482
483 std::vector <File> file_stack_;
484 const std::filesystem::path* cur_file_;
485
486 // Current interface data. Also used for value types.
487 struct InterfaceData
488 {
489 Symbols all_members;
490 std::unordered_set <const Item*> all_bases;
491
492 void clear ()
493 {
494 all_members.clear ();
495 all_bases.clear ();
496 }
497
498 }
499 interface_;
500
501 // Current operation data
502 struct OperationData
503 {
504 OperationBase* op;
505 Symbols params;
506
507 OperationData () :
508 op (nullptr)
509 {}
510
511 void clear ()
512 {
513 op = nullptr;
514 params.clear ();
515 }
516 }
517 operation_;
518
519 // Current attribute data
520 struct AttributeData
521 {
522 Attribute* att;
523
524 AttributeData () noexcept :
525 att (nullptr)
526 {}
527
528 void clear () noexcept
529 {
530 att = nullptr;
531 }
532 }
533 attribute_;
534
535 // Constructed type: struct, exception, union
536 struct ConstrType
537 {
538 const Ptr <NamedItem>* symbol;
539 Symbols members;
540
541 ConstrType () noexcept :
542 symbol (nullptr)
543 {}
544
545 void clear () noexcept
546 {
547 symbol = nullptr;
548 members.clear ();
549 }
550
551 NamedItem* obj () noexcept
552 {
553 return symbol ? *symbol : nullptr;
554 }
555 }
556 constr_type_;
557
558 // Current union data
559 struct UnionData
560 {
561 std::unordered_map <Variant::Key, Location> all_labels;
562 bool has_default;
563 Location default_loc;
564
565 UnionData () :
566 has_default (false)
567 {}
568
569 void clear () noexcept
570 {
571 all_labels.clear ();
572 has_default = false;
573 }
574
575 struct ElementData
576 {
577 bool is_default;
578 std::vector <Variant> labels;
579
580 ElementData () :
581 is_default (false)
582 {}
583
584 void clear ()
585 {
586 is_default = false;
587 labels.clear ();
588 }
589 }
590 element;
591 }
592 union_;
593};
594
595}
596
597#endif
The AST builder.
Definition Builder.h:60
void exception_begin(const SimpleDeclarator &name)
Begin of the exception definition.
void valuetype_factory_end()
End valuetype factory.
Definition Builder.h:335
void attribute_begin(bool readonly, Type &&type, const SimpleDeclarator &name)
Begin attribute definition for the current interface or valuetype.
void union_label(const Variant &label, const Location &loc)
Create label for the current union.
void valuetype_supports(const ScopedNames &interfaces)
Set current valuetype supported interfaces.
void getraises(const ScopedNames &names)
Set getraises for the current attribute.
void interface_begin(const SimpleDeclarator &name, InterfaceKind ik=InterfaceKind())
Begin interface definition.
void struct_begin(const SimpleDeclarator &name)
Begin of the structure definition.
void interface_bases(const ScopedNames &bases)
Set current interface bases.
void struct_decl(const SimpleDeclarator &name)
Create structure forward declaration.
void module_begin(const SimpleDeclarator &name)
Begin module.
void type_id(const ScopedName &name, const Variant &id, const Location &id_loc)
Set repository id for item. See the typeid IDL keyword.
Definition Builder.h:95
void exception_end()
End of the exception definition.
Definition Builder.h:246
const std::filesystem::path * file() const noexcept
Currently parsed IDL file path.
Definition Builder.h:63
void union_default(const Location &loc)
Create default label for the current union.
const std::string & prefix() const
void union_decl(const SimpleDeclarator &name)
Create union forward declaration.
void constant(Type &&t, const SimpleDeclarator &name)
Create interface constant definition (Nirvana extension).
void state_member(bool is_public, Type &&type, const Declarators &names)
Add members to the current valuetype.
void setraises(const ScopedNames &names)
Set setraises for the current attribute.
void operation_end()
End of the operation definition.
Definition Builder.h:176
void parameter(Parameter::Attribute att, Type &&type, const SimpleDeclarator &name)
Add parameter to the current operation.
const NamedItem * enum_type(const SimpleDeclarator &name, const SimpleDeclarators &items)
Create enum type.
void type_def(Type &&type, const Declarators &declarators)
Create type alias.
Location location() const
const NamedItem * struct_end()
End of the structure definition.
Definition Builder.h:235
void raises(const ScopedNames &names)
Set raises for the current operation.
void valuetype_bases(bool truncatable, const ScopedNames &bases)
Set current valuetype bases.
void valuetype_end()
End of the valuetype definition.
Definition Builder.h:341
void member(Type &&type, const Declarators &names)
Add members to the current structure or exception.
void union_begin(const SimpleDeclarator &name, const Type &switch_type, const Location &type_loc)
Begin of the union definition.
void attribute_end()
End of the attribute definition.
Definition Builder.h:206
void native(const SimpleDeclarator &name)
Create native type.
void module_end()
End module.
Definition Builder.h:127
void valuetype_box(const SimpleDeclarator &name, Type &&type)
Create value box definition.
void valuetype_factory_begin(const SimpleDeclarator &name)
Begin valuetype factory.
bool is_main_file() const noexcept
Test if currently parsed file is main.
Definition Builder.h:75
const NamedItem * union_end()
End of the union definition.
void valuetype_decl(const SimpleDeclarator &name, bool is_abstract=false)
Create valuetype forward declaration.
void pragma_version(const ScopedName &name, const Version &ver, const Location &loc)
Set repository id version for item. See #pragma version.
Definition Builder.h:105
void operation_context(const Variants &strings)
Set context for the current operation.
void interface_decl(const SimpleDeclarator &name, InterfaceKind ik=InterfaceKind())
Create interface forward declaration.
void operation_begin(bool oneway, Type &&type, const SimpleDeclarator &name)
Begin operation definition for the current interface or valuetype.
Type lookup_type(const ScopedName &scoped_name)
Find type by name.
void type_prefix(const ScopedName &name, const Variant &s, const Location &id_loc)
Set repository id prefix for item. See the typeprefix IDL keyword.
void attribute(bool readonly, Type &&type, const SimpleDeclarators &declarators)
Add attributes to the current interface or valuetype.
void valuetype_begin(const SimpleDeclarator &name, ValueType::Modifier mod=ValueType::Modifier::NONE)
Begin valuetype definition.
void constant(Type &&t, const SimpleDeclarator &name, Variant &&val, const Location &loc)
Create constant definition.
void union_element(Type &&type, const Declarator &decl)
Create union element for the current label.
void interface_end()
End of the interface definition.
Definition Builder.h:212
const Item * cur_parent() const
The IDL declarator.
Definition Declarators.h:80
An identifier.
Definition Identifier.h:37
The kind of interface.
Definition Interface.h:40
Kind
The kind of interface.
Definition Interface.h:44
An AST item.
Definition Item.h:41
Kind
The kind of item.
Definition Item.h:45
@ MODULE
class Module
@ VALUE_TYPE
class ValueType
@ INTERFACE
class Interface
Items which have repository identifiers derive from this class.
Definition ItemWithId.h:42
Stores the location information.
Definition Location.h:43
A named AST item.
Definition NamedItem.h:45
Attribute
Parameter attribute: in, out, inout.
Definition Parameter.h:45
The IDL simple declarator.
Definition Declarators.h:41
An IDL type.
Definition Type.h:47
Modifier
Value type modifier.
Definition ValueType.h:65
Stores the constant value.
Definition Variant.h:42
Compiler messages output.
Definition MessageOut.h:42
void message(const AST::Location &l, MessageType mt, const std::string &msg)
IDL front-end.
Abstract Syntax Tree namespace.
Definition Array.h:34
std::forward_list< SimpleDeclarator > SimpleDeclarators
The IDL simple declarators.
Definition Declarators.h:72
std::forward_list< Declarator > Declarators
The IDL declarators.
std::forward_list< ScopedName > ScopedNames
Sequence of scoped names.
Definition ScopedName.h:115
std::vector< const ItemWithId * > Raises
Definition Exception.h:55
A scoped name: sequence of identifiers.
Definition ScopedName.h:42