# -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:ft=tcl:et:sw=4:ts=4:sts=4

PortSystem              1.0
PortGroup active_variants 1.1
PortGroup cmake         1.0
PortGroup legacysupport 1.0

# link legacysupport statically for compilers
legacysupport.use_static yes
legacysupport.newest_darwin_requires_legacy 13

set llvm_version        11
set clang_executable_version 11
set lldb_executable_version 11

version                 11.1.0
master_sites            https://github.com/llvm/llvm-project/releases/download/llvmorg-${version}
distname                llvm-project-${version}.src
use_xz                  yes

checksums               rmd160  f566b4b75c8f30418f19069a9a84864ead766401 \
                        sha256  74d2529159fd118c3eac6f90107b5611bccc6f647fdea104024183e8d5e25831 \
                        size    84065492

name                    llvm-${llvm_version}
revision                6
subport                 clang-${llvm_version} { revision 8 }
subport                 flang-${llvm_version} { revision 1 }
subport                 lldb-${llvm_version} { revision 4 }
set suffix              mp-${llvm_version}
set sub_prefix          ${prefix}/libexec/llvm-${llvm_version}
dist_subdir             llvm
categories              lang
platforms               {darwin < 23}
license                 NCSA
maintainers             {jeremyhu @jeremyhu}

if {${subport} eq "llvm-${llvm_version}"} {
    homepage            https://llvm.org/
    description         llvm is a next generation compiler infrastructure
    long_description    The LLVM Core libraries provide a modern source- and \
                        target-independent optimizer, along with code \
                        generation support for many popular CPUs (as well as \
                        some less common ones!) These libraries are built \
                        around a well specified code representation known as \
                        the LLVM intermediate representation ("LLVM IR").

    depends_lib         port:libedit port:libffi port:ncurses path:lib/libxar.dylib:xar port:zlib
    depends_run         bin:perl:perl5 port:llvm_select-${llvm_version}
} elseif {${subport} eq "clang-${llvm_version}"} {
    homepage            https://clang.llvm.org/
    description         C, C++, Objective C and Objective C++ compiler
    long_description    Clang is an "LLVM native" C/C++/Objective-C compiler, \
                        which aims to deliver amazingly fast compiles (e.g. \
                        about 3x faster than GCC when compiling Objective-C \
                        code in a debug configuration), extremely useful error \
                        and warning messages and to provide a platform for \
                        building great source level tools. The included Clang \
                        Static Analyzer is a tool that automatically finds bugs in \
                        your code, and is a great example of the sort of tool \
                        that can be built using the Clang frontend as a \
                        library to parse C/C++ code.

    depends_lib         port:libxml2 port:libomp port:llvm-${llvm_version}
    depends_run         port:clang_select-${llvm_version} port:ld64 port:cctools
    depends_skip_archcheck-append ld64 subversion

    # Avoid requiring a bootstrap version of perl5 on 10.6.
    if {${os.major} >= 11} {
        default_variants    +analyzer
    }

} elseif {${subport} eq "flang-${llvm_version}"} {
    homepage            https://flang.llvm.org/
    description         LLVM Fortran compiler
    long_description    ${description}

    depends_lib-append  port:llvm-${llvm_version} port:clang-${llvm_version}

    # flang currently requires gfortran to actually compile anything
    # and we may have to set "F18_FC" in the environment to something else
    # for it to find the gfortran we want to use
    if {${build_arch} eq "arm64"} {
        depends_run-append  port:gcc-devel
    } else {
        if {${os.major} <= 10} {
            depends_run-append  port:gcc8
        } else {
            depends_run-append  port:gcc11
        }
    }

} elseif {${subport} eq "lldb-${llvm_version}"} {
    homepage            https://lldb.llvm.org/
    description         the LLVM debugger
    long_description    Lldb is the "LLVM native" debugger.

    depends_lib         port:libxml2 port:libomp port:llvm-${llvm_version} port:ncurses
    depends_build-append port:swig-python path:bin/doxygen:doxygen
    depends_run-append  port:lldb_select-${llvm_version}
}

