Index: src/Validate/FindSpecialDecls.h
===================================================================
--- src/Validate/FindSpecialDecls.h	(revision 5339a87ca7689b734a2eb1d355830ea9713784a1)
+++ src/Validate/FindSpecialDecls.h	(revision ce36b5519dcfbed597a596a468dc1684221e78ab)
@@ -9,7 +9,7 @@
 // Author           : Rob Schluntz
 // Created On       : Thu Aug 30 09:49:02 2018
-// Last Modified By : Rob Schluntz
-// Last Modified On : Thu Aug 30 09:51:12 2018
-// Update Count     : 2
+// Last Modified By : Andrew Beach
+// Last Modified On : Wed Nov 10 15:16:00 2021
+// Update Count     : 3
 //
 
@@ -22,4 +22,8 @@
 class StructDecl;
 class Type;
+
+namespace ast {
+	class TranslationUnit;
+}
 
 namespace Validate {
@@ -38,4 +42,9 @@
 	/// find and remember some of the special declarations that are useful for generating code, so that they do not have to be discovered multiple times.
 	void findSpecialDecls( std::list< Declaration * > & translationUnit );
+
+/// find and remember some of the special declarations that are useful for
+/// generating code, so that they do not have to be discovered multiple times.
+void findGlobalDecls( ast::TranslationUnit & translationUnit );
+
 } // namespace Validate
 
