Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
27 changes: 23 additions & 4 deletions src/compiler/c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ where
pub enum Language {
C,
Cxx,
GenericHeader,
CHeader,
CxxHeader,
ObjectiveC,
ObjectiveCxx,
Cuda,
Expand Down Expand Up @@ -131,12 +134,14 @@ impl Language {
match file.extension().and_then(|e| e.to_str()) {
// gcc: https://gcc.gnu.org/onlinedocs/gcc/Overall-Options.html
Some("c") => Some(Language::C),
// Could be C or C++
Some("h") => Some(Language::GenericHeader),
// TODO i
Some("C") | Some("cc") | Some("cp") | Some("cpp") | Some("CPP") | Some("cxx")
| Some("c++") => Some(Language::Cxx),
// TODO ii
// TODO H hh hp hpp HPP hxx h++
// TODO tcc
Some("H") | Some("hh") | Some("hp") | Some("hpp") | Some("HPP") | Some("hxx")
| Some("h++") | Some("tcc") => Some(Language::CxxHeader),
Some("m") => Some(Language::ObjectiveC),
// TODO mi
Some("M") | Some("mm") => Some(Language::ObjectiveCxx),
Expand All @@ -151,8 +156,9 @@ impl Language {

pub fn as_str(self) -> &'static str {
match self {
Language::C => "c",
Language::Cxx => "c++",
Language::C | Language::CHeader => "c",
Language::Cxx | Language::CxxHeader => "c++",
Copy link
Contributor

Choose a reason for hiding this comment

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

FYI this led to issue #1851 and to commit b881869 to remediate.

Language::GenericHeader => "c/c++",
Language::ObjectiveC => "objc",
Language::ObjectiveCxx => "objc++",
Language::Cuda => "cuda",
Expand Down Expand Up @@ -874,6 +880,17 @@ mod test {
t("cxx", Language::Cxx);
t("c++", Language::Cxx);

t("h", Language::GenericHeader);

t("hh", Language::CxxHeader);
t("H", Language::CxxHeader);
t("hp", Language::CxxHeader);
t("hxx", Language::CxxHeader);
t("hpp", Language::CxxHeader);
t("HPP", Language::CxxHeader);
t("h++", Language::CxxHeader);
t("tcc", Language::CxxHeader);

t("m", Language::ObjectiveC);

t("M", Language::ObjectiveCxx);
Expand All @@ -895,6 +912,8 @@ mod test {
// gcc parses file-extensions as case-sensitive
t("Cp");
t("Cpp");
t("Hp");
t("Hpp");
t("Mm");
t("Cu");
}
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/clang.rs
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ mod test {
"pch.hxx.cxx"
);
assert_eq!(Some("pch.hxx.cxx"), a.input.to_str());
assert_eq!(Language::Cxx, a.language);
assert_eq!(Language::CxxHeader, a.language);
assert_map_contains!(
a.outputs,
(
Expand Down
147 changes: 113 additions & 34 deletions src/compiler/gcc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,9 @@ where
Some(Language(lang)) => {
language = match lang.to_string_lossy().as_ref() {
"c" => Some(Language::C),
"c++" | "c++-header" => Some(Language::Cxx),
"c-header" => Some(Language::CHeader),
"c++" => Some(Language::Cxx),
"c++-header" => Some(Language::CxxHeader),
"objective-c" => Some(Language::ObjectiveC),
"objective-c++" => Some(Language::ObjectiveCxx),
"cu" => Some(Language::Cuda),
Expand Down Expand Up @@ -604,6 +606,19 @@ where
})
}

fn language_to_gcc_arg(lang: Language) -> Option<&'static str> {
match lang {
Language::C => Some("c"),
Language::CHeader => Some("c-header"),
Language::Cxx => Some("c++"),
Language::CxxHeader => Some("c++-header"),
Language::ObjectiveC => Some("objective-c"),
Language::ObjectiveCxx => Some("objective-c++"),
Language::Cuda => Some("cu"),
Language::GenericHeader => None, // Let the compiler decide
}
}

#[allow(clippy::too_many_arguments)]
fn preprocess_cmd<T>(
cmd: &mut T,
Expand All @@ -617,14 +632,11 @@ fn preprocess_cmd<T>(
) where
T: RunCommand,
{
let language = match parsed_args.language {
Language::C => "c",
Language::Cxx => "c++",
Language::ObjectiveC => "objective-c",
Language::ObjectiveCxx => "objective-c++",
Language::Cuda => "cu",
};
cmd.arg("-x").arg(language).arg("-E");
let language = language_to_gcc_arg(parsed_args.language);
if let Some(lang) = &language {
cmd.arg("-x").arg(lang);
}
cmd.arg("-E");
// When performing distributed compilation, line number info is important for error
// reporting and to not cause spurious compilation failure (e.g. no exceptions build
// fails due to exceptions transitively included in the stdlib).
Expand Down Expand Up @@ -743,21 +755,17 @@ pub fn generate_compile_commands(

// Pass the language explicitly as we might have gotten it from the
// command line.
let language = match parsed_args.language {
Language::C => "c",
Language::Cxx => "c++",
Language::ObjectiveC => "objective-c",
Language::ObjectiveCxx => "objective-c++",
Language::Cuda => "cu",
};
let mut arguments: Vec<OsString> = vec![
"-x".into(),
language.into(),
let language = language_to_gcc_arg(parsed_args.language);
let mut arguments: Vec<OsString> = vec![];
if let Some(lang) = &language {
arguments.extend(vec!["-x".into(), lang.into()])
}
arguments.extend(vec![
parsed_args.compilation_flag.clone(),
parsed_args.input.clone().into(),
"-o".into(),
out_file.into(),
];
]);
arguments.extend(parsed_args.preprocessor_args.clone());
arguments.extend(parsed_args.unhashed_args.clone());
arguments.extend(parsed_args.common_args.clone());
Expand All @@ -774,28 +782,27 @@ pub fn generate_compile_commands(
#[cfg(feature = "dist-client")]
let dist_command = (|| {
// https://gcc.gnu.org/onlinedocs/gcc-4.9.0/gcc/Overall-Options.html
let mut language: String = match parsed_args.language {
Language::C => "c",
Language::Cxx => "c++",
Language::ObjectiveC => "objective-c",
Language::ObjectiveCxx => "objective-c++",
Language::Cuda => "cu",
}
.into();
let mut language: Option<String> =
language_to_gcc_arg(parsed_args.language).map(|lang| lang.into());
if !rewrite_includes_only {
match parsed_args.language {
Language::C => language = "cpp-output".into(),
_ => language.push_str("-cpp-output"),
Language::C => language = Some("cpp-output".into()),
Language::GenericHeader | Language::CHeader | Language::CxxHeader => {}
_ => language.as_mut()?.push_str("-cpp-output"),
}
}
let mut arguments: Vec<String> = vec![
"-x".into(),
language,

let mut arguments: Vec<String> = vec![];
// Language needs to be before input
if let Some(lang) = &language {
arguments.extend(vec!["-x".into(), lang.into()])
}
arguments.extend(vec![
parsed_args.compilation_flag.clone().into_string().ok()?,
path_transformer.as_dist(&parsed_args.input)?,
"-o".into(),
path_transformer.as_dist(out_file)?,
];
]);
if let CCompilerKind::Gcc = kind {
// From https://gcc.gnu.org/onlinedocs/gcc/Preprocessor-Options.html:
//
Expand Down Expand Up @@ -1943,4 +1950,76 @@ mod test {
assert!(common_args.is_empty());
assert!(!msvc_show_includes);
}

#[test]
fn test_pch_explicit() {
let args = stringvec!["-c", "-x", "c++-header", "pch.h", "-o", "pch.pch"];
let parsed_args = match parse_arguments_(args, false) {
CompilerArguments::Ok(args) => args,
o => panic!("Got unexpected parse result: {:?}", o),
};
let mut cmd = MockCommand {
child: None,
args: vec![],
};
preprocess_cmd(
&mut cmd,
&parsed_args,
Path::new(""),
&[],
true,
CCompilerKind::Gcc,
true,
vec![],
);
assert!(cmd.args.contains(&"-x".into()) && cmd.args.contains(&"c++-header".into()));
}

#[test]
fn test_pch_implicit() {
let args = stringvec!["-c", "pch.hpp", "-o", "pch.pch"];
let parsed_args = match parse_arguments_(args, false) {
CompilerArguments::Ok(args) => args,
o => panic!("Got unexpected parse result: {:?}", o),
};
let mut cmd = MockCommand {
child: None,
args: vec![],
};
preprocess_cmd(
&mut cmd,
&parsed_args,
Path::new(""),
&[],
true,
CCompilerKind::Gcc,
true,
vec![],
);
assert!(cmd.args.contains(&"-x".into()) && cmd.args.contains(&"c++-header".into()));
}

#[test]
fn test_pch_generic() {
let args = stringvec!["-c", "pch.h", "-o", "pch.pch"];
let parsed_args = match parse_arguments_(args, false) {
CompilerArguments::Ok(args) => args,
o => panic!("Got unexpected parse result: {:?}", o),
};
let mut cmd = MockCommand {
child: None,
args: vec![],
};
preprocess_cmd(
&mut cmd,
&parsed_args,
Path::new(""),
&[],
true,
CCompilerKind::Gcc,
true,
vec![],
);
assert!(!cmd.args.contains(&"-x".into()));
}
}
13 changes: 7 additions & 6 deletions src/compiler/nvcc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,13 @@ impl CCompilerImpl for Nvcc {
T: CommandCreatorSync,
{
let language = match parsed_args.language {
Language::C => "c",
Language::Cxx => "c++",
Language::ObjectiveC => "objective-c",
Language::ObjectiveCxx => "objective-c++",
Language::Cuda => "cu",
};
Language::C => Ok("c"),
Language::Cxx => Ok("c++"),
Language::ObjectiveC => Ok("objective-c"),
Language::ObjectiveCxx => Ok("objective-c++"),
Language::Cuda => Ok("cu"),
_ => Err(anyhow!("PCH not supported by nvcc")),
}?;

let initialize_cmd_and_args = || {
let mut command = creator.clone().new_command_sync(executable);
Expand Down