source: src/AST/Node.cpp @ 4407b7e

ADTast-experimentalpthread-emulation
Last change on this file since 4407b7e was f6e6a55, checked in by Andrew Beach <ajbeach@…>, 3 years ago

Added ast::WaitForClause? and changed ast::WaitForStmt? to use it. This simplified a lot of the internal code.

  • Property mode set to 100644
File size: 19.1 KB
RevLine 
[87701b6]1//
2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// Node.hpp --
8//
9// Author           : Thierry Delisle
10// Created On       : Thu May 16 14:16:00 2019
[8631c84]11// Last Modified By : Andrew Beach
12// Last Modified On : Fri Mar 25 10:30:00 2022
13// Update Count     : 4
[87701b6]14//
15
16#include "Node.hpp"
17#include "Fwd.hpp"
[10a1225]18
[9ea38de]19#include <csignal>  // MEMORY DEBUG -- for raise
[733074e]20#include <iostream>
[8631c84]21#include <utility>
[733074e]22
[10a1225]23#include "Attribute.hpp"
[87701b6]24#include "Decl.hpp"
25#include "Expr.hpp"
[10a1225]26#include "Init.hpp"
[87701b6]27#include "Stmt.hpp"
28#include "Type.hpp"
[10a1225]29#include "TypeSubstitution.hpp"
[87701b6]30
[461046f]31#include "Print.hpp"
32
[bcb311b]33/// MEMORY DEBUG -- allows breaking on ref-count changes of dynamically chosen object.
[9ea38de]34/// Process to use in GDB:
35///   break ast::Node::_trap()
36///   run
37///   set variable MEM_TRAP_OBJ = <target>
38///   disable <first breakpoint>
39///   continue
40void * MEM_TRAP_OBJ = nullptr;
41
[bcb311b]42void _trap( const void * node ) {
43        if ( node == MEM_TRAP_OBJ ) std::raise(SIGTRAP);
[9ea38de]44}
45
[52a4d69]46[[noreturn]] static inline void strict_fail(const ast::Node * node) {
47        assertf(node, "strict_as had nullptr input.");
48        const ast::ParseNode * parse = dynamic_cast<const ast::ParseNode *>( node );
49        if ( nullptr == parse ) {
[943bfad]50                assertf(false, "%s (no location)", toString(node).c_str());
[52a4d69]51        } else if ( parse->location.isUnset() ) {
[943bfad]52                assertf(false, "%s (unset location)", toString(node).c_str());
[52a4d69]53        } else {
[943bfad]54                assertf(false, "%s (at %s:%d)", toString(node).c_str(),
[52a4d69]55                        parse->location.filename.c_str(), parse->location.first_line);
56        }
57}
58
59template< typename node_t, enum ast::Node::ref_type ref_t >
60void ast::ptr_base<node_t, ref_t>::_strict_fail() const {
61        strict_fail(node);
62}
63
[87701b6]64template< typename node_t, enum ast::Node::ref_type ref_t >
[bcb311b]65void ast::ptr_base<node_t, ref_t>::_inc( const node_t * node ) {
66        node->increment(ref_t);
67        _trap( node );
68}
[87701b6]69
70template< typename node_t, enum ast::Node::ref_type ref_t >
[7d0881c]71void ast::ptr_base<node_t, ref_t>::_dec( const node_t * node, bool do_delete ) {
[bcb311b]72        _trap( node );
[52a4d69]73        node->decrement( ref_t, do_delete );
[bcb311b]74}
[87701b6]75
[4864a73]76template< typename node_t, enum ast::Node::ref_type ref_t >
[52a4d69]77void ast::ptr_base<node_t, ref_t>::_check() const {
[e0e9a0b]78        // if(node) assert(node->was_ever_strong == false || node->strong_count > 0);
79}
[4864a73]80
[8631c84]81template< typename node_t, enum ast::Node::ref_type ref_t >
82void ast::ptr_base<node_t, ref_t>::swap( ptr_base & other ) noexcept {
83        std::swap( this->node, other.node );
84        _trap( this->node );
85        _trap( other.node );
86}
87
[10a1225]88template< typename node_t, enum ast::Node::ref_type ref_t >
[76ed81f]89node_t * ast::ptr_base<node_t, ref_t>::get_and_mutate() {
[10a1225]90        // get mutable version of `n`
91        auto r = mutate( node );
92        // re-assign mutable version in case `mutate()` produced a new pointer
93        assign( r );
94        return r;
95}
96
[76ed81f]97template< typename node_t, enum ast::Node::ref_type ref_t >
98node_t * ast::ptr_base<node_t, ref_t>::set_and_mutate( const node_t * n ) {
99        // ensure ownership of `n` by this node to avoid spurious single-owner mutates
100        assign( n );
101        // return mutable version
102        return get_and_mutate();
103}
104
[733074e]105std::ostream & ast::operator<< ( std::ostream & out, const ast::Node * node ) {
[461046f]106        print(out, node);
[733074e]107        return out;
108}
109
[87701b6]110template class ast::ptr_base< ast::Node, ast::Node::ref_type::weak >;
111template class ast::ptr_base< ast::Node, ast::Node::ref_type::strong >;
112template class ast::ptr_base< ast::ParseNode, ast::Node::ref_type::weak >;
113template class ast::ptr_base< ast::ParseNode, ast::Node::ref_type::strong >;
114template class ast::ptr_base< ast::Decl, ast::Node::ref_type::weak >;
115template class ast::ptr_base< ast::Decl, ast::Node::ref_type::strong >;
116template class ast::ptr_base< ast::DeclWithType, ast::Node::ref_type::weak >;
117template class ast::ptr_base< ast::DeclWithType, ast::Node::ref_type::strong >;
118template class ast::ptr_base< ast::ObjectDecl, ast::Node::ref_type::weak >;
119template class ast::ptr_base< ast::ObjectDecl, ast::Node::ref_type::strong >;
120template class ast::ptr_base< ast::FunctionDecl, ast::Node::ref_type::weak >;
121template class ast::ptr_base< ast::FunctionDecl, ast::Node::ref_type::strong >;
122template class ast::ptr_base< ast::AggregateDecl, ast::Node::ref_type::weak >;
123template class ast::ptr_base< ast::AggregateDecl, ast::Node::ref_type::strong >;
124template class ast::ptr_base< ast::StructDecl, ast::Node::ref_type::weak >;
125template class ast::ptr_base< ast::StructDecl, ast::Node::ref_type::strong >;
126template class ast::ptr_base< ast::UnionDecl, ast::Node::ref_type::weak >;
127template class ast::ptr_base< ast::UnionDecl, ast::Node::ref_type::strong >;
128template class ast::ptr_base< ast::EnumDecl, ast::Node::ref_type::weak >;
129template class ast::ptr_base< ast::EnumDecl, ast::Node::ref_type::strong >;
130template class ast::ptr_base< ast::TraitDecl, ast::Node::ref_type::weak >;
131template class ast::ptr_base< ast::TraitDecl, ast::Node::ref_type::strong >;
132template class ast::ptr_base< ast::NamedTypeDecl, ast::Node::ref_type::weak >;
133template class ast::ptr_base< ast::NamedTypeDecl, ast::Node::ref_type::strong >;
134template class ast::ptr_base< ast::TypeDecl, ast::Node::ref_type::weak >;
135template class ast::ptr_base< ast::TypeDecl, ast::Node::ref_type::strong >;
136template class ast::ptr_base< ast::TypedefDecl, ast::Node::ref_type::weak >;
137template class ast::ptr_base< ast::TypedefDecl, ast::Node::ref_type::strong >;
138template class ast::ptr_base< ast::AsmDecl, ast::Node::ref_type::weak >;
139template class ast::ptr_base< ast::AsmDecl, ast::Node::ref_type::strong >;
[2d019af]140template class ast::ptr_base< ast::DirectiveDecl, ast::Node::ref_type::weak >;
141template class ast::ptr_base< ast::DirectiveDecl, ast::Node::ref_type::strong >;
[87701b6]142template class ast::ptr_base< ast::StaticAssertDecl, ast::Node::ref_type::weak >;
143template class ast::ptr_base< ast::StaticAssertDecl, ast::Node::ref_type::strong >;
144template class ast::ptr_base< ast::Stmt, ast::Node::ref_type::weak >;
145template class ast::ptr_base< ast::Stmt, ast::Node::ref_type::strong >;
146template class ast::ptr_base< ast::CompoundStmt, ast::Node::ref_type::weak >;
147template class ast::ptr_base< ast::CompoundStmt, ast::Node::ref_type::strong >;
148template class ast::ptr_base< ast::ExprStmt, ast::Node::ref_type::weak >;
149template class ast::ptr_base< ast::ExprStmt, ast::Node::ref_type::strong >;
150template class ast::ptr_base< ast::AsmStmt, ast::Node::ref_type::weak >;
151template class ast::ptr_base< ast::AsmStmt, ast::Node::ref_type::strong >;
152template class ast::ptr_base< ast::DirectiveStmt, ast::Node::ref_type::weak >;
153template class ast::ptr_base< ast::DirectiveStmt, ast::Node::ref_type::strong >;
154template class ast::ptr_base< ast::IfStmt, ast::Node::ref_type::weak >;
155template class ast::ptr_base< ast::IfStmt, ast::Node::ref_type::strong >;
[3b0bc16]156template class ast::ptr_base< ast::WhileDoStmt, ast::Node::ref_type::weak >;
157template class ast::ptr_base< ast::WhileDoStmt, ast::Node::ref_type::strong >;
[87701b6]158template class ast::ptr_base< ast::ForStmt, ast::Node::ref_type::weak >;
159template class ast::ptr_base< ast::ForStmt, ast::Node::ref_type::strong >;
160template class ast::ptr_base< ast::SwitchStmt, ast::Node::ref_type::weak >;
161template class ast::ptr_base< ast::SwitchStmt, ast::Node::ref_type::strong >;
[400b8be]162template class ast::ptr_base< ast::CaseClause, ast::Node::ref_type::weak >;
163template class ast::ptr_base< ast::CaseClause, ast::Node::ref_type::strong >;
[87701b6]164template class ast::ptr_base< ast::BranchStmt, ast::Node::ref_type::weak >;
165template class ast::ptr_base< ast::BranchStmt, ast::Node::ref_type::strong >;
166template class ast::ptr_base< ast::ReturnStmt, ast::Node::ref_type::weak >;
167template class ast::ptr_base< ast::ReturnStmt, ast::Node::ref_type::strong >;
168template class ast::ptr_base< ast::ThrowStmt, ast::Node::ref_type::weak >;
169template class ast::ptr_base< ast::ThrowStmt, ast::Node::ref_type::strong >;
170template class ast::ptr_base< ast::TryStmt, ast::Node::ref_type::weak >;
171template class ast::ptr_base< ast::TryStmt, ast::Node::ref_type::strong >;
[400b8be]172template class ast::ptr_base< ast::CatchClause, ast::Node::ref_type::weak >;
173template class ast::ptr_base< ast::CatchClause, ast::Node::ref_type::strong >;
174template class ast::ptr_base< ast::FinallyClause, ast::Node::ref_type::weak >;
175template class ast::ptr_base< ast::FinallyClause, ast::Node::ref_type::strong >;
[87701b6]176template class ast::ptr_base< ast::WaitForStmt, ast::Node::ref_type::weak >;
177template class ast::ptr_base< ast::WaitForStmt, ast::Node::ref_type::strong >;
[f6e6a55]178template class ast::ptr_base< ast::WaitForClause, ast::Node::ref_type::weak >;
179template class ast::ptr_base< ast::WaitForClause, ast::Node::ref_type::strong >;
[87701b6]180template class ast::ptr_base< ast::WithStmt, ast::Node::ref_type::weak >;
181template class ast::ptr_base< ast::WithStmt, ast::Node::ref_type::strong >;
182template class ast::ptr_base< ast::DeclStmt, ast::Node::ref_type::weak >;
183template class ast::ptr_base< ast::DeclStmt, ast::Node::ref_type::strong >;
184template class ast::ptr_base< ast::NullStmt, ast::Node::ref_type::weak >;
185template class ast::ptr_base< ast::NullStmt, ast::Node::ref_type::strong >;
186template class ast::ptr_base< ast::ImplicitCtorDtorStmt, ast::Node::ref_type::weak >;
187template class ast::ptr_base< ast::ImplicitCtorDtorStmt, ast::Node::ref_type::strong >;
[6cebfef]188template class ast::ptr_base< ast::MutexStmt, ast::Node::ref_type::weak >;
189template class ast::ptr_base< ast::MutexStmt, ast::Node::ref_type::strong >;
[87701b6]190template class ast::ptr_base< ast::Expr, ast::Node::ref_type::weak >;
191template class ast::ptr_base< ast::Expr, ast::Node::ref_type::strong >;
192template class ast::ptr_base< ast::ApplicationExpr, ast::Node::ref_type::weak >;
193template class ast::ptr_base< ast::ApplicationExpr, ast::Node::ref_type::strong >;
194template class ast::ptr_base< ast::UntypedExpr, ast::Node::ref_type::weak >;
195template class ast::ptr_base< ast::UntypedExpr, ast::Node::ref_type::strong >;
196template class ast::ptr_base< ast::NameExpr, ast::Node::ref_type::weak >;
197template class ast::ptr_base< ast::NameExpr, ast::Node::ref_type::strong >;
198template class ast::ptr_base< ast::AddressExpr, ast::Node::ref_type::weak >;
199template class ast::ptr_base< ast::AddressExpr, ast::Node::ref_type::strong >;
200template class ast::ptr_base< ast::LabelAddressExpr, ast::Node::ref_type::weak >;
201template class ast::ptr_base< ast::LabelAddressExpr, ast::Node::ref_type::strong >;
202template class ast::ptr_base< ast::CastExpr, ast::Node::ref_type::weak >;
203template class ast::ptr_base< ast::CastExpr, ast::Node::ref_type::strong >;
204template class ast::ptr_base< ast::KeywordCastExpr, ast::Node::ref_type::weak >;
205template class ast::ptr_base< ast::KeywordCastExpr, ast::Node::ref_type::strong >;
206template class ast::ptr_base< ast::VirtualCastExpr, ast::Node::ref_type::weak >;
207template class ast::ptr_base< ast::VirtualCastExpr, ast::Node::ref_type::strong >;
208template class ast::ptr_base< ast::MemberExpr, ast::Node::ref_type::weak >;
209template class ast::ptr_base< ast::MemberExpr, ast::Node::ref_type::strong >;
210template class ast::ptr_base< ast::UntypedMemberExpr, ast::Node::ref_type::weak >;
211template class ast::ptr_base< ast::UntypedMemberExpr, ast::Node::ref_type::strong >;
212template class ast::ptr_base< ast::VariableExpr, ast::Node::ref_type::weak >;
213template class ast::ptr_base< ast::VariableExpr, ast::Node::ref_type::strong >;
214template class ast::ptr_base< ast::ConstantExpr, ast::Node::ref_type::weak >;
215template class ast::ptr_base< ast::ConstantExpr, ast::Node::ref_type::strong >;
216template class ast::ptr_base< ast::SizeofExpr, ast::Node::ref_type::weak >;
217template class ast::ptr_base< ast::SizeofExpr, ast::Node::ref_type::strong >;
218template class ast::ptr_base< ast::AlignofExpr, ast::Node::ref_type::weak >;
219template class ast::ptr_base< ast::AlignofExpr, ast::Node::ref_type::strong >;
220template class ast::ptr_base< ast::UntypedOffsetofExpr, ast::Node::ref_type::weak >;
221template class ast::ptr_base< ast::UntypedOffsetofExpr, ast::Node::ref_type::strong >;
222template class ast::ptr_base< ast::OffsetofExpr, ast::Node::ref_type::weak >;
223template class ast::ptr_base< ast::OffsetofExpr, ast::Node::ref_type::strong >;
224template class ast::ptr_base< ast::OffsetPackExpr, ast::Node::ref_type::weak >;
225template class ast::ptr_base< ast::OffsetPackExpr, ast::Node::ref_type::strong >;
226template class ast::ptr_base< ast::LogicalExpr, ast::Node::ref_type::weak >;
227template class ast::ptr_base< ast::LogicalExpr, ast::Node::ref_type::strong >;
228template class ast::ptr_base< ast::ConditionalExpr, ast::Node::ref_type::weak >;
229template class ast::ptr_base< ast::ConditionalExpr, ast::Node::ref_type::strong >;
230template class ast::ptr_base< ast::CommaExpr, ast::Node::ref_type::weak >;
231template class ast::ptr_base< ast::CommaExpr, ast::Node::ref_type::strong >;
232template class ast::ptr_base< ast::TypeExpr, ast::Node::ref_type::weak >;
233template class ast::ptr_base< ast::TypeExpr, ast::Node::ref_type::strong >;
234template class ast::ptr_base< ast::AsmExpr, ast::Node::ref_type::weak >;
235template class ast::ptr_base< ast::AsmExpr, ast::Node::ref_type::strong >;
236template class ast::ptr_base< ast::ImplicitCopyCtorExpr, ast::Node::ref_type::weak >;
237template class ast::ptr_base< ast::ImplicitCopyCtorExpr, ast::Node::ref_type::strong >;
238template class ast::ptr_base< ast::ConstructorExpr, ast::Node::ref_type::weak >;
239template class ast::ptr_base< ast::ConstructorExpr, ast::Node::ref_type::strong >;
240template class ast::ptr_base< ast::CompoundLiteralExpr, ast::Node::ref_type::weak >;
241template class ast::ptr_base< ast::CompoundLiteralExpr, ast::Node::ref_type::strong >;
242template class ast::ptr_base< ast::RangeExpr, ast::Node::ref_type::weak >;
243template class ast::ptr_base< ast::RangeExpr, ast::Node::ref_type::strong >;
244template class ast::ptr_base< ast::UntypedTupleExpr, ast::Node::ref_type::weak >;
245template class ast::ptr_base< ast::UntypedTupleExpr, ast::Node::ref_type::strong >;
246template class ast::ptr_base< ast::TupleExpr, ast::Node::ref_type::weak >;
247template class ast::ptr_base< ast::TupleExpr, ast::Node::ref_type::strong >;
248template class ast::ptr_base< ast::TupleIndexExpr, ast::Node::ref_type::weak >;
249template class ast::ptr_base< ast::TupleIndexExpr, ast::Node::ref_type::strong >;
250template class ast::ptr_base< ast::TupleAssignExpr, ast::Node::ref_type::weak >;
251template class ast::ptr_base< ast::TupleAssignExpr, ast::Node::ref_type::strong >;
252template class ast::ptr_base< ast::StmtExpr, ast::Node::ref_type::weak >;
253template class ast::ptr_base< ast::StmtExpr, ast::Node::ref_type::strong >;
254template class ast::ptr_base< ast::UniqueExpr, ast::Node::ref_type::weak >;
255template class ast::ptr_base< ast::UniqueExpr, ast::Node::ref_type::strong >;
256template class ast::ptr_base< ast::UntypedInitExpr, ast::Node::ref_type::weak >;
257template class ast::ptr_base< ast::UntypedInitExpr, ast::Node::ref_type::strong >;
258template class ast::ptr_base< ast::InitExpr, ast::Node::ref_type::weak >;
259template class ast::ptr_base< ast::InitExpr, ast::Node::ref_type::strong >;
260template class ast::ptr_base< ast::DeletedExpr, ast::Node::ref_type::weak >;
261template class ast::ptr_base< ast::DeletedExpr, ast::Node::ref_type::strong >;
262template class ast::ptr_base< ast::DefaultArgExpr, ast::Node::ref_type::weak >;
263template class ast::ptr_base< ast::DefaultArgExpr, ast::Node::ref_type::strong >;
264template class ast::ptr_base< ast::GenericExpr, ast::Node::ref_type::weak >;
265template class ast::ptr_base< ast::GenericExpr, ast::Node::ref_type::strong >;
266template class ast::ptr_base< ast::Type, ast::Node::ref_type::weak >;
267template class ast::ptr_base< ast::Type, ast::Node::ref_type::strong >;
268template class ast::ptr_base< ast::VoidType, ast::Node::ref_type::weak >;
269template class ast::ptr_base< ast::VoidType, ast::Node::ref_type::strong >;
270template class ast::ptr_base< ast::BasicType, ast::Node::ref_type::weak >;
271template class ast::ptr_base< ast::BasicType, ast::Node::ref_type::strong >;
272template class ast::ptr_base< ast::PointerType, ast::Node::ref_type::weak >;
273template class ast::ptr_base< ast::PointerType, ast::Node::ref_type::strong >;
274template class ast::ptr_base< ast::ArrayType, ast::Node::ref_type::weak >;
275template class ast::ptr_base< ast::ArrayType, ast::Node::ref_type::strong >;
276template class ast::ptr_base< ast::ReferenceType, ast::Node::ref_type::weak >;
277template class ast::ptr_base< ast::ReferenceType, ast::Node::ref_type::strong >;
278template class ast::ptr_base< ast::QualifiedType, ast::Node::ref_type::weak >;
279template class ast::ptr_base< ast::QualifiedType, ast::Node::ref_type::strong >;
280template class ast::ptr_base< ast::FunctionType, ast::Node::ref_type::weak >;
281template class ast::ptr_base< ast::FunctionType, ast::Node::ref_type::strong >;
[98e8b3b]282template class ast::ptr_base< ast::BaseInstType, ast::Node::ref_type::weak >;
283template class ast::ptr_base< ast::BaseInstType, ast::Node::ref_type::strong >;
[87701b6]284template class ast::ptr_base< ast::StructInstType, ast::Node::ref_type::weak >;
285template class ast::ptr_base< ast::StructInstType, ast::Node::ref_type::strong >;
286template class ast::ptr_base< ast::UnionInstType, ast::Node::ref_type::weak >;
287template class ast::ptr_base< ast::UnionInstType, ast::Node::ref_type::strong >;
288template class ast::ptr_base< ast::EnumInstType, ast::Node::ref_type::weak >;
289template class ast::ptr_base< ast::EnumInstType, ast::Node::ref_type::strong >;
290template class ast::ptr_base< ast::TraitInstType, ast::Node::ref_type::weak >;
291template class ast::ptr_base< ast::TraitInstType, ast::Node::ref_type::strong >;
292template class ast::ptr_base< ast::TypeInstType, ast::Node::ref_type::weak >;
293template class ast::ptr_base< ast::TypeInstType, ast::Node::ref_type::strong >;
294template class ast::ptr_base< ast::TupleType, ast::Node::ref_type::weak >;
295template class ast::ptr_base< ast::TupleType, ast::Node::ref_type::strong >;
296template class ast::ptr_base< ast::TypeofType, ast::Node::ref_type::weak >;
297template class ast::ptr_base< ast::TypeofType, ast::Node::ref_type::strong >;
298template class ast::ptr_base< ast::VarArgsType, ast::Node::ref_type::weak >;
299template class ast::ptr_base< ast::VarArgsType, ast::Node::ref_type::strong >;
300template class ast::ptr_base< ast::ZeroType, ast::Node::ref_type::weak >;
301template class ast::ptr_base< ast::ZeroType, ast::Node::ref_type::strong >;
302template class ast::ptr_base< ast::OneType, ast::Node::ref_type::weak >;
303template class ast::ptr_base< ast::OneType, ast::Node::ref_type::strong >;
304template class ast::ptr_base< ast::GlobalScopeType, ast::Node::ref_type::weak >;
305template class ast::ptr_base< ast::GlobalScopeType, ast::Node::ref_type::strong >;
306template class ast::ptr_base< ast::Designation, ast::Node::ref_type::weak >;
307template class ast::ptr_base< ast::Designation, ast::Node::ref_type::strong >;
308template class ast::ptr_base< ast::Init, ast::Node::ref_type::weak >;
309template class ast::ptr_base< ast::Init, ast::Node::ref_type::strong >;
310template class ast::ptr_base< ast::SingleInit, ast::Node::ref_type::weak >;
311template class ast::ptr_base< ast::SingleInit, ast::Node::ref_type::strong >;
312template class ast::ptr_base< ast::ListInit, ast::Node::ref_type::weak >;
313template class ast::ptr_base< ast::ListInit, ast::Node::ref_type::strong >;
314template class ast::ptr_base< ast::ConstructorInit, ast::Node::ref_type::weak >;
315template class ast::ptr_base< ast::ConstructorInit, ast::Node::ref_type::strong >;
316template class ast::ptr_base< ast::Attribute, ast::Node::ref_type::weak >;
317template class ast::ptr_base< ast::Attribute, ast::Node::ref_type::strong >;
318template class ast::ptr_base< ast::TypeSubstitution, ast::Node::ref_type::weak >;
[52a4d69]319template class ast::ptr_base< ast::TypeSubstitution, ast::Node::ref_type::strong >;
Note: See TracBrowser for help on using the repository browser.