@@ -4021,6 +4021,33 @@ static FormatStyle::LanguageKind getLanguageByFileName(StringRef FileName) {
40214021 return FormatStyle::LK_Cpp;
40224022}
40234023
4024+ static FormatStyle::LanguageKind getLanguageByComment (const Environment &Env) {
4025+ const auto ID = Env.getFileID ();
4026+ const auto &SourceMgr = Env.getSourceManager ();
4027+
4028+ LangOptions LangOpts;
4029+ LangOpts.CPlusPlus = 1 ;
4030+ LangOpts.LineComment = 1 ;
4031+
4032+ Lexer Lex (ID, SourceMgr.getBufferOrFake (ID), SourceMgr, LangOpts);
4033+ Lex.SetCommentRetentionState (true );
4034+
4035+ for (Token Tok; !Lex.LexFromRawLexer (Tok) && Tok.is (tok::comment);) {
4036+ auto Text = StringRef (SourceMgr.getCharacterData (Tok.getLocation ()),
4037+ Tok.getLength ());
4038+ if (!Text.consume_front (" // clang-format Language:" ))
4039+ continue ;
4040+
4041+ Text = Text.trim ();
4042+ if (Text == " Cpp" )
4043+ return FormatStyle::LK_Cpp;
4044+ if (Text == " ObjC" )
4045+ return FormatStyle::LK_ObjC;
4046+ }
4047+
4048+ return FormatStyle::LK_None;
4049+ }
4050+
40244051FormatStyle::LanguageKind guessLanguage (StringRef FileName, StringRef Code) {
40254052 const auto GuessedLanguage = getLanguageByFileName (FileName);
40264053 if (GuessedLanguage == FormatStyle::LK_Cpp) {
@@ -4030,6 +4057,10 @@ FormatStyle::LanguageKind guessLanguage(StringRef FileName, StringRef Code) {
40304057 if (!Code.empty () && (Extension.empty () || Extension == " .h" )) {
40314058 auto NonEmptyFileName = FileName.empty () ? " guess.h" : FileName;
40324059 Environment Env (Code, NonEmptyFileName, /* Ranges=*/ {});
4060+ if (const auto Language = getLanguageByComment (Env);
4061+ Language != FormatStyle::LK_None) {
4062+ return Language;
4063+ }
40334064 ObjCHeaderStyleGuesser Guesser (Env, getLLVMStyle ());
40344065 Guesser.process ();
40354066 if (Guesser.isObjC ())
0 commit comments