src/compiler/NameBinding.cpp
author David Anderson <dvander@alliedmods.net>
Sat Nov 17 23:11:38 2012 -0800 (2012-11-17)
changeset 209 5cbec15fadfe
parent 208 7c5be05296e3
child 212 443d24cfdf2d
permissions -rw-r--r--
Split ArrayType from Type.
     1 /* vim: set ts=4 sw=4 tw=99 et:
     2  *
     3  * Copyright (C) 2012 David Anderson
     4  *
     5  * This file is part of SourcePawn.
     6  *
     7  * SourcePawn is free software: you can redistribute it and/or modify it under
     8  * the terms of the GNU General Public License as published by the Free
     9  * Software Foundation, either version 3 of the License, or (at your option)
    10  * any later version.
    11  * 
    12  * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
    13  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    14  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
    15  *
    16  * You should have received a copy of the GNU General Public License along with
    17  * SourcePawn. If not, see http://www.gnu.org/licenses/.
    18  */
    19 #include "../Strings.h"
    20 #include "../Zone.h"
    21 #include "../TypeManager.h"
    22 #include "NameBinding.h"
    23 #include "Scopes.h"
    24 #include "ConstantEvaluator.h"
    25 #include "../Spaces-inl.h"
    26 #include "../Heap-inl.h"
    27 
    28 using namespace ke;
    29 
    30 // Create symbol tables and symbols for every scope and declaration. For type
    31 // declarations and methods, we also pre-allocate a Type object, so that
    32 // circular dependencies between types will work.
    33 class NamePopulator : public AstVisitor
    34 {
    35   private:
    36     // This class is analagous to a Scope, however, it allows us to create
    37     // scopes lazily. If a scope is requested, and the current environment
    38     // has no scope, then a scope is created. If no scope is ever requested,
    39     // a scope does not need to be created.
    40     class SymbolEnv
    41     {
    42       public:
    43         SymbolEnv(SymbolEnv **prevp, Scope *scope = NULL)
    44           : envp_(prevp),
    45             prev_(*prevp),
    46             scope_(scope)
    47         {
    48             *envp_ = this;
    49         }
    50         ~SymbolEnv() {
    51             *envp_ = prev_;
    52         }
    53 
    54         Scope *scope() {
    55             return scope_;
    56         }
    57         void setScope(Scope *scope) {
    58             assert(!scope_);
    59             scope_ = scope;
    60         }
    61         SymbolEnv *prev() const {
    62             return prev_;
    63         }
    64 
    65       private:
    66         SymbolEnv **envp_;
    67         SymbolEnv *prev_;
    68         Scope *scope_;
    69     };
    70 
    71     enum ReturnStatus {
    72         NoReturn,
    73         VoidReturn,
    74         ValueReturn
    75     };
    76 
    77     class FunctionScope
    78     {
    79       public:
    80         FunctionScope(FunctionScope **prevp)
    81           : prevp_(prevp),
    82             prev_(*prevp),
    83             status_(NoReturn)
    84         {
    85             *prevp_ = this;
    86         }
    87         ~FunctionScope() {
    88             *prevp_ = prev_;
    89         }
    90         ReturnStatus returns() const {
    91             return status_;
    92         }
    93         void returns(ReturnStatus status) {
    94             if (status > status_)
    95                 status_ = status;
    96         }
    97       private:
    98         FunctionScope **prevp_;
    99         FunctionScope *prev_;
   100         ReturnStatus status_;
   101     };
   102 
   103   public:
   104     NamePopulator(Zone *zone, CompileContext &cc, TranslationUnit *unit)
   105       : zone_(zone),
   106         pool_(zone->pool()),
   107         cc_(cc),
   108         unit_(unit),
   109         env_(NULL),
   110         fun_(NULL)
   111     {
   112     }
   113 
   114     bool analyze() {
   115         ImportScope *importScope = ImportScope::New(pool_);
   116         if (!importScope)
   117             return false;
   118 
   119         // At the import level, we declare system types.
   120         if (!declareSystemTypes(importScope))
   121             return false;
   122 
   123         GlobalScope *globalScope = GlobalScope::New(pool_, importScope);
   124         if (!globalScope)
   125             return false;
   126 
   127         unit_->setImportScope(importScope);
   128         unit_->setGlobalScope(globalScope);
   129 
   130         SymbolEnv env(&env_, globalScope);
   131 
   132         for (size_t i = 0; i < unit_->tree()->statements()->length(); i++) {
   133             Statement *stmt = unit_->tree()->statements()->at(i);
   134             stmt->accept(this);
   135         }
   136 
   137         return true;
   138     }
   139 
   140     bool declareSystemType(ImportScope *scope, const char *name, Handle<Type> type) {
   141         Local<String> tag(zone_, zone_->makeSymbol(name));
   142         if (!tag)
   143             return false;
   144 
   145         TypeSymbol *sym = new (pool_) TypeSymbol(scope, tag, type);
   146         return scope->addSymbol(sym);
   147     }
   148 
   149     bool declareSystemType(ImportScope *scope, const char *name, PrimitiveType prim) {
   150         Local<Type> primitive(zone_, zone_->types()->getPrimitive(prim));
   151         assert(primitive);
   152         return declareSystemType(scope, name, primitive);
   153     }
   154 
   155     bool declareSystemTypes(ImportScope *scope) {
   156         if (!declareSystemType(scope, "float", PrimitiveType_Float))
   157             return false;
   158         if (!declareSystemType(scope, "_", PrimitiveType_Int32))
   159             return false;
   160         if (!declareSystemType(scope, "int", PrimitiveType_Int32))
   161             return false;
   162         if (!declareSystemType(scope, "bool", PrimitiveType_Bool))
   163             return false;
   164         if (!declareSystemType(scope, "char", PrimitiveType_Char))
   165             return false;
   166 
   167         Local<Type> voidType(zone_, zone_->types()->getVoid());
   168         if (!declareSystemType(scope, "void", voidType))
   169             return false;
   170 
   171         return true;
   172     }
   173 
   174     void visitVariableDeclaration(VariableDeclaration *node) {
   175         Scope *scope = env_->scope();
   176         if (!scope || scope->kind() != Scope::GLOBAL) {
   177             if ((scope = getOrCreateBlockScope()) == NULL)
   178                 return;
   179         }
   180 
   181         if (scope->kind() == Scope::GLOBAL) {
   182             // The symbol must be added now, since it could be an export.
   183             VariableSymbol *sym = new (pool_) VariableSymbol(scope, node->name(), node->pos());
   184             node->setSymbol(sym);
   185 
   186             if (!registerName(scope, sym))
   187                 return;
   188         } else {
   189             // We ensure the scope will exist at the name binding phase, but
   190             // we don't actually register the variable symbol yet. Otherwise,
   191             // when binding the initializer, we could encounter:
   192             //    new x = x;
   193             //
   194             // And we don't necessarily want this to bind.
   195         }
   196 
   197         node->initialization()->accept(this);
   198     }
   199     void visitEnumStatement(EnumStatement *node) {
   200         assert(false);
   201     }
   202     void visitFunctionStatement(FunctionStatement *node) {
   203         // We create function types ahead of time, not for any particular
   204         // reason. It makes things consistent with FunctionTypeStatement,
   205         // which actually does produce a type.
   206         Local<FunctionType> type(zone_, FunctionType::New(zone_, node->token()));
   207         if (!type)
   208             return;
   209 
   210         assert(env_->scope());
   211 
   212         // Function statements are always named, so add the name to the outer scope.
   213         FunctionSymbol *sym = new (pool_) FunctionSymbol(env_->scope(), node->name(), node->pos(), type);
   214         if (!registerName(env_->scope(), sym))
   215             return;
   216 
   217         if (node->token() == TOK_PUBLIC ||
   218             node->token() == TOK_FORWARD ||
   219             node->token() == TOK_NATIVE)
   220         {
   221             // We're in the global scope, for sure.
   222             assert(env_->scope()->kind() == Scope::GLOBAL);
   223             GlobalScope *globals = (GlobalScope *)env_->scope();
   224             if (!globals->addPublic(sym))
   225                 return;
   226         }
   227 
   228         node->setSymbol(sym);
   229 
   230         // Scope for the function's arguments.
   231         SymbolEnv argEnv(&env_);
   232         if (!registerArguments(node->signature()))
   233             return;
   234 
   235         // Scope for function body.
   236         SymbolEnv localEnv(&env_);
   237         FunctionScope fun(&fun_);
   238         if (node->body())
   239             node->body()->accept(this);
   240 
   241         // Function statements have quirky semantics around their return
   242         // type. For reasonable compatibility with SP1, we use the following
   243         // heuristics for when no explicit type is declared.
   244         if (!node->signature().returnType()) {
   245             Local<Type> type(zone_);
   246             if (node->token() == TOK_FORWARD || node->token() == TOK_NATIVE) {
   247                 // If the function type is a native or forward, we always
   248                 // assume it returns an int32.
   249                 type = zone_->types()->getPrimitive(PrimitiveType_Int32);
   250             } else if (fun.returns() != ValueReturn) {
   251                 // This function never returns a value, so mark it as
   252                 // returning void.
   253                 type = zone_->types()->getVoid();
   254             }
   255             // No need to NULL check here, we'll catch OOM later.
   256             node->sym()->type()->setReturnType(type);
   257         }
   258 
   259         node->setScopes(argEnv.scope(), localEnv.scope());
   260     }
   261     void visitStructureStatement(StructureStatement *node) {
   262         assert(false);
   263     }
   264     void visiFunctionTypeStatementt(FunctionTypeStatement *node) {
   265         assert(false);
   266     }
   267 
   268     void visitNameProxy(NameProxy *name) {
   269     }
   270     void visitAssignment(Assignment *node) {
   271         node->lvalue()->accept(this);
   272         node->expression()->accept(this);
   273     }
   274     void visitBinaryExpression(BinaryExpression *node) {
   275         node->left()->accept(this);
   276         node->right()->accept(this);
   277     }
   278     void visitReturnStatement(ReturnStatement *node) {
   279         if (node->expression())
   280             fun_->returns(ValueReturn);
   281         else
   282             fun_->returns(VoidReturn);
   283     }
   284     void visitForStatement(ForStatement *node) {
   285         SymbolEnv env(&env_);
   286 
   287         if (node->initialization())
   288             node->initialization()->accept(this);
   289         if (node->condition())
   290             node->condition()->accept(this);
   291         if (node->update())
   292             node->update()->accept(this);
   293         node->body()->accept(this);
   294 
   295         node->setScope(env.scope());
   296     }
   297     void visitBlockStatement(BlockStatement *node) {
   298         SymbolEnv env(&env_);
   299 
   300         for (size_t i = 0; i < node->statements()->length(); i++)
   301             node->statements()->at(i)->accept(this);
   302 
   303         node->setScope(env.scope());
   304     }
   305     void visitIntegerLiteral(IntegerLiteral *node) {
   306     }
   307     void visitExpressionStatement(ExpressionStatement *node) {
   308         node->expression()->accept(this);
   309     }
   310     void visitCallExpression(CallExpression *node) {
   311         node->callee()->accept(this);
   312         for (size_t i = 0; i < node->arguments()->length(); i++)
   313             node->arguments()->at(i)->accept(this);
   314     }
   315     void visitIfStatement(IfStatement *node) {
   316         node->ifTrue()->accept(this);
   317         if (node->ifFalse())
   318             node->ifFalse()->accept(this);
   319     }
   320     void visitIndexExpression(IndexExpression *node) {
   321         assert(false);
   322     }
   323     void visitFloatLiteral(FloatLiteral *node) {
   324     }
   325     void visitWhileStatement(WhileStatement *node) {
   326         node->condition()->accept(this);
   327         node->body()->accept(this);
   328     }
   329     void visitBreakStatement(BreakStatement *node) {
   330     }
   331     void visitContinueStatement(ContinueStatement *node) {
   332     }
   333     void visitStringLiteral(StringLiteral *node) {
   334     }
   335     void visitIncDecExpression(IncDecExpression *node) {
   336         assert(false);
   337     }
   338     void visitUnaryExpression(UnaryExpression *node) {
   339         assert(false);
   340     }
   341     void visitTernaryExpression(TernaryExpression *node) {
   342         assert(false);
   343     }
   344     void visitBooleanLiteral(BooleanLiteral *node) {
   345     }
   346     void visitFieldExpression(FieldExpression *node) {
   347     }
   348     void visitSwitchStatement(SwitchStatement *node) {
   349         if (node->defaultCase())
   350             node->defaultCase()->accept(this);
   351 
   352         for (size_t i = 0; i < node->cases()->length(); i++)
   353             node->cases()->at(i)->statement()->accept(this);
   354     }
   355     void visitArrayLiteral(ArrayLiteral *node) {
   356     }
   357     void visitImportStatement(ImportStatement *node) {
   358     }
   359 
   360   private:
   361     Scope *getOrCreateBlockScope() {
   362         if (env_->scope()) {
   363             assert(env_->scope()->kind() == Scope::BLOCK);
   364             return env_->scope();
   365         }
   366         
   367         LocalScope *scope = LocalScope::New(pool_);
   368         if (!scope)
   369             return NULL;
   370 
   371         env_->setScope(scope);
   372         return scope;
   373     }
   374 
   375     bool registerName(Scope *scope, Symbol *sym) {
   376         if (!scope)
   377             return false;
   378 
   379         if (Symbol *other = scope->localLookup(sym->name())) {
   380             // Report, but allow errors to continue.
   381             cc_.reportError(sym->pos(), Message_RedeclaredName,
   382                             sym->name()->chars(),
   383                             other->pos().line,
   384                             other->pos().col);
   385             return true;
   386         }
   387 
   388         return scope->addSymbol(sym);
   389     }
   390 
   391     bool registerArguments(const FunctionSignature &sig) {
   392         if (!sig.parameters()->length())
   393             return true;
   394 
   395         ArgumentScope *argScope = ArgumentScope::New(pool_);
   396         if (!argScope)
   397             return false;
   398         env_->setScope(argScope);
   399 
   400         for (size_t i = 0; i < sig.parameters()->length(); i++) {
   401             Parameter *param = sig.parameters()->at(i);
   402             VariableSymbol *sym = new (pool_) VariableSymbol(argScope, param->name(), param->pos());
   403             if (!registerName(env_->scope(), sym))
   404                 return false;
   405             param->setSymbol(sym);
   406         }
   407 
   408         return true;
   409     }
   410 
   411   private:
   412     Zone *zone_;
   413     PoolAllocator &pool_;
   414     CompileContext &cc_;
   415     TranslationUnit *unit_;
   416     SymbolEnv *env_;
   417     FunctionScope *fun_;
   418 };
   419 
   420 bool
   421 ke::PopulateNamesAndTypes(Zone *zone, CompileContext &cc, TranslationUnit *unit)
   422 {
   423     NamePopulator populator(zone, cc, unit);
   424     return populator.analyze();
   425 }
   426 
   427 class NameBinder : public AstVisitor
   428 {
   429   public:
   430     class AutoLinkScope
   431     {
   432       public:
   433         AutoLinkScope(AutoLinkScope **prevp, Scope *scope)
   434           : prevp_(prevp),
   435             prev_(*prevp),
   436             scope_(scope)
   437         {
   438             if (scope_) {
   439                 *prevp_ = this;
   440                 if (prev_)
   441                     scope_->setParent(prev_->scope());
   442             }
   443         }
   444         ~AutoLinkScope() {
   445             if (scope_) {
   446                 assert(*prevp_ == this);
   447                 *prevp_ = prev_;
   448             }
   449         }
   450         Scope *scope() const {
   451             return scope_;
   452         }
   453 
   454       private:
   455         AutoLinkScope **prevp_;
   456         AutoLinkScope *prev_;
   457         Scope *scope_;
   458     };
   459 
   460   public:
   461     NameBinder(Zone *zone, CompileContext &cc, TranslationUnit *unit)
   462       : zone_(zone),
   463         pool_(zone->pool()),
   464         cc_(cc),
   465         unit_(unit),
   466         link_(NULL)
   467     {
   468     }
   469 
   470     bool bind() {
   471         // Start with the import scope, and collect all imported names.
   472         AutoLinkScope importScope(&link_, unit_->importScope());
   473 
   474         for (size_t i = 0; i < unit_->tree()->imports()->length(); i++)
   475             unit_->tree()->imports()->at(i)->accept(this);
   476 
   477         // Next, enter the global scope and walk all statements.
   478         AutoLinkScope globalScope(&link_, unit_->globalScope());
   479         for (size_t i = 0; i < unit_->tree()->statements()->length(); i++) {
   480             Statement *stmt = unit_->tree()->statements()->at(i);
   481             stmt->accept(this);
   482         }
   483 
   484         return true;
   485     }
   486 
   487     void visitVariableDeclaration(VariableDeclaration *node) {
   488         // Bind the initializer before registering the declaration, so that we
   489         // can error on bogus initializers (new x = x).
   490         node->initialization()->accept(this);
   491 
   492         Local<Type> type(zone_, bindType(node->type()));
   493         if (!type)
   494             return;
   495 
   496         if (node->dims()) {
   497             
   498         }
   499 
   500         // If the node already has a symbol (meaning it was a global), then
   501         // we don't have to do anything more.
   502         if (node->sym()) {
   503             assert(node->sym()->scope()->kind() == Scope::GLOBAL);
   504             node->sym()->setType(type);
   505             return;
   506         }
   507 
   508         VariableSymbol *sym = new (pool_) VariableSymbol(link_->scope(), node->name(), node->pos(), type);
   509         node->setSymbol(sym);
   510        
   511         if (Symbol *other = link_->scope()->localLookup(sym->name())) {
   512             // Report, but allow errors to continue.
   513             cc_.reportError(sym->pos(), Message_RedeclaredName,
   514                             sym->name()->chars(),
   515                             other->pos().line,
   516                             other->pos().col);
   517             return;
   518         }
   519         
   520         if (link_->scope()->addSymbol(sym))
   521             return;
   522     }
   523     void visitEnumStatement(EnumStatement *node) {
   524         assert(false);
   525     }
   526     void visitFunctionStatement(FunctionStatement *node) {
   527         AutoLinkScope argScope(&link_, node->argScope());
   528         AutoLinkScope varScope(&link_, node->varScope());
   529 
   530         Local<FunctionType> type(zone_, node->sym()->type());
   531         if (!fillFunctionType(type, node->signature()))
   532             return;
   533 
   534         if (node->body())
   535             node->body()->accept(this);
   536     }
   537     void visitStructureStatement(StructureStatement *node) {
   538         assert(false);
   539     }
   540     void visitFunctionTypeStatement(FunctionTypeStatement *node) {
   541         assert(false);
   542     }
   543 
   544     void visitNameProxy(NameProxy *proxy) {
   545         Scope *scope = link_->scope();
   546         Symbol *sym = scope->lookup(proxy->name());
   547         if (!sym)
   548             cc_.reportError(proxy->pos(), Message_IdentifierNotFound, proxy->name()->chars());
   549         proxy->bind(sym);
   550     }
   551     void visitAssignment(Assignment *node) {
   552         node->lvalue()->accept(this);
   553         node->expression()->accept(this);
   554     }
   555     void visitBinaryExpression(BinaryExpression *node) {
   556         node->left()->accept(this);
   557         node->right()->accept(this);
   558     }
   559     void visitReturnStatement(ReturnStatement *node) {
   560         node->expression()->accept(this);
   561     }
   562     void visitForStatement(ForStatement *node) {
   563         AutoLinkScope scope(&link_, node->scope());
   564 
   565         if (node->initialization())
   566             node->initialization()->accept(this);
   567         if (node->condition())
   568             node->condition()->accept(this);
   569         if (node->update())
   570             node->update()->accept(this);
   571         node->body()->accept(this);
   572     }
   573     void visitBlockStatement(BlockStatement *node) {
   574         AutoLinkScope scope(&link_, node->scope());
   575         for (size_t i = 0; i < node->statements()->length(); i++)
   576             node->statements()->at(i)->accept(this);
   577     }
   578     void visitIntegerLiteral(IntegerLiteral *node) {
   579     }
   580     void visitExpressionStatement(ExpressionStatement *node) {
   581         node->expression()->accept(this);
   582     }
   583     void visitCallExpression(CallExpression *node) {
   584         node->callee()->accept(this);
   585         for (size_t i = 0; i < node->arguments()->length(); i++)
   586             node->arguments()->at(i)->accept(this);
   587     }
   588     void visitIfStatement(IfStatement *node) {
   589         node->condition()->accept(this);
   590         node->ifTrue()->accept(this);
   591         if (node->ifFalse())
   592             node->ifFalse()->accept(this);
   593     }
   594     void visitIndexExpression(IndexExpression *node) {
   595         node->left()->accept(this);
   596         node->right()->accept(this);
   597     }
   598     void visitFloatLiteral(FloatLiteral *node) {
   599     }
   600     void visitWhileStatement(WhileStatement *node) {
   601         node->condition()->accept(this);
   602         node->body()->accept(this);
   603     }
   604     void visitBreakStatement(BreakStatement *node) {
   605     }
   606     void visitContinueStatement(ContinueStatement *node) {
   607     }
   608     void visitStringLiteral(StringLiteral *node) {
   609     }
   610     void visitIncDecExpression(IncDecExpression *node) {
   611         node->expression()->accept(this);
   612     }
   613     void visitUnaryExpression(UnaryExpression *node) {
   614         if (node->tag())
   615             node->tag()->accept(this);
   616         node->expression()->accept(this);
   617     }
   618     void visitTernaryExpression(TernaryExpression *node) {
   619         node->condition()->accept(this);
   620         node->left()->accept(this);
   621         node->right()->accept(this);
   622     }
   623     void visitBooleanLiteral(BooleanLiteral *node) {
   624     }
   625     void visitFieldExpression(FieldExpression *node) {
   626         node->left()->accept(this);
   627     }
   628     void visitSwitchStatement(SwitchStatement *node) {
   629         node->expression()->accept(this);
   630         node->defaultCase()->accept(this);
   631         for (size_t i = 0; i < node->cases()->length(); i++) {
   632             // We don't test case expressions because they are literals.
   633             Case *c = node->cases()->at(i);
   634             c->statement()->accept(this);
   635         }
   636     }
   637     void visitArrayLiteral(ArrayLiteral *node) {
   638         for (size_t i = 0; i < node->expressions()->length(); i++)
   639             node->expressions()->at(i)->accept(this);
   640     }
   641     void visitImportStatement(ImportStatement *node) {
   642         if (node->suffix() == TOK_STAR) {
   643             // Import every name.
   644             assert(false);
   645         } else {
   646             GlobalScope *other = node->source()->globalScope();
   647             Symbol *sym = other->findPublic(node->name());
   648             if (!sym) {
   649                 cc_.reportError(node->pos(), Message_CannotResolveImport, node->name()->chars());
   650                 return;
   651             }
   652             link_->scope()->addSymbol(sym);
   653         }
   654     }
   655 
   656   private:
   657     bool fillFunctionType(Handle<FunctionType> fun, const FunctionSignature &sig) {
   658         Local<Type> type(zone_);
   659         if (!fun->returnType()) {
   660             if ((type = bindType(sig.returnType())) == NULL)
   661                 return false;
   662             fun->setReturnType(type);
   663         }
   664 
   665         Local<FixedArray> params(zone_, FixedArray::New(zone_, sig.parameters()->length(), Heap::Tenure_Old));
   666         if (!params)
   667             return false;
   668 
   669         for (size_t i = 0; i < sig.parameters()->length(); i++) {
   670             Parameter *param = sig.parameters()->at(i);
   671             if ((type = bindType(param->type())) == NULL)
   672                 return false;
   673             params->set(zone_, i, type);
   674         }
   675 
   676         fun->setParameterTypes(params);
   677 
   678         return true;
   679     }
   680 
   681     Type *bindType(Expression *expr) {
   682         if (!expr) {
   683             // If no type was declared, we return int32.
   684             return zone_->types()->getPrimitive(PrimitiveType_Int32);
   685         }
   686         
   687         expr->accept(this);
   688 
   689         NameProxy *proxy = expr->asNameProxy();
   690         assert(proxy);
   691 
   692         Symbol *sym = proxy->sym();
   693         if (!sym)
   694             return NULL;
   695 
   696         if (!sym->isType()) {
   697             cc_.reportError(expr->pos(), Message_IdentifierIsNotAType, sym->name()->chars());
   698             return NULL;
   699         }
   700 
   701         return sym->type();
   702     }
   703 
   704   private:
   705     Zone *zone_;
   706     PoolAllocator &pool_;
   707     CompileContext &cc_;
   708     TranslationUnit *unit_;
   709     AutoLinkScope *link_;
   710 };
   711 
   712 bool
   713 ke::BindNamesAndTypes(Zone *zone, CompileContext &cc, TranslationUnit *unit)
   714 {
   715     NameBinder binder(zone, cc, unit);
   716     return binder.bind();
   717 }