diff --git a/PWire.cc b/PWire.cc index d9a9899c6..dbe68afcb 100644 --- a/PWire.cc +++ b/PWire.cc @@ -33,7 +33,7 @@ PWire::PWire(perm_string n, : name_(n), type_(t), port_type_(pt), data_type_(dt), signed_(false), port_set_(false), net_set_(false), is_scalar_(false), - error_cnt_(0), set_data_type_(0), discipline_(0) + error_cnt_(0), discipline_(0) { switch (rt) { case SR_PORT: @@ -195,8 +195,11 @@ void PWire::set_unpacked_idx(const list&ranges) void PWire::set_data_type(data_type_t*type) { - assert(set_data_type_ == 0 || set_data_type_ == type); - set_data_type_ = type; + if (set_data_type_.get() == type) + return; + + assert(!set_data_type_.get()); + set_data_type_.reset(type); } void PWire::set_discipline(ivl_discipline_t d) diff --git a/PWire.h b/PWire.h index e9565a2d5..1f92fac9e 100644 --- a/PWire.h +++ b/PWire.h @@ -123,7 +123,7 @@ class PWire : public PNamedItem { // This is the complex type of the wire. the data_type_ may // modify how this is interpreted. - data_type_t*set_data_type_; + std::unique_ptr set_data_type_; ivl_discipline_t discipline_; diff --git a/configure.ac b/configure.ac index 13585836c..7055f4f32 100644 --- a/configure.ac +++ b/configure.ac @@ -104,7 +104,7 @@ AS_IF( [test "x$with_m32" = xyes], []) CFLAGS="$CTARGETFLAGS $CFLAGS" -CXXFLAGS="$CTARGETFLAGS $CXXFLAGS" +CXXFLAGS="$CTARGETFLAGS $CXXFLAGS -std=c++11" LDFLAGS="$CTARGETFLAGS $LDFLAGS" # Check that we are using either the GNU compilers or the Sun compilers diff --git a/elab_scope.cc b/elab_scope.cc index e798d0c91..a03d4df75 100644 --- a/elab_scope.cc +++ b/elab_scope.cc @@ -444,7 +444,7 @@ static void blend_class_constructors(PClass*pclass) // If we do not have an explicit constructor chain, but there // is a parent class, then create an implicit chain. - if (chain_new==0 && pclass->type->base_type!=0) { + if (chain_new==0 && pclass->type->base_type) { chain_new = new PChainConstructor(pclass->type->base_args); chain_new->set_line(*pclass); } @@ -512,16 +512,6 @@ static void elaborate_scope_class(Design*des, NetScope*scope, PClass*pclass) netclass_t*use_class = new netclass_t(use_type->name, use_base_class); - // If this is a package we need to remember the elaborated type so that - // scoped type references work. Since there is only one instance for each - // package this works. For classes defined in modules there might be - // multiple instances though. Each module instance will have its own class - // type instance, so the same does not work there. - if (scope->type() == NetScope::PACKAGE) { - ivl_assert(*pclass, use_type->save_elaborated_type == 0); - use_type->save_elaborated_type = use_class; - } - NetScope*class_scope = new NetScope(scope, hname_t(pclass->pscope_name()), NetScope::CLASS, scope->unit()); class_scope->set_line(pclass); diff --git a/elab_sig.cc b/elab_sig.cc index f4e26c5bd..924fdb945 100644 --- a/elab_sig.cc +++ b/elab_sig.cc @@ -939,10 +939,10 @@ bool test_ranges_eeq(const vector&lef, const vector&rig) ivl_type_t PWire::elaborate_type(Design*des, NetScope*scope, const std::vector&packed_dimensions) const { - if (set_data_type_ && !dynamic_cast(set_data_type_)) { - ivl_type_t use_type = set_data_type_->elaborate_type(des, scope); + vector_type_t *vec_type = dynamic_cast(set_data_type_.get()); + if (set_data_type_ && !vec_type) { ivl_assert(*this, packed_dimensions.empty()); - return use_type; + return set_data_type_->elaborate_type(des, scope); } // Fallback method. Create vector type. @@ -1003,10 +1003,6 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const unsigned wid = 1; vectorpacked_dimensions; - NetScope *type_scope = scope; - if (set_data_type_ && !set_data_type_->name.nil()) - type_scope = type_scope->find_typedef_scope(des, set_data_type_); - des->errors += error_cnt_; if (port_set_ || net_set_) { @@ -1046,7 +1042,7 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const cerr << get_fileline() << ": PWire::elaborate_sig: " << "Evaluate ranges for net " << basename() << endl; } - dimensions_ok &= evaluate_ranges(des, type_scope, this, nlist, net_); + dimensions_ok &= evaluate_ranges(des, scope, this, nlist, net_); } assert(net_set_ || net_.empty()); @@ -1147,10 +1143,10 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const wtype = NetNet::WIRE; } - ivl_type_t type = elaborate_type(des, type_scope, packed_dimensions); + ivl_type_t type = elaborate_type(des, scope, packed_dimensions); // Create the type for the unpacked dimensions. If the // unpacked_dimensions are empty this will just return the base type. - type = elaborate_array_type(des, type_scope, *this, type, unpacked_); + type = elaborate_array_type(des, scope, *this, type, unpacked_); list unpacked_dimensions; // If this is an unpacked array extract the base type and unpacked diff --git a/elab_type.cc b/elab_type.cc index a6be08f69..9c8280c61 100644 --- a/elab_type.cc +++ b/elab_type.cc @@ -18,6 +18,7 @@ */ # include "PExpr.h" +# include "PScope.h" # include "pform_types.h" # include "netlist.h" # include "netclass.h" @@ -40,10 +41,7 @@ using namespace std; */ ivl_type_t data_type_t::elaborate_type(Design*des, NetScope*scope) { - // User-defined types must be elaborated in the context - // where they were defined. - if (!name.nil()) - scope = scope->find_typedef_scope(des, this); + scope = find_scope(des, scope); ivl_assert(*this, scope); Definitions*use_definitions = scope; @@ -57,6 +55,11 @@ ivl_type_t data_type_t::elaborate_type(Design*des, NetScope*scope) return tmp; } +NetScope *data_type_t::find_scope(Design *, NetScope *scope) const +{ + return scope; +} + ivl_type_t data_type_t::elaborate_type_raw(Design*des, NetScope*) const { cerr << get_fileline() << ": internal error: " @@ -112,8 +115,6 @@ ivl_type_t atom_type_t::elaborate_type_raw(Design*des, NetScope*) const ivl_type_t class_type_t::elaborate_type_raw(Design*des, NetScope*scope) const { - if (save_elaborated_type) - return save_elaborated_type; return scope->find_class(des, name); } @@ -366,3 +367,26 @@ ivl_type_t uarray_type_t::elaborate_type_raw(Design*des, NetScope*scope) const return elaborate_array_type(des, scope, *this, btype, *dims.get()); } + +ivl_type_t typeref_t::elaborate_type_raw(Design*des, NetScope*s) const +{ + if (!s) { + // Try to recover + return new netvector_t(IVL_VT_LOGIC); + } + + return type->elaborate_type(des, s); +} + +NetScope *typeref_t::find_scope(Design *des, NetScope *s) const +{ + // If a scope has been specified use that as a starting point for the + // search + if (scope) + s = des->find_package(scope->pscope_name()); + + if (!type->name.nil()) + s = s->find_typedef_scope(des, type); + + return s; +} diff --git a/ivtest/ivltests/module_port_typedef_vector.v b/ivtest/ivltests/module_port_typedef_vector.v new file mode 100644 index 000000000..ca5d4592a --- /dev/null +++ b/ivtest/ivltests/module_port_typedef_vector.v @@ -0,0 +1,29 @@ +// Check that a packed array type identifier used for a module port is +// elaborated in the correct scope. + +localparam A = 2; + +typedef logic [A-1:0] T; + +module test ( + input T x +); + + localparam A = 5; + + bit failed = 1'b0; + + `define check(expr, val) \ + if (expr !== val) begin \ + $display("FAILED: %s, expected %0d, got %0d", `"expr`", val, expr); \ + failed = 1'b1; \ + end + + initial begin + `check($bits(x), 2); + if (!failed) begin + $display("PASSED"); + end + end + +endmodule diff --git a/ivtest/ivltests/sv_ps_type_cast1.v b/ivtest/ivltests/sv_ps_type_cast1.v new file mode 100644 index 000000000..305b05326 --- /dev/null +++ b/ivtest/ivltests/sv_ps_type_cast1.v @@ -0,0 +1,26 @@ +// Check that it is possible to reference a package scoped type identifier as +// the type in a type cast expression. + +bit failed = 1'b0; + +`define check(expr, val) \ + if (expr !== val) begin \ + $display("FAILED: %s, expected %0d, got %0d", `"expr`", val, expr); \ + failed = 1'b1; \ + end + +package P; + typedef integer T; +endpackage + +module test; + integer x; + initial begin + x = P::T'(-1024.123); + `check(x, -1024) + + if (!failed) begin + $display("PASSED"); + end + end +endmodule diff --git a/ivtest/ivltests/sv_ps_type_cast2.v b/ivtest/ivltests/sv_ps_type_cast2.v new file mode 100644 index 000000000..61ea62bb7 --- /dev/null +++ b/ivtest/ivltests/sv_ps_type_cast2.v @@ -0,0 +1,28 @@ +// Check that it is possible to reference a package scoped type identifier as +// the type in a type cast expression, even if there is a identifier of the same +// name in the local scope. + +bit failed = 1'b0; + +`define check(expr, val) \ + if (expr !== val) begin \ + $display("FAILED: %s, expected %0d, got %0d", `"expr`", val, expr); \ + failed = 1'b1; \ + end + +package P; + typedef integer T; +endpackage + +module test; + localparam T = 2; + integer x; + initial begin + x = P::T'(-1024.123); + `check(x, -1024) + + if (!failed) begin + $display("PASSED"); + end + end +endmodule diff --git a/ivtest/ivltests/sv_ps_type_class1.v b/ivtest/ivltests/sv_ps_type_class1.v new file mode 100644 index 000000000..4742a8c8e --- /dev/null +++ b/ivtest/ivltests/sv_ps_type_class1.v @@ -0,0 +1,39 @@ +// Check that class types declared in a package can be referenced using a scoped +// type identifier. + +bit failed = 1'b0; + +`define check(expr, val) \ + if (expr !== val) begin \ + $display("FAILED: %s, expected %0d, got %0d", `"expr`", val, expr); \ + failed = 1'b1; \ + end + +package P; + + localparam A = 8; + + class C; + logic [A-1:0] x; + + task t; + `check($bits(x), 8) + if (!failed) begin + $display("PASSED"); + end + endtask + endclass + +endpackage + +module test; + + localparam A = 4; + P::C c; + + initial begin + c = new; + c.t(); + end + +endmodule diff --git a/ivtest/ivltests/sv_ps_type_enum1.v b/ivtest/ivltests/sv_ps_type_enum1.v new file mode 100644 index 000000000..4745a218f --- /dev/null +++ b/ivtest/ivltests/sv_ps_type_enum1.v @@ -0,0 +1,38 @@ +// Check that enum types declared in a package can be referenced using a scoped +// type identifier. + +bit failed = 1'b0; + +`define check(expr, val) \ + if (expr !== val) begin \ + $display("FAILED: %s, expected %0d, got %0d", `"expr`", val, expr); \ + failed = 1'b1; \ + end + +package P; + + localparam X = 8; + + typedef enum logic [X-1:0] { + A, B = X + } T; + +endpackage + +module test; + localparam X = 4; + + typedef int T; + + P::T x = P::B; + + initial begin + `check(x, P::B) + `check(x, 8) + `check($bits(x), 8); + if (!failed) begin + $display("PASSED"); + end + end + +endmodule diff --git a/ivtest/ivltests/sv_ps_type_expr1.v b/ivtest/ivltests/sv_ps_type_expr1.v new file mode 100644 index 000000000..7ce97f2f7 --- /dev/null +++ b/ivtest/ivltests/sv_ps_type_expr1.v @@ -0,0 +1,24 @@ +// Check that it is possible to reference a package scoped type identifier in an +// expression. + +bit failed = 1'b0; + +`define check(expr, val) \ + if (expr !== val) begin \ + $display("FAILED: %s, expected %0d, got %0d", `"expr`", val, expr); \ + failed = 1'b1; \ + end + +package P; + typedef integer T; +endpackage + +module test; + initial begin + `check($bits(P::T), $bits(integer)) + + if (!failed) begin + $display("PASSED"); + end + end +endmodule diff --git a/ivtest/ivltests/sv_ps_type_expr2.v b/ivtest/ivltests/sv_ps_type_expr2.v new file mode 100644 index 000000000..30ca5b246 --- /dev/null +++ b/ivtest/ivltests/sv_ps_type_expr2.v @@ -0,0 +1,26 @@ +// Check that it is possible to reference a package scoped type identifier in an +// expression, even if there is a non type identifier of the same name in the +// current scope. + +bit failed = 1'b0; + +`define check(expr, val) \ + if (expr !== val) begin \ + $display("FAILED: %s, expected %0d, got %0d", `"expr`", val, expr); \ + failed = 1'b1; \ + end + +package P; + typedef integer T; +endpackage + +module test; + integer T; + initial begin + `check($bits(P::T), $bits(integer)) + + if (!failed) begin + $display("PASSED"); + end + end +endmodule diff --git a/ivtest/ivltests/sv_ps_type_struct1.v b/ivtest/ivltests/sv_ps_type_struct1.v new file mode 100644 index 000000000..3ec1b545d --- /dev/null +++ b/ivtest/ivltests/sv_ps_type_struct1.v @@ -0,0 +1,40 @@ +// Check that struct types declared in a package can be referenced using a +// scoped type identifier. + +bit failed = 1'b0; + +`define check(expr, val) \ + if (expr !== val) begin \ + $display("FAILED: %s, expected %0d, got %0d", `"expr`", val, expr); \ + failed = 1'b1; \ + end + +package P; + + localparam A = 8; + + typedef struct packed { + logic [A-1:0] x; + } T; + +endpackage + +typedef int T; + +module test; + localparam A = 4; + + typedef int T; + + P::T x; + + initial begin + x = 8'hff; + `check(x, 8'hff) + `check($bits(x), 8) + if (!failed) begin + $display("PASSED"); + end + end + +endmodule diff --git a/ivtest/ivltests/sv_typedef_chained.v b/ivtest/ivltests/sv_typedef_chained.v new file mode 100644 index 000000000..d62399cec --- /dev/null +++ b/ivtest/ivltests/sv_typedef_chained.v @@ -0,0 +1,51 @@ +// Check that chained type definitions declared in different scopes work +// correctly. + +package P1; + localparam A = 8; + typedef logic [A-1:0] T; +endpackage + +package P2; + localparam A = 4; + typedef P1::T T; +endpackage + +bit failed = 1'b0; + +`define check(expr, val) \ + if (expr !== val) begin \ + $display("FAILED: %s, expected %0d, got %0d", `"expr`", val, expr); \ + failed = 1'b1; \ + end + +module test; + localparam A = 2; + + typedef P2::T T; + + T x; + P1::T y; + P2::T z; + + initial begin + x = 8'hff; + y = 8'hff; + z = 8'hff; + + `check(x, 8'hff); + `check($bits(T), 8); + `check($bits(x), 8); + `check(y, 8'hff); + `check($bits(y), 8); + `check($bits(P1::T), 8); + `check(z, 8'hff); + `check($bits(z), 8); + `check($bits(P2::T), 8); + + if (!failed) begin + $display("PASSED"); + end + end + +endmodule diff --git a/ivtest/regress-sv.list b/ivtest/regress-sv.list index 83cf8df61..2ac65d99d 100644 --- a/ivtest/regress-sv.list +++ b/ivtest/regress-sv.list @@ -372,6 +372,7 @@ module_nonansi_struct_fail CE,-g2005-sv ivltests module_output_port_sv_var1 normal,-g2005-sv ivltests module_output_port_sv_var2 normal,-g2005-sv ivltests module_port_typedef_array1 normal,-g2005-sv ivltests +module_port_typedef_vector normal,-g2005-sv ivltests named_begin normal,-g2009 ivltests named_begin_fail CE,-g2009 ivltests named_fork normal,-g2009 ivltests @@ -634,6 +635,13 @@ sv_ps_function2 normal,-g2009 ivltests sv_ps_function3 normal,-g2009 ivltests sv_ps_function4 normal,-g2009 ivltests sv_ps_type1 normal,-g2009 ivltests +sv_ps_type_cast1 normal,-g2009 ivltests +sv_ps_type_cast2 normal,-g2009 ivltests +sv_ps_type_class1 normal,-g2009 ivltests +sv_ps_type_enum1 normal,-g2009 ivltests +sv_ps_type_expr1 normal,-g2009 ivltests +sv_ps_type_expr2 normal,-g2009 ivltests +sv_ps_type_struct1 normal,-g2009 ivltests sv_ps_var1 normal,-g2009 ivltests sv_queue1 normal,-g2009 ivltests sv_queue2 normal,-g2009 ivltests @@ -705,6 +713,7 @@ sv_typedef_array_base1 normal,-g2009 ivltests sv_typedef_array_base2 normal,-g2009 ivltests sv_typedef_array_base3 normal,-g2009 ivltests sv_typedef_array_base4 normal,-g2009 ivltests +sv_typedef_chained normal,-g2009 ivltests sv_typedef_darray_base1 normal,-g2009 ivltests sv_typedef_darray_base2 normal,-g2009 ivltests sv_typedef_darray_base3 normal,-g2009 ivltests diff --git a/ivtest/regress-vlog95.list b/ivtest/regress-vlog95.list index cde38066f..bec2bf336 100644 --- a/ivtest/regress-vlog95.list +++ b/ivtest/regress-vlog95.list @@ -438,6 +438,7 @@ sv_port_default6 CE,-g2009,-pallowsigned=1 ivltests sv_port_default7 CE,-g2009,-pallowsigned=1 ivltests sv_port_default8 CE,-g2009,-pallowsigned=1 ivltests sv_port_default9 CE,-g2009 ivltests +sv_ps_type_class1 CE,-g2009 ivltests sv_root_class CE,-g2009 ivltests sv_typedef_scope3 CE,-g2009 ivltests sv_unit2b CE,-g2009 ivltests diff --git a/net_func_eval.cc b/net_func_eval.cc index 58b7d629d..278e17299 100644 --- a/net_func_eval.cc +++ b/net_func_eval.cc @@ -23,10 +23,6 @@ # include # include "ivl_assert.h" -#if __cplusplus < 201103L -#define unique_ptr auto_ptr -#endif - using namespace std; /* diff --git a/parse.y b/parse.y index 16ba324d4..e27c35cd4 100644 --- a/parse.y +++ b/parse.y @@ -28,6 +28,7 @@ # include "pform.h" # include "Statement.h" # include "PSpec.h" +# include "PPackage.h" # include # include # include @@ -825,20 +826,9 @@ class_identifier the class name is detected by the lexor as a TYPE_IDENTIFIER if it does indeed match a name. */ class_declaration_endlabel_opt - : ':' TYPE_IDENTIFIER - { class_type_t*tmp = dynamic_cast ($2.type); - if (tmp == 0) { - yyerror(@2, "error: class declaration endlabel \"%s\" is not a class name\n", $2.text); - $$ = 0; - } else { - $$ = strdupnew(tmp->name.str()); - } - delete[]$2.text; - } - | ':' IDENTIFIER - { $$ = $2; } - | - { $$ = 0; } + : ':' TYPE_IDENTIFIER { $$ = $2.text; } + | ':' IDENTIFIER { $$ = $2; } + | { $$ = 0; } ; /* This rule implements [ extends class_type ] in the @@ -1179,12 +1169,14 @@ ps_type_identifier /* IEEE1800-2017: A.9.3 */ : TYPE_IDENTIFIER { pform_set_type_referenced(@1, $1.text); delete[]$1.text; - $$ = $1.type; + $$ = new typeref_t($1.type); + FILE_NAME($$, @1); } | package_scope TYPE_IDENTIFIER { lex_in_package_scope(0); - $$ = $2.type; - delete[]$2.text; + $$ = new typeref_t($2.type, $1); + FILE_NAME($$, @2); + delete[] $2.text; } ; diff --git a/pform_dump.cc b/pform_dump.cc index 4e1be9146..f6bc1c1b3 100644 --- a/pform_dump.cc +++ b/pform_dump.cc @@ -173,6 +173,15 @@ ostream& data_type_t::debug_dump(ostream&out) const return out; } +std::ostream& typeref_t::debug_dump(ostream&out) const +{ + if (scope) + out << scope->pscope_name() << "::"; + out << type->name; + + return out; +} + ostream& atom_type_t::debug_dump(ostream&out) const { if (signed_flag) diff --git a/pform_pclass.cc b/pform_pclass.cc index 5d0745b88..f1692ad4f 100644 --- a/pform_pclass.cc +++ b/pform_pclass.cc @@ -51,7 +51,7 @@ void pform_start_class_declaration(const struct vlltype&loc, pform_cur_class = class_scope; assert(type->base_type == 0); - type->base_type = base_type; + type->base_type.reset(base_type); assert(type->base_args.empty()); if (base_exprs) { diff --git a/pform_types.h b/pform_types.h index 557b2a268..2ef0585c6 100644 --- a/pform_types.h +++ b/pform_types.h @@ -33,10 +33,6 @@ # include # include -#if __cplusplus < 201103L -#define unique_ptr auto_ptr -#endif - /* * parse-form types. */ @@ -45,6 +41,7 @@ class Design; class NetScope; class Definitions; class PExpr; +class PScope; class PWire; class Statement; class netclass_t; @@ -165,6 +162,8 @@ class data_type_t : public PNamedItem { virtual SymbolType symbol_type() const; + virtual NetScope *find_scope(Design* des, NetScope *scope) const; + perm_string name; private: @@ -175,6 +174,19 @@ class data_type_t : public PNamedItem { std::map cache_type_elaborate_; }; +struct typeref_t : public data_type_t { + explicit typeref_t(data_type_t *t, PScope *s = 0) : scope(s), type(t) {} + + ivl_type_t elaborate_type_raw(Design*des, NetScope*scope) const; + NetScope *find_scope(Design* des, NetScope *scope) const; + + std::ostream& debug_dump(std::ostream&out) const; + +private: + PScope *scope; + data_type_t *type; +}; + struct void_type_t : public data_type_t { virtual void pform_dump(std::ostream&out, unsigned indent) const; }; @@ -193,7 +205,7 @@ struct enum_type_t : public data_type_t { SymbolType symbol_type() const; - data_type_t *base_type; + std::unique_ptr base_type; std::unique_ptr< std::list > names; }; @@ -270,7 +282,7 @@ struct array_base_t : public data_type_t { inline explicit array_base_t(data_type_t*btype, std::list*pd) : base_type(btype), dims(pd) { } - data_type_t*base_type; + std::unique_ptr base_type; std::unique_ptr< std::list > dims; }; @@ -323,8 +335,7 @@ struct string_type_t : public data_type_t { struct class_type_t : public data_type_t { - inline explicit class_type_t(perm_string n) - : base_type(0), save_elaborated_type(0) { name = n; } + inline explicit class_type_t(perm_string n) { name = n; } void pform_dump(std::ostream&out, unsigned indent) const; void pform_dump_init(std::ostream&out, unsigned indent) const; @@ -333,15 +344,17 @@ struct class_type_t : public data_type_t { // class that we are extending. This is nil if there is no // hierarchy. If there are arguments to the base class, then // put them in the base_args vector. - data_type_t*base_type; + std::unique_ptr base_type; std::listbase_args; // This is a map of the properties. Map the name to the type. struct prop_info_t : public LineInfo { - inline prop_info_t() : qual(property_qualifier_t::make_none()), type(0) { } + inline prop_info_t() : qual(property_qualifier_t::make_none()) { } inline prop_info_t(property_qualifier_t q, data_type_t*t) : qual(q), type(t) { } + prop_info_t(prop_info_t&&) = default; + prop_info_t& operator=(prop_info_t&&) = default; property_qualifier_t qual; - data_type_t* type; + std::unique_ptr type; }; std::map properties; @@ -356,11 +369,6 @@ struct class_type_t : public data_type_t { std::vector initialize_static; ivl_type_t elaborate_type_raw(Design*, NetScope*) const; - // The save_elaborated_type member must be set to the pointer - // to the netclass_t object that is created to represent this - // type. The elaborate_type_raw() method uses this pointer, - // and it is used in some other situations as well. - netclass_t* save_elaborated_type; virtual SymbolType symbol_type() const; }; @@ -425,8 +433,4 @@ extern std::ostream& operator<< (std::ostream&out, const pform_name_t&); extern std::ostream& operator<< (std::ostream&out, const name_component_t&that); extern std::ostream& operator<< (std::ostream&out, const index_component_t&that); -#if __cplusplus < 201103L -#undef unique_ptr -#endif - #endif /* IVL_pform_types_H */