# for devel version only
# default_variants-append +assertions

worksrcdir              llvm-project/llvm
patch.dir               ${workpath}/llvm-project/llvm

post-extract {
    ln -s ${workpath}/${distname} ${workpath}/llvm-project

    if {${subport} eq "llvm-${llvm_version}"} {
        if {[variant_isset polly]} {
            ln -s ${workpath}/llvm-project/polly                        ${worksrcpath}/tools/polly
        }
    } elseif {${subport} eq "clang-${llvm_version}"} {
        ln -s ${workpath}/llvm-project/clang                            ${worksrcpath}/tools/clang
        ln -s ${workpath}/llvm-project/compiler-rt                      ${worksrcpath}/projects/compiler-rt
        ln -s ${workpath}/llvm-project/libcxx                           ${worksrcpath}/projects/libcxx
        ln -s ${workpath}/llvm-project/libcxxabi                        ${worksrcpath}/projects/libcxxabi
        ln -s ${workpath}/llvm-project/lld                              ${worksrcpath}/projects/lld
        ln -s ${workpath}/llvm-project/clang-tools-extra                ${worksrcpath}/tools/clang/tools/extra
    } elseif {${subport} eq "flang-${llvm_version}"} {
        ln -s ${workpath}/llvm-project/mlir                             ${worksrcpath}/tools/mlir
        ln -s ${workpath}/llvm-project/flang                            ${worksrcpath}/tools/flang
    } elseif {${subport} eq "lldb-${llvm_version}"} {
        ln -s ${workpath}/llvm-project/clang                            ${worksrcpath}/tools/clang
        ln -s ${workpath}/llvm-project/lldb                             ${worksrcpath}/tools/lldb
    }
}

patch.pre_args-replace  -p0 -p1
patchfiles \
    0002-Define-EXC_MASK_CRASH-and-MACH_EXCEPTION_CODES-if-th.patch \
    0003-MacPorts-Only-Don-t-embed-the-deployment-target-in-t.patch \
    0005-Threading-Only-call-pthread_setname_np-on-SnowLeopar.patch \
    0006-Only-call-setpriority-PRIO_DARWIN_THREAD-0-PRIO_DARW.patch \
    0008-patch-lib-support-unix-path-copyfileclone-on-older-systems.diff \
    0009-x86-pad-for-align.diff

if {${subport} eq "clang-${llvm_version}"} {
    patchfiles-append \
        1001-MacPorts-Only-Prepare-clang-format-for-replacement-w.patch \
        1002-MacPorts-Only-Fix-name-of-scan-view-executable-insid.patch \
        1004-Default-to-fragile-ObjC-runtime-when-targeting-darwi.patch \
        1005-Fixup-libstdc-header-search-paths-for-older-versions.patch \
        1007-Fix-float.h-to-work-on-Snow-Leopard-and-earlier.patch \
        1008-compilerrt-fuzzer-missingdefs.diff \
        1009-compilerrt-sanitizer-missingdefs.diff \
        2002-Work-around-no-libdispatch-on-10.6.patch \
        3001-Fix-missing-long-long-math-prototypes-when-using-the.patch \
        3002-implement-atomic-using-mutex-lock_guard-for-64b-ops-.patch \
        3003-patch-libcxx-chrono-restore-steadyclock-fallback.diff \
        openmp-locations.patch \
        leopard-no-asan.patch \
        5000-patch-compilerrtdarwinutils-find-macosxsdkversion.diff \
        5002-patch-toolchains-darwin-add-back-pre-10.6-link-libs.diff \
        patch-clang-fix-include-next-sysroot-cpp-headers.diff
}

if {${subport} eq "flang-${llvm_version}"} {
# no patches needed at present.
}

