Index: src/ResolvExpr/Alternative.cc
===================================================================
--- src/ResolvExpr/Alternative.cc	(revision aeb8f70056004f741c9dcb505f8cb1cecb640ff1)
+++ src/ResolvExpr/Alternative.cc	(revision e99e43f290a67032231db42a3e1c62f8c7ba7ca7)
@@ -120,5 +120,5 @@
 			os << "Null expression!" << std::endl;
 		} // if
-		os << indent << "Environment: ";
+		os << indent << "Environment:";
 		env.print( os, indent+1 );
 		os << std::endl;
Index: src/ResolvExpr/AlternativeFinder.cc
===================================================================
--- src/ResolvExpr/AlternativeFinder.cc	(revision aeb8f70056004f741c9dcb505f8cb1cecb640ff1)
+++ src/ResolvExpr/AlternativeFinder.cc	(revision e99e43f290a67032231db42a3e1c62f8c7ba7ca7)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Sat May 16 23:52:08 2015
-// Last Modified By : Aaron B. Moss
-// Last Modified On : Fri Oct -5 10:01:00 2018
-// Update Count     : 34
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Thu Nov  1 21:00:56 2018
+// Update Count     : 35
 //
 
@@ -500,111 +500,6 @@
 				needAssertions[ *assert ].isUsed = true;
 			}
-///     needAssertions.insert( needAssertions.end(), (*tyvar)->get_assertions().begin(), (*tyvar)->get_assertions().end() );
-		}
-	}
-
-// 	template< typename ForwardIterator, typename OutputIterator >
-// 	void inferRecursive( ForwardIterator begin, ForwardIterator end, const Alternative &newAlt, OpenVarSet &openVars, const SymTab::Indexer &decls, const AssertionSet &newNeed, int level, const SymTab::Indexer &indexer, OutputIterator out ) {
-// 		if ( newAlt.cost == Cost::infinity ) return; // don't proceed down this dead end
-// 		if ( begin == end ) {
-// 			if ( newNeed.empty() ) {
-// 				PRINT(
-// 					std::cerr << "all assertions satisfied, output alternative: ";
-// 					newAlt.print( std::cerr );
-// 					std::cerr << std::endl;
-// 				);
-// 				*out++ = newAlt;
-// 				return;
-// 			} else if ( level >= recursionLimit ) {
-// 				SemanticError( newAlt.expr->location, "Too many recursive assertions" );
-// 			} else {
-// 				AssertionSet newerNeed;
-// 				PRINT(
-// 					std::cerr << "recursing with new set:" << std::endl;
-// 					printAssertionSet( newNeed, std::cerr, 8 );
-// 				)
-// 				inferRecursive( newNeed.begin(), newNeed.end(), newAlt, openVars, decls, newerNeed, level+1, indexer, out );
-// 				return;
-// 			}
-// 		}
-
-// 		ForwardIterator cur = begin++;
-// 		if ( ! cur->second.isUsed ) {
-// 			inferRecursive( begin, end, newAlt, openVars, decls, newNeed, level, indexer, out );
-// 			return; // xxx - should this continue? previously this wasn't here, and it looks like it should be
-// 		}
-// 		DeclarationWithType *curDecl = cur->first;
-
-// 		PRINT(
-// 			std::cerr << "inferRecursive: assertion is ";
-// 			curDecl->print( std::cerr );
-// 			std::cerr << std::endl;
-// 		)
-// 		std::list< SymTab::Indexer::IdData > candidates;
-// 		decls.lookupId( curDecl->get_name(), candidates );
-// ///   if ( candidates.empty() ) { std::cerr << "no candidates!" << std::endl; }
-// 		for ( const auto & data : candidates ) {
-// 			DeclarationWithType * candidate = data.id;
-// 			PRINT(
-// 				std::cerr << "inferRecursive: candidate is ";
-// 				candidate->print( std::cerr );
-// 				std::cerr << std::endl;
-// 			)
-
-// 			AssertionSet newHave, newerNeed( newNeed );
-// 			TypeEnvironment newEnv( newAlt.env );
-// 			OpenVarSet newOpenVars( openVars );
-// 			Type *adjType = candidate->get_type()->clone();
-// 			adjustExprType( adjType, newEnv, indexer );
-// 			renameTyVars( adjType );
-// 			PRINT(
-// 				std::cerr << "unifying ";
-// 				curDecl->get_type()->print( std::cerr );
-// 				std::cerr << " with ";
-// 				adjType->print( std::cerr );
-// 				std::cerr << std::endl;
-// 			)
-// 			if ( unify( curDecl->get_type(), adjType, newEnv, newerNeed, newHave, newOpenVars, indexer ) ) {
-// 				PRINT(
-// 					std::cerr << "success!" << std::endl;
-// 				)
-// 				SymTab::Indexer newDecls( decls );
-// 				addToIndexer( newHave, newDecls );
-// 				Alternative newerAlt( newAlt );
-// 				newerAlt.env = newEnv;
-// 				assertf( candidate->get_uniqueId(), "Assertion candidate does not have a unique ID: %s", toString( candidate ).c_str() );
-
-// 				// everything with an empty idChain was pulled in by the current assertion.
-// 				// add current assertion's idChain + current assertion's ID so that the correct inferParameters can be found.
-// 				for ( auto & a : newerNeed ) {
-// 					if ( a.second.idChain.empty() ) {
-// 						a.second.idChain = cur->second.idChain;
-// 						a.second.idChain.push_back( curDecl->get_uniqueId() );
-// 					}
-// 				}
-
-// 				Expression *varExpr = data.combine( newerAlt.cvtCost );
-// 				delete varExpr->get_result();
-// 				varExpr->set_result( adjType->clone() );
-// 				PRINT(
-// 					std::cerr << "satisfying assertion " << curDecl->get_uniqueId() << " ";
-// 					curDecl->print( std::cerr );
-// 					std::cerr << " with declaration " << candidate->get_uniqueId() << " ";
-// 					candidate->print( std::cerr );
-// 					std::cerr << std::endl;
-// 				)
-// 				// follow the current assertion's ID chain to find the correct set of inferred parameters to add the candidate to (i.e. the set of inferred parameters belonging to the entity which requested the assertion parameter).
-// 				InferredParams * inferParameters = &newerAlt.expr->inferParams;
-// 				for ( UniqueId id : cur->second.idChain ) {
-// 					inferParameters = (*inferParameters)[ id ].inferParams.get();
-// 				}
-// 				// XXX: this is a memory leak, but adjType can't be deleted because it might contain assertions
-// 				(*inferParameters)[ curDecl->get_uniqueId() ] = ParamEntry( candidate->get_uniqueId(), adjType->clone(), curDecl->get_type()->clone(), varExpr );
-// 				inferRecursive( begin, end, newerAlt, newOpenVars, newDecls, newerNeed, level, indexer, out );
-// 			} else {
-// 				delete adjType;
-// 			}
-// 		}
-// 	}
+		}
+	}
 
 	/// Unique identifier for matching expression resolutions to their requesting expression