Index: src/Validate/FindSpecialDeclsNew.cpp
===================================================================
--- src/Validate/FindSpecialDeclsNew.cpp	(revision ce36b5519dcfbed597a596a468dc1684221e78ab)
+++ src/Validate/FindSpecialDeclsNew.cpp	(revision ce36b5519dcfbed597a596a468dc1684221e78ab)
@@ -0,0 +1,93 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// FindSpecialDeclsNew.cpp -- Find special declarations used in the compiler.
+//
+// Author           : Andrew Beach
+// Created On       : Wed Nov 10 13:51:00 2021
+// Last Modified By : Andrew Beach
+// Last Modified On : Wed Nov 10 15:22:00 2021
+// Update Count     : 0
+//
+
+#include "Validate/FindSpecialDecls.h"
+
+#include "AST/Decl.hpp"
+#include "AST/Pass.hpp"
+#include "AST/TranslationUnit.hpp"
+
+// NOTE: currently, it is assumed that every special declaration occurs at the
+// top-level, so function bodies, aggregate bodies, object initializers, etc.
+// are not visited. If this assumption changes, e.g., with the introduction
+// of namespaces, remove the visit_children assignments.
+
+namespace Validate {
+
+namespace {
+
+struct FindDeclsCore : public ast::WithShortCircuiting {
+	ast::TranslationUnit::Global & global;
+	FindDeclsCore( ast::TranslationUnit::Global & g ) : global( g ) {}
+
+	void previsit( const ast::Decl * decl );
+	void previsit( const ast::FunctionDecl * decl );
+	void previsit( const ast::StructDecl * decl );
+};
+
+void FindDeclsCore::previsit( const ast::Decl * ) {
+	visit_children = false;
+}
+
+void FindDeclsCore::previsit( const ast::FunctionDecl * decl ) {
+	visit_children = false;
+	if ( !global.dereference && decl->name == "*?" ) {
+		const ast::FunctionType * type = decl->type.get();
+		if ( decl->linkage == ast::Linkage::Intrinsic && type->params.size() == 1 ) {
+			const ast::PointerType * ptrType = type->params.front().strict_as<ast::PointerType>();
+			ast::ptr<ast::Type> baseType = ptrType->base;
+			if ( baseType->qualifiers == ast::CV::Qualifiers() ) {
+				const ast::TypeInstType * inst = baseType.as<ast::TypeInstType>();
+				if ( inst || inst->kind != ast::TypeDecl::Ftype ) {
+					global.dereference = decl;
+				}
+			}
+		}
+	} else if ( !global.dtorDestroy && decl->name == "__destroy_Destructor" ) {
+		global.dtorDestroy = decl;
+	}
+}
+
+void FindDeclsCore::previsit( const ast::StructDecl * decl ) {
+	visit_children = false;
+	if ( !global.dtorStruct && decl->name == "__Destructor" ) {
+		global.dtorStruct = decl;
+	}
+}
+
+} // namespace
+
+// Fill the TranslationUnit's dereference, dtorStruct and dtorDestroy fields.
+void findGlobalDecls( ast::TranslationUnit & translationUnit ) {
+	ast::Pass<FindDeclsCore>::run( translationUnit, translationUnit.global );
+
+	// TODO: When everything gets the globals from the translation unit,
+	// remove these.
+	ast::dereferenceOperator = translationUnit.global.dereference;
+	ast::dtorStruct = translationUnit.global.dtorStruct;
+	ast::dtorStructDestroy = translationUnit.global.dtorDestroy;
+
+	// TODO: conditionally generate 'fake' declarations for missing features,
+	// so that translation can proceed in the event that builtins, prelude,
+	// etc. are missing.
+}
+
+} // namespace Validate
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/Validate/InitializerLength.cpp
===================================================================
--- src/Validate/InitializerLength.cpp	(revision ce36b5519dcfbed597a596a468dc1684221e78ab)
+++ src/Validate/InitializerLength.cpp	(revision ce36b5519dcfbed597a596a468dc1684221e78ab)
@@ -0,0 +1,65 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2018 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// InitializerLength.cpp -- Calculate the length of arrays from initializers.
+//
+// Author           : Andrew Beach
+// Created On       : Fri Nov 12 11:46:00 2021
+// Last Modified By : Andrew Beach
+// Last Modified On : Fri Nov 12 13:35:00 2021
+// Update Count     : 0
+//
+
+//#include "InitializerLength.hpp"
+
+#include "AST/Expr.hpp"
+#include "AST/Decl.hpp"
+#include "AST/Pass.hpp"
+#include "AST/TranslationUnit.hpp"
+
+namespace Validate {
+
+namespace {
+
+/// for array types without an explicit length, compute the length and store it so that it
+/// is known to the rest of the phases. For example,
+///   int x[] = { 1, 2, 3 };
+///   int y[][2] = { { 1, 2, 3 }, { 1, 2, 3 } };
+/// here x and y are known at compile-time to have length 3, so change this into
+///   int x[3] = { 1, 2, 3 };
+///   int y[3][2] = { { 1, 2, 3 }, { 1, 2, 3 } };
+struct InitializerLength {
+	const ast::ObjectDecl * previsit( const ast::ObjectDecl * decl );
+};
+
+const ast::ObjectDecl * InitializerLength::previsit( const ast::ObjectDecl * decl ) {
+	if ( auto type = decl->type.as<ast::ArrayType>() ) {
+		if ( type->dimension ) return decl;
+		if ( auto init = decl->init.as<ast::ListInit>() ) {
+			ast::ObjectDecl * mutDecl = ast::mutate( decl );
+			ast::ArrayType * mutType = ast::mutate( type );
+			mutType->dimension = ast::ConstantExpr::from_ulong(
+				mutDecl->location, init->size() );
+			mutDecl->type = mutType;
+			return mutDecl;
+		}
+	}
+	return decl;
+}
+
+} // namespace
+
+void setLengthFromInitializer( ast::TranslationUnit & translationUnit ) {
+	ast::Pass<InitializerLength>::run( translationUnit );
+}
+
+} // namespace Validate
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/Validate/InitializerLength.hpp
===================================================================
--- src/Validate/InitializerLength.hpp	(revision ce36b5519dcfbed597a596a468dc1684221e78ab)
+++ src/Validate/InitializerLength.hpp	(revision ce36b5519dcfbed597a596a468dc1684221e78ab)
@@ -0,0 +1,27 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2018 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// InitializerLength.hpp -- Calculate the length of arrays from initializers.
+//
+// Author           : Andrew Beach
+// Created On       : Fri Nov 12 16:25:00 2021
+// Last Modified By : Andrew Beach
+// Last Modified On : Fri Nov 12 16:28:00 2021
+// Update Count     : 0
+//
+
+namespace Validate {
+
+/// Set implicit length of array from the initializer.
+void setLengthFromInitializer( ast::TranslationUnit & translationUnit );
+
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/Validate/LabelAddressFixer.cpp
===================================================================
--- src/Validate/LabelAddressFixer.cpp	(revision ce36b5519dcfbed597a596a468dc1684221e78ab)
+++ src/Validate/LabelAddressFixer.cpp	(revision ce36b5519dcfbed597a596a468dc1684221e78ab)
@@ -0,0 +1,74 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2018 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// LabelAddressFixer.cpp --
+//
+// Author           : Andrew Beach
+// Created On       : Fri Nov 12 16:30:00 2021
+// Last Modified By : Andrew Beach
+// Last Modified On : Fri Nov 12 16:30:00 2021
+// Update Count     : 0
+//
+
+#include "Validate/LabelAddressFixer.hpp"
+
+#include "AST/Decl.hpp"
+#include "AST/Expr.hpp"
+#include "AST/Pass.hpp"
+#include "AST/TranslationUnit.hpp"
+
+#include <set>
+
+namespace Validate {
+
+namespace {
+
+struct LabelFinder {
+	std::set<ast::Label> & labels;
+	LabelFinder( std::set<ast::Label> & labels ) : labels( labels ) {}
+	void previsit( const ast::Stmt * stmt ) {
+		for ( const ast::Label & label : stmt->labels ) {
+			labels.insert( label );
+		}
+	}
+};
+
+struct LabelAddressFixer : public ast::WithGuards {
+	std::set<ast::Label> labels;
+	void previsit( const ast::FunctionDecl * decl );
+	const ast::Expr * postvisit( const ast::AddressExpr * expr );
+};
+
+void LabelAddressFixer::previsit( const ast::FunctionDecl * decl ) {
+	GuardValue( labels );
+	ast::Pass<LabelFinder>::read( decl, labels );
+}
+
+const ast::Expr * LabelAddressFixer::postvisit( const ast::AddressExpr * expr ) {
+	if ( auto inner = expr->arg.as<ast::AddressExpr>() ) {
+		if ( auto nameExpr = inner->arg.as<ast::NameExpr>() ) {
+			ast::Label label( nameExpr->location, nameExpr->name );
+			if ( labels.count( label ) ) {
+				return new ast::LabelAddressExpr( nameExpr->location, std::move( label ) );
+			}
+		}
+	}
+	return expr;
+}
+
+} // namespace
+
+void fixLabelAddresses( ast::TranslationUnit & translationUnit ) {
+	ast::Pass<LabelAddressFixer>::run( translationUnit );
+}
+
+} // namespace Validate
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/Validate/LabelAddressFixer.hpp
===================================================================
--- src/Validate/LabelAddressFixer.hpp	(revision ce36b5519dcfbed597a596a468dc1684221e78ab)
+++ src/Validate/LabelAddressFixer.hpp	(revision ce36b5519dcfbed597a596a468dc1684221e78ab)
@@ -0,0 +1,30 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2018 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// LabelAddressFixer.hpp --
+//
+// Author           : Andrew Beach
+// Created On       : Fri Nov 12 16:29:00 2021
+// Last Modified By : Andrew Beach
+// Last Modified On : Fri Nov 12 16:35:00 2021
+// Update Count     : 0
+//
+
+namespace ast {
+	class TranslationUnit;
+}
+
+namespace Validate {
+
+void fixLabelAddresses( ast::TranslationUnit & translationUnit );
+
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/Validate/module.mk
===================================================================
--- src/Validate/module.mk	(revision 5339a87ca7689b734a2eb1d355830ea9713784a1)
+++ src/Validate/module.mk	(revision ce36b5519dcfbed597a596a468dc1684221e78ab)
@@ -15,4 +15,15 @@
 ###############################################################################
 
-SRC += Validate/HandleAttributes.cc Validate/HandleAttributes.h Validate/FindSpecialDecls.cc Validate/FindSpecialDecls.h
-SRCDEMANGLE += Validate/HandleAttributes.cc Validate/HandleAttributes.h Validate/FindSpecialDecls.cc Validate/FindSpecialDecls.h
+SRC_VALIDATE = \
+	Validate/HandleAttributes.cc \
+	Validate/HandleAttributes.h \
+	Validate/InitializerLength.cpp \
+	Validate/InitializerLength.hpp \
+	Validate/LabelAddressFixer.cpp \
+	Validate/LabelAddressFixer.hpp \
+	Validate/FindSpecialDeclsNew.cpp \
+	Validate/FindSpecialDecls.cc \
+	Validate/FindSpecialDecls.h
+
+SRC += $(SRC_VALIDATE)
+SRCDEMANGLE += $(SRC_VALIDATE)
