@@ -442,22 +442,28 @@ void RegistrationVisitor::caseScriptTypeDef(ASTScriptTypeDef& host, void* param)
442442void RegistrationVisitor::caseDataDeclList (ASTDataDeclList& host, void * param)
443443{
444444 // Resolve the base type.
445- DataType const & baseType = host.baseType ->resolve (*scope, this );
445+ DataType const * baseType = host.baseType ->resolve_ornull (*scope, this );
446446 if (breakRecursion (*host.baseType .get ())) return ;
447- if (!host.baseType ->wasResolved ()) return ;
447+ if (!host.baseType ->wasResolved () || !baseType ) return ;
448448
449449 // Don't allow void type.
450- if (baseType == DataType::ZVOID )
450+ if (baseType-> isVoid () )
451451 {
452- handleError (CompileError::VoidVar (&host, host.asString ()));
452+ handleError (CompileError::BadVarType (&host, host.asString (), baseType-> getName ()));
453453 doRegister (host);
454454 return ;
455455 }
456-
456+
457+ if (baseType->isAuto () && host.getDeclarations ().size () > 1 )
458+ {
459+ handleError (CompileError::GroupAuto (&host));
460+ return ;
461+ }
462+
457463 // Check for disallowed global types.
458- if (scope->isGlobal () && !baseType. canBeGlobal ())
464+ if (scope->isGlobal () && !baseType-> canBeGlobal ())
459465 {
460- handleError (CompileError::RefVar (&host, baseType. getName ()));
466+ handleError (CompileError::RefVar (&host, baseType-> getName ()));
461467 doRegister (host);
462468 return ;
463469 }
@@ -471,22 +477,22 @@ void RegistrationVisitor::caseDataDeclList(ASTDataDeclList& host, void* param)
471477void RegistrationVisitor::caseDataEnum (ASTDataEnum& host, void * param)
472478{
473479 // Resolve the base type.
474- DataType const & baseType = host.baseType ->resolve (*scope, this );
480+ DataType const * baseType = host.baseType ->resolve_ornull (*scope, this );
475481 if (breakRecursion (*host.baseType .get ())) return ;
476- if (!baseType. isResolved () ) return ;
482+ if (!baseType) return ;
477483
478- // Don't allow void type .
479- if (baseType == DataType::ZVOID )
484+ // Don't allow void/auto types .
485+ if (baseType-> isVoid () || baseType-> isAuto () )
480486 {
481- handleError (CompileError::VoidVar (&host, host.asString ()));
487+ handleError (CompileError::BadVarType (&host, host.asString (), baseType-> getName ()));
482488 doRegister (host);
483489 return ;
484490 }
485491
486492 // Check for disallowed global types.
487- if (scope->isGlobal () && !baseType. canBeGlobal ())
493+ if (scope->isGlobal () && !baseType-> canBeGlobal ())
488494 {
489- handleError (CompileError::RefVar (&host, baseType. getName ()));
495+ handleError (CompileError::RefVar (&host, baseType-> getName ()));
490496 doRegister (host);
491497 return ;
492498 }
@@ -532,29 +538,51 @@ void RegistrationVisitor::caseDataDecl(ASTDataDecl& host, void* param)
532538 if (breakRecursion (host)) return ;
533539 if (!(registered (host, host.extraArrays ) && (!host.getInitializer () || registered (host.getInitializer ())))) return ;
534540 // Then resolve the type.
535- DataType const & type = host.resolveType (scope, this );
541+ DataType const * type = host.resolve_ornull (scope, this );
536542 if (breakRecursion (host)) return ;
537- if (!type. isResolved () ) return ;
543+ if (!type) return ;
538544
539545 doRegister (host);
540546
541547 // Don't allow void type.
542- if (type == DataType::ZVOID )
548+ if (type-> isVoid () )
543549 {
544- handleError (CompileError::VoidVar (&host, host.name ));
550+ handleError (CompileError::BadVarType (&host, host.name , type-> getName () ));
545551 return ;
546552 }
553+
554+ if (type->isAuto ())
555+ {
556+ bool good = false ;
557+ auto init = host.getInitializer ();
558+ if (init)
559+ {
560+ auto readty = init->getReadType (scope, this );
561+ if (readty && readty->isResolved () && !readty->isVoid () && !readty->isAuto ())
562+ {
563+ auto newty = type->isConstant () ? readty->getConstType () : readty->getMutType ();
564+ host.replaceType (*newty);
565+ type = host.resolve_ornull (scope, this );
566+ good = true ;
567+ }
568+ }
569+ if (!good)
570+ {
571+ handleError (CompileError::BadAutoType (&host));
572+ return ;
573+ }
574+ }
547575
548576 // Check for disallowed global types.
549- if (scope->isGlobal () && !type. canBeGlobal ())
577+ if (scope->isGlobal () && !type-> canBeGlobal ())
550578 {
551579 handleError (CompileError::RefVar (
552- &host, type. getName () + " " + host.name ));
580+ &host, type-> getName () + " " + host.name ));
553581 return ;
554582 }
555583
556584 // Currently disabled syntaxes:
557- if (getArrayDepth (type) > 1 )
585+ if (getArrayDepth (* type) > 1 )
558586 {
559587 handleError (CompileError::UnimplementedFeature (
560588 &host, " Nested Array Declarations" ));
@@ -563,7 +591,7 @@ void RegistrationVisitor::caseDataDecl(ASTDataDecl& host, void* param)
563591
564592 // Is it a constant?
565593 bool isConstant = false ;
566- if (type. isConstant ())
594+ if (type-> isConstant ())
567595 {
568596 // A constant without an initializer doesn't make sense.
569597 if (!host.getInitializer ())
@@ -599,13 +627,13 @@ void RegistrationVisitor::caseDataDecl(ASTDataDecl& host, void* param)
599627 }
600628
601629 int32_t value = *host.getInitializer ()->getCompileTimeValue (this , scope);
602- Constant::create (*scope, host, type, value, this );
630+ Constant::create (*scope, host, * type, value, this );
603631 }
604632 else
605633 {
606634 if (parsing_user_class == puc_vars)
607635 {
608- UserClassVar::create (*scope, host, type, this );
636+ UserClassVar::create (*scope, host, * type, this );
609637 }
610638 else
611639 {
@@ -615,7 +643,7 @@ void RegistrationVisitor::caseDataDecl(ASTDataDecl& host, void* param)
615643 return ;
616644 }
617645
618- Variable::create (*scope, host, type, this );
646+ Variable::create (*scope, host, * type, this );
619647 }
620648 }
621649}
@@ -701,6 +729,12 @@ void RegistrationVisitor::caseFuncDecl(ASTFuncDecl& host, void* param)
701729 DataType const & returnType = host.returnType ->resolve (*scope, this );
702730 if (breakRecursion (*host.returnType .get ())) {scope = oldScope; return ;}
703731 if (!returnType.isResolved ()) {scope = oldScope; return ;}
732+ if (returnType.isAuto ())
733+ {
734+ handleError (CompileError::BadReturnType (&host, returnType.getName ()));
735+ scope = oldScope;
736+ return ;
737+ }
704738
705739 // Gather the parameter types.
706740 vector<DataType const *> paramTypes;
@@ -712,20 +746,20 @@ void RegistrationVisitor::caseFuncDecl(ASTFuncDecl& host, void* param)
712746 ASTDataDecl& decl = **it;
713747
714748 // Resolve the parameter type under current scope.
715- DataType const & type = decl.resolveType (scope, this );
749+ DataType const * type = decl.resolve_ornull (scope, this );
716750 if (breakRecursion (decl)) {scope = oldScope; return ;}
717- if (!type. isResolved () ) {scope = oldScope; return ;}
751+ if (!type) {scope = oldScope; return ;}
718752
719- // Don't allow void params.
720- if (type == DataType::ZVOID )
753+ // Don't allow void/auto params.
754+ if (type-> isVoid () || type-> isAuto () )
721755 {
722- handleError (CompileError::FunctionVoidParam (&decl, decl.name ));
756+ handleError (CompileError::FunctionBadParamType (&decl, decl.name , type-> getName () ));
723757 doRegister (host);
724758 scope = oldScope;
725759 return ;
726760 }
727761 paramNames.push_back (new string (decl.name ));
728- paramTypes.push_back (& type);
762+ paramTypes.push_back (type);
729763 }
730764 if (host.prototype )
731765 {
0 commit comments