@@ -613,15 +508,4 @@
 	template< typename OutputIterator >
 	void AlternativeFinder::Finder::inferParameters( Alternative &newAlt, OutputIterator out ) {
-		// SymTab::Indexer decls( indexer );
-		// addToIndexer( have, decls );
-		// AssertionSet newNeed;
-		// PRINT(
-		// 	std::cerr << "env is: " << std::endl;
-		// 	newAlt.env.print( std::cerr, 0 );
-		// 	std::cerr << std::endl;
-		// )
-
-		// inferRecursive( need.begin(), need.end(), newAlt, openVars, decls, newNeed, 0, indexer, out );
-
 		// Set need bindings for any unbound assertions
 		UniqueId crntResnSlot = 0;  // matching ID for this expression's assertions
@@ -1373,4 +1257,7 @@
 		/// Gets name from untyped member expression (member must be NameExpr)
 		const std::string& get_member_name( UntypedMemberExpr *memberExpr ) {
+			if ( dynamic_cast< ConstantExpr * >( memberExpr->get_member() ) ) {
+				SemanticError( memberExpr, "Indexed access to struct fields unsupported: " );
+			} // if
 			NameExpr * nameExpr = dynamic_cast< NameExpr * >( memberExpr->get_member() );
 			assert( nameExpr );
Index: src/ResolvExpr/ResolveTypeof.cc
===================================================================
--- src/ResolvExpr/ResolveTypeof.cc	(revision aeb8f70056004f741c9dcb505f8cb1cecb640ff1)
+++ src/ResolvExpr/ResolveTypeof.cc	(revision e99e43f290a67032231db42a3e1c62f8c7ba7ca7)
@@ -67,14 +67,43 @@
 		std::cerr << std::endl;
 #endif
-		if ( typeofType->expr ) {
+		// pass on null expression
+		if ( ! typeofType->expr ) return typeofType;
+
+		bool isBasetypeof = typeofType->is_basetypeof;
+		auto oldQuals = typeofType->get_qualifiers().val;
+
+		Type* newType;
+		if ( TypeExpr* tyExpr = dynamic_cast<TypeExpr*>(typeofType->expr) ) {
+			// typeof wrapping type
+			newType = tyExpr->type;
+			tyExpr->type = nullptr;
+			delete tyExpr;
+		} else {
+			// typeof wrapping expression
 			Expression * newExpr = resolveInVoidContext( typeofType->expr, indexer );
 			assert( newExpr->result && ! newExpr->result->isVoid() );
-			Type * newType = newExpr->result;
+			newType = newExpr->result;
 			newExpr->result = nullptr;
 			delete typeofType;
 			delete newExpr;
-			return newType;
-		} // if
-		return typeofType;
+		}
+
+		// clear qualifiers for base, combine with typeoftype quals in any case
+		if ( isBasetypeof ) {
+			// replace basetypeof(<enum>) by int
+			if ( dynamic_cast<EnumInstType*>(newType) ) {
+				Type* newerType = 
+					new BasicType{ newType->get_qualifiers(), BasicType::SignedInt, 
+					newType->attributes };
+				delete newType;
+				newType = newerType;
+			}
+			newType->get_qualifiers().val 
+				= ( newType->get_qualifiers().val & ~Type::Qualifiers::Mask ) | oldQuals;
+		} else {
+			newType->get_qualifiers().val |= oldQuals;
+		}
+		
+		return newType;
 	}
 } // namespace ResolvExpr
