@@ -401,6 +401,7 @@ template <> struct MappingTraits<FormatStyle::KeepEmptyLinesStyle> {
401
401
402
402
template <> struct ScalarEnumerationTraits <FormatStyle::LanguageKind> {
403
403
static void enumeration (IO &IO, FormatStyle::LanguageKind &Value) {
404
+ IO.enumCase (Value, " C" , FormatStyle::LK_C);
404
405
IO.enumCase (Value, " Cpp" , FormatStyle::LK_Cpp);
405
406
IO.enumCase (Value, " Java" , FormatStyle::LK_Java);
406
407
IO.enumCase (Value, " JavaScript" , FormatStyle::LK_JavaScript);
@@ -3952,7 +3953,12 @@ LangOptions getFormattingLangOpts(const FormatStyle &Style) {
3952
3953
LangOpts.Digraphs = LexingStd >= FormatStyle::LS_Cpp11;
3953
3954
3954
3955
LangOpts.LineComment = 1 ;
3955
- LangOpts.CXXOperatorNames = Style.isCpp ();
3956
+
3957
+ const auto Language = Style.Language ;
3958
+ LangOpts.C17 = Language == FormatStyle::LK_C;
3959
+ LangOpts.CXXOperatorNames =
3960
+ Language == FormatStyle::LK_Cpp || Language == FormatStyle::LK_ObjC;
3961
+
3956
3962
LangOpts.Bool = 1 ;
3957
3963
LangOpts.ObjC = 1 ;
3958
3964
LangOpts.MicrosoftExt = 1 ; // To get kw___try, kw___finally.
@@ -3977,6 +3983,8 @@ const char *StyleOptionHelpDescription =
3977
3983
" --style=\" {BasedOnStyle: llvm, IndentWidth: 8}\" " ;
3978
3984
3979
3985
static FormatStyle::LanguageKind getLanguageByFileName (StringRef FileName) {
3986
+ if (FileName.ends_with (" .c" ))
3987
+ return FormatStyle::LK_C;
3980
3988
if (FileName.ends_with (" .java" ))
3981
3989
return FormatStyle::LK_Java;
3982
3990
if (FileName.ends_with_insensitive (" .js" ) ||
@@ -4016,6 +4024,35 @@ static FormatStyle::LanguageKind getLanguageByFileName(StringRef FileName) {
4016
4024
return FormatStyle::LK_Cpp;
4017
4025
}
4018
4026
4027
+ static FormatStyle::LanguageKind getLanguageByComment (const Environment &Env) {
4028
+ const auto ID = Env.getFileID ();
4029
+ const auto &SourceMgr = Env.getSourceManager ();
4030
+
4031
+ LangOptions LangOpts;
4032
+ LangOpts.CPlusPlus = 1 ;
4033
+ LangOpts.LineComment = 1 ;
4034
+
4035
+ Lexer Lex (ID, SourceMgr.getBufferOrFake (ID), SourceMgr, LangOpts);
4036
+ Lex.SetCommentRetentionState (true );
4037
+
4038
+ for (Token Tok; !Lex.LexFromRawLexer (Tok) && Tok.is (tok::comment);) {
4039
+ auto Text = StringRef (SourceMgr.getCharacterData (Tok.getLocation ()),
4040
+ Tok.getLength ());
4041
+ if (!Text.consume_front (" // clang-format Language:" ))
4042
+ continue ;
4043
+
4044
+ Text = Text.trim ();
4045
+ if (Text == " C" )
4046
+ return FormatStyle::LK_C;
4047
+ if (Text == " Cpp" )
4048
+ return FormatStyle::LK_Cpp;
4049
+ if (Text == " ObjC" )
4050
+ return FormatStyle::LK_ObjC;
4051
+ }
4052
+
4053
+ return FormatStyle::LK_None;
4054
+ }
4055
+
4019
4056
FormatStyle::LanguageKind guessLanguage (StringRef FileName, StringRef Code) {
4020
4057
const auto GuessedLanguage = getLanguageByFileName (FileName);
4021
4058
if (GuessedLanguage == FormatStyle::LK_Cpp) {
@@ -4025,6 +4062,10 @@ FormatStyle::LanguageKind guessLanguage(StringRef FileName, StringRef Code) {
4025
4062
if (!Code.empty () && (Extension.empty () || Extension == " .h" )) {
4026
4063
auto NonEmptyFileName = FileName.empty () ? " guess.h" : FileName;
4027
4064
Environment Env (Code, NonEmptyFileName, /* Ranges=*/ {});
4065
+ if (const auto Language = getLanguageByComment (Env);
4066
+ Language != FormatStyle::LK_None) {
4067
+ return Language;
4068
+ }
4028
4069
ObjCHeaderStyleGuesser Guesser (Env, getLLVMStyle ());
4029
4070
Guesser.process ();
4030
4071
if (Guesser.isObjC ())
0 commit comments