Index: clang/lib/Driver/Driver.cpp =================================================================== --- clang/lib/Driver/Driver.cpp +++ clang/lib/Driver/Driver.cpp @@ -1164,26 +1164,30 @@ unsigned short DisableFlags = options::NoDriverOption | options::Unsupported | options::Ignored; - // We want to show cc1-only options only when clang is invoked as "clang - // -cc1". When clang is invoked as "clang -cc1", we add "#" to the beginning - // of an --autocomplete option so that the clang driver can distinguish - // whether it is requested to show cc1-only options or not. - if (PassedFlags.size() > 0 && PassedFlags[0] == '#') { - DisableFlags &= ~options::NoDriverOption; - PassedFlags = PassedFlags.substr(1); + + // Parse PassedFlags by ":" as all the command-line flags are passed to this + // function separated by ":" + StringRef TargetFlag = PassedFlags; + for (; TargetFlag.find(':') != StringRef::npos;) { + StringRef CurFlag; + std::tie(CurFlag, TargetFlag) = TargetFlag.split(":"); + // We want to show cc1-only options only when clang is invoked with -cc1 or + // -Xclang. + if (CurFlag == "-Xclang" || CurFlag == "-cc1") + DisableFlags &= ~options::NoDriverOption; } - if (PassedFlags.find(',') == StringRef::npos) { + if (TargetFlag.find(',') == StringRef::npos) { // If the flag is in the form of "--autocomplete=-foo", // we were requested to print out all option names that start with "-foo". // For example, "--autocomplete=-fsyn" is expanded to "-fsyntax-only". - SuggestedCompletions = Opts->findByPrefix(PassedFlags, DisableFlags); + SuggestedCompletions = Opts->findByPrefix(TargetFlag, DisableFlags); // We have to query the -W flags manually as they're not in the OptTable. // TODO: Find a good way to add them to OptTable instead and them remove // this code. for (StringRef S : DiagnosticIDs::getDiagnosticFlags()) - if (S.startswith(PassedFlags)) + if (S.startswith(TargetFlag)) SuggestedCompletions.push_back(S); } else { // If the flag is in the form of "--autocomplete=foo,bar", we were @@ -1191,7 +1195,7 @@ // "bar". For example, // "--autocomplete=-stdlib=,l" is expanded to "libc++" and "libstdc++". StringRef Option, Arg; - std::tie(Option, Arg) = PassedFlags.split(','); + std::tie(Option, Arg) = TargetFlag.split(','); SuggestedCompletions = Opts->suggestValueCompletions(Option, Arg); } Index: clang/test/Driver/autocomplete.c =================================================================== --- clang/test/Driver/autocomplete.c +++ clang/test/Driver/autocomplete.c @@ -4,7 +4,6 @@ // Some corner cases. // RUN: %clang --autocomplete= | FileCheck %s -check-prefix=ALL_FLAGS -// RUN: %clang --autocomplete=# | FileCheck %s -check-prefix=ALL_FLAGS // Let's pick some example flags that are hopefully unlikely to change. // ALL_FLAGS: -fast // ALL_FLAGS: -fastcp @@ -93,10 +92,6 @@ // MRELOCMODELALL-NEXT: ropi-rwpi // MRELOCMODELALL-NEXT: rwpi // MRELOCMODELALL-NEXT: static -// RUN: %clang --autocomplete=-mrelocation-mode | FileCheck %s -check-prefix=MRELOCMODEL_CLANG -// MRELOCMODEL_CLANG-NOT: -mrelocation-model -// RUN: %clang --autocomplete=#-mrelocation-mode | FileCheck %s -check-prefix=MRELOCMODEL_CC1 -// MRELOCMODEL_CC1: -mrelocation-model // RUN: %clang --autocomplete=-Wma | FileCheck %s -check-prefix=WARNING // WARNING: -Wmacro-redefined // WARNING-NEXT: -Wmain @@ -110,3 +105,16 @@ // ANALYZER: unix.Malloc // RUN: %clang --autocomplete=-std=, | FileCheck %s -check-prefix=STDVAL // STDVAL: c99 +// +// Clang shouldn't autocomplete CC1 options unless -cc1 or -Xclang were provided +// RUN: %clang --autocomplete=-mrelocation-mode | FileCheck %s -check-prefix=MRELOCMODEL_CLANG +// MRELOCMODEL_CLANG-NOT: -mrelocation-model +// RUN: %clang --autocomplete=-Xclang:-mrelocation-mode | FileCheck %s -check-prefix=MRELOCMODEL_CC1 +// RUN: %clang --autocomplete=-cc1:-mrelocation-mode | FileCheck %s -check-prefix=MRELOCMODEL_CC1 +// MRELOCMODEL_CC1: -mrelocation-model +// Make sure it ignores passed flags unlesss they are -Xclang or -cc1 +// RUN: %clang --autocomplete=foo:bar::-fsyn | FileCheck %s -check-prefix=FSYN-CORON +// FSYN-CORON: -fsyntax-only +// Check if they can autocomplete values with coron +// RUN: %clang --autocomplete=foo::bar::::-fno-sanitize-coverage=,f | FileCheck %s -check-prefix=FNOSANICOVER-CORON +// FNOSANICOVER-CORON: func Index: clang/utils/bash-autocomplete.sh =================================================================== --- clang/utils/bash-autocomplete.sh +++ clang/utils/bash-autocomplete.sh @@ -25,11 +25,11 @@ w2="${COMP_WORDS[$cword - 2]}" fi - # Clang want to know if -cc1 or -Xclang option is specified or not, because we don't want to show - # cc1 options otherwise. - if [[ "${COMP_WORDS[1]}" == "-cc1" || "$w1" == "-Xclang" ]]; then - arg="#" - fi + # Pass all the current command-line flags to clang, so that clang can handle + # these internally. + for i in `seq 1 $(($cword-1))`; do + arg="$arg${COMP_WORDS[$i]}:" + done # bash always separates '=' as a token even if there's no space before/after '='. # On the other hand, '=' is just a regular character for clang options that