source: src/SymTab/Indexer.cc@ 52c2a72

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors ctor deferred_resn demangler enum forall-pointer-decay gc_noraii jacob/cs343-translation jenkins-sandbox memory new-ast new-ast-unique-expr new-env no_list persistent-indexer pthread-emulation qualifiedEnum resolv-new string with_gc
Last change on this file since 52c2a72 was 52c2a72, checked in by Aaron Moss <a3moss@…>, 10 years ago

Fold StackTable variants into indexer

  • Property mode set to 100644
File size: 22.0 KB
Line 
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// Indexer.cc --
8//
9// Author : Richard C. Bilson
10// Created On : Sun May 17 21:37:33 2015
11// Last Modified By : Peter A. Buhr
12// Last Modified On : Wed Mar 2 17:31:29 2016
13// Update Count : 11
14//
15
16#include "Indexer.h"
17
18#include <string>
19#include <typeinfo>
20#include <unordered_map>
21#include <utility>
22
23#include "IdTable.h"
24
25#include "SynTree/Declaration.h"
26#include "SynTree/Type.h"
27#include "SynTree/Expression.h"
28#include "SynTree/Initializer.h"
29#include "SynTree/Statement.h"
30
31#include "Common/utility.h"
32
33#define debugPrint(x) if ( doDebug ) { std::cout << x; }
34
35namespace SymTab {
36 template< typename Container, typename VisitorType >
37 inline void acceptAllNewScope( Container &container, VisitorType &visitor ) {
38 visitor.enterScope();
39 acceptAll( container, visitor );
40 visitor.leaveScope();
41 }
42
43 typedef std::unordered_map< std::string, NamedTypeDecl* > TypeTable;
44 typedef std::unordered_map< std::string, StructDecl* > StructTable;
45 typedef std::unordered_map< std::string, EnumDecl* > EnumTable;
46 typedef std::unordered_map< std::string, UnionDecl* > UnionTable;
47 typedef std::unordered_map< std::string, TraitDecl* > TraitTable;
48
49 template< typename Decl >
50 void dump( const std::unordered_map< std::string, Decl* > &table, std::ostream &os ) {
51 for ( typename std::unordered_map< std::string, Decl* >::const_iterator it = table.begin(); it != table.end(); ++it ) {
52 os << it->second << std::endl;
53 } // for
54 }
55
56 struct Indexer::Impl {
57 Impl( unsigned long _scope ) : refCount(1), scope( _scope ), size( 0 ), base(),
58 idTable(), typeTable(), structTable(), enumTable(), unionTable(), traitTable() {}
59 Impl( unsigned long _scope, Indexer &&_base ) : refCount(1), scope( _scope ), size( 0 ), base( _base ),
60 idTable(), typeTable(), structTable(), enumTable(), unionTable(), traitTable() {}
61 unsigned long refCount; ///< Number of references to these tables
62 unsigned long scope; ///< Scope these tables are associated with
63 unsigned long size; ///< Number of elements stored in this table
64 const Indexer base; ///< Base indexer this extends
65
66 IdTable idTable; ///< Identifier namespace
67 TypeTable typeTable; ///< Type namespace
68 StructTable structTable; ///< Struct namespace
69 EnumTable enumTable; ///< Enum namespace
70 UnionTable unionTable; ///< Union namespace
71 TraitTable traitTable; ///< Trait namespace
72 };
73
74 Indexer::Impl *Indexer::newRef( Indexer::Impl *toClone ) {
75 if ( ! toClone ) return 0;
76
77 // shorten the search chain by skipping empty links
78 Indexer::Impl *ret = toClone->size == 0 ? toClone->base.tables : toClone;
79 if ( ret ) { ++ret->refCount; }
80
81 return ret;
82 }
83
84 void Indexer::deleteRef( Indexer::Impl *toFree ) {
85 if ( ! toFree ) return;
86
87 if ( --toFree->refCount == 0 ) delete toFree;
88 }
89
90 void Indexer::makeWritable() {
91 if ( ! tables ) {
92 // create indexer if not yet set
93 tables = new Indexer::Impl( scope );
94 } else if ( tables->refCount > 1 || tables->scope != scope ) {
95 // make this indexer the base of a fresh indexer at the current scope
96 tables = new Indexer::Impl( scope, std::move( *this ) );
97 }
98 }
99
100 Indexer::Indexer( bool _doDebug ) : tables( 0 ), scope( 0 ), doDebug( _doDebug ) {}
101
102 Indexer::Indexer( const Indexer &that ) : tables( newRef( that.tables ) ), scope( that.scope ), doDebug( that.doDebug ) {}
103
104 Indexer::Indexer( Indexer &&that ) : tables( that.tables ), scope( that.scope ), doDebug( that.doDebug ) {
105 that.tables = 0;
106 }
107
108 Indexer::~Indexer() {
109 deleteRef( tables );
110 }
111
112 Indexer& Indexer::operator= ( const Indexer &that ) {
113 deleteRef( tables );
114
115 tables = newRef( that.tables );
116 scope = that.scope;
117 doDebug = that.doDebug;
118
119 return *this;
120 }
121
122 Indexer& Indexer::operator= ( Indexer &&that ) {
123 deleteRef( tables );
124
125 tables = that.tables;
126 scope = that.scope;
127 doDebug = that.doDebug;
128
129 that.tables = 0;
130
131 return *this;
132 }
133
134 void Indexer::visit( ObjectDecl *objectDecl ) {
135 enterScope();
136 maybeAccept( objectDecl->get_type(), *this );
137 leaveScope();
138 maybeAccept( objectDecl->get_init(), *this );
139 maybeAccept( objectDecl->get_bitfieldWidth(), *this );
140 if ( objectDecl->get_name() != "" ) {
141 debugPrint( "Adding object " << objectDecl->get_name() << std::endl );
142 addId( objectDecl );
143 } // if
144 }
145
146 void Indexer::visit( FunctionDecl *functionDecl ) {
147 if ( functionDecl->get_name() == "" ) return;
148 debugPrint( "Adding function " << functionDecl->get_name() << std::endl );
149 addId( functionDecl );
150 enterScope();
151 maybeAccept( functionDecl->get_functionType(), *this );
152 acceptAll( functionDecl->get_oldDecls(), *this );
153 maybeAccept( functionDecl->get_statements(), *this );
154 leaveScope();
155 }
156
157
158// A NOTE ON THE ORDER OF TRAVERSAL
159//
160// Types and typedefs have their base types visited before they are added to the type table. This is ok, since there is
161// no such thing as a recursive type or typedef.
162//
163// typedef struct { T *x; } T; // never allowed
164//
165// for structs/unions, it is possible to have recursion, so the decl should be added as if it's incomplete to begin, the
166// members are traversed, and then the complete type should be added (assuming the type is completed by this particular
167// declaration).
168//
169// struct T { struct T *x; }; // allowed
170//
171// It is important to add the complete type to the symbol table *after* the members/base has been traversed, since that
172// traversal may modify the definition of the type and these modifications should be visible when the symbol table is
173// queried later in this pass.
174//
175// TODO: figure out whether recursive contexts are sensible/possible/reasonable.
176
177
178 void Indexer::visit( TypeDecl *typeDecl ) {
179 // see A NOTE ON THE ORDER OF TRAVERSAL, above
180 // note that assertions come after the type is added to the symtab, since they are not part of the type proper
181 // and may depend on the type itself
182 enterScope();
183 acceptAll( typeDecl->get_parameters(), *this );
184 maybeAccept( typeDecl->get_base(), *this );
185 leaveScope();
186 debugPrint( "Adding type " << typeDecl->get_name() << std::endl );
187 addType( typeDecl );
188 acceptAll( typeDecl->get_assertions(), *this );
189 }
190
191 void Indexer::visit( TypedefDecl *typeDecl ) {
192 enterScope();
193 acceptAll( typeDecl->get_parameters(), *this );
194 maybeAccept( typeDecl->get_base(), *this );
195 leaveScope();
196 debugPrint( "Adding typedef " << typeDecl->get_name() << std::endl );
197 addType( typeDecl );
198 }
199
200 void Indexer::visit( StructDecl *aggregateDecl ) {
201 // make up a forward declaration and add it before processing the members
202 StructDecl fwdDecl( aggregateDecl->get_name() );
203 cloneAll( aggregateDecl->get_parameters(), fwdDecl.get_parameters() );
204 debugPrint( "Adding fwd decl for struct " << fwdDecl.get_name() << std::endl );
205 addStruct( &fwdDecl );
206
207 enterScope();
208 acceptAll( aggregateDecl->get_parameters(), *this );
209 acceptAll( aggregateDecl->get_members(), *this );
210 leaveScope();
211
212 debugPrint( "Adding struct " << aggregateDecl->get_name() << std::endl );
213 // this addition replaces the forward declaration
214 addStruct( aggregateDecl );
215 }
216
217 void Indexer::visit( UnionDecl *aggregateDecl ) {
218 // make up a forward declaration and add it before processing the members
219 UnionDecl fwdDecl( aggregateDecl->get_name() );
220 cloneAll( aggregateDecl->get_parameters(), fwdDecl.get_parameters() );
221 debugPrint( "Adding fwd decl for union " << fwdDecl.get_name() << std::endl );
222 addUnion( &fwdDecl );
223
224 enterScope();
225 acceptAll( aggregateDecl->get_parameters(), *this );
226 acceptAll( aggregateDecl->get_members(), *this );
227 leaveScope();
228
229 debugPrint( "Adding union " << aggregateDecl->get_name() << std::endl );
230 addUnion( aggregateDecl );
231 }
232
233 void Indexer::visit( EnumDecl *aggregateDecl ) {
234 debugPrint( "Adding enum " << aggregateDecl->get_name() << std::endl );
235 addEnum( aggregateDecl );
236 // unlike structs, contexts, and unions, enums inject their members into the global scope
237 acceptAll( aggregateDecl->get_members(), *this );
238 }
239
240 void Indexer::visit( TraitDecl *aggregateDecl ) {
241 enterScope();
242 acceptAll( aggregateDecl->get_parameters(), *this );
243 acceptAll( aggregateDecl->get_members(), *this );
244 leaveScope();
245
246 debugPrint( "Adding context " << aggregateDecl->get_name() << std::endl );
247 addTrait( aggregateDecl );
248 }
249
250 void Indexer::visit( CompoundStmt *compoundStmt ) {
251 enterScope();
252 acceptAll( compoundStmt->get_kids(), *this );
253 leaveScope();
254 }
255
256
257 void Indexer::visit( ApplicationExpr *applicationExpr ) {
258 acceptAllNewScope( applicationExpr->get_results(), *this );
259 maybeAccept( applicationExpr->get_function(), *this );
260 acceptAll( applicationExpr->get_args(), *this );
261 }
262
263 void Indexer::visit( UntypedExpr *untypedExpr ) {
264 acceptAllNewScope( untypedExpr->get_results(), *this );
265 acceptAll( untypedExpr->get_args(), *this );
266 }
267
268 void Indexer::visit( NameExpr *nameExpr ) {
269 acceptAllNewScope( nameExpr->get_results(), *this );
270 }
271
272 void Indexer::visit( AddressExpr *addressExpr ) {
273 acceptAllNewScope( addressExpr->get_results(), *this );
274 maybeAccept( addressExpr->get_arg(), *this );
275 }
276
277 void Indexer::visit( LabelAddressExpr *labAddressExpr ) {
278 acceptAllNewScope( labAddressExpr->get_results(), *this );
279 maybeAccept( labAddressExpr->get_arg(), *this );
280 }
281
282 void Indexer::visit( CastExpr *castExpr ) {
283 acceptAllNewScope( castExpr->get_results(), *this );
284 maybeAccept( castExpr->get_arg(), *this );
285 }
286
287 void Indexer::visit( UntypedMemberExpr *memberExpr ) {
288 acceptAllNewScope( memberExpr->get_results(), *this );
289 maybeAccept( memberExpr->get_aggregate(), *this );
290 }
291
292 void Indexer::visit( MemberExpr *memberExpr ) {
293 acceptAllNewScope( memberExpr->get_results(), *this );
294 maybeAccept( memberExpr->get_aggregate(), *this );
295 }
296
297 void Indexer::visit( VariableExpr *variableExpr ) {
298 acceptAllNewScope( variableExpr->get_results(), *this );
299 }
300
301 void Indexer::visit( ConstantExpr *constantExpr ) {
302 acceptAllNewScope( constantExpr->get_results(), *this );
303 maybeAccept( constantExpr->get_constant(), *this );
304 }
305
306 void Indexer::visit( SizeofExpr *sizeofExpr ) {
307 acceptAllNewScope( sizeofExpr->get_results(), *this );
308 if ( sizeofExpr->get_isType() ) {
309 maybeAccept( sizeofExpr->get_type(), *this );
310 } else {
311 maybeAccept( sizeofExpr->get_expr(), *this );
312 }
313 }
314
315 void Indexer::visit( AlignofExpr *alignofExpr ) {
316 acceptAllNewScope( alignofExpr->get_results(), *this );
317 if ( alignofExpr->get_isType() ) {
318 maybeAccept( alignofExpr->get_type(), *this );
319 } else {
320 maybeAccept( alignofExpr->get_expr(), *this );
321 }
322 }
323
324 void Indexer::visit( UntypedOffsetofExpr *offsetofExpr ) {
325 acceptAllNewScope( offsetofExpr->get_results(), *this );
326 maybeAccept( offsetofExpr->get_type(), *this );
327 }
328
329 void Indexer::visit( OffsetofExpr *offsetofExpr ) {
330 acceptAllNewScope( offsetofExpr->get_results(), *this );
331 maybeAccept( offsetofExpr->get_type(), *this );
332 maybeAccept( offsetofExpr->get_member(), *this );
333 }
334
335 void Indexer::visit( AttrExpr *attrExpr ) {
336 acceptAllNewScope( attrExpr->get_results(), *this );
337 if ( attrExpr->get_isType() ) {
338 maybeAccept( attrExpr->get_type(), *this );
339 } else {
340 maybeAccept( attrExpr->get_expr(), *this );
341 }
342 }
343
344 void Indexer::visit( LogicalExpr *logicalExpr ) {
345 acceptAllNewScope( logicalExpr->get_results(), *this );
346 maybeAccept( logicalExpr->get_arg1(), *this );
347 maybeAccept( logicalExpr->get_arg2(), *this );
348 }
349
350 void Indexer::visit( ConditionalExpr *conditionalExpr ) {
351 acceptAllNewScope( conditionalExpr->get_results(), *this );
352 maybeAccept( conditionalExpr->get_arg1(), *this );
353 maybeAccept( conditionalExpr->get_arg2(), *this );
354 maybeAccept( conditionalExpr->get_arg3(), *this );
355 }
356
357 void Indexer::visit( CommaExpr *commaExpr ) {
358 acceptAllNewScope( commaExpr->get_results(), *this );
359 maybeAccept( commaExpr->get_arg1(), *this );
360 maybeAccept( commaExpr->get_arg2(), *this );
361 }
362
363 void Indexer::visit( TupleExpr *tupleExpr ) {
364 acceptAllNewScope( tupleExpr->get_results(), *this );
365 acceptAll( tupleExpr->get_exprs(), *this );
366 }
367
368 void Indexer::visit( SolvedTupleExpr *tupleExpr ) {
369 acceptAllNewScope( tupleExpr->get_results(), *this );
370 acceptAll( tupleExpr->get_exprs(), *this );
371 }
372
373 void Indexer::visit( TypeExpr *typeExpr ) {
374 acceptAllNewScope( typeExpr->get_results(), *this );
375 maybeAccept( typeExpr->get_type(), *this );
376 }
377
378 void Indexer::visit( AsmExpr *asmExpr ) {
379 maybeAccept( asmExpr->get_inout(), *this );
380 maybeAccept( asmExpr->get_constraint(), *this );
381 maybeAccept( asmExpr->get_operand(), *this );
382 }
383
384 void Indexer::visit( UntypedValofExpr *valofExpr ) {
385 acceptAllNewScope( valofExpr->get_results(), *this );
386 maybeAccept( valofExpr->get_body(), *this );
387 }
388
389
390 void Indexer::visit( TraitInstType *contextInst ) {
391 acceptAll( contextInst->get_parameters(), *this );
392 acceptAll( contextInst->get_members(), *this );
393 }
394
395 void Indexer::visit( StructInstType *structInst ) {
396 if ( ! lookupStruct( structInst->get_name() ) ) {
397 debugPrint( "Adding struct " << structInst->get_name() << " from implicit forward declaration" << std::endl );
398 addStruct( structInst->get_name() );
399 }
400 enterScope();
401 acceptAll( structInst->get_parameters(), *this );
402 leaveScope();
403 }
404
405 void Indexer::visit( UnionInstType *unionInst ) {
406 if ( ! lookupUnion( unionInst->get_name() ) ) {
407 debugPrint( "Adding union " << unionInst->get_name() << " from implicit forward declaration" << std::endl );
408 addUnion( unionInst->get_name() );
409 }
410 enterScope();
411 acceptAll( unionInst->get_parameters(), *this );
412 leaveScope();
413 }
414
415 void Indexer::visit( ForStmt *forStmt ) {
416 // for statements introduce a level of scope
417 enterScope();
418 Visitor::visit( forStmt );
419 leaveScope();
420 }
421
422
423 void Indexer::lookupId( const std::string &id, std::list< DeclarationWithType* > &list ) const {
424 if ( ! tables ) return;
425
426 tables->idTable.lookupId( id, list );
427 tables->base.lookupId( id, list );
428 }
429
430 DeclarationWithType* Indexer::lookupId( const std::string &id) const {
431 if ( ! tables ) return 0;
432
433 DeclarationWithType *ret = tables->idTable.lookupId(id);
434 return ret ? ret : tables->base.lookupId(id);
435 }
436
437 NamedTypeDecl *Indexer::lookupType( const std::string &id ) const {
438 if ( ! tables ) return 0;
439
440 TypeTable::const_iterator ret = tables->typeTable.find( id );
441 return ret != tables->typeTable.end() ? ret->second : tables->base.lookupType( id );
442 }
443
444 StructDecl *Indexer::lookupStruct( const std::string &id ) const {
445 if ( ! tables ) return 0;
446
447 StructTable::const_iterator ret = tables->structTable.find( id );
448 return ret != tables->structTable.end() ? ret->second : tables->base.lookupStruct( id );
449 }
450
451 EnumDecl *Indexer::lookupEnum( const std::string &id ) const {
452 if ( ! tables ) return 0;
453
454 EnumTable::const_iterator ret = tables->enumTable.find( id );
455 return ret != tables->enumTable.end() ? ret->second : tables->base.lookupEnum( id );
456 }
457
458 UnionDecl *Indexer::lookupUnion( const std::string &id ) const {
459 if ( ! tables ) return 0;
460
461 UnionTable::const_iterator ret = tables->unionTable.find( id );
462 return ret != tables->unionTable.end() ? ret->second : tables->base.lookupUnion( id );
463 }
464
465 TraitDecl *Indexer::lookupTrait( const std::string &id ) const {
466 if ( ! tables ) return 0;
467
468 TraitTable::const_iterator ret = tables->traitTable.find( id );
469 return ret != tables->traitTable.end() ? ret->second : tables->base.lookupTrait( id );
470 }
471
472 NamedTypeDecl *Indexer::lookupTypeAtScope( const std::string &id, unsigned long scope ) const {
473 if ( ! tables ) return 0;
474 if ( tables->scope < scope ) return 0;
475
476 TypeTable::const_iterator ret = tables->typeTable.find( id );
477 return ret != tables->typeTable.end() ? ret->second : tables->base.lookupTypeAtScope( id, scope );
478 }
479
480 StructDecl *Indexer::lookupStructAtScope( const std::string &id, unsigned long scope ) const {
481 if ( ! tables ) return 0;
482 if ( tables->scope < scope ) return 0;
483
484 StructTable::const_iterator ret = tables->structTable.find( id );
485 return ret != tables->structTable.end() ? ret->second : tables->base.lookupStructAtScope( id, scope );
486 }
487
488 EnumDecl *Indexer::lookupEnumAtScope( const std::string &id, unsigned long scope ) const {
489 if ( ! tables ) return 0;
490 if ( tables->scope < scope ) return 0;
491
492 EnumTable::const_iterator ret = tables->enumTable.find( id );
493 return ret != tables->enumTable.end() ? ret->second : tables->base.lookupEnumAtScope( id, scope );
494 }
495
496 UnionDecl *Indexer::lookupUnionAtScope( const std::string &id, unsigned long scope ) const {
497 if ( ! tables ) return 0;
498 if ( tables->scope < scope ) return 0;
499
500 UnionTable::const_iterator ret = tables->unionTable.find( id );
501 return ret != tables->unionTable.end() ? ret->second : tables->base.lookupUnionAtScope( id, scope );
502 }
503
504 TraitDecl *Indexer::lookupTraitAtScope( const std::string &id, unsigned long scope ) const {
505 if ( ! tables ) return 0;
506 if ( tables->scope < scope ) return 0;
507
508 TraitTable::const_iterator ret = tables->traitTable.find( id );
509 return ret != tables->traitTable.end() ? ret->second : tables->base.lookupTraitAtScope( id, scope );
510 }
511
512 void Indexer::addId( DeclarationWithType *decl ) {
513 makeWritable();
514 tables->idTable.addDecl( decl );
515 ++tables->size;
516 }
517
518 bool addedTypeConflicts( NamedTypeDecl *existing, NamedTypeDecl *added ) {
519 if ( existing->get_base() == 0 ) {
520 return false;
521 } else if ( added->get_base() == 0 ) {
522 return true;
523 } else {
524 throw SemanticError( "redeclaration of ", added );
525 }
526 }
527
528 void Indexer::addType( NamedTypeDecl *decl ) {
529 makeWritable();
530
531 const std::string &id = decl->get_name();
532 TypeTable::iterator existing = tables->typeTable.find( id );
533 if ( existing == tables->typeTable.end() ) {
534 NamedTypeDecl *parent = tables->base.lookupTypeAtScope( id, scope );
535 if ( ! parent || ! addedTypeConflicts( parent, decl ) ) {
536 tables->typeTable.insert( existing, std::make_pair( id, decl ) );
537 ++tables->size;
538 }
539 } else {
540 if ( ! addedTypeConflicts( existing->second, decl ) ) {
541 existing->second = decl;
542 }
543 }
544 }
545
546 bool addedDeclConflicts( AggregateDecl *existing, AggregateDecl *added ) {
547 if ( existing->get_members().empty() ) {
548 return false;
549 } else if ( ! added->get_members().empty() ) {
550 throw SemanticError( "redeclaration of ", added );
551 } // if
552 return true;
553 }
554
555 void Indexer::addStruct( const std::string &id ) {
556 addStruct( new StructDecl( id ) );
557 }
558
559 void Indexer::addStruct( StructDecl *decl ) {
560 makeWritable();
561
562 const std::string &id = decl->get_name();
563 StructTable::iterator existing = tables->structTable.find( id );
564 if ( existing == tables->structTable.end() ) {
565 StructDecl *parent = tables->base.lookupStructAtScope( id, scope );
566 if ( ! parent || ! addedDeclConflicts( parent, decl ) ) {
567 tables->structTable.insert( existing, std::make_pair( id, decl ) );
568 ++tables->size;
569 }
570 } else {
571 if ( ! addedDeclConflicts( existing->second, decl ) ) {
572 existing->second = decl;
573 }
574 }
575 }
576
577 void Indexer::addEnum( EnumDecl *decl ) {
578 makeWritable();
579
580 const std::string &id = decl->get_name();
581 EnumTable::iterator existing = tables->enumTable.find( id );
582 if ( existing == tables->enumTable.end() ) {
583 EnumDecl *parent = tables->base.lookupEnumAtScope( id, scope );
584 if ( ! parent || ! addedDeclConflicts( parent, decl ) ) {
585 tables->enumTable.insert( existing, std::make_pair( id, decl ) );
586 ++tables->size;
587 }
588 } else {
589 if ( ! addedDeclConflicts( existing->second, decl ) ) {
590 existing->second = decl;
591 }
592 }
593 }
594
595 void Indexer::addUnion( const std::string &id ) {
596 addUnion( new UnionDecl( id ) );
597 }
598
599 void Indexer::addUnion( UnionDecl *decl ) {
600 makeWritable();
601
602 const std::string &id = decl->get_name();
603 UnionTable::iterator existing = tables->unionTable.find( id );
604 if ( existing == tables->unionTable.end() ) {
605 UnionDecl *parent = tables->base.lookupUnionAtScope( id, scope );
606 if ( ! parent || ! addedDeclConflicts( parent, decl ) ) {
607 tables->unionTable.insert( existing, std::make_pair( id, decl ) );
608 ++tables->size;
609 }
610 } else {
611 if ( ! addedDeclConflicts( existing->second, decl ) ) {
612 existing->second = decl;
613 }
614 }
615 }
616
617 void Indexer::addTrait( TraitDecl *decl ) {
618 makeWritable();
619
620 const std::string &id = decl->get_name();
621 TraitTable::iterator existing = tables->traitTable.find( id );
622 if ( existing == tables->traitTable.end() ) {
623 TraitDecl *parent = tables->base.lookupTraitAtScope( id, scope );
624 if ( ! parent || ! addedDeclConflicts( parent, decl ) ) {
625 tables->traitTable.insert( existing, std::make_pair( id, decl ) );
626 ++tables->size;
627 }
628 } else {
629 if ( ! addedDeclConflicts( existing->second, decl ) ) {
630 existing->second = decl;
631 }
632 }
633 }
634
635 void Indexer::enterScope() {
636 ++scope;
637
638 if ( doDebug ) {
639 std::cout << "--- Entering scope " << scope << std::endl;
640 }
641 }
642
643 void Indexer::leaveScope() {
644 using std::cout;
645
646 assert( scope > 0 && "cannot leave initial scope" );
647 --scope;
648
649 while ( tables && tables->scope > scope ) {
650 if ( doDebug ) {
651 cout << "--- Leaving scope " << tables->scope << " containing" << std::endl;
652 tables->idTable.dump( cout );
653 dump( tables->typeTable, cout );
654 dump( tables->structTable, cout );
655 dump( tables->enumTable, cout );
656 dump( tables->unionTable, cout );
657 dump( tables->traitTable, cout );
658 }
659
660 // swap tables for base table until we find one at an appropriate scope
661 Indexer::Impl *base = newRef( tables->base.tables );
662 deleteRef( tables );
663 tables = base;
664 }
665 }
666
667 void Indexer::print( std::ostream &os, int indent ) const {
668 using std::cerr;
669
670 cerr << "===idTable===" << std::endl;
671 if ( tables ) tables->idTable.dump( os );
672 cerr << "===typeTable===" << std::endl;
673 if ( tables ) dump( tables->typeTable, os );
674 cerr << "===structTable===" << std::endl;
675 if ( tables ) dump( tables->structTable, os );
676 cerr << "===enumTable===" << std::endl;
677 if ( tables ) dump( tables->enumTable, os );
678 cerr << "===unionTable===" << std::endl;
679 if ( tables ) dump( tables->unionTable, os );
680 cerr << "===contextTable===" << std::endl;
681 if ( tables ) dump( tables->traitTable, os );
682 }
683} // namespace SymTab
684
685// Local Variables: //
686// tab-width: 4 //
687// mode: c++ //
688// compile-command: "make install" //
689// End: //
Note: See TracBrowser for help on using the repository browser.