Index: src/Common/PassVisitor.h
===================================================================
--- src/Common/PassVisitor.h	(revision 53d55b68158651c2d2806af3d498cb8efd355819)
+++ src/Common/PassVisitor.h	(revision 99581ee3ebb93015c6498c2976cbb8fcb21c84b6)
@@ -360,4 +360,5 @@
 private:
 	bool inFunction = false;
+	bool atFunctionTop = false;
 
 	template<typename pass_t> friend void acceptAll( std::list< Declaration* > &decls, PassVisitor< pass_t >& visitor );
@@ -532,5 +533,5 @@
 
 	bool isInFunction() const {
-		return visitor->inFunction;
+		return visitor->isInFunction();
 	}
 };
Index: src/Common/PassVisitor.impl.h
===================================================================
--- src/Common/PassVisitor.impl.h	(revision 53d55b68158651c2d2806af3d498cb8efd355819)
+++ src/Common/PassVisitor.impl.h	(revision 99581ee3ebb93015c6498c2976cbb8fcb21c84b6)
@@ -532,8 +532,11 @@
 			indexerAddId( &func );
 			maybeAccept_impl( node->type, *this );
-			// function body needs to have the same scope as parameters - CompoundStmt will not enter
-			// a new scope if inFunction is true
+			// First remember that we are now within a function.
 			ValueGuard< bool > oldInFunction( inFunction );
 			inFunction = true;
+			// The function body needs to have the same scope as parameters.
+			// A CompoundStmt will not enter a new scope if atFunctionTop is true.
+			ValueGuard< bool > oldAtFunctionTop( atFunctionTop );
+			atFunctionTop = true;
 			maybeAccept_impl( node->statements, *this );
 			maybeAccept_impl( node->attributes, *this );
@@ -567,8 +570,11 @@
 			indexerAddId( &func );
 			maybeAccept_impl( node->type, *this );
-			// function body needs to have the same scope as parameters - CompoundStmt will not enter
-			// a new scope if inFunction is true
+			// First remember that we are now within a function.
 			ValueGuard< bool > oldInFunction( inFunction );
 			inFunction = true;
+			// The function body needs to have the same scope as parameters.
+			// A CompoundStmt will not enter a new scope if atFunctionTop is true.
+			ValueGuard< bool > oldAtFunctionTop( atFunctionTop );
+			atFunctionTop = true;
 			maybeAccept_impl( node->statements, *this );
 			maybeAccept_impl( node->attributes, *this );
@@ -601,8 +607,11 @@
 			indexerAddId( &func );
 			maybeMutate_impl( node->type, *this );
-			// function body needs to have the same scope as parameters - CompoundStmt will not enter
-			// a new scope if inFunction is true
+			// First remember that we are now within a function.
 			ValueGuard< bool > oldInFunction( inFunction );
 			inFunction = true;
+			// The function body needs to have the same scope as parameters.
+			// A CompoundStmt will not enter a new scope if atFunctionTop is true.
+			ValueGuard< bool > oldAtFunctionTop( atFunctionTop );
+			atFunctionTop = true;
 			maybeMutate_impl( node->statements, *this );
 			maybeMutate_impl( node->attributes, *this );
@@ -1007,9 +1016,9 @@
 	VISIT_START( node );
 	{
-		// do not enter a new scope if inFunction is true - needs to check old state before the assignment
-		ValueGuard< bool > oldInFunction( inFunction );
-		auto guard1 = makeFuncGuard( [this, &oldInFunction]() { if ( ! oldInFunction.old ) indexerScopeEnter(); }, [this, &oldInFunction]() { if ( ! oldInFunction.old ) indexerScopeLeave(); } );
+		// Do not enter a new scope if atFunctionTop is true, don't leave one either.
+		ValueGuard< bool > oldAtFunctionTop( atFunctionTop );
+		auto guard1 = makeFuncGuard( [this, go = !atFunctionTop]() { if ( go ) indexerScopeEnter(); }, [this, go = !atFunctionTop]() { if ( go ) indexerScopeLeave(); } );
 		auto guard2 = makeFuncGuard( [this]() { call_beginScope();   }, [this]() { call_endScope();     } );
-		inFunction = false;
+		atFunctionTop = false;
 		visitStatementList( node->kids );
 	}
@@ -1021,9 +1030,9 @@
 	VISIT_START( node );
 	{
-		// do not enter a new scope if inFunction is true - needs to check old state before the assignment
-		ValueGuard< bool > oldInFunction( inFunction );
-		auto guard1 = makeFuncGuard( [this, &oldInFunction]() { if ( ! oldInFunction.old ) indexerScopeEnter(); }, [this, &oldInFunction]() { if ( ! oldInFunction.old ) indexerScopeLeave(); } );
+		// Do not enter a new scope if atFunctionTop is true, don't leave one either.
+		ValueGuard< bool > oldAtFunctionTop( atFunctionTop );
+		auto guard1 = makeFuncGuard( [this, go = !atFunctionTop]() { if ( go ) indexerScopeEnter(); }, [this, go = !atFunctionTop]() { if ( go ) indexerScopeLeave(); } );
 		auto guard2 = makeFuncGuard( [this]() { call_beginScope();   }, [this]() { call_endScope();     } );
-		inFunction = false;
+		atFunctionTop = false;
 		visitStatementList( node->kids );
 	}
@@ -1035,9 +1044,9 @@
 	MUTATE_START( node );
 	{
-		// do not enter a new scope if inFunction is true - needs to check old state before the assignment
-		ValueGuard< bool > oldInFunction( inFunction );
-		auto guard1 = makeFuncGuard( [this, &oldInFunction]() { if ( ! oldInFunction.old ) indexerScopeEnter(); }, [this, &oldInFunction]() { if ( ! oldInFunction.old ) indexerScopeLeave(); } );
+		// Do not enter a new scope if atFunctionTop is true, don't leave one either.
+		ValueGuard< bool > oldAtFunctionTop( atFunctionTop );
+		auto guard1 = makeFuncGuard( [this, go = !atFunctionTop]() { if ( go ) indexerScopeEnter(); }, [this, go = !atFunctionTop]() { if ( go ) indexerScopeLeave(); } );
 		auto guard2 = makeFuncGuard( [this]() { call_beginScope();   }, [this]() { call_endScope();     } );
-		inFunction = false;
+		atFunctionTop = false;
 		mutateStatementList( node->kids );
 	}
