Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions clang/include/clang/Basic/DiagnosticFrontendKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ def err_fe_no_pch_in_dir : Error<
"no suitable precompiled header file found in directory '%0'">;
def err_fe_action_not_available : Error<
"action %0 not compiled in">;
def err_fe_invalid_multiple_actions : Error<
"action %0 is specified, another action is not allowed: %1">;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"action %0 is specified, another action is not allowed: %1">;
"'%1' action ignored; '%0' action specified previously">;

Maybe something like this? I dont think the original fits very well? Also the single ticks around the actions is, IMO, better for readability.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the suggestion. I adopted it by swapping %1 and %0 ...

def err_fe_invalid_alignment : Error<
"invalid value '%1' in '%0'; alignment must be a power of 2">;
def err_fe_invalid_exception_model
Expand Down
24 changes: 24 additions & 0 deletions clang/lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2841,6 +2841,30 @@ static bool ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
}

Opts.ProgramAction = *ProgramAction;

// Catch common mistakes when multiple actions are specified for cc1 (e.g.
// -S -emit-llvm means -emit-llvm while -emit-llvm -S means -S). However, to
// support driver `-c -Xclang ACTION` (-cc1 -emit-llvm file -main-file-name
// X ACTION), we suppress the error when the two actions are separated by
// -main-file-name.
//
// As an exception, accept composable -ast-dump*.
if (!A->getSpelling().starts_with("-ast-dump")) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason why use string-based prefix instead of checking for the OPT_ enums?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-ast-dump -ast-dump-lookups and -ast-dump-lookups -ast-dump are composable. llvm/utils/update_cc_test_checks.py appends -ast-dump=json when the cc1 command line may contain another action option.

Since there are 3+ -ast-dump* options that need an exception, I feel that starts_with("-ast-dump")) is simpler than listing all OPT_ast_dump*..

const Arg *SavedAction = nullptr;
for (const Arg *AA :
Args.filtered(OPT_Action_Group, OPT_main_file_name)) {
if (AA->getOption().matches(OPT_main_file_name)) {
SavedAction = nullptr;
} else if (!SavedAction) {
SavedAction = AA;
} else {
if (!A->getOption().matches(OPT_ast_dump_EQ))
Diags.Report(diag::err_fe_invalid_multiple_actions)
<< A->getSpelling() << SavedAction->getSpelling();
break;
}
}
}
}

if (const Arg* A = Args.getLastArg(OPT_plugin)) {
Expand Down
7 changes: 7 additions & 0 deletions clang/test/Frontend/multiple-actions.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// RUN: not %clang_cc1 -S -emit-llvm -main-file-name %s 2>&1 | FileCheck %s --check-prefix=ERR1 --implicit-check-not=error:
// ERR1: error: action -emit-llvm is specified, another action is not allowed: -S

// RUN: not %clang_cc1 -main-file-name %s -emit-llvm-only -emit-llvm -S 2>&1 | FileCheck %s --check-prefix=ERR2 --implicit-check-not=error:
// ERR2: error: action -S is specified, another action is not allowed: -emit-llvm-only

// RUN: %clang_cc1 -S -main-file-name %s -emit-llvm -o /dev/null