ci: upgrade distro to xenial and add arm64 test cases (#1662)

Start from xenial, Travis supports multiple CPU architectures.
To bump to this version allows expand test coverage for more
architectures.
See: https://docs.travis-ci.com/user/reference/overview/#virtualisation-environment-vs-operating-system
Add arm64 test cases to matrix.

Change-Id: If61e2d38223dad70b542d6ec0afcf4a433c9debf
Signed-off-by: Jun He <jun.he@arm.com>

Co-authored-by: Jun He <jun.he@arm.com>
diff --git a/.travis.yml b/.travis.yml
index 783c052..8f34664 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,11 +1,18 @@
 sudo: required
-dist: trusty
-group: edge
+dist: xenial
 
 language: cpp
 cache:
   - ccache
 
+addons:
+  apt:
+    sources:
+      - ubuntu-toolchain-r-test
+    packages:
+      - cmake
+      - valgrind
+      - clang-8
 env:
   global:
     - USE_CCACHE=1
@@ -14,41 +21,60 @@
     - CCACHE_MAXSIZE=100M
     - ARCH_FLAGS_x86='-m32'        # #266: don't use SSE on 32-bit
     - ARCH_FLAGS_x86_64='-msse4.2' #       use SSE4.2 on 64-bit
+    - ARCH_FLAGS_aarch64='-march=armv8-a'
     - GITHUB_REPO='Tencent/rapidjson'
     - secure: "HrsaCb+N66EG1HR+LWH1u51SjaJyRwJEDzqJGYMB7LJ/bfqb9mWKF1fLvZGk46W5t7TVaXRDD5KHFx9DPWvKn4gRUVkwTHEy262ah5ORh8M6n/6VVVajeV/AYt2C0sswdkDBDO4Xq+xy5gdw3G8s1A4Inbm73pUh+6vx+7ltBbk="
 
-before_install:
-    - sudo apt-add-repository -y ppa:ubuntu-toolchain-r/test
-    - sudo apt-get update -qq
-    - sudo apt-get install -y cmake valgrind g++-multilib libc6-dbg:i386 --allow-unauthenticated
-
 matrix:
   include:
     # gcc
     - env: CONF=release ARCH=x86    CXX11=ON
       compiler: gcc
+      arch: amd64
     - env: CONF=release ARCH=x86_64 CXX11=ON
       compiler: gcc
+      arch: amd64
     - env: CONF=debug   ARCH=x86    CXX11=OFF
       compiler: gcc
+      arch: amd64
     - env: CONF=debug   ARCH=x86_64 CXX11=OFF
       compiler: gcc
+      arch: amd64
+    - env: CONF=release ARCH=aarch64 CXX11=ON
+      compiler: gcc
+      arch: arm64
+    - env: CONF=debug   ARCH=aarch64 CXX11=OFF
+      compiler: gcc
+      arch: arm64
     # clang
     - env: CONF=debug   ARCH=x86    CXX11=ON CCACHE_CPP2=yes
       compiler: clang
+      arch: amd64
     - env: CONF=debug   ARCH=x86_64 CXX11=ON CCACHE_CPP2=yes
       compiler: clang
+      arch: amd64
     - env: CONF=debug   ARCH=x86    CXX11=OFF CCACHE_CPP2=yes
       compiler: clang
+      arch: amd64
     - env: CONF=debug   ARCH=x86_64 CXX11=OFF CCACHE_CPP2=yes
       compiler: clang
+      arch: amd64
     - env: CONF=release ARCH=x86    CXX11=ON CCACHE_CPP2=yes
       compiler: clang
+      arch: amd64
     - env: CONF=release ARCH=x86_64 CXX11=ON CCACHE_CPP2=yes
       compiler: clang
+      arch: amd64
+    - env: CONF=debug   ARCH=aarch64 CXX11=ON CCACHE_CPP2=yes
+      compiler: clang
+      arch: arm64
+    - env: CONF=debug   ARCH=aarch64 CXX11=OFF CCACHE_CPP2=yes
+      compiler: clang
+      arch: arm64
     # coverage report
     - env: CONF=debug   ARCH=x86    CXX11=ON GCOV_FLAGS='--coverage'
       compiler: gcc
+      arch: amd64
       cache:
         - ccache
         - pip
@@ -57,6 +83,16 @@
         - coveralls -r .. --gcov-options '\-lp' -e thirdparty -e example -e test -e build/CMakeFiles -e include/rapidjson/msinttypes -e include/rapidjson/internal/meta.h -e include/rapidjson/error/en.h
     - env: CONF=debug   ARCH=x86_64 GCOV_FLAGS='--coverage'
       compiler: gcc
+      arch: amd64
+      cache:
+        - ccache
+        - pip
+      after_success:
+        - pip install --user cpp-coveralls
+        - coveralls -r .. --gcov-options '\-lp' -e thirdparty -e example -e test -e build/CMakeFiles -e include/rapidjson/msinttypes -e include/rapidjson/internal/meta.h -e include/rapidjson/error/en.h
+    - env: CONF=debug   ARCH=aarch64 GCOV_FLAGS='--coverage'
+      compiler: gcc
+      arch: arm64
       cache:
         - ccache
         - pip
@@ -73,13 +109,24 @@
           packages:
             - doxygen
 
+before_install:
+  - if [ "x86_64" = "$(arch)" ]; then sudo apt-get install -y g++-multilib libc6-dbg:i386 --allow-unauthenticated; fi
+
 before_script:
-    - ccache -s
-      #   hack to avoid Valgrind bug (https://bugs.kde.org/show_bug.cgi?id=326469),
-      #   exposed by merging PR#163 (using -march=native)
-      #   TODO: Since this bug is already fixed. Remove this when valgrind can be upgraded.
-    - sed -i "s/-march=native//" CMakeLists.txt
-    - mkdir build
+    # travis provides clang-7 for amd64 and clang-3.8 for arm64
+    # here use clang-8 to all architectures as clang-7 is not available for arm64
+  - if [ -f /usr/bin/clang++-8 ]; then
+      sudo update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-8 1000;
+      sudo update-alternatives --config clang++;
+      export PATH=/usr/bin:$PATH;
+    fi
+  - if [ "$CXX" = "clang++" ]; then export CCACHE_CPP2=yes; fi
+  - ccache -s
+    #   hack to avoid Valgrind bug (https://bugs.kde.org/show_bug.cgi?id=326469),
+    #   exposed by merging PR#163 (using -march=native)
+    #   TODO: Since this bug is already fixed. Remove this when valgrind can be upgraded.
+  - sed -i "s/-march=native//" CMakeLists.txt
+  - mkdir build
 
 script:
   - if [ "$CXX" = "clang++" ]; then export CXXFLAGS="-stdlib=libc++ ${CXXFLAGS}"; fi