if {${subport} eq "lldb-${llvm_version}"} {
    # lldb needs the clang sources present, so we apply the applicable patches.
    patchfiles-append \
        1001-MacPorts-Only-Prepare-clang-format-for-replacement-w.patch \
        1002-MacPorts-Only-Fix-name-of-scan-view-executable-insid.patch \
        1004-Default-to-fragile-ObjC-runtime-when-targeting-darwi.patch \
        1005-Fixup-libstdc-header-search-paths-for-older-versions.patch \
        1007-Fix-float.h-to-work-on-Snow-Leopard-and-earlier.patch \
        openmp-locations.patch \
        patch-lldb-stdc-macros-134877.diff \
        patch-lldb-fix-swig-lvalue-2128646.diff
}

configure.post_args         ../${worksrcdir}
default configure.dir       {${workpath}/build}
default build.dir           {${workpath}/build}

cmake.install_prefix ${sub_prefix}

# clang shared libraries are not all installed in ${cmake.install_prefix}/lib
# so we have to let the llvm/clang cmake scripts handle the @rpath setting
# See:
#     https://llvm.org/bugs/show_bug.cgi?id=31425
#     https://trac.macports.org/ticket/53299
configure.args-delete \
    -DCMAKE_INSTALL_NAME_DIR=${cmake.install_prefix}/lib \
    -DCMAKE_INSTALL_RPATH=${cmake.install_prefix}/lib

configure.args-replace \
    -DCMAKE_SYSTEM_PREFIX_PATH="${prefix}\;/usr" \
    -DCMAKE_SYSTEM_PREFIX_PATH="${cmake.install_prefix}\;${prefix}\;/usr"

configure.args-append \
    -DLLVM_LINK_LLVM_DYLIB=ON \
    -DLLVM_ENABLE_ASSERTIONS=OFF \
    -DLLVM_ENABLE_RTTI=ON \
    -DLLVM_INCLUDE_TESTS=OFF \
    -DLLVM_INCLUDE_EXAMPLES=OFF \
    -DLLVM_BINDINGS_LIST=none \
    -DLLVM_ENABLE_FFI=ON \
    -DFFI_INCLUDE_DIR=${prefix}/include \
    -DFFI_LIBRARY_DIR=${prefix}/lib

if {${subport} eq "clang-${llvm_version}"} {
    # CMAKE_LINKER is used to determine the value for HOST_LINK_VERSION
    configure.args-append \
        -DCMAKE_LINKER=${prefix}/bin/ld \
        -DLD64_EXECUTABLE=${prefix}/bin/ld \
        -DCLANG_INCLUDE_TESTS=OFF \
        -DCLANG_ENABLE_STATIC_ANALYZER=OFF \
        -DCLANG_ENABLE_ARCMT=OFF \
        -DDARWIN_PREFER_PUBLIC_SDK=ON \
        -DLLVM_BUILD_RUNTIME=ON \
        -DLIBCXX_ENABLE_SHARED=ON \
        -DLIBCXX_INSTALL_LIBRARY=ON

} elseif {${subport} eq "flang-${llvm_version}"} {

    # CMAKE_LINKER is used to determine the value for HOST_LINK_VERSION
    configure.args-append \
        -DCMAKE_LINKER=${prefix}/bin/ld \
        -DLD64_EXECUTABLE=${prefix}/bin/ld \
        -DCLANG_INCLUDE_TESTS=OFF \
        -DCLANG_ENABLE_STATIC_ANALYZER=OFF \
        -DCLANG_ENABLE_ARCMT=OFF \
        -DDARWIN_PREFER_PUBLIC_SDK=ON \
        -DLLVM_BUILD_RUNTIME=ON \
        -DLIBCXX_ENABLE_SHARED=OFF \
        -DLIBCXX_INSTALL_LIBRARY=OFF

# useful in clang-devel and newer
#        configure.args-append -DFLANG_BUILD_NEW_DRIVER=ON

} elseif {${subport} eq "lldb-${llvm_version}"} {
    configure.args-append \
        -DLLDB_CODESIGN_IDENTITY=- \
        -DLLDB_ENABLE_LUA=OFF \
        -DCLANG_INCLUDE_TESTS=OFF \
        -DCLANG_ENABLE_STATIC_ANALYZER=OFF \
        -DCLANG_ENABLE_ARCMT=OFF \
        -DLLVM_BUILD_RUNTIME=ON \
        -DLIBCXX_ENABLE_SHARED=OFF \
        -DLIBCXX_INSTALL_LIBRARY=OFF
}

