35 #include "llvm/ADT/ArrayRef.h"
36 #include "llvm/ADT/ScopeExit.h"
37 #include "llvm/ADT/SmallString.h"
38 #include "llvm/ADT/SmallVector.h"
39 #include "llvm/ADT/STLExtras.h"
40 #include "llvm/ADT/StringSwitch.h"
41 #include "llvm/ADT/StringRef.h"
42 #include "llvm/Support/AlignOf.h"
43 #include "llvm/Support/ErrorHandling.h"
44 #include "llvm/Support/Path.h"
52 using namespace clang;
59 auto *MIChain =
new (BP) MacroInfoChain{L, MIChainHead};
60 MIChainHead = MIChain;
70 Preprocessor::AllocateUndefMacroDirective(
SourceLocation UndefLoc) {
88 while (Tmp.
isNot(tok::eod)) {
89 assert(Tmp.
isNot(
tok::eof) &&
"EOF seen while discarding directive tokens");
118 StringRef ModuleName) {
124 !CurrentModule.endswith(
"_Private") && TopLevelName.endswith(
"_Private"))
125 TopLevelName = TopLevelName.drop_back(8);
127 return TopLevelName == CurrentModule;
138 static constexpr StringRef ReservedMacro[] = {
141 "_CRT_NONSTDC_NO_WARNINGS",
142 "_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES",
143 "_CRT_SECURE_NO_WARNINGS",
146 "_GLIBCXX_ASSERTIONS",
147 "_GLIBCXX_CONCEPT_CHECKS",
149 "_GLIBCXX_DEBUG_PEDANTIC",
151 "_GLIBCXX_PARALLEL_ASSERTIONS",
152 "_GLIBCXX_SANITIZE_VECTOR",
153 "_GLIBCXX_USE_CXX11_ABI",
154 "_GLIBCXX_USE_DEPRECATED",
159 "_LARGEFILE64_SOURCE",
165 "_XOPEN_SOURCE_EXTENDED",
166 "__STDCPP_WANT_MATH_SPEC_FUNCS__",
167 "__STDC_FORMAT_MACROS",
169 if (std::binary_search(std::begin(ReservedMacro), std::end(ReservedMacro),
178 if (Lang.CPlusPlus11 && (
Text.equals(
"override") ||
Text.equals(
"final")))
199 if (::llvm::sys::path::begin(Include)->equals_insensitive(
"boost"))
204 static const size_t MaxStdHeaderNameLen = 18u;
205 if (Include.size() > MaxStdHeaderNameLen)
210 for (
char &Ch : LowerInclude) {
212 if (
static_cast<unsigned char>(Ch) > 0x7f)
215 if (Ch >=
'A' && Ch <=
'Z')
218 else if (::llvm::sys::path::is_separator(Ch))
223 return llvm::StringSwitch<bool>(LowerInclude)
225 .Cases(
"assert.h",
"complex.h",
"ctype.h",
"errno.h",
"fenv.h",
true)
226 .Cases(
"float.h",
"inttypes.h",
"iso646.h",
"limits.h",
"locale.h",
true)
227 .Cases(
"math.h",
"setjmp.h",
"signal.h",
"stdalign.h",
"stdarg.h",
true)
228 .Cases(
"stdatomic.h",
"stdbool.h",
"stddef.h",
"stdint.h",
"stdio.h",
true)
229 .Cases(
"stdlib.h",
"stdnoreturn.h",
"string.h",
"tgmath.h",
"threads.h",
true)
230 .Cases(
"time.h",
"uchar.h",
"wchar.h",
"wctype.h",
true)
233 .Cases(
"cassert",
"ccomplex",
"cctype",
"cerrno",
"cfenv",
true)
234 .Cases(
"cfloat",
"cinttypes",
"ciso646",
"climits",
"clocale",
true)
235 .Cases(
"cmath",
"csetjmp",
"csignal",
"cstdalign",
"cstdarg",
true)
236 .Cases(
"cstdbool",
"cstddef",
"cstdint",
"cstdio",
"cstdlib",
true)
237 .Cases(
"cstring",
"ctgmath",
"ctime",
"cuchar",
"cwchar",
true)
238 .Case(
"cwctype",
true)
241 .Cases(
"algorithm",
"fstream",
"list",
"regex",
"thread",
true)
242 .Cases(
"array",
"functional",
"locale",
"scoped_allocator",
"tuple",
true)
243 .Cases(
"atomic",
"future",
"map",
"set",
"type_traits",
true)
244 .Cases(
"bitset",
"initializer_list",
"memory",
"shared_mutex",
"typeindex",
true)
245 .Cases(
"chrono",
"iomanip",
"mutex",
"sstream",
"typeinfo",
true)
246 .Cases(
"codecvt",
"ios",
"new",
"stack",
"unordered_map",
true)
247 .Cases(
"complex",
"iosfwd",
"numeric",
"stdexcept",
"unordered_set",
true)
248 .Cases(
"condition_variable",
"iostream",
"ostream",
"streambuf",
"utility",
true)
249 .Cases(
"deque",
"istream",
"queue",
"string",
"valarray",
true)
250 .Cases(
"exception",
"iterator",
"random",
"strstream",
"vector",
true)
251 .Cases(
"forward_list",
"limits",
"ratio",
"system_error",
true)
254 .Cases(
"aio.h",
"arpa/inet.h",
"cpio.h",
"dirent.h",
"dlfcn.h",
true)
255 .Cases(
"fcntl.h",
"fmtmsg.h",
"fnmatch.h",
"ftw.h",
"glob.h",
true)
256 .Cases(
"grp.h",
"iconv.h",
"langinfo.h",
"libgen.h",
"monetary.h",
true)
257 .Cases(
"mqueue.h",
"ndbm.h",
"net/if.h",
"netdb.h",
"netinet/in.h",
true)
258 .Cases(
"netinet/tcp.h",
"nl_types.h",
"poll.h",
"pthread.h",
"pwd.h",
true)
259 .Cases(
"regex.h",
"sched.h",
"search.h",
"semaphore.h",
"spawn.h",
true)
260 .Cases(
"strings.h",
"stropts.h",
"sys/ipc.h",
"sys/mman.h",
"sys/msg.h",
true)
261 .Cases(
"sys/resource.h",
"sys/select.h",
"sys/sem.h",
"sys/shm.h",
"sys/socket.h",
true)
262 .Cases(
"sys/stat.h",
"sys/statvfs.h",
"sys/time.h",
"sys/times.h",
"sys/types.h",
true)
263 .Cases(
"sys/uio.h",
"sys/un.h",
"sys/utsname.h",
"sys/wait.h",
"syslog.h",
true)
264 .Cases(
"tar.h",
"termios.h",
"trace.h",
"ulimit.h",
true)
265 .Cases(
"unistd.h",
"utime.h",
"utmpx.h",
"wordexp.h",
true)
278 StringRef LHS,
const std::vector<StringRef> &Candidates) {
281 for (StringRef C : Candidates) {
282 if (LHS.equals_insensitive(C)) {
290 size_t Length = LHS.size();
291 size_t MaxDist = Length < 3 ? Length - 1 : Length / 3;
294 for (StringRef C : Candidates) {
295 size_t CurDist = LHS.edit_distance(C,
true);
296 if (CurDist <= MaxDist) {
297 if (!SimilarStr.hasValue()) {
299 SimilarStr = {C, CurDist};
300 }
else if (CurDist < SimilarStr->second) {
302 SimilarStr = {C, CurDist};
307 if (SimilarStr.hasValue()) {
308 return SimilarStr->first;
317 if (MacroNameTok.
is(tok::eod))
318 return Diag(MacroNameTok, diag::err_pp_missing_macro_name);
322 return Diag(MacroNameTok, diag::err_pp_macro_not_identifier);
328 ? diag::ext_pp_operator_used_as_macro_name
329 : diag::err_pp_operator_used_as_macro_name)
330 << II << MacroNameTok.
getKind();
337 return Diag(MacroNameTok, diag::err_defined_macro_name);
345 Diag(MacroNameTok, diag::ext_pp_undef_builtin_macro);
370 Diag(MacroNameTok, diag::warn_pp_macro_is_reserved_id);
386 void Preprocessor::ReadMacroName(
Token &MacroNameTok,
MacroUse isDefineUndef,
391 if (MacroNameTok.
is(tok::code_completion)) {
403 if (MacroNameTok.
isNot(tok::eod)) {
404 MacroNameTok.
setKind(tok::eod);
428 while (Tmp.
is(tok::comment))
431 if (Tmp.
is(tok::eod))
439 if ((LangOpts.GNUMode || LangOpts.C99 || LangOpts.CPlusPlus) &&
442 Diag(Tmp, diag::ext_pp_extra_tokens_at_eol) << DirType << Hint;
448 if (!ExcludedConditionalDirectiveSkipMappings)
453 std::pair<FileID, unsigned> HashFileOffset =
460 ExcludedConditionalDirectiveSkipMappings->find(Buf->getBufferStart());
461 if (It == ExcludedConditionalDirectiveSkipMappings->end())
466 auto MappingIt = SkippedRanges.find(HashFileOffset.second);
467 if (MappingIt == SkippedRanges.end())
470 unsigned BytesToSkip = MappingIt->getSecond();
471 unsigned CurLexerBufferOffset = CurLexer->getCurrentBufferOffset();
472 assert(CurLexerBufferOffset >= HashFileOffset.second &&
473 "lexer is before the hash?");
476 unsigned LengthDiff = CurLexerBufferOffset - HashFileOffset.second;
477 assert(BytesToSkip >= LengthDiff &&
"lexer is after the skipped range?");
478 return BytesToSkip - LengthDiff;
481 void Preprocessor::SuggestTypoedDirective(
const Token &Tok,
484 std::vector<StringRef> Candidates = {
485 "if",
"ifdef",
"ifndef",
"elif",
"else",
"endif"
487 if (LangOpts.C2x || LangOpts.CPlusPlus2b)
488 Candidates.insert(Candidates.end(), {
"elifdef",
"elifndef"});
496 Diag(Tok, diag::warn_pp_invalid_directive) << 1 << SuggValue << Hint;
508 void Preprocessor::SkipExcludedConditionalBlock(
SourceLocation HashTokenLoc,
510 bool FoundNonSkipPortion,
514 assert(!CurTokenLexer && CurPPLexer &&
"Lexing a macro, not a file?");
516 if (PreambleConditionalStack.reachedEOFWhileSkipping())
517 PreambleConditionalStack.clearSkipInfo();
520 FoundNonSkipPortion, FoundElse);
526 if (
auto SkipLength =
527 getSkippedRangeForExcludedConditionalBlock(HashTokenLoc)) {
529 CurLexer->skipOver(*SkipLength);
535 if (Tok.
is(tok::code_completion)) {
547 if (PreambleConditionalStack.isRecording())
548 PreambleConditionalStack.SkipInfo.emplace(
549 HashTokenLoc, IfTokenLoc, FoundNonSkipPortion, FoundElse, ElseLoc);
561 if (CurLexer) CurLexer->SetKeepWhitespaceMode(
false);
569 if (Tok.
isNot(tok::raw_identifier)) {
572 if (CurLexer) CurLexer->resetExtendedTokenMode();
583 char FirstChar = RI[0];
584 if (FirstChar >=
'a' && FirstChar <=
'z' &&
585 FirstChar !=
'i' && FirstChar !=
'e') {
588 if (CurLexer) CurLexer->resetExtendedTokenMode();
595 char DirectiveBuf[20];
601 size_t IdLen = DirectiveStr.size();
605 if (CurLexer) CurLexer->resetExtendedTokenMode();
608 memcpy(DirectiveBuf, &DirectiveStr[0], IdLen);
609 Directive = StringRef(DirectiveBuf, IdLen);
624 SuggestTypoedDirective(Tok,
Directive, endLoc);
633 assert(!InCond &&
"Can't be skipping if not in a conditional!");
648 }
else if (
Sub ==
"lse") {
656 Diag(Tok, diag::pp_err_else_after_else);
676 }
else if (
Sub ==
"lif") {
694 assert(CurPPLexer->
LexingRawMode &&
"We have to be skipping here!");
697 DirectiveEvalResult DER = EvaluateDirectiveExpression(IfNDefMacro);
701 const bool CondValue = DER.Conditional;
715 }
else if (
Sub ==
"lifdef" ||
717 bool IsElifDef =
Sub ==
"lifdef";
719 Token DirectiveToken = Tok;
724 if (LangOpts.CPlusPlus)
725 DiagID = LangOpts.CPlusPlus2b ? diag::warn_cxx2b_compat_pp_directive
726 : diag::ext_cxx2b_pp_directive;
728 DiagID = LangOpts.C2x ? diag::warn_c2x_compat_pp_directive
729 : diag::ext_c2x_pp_directive;
734 Diag(Tok, diag::pp_err_elif_after_else)
748 assert(CurPPLexer->
LexingRawMode &&
"We have to be skipping here!");
751 ReadMacroName(MacroNameTok);
756 if (MacroNameTok.
is(tok::eod)) {
772 Callbacks->Elifdef(DirectiveToken.
getLocation(), MacroNameTok,
775 Callbacks->Elifndef(DirectiveToken.
getLocation(), MacroNameTok,
780 if (
static_cast<bool>(MI) == IsElifDef) {
786 SuggestTypoedDirective(Tok,
Directive, endLoc);
789 SuggestTypoedDirective(Tok,
Directive, endLoc);
794 if (CurLexer) CurLexer->resetExtendedTokenMode();
805 Callbacks->SourceRangeSkipped(
842 while (!Loc.
isInvalid() && !
SM.isInMainFile(Loc)) {
843 auto ID =
SM.getFileID(
SM.getExpansionLoc(Loc));
844 auto *FE =
SM.getFileEntryForID(
ID);
853 bool InPrivateHeader =
false;
855 if (!Header.isAccessibleFrom(IncM)) {
860 InPrivateHeader =
true;
893 Loc =
SM.getIncludeLoc(
ID);
905 bool *IsFrameworkFound,
bool SkipCache) {
910 bool RequestingModuleIsModuleInterface = !SourceMgr.
isInMainFile(FilenameLoc);
916 bool BuildSystemModule =
false;
917 if (!FromDir && !FromFile) {
935 Includers.push_back(std::make_pair(
nullptr, MainFileDir));
937 }
else if ((FileEnt =
939 Includers.push_back(std::make_pair(FileEnt, *FileMgr.
getDirectory(
".")));
941 Includers.push_back(std::make_pair(FileEnt, FileEnt->
getDir()));
947 if (LangOpts.MSVCCompat && !isAngled) {
948 for (IncludeStackInfo &ISEntry : llvm::reverse(IncludeMacroStack)) {
949 if (IsFileLexer(ISEntry))
950 if ((FileEnt = ISEntry.ThePPLexer->getFileEntry()))
951 Includers.push_back(std::make_pair(FileEnt, FileEnt->
getDir()));
956 CurDir = CurDirLookup;
964 Filename, FilenameLoc, isAngled, TmpFromDir, &TmpCurDir,
965 Includers, SearchPath, RelativePath, RequestingModule,
966 SuggestedModule,
nullptr,
967 nullptr, SkipCache)) {
969 TmpFromDir = TmpCurDir;
971 if (&FE->getFileEntry() == FromFile) {
973 FromDir = TmpFromDir;
982 Filename, FilenameLoc, isAngled, FromDir, &CurDir, Includers, SearchPath,
983 RelativePath, RequestingModule, SuggestedModule, IsMapped,
984 IsFrameworkFound, SkipCache, BuildSystemModule);
986 if (SuggestedModule && !LangOpts.AsmPreprocessor)
988 RequestingModule, RequestingModuleIsModuleInterface, FilenameLoc,
1000 Filename, CurFileEnt, SearchPath, RelativePath, RequestingModule,
1002 if (SuggestedModule && !LangOpts.AsmPreprocessor)
1004 RequestingModule, RequestingModuleIsModuleInterface, FilenameLoc,
1011 for (IncludeStackInfo &ISEntry : llvm::reverse(IncludeMacroStack)) {
1012 if (IsFileLexer(ISEntry)) {
1013 if ((CurFileEnt = ISEntry.ThePPLexer->getFileEntry())) {
1015 Filename, CurFileEnt, SearchPath, RelativePath,
1016 RequestingModule, SuggestedModule)) {
1017 if (SuggestedModule && !LangOpts.AsmPreprocessor)
1019 RequestingModule, RequestingModuleIsModuleInterface,
1038 : PP(pp), save(pp->DisableMacroExpansion) {
1039 if (pp->MacroExpansionInDirectivesOverride)
1040 pp->DisableMacroExpansion =
false;
1044 PP->DisableMacroExpansion = save;
1062 return HandleDefineDirective(Result,
1065 if (SkippingUntilPCHThroughHeader &&
1067 return HandleIncludeDirective(HashLoc, Result);
1069 if (SkippingUntilPragmaHdrStop && II->getPPKeywordID() == tok::pp_pragma) {
1071 auto *II = Result.getIdentifierInfo();
1072 if (II && II->getName() ==
"hdrstop")
1090 if (CurLexer) CurLexer->SetKeepWhitespaceMode(
false);
1092 bool ImmediatelyAfterTopLevelIfndef =
1104 Token SavedHash = Result;
1120 switch (II->getPPKeywordID()) {
1125 case tok::pp_pragma:
1126 Diag(Result, diag::err_embedded_directive) << II->getName();
1127 Diag(*ArgMacro, diag::note_macro_expansion_here)
1135 Diag(Result, diag::ext_embedded_directive);
1142 if (SkippingUntilPCHThroughHeader || SkippingUntilPragmaHdrStop)
1148 case tok::code_completion:
1154 case tok::numeric_constant:
1157 return HandleDigitDirective(Result);
1167 return HandleIfDirective(Result, SavedHash, ReadAnyTokensBeforeDirective);
1169 return HandleIfdefDirective(Result, SavedHash,
false,
1172 return HandleIfdefDirective(Result, SavedHash,
true,
1173 ReadAnyTokensBeforeDirective);
1177 return HandleElifFamilyDirective(Result, SavedHash, II->
getPPKeywordID());
1180 return HandleElseDirective(Result, SavedHash);
1182 return HandleEndifDirective(Result);
1187 return HandleIncludeDirective(SavedHash.
getLocation(), Result);
1190 return HandleIncludeMacrosDirective(SavedHash.
getLocation(), Result);
1194 return HandleDefineDirective(Result, ImmediatelyAfterTopLevelIfndef);
1196 return HandleUndefDirective();
1200 return HandleLineDirective();
1204 return HandleUserDiagnosticDirective(Result,
false);
1207 case tok::pp_pragma:
1212 return HandleImportDirective(SavedHash.
getLocation(), Result);
1214 return HandleIncludeNextDirective(SavedHash.
getLocation(), Result);
1216 case tok::pp_warning:
1217 Diag(Result, diag::ext_pp_warning_directive);
1218 return HandleUserDiagnosticDirective(Result,
true);
1220 return HandleIdentSCCSDirective(Result);
1222 return HandleIdentSCCSDirective(Result);
1223 case tok::pp_assert:
1226 case tok::pp_unassert:
1230 case tok::pp___public_macro:
1232 return HandleMacroPublicDirective(Result);
1235 case tok::pp___private_macro:
1237 return HandleMacroPrivateDirective();
1248 auto Toks = std::make_unique<Token[]>(2);
1250 Toks[0] = SavedHash;
1255 if (Result.is(tok::hashhash))
1256 Toks[1].setKind(tok::unknown);
1261 EnterTokenStream(std::move(Toks), 2,
false,
false);
1267 Diag(Result, diag::err_pp_invalid_directive) << 0;
1279 bool IsGNULineDirective=
false) {
1280 if (DigitTok.
isNot(tok::numeric_constant)) {
1281 PP.
Diag(DigitTok, DiagID);
1283 if (DigitTok.
isNot(tok::eod))
1289 IntegerBuffer.resize(DigitTok.
getLength());
1290 const char *DigitTokBegin = &IntegerBuffer[0];
1291 bool Invalid =
false;
1292 unsigned ActualLength = PP.
getSpelling(DigitTok, DigitTokBegin, &Invalid);
1300 for (
unsigned i = 0; i != ActualLength; ++i) {
1303 if (DigitTokBegin[i] ==
'\'')
1306 if (!
isDigit(DigitTokBegin[i])) {
1308 diag::err_pp_line_digit_sequence) << IsGNULineDirective;
1313 unsigned NextVal = Val*10+(DigitTokBegin[i]-
'0');
1314 if (NextVal < Val) {
1315 PP.
Diag(DigitTok, DiagID);
1322 if (DigitTokBegin[0] ==
'0' && Val)
1324 << IsGNULineDirective;
1336 void Preprocessor::HandleLineDirective() {
1344 if (
GetLineValue(DigitTok, LineNo, diag::err_pp_line_requires_integer,*
this))
1348 Diag(DigitTok, diag::ext_pp_line_zero);
1352 unsigned LineLimit = 32768
U;
1353 if (LangOpts.C99 || LangOpts.CPlusPlus11)
1354 LineLimit = 2147483648
U;
1355 if (LineNo >= LineLimit)
1356 Diag(DigitTok, diag::ext_pp_line_too_big) << LineLimit;
1357 else if (LangOpts.CPlusPlus11 && LineNo >= 32768
U)
1358 Diag(DigitTok, diag::warn_cxx98_compat_pp_line_too_big);
1360 int FilenameID = -1;
1366 if (StrTok.
is(tok::eod))
1368 else if (StrTok.
isNot(tok::string_literal)) {
1369 Diag(StrTok, diag::err_pp_line_invalid_filename);
1373 Diag(StrTok, diag::err_invalid_string_udl);
1379 assert(
Literal.isAscii() &&
"Didn't allow wide strings in");
1385 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1420 if (FlagTok.
is(tok::eod))
return false;
1421 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag, PP))
1428 if (FlagTok.
is(tok::eod))
return false;
1429 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag,PP))
1431 }
else if (FlagVal == 2) {
1447 SM.getDecomposedExpansionLoc(IncLoc).first != CurFileID) {
1448 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_pop);
1454 if (FlagTok.
is(tok::eod))
return false;
1455 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag,PP))
1461 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1469 if (FlagTok.
is(tok::eod))
return false;
1470 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag, PP))
1475 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1483 if (FlagTok.
is(tok::eod))
return false;
1486 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1498 void Preprocessor::HandleDigitDirective(
Token &DigitTok) {
1502 if (
GetLineValue(DigitTok, LineNo, diag::err_pp_linemarker_requires_integer,
1509 bool IsFileEntry =
false, IsFileExit =
false;
1510 int FilenameID = -1;
1515 if (StrTok.
is(tok::eod)) {
1516 Diag(StrTok, diag::ext_pp_gnu_line_directive);
1519 }
else if (StrTok.
isNot(tok::string_literal)) {
1520 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1524 Diag(StrTok, diag::err_invalid_string_udl);
1530 assert(
Literal.isAscii() &&
"Didn't allow wide strings in");
1536 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1546 Diag(StrTok, diag::ext_pp_gnu_line_directive);
1550 if (!(IsFileExit &&
Literal.GetString().empty()))
1556 IsFileExit, FileKind);
1565 else if (IsFileExit)
1574 void Preprocessor::HandleUserDiagnosticDirective(
Token &Tok,
1582 CurLexer->ReadToEndOfLine(&Message);
1586 StringRef Msg =
Message.str().ltrim(
' ');
1589 Diag(Tok, diag::pp_hash_warning) << Msg;
1591 Diag(Tok, diag::err_pp_hash_error) << Msg;
1596 void Preprocessor::HandleIdentSCCSDirective(
Token &Tok) {
1598 Diag(Tok, diag::ext_pp_ident_directive);
1605 if (StrTok.
isNot(tok::string_literal) &&
1606 StrTok.
isNot(tok::wide_string_literal)) {
1607 Diag(StrTok, diag::err_pp_malformed_ident);
1608 if (StrTok.
isNot(tok::eod))
1614 Diag(StrTok, diag::err_invalid_string_udl);
1631 void Preprocessor::HandleMacroPublicDirective(
Token &Tok) {
1633 ReadMacroName(MacroNameTok,
MU_Undef);
1636 if (MacroNameTok.
is(tok::eod))
1648 Diag(MacroNameTok, diag::err_pp_visibility_non_macro) << II;
1658 void Preprocessor::HandleMacroPrivateDirective() {
1660 ReadMacroName(MacroNameTok,
MU_Undef);
1663 if (MacroNameTok.
is(tok::eod))
1675 Diag(MacroNameTok, diag::err_pp_visibility_non_macro) << II;
1695 StringRef &Buffer) {
1697 assert(!Buffer.empty() &&
"Can't have tokens with empty spellings!");
1709 if (Buffer[0] ==
'<') {
1710 if (Buffer.back() !=
'>') {
1711 Diag(Loc, diag::err_pp_expects_filename);
1712 Buffer = StringRef();
1716 }
else if (Buffer[0] ==
'"') {
1717 if (Buffer.back() !=
'"') {
1718 Diag(Loc, diag::err_pp_expects_filename);
1719 Buffer = StringRef();
1724 Diag(Loc, diag::err_pp_expects_filename);
1725 Buffer = StringRef();
1730 if (Buffer.size() <= 2) {
1731 Diag(Loc, diag::err_pp_empty_filename);
1732 Buffer = StringRef();
1737 Buffer = Buffer.substr(1, Buffer.size()-2);
1744 void *AnnotationVal) {
1747 auto Tok = std::make_unique<Token[]>(1);
1753 EnterTokenStream(std::move(Tok), 1,
true,
false);
1760 ArrayRef<std::pair<IdentifierInfo *, SourceLocation>> Path,
1762 StringRef ImportKeyword;
1764 ImportKeyword =
"@import";
1766 ImportKeyword =
"import";
1771 for (
size_t I = 0, N = Path.size(); I != N; ++I) {
1774 PathString += Path[I].first->getName();
1776 int IncludeKind = 0;
1796 llvm_unreachable(
"unknown include directive kind");
1801 PP.
Diag(HashLoc, diag::warn_auto_module_import)
1802 << IncludeKind << PathString
1804 ReplaceRange, (ImportKeyword +
" " + PathString +
";").str());
1811 StringRef RealPathName) {
1812 auto RealPathComponentIter = llvm::sys::path::rbegin(RealPathName);
1813 auto RealPathComponentEnd = llvm::sys::path::rend(RealPathName);
1815 bool SuggestReplacement =
false;
1818 for (
auto &Component : llvm::reverse(Components)) {
1819 if (
"." == Component) {
1820 }
else if (
".." == Component) {
1824 }
else if (RealPathComponentIter != RealPathComponentEnd) {
1825 if (Component != *RealPathComponentIter) {
1829 SuggestReplacement =
1830 RealPathComponentIter->equals_insensitive(Component);
1831 if (!SuggestReplacement)
1833 Component = *RealPathComponentIter;
1835 ++RealPathComponentIter;
1838 return SuggestReplacement;
1846 Module *ShadowingModule =
nullptr;
1854 }
else if (ShadowingModule) {
1857 diag::note_previous_definition);
1867 std::pair<ConstSearchDirIterator, const FileEntry *>
1868 Preprocessor::getIncludeNextStart(
const Token &IncludeNextTok)
const {
1873 const FileEntry *LookupFromFile =
nullptr;
1881 Diag(IncludeNextTok, diag::pp_include_next_in_primary);
1882 }
else if (CurLexerSubmodule) {
1885 assert(CurPPLexer &&
"#include_next directive in macro?");
1888 }
else if (!Lookup) {
1893 Diag(IncludeNextTok, diag::pp_include_next_absolute_path);
1899 return {Lookup, LookupFromFile};
1907 void Preprocessor::HandleIncludeDirective(
SourceLocation HashLoc,
1915 if (FilenameTok.
isNot(tok::header_name)) {
1917 if (FilenameTok.
isNot(tok::eod))
1929 auto Action = HandleHeaderIncludeOrImport(HashLoc, IncludeTok, FilenameTok,
1930 EndLoc, LookupFrom, LookupFromFile);
1931 switch (Action.Kind) {
1933 case ImportAction::SkippedModuleImport:
1935 case ImportAction::ModuleBegin:
1937 tok::annot_module_begin, Action.ModuleForHeader);
1939 case ImportAction::ModuleImport:
1941 tok::annot_module_include, Action.ModuleForHeader);
1943 case ImportAction::Failure:
1945 "This should be an early exit only to a fatal error");
1948 CurLexer->cutOffLexing();
1956 const Token &FilenameTok,
bool &IsFrameworkFound,
bool IsImportDecl,
1958 const FileEntry *LookupFromFile, StringRef &LookupFilename,
1962 FilenameLoc, LookupFilename,
1963 isAngled, LookupFrom, LookupFromFile, CurDir,
1964 Callbacks ? &SearchPath :
nullptr, Callbacks ? &RelativePath :
nullptr,
1965 &SuggestedModule, &IsMapped, &IsFrameworkFound);
1969 if (SuppressIncludeNotFoundError)
1977 FilenameLoc, LookupFilename,
1978 false, LookupFrom, LookupFromFile, CurDir,
1979 Callbacks ? &SearchPath :
nullptr, Callbacks ? &RelativePath :
nullptr,
1980 &SuggestedModule, &IsMapped,
1983 Diag(FilenameTok, diag::err_pp_file_not_found_angled_include_not_fatal)
1993 StringRef OriginalFilename =
Filename;
1994 if (LangOpts.SpellChecking) {
1997 auto CorrectTypoFilename = [](llvm::StringRef
Filename) {
2004 StringRef TypoCorrectionName = CorrectTypoFilename(
Filename);
2005 StringRef TypoCorrectionLookupName = CorrectTypoFilename(LookupFilename);
2008 FilenameLoc, TypoCorrectionLookupName, isAngled, LookupFrom, LookupFromFile,
2009 CurDir, Callbacks ? &SearchPath :
nullptr,
2010 Callbacks ? &RelativePath :
nullptr, &SuggestedModule, &IsMapped,
2015 FilenameRange,
"<" + TypoCorrectionName.str() +
">")
2017 FilenameRange,
"\"" + TypoCorrectionName.str() +
"\"");
2018 Diag(FilenameTok, diag::err_pp_file_not_found_typo_not_fatal)
2019 << OriginalFilename << TypoCorrectionName << Hint;
2023 LookupFilename = TypoCorrectionLookupName;
2029 assert(!
File.hasValue() &&
"expected missing file");
2030 Diag(FilenameTok, diag::err_pp_file_not_found)
2031 << OriginalFilename << FilenameRange;
2032 if (IsFrameworkFound) {
2033 size_t SlashPos = OriginalFilename.find(
'/');
2034 assert(SlashPos != StringRef::npos &&
2035 "Include with framework name should have '/' in the filename");
2036 StringRef FrameworkName = OriginalFilename.substr(0, SlashPos);
2039 assert(CacheEntry.
Directory &&
"Found framework should be in cache");
2040 Diag(FilenameTok, diag::note_pp_framework_without_header)
2041 << OriginalFilename.substr(SlashPos + 1) << FrameworkName
2060 Preprocessor::ImportAction Preprocessor::HandleHeaderIncludeOrImport(
2070 StringRef OriginalFilename =
Filename;
2079 bool IsImportDecl = HashLoc.
isInvalid();
2083 if (PragmaARCCFCodeAuditedInfo.second.isValid()) {
2084 Diag(StartLoc, diag::err_pp_include_in_arc_cf_code_audited) << IsImportDecl;
2085 Diag(PragmaARCCFCodeAuditedInfo.second, diag::note_pragma_entered_here);
2092 if (PragmaAssumeNonNullLoc.
isValid()) {
2093 Diag(StartLoc, diag::err_pp_include_in_assume_nonnull) << IsImportDecl;
2094 Diag(PragmaAssumeNonNullLoc, diag::note_pragma_entered_here);
2105 if (!NewName.empty())
2110 bool IsMapped =
false;
2111 bool IsFrameworkFound =
false;
2119 StringRef LookupFilename =
Filename;
2124 llvm::sys::path::Style BackslashStyle = llvm::sys::path::Style::native;
2125 if (is_style_posix(BackslashStyle) && LangOpts.MicrosoftExt) {
2127 llvm::sys::path::native(NormalizedPath);
2128 LookupFilename = NormalizedPath;
2129 BackslashStyle = llvm::sys::path::Style::windows;
2133 &CurDir,
Filename, FilenameLoc, FilenameRange, FilenameTok,
2134 IsFrameworkFound, IsImportDecl, IsMapped, LookupFrom, LookupFromFile,
2135 LookupFilename, RelativePath, SearchPath, SuggestedModule, isAngled);
2139 SkippingUntilPCHThroughHeader =
false;
2147 enum { Enter, Import, Skip, IncludeLimitReached } Action = Enter;
2149 if (PPOpts->SingleFileParseMode)
2150 Action = IncludeLimitReached;
2155 if (Action == Enter && HasReachedMaxIncludeDepth && File &&
2157 Action = IncludeLimitReached;
2162 if (Action == Enter && File && SuggestedModule &&
getLangOpts().Modules &&
2173 diag::note_implicit_top_level_module_import_here)
2185 std::reverse(Path.begin(), Path.end());
2198 assert((Imported ==
nullptr || Imported == SuggestedModule.
getModule()) &&
2199 "the imported module is different than the suggested one");
2216 Token &Result = IncludeTok;
2217 assert(CurLexer &&
"#include but no current lexer set!");
2218 Result.startToken();
2219 CurLexer->FormTokenWithChars(Result, CurLexer->BufferEnd,
tok::eof);
2220 CurLexer->cutOffLexing();
2244 bool IsFirstIncludeOfFile =
false;
2248 if (Action == Enter && File &&
2251 SuggestedModule.
getModule(), IsFirstIncludeOfFile)) {
2259 Action = (SuggestedModule && !
getLangOpts().CompilingPCH) ? Import : Skip;
2267 if (Action == Enter && File && PreambleConditionalStack.isRecording() &&
2270 diag::err_pp_including_mainfile_in_preamble);
2274 if (Callbacks && !IsImportDecl) {
2277 Callbacks->InclusionDirective(HashLoc, IncludeTok, LookupFilename, isAngled,
2278 FilenameRange, File, SearchPath, RelativePath,
2279 Action == Import ? SuggestedModule.
getModule()
2282 if (Action == Skip && File)
2283 Callbacks->FileSkipped(*File, FilenameTok, FileCharacter);
2291 if (IsImportDecl && !SuggestedModule) {
2292 Diag(FilenameTok, diag::err_header_import_not_header_unit)
2293 << OriginalFilename <<
File->getName();
2299 const bool CheckIncludePathPortability =
2300 !IsMapped && !
File->getFileEntry().tryGetRealPathName().empty();
2302 if (CheckIncludePathPortability) {
2303 StringRef Name = LookupFilename;
2304 StringRef NameWithoriginalSlashes =
Filename;
2308 bool NameWasUNC = Name.consume_front(
"\\\\?\\");
2309 NameWithoriginalSlashes.consume_front(
"\\\\?\\");
2311 StringRef RealPathName =
File->getFileEntry().tryGetRealPathName();
2313 llvm::sys::path::end(Name));
2326 if (llvm::sys::path::is_absolute(Name) &&
2327 llvm::sys::path::is_absolute(RealPathName) &&
2330 assert(Components.size() >= 3 &&
"should have drive, backslash, name");
2331 assert(Components[0].size() == 2 &&
"should start with drive");
2332 assert(Components[0][1] ==
':' &&
"should have colon");
2333 FixedDriveRealPath = (Name.substr(0, 1) + RealPathName.substr(1)).str();
2334 RealPathName = FixedDriveRealPath;
2340 Path.reserve(Name.size()+2);
2341 Path.push_back(isAngled ?
'<' :
'"');
2343 const auto IsSep = [BackslashStyle](
char c) {
2344 return llvm::sys::path::is_separator(
c, BackslashStyle);
2347 for (
auto Component : Components) {
2359 if (!(Component.size() == 1 && IsSep(Component[0])))
2360 Path.append(Component);
2361 else if (!Path.empty())
2365 if (Path.size() > NameWithoriginalSlashes.size()) {
2366 Path.push_back(isAngled ?
'>' :
'"');
2369 assert(IsSep(NameWithoriginalSlashes[Path.size()-1]));
2371 Path.push_back(NameWithoriginalSlashes[Path.size()-1]);
2372 while (Path.size() <= NameWithoriginalSlashes.size() &&
2373 IsSep(NameWithoriginalSlashes[Path.size()-1]));
2379 Path = (Path.substr(0, 1) +
"\\\\?\\" + Path.substr(1)).str();
2386 ? diag::pp_nonportable_path
2387 : diag::pp_nonportable_system_path;
2388 Diag(FilenameTok, DiagId) << Path <<
2397 return {ImportAction::SkippedModuleImport, M};
2400 case IncludeLimitReached:
2408 assert(M &&
"no module to import");
2416 return {ImportAction::ModuleImport, M};
2424 if (IncludeMacroStack.size() == MaxAllowedIncludeStackDepth-1) {
2425 Diag(FilenameTok, diag::err_pp_include_too_deep);
2426 HasReachedMaxIncludeDepth =
true;
2439 return ImportAction::Failure;
2444 IsFirstIncludeOfFile))
2448 if (
auto *M = SuggestedModule.
getModule()) {
2455 diag::note_previous_definition);
2471 assert(!CurLexerSubmodule &&
"should not have marked this as a module yet");
2472 CurLexerSubmodule = M;
2482 return {ImportAction::ModuleBegin, M};
2485 assert(!IsImportDecl &&
"failed to diagnose missing module for import decl");
2491 void Preprocessor::HandleIncludeNextDirective(
SourceLocation HashLoc,
2492 Token &IncludeNextTok) {
2493 Diag(IncludeNextTok, diag::ext_pp_include_next_directive);
2497 std::tie(Lookup, LookupFromFile) = getIncludeNextStart(IncludeNextTok);
2499 return HandleIncludeDirective(HashLoc, IncludeNextTok, Lookup,
2504 void Preprocessor::HandleMicrosoftImportDirective(
Token &Tok) {
2510 Diag(Tok, diag::err_pp_import_directive_ms );
2521 if (!LangOpts.ObjC) {
2522 if (LangOpts.MSVCCompat)
2523 return HandleMicrosoftImportDirective(ImportTok);
2524 Diag(ImportTok, diag::ext_pp_import_directive);
2526 return HandleIncludeDirective(HashLoc, ImportTok);
2533 void Preprocessor::HandleIncludeMacrosDirective(
SourceLocation HashLoc,
2534 Token &IncludeMacrosTok) {
2540 diag::pp_include_macros_out_of_predefines);
2547 HandleIncludeDirective(HashLoc, IncludeMacrosTok);
2552 assert(TmpTok.
isNot(
tok::eof) &&
"Didn't find end of -imacros!");
2553 }
while (TmpTok.
isNot(tok::hashhash));
2564 bool Preprocessor::ReadMacroParameterList(
MacroInfo *MI,
Token &Tok) {
2575 Diag(Tok, diag::err_pp_expected_ident_in_arg_list);
2579 Diag(Tok, LangOpts.CPlusPlus11 ?
2580 diag::warn_cxx98_compat_variadic_macro :
2581 diag::ext_variadic_macro);
2584 if (LangOpts.OpenCL && !LangOpts.OpenCLCPlusPlus) {
2585 Diag(Tok, diag::ext_pp_opencl_variadic_macros);
2590 if (Tok.
isNot(tok::r_paren)) {
2591 Diag(Tok, diag::err_pp_missing_rparen_in_macro_def);
2600 Diag(Tok, diag::err_pp_missing_rparen_in_macro_def);
2608 Diag(Tok, diag::err_pp_invalid_tok_in_arg_list);
2614 if (llvm::is_contained(Parameters, II)) {
2615 Diag(Tok, diag::err_pp_duplicate_name_in_arg_list) << II;
2627 Diag(Tok, diag::err_pp_expected_comma_in_arg_list);
2636 Diag(Tok, diag::ext_named_variadic_macro);
2640 if (Tok.
isNot(tok::r_paren)) {
2641 Diag(Tok, diag::err_pp_missing_rparen_in_macro_def);
2671 StringRef ValueText = II->
getName();
2672 StringRef TrimmedValue = ValueText;
2673 if (!ValueText.startswith(
"__")) {
2674 if (ValueText.startswith(
"_"))
2675 TrimmedValue = TrimmedValue.drop_front(1);
2679 TrimmedValue = TrimmedValue.drop_front(2);
2680 if (TrimmedValue.endswith(
"__"))
2681 TrimmedValue = TrimmedValue.drop_back(2);
2683 return TrimmedValue.equals(MacroText);
2690 return MacroName.
isOneOf(tok::kw_extern, tok::kw_inline, tok::kw_static,
2703 MacroInfo *Preprocessor::ReadOptionalMacroParameterListAndBody(
2704 const Token &MacroNameTok,
const bool ImmediatelyAfterHeaderGuard) {
2706 Token LastTok = MacroNameTok;
2714 auto _ = llvm::make_scope_exit([&]() {
2716 if (CurLexer->ParsingPreprocessorDirective)
2727 if (Tok.
is(tok::eod)) {
2728 if (ImmediatelyAfterHeaderGuard) {
2738 }
else if (Tok.
is(tok::l_paren)) {
2741 if (ReadMacroParameterList(MI, LastTok))
2755 }
else if (LangOpts.C99 || LangOpts.CPlusPlus11) {
2758 Diag(Tok, diag::ext_c99_whitespace_required_after_macro_name);
2767 if (Tok.
is(tok::at))
2769 else if (Tok.
is(tok::unknown)) {
2776 Diag(Tok, diag::ext_missing_whitespace_after_macro_name);
2778 Diag(Tok, diag::warn_missing_whitespace_after_macro_name);
2781 if (!Tok.
is(tok::eod))
2789 while (Tok.
isNot(tok::eod)) {
2791 Tokens.push_back(Tok);
2802 while (Tok.
isNot(tok::eod)) {
2805 if (!Tok.
isOneOf(tok::hash, tok::hashat, tok::hashhash)) {
2806 Tokens.push_back(Tok);
2808 if (VAOCtx.isVAOptToken(Tok)) {
2810 if (VAOCtx.isInVAOpt()) {
2811 Diag(Tok, diag::err_pp_vaopt_nested_use);
2816 if (Tok.
isNot(tok::l_paren)) {
2817 Diag(Tok, diag::err_pp_missing_lparen_in_vaopt_use);
2820 Tokens.push_back(Tok);
2821 VAOCtx.sawVAOptFollowedByOpeningParens(Tok.
getLocation());
2823 if (Tok.
is(tok::hashhash)) {
2824 Diag(Tok, diag::err_vaopt_paste_at_start);
2828 }
else if (VAOCtx.isInVAOpt()) {
2829 if (Tok.
is(tok::r_paren)) {
2830 if (VAOCtx.sawClosingParen()) {
2831 assert(Tokens.size() >= 3 &&
2832 "Must have seen at least __VA_OPT__( "
2833 "and a subsequent tok::r_paren");
2834 if (Tokens[Tokens.size() - 2].is(tok::hashhash)) {
2835 Diag(Tok, diag::err_vaopt_paste_at_end);
2839 }
else if (Tok.
is(tok::l_paren)) {
2853 Tokens.push_back(Tok);
2860 if (Tok.
is(tok::hashhash)) {
2868 if (Tok.
is(tok::eod)) {
2869 Tokens.push_back(LastTok);
2874 Tokens[Tokens.size() - 1].is(tok::comma))
2878 Tokens.push_back(LastTok);
2887 if (!VAOCtx.isVAOptToken(Tok) &&
2896 LastTok.
setKind(tok::unknown);
2897 Tokens.push_back(LastTok);
2900 Diag(Tok, diag::err_pp_stringize_not_parameter)
2901 << LastTok.
is(tok::hashat);
2907 Tokens.push_back(LastTok);
2912 if (!VAOCtx.isVAOptToken(Tok)) {
2913 Tokens.push_back(Tok);
2920 if (VAOCtx.isInVAOpt()) {
2921 assert(Tok.
is(tok::eod) &&
"Must be at End Of preprocessing Directive");
2922 Diag(Tok, diag::err_pp_expected_after)
2923 << LastTok.
getKind() << tok::r_paren;
2924 Diag(VAOCtx.getUnmatchedOpeningParenLoc(), diag::note_matching) << tok::l_paren;
2935 void Preprocessor::HandleDefineDirective(
2936 Token &DefineTok,
const bool ImmediatelyAfterHeaderGuard) {
2940 bool MacroShadowsKeyword;
2941 ReadMacroName(MacroNameTok,
MU_Define, &MacroShadowsKeyword);
2944 if (MacroNameTok.
is(tok::eod))
2951 emitFinalMacroWarning(MacroNameTok,
false);
2955 if (CurLexer) CurLexer->SetCommentRetentionState(KeepMacroComments);
2957 MacroInfo *
const MI = ReadOptionalMacroParameterListAndBody(
2958 MacroNameTok, ImmediatelyAfterHeaderGuard);
2962 if (MacroShadowsKeyword &&
2964 Diag(MacroNameTok, diag::warn_pp_macro_hides_keyword);
2969 if (NumTokens != 0) {
2981 if (SkippingUntilPCHThroughHeader) {
2984 LangOpts.MicrosoftExt))
2988 if (!LangOpts.MicrosoftExt)
2999 emitFinalMacroWarning(MacroNameTok,
false);
3004 auto isObjCProtectedMacro = [](
const IdentifierInfo *II) ->
bool {
3005 return II->
isStr(
"__strong") ||
3006 II->
isStr(
"__weak") ||
3007 II->
isStr(
"__unsafe_unretained") ||
3008 II->
isStr(
"__autoreleasing");
3018 LangOpts.MicrosoftExt)) {
3037 Diag(MacroNameTok, diag::ext_pp_redef_builtin_macro);
3041 !MI->
isIdenticalTo(*OtherMI, *
this, LangOpts.MicrosoftExt)) {
3059 !MacroExpansionInDirectivesOverride &&
3068 Callbacks->MacroDefined(MacroNameTok, MD);
3081 Tok.
setKind(tok::kw__Static_assert);
3090 void Preprocessor::HandleUndefDirective() {
3094 ReadMacroName(MacroNameTok,
MU_Undef);
3097 if (MacroNameTok.
is(tok::eod))
3109 emitFinalMacroWarning(MacroNameTok,
true);
3119 Undef = AllocateUndefMacroDirective(MacroNameTok.
getLocation());
3125 Callbacks->MacroUndefined(MacroNameTok, MD, Undef);
3140 void Preprocessor::HandleIfdefDirective(
Token &Result,
3141 const Token &HashToken,
3143 bool ReadAnyTokensBeforeDirective) {
3145 Token DirectiveTok = Result;
3148 ReadMacroName(MacroNameTok);
3151 if (MacroNameTok.
is(tok::eod)) {
3154 SkipExcludedConditionalBlock(HashToken.
getLocation(),
3174 if (!ReadAnyTokensBeforeDirective && !MI) {
3175 assert(isIfndef &&
"#ifdef shouldn't reach here");
3187 Callbacks->Ifndef(DirectiveTok.
getLocation(), MacroNameTok, MD);
3189 Callbacks->Ifdef(DirectiveTok.
getLocation(), MacroNameTok, MD);
3192 bool RetainExcludedCB = PPOpts->RetainExcludedConditionalBlocks &&
3196 if (PPOpts->SingleFileParseMode && !MI) {
3202 }
else if (!MI == isIfndef || RetainExcludedCB) {
3209 SkipExcludedConditionalBlock(HashToken.
getLocation(),
3218 void Preprocessor::HandleIfDirective(
Token &IfToken,
3219 const Token &HashToken,
3220 bool ReadAnyTokensBeforeDirective) {
3225 const DirectiveEvalResult DER = EvaluateDirectiveExpression(IfNDefMacro);
3226 const bool ConditionalTrue = DER.Conditional;
3235 if (!ReadAnyTokensBeforeDirective && IfNDefMacro && ConditionalTrue)
3247 bool RetainExcludedCB = PPOpts->RetainExcludedConditionalBlocks &&
3251 if (PPOpts->SingleFileParseMode && DER.IncludedUndefinedIds) {
3256 }
else if (ConditionalTrue || RetainExcludedCB) {
3270 void Preprocessor::HandleEndifDirective(
Token &EndifToken) {
3279 Diag(EndifToken, diag::err_pp_endif_without_if);
3288 "This code should only be reachable in the non-skipping case!");
3296 void Preprocessor::HandleElseDirective(
Token &Result,
const Token &HashToken) {
3304 Diag(Result, diag::pp_err_else_without_if);
3313 if (CI.
FoundElse)
Diag(Result, diag::pp_err_else_after_else);
3318 bool RetainExcludedCB = PPOpts->RetainExcludedConditionalBlocks &&
3321 if ((PPOpts->SingleFileParseMode && !CI.
FoundNonSkip) || RetainExcludedCB) {
3336 void Preprocessor::HandleElifFamilyDirective(
Token &ElifToken,
3337 const Token &HashToken,
3349 if (LangOpts.CPlusPlus)
3350 DiagID = LangOpts.CPlusPlus2b ? diag::warn_cxx2b_compat_pp_directive
3351 : diag::ext_cxx2b_pp_directive;
3353 DiagID = LangOpts.C2x ? diag::warn_c2x_compat_pp_directive
3354 : diag::ext_c2x_pp_directive;
3355 Diag(ElifToken, DiagID) << DirKind;
3368 Diag(ElifToken, diag::pp_err_elif_without_if) << DirKind;
3378 Diag(ElifToken, diag::pp_err_elif_after_else) << DirKind;
3383 Callbacks->Elif(ElifToken.
getLocation(), ConditionRange,
3393 assert(
false &&
"unexpected directive kind");
3398 bool RetainExcludedCB = PPOpts->RetainExcludedConditionalBlocks &&
3401 if ((PPOpts->SingleFileParseMode && !CI.
FoundNonSkip) || RetainExcludedCB) {
3410 SkipExcludedConditionalBlock(