Changeset 8b11840


Ignore:
Timestamp:
Sep 22, 2017, 1:50:00 PM (7 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
b56c17c
Parents:
05807e9
Message:

Cleanup pass through several files

Location:
src
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/GenInit.cc

    r05807e9 r8b11840  
    115115
    116116        void genInit( std::list< Declaration * > & translationUnit ) {
    117                 ReturnFixer::makeReturnTemp( translationUnit );
     117                fixReturnStatements( translationUnit );
    118118                HoistArrayDimension::hoistArrayDimension( translationUnit );
    119119                CtorDtor::generateCtorDtor( translationUnit );
    120120        }
    121121
    122         void ReturnFixer::makeReturnTemp( std::list< Declaration * > & translationUnit ) {
     122        void fixReturnStatements( std::list< Declaration * > & translationUnit ) {
    123123                PassVisitor<ReturnFixer> fixer;
    124124                mutateAll( translationUnit, fixer );
  • src/InitTweak/GenInit.h

    r05807e9 r8b11840  
    2525        void genInit( std::list< Declaration * > & translationUnit );
    2626
    27   /// generates a single ctor/dtor statement using objDecl as the 'this' parameter and arg as the optional argument
    28   ImplicitCtorDtorStmt * genCtorDtor( const std::string & fname, ObjectDecl * objDecl, Expression * arg = nullptr );
     27        /// Converts return statements into copy constructor calls on the hidden return variable
     28        void fixReturnStatements( std::list< Declaration * > & translationUnit );
     29
     30        /// generates a single ctor/dtor statement using objDecl as the 'this' parameter and arg as the optional argument
     31        ImplicitCtorDtorStmt * genCtorDtor( const std::string & fname, ObjectDecl * objDecl, Expression * arg = nullptr );
    2932
    3033        /// creates an appropriate ConstructorInit node which contains a constructor, destructor, and C-initializer
  • src/ResolvExpr/Resolver.cc

    r05807e9 r8b11840  
    9393                PassVisitor<Resolver> resolver;
    9494                acceptAll( translationUnit, resolver );
     95        }
     96
     97        void resolveDecl( Declaration * decl, const SymTab::Indexer &indexer ) {
     98                PassVisitor<Resolver> resolver( indexer );
     99                maybeAccept( decl, resolver );
    95100        }
    96101
  • src/ResolvExpr/Resolver.h

    r05807e9 r8b11840  
    2929        /// Checks types and binds syntactic constructs to typed representations
    3030        void resolve( std::list< Declaration * > translationUnit );
     31        void resolveDecl( Declaration *, const SymTab::Indexer &indexer );
    3132        Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer );
    3233        Expression *findVoidExpression( Expression *untyped, const SymTab::Indexer &indexer );
  • src/ResolvExpr/TypeEnvironment.cc

    r05807e9 r8b11840  
    123123                for ( std::list< EqvClass >::const_iterator theClass = env.begin(); theClass != env.end(); ++theClass ) {
    124124                        for ( std::set< std::string >::const_iterator theVar = theClass->vars.begin(); theVar != theClass->vars.end(); ++theVar ) {
    125 ///       std::cout << "adding " << *theVar;
     125///       std::cerr << "adding " << *theVar;
    126126                                if ( theClass->type ) {
    127 ///         std::cout << " bound to ";
    128 ///         theClass->type->print( std::cout );
    129 ///         std::cout << std::endl;
     127///         std::cerr << " bound to ";
     128///         theClass->type->print( std::cerr );
     129///         std::cerr << std::endl;
    130130                                        sub.add( *theVar, theClass->type );
    131131                                } else if ( theVar != theClass->vars.begin() ) {
    132132                                        TypeInstType *newTypeInst = new TypeInstType( Type::Qualifiers(), *theClass->vars.begin(), theClass->data.kind == TypeDecl::Ftype );
    133 ///         std::cout << " bound to variable " << *theClass->vars.begin() << std::endl;
     133///         std::cerr << " bound to variable " << *theClass->vars.begin() << std::endl;
    134134                                        sub.add( *theVar, newTypeInst );
    135135                                        delete newTypeInst;
  • src/SymTab/Autogen.cc

    r05807e9 r8b11840  
    1616#include "Autogen.h"
    1717
    18 #include <cstddef>                 // for NULL
    1918#include <algorithm>               // for count_if
    2019#include <cassert>                 // for strict_dynamic_cast, assert, assertf
     
    3231#include "GenPoly/DeclMutator.h"   // for DeclMutator
    3332#include "GenPoly/ScopedSet.h"     // for ScopedSet, ScopedSet<>::iterator
     33#include "InitTweak/GenInit.h"     // for fixReturnStatements
     34#include "ResolvExpr/Resolver.h"   // for resolveDecl
    3435#include "SymTab/Mangler.h"        // for Mangler
    3536#include "SynTree/Attribute.h"     // For Attribute
     
    108109
    109110        bool isUnnamedBitfield( ObjectDecl * obj ) {
    110                 return obj != NULL && obj->get_name() == "" && obj->get_bitfieldWidth() != NULL;
     111                return obj != nullptr && obj->get_name() == "" && obj->get_bitfieldWidth() != nullptr;
    111112        }
    112113
     
    115116                FunctionDecl * decl = functionDecl->clone();
    116117                delete decl->get_statements();
    117                 decl->set_statements( NULL );
     118                decl->set_statements( nullptr );
    118119                declsToAdd.push_back( decl );
    119120                decl->fixUniqueId();
     
    326327                                assert( ! func->get_functionType()->get_parameters().empty() );
    327328                                ObjectDecl * dstParam = dynamic_cast<ObjectDecl*>( func->get_functionType()->get_parameters().front() );
    328                                 ObjectDecl * srcParam = NULL;
     329                                ObjectDecl * srcParam = nullptr;
    329330                                if ( func->get_functionType()->get_parameters().size() == 2 ) {
    330331                                        srcParam = dynamic_cast<ObjectDecl*>( func->get_functionType()->get_parameters().back() );
     
    333334                                assert( dstParam );
    334335
    335                                 Expression *srcselect = srcParam ? new MemberExpr( field, new VariableExpr( srcParam ) ) : NULL;
     336                                Expression *srcselect = srcParam ? new MemberExpr( field, new VariableExpr( srcParam ) ) : nullptr;
    336337                                makeStructMemberOp( dstParam, srcselect, field, func, forward );
    337338                        } // if
     
    372373                                } else {
    373374                                        // no matching parameter, initialize field with default ctor
    374                                         makeStructMemberOp( dstParam, NULL, field, func );
     375                                        makeStructMemberOp( dstParam, nullptr, field, func );
    375376                                }
    376377                        }
     
    388389        void makeStructFunctions( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting, std::list< Declaration * > & declsToAdd, const std::vector< FuncData > & data ) {
    389390                // Builtins do not use autogeneration.
    390                 if ( aggregateDecl->get_linkage() == LinkageSpec::BuiltinCFA ||
    391                          aggregateDecl->get_linkage() == LinkageSpec::BuiltinC ) {
     391                if ( LinkageSpec::isBuiltin( aggregateDecl->get_linkage() ) ) {
    392392                        return;
    393393                }
    394394
    395395                // Make function polymorphic in same parameters as generic struct, if applicable
    396                 const std::list< TypeDecl* > & typeParams = aggregateDecl->get_parameters(); // List of type variables to be placed on the generated functions
     396                const std::list< TypeDecl * > & typeParams = aggregateDecl->get_parameters(); // List of type variables to be placed on the generated functions
    397397
    398398                // generate each of the functions based on the supplied FuncData objects
     
    565565        }
    566566
    567         void AutogenerateRoutines::previsit( EnumDecl *enumDecl ) {
     567        void AutogenerateRoutines::previsit( EnumDecl * enumDecl ) {
    568568                visit_children = false;
    569569                if ( ! enumDecl->get_members().empty() ) {
     
    574574        }
    575575
    576         void AutogenerateRoutines::previsit( StructDecl *structDecl ) {
     576        void AutogenerateRoutines::previsit( StructDecl * structDecl ) {
    577577                visit_children = false;
    578                 if ( structDecl->has_body() && structsDone.find( structDecl->get_name() ) == structsDone.end() ) {
    579                         StructInstType structInst( Type::Qualifiers(), structDecl->get_name() );
    580                         for ( TypeDecl * typeDecl : structDecl->get_parameters() ) {
     578                if ( structDecl->has_body() && structsDone.find( structDecl->name ) == structsDone.end() ) {
     579                        StructInstType structInst( Type::Qualifiers(), structDecl->name );
     580                        for ( TypeDecl * typeDecl : structDecl->parameters ) {
    581581                                // need to visit assertions so that they are added to the appropriate maps
    582                                 acceptAll( typeDecl->get_assertions(), *visitor );
    583                                 structInst.get_parameters().push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeDecl->get_name(), typeDecl ) ) );
     582                                acceptAll( typeDecl->assertions, *visitor );
     583                                structInst.parameters.push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeDecl->name, typeDecl ) ) );
    584584                        }
    585585                        structInst.set_baseStruct( structDecl );
    586586                        makeStructFunctions( structDecl, &structInst, functionNesting, declsToAddAfter, data );
    587                         structsDone.insert( structDecl->get_name() );
     587                        structsDone.insert( structDecl->name );
    588588                } // if
    589589        }
    590590
    591         void AutogenerateRoutines::previsit( UnionDecl *unionDecl ) {
     591        void AutogenerateRoutines::previsit( UnionDecl * unionDecl ) {
    592592                visit_children = false;
    593593                if ( ! unionDecl->get_members().empty() ) {
     
    609609
    610610        // generate ctor/dtors/assign for typedecls, e.g., otype T = int *;
    611         void AutogenerateRoutines::previsit( TypeDecl *typeDecl ) {
     611        void AutogenerateRoutines::previsit( TypeDecl * typeDecl ) {
    612612                visit_children = false;
    613613                if ( ! typeDecl->base ) return;
     
    678678                insert( functionDecl, destructable, InitTweak::isDestructor );
    679679
    680                 maybeAccept( functionDecl->get_functionType(), *visitor );
     680                maybeAccept( functionDecl->type, *visitor );
    681681                functionNesting += 1;
    682                 maybeAccept( functionDecl->get_statements(), *visitor );
     682                maybeAccept( functionDecl->statements, *visitor );
    683683                functionNesting -= 1;
    684684        }
  • src/SymTab/FixFunction.cc

    r05807e9 r8b11840  
    2727
    2828        DeclarationWithType * FixFunction::mutate(FunctionDecl *functionDecl) {
     29                // can't delete function type because it may contain assertions, so transfer ownership to new object
    2930                ObjectDecl *pointer = new ObjectDecl( functionDecl->get_name(), functionDecl->get_storageClasses(), functionDecl->get_linkage(), 0, new PointerType( Type::Qualifiers(), functionDecl->get_type() ), 0, functionDecl->get_attributes() );
    3031                functionDecl->get_attributes().clear();
    31                 // can't delete function type because it may contain assertions, but can't transfer ownership without a clone since set_type checks for nullptr
    32                 functionDecl->set_type( functionDecl->get_type()->clone() );
     32                functionDecl->type = nullptr;
    3333                delete functionDecl;
    3434                return pointer;
  • src/SymTab/Indexer.cc

    r05807e9 r8b11840  
    4040
    4141namespace SymTab {
    42         struct NewScope {
    43                 NewScope( SymTab::Indexer & indexer ) : indexer( indexer ) { indexer.enterScope(); }
    44                 ~NewScope() { indexer.leaveScope(); }
    45                 SymTab::Indexer & indexer;
    46         };
    47 
    48         template< typename TreeType, typename VisitorType >
    49         inline void acceptNewScope( TreeType *tree, VisitorType &visitor ) {
    50                 visitor.enterScope();
    51                 maybeAccept( tree, visitor );
    52                 visitor.leaveScope();
    53         }
    54 
    5542        typedef std::unordered_map< std::string, DeclarationWithType* > MangleTable;
    5643        typedef std::unordered_map< std::string, MangleTable > IdTable;
     
    198185        }
    199186
    200         Indexer::Indexer( bool _doDebug ) : tables( 0 ), scope( 0 ), doDebug( _doDebug ) {}
    201 
    202         Indexer::Indexer( const Indexer &that ) : tables( newRef( that.tables ) ), scope( that.scope ), doDebug( that.doDebug ) {}
    203 
    204         Indexer::Indexer( Indexer &&that ) : tables( that.tables ), scope( that.scope ), doDebug( that.doDebug ) {
     187        Indexer::Indexer() : tables( 0 ), scope( 0 ) {}
     188
     189        Indexer::Indexer( const Indexer &that ) : doDebug( that.doDebug ), tables( newRef( that.tables ) ), scope( that.scope ) {}
     190
     191        Indexer::Indexer( Indexer &&that ) : doDebug( that.doDebug ), tables( that.tables ), scope( that.scope ) {
    205192                that.tables = 0;
    206193        }
  • src/SymTab/Indexer.h

    r05807e9 r8b11840  
    2626        class Indexer {
    2727          public:
    28                 explicit Indexer( bool useDebug = false );
     28                explicit Indexer();
    2929
    3030                Indexer( const Indexer &that );
     
    7676                void addTrait( TraitDecl *decl );
    7777
     78                bool doDebug = false; ///< Display debugging trace?
    7879          private:
    7980                struct Impl;
     
    8182                Impl *tables;         ///< Copy-on-write instance of table data structure
    8283                unsigned long scope;  ///< Scope index of this pointer
    83                 bool doDebug;         ///< Display debugging trace?
    8484
    8585                /// Takes a new ref to a table (returns null if null)
  • src/SymTab/Mangler.cc

    r05807e9 r8b11840  
    3131
    3232namespace SymTab {
    33         std::string Mangler::mangleType( Type *ty ) {
     33        std::string Mangler::mangleType( Type * ty ) {
    3434                Mangler mangler( false, true );
    3535                maybeAccept( ty, mangler );
     
    4848        }
    4949
    50         void Mangler::mangleDecl( DeclarationWithType *declaration ) {
     50        void Mangler::mangleDecl( DeclarationWithType * declaration ) {
    5151                bool wasTopLevel = isTopLevel;
    5252                if ( isTopLevel ) {
     
    7979        }
    8080
    81         void Mangler::visit( ObjectDecl *declaration ) {
     81        void Mangler::visit( ObjectDecl * declaration ) {
    8282                mangleDecl( declaration );
    8383        }
    8484
    85         void Mangler::visit( FunctionDecl *declaration ) {
     85        void Mangler::visit( FunctionDecl * declaration ) {
    8686                mangleDecl( declaration );
    8787        }
    8888
    89         void Mangler::visit( VoidType *voidType ) {
     89        void Mangler::visit( VoidType * voidType ) {
    9090                printQualifiers( voidType );
    9191                mangleName << "v";
    9292        }
    9393
    94         void Mangler::visit( BasicType *basicType ) {
     94        void Mangler::visit( BasicType * basicType ) {
    9595                static const char *btLetter[] = {
    9696                        "b",    // Bool
     
    121121        }
    122122
    123         void Mangler::visit( PointerType *pointerType ) {
     123        void Mangler::visit( PointerType * pointerType ) {
    124124                printQualifiers( pointerType );
    125125                mangleName << "P";
     
    127127        }
    128128
    129         void Mangler::visit( ArrayType *arrayType ) {
     129        void Mangler::visit( ArrayType * arrayType ) {
    130130                // TODO: encode dimension
    131131                printQualifiers( arrayType );
     
    134134        }
    135135
    136         void Mangler::visit( ReferenceType *refType ) {
     136        void Mangler::visit( ReferenceType * refType ) {
    137137                printQualifiers( refType );
    138138                mangleName << "R";
     
    149149        }
    150150
    151         void Mangler::visit( FunctionType *functionType ) {
     151        void Mangler::visit( FunctionType * functionType ) {
    152152                printQualifiers( functionType );
    153153                mangleName << "F";
     
    160160        }
    161161
    162         void Mangler::mangleRef( ReferenceToType *refType, std::string prefix ) {
     162        void Mangler::mangleRef( ReferenceToType * refType, std::string prefix ) {
    163163                printQualifiers( refType );
    164164
     
    166166        }
    167167
    168         void Mangler::mangleGenericRef( ReferenceToType *refType, std::string prefix ) {
     168        void Mangler::mangleGenericRef( ReferenceToType * refType, std::string prefix ) {
    169169                printQualifiers( refType );
    170170
     
    189189        }
    190190
    191         void Mangler::visit( StructInstType *aggregateUseType ) {
     191        void Mangler::visit( StructInstType * aggregateUseType ) {
    192192                if ( typeMode ) mangleGenericRef( aggregateUseType, "s" );
    193193                else mangleRef( aggregateUseType, "s" );
    194194        }
    195195
    196         void Mangler::visit( UnionInstType *aggregateUseType ) {
     196        void Mangler::visit( UnionInstType * aggregateUseType ) {
    197197                if ( typeMode ) mangleGenericRef( aggregateUseType, "u" );
    198198                else mangleRef( aggregateUseType, "u" );
    199199        }
    200200
    201         void Mangler::visit( EnumInstType *aggregateUseType ) {
     201        void Mangler::visit( EnumInstType * aggregateUseType ) {
    202202                mangleRef( aggregateUseType, "e" );
    203203        }
    204204
    205         void Mangler::visit( TypeInstType *typeInst ) {
     205        void Mangler::visit( TypeInstType * typeInst ) {
    206206                VarMapType::iterator varNum = varNums.find( typeInst->get_name() );
    207207                if ( varNum == varNums.end() ) {
     
    231231        }
    232232
    233         void Mangler::visit( TupleType *tupleType ) {
     233        void Mangler::visit( TupleType * tupleType ) {
    234234                printQualifiers( tupleType );
    235235                mangleName << "T";
    236                 acceptAll( tupleType->get_types(), *this );
     236                acceptAll( tupleType->types, *this );
    237237                mangleName << "_";
    238238        }
    239239
    240         void Mangler::visit( VarArgsType *varArgsType ) {
     240        void Mangler::visit( VarArgsType * varArgsType ) {
    241241                printQualifiers( varArgsType );
    242242                mangleName << "VARGS";
    243243        }
    244244
    245         void Mangler::visit( __attribute__((unused)) ZeroType *zeroType ) {
     245        void Mangler::visit( ZeroType * ) {
    246246                mangleName << "Z";
    247247        }
    248248
    249         void Mangler::visit( __attribute__((unused)) OneType *oneType ) {
     249        void Mangler::visit( OneType * ) {
    250250                mangleName << "O";
    251251        }
    252252
    253         void Mangler::visit( TypeDecl *decl ) {
     253        void Mangler::visit( TypeDecl * decl ) {
    254254                static const char *typePrefix[] = { "BT", "BD", "BF" };
    255                 mangleName << typePrefix[ decl->get_kind() ] << ( decl->get_name().length() + 1 ) << decl->get_name();
     255                mangleName << typePrefix[ decl->get_kind() ] << ( decl->name.length() + 1 ) << decl->name;
    256256        }
    257257
     
    262262        }
    263263
    264         void Mangler::printQualifiers( Type *type ) {
     264        void Mangler::printQualifiers( Type * type ) {
    265265                // skip if not including qualifiers
    266266                if ( typeMode ) return;
     
    270270                        int tcount = 0, dcount = 0, fcount = 0, vcount = 0;
    271271                        mangleName << "A";
    272                         for ( Type::ForallList::iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) {
     272                        for ( Type::ForallList::iterator i = type->forall.begin(); i != type->forall.end(); ++i ) {
    273273                                switch ( (*i)->get_kind() ) {
    274274                                  case TypeDecl::Any:
     
    287287                                        assert( false );
    288288                                } // switch
    289                                 varNums[ (*i )->get_name() ] = std::pair< int, int >( nextVarNum++, (int )(*i )->get_kind() );
    290                                 for ( std::list< DeclarationWithType* >::iterator assert = (*i )->get_assertions().begin(); assert != (*i )->get_assertions().end(); ++assert ) {
     289                                varNums[ (*i)->name ] = std::pair< int, int >( nextVarNum++, (int)(*i)->get_kind() );
     290                                for ( std::list< DeclarationWithType* >::iterator assert = (*i)->assertions.begin(); assert != (*i)->assertions.end(); ++assert ) {
    291291                                        Mangler sub_mangler( mangleOverridable, typeMode );
    292292                                        sub_mangler.nextVarNum = nextVarNum;
     
    311311//                      mangleName << "E";
    312312//              } // if
    313                 if ( type->get_lvalue() ) {
    314                         mangleName << "L";
    315                 } // if
    316313                if ( type->get_atomic() ) {
    317314                        mangleName << "A";
  • src/SymTab/Validate.cc

    r05807e9 r8b11840  
    5656#include "FixFunction.h"               // for FixFunction
    5757#include "Indexer.h"                   // for Indexer
     58#include "InitTweak/GenInit.h"         // for fixReturnStatements
    5859#include "InitTweak/InitTweak.h"       // for isCtorDtorAssign
    5960#include "Parser/LinkageSpec.h"        // for C
     
    150151        /// Replaces array and function types in forall lists by appropriate pointer type and assigns each Object and Function declaration a unique ID.
    151152        struct ForallPointerDecay final {
    152                 void previsit( ObjectDecl *object );
    153                 void previsit( FunctionDecl *func );
     153                void previsit( ObjectDecl * object );
     154                void previsit( FunctionDecl * func );
    154155        };
    155156
     
    268269                acceptAll( translationUnit, genericParams );  // check as early as possible - can't happen before LinkReferenceToTypes
    269270                acceptAll( translationUnit, epc ); // must happen before VerifyCtorDtorAssign, because void return objects should not exist
     271                acceptAll( translationUnit, fpd ); // must happen before autogenerateRoutines
    270272                VerifyCtorDtorAssign::verify( translationUnit );  // must happen before autogen, because autogen examines existing ctor/dtors
    271273                Concurrency::applyKeywords( translationUnit );
     
    275277                ReturnChecker::checkFunctionReturns( translationUnit );
    276278                mutateAll( translationUnit, compoundliteral );
    277                 acceptAll( translationUnit, fpd );
    278279                ArrayLength::computeLength( translationUnit );
    279280                acceptAll( translationUnit, finder );
     
    579580
    580581        /// Fix up assertions - flattens assertion lists, removing all trait instances
    581         void forallFixer( Type * func ) {
    582                 for ( TypeDecl * type : func->get_forall() ) {
     582        void forallFixer( std::list< TypeDecl * > & forall, BaseSyntaxNode * node ) {
     583                for ( TypeDecl * type : forall ) {
    583584                        std::list< DeclarationWithType * > asserts;
    584585                        asserts.splice( asserts.end(), type->assertions );
     
    599600                                assertion = assertion->acceptMutator( fixer );
    600601                                if ( fixer.get_isVoid() ) {
    601                                         throw SemanticError( "invalid type void in assertion of function ", func );
     602                                        throw SemanticError( "invalid type void in assertion of function ", node );
    602603                                } // if
    603604                        } // for
     
    607608
    608609        void ForallPointerDecay::previsit( ObjectDecl *object ) {
    609                 forallFixer( object->get_type() );
    610                 if ( PointerType *pointer = dynamic_cast< PointerType * >( object->get_type() ) ) {
    611                         forallFixer( pointer->get_base() );
     610                forallFixer( object->type->forall, object );
     611                if ( PointerType *pointer = dynamic_cast< PointerType * >( object->type ) ) {
     612                        forallFixer( pointer->base->forall, object );
    612613                } // if
    613614                object->fixUniqueId();
     
    615616
    616617        void ForallPointerDecay::previsit( FunctionDecl *func ) {
    617                 forallFixer( func->get_type() );
     618                forallFixer( func->type->forall, func );
    618619                func->fixUniqueId();
    619620        }
  • src/SynTree/Visitor.h

    r05807e9 r8b11840  
    2525  public:
    2626        // visit: Default implementation of all functions visits the children
    27     // of the given syntax node, but performs no other action.
     27        // of the given syntax node, but performs no other action.
    2828
    2929        virtual void visit( ObjectDecl *objectDecl );
Note: See TracChangeset for help on using the changeset viewer.