# not building with macports-clang up to 3.7
# error: no type named 'type' in 'std::__1::enable_if<false, void>'; 'enable_if' cannot be used to disable this declaration
#                 ,typename enable_if<is_convertible<const _U1&, _T1>::value &&
#                                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# clang-1000.11.45.5 gives missing symbols for ZTIDu and others during libcxxabi build
compiler.blacklist *gcc* {clang < 1001} macports-clang-3.*

# Override the normal compiler fallback list entirely since we have
# such specific requirements.
compiler.fallback   clang

# fall back to clang-9.0 when system clang is too old
# clang-9.0 was that last one that built with clang-3.7
compiler.fallback-append macports-clang-9.0

# cctools is needed to handle objects from newer clang toolchains
if {[string match macports-clang-* ${configure.compiler}]} {
    depends_build-append port:cctools
    depends_skip_archcheck-append cctools
}

if {${os.major} <= 14} {
    # compiler-rt does a broad search for an SDK it likes, but this
    # search fails on older systems that don't have a MacOSX.sdk
    # TODO: apply this always to all systems?
    if {${configure.sdkroot} eq ""} {set configure.sdkroot "/"}
    configure.args-append -DDARWIN_osx_SYSROOT="${configure.sdkroot}"
}

# Set CMAKE_LIBTOOL if we're using MacPorts-provided cctools
if {[lsearch -exact $PortInfo(depends_build) port:cctools] != -1} {
    configure.args-append \
        -DCMAKE_LIBTOOL=${prefix}/bin/libtool
}

depends_build-append    port:python310
set pythonfullpath      ${prefix}/bin/python3.10
configure.args-append   -D_Python3_EXECUTABLE=${pythonfullpath}

platform darwin {
    # Note that we are forcing this choice.  This means that anything linking
    # against llvm needs to also be using libc++.  This is possibly
    # problematic, but luckily there is just a limited set of such dependents.

    configure.cxx_stdlib libc++
    depends_lib-append port:libcxx

    if {${os.major} < 11} {
        # exclude older systems from trying to build this as ppc
        # otherwise we can use MacPort's base defaults for the rest
        supported_archs i386 x86_64
        pre-fetch {
            if {![file exists /usr/lib/libc++.dylib]} {
                ui_error "$name requires a C++11 runtime, which your configuration does not allow"
                error "unsupported configuration"
            }
        }
    }
    if {${subport} eq "flang-${llvm_version}"} {
        supported_archs arm64 x86_64
    }
}

variant assertions description "Enable assertions for error detection (has performance impacts, especially on JIT)" {
    configure.args-delete -DLLVM_ENABLE_ASSERTIONS=OFF
    configure.args-append -DLLVM_ENABLE_ASSERTIONS=ON
}

