cxx_build/gen/
pragma.rs

1use crate::gen::out::{Content, OutFile};
2use std::collections::BTreeSet;
3
4#[derive(Default)]
5pub(crate) struct Pragma<'a> {
6    pub gnu_diagnostic_ignore: BTreeSet<&'a str>,
7    pub clang_diagnostic_ignore: BTreeSet<&'a str>,
8    pub dollar_in_identifier: bool,
9    pub missing_declarations: bool,
10    pub return_type_c_linkage: bool,
11    pub begin: Content<'a>,
12    pub end: Content<'a>,
13}
14
15impl<'a> Pragma<'a> {
16    pub fn new() -> Self {
17        Pragma::default()
18    }
19}
20
21pub(super) fn write(out: &mut OutFile) {
22    let Pragma {
23        ref mut gnu_diagnostic_ignore,
24        ref mut clang_diagnostic_ignore,
25        dollar_in_identifier,
26        missing_declarations,
27        return_type_c_linkage,
28        ref mut begin,
29        ref mut end,
30    } = out.pragma;
31
32    if dollar_in_identifier {
33        clang_diagnostic_ignore.insert("-Wdollar-in-identifier-extension");
34    }
35    if missing_declarations {
36        gnu_diagnostic_ignore.insert("-Wmissing-declarations");
37    }
38    if return_type_c_linkage {
39        clang_diagnostic_ignore.insert("-Wreturn-type-c-linkage");
40    }
41    let gnu_diagnostic_ignore = &*gnu_diagnostic_ignore;
42    let clang_diagnostic_ignore = &*clang_diagnostic_ignore;
43
44    if !gnu_diagnostic_ignore.is_empty() {
45        writeln!(begin, "#ifdef __GNUC__");
46        if out.header {
47            writeln!(begin, "#pragma GCC diagnostic push");
48        }
49        for diag in gnu_diagnostic_ignore {
50            writeln!(begin, "#pragma GCC diagnostic ignored \"{diag}\"");
51        }
52    }
53    if !clang_diagnostic_ignore.is_empty() {
54        writeln!(begin, "#ifdef __clang__");
55        if out.header && gnu_diagnostic_ignore.is_empty() {
56            writeln!(begin, "#pragma clang diagnostic push");
57        }
58        for diag in clang_diagnostic_ignore {
59            writeln!(begin, "#pragma clang diagnostic ignored \"{diag}\"");
60        }
61        writeln!(begin, "#endif // __clang__");
62    }
63    if !gnu_diagnostic_ignore.is_empty() {
64        writeln!(begin, "#endif // __GNUC__");
65    }
66
67    if out.header {
68        if !gnu_diagnostic_ignore.is_empty() {
69            writeln!(end, "#ifdef __GNUC__");
70            writeln!(end, "#pragma GCC diagnostic pop");
71            writeln!(end, "#endif // __GNUC__");
72        } else if !clang_diagnostic_ignore.is_empty() {
73            writeln!(end, "#ifdef __clang__");
74            writeln!(end, "#pragma clang diagnostic pop");
75            writeln!(end, "#endif // __clang__");
76        }
77    }
78}