Add variant methods to SingletonContext and Context

Add VisitAllModuleVariants, PrimaryModule, and FinalModule to
SingletonContext so singletons and tools can deal with modules with
multiple variants.
diff --git a/context.go b/context.go
index e45c237..a20de91 100644
--- a/context.go
+++ b/context.go
@@ -2144,6 +2144,23 @@
 	c.visitDepsDepthFirstIf(c.moduleInfo[module], pred, visit)
 }
 
+func (c *Context) PrimaryModule(module Module) Module {
+	return c.moduleInfo[module].group.modules[0].logicModule
+}
+
+func (c *Context) FinalModule(module Module) Module {
+	modules := c.moduleInfo[module].group.modules
+	return modules[len(modules)-1].logicModule
+}
+
+func (c *Context) VisitAllModuleVariants(module Module,
+	visit func(Module)) {
+
+	for _, module := range c.moduleInfo[module].group.modules {
+		visit(module.logicModule)
+	}
+}
+
 // WriteBuildFile writes the Ninja manifeset text for the generated build
 // actions to w.  If this is called before PrepareBuildActions successfully
 // completes then ErrBuildActionsNotReady is returned.
diff --git a/singleton_ctx.go b/singleton_ctx.go
index e982086..c4c0b6c 100644
--- a/singleton_ctx.go
+++ b/singleton_ctx.go
@@ -49,6 +49,11 @@
 	VisitDepsDepthFirstIf(module Module, pred func(Module) bool,
 		visit func(Module))
 
+	VisitAllModuleVariants(module Module, visit func(Module))
+
+	PrimaryModule(module Module) Module
+	FinalModule(module Module) Module
+
 	AddNinjaFileDeps(deps ...string)
 }
 
@@ -166,6 +171,18 @@
 	s.context.VisitDepsDepthFirstIf(module, pred, visit)
 }
 
+func (s *singletonContext) PrimaryModule(module Module) Module {
+	return s.context.PrimaryModule(module)
+}
+
+func (s *singletonContext) FinalModule(module Module) Module {
+	return s.context.FinalModule(module)
+}
+
+func (s *singletonContext) VisitAllModuleVariants(module Module, visit func(Module)) {
+	s.context.VisitAllModuleVariants(module, visit)
+}
+
 func (s *singletonContext) AddNinjaFileDeps(deps ...string) {
 	s.ninjaFileDeps = append(s.ninjaFileDeps, deps...)
 }