platform darwin {

    if {${subport} eq "clang-${llvm_version}"} {

        if {${os.major} <= 18} {
            # on systems that might build i386, we need atomic builtins
            # https://trac.macports.org/ticket/58712
            configure.args-append    -DCOMPILER_RT_EXCLUDE_ATOMIC_BUILTIN=OFF
        }

        if {${os.major} == 14} {
            # Building Xray forces build of sanitizer_common, even if
            # COMPILER_RT_BUILD_SANITIZERS=OFF, and this fails on 10.10
            # TODO: See why sanitizer_common fails on 10.10
            configure.args-append    -DCOMPILER_RT_BUILD_XRAY=OFF
        }

        if {${os.major} <= 14} {
            # We unfortunately don't have an option to just turn off tsan
            # https://llvm.org/bugs/show_bug.cgi?id=27715
            configure.args-append    -DCOMPILER_RT_BUILD_SANITIZERS=OFF
        }

        if {${os.major} <= 11} {
            # xpc.h available 10.7 but doesn't support nullable features
            # xpc.h works currently on 10.8+
            # toggle enabled in https://reviews.llvm.org/D59808
            configure.args-append    -DCLANGD_BUILD_XPC=OFF
        }

        if {${os.major} <= 10} {
            # avoid need for thread_local_storage
            configure.args-append -DCLANG_ENABLE_CLANGD=OFF
            configure.args-append -DLLVM_ENABLE_BACKTRACES=OFF

            # the directorywatcher code is currently 10.7+
            patchfiles-append 5003-patch-no-directory-watcher-on-snowleopard.diff

            # reexported_symbols_list is available on 10.7+ only, used by libcxx
            patchfiles-append 5004-patch-libcxx-reexport-symbols-lionorgreater-only.diff

            # the libcxx installed by MacPorts on darwin 10 and less does not correspond to Apple's builtin libcxx
            patchfiles-append 5005-MacPorts-only-patch-libcxx-includes-disable-availability-tests.diff
        }

        if {${os.major} <= 9} {
            # TO DO: the blocks functionality can be replaced by libblocksruntime
            # this might be integrated into clang on < 10.6
            patchfiles-append leopard-no-blocks.patch

            # Building Xray forces build of sanitizer_common, even if
            # COMPILER_RT_BUILD_SANITIZERS=OFF, and this fails on 10.5
            # due to lack of pthread_getname_np
            configure.args-append    -DCOMPILER_RT_BUILD_XRAY=OFF

            # on Leopard part of symbols like __udivdi3 in -lgcc_s.1 instead of -lSystem
            patchfiles-append leopard-link-against-gcc_s.diff
        }
    }
}

if {${subport} eq "lldb-${llvm_version}"} {
    platforms {darwin >= 17} {darwin < 23}
}

if {${subport} eq "clang-${llvm_version}"} {
    destroot {
        system "cd ${destroot.dir}/tools/clang && ${destroot.cmd} ${destroot.pre_args} ${destroot.target} ${destroot.post_args}"
        system "cd ${destroot.dir}/projects/compiler-rt && ${destroot.cmd} ${destroot.pre_args} ${destroot.target} ${destroot.post_args}"
        system "cd ${destroot.dir}/projects/libcxx && ${destroot.cmd} ${destroot.pre_args} ${destroot.target} ${destroot.post_args}"
        system "cd ${destroot.dir}/projects/libcxxabi && ${destroot.cmd} ${destroot.pre_args} ${destroot.target} ${destroot.post_args}"
        system "cd ${destroot.dir}/projects/lld && ${destroot.cmd} ${destroot.pre_args} ${destroot.target} ${destroot.post_args}"

        delete ${destroot}${sub_prefix}/bin/clang
        file rename ${destroot}${sub_prefix}/bin/clang-${clang_executable_version} ${destroot}${sub_prefix}/bin/clang
        reinplace "s|/bin/clang-${clang_executable_version}|/bin/clang|g" \
            "${destroot}${sub_prefix}/lib/cmake/clang/ClangTargets-release.cmake"
    }
}

if {${subport} eq "flang-${llvm_version}"} {
    destroot {
        system "cd ${destroot.dir}/tools/mlir && ${destroot.cmd} ${destroot.pre_args} ${destroot.target} ${destroot.post_args}"
        system "cd ${destroot.dir}/tools/flang && ${destroot.cmd} ${destroot.pre_args} ${destroot.target} ${destroot.post_args}"

        system "chmod 755 ${destroot}${sub_prefix}/bin/flang"
    }

    notes-append {
        This version of flang passes off to another fortran compiler to do the actual compiling.
        At present, you may need to set the desired fortran compiler with an ENV VAR if\
        the default gfortran is not found on PATH.
        For example: F18_FC=gfortran-mp-10 flang-mp-11 hello.f90 -o hello.bin
        See  https://github.com/llvm/llvm-project/blob/master/flang/docs/ReleaseNotes.md
    }
}

