#!/bin/sh

# This script is invoked by Android build system "WITH_SYNTAX_CHECK=1 m/mm/mmm ..." and
# accepts command line in the following format:
#
#    ccc-analyzer ARCH LOCAL_CXX ...
#
# Under WITH_SYNTAX_CHECK=1, m/mm/mmm/mma/mmma wrap "make" with "tools/scan-build/scan-build"
# which utillizes "clang++ --analyze" for static code analyses.  Script scan-build interposes
# on compiler with CC/CXX ignored by the Android build system unfortunately.  Instead,
# Android build system recognizes WITH_SYNTAX_CHECK and replace LOCAL_CXX with our own cxx-syntax,
# which in turn setup the following env. vars expected by tools/scan-build/c++-analyzer
#
#   CCC_CXX: The origianl LOCAL_CXX which does the real compilation and code-gen
#   CLANG_CXX: The clang++ compiler which run code analyses
#
# Our own cxx-syntax also export the following, and tools/scan-build/ccc-analyzer is slightly
# modified to prefix/append them in options passed to clang++ for successful compilation
#
#   CLANG_FLAGS: Flags to set correct target, be compatible with gcc, etc
#   CLANG_FLAGS_END:  Flags to override "$@"
#

ARCH="$1"
LOCAL_CXX="$2"
shift ; shift

# Turn off warning about unused options
CLANG_FLAGS="-Qunused-arguments"

# Turn off unknown warning options
CLANG_FLAGS="$CLANG_FLAGS -Wno-unknown-warning-option"

# Define WITH_SYNTAX_CHECK for code wish to behave differently when check
CLANG_FLAGS="$CLANG_FLAGS -DWITH_SYNTAX_CHECK"

# Ignore C standard like -std=gnu99 in LOCAL_CFLAGS but get
# passed for C++ compilation by build system
CLANG_FLAGS="$CLANG_FLAGS -Qignore-c-std-not-allowed-with-cplusplus"

# Turn off warnings which aren't useful in this context
CLANG_FLAGS="$CLANG_FLAGS -Wno-ignored-attributes -Wno-pedantic -Wno-builtin-requires-header -Wno-gnu -Wno-gnu-designator -Wno-knr-promoted-parameter"

if [ "$ARCH" != "host" ]; then
    # Add target to get proper pre-defined preprocessor symbols/macros.
    case $ARCH in
        arm) CLANG_FLAGS="$CLANG_FLAGS -target armv5te-none-linux-androideabi"
            ;;
        mips) CLANG_FLAGS="$CLANG_FLAGS -target mipsel-none-linux-android"
            ;;
        x86) CLANG_FLAGS="$CLANG_FLAGS -target i686-none-linux-android"
            ;;
    esac
    if [ "$LOCAL_CXX" != "${LOCAL_CXX%clang++*}" ]; then
        # Don't look for its own lib/clang/x.y/include when LOCAL_CXX is clang
        # which is rebuilt from source w/o installing its include as well
        CLANG_FLAGS="$CLANG_FLAGS -nostdinc"
    fi
else
    # Note that unlike target flags where Android build system explicitly specify
    # everything in command line, host tools have their own sysroot and --sysroot
    # isn't explicitly added in the commmand line.  Likelywise for other gcc implicit
    # search directories.
    #
    # We can query search paths by doing "g++ -v" and parsing the output with
    # sed -n '1,/BEGIN/!{ /END/,/BEING/!p; }' (*1), but forking gcc here adds overhead.
    # Because host tool refresh only once 1-2 year, here we hard-code the path obtained by (*2).
    # ToDo: The build system can do it once for each module, although it still needs to
    # prepare both -m32 and -m64 versions, anding 2 more args in additional to $ARCH
    # and $LOCAL_CXX
    #
    # (*1) as described in http://sed.sourceforge.net/sedfaq4.html#s4.24
    # (*2) prebuilts/tools/gcc-sdk/g++ -m64 -v -E - < /dev/null 2>&1 | \
    #         sed -n '1,/> search starts here/!{ /End of search list/,/> search starts here/!p; }' |\
    #         sed -e 's/^/-I/'
    #      Likewise for -m32
    #
    # Please refer to prebuilts/tools/gcc-sdk/gcc for similar trick to determine
    # bitness
    options=" ${@} "   # sentinel prefix/suffix space to simplify pattern match below
    suffix_m32=${options##* -m32 }    # suffix after the last -m32
    suffix_m64=${options##* -m64 }    # suffix after the last -m64
    len_m32=${#suffix_m32}            # length of suffix after the last -m32
    len_m64=${#suffix_m64}            # length of suffix after the last -m64
    if [ $len_m32 -ge $len_m64 ] ; then
        CLANG_FLAGS_END="\
-I prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6/x86_64-linux/include/c++/4.6.x-google \
-I prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6/x86_64-linux/include/c++/4.6.x-google/x86_64-linux \
-I prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6/x86_64-linux/include/c++/4.6.x-google/backward \
-I prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6/lib/gcc/x86_64-linux/4.6.x-google/include \
-I prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6/lib/gcc/x86_64-linux/4.6.x-google/include-fixed \
-I prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6/x86_64-linux/include \
-I prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6/sysroot/usr/include"
    else
        CLANG_FLAGS_END="\
-I prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6/i686-linux/include/c++/4.6.x-google \
-I prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6/i686-linux/include/c++/4.6.x-google/i686-linux \
-I prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6/i686-linux/include/c++/4.6.x-google/backward \
-I prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6/lib/gcc/i686-linux/4.6.x-google/include \
-I prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6/lib/gcc/i686-linux/4.6.x-google/include-fixed \
-I prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6/i686-linux/include \
-I prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6/sysroot/usr/include"
    fi
fi

# Turn off warnings (at the end) on features we exploit
CLANG_FLAGS_END="$CLANG_FLAGS_END -Wno-return-type-c-linkage"

# Call the real c++-analyzer.  Note that tools/scan-build/c++-analyzer "exec" $CCC_CXX,
# which is LOCAL_CXX w/o optional ccache (in "ccache g++" format)
export CCC_CXX="${LOCAL_CXX##* }"
export CLANG_CXX="`dirname $0`/analyzer++"
export CLANG_FLAGS
export CLANG_FLAGS_END
`dirname $0`/../tools/scan-build/c++-analyzer "$@"