     ValFunction -> throw InvalidFunctionInTranslateValue
     ValAlias -> throw InvalidAliasInTranslateValue
     ValGlobalvariable -> throw InvalidGlobalVarInTranslateValue
+    ValConstantexpr -> translateConstantExpr finalState (castPtr dataPtr)
 
   uid <- nextId
 

cInsExtIndices ie =
  peekArray ie {#get CInsExtValInfo->indices#} {#get CInsExtValInfo->numIndices#}

data CPHIInfo
{#pointer *CPHIInfo as PHIInfoPtr -> CPHIInfo #}
cPHIValues :: PHIInfoPtr -> IO [ValuePtr]

      recordValue vp v
      return v

-- | This wrapper checks to see if we have translated the value yet
-- (but not against the final state - only the internal running
-- state).  This way we really translate it if it hasn't been seen
-- yet, but get the translated value if we have touched it before.
translateValue :: KnotState -> ValuePtr -> KnotMonad Value
translateValue finalState vp = do
  s <- get
  case M.lookup vp (valueMap s) of
    Nothing -> translateValue' finalState vp
    Just v -> return v

-- | Only the top-level translators should call this: Globals and BasicBlocks
-- (Or translateConstOrRef when translating constants)
translateValue' :: KnotState -> ValuePtr -> KnotMonad Value
translateValue' finalState vp = do
  tag <- liftIO $ cValueTag vp
  name <- liftIO $ cValueName vp
  typePtr <- liftIO $ cValueType vp