if {${subport} eq "lldb-${llvm_version}"} {
    post-patch {
        reinplace "s|@@PREFIX@@|${prefix}|" \
            ${worksrcpath}/tools/clang/lib/Driver/ToolChains/Clang.cpp \
            ${worksrcpath}/tools/clang/lib/Driver/ToolChains/CommonArgs.cpp

        reinplace "s|@CLANG_FORMAT_PATH@|${prefix}/bin/clang-format-${suffix}|g" \
            ${worksrcpath}/tools/clang/tools/clang-format/clang-format-bbedit.applescript \
            ${worksrcpath}/tools/clang/tools/clang-format/clang-format-diff.py            \
            ${worksrcpath}/tools/clang/tools/clang-format/clang-format-sublime.py         \
            ${worksrcpath}/tools/clang/tools/clang-format/clang-format.el                 \
            ${worksrcpath}/tools/clang/tools/clang-format/clang-format.py
    }

    build.dir   ${build.dir}/tools/lldb

    notes "Please follow the instructions at https://lldb.llvm.org/resources/build.html#code-signing-on-macos and then codesign lldb-server with:\n--------------------\n"
    notes-append "${sub_prefix}/scripts/lldb/macos-setup-codesign.sh"
    if {${os.major} >= 13} {
        notes-append "sudo codesign --force --deep --preserve-metadata=identifier,entitlements,resource-rules,requirements,flags,team-identifier --sign lldb_codesign ${sub_prefix}/bin/lldb-server"
    } else {
        notes-append "sudo codesign --force --deep --preserve-metadata=identifier,entitlements,resource-rules,requirements --sign lldb_codesign ${sub_prefix}/bin/lldb-server"
    }
}

