Skip to content

Commit 0968df9

Browse files
authored
[clang-format] Add the C language instead of treating it like C++ (#128287)
Closes #128120
1 parent 8ff4d27 commit 0968df9

File tree

9 files changed

+40
-17
lines changed

9 files changed

+40
-17
lines changed

clang/docs/ClangFormatStyleOptions.rst

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4786,17 +4786,20 @@ the configuration (without a prefix: ``Auto``).
47864786

47874787
.. note::
47884788

4789-
You can also specify the language (``Cpp`` or ``ObjC``) for ``.h`` files
4790-
by adding a ``// clang-format Language:`` line before the first
4789+
You can specify the language (``C``, ``Cpp``, or ``ObjC``) for ``.h``
4790+
files by adding a ``// clang-format Language:`` line before the first
47914791
non-comment (and non-empty) line, e.g. ``// clang-format Language: Cpp``.
47924792

47934793
Possible values:
47944794

47954795
* ``LK_None`` (in configuration: ``None``)
47964796
Do not use.
47974797

4798+
* ``LK_C`` (in configuration: ``C``)
4799+
Should be used for C.
4800+
47984801
* ``LK_Cpp`` (in configuration: ``Cpp``)
4799-
Should be used for C, C++.
4802+
Should be used for C++.
48004803

48014804
* ``LK_CSharp`` (in configuration: ``CSharp``)
48024805
Should be used for C#.

clang/docs/ReleaseNotes.rst

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -271,9 +271,10 @@ clang-format
271271
- Adds ``BreakBeforeTemplateCloser`` option.
272272
- Adds ``BinPackLongBracedList`` option to override bin packing options in
273273
long (20 item or more) braced list initializer lists.
274-
- Allow specifying the language (C++ or Objective-C) for a ``.h`` file by adding
275-
a special comment (e.g. ``// clang-format Language: ObjC``) near the top of
276-
the file.
274+
- Add the C language instead of treating it like C++.
275+
- Allow specifying the language (C, C++, or Objective-C) for a ``.h`` file by
276+
adding a special comment (e.g. ``// clang-format Language: ObjC``) near the
277+
top of the file.
277278

278279
libclang
279280
--------

clang/include/clang/Format/Format.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3318,7 +3318,9 @@ struct FormatStyle {
33183318
enum LanguageKind : int8_t {
33193319
/// Do not use.
33203320
LK_None,
3321-
/// Should be used for C, C++.
3321+
/// Should be used for C.
3322+
LK_C,
3323+
/// Should be used for C++.
33223324
LK_Cpp,
33233325
/// Should be used for C#.
33243326
LK_CSharp,
@@ -3343,7 +3345,9 @@ struct FormatStyle {
33433345
/// https://sci-hub.st/10.1109/IEEESTD.2018.8299595
33443346
LK_Verilog
33453347
};
3346-
bool isCpp() const { return Language == LK_Cpp || Language == LK_ObjC; }
3348+
bool isCpp() const {
3349+
return Language == LK_Cpp || Language == LK_C || Language == LK_ObjC;
3350+
}
33473351
bool isCSharp() const { return Language == LK_CSharp; }
33483352
bool isJson() const { return Language == LK_Json; }
33493353
bool isJavaScript() const { return Language == LK_JavaScript; }
@@ -3355,8 +3359,8 @@ struct FormatStyle {
33553359

33563360
/// The language that this format style targets.
33573361
/// \note
3358-
/// You can also specify the language (``Cpp`` or ``ObjC``) for ``.h`` files
3359-
/// by adding a ``// clang-format Language:`` line before the first
3362+
/// You can specify the language (``C``, ``Cpp``, or ``ObjC``) for ``.h``
3363+
/// files by adding a ``// clang-format Language:`` line before the first
33603364
/// non-comment (and non-empty) line, e.g. ``// clang-format Language: Cpp``.
33613365
/// \endnote
33623366
/// \version 3.5
@@ -5715,6 +5719,8 @@ FormatStyle::LanguageKind guessLanguage(StringRef FileName, StringRef Code);
57155719
// Returns a string representation of ``Language``.
57165720
inline StringRef getLanguageName(FormatStyle::LanguageKind Language) {
57175721
switch (Language) {
5722+
case FormatStyle::LK_C:
5723+
return "C";
57185724
case FormatStyle::LK_Cpp:
57195725
return "C++";
57205726
case FormatStyle::LK_CSharp:

clang/lib/Format/Format.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,7 @@ template <> struct MappingTraits<FormatStyle::KeepEmptyLinesStyle> {
401401

402402
template <> struct ScalarEnumerationTraits<FormatStyle::LanguageKind> {
403403
static void enumeration(IO &IO, FormatStyle::LanguageKind &Value) {
404+
IO.enumCase(Value, "C", FormatStyle::LK_C);
404405
IO.enumCase(Value, "Cpp", FormatStyle::LK_Cpp);
405406
IO.enumCase(Value, "Java", FormatStyle::LK_Java);
406407
IO.enumCase(Value, "JavaScript", FormatStyle::LK_JavaScript);
@@ -3957,7 +3958,12 @@ LangOptions getFormattingLangOpts(const FormatStyle &Style) {
39573958
LangOpts.Digraphs = LexingStd >= FormatStyle::LS_Cpp11;
39583959

39593960
LangOpts.LineComment = 1;
3960-
LangOpts.CXXOperatorNames = Style.isCpp();
3961+
3962+
const auto Language = Style.Language;
3963+
LangOpts.C17 = Language == FormatStyle::LK_C;
3964+
LangOpts.CXXOperatorNames =
3965+
Language == FormatStyle::LK_Cpp || Language == FormatStyle::LK_ObjC;
3966+
39613967
LangOpts.Bool = 1;
39623968
LangOpts.ObjC = 1;
39633969
LangOpts.MicrosoftExt = 1; // To get kw___try, kw___finally.
@@ -3982,6 +3988,8 @@ const char *StyleOptionHelpDescription =
39823988
" --style=\"{BasedOnStyle: llvm, IndentWidth: 8}\"";
39833989

39843990
static FormatStyle::LanguageKind getLanguageByFileName(StringRef FileName) {
3991+
if (FileName.ends_with(".c"))
3992+
return FormatStyle::LK_C;
39853993
if (FileName.ends_with(".java"))
39863994
return FormatStyle::LK_Java;
39873995
if (FileName.ends_with_insensitive(".js") ||
@@ -4039,6 +4047,8 @@ static FormatStyle::LanguageKind getLanguageByComment(const Environment &Env) {
40394047
continue;
40404048

40414049
Text = Text.trim();
4050+
if (Text == "C")
4051+
return FormatStyle::LK_C;
40424052
if (Text == "Cpp")
40434053
return FormatStyle::LK_Cpp;
40444054
if (Text == "ObjC")

clang/lib/Format/FormatToken.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,7 @@ static SmallVector<StringRef> CppNonKeywordTypes = {
4444
bool FormatToken::isTypeName(const LangOptions &LangOpts) const {
4545
if (is(TT_TypeName) || Tok.isSimpleTypeSpecifier(LangOpts))
4646
return true;
47-
const bool IsCpp = LangOpts.CXXOperatorNames;
48-
return IsCpp && is(tok::identifier) &&
47+
return (LangOpts.CXXOperatorNames || LangOpts.C17) && is(tok::identifier) &&
4948
std::binary_search(CppNonKeywordTypes.begin(),
5049
CppNonKeywordTypes.end(), TokenText);
5150
}

clang/lib/Format/TokenAnnotator.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ class AnnotatingParser {
129129
: Style(Style), Line(Line), CurrentToken(Line.First), AutoFound(false),
130130
IsCpp(Style.isCpp()), LangOpts(getFormattingLangOpts(Style)),
131131
Keywords(Keywords), Scopes(Scopes), TemplateDeclarationDepth(0) {
132-
assert(IsCpp == LangOpts.CXXOperatorNames);
132+
assert(IsCpp == (LangOpts.CXXOperatorNames || LangOpts.C17));
133133
Contexts.push_back(Context(tok::unknown, 1, /*IsExpression=*/false));
134134
resetTokenMetadata();
135135
}
@@ -3821,7 +3821,7 @@ static bool isFunctionDeclarationName(const LangOptions &LangOpts,
38213821
};
38223822

38233823
const auto *Next = Current.Next;
3824-
const bool IsCpp = LangOpts.CXXOperatorNames;
3824+
const bool IsCpp = LangOpts.CXXOperatorNames || LangOpts.C17;
38253825

38263826
// Find parentheses of parameter list.
38273827
if (Current.is(tok::kw_operator)) {

clang/lib/Format/TokenAnnotator.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ class TokenAnnotator {
225225
TokenAnnotator(const FormatStyle &Style, const AdditionalKeywords &Keywords)
226226
: Style(Style), IsCpp(Style.isCpp()),
227227
LangOpts(getFormattingLangOpts(Style)), Keywords(Keywords) {
228-
assert(IsCpp == LangOpts.CXXOperatorNames);
228+
assert(IsCpp == (LangOpts.CXXOperatorNames || LangOpts.C17));
229229
}
230230

231231
/// Adapts the indent levels of comment lines to the indent of the

clang/lib/Format/UnwrappedLineParser.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ UnwrappedLineParser::UnwrappedLineParser(
168168
: IG_Inited),
169169
IncludeGuardToken(nullptr), FirstStartColumn(FirstStartColumn),
170170
Macros(Style.Macros, SourceMgr, Style, Allocator, IdentTable) {
171-
assert(IsCpp == LangOpts.CXXOperatorNames);
171+
assert(IsCpp == (LangOpts.CXXOperatorNames || LangOpts.C17));
172172
}
173173

174174
void UnwrappedLineParser::reset() {

clang/unittests/Format/FormatTest.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24971,6 +24971,7 @@ TEST_F(FormatTest, StructuredBindings) {
2497124971
}
2497224972

2497324973
TEST_F(FormatTest, FileAndCode) {
24974+
EXPECT_EQ(FormatStyle::LK_C, guessLanguage("foo.c", ""));
2497424975
EXPECT_EQ(FormatStyle::LK_Cpp, guessLanguage("foo.cc", ""));
2497524976
EXPECT_EQ(FormatStyle::LK_ObjC, guessLanguage("foo.m", ""));
2497624977
EXPECT_EQ(FormatStyle::LK_ObjC, guessLanguage("foo.mm", ""));
@@ -25137,6 +25138,9 @@ TEST_F(FormatTest, GuessLanguageWithChildLines) {
2513725138
}
2513825139

2513925140
TEST_F(FormatTest, GetLanguageByComment) {
25141+
EXPECT_EQ(FormatStyle::LK_C,
25142+
guessLanguage("foo.h", "// clang-format Language: C\n"
25143+
"int i;"));
2514025144
EXPECT_EQ(FormatStyle::LK_Cpp,
2514125145
guessLanguage("foo.h", "// clang-format Language: Cpp\n"
2514225146
"int DoStuff(CGRect rect);"));

0 commit comments

Comments
 (0)