Grep to search for array of location targets
Your questions:


Yes. Use double quotes and then drop the eval (this will also cause the script to show /path/to/prod/home instead of $PROD_HOME)
Yes, just do it once at the start of the script.
No. 
Depends on your requirements.


Other issues: 


Using multiple regex can be specified but won't work
Using paths with spaces doesn't work


Keeping most of your current functionality, I probably do something like this:

#!/bin/bash
shopt -s nullglob

# Allow using ** to recursively expand globs
shopt -s globstar

# Don't do any field splitting
IFS=''

if (( ! $# ))
then
    echo "specify at least one regex"
    exit 1
fi

locations=(
  "$BIN_HOME/*"
  "$PBIN_HOME/**"
  "$SH_HOME/**"
  "$PROD_HOME/psp/*.psp"
  "$PROD_HOME/sql/*.sql"
  "$PROD_HOME/sql/*/*.sql"
  "$PROD_HOME/rpt/[A-Z]*.rpt"
  "$PROD_HOME/script/*"
  "$PROD_HOME/fmb/[A-Z]*.pll"
  "$PROD_HOME/xml/[A-Z]*.pld"
  "$PROD_HOME/fmb/[A-Z]*.mmb"
  "$PROD_HOME/xml/[A-Z]*.xml"
  "$PROD_HOME/cgi/*"
  "$ELETTUS_HOME/**"
  "$PROD_HOME/guicommon/*"
)

# Quote all variables unless you specifically can't
for location in "${locations[@]}"
do
    echo "--------------------------------------------------------------------------------"
    # Printf generally works better for arbitrary data, though this is unlikely to be an issue in your case
    printf "%s\n" "$location"
    echo
    if [[ "$location" != /u2/* ]]
    then
        printf "%s is not a part of Lettus system\n" "$location" &gt;&amp;2
        echo
        continue
    fi

    # grep can accept multiple patterns separated by line feeds
    # Add a dummy file so non-matching globs won't cause grep to read from stdin
    # Here we want $location to glob expand, so no quotes (IFS was set earlier to prevent field splitting)
    grep -E -I -d skip "$(printf "%s\n" "$@")" /dev/null $location
done