post-destroot {
    foreach bin [glob ${destroot}${sub_prefix}/bin/*] {
        set bin_filename [string map "${sub_prefix} ${prefix}" ${bin}]-${suffix}
        set exec_path [string map "${destroot}${sub_prefix} ${sub_prefix}" ${bin}]

        # see https://trac.macports.org/ticket/54985
        if {${os.platform} eq "darwin" && [vercmp ${xcodeversion} 4.6] < 0} {
             xinstall -m 755 "${filespath}/llvm-bin-compat" "${bin_filename}"
        } else {
             xinstall -m 755 "${filespath}/llvm-bin" "${bin_filename}"
        }

        reinplace "s:EXEC_PATH:${exec_path}:" "${bin_filename}"
    }

    if {${subport} eq "llvm-${llvm_version}"} {
        # r156389 (a5d2435409858728970202226d0bbbee508fe408) temporarilary removed llvm man pages
        #foreach man [glob ${destroot}${sub_prefix}/share/man/man1/*.1] {
        #    set basename [string map "${destroot}${sub_prefix}/share/man/man1/ {}" ${man}]
        #    file rename ${man} ${destroot}${prefix}/share/man/man1/[string map ".1 -${suffix}.1" ${basename}]
        #}

        # https://llvm.org/bugs/show_bug.cgi?id=19465
        if {[variant_isset polly]} {
            ln -s LLVMPolly.so ${destroot}${sub_prefix}/lib/LLVMPolly.dylib
        }
    } elseif {${subport} eq "clang-${llvm_version}"} {
        system "ditto ${worksrcpath}/projects/libcxx/include ${destroot}${sub_prefix}/lib/c++/v1"

        # http://trac.macports.org/ticket/33207
        ln -s ${prefix}/libexec/ld64/ld ${destroot}${sub_prefix}/bin/ld
    } elseif {${subport} eq "lldb-${llvm_version}"} {
        delete ${destroot}${prefix}/bin/debugserver-${suffix}

        set lldb_scripts_srcdir ${worksrcpath}/tools/lldb/scripts
        set lldb_scripts_destdir ${destroot}${sub_prefix}/scripts/lldb
        xinstall -d ${lldb_scripts_destdir}
        xinstall -m 755 -W ${lldb_scripts_srcdir} \
            macos-setup-codesign.sh \
            ${lldb_scripts_destdir}
    }
}

variant emulated_tls description { enable c11/c++11 thread_local_storage support on older systems using emulated-tls } {
    # use emulated-tls to support thread_local on systems prior to 10.7
    patchfiles-append      9000-patch-llvm-7.0-support-emulated-tls.diff
    if {${subport} eq "clang-${llvm_version}"} {
        patchfiles-append  9000-patch-clang-7.0-support-emulated-tls.diff
    }
}
default_variants-append +emulated_tls

if {${subport} eq "llvm-${llvm_version}"} {
    variant polly description {Provide the polly polyhedral optimizer} {}

    # Unless upstream reverts to their old OCaml detection mechanism,
    # this variant will be broken until #46161 is resolved.
    variant ocaml description {Enable generation of OCaml binding} {
        depends_lib-append   port:ocaml

        configure.args-delete -DLLVM_BINDINGS_LIST=none
        configure.args-append -DLLVM_BINDINGS_LIST=ocaml

        destroot.args-append  OVERRIDE_libdir=${sub_prefix}/lib
    }
} elseif {${subport} eq "clang-${llvm_version}"} {
    if {[variant_isset assertions]} {
        # Need to match llvm +-assertions
        require_active_variants port:llvm-${llvm_version} assertions
    } else {
        # Need to match llvm +-assertions
        require_active_variants port:llvm-${llvm_version} {} assertions
    }

    variant analyzer description {Install clang static analyzer} {
        # these have to be switched on or off together
        configure.args-replace -DCLANG_ENABLE_STATIC_ANALYZER=OFF \
                               -DCLANG_ENABLE_STATIC_ANALYZER=ON
        configure.args-replace -DCLANG_ENABLE_ARCMT=OFF \
                               -DCLANG_ENABLE_ARCMT=ON

        depends_run-append port:perl5
        depends_build-delete    port:python310
        depends_lib-append      port:python310

        post-patch {
            reinplace "s|/usr/bin/env perl|${prefix}/bin/perl5|g" \
                ${worksrcpath}/tools/clang/tools/scan-build/libexec/ccc-analyzer \
                ${worksrcpath}/tools/clang/tools/scan-build/libexec/c++-analyzer \
                ${worksrcpath}/tools/clang/tools/scan-build/bin/scan-build

            # pythonfullpath is set above, depending on presence of system python2.7
            reinplace "s|/usr/bin/env python|${pythonfullpath}|g" \
                 ${worksrcpath}/tools/clang/tools/scan-view/bin/scan-view

            reinplace "s|/usr/bin/python|${pythonfullpath}|g" \
                ${worksrcpath}/tools/clang/tools/scan-build/bin/set-xcode-analyzer
        }
    }

    if { ${cxx_stdlib} eq "libc++" && ${os.major} < 13 } {
        variant defaultlibcxx description {default to -stdlib=libc++ if not otherwise specified}  {
            # on systems older than darwin 13, if macports.conf is configured to stdlib=libc++
            # then make that the default if not otherwise specified. This matches the behaviour of newer systems.
            patchfiles-append 9003-patch-clang-7.0-default-to-libcxx-on-all-systems.diff
        }
        default_variants-append +defaultlibcxx
    }

    variant libstdcxx description {-stdlib=libstdc++_macports searches for MacPorts libstdc++} {

        patchfiles-append 9001-macports-libstdcxx.diff
        if {${os.major} < 11} {
            # see https://trac.macports.org/ticket/61778
            depends_run-append  port:libstdcxx_clang_fix
        }

        post-patch {
            reinplace "s|@@MACPORTS_GCC_INCLUDE_DIR@@|${prefix}/include/gcc/c++|g" \
                ${worksrcpath}/tools/clang/lib/Frontend/InitHeaderSearch.cpp \
                ${worksrcpath}/tools/clang/lib/Driver/ToolChains/Darwin.cpp
            reinplace "s|@@MACPORTS_HOST_NAME@@|${configure.build_arch}-apple-darwin${os.major}|g" \
                ${worksrcpath}/tools/clang/lib/Driver/ToolChains/Darwin.cpp
            reinplace "s|@@MACPORTS_libstdc++@@|${prefix}/lib/libgcc/libstdc++.6.dylib|g" \
                ${worksrcpath}/tools/clang/lib/Driver/ToolChains/Darwin.cpp

            # GCC was built for ${configure.build_arch}-apple-darwin${os.major}
            # if GCC was also built universal, it has an extra include directory
            # if ${configure.build_arch} is 32-bit, there is an extra 64-bit subdirectory
            # if ${configure.build_arch} is 64-bit, there is an extra 32-bit subdirectory
            # MacPorts GCC cannot compile across platforms
            switch ${configure.build_arch} {
                x86_64 {
                    reinplace {s|@@MACPORTS_TEST_32_64@@|getTriple().getArch() == llvm::Triple::x86_64 ? "" : "i386"|g} \
                        ${worksrcpath}/tools/clang/lib/Driver/ToolChains/Darwin.cpp
                }
                i386 {
                    reinplace {s|@@MACPORTS_TEST_32_64@@|getTriple().getArch() == llvm::Triple::x86_64 ? "x86_64" : ""|g} \
                        ${worksrcpath}/tools/clang/lib/Driver/ToolChains/Darwin.cpp
                }
                ppc64 {
                    reinplace {s|@@MACPORTS_TEST_32_64@@|getTriple().getArch() == llvm::Triple::ppc64 ? "" : "ppc"|g} \
                        ${worksrcpath}/tools/clang/lib/Driver/ToolChains/Darwin.cpp
                }
                ppc {
                    reinplace {s|@@MACPORTS_TEST_32_64@@|getTriple().getArch() == llvm::Triple::ppc64 ? "ppc64" : ""|g} \
                        ${worksrcpath}/tools/clang/lib/Driver/ToolChains/Darwin.cpp
                }
                arm64 {
                    reinplace {s|@@MACPORTS_TEST_32_64@@|""|g} \
                        ${worksrcpath}/tools/clang/lib/Driver/ToolChains/Darwin.cpp
                }
            }
        }
    }
    if { ${cxx_stdlib} eq "libstdc++" } {
        default_variants-append +libstdcxx
    }

    post-patch {
        reinplace "s|@@PREFIX@@|${prefix}|" \
            ${worksrcpath}/tools/clang/lib/Driver/ToolChains/Clang.cpp \
            ${worksrcpath}/tools/clang/lib/Driver/ToolChains/CommonArgs.cpp

        reinplace "s|@CLANG_FORMAT_PATH@|${prefix}/bin/clang-format-${suffix}|g" \
            ${worksrcpath}/tools/clang/tools/clang-format/clang-format-bbedit.applescript \
            ${worksrcpath}/tools/clang/tools/clang-format/clang-format-diff.py            \
            ${worksrcpath}/tools/clang/tools/clang-format/clang-format-sublime.py         \
            ${worksrcpath}/tools/clang/tools/clang-format/clang-format.el                 \
            ${worksrcpath}/tools/clang/tools/clang-format/clang-format.py
    }

    post-destroot {
        file mkdir ${destroot}${sub_prefix}/libexec
        file copy ${worksrcpath}/tools/clang/tools/clang-format ${destroot}${sub_prefix}/libexec/clang-format

        file delete -force ${destroot}${sub_prefix}/libexec/clang-format/.svn
        file delete -force ${destroot}${sub_prefix}/libexec/clang-format/Makefile
        file delete -force ${destroot}${sub_prefix}/libexec/clang-format/Release+Debug+Asserts
        file delete -force ${destroot}${sub_prefix}/libexec/clang-format/CMakeLists.txt
        file delete -force ${destroot}${sub_prefix}/libexec/clang-format/ClangFormat.cpp
    }
}

livecheck.type          none
