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");
110 if (Text.size() >= 2 && Text[0] ==
'_' &&
116 if (Lang.CPlusPlus) {
117 if (Text.find(
"__") != StringRef::npos)
130 StringRef ModuleName) {
136 !CurrentModule.endswith(
"_Private") && TopLevelName.endswith(
"_Private"))
137 TopLevelName = TopLevelName.drop_back(8);
139 return TopLevelName == CurrentModule;
149 if (Lang.CPlusPlus11 && (Text.equals(
"override") || Text.equals(
"final")))
171 if (::llvm::sys::path::begin(Include)->equals_lower(
"boost"))
176 static const size_t MaxStdHeaderNameLen = 18u;
177 if (Include.size() > MaxStdHeaderNameLen)
182 for (
char &Ch : LowerInclude) {
184 if (static_cast<unsigned char>(Ch) > 0x7f)
187 if (Ch >=
'A' && Ch <=
'Z')
190 else if (::llvm::sys::path::is_separator(Ch))
195 return llvm::StringSwitch<bool>(LowerInclude)
197 .Cases(
"assert.h",
"complex.h",
"ctype.h",
"errno.h",
"fenv.h",
true)
198 .Cases(
"float.h",
"inttypes.h",
"iso646.h",
"limits.h",
"locale.h",
true)
199 .Cases(
"math.h",
"setjmp.h",
"signal.h",
"stdalign.h",
"stdarg.h",
true)
200 .Cases(
"stdatomic.h",
"stdbool.h",
"stddef.h",
"stdint.h",
"stdio.h",
true)
201 .Cases(
"stdlib.h",
"stdnoreturn.h",
"string.h",
"tgmath.h",
"threads.h",
true)
202 .Cases(
"time.h",
"uchar.h",
"wchar.h",
"wctype.h",
true)
205 .Cases(
"cassert",
"ccomplex",
"cctype",
"cerrno",
"cfenv",
true)
206 .Cases(
"cfloat",
"cinttypes",
"ciso646",
"climits",
"clocale",
true)
207 .Cases(
"cmath",
"csetjmp",
"csignal",
"cstdalign",
"cstdarg",
true)
208 .Cases(
"cstdbool",
"cstddef",
"cstdint",
"cstdio",
"cstdlib",
true)
209 .Cases(
"cstring",
"ctgmath",
"ctime",
"cuchar",
"cwchar",
true)
210 .Case(
"cwctype",
true)
213 .Cases(
"algorithm",
"fstream",
"list",
"regex",
"thread",
true)
214 .Cases(
"array",
"functional",
"locale",
"scoped_allocator",
"tuple",
true)
215 .Cases(
"atomic",
"future",
"map",
"set",
"type_traits",
true)
216 .Cases(
"bitset",
"initializer_list",
"memory",
"shared_mutex",
"typeindex",
true)
217 .Cases(
"chrono",
"iomanip",
"mutex",
"sstream",
"typeinfo",
true)
218 .Cases(
"codecvt",
"ios",
"new",
"stack",
"unordered_map",
true)
219 .Cases(
"complex",
"iosfwd",
"numeric",
"stdexcept",
"unordered_set",
true)
220 .Cases(
"condition_variable",
"iostream",
"ostream",
"streambuf",
"utility",
true)
221 .Cases(
"deque",
"istream",
"queue",
"string",
"valarray",
true)
222 .Cases(
"exception",
"iterator",
"random",
"strstream",
"vector",
true)
223 .Cases(
"forward_list",
"limits",
"ratio",
"system_error",
true)
226 .Cases(
"aio.h",
"arpa/inet.h",
"cpio.h",
"dirent.h",
"dlfcn.h",
true)
227 .Cases(
"fcntl.h",
"fmtmsg.h",
"fnmatch.h",
"ftw.h",
"glob.h",
true)
228 .Cases(
"grp.h",
"iconv.h",
"langinfo.h",
"libgen.h",
"monetary.h",
true)
229 .Cases(
"mqueue.h",
"ndbm.h",
"net/if.h",
"netdb.h",
"netinet/in.h",
true)
230 .Cases(
"netinet/tcp.h",
"nl_types.h",
"poll.h",
"pthread.h",
"pwd.h",
true)
231 .Cases(
"regex.h",
"sched.h",
"search.h",
"semaphore.h",
"spawn.h",
true)
232 .Cases(
"strings.h",
"stropts.h",
"sys/ipc.h",
"sys/mman.h",
"sys/msg.h",
true)
233 .Cases(
"sys/resource.h",
"sys/select.h",
"sys/sem.h",
"sys/shm.h",
"sys/socket.h",
true)
234 .Cases(
"sys/stat.h",
"sys/statvfs.h",
"sys/time.h",
"sys/times.h",
"sys/types.h",
true)
235 .Cases(
"sys/uio.h",
"sys/un.h",
"sys/utsname.h",
"sys/wait.h",
"syslog.h",
true)
236 .Cases(
"tar.h",
"termios.h",
"trace.h",
"ulimit.h",
true)
237 .Cases(
"unistd.h",
"utime.h",
"utmpx.h",
"wordexp.h",
true)
244 if (MacroNameTok.
is(tok::eod))
245 return Diag(MacroNameTok, diag::err_pp_missing_macro_name);
249 return Diag(MacroNameTok, diag::err_pp_macro_not_identifier);
255 ? diag::ext_pp_operator_used_as_macro_name
256 : diag::err_pp_operator_used_as_macro_name)
257 << II << MacroNameTok.
getKind();
264 return Diag(MacroNameTok, diag::err_defined_macro_name);
272 Diag(MacroNameTok, diag::ext_pp_undef_builtin_macro);
297 Diag(MacroNameTok, diag::warn_pp_macro_is_reserved_id);
313 void Preprocessor::ReadMacroName(
Token &MacroNameTok,
MacroUse isDefineUndef,
318 if (MacroNameTok.
is(tok::code_completion)) {
330 if (MacroNameTok.
isNot(tok::eod)) {
331 MacroNameTok.
setKind(tok::eod);
355 while (Tmp.
is(tok::comment))
358 if (Tmp.
is(tok::eod))
366 if ((LangOpts.GNUMode || LangOpts.C99 || LangOpts.CPlusPlus) &&
369 Diag(Tmp, diag::ext_pp_extra_tokens_at_eol) << DirType << Hint;
375 if (!ExcludedConditionalDirectiveSkipMappings)
380 std::pair<FileID, unsigned> HashFileOffset =
382 const llvm::MemoryBuffer *Buf = SourceMgr.
getBuffer(HashFileOffset.first);
383 auto It = ExcludedConditionalDirectiveSkipMappings->find(Buf);
384 if (It == ExcludedConditionalDirectiveSkipMappings->end())
389 auto MappingIt = SkippedRanges.find(HashFileOffset.second);
390 if (MappingIt == SkippedRanges.end())
393 unsigned BytesToSkip = MappingIt->getSecond();
394 unsigned CurLexerBufferOffset = CurLexer->getCurrentBufferOffset();
395 assert(CurLexerBufferOffset >= HashFileOffset.second &&
396 "lexer is before the hash?");
399 unsigned LengthDiff = CurLexerBufferOffset - HashFileOffset.second;
400 assert(BytesToSkip >= LengthDiff &&
"lexer is after the skipped range?");
401 return BytesToSkip - LengthDiff;
412 void Preprocessor::SkipExcludedConditionalBlock(
SourceLocation HashTokenLoc,
414 bool FoundNonSkipPortion,
418 assert(!CurTokenLexer && CurPPLexer &&
"Lexing a macro, not a file?");
420 if (PreambleConditionalStack.reachedEOFWhileSkipping())
421 PreambleConditionalStack.clearSkipInfo();
424 FoundNonSkipPortion, FoundElse);
430 if (
auto SkipLength =
431 getSkippedRangeForExcludedConditionalBlock(HashTokenLoc)) {
433 CurLexer->skipOver(*SkipLength);
438 if (Tok.
is(tok::code_completion)) {
450 if (PreambleConditionalStack.isRecording())
451 PreambleConditionalStack.SkipInfo.emplace(
452 HashTokenLoc, IfTokenLoc, FoundNonSkipPortion, FoundElse, ElseLoc);
464 if (CurLexer) CurLexer->SetKeepWhitespaceMode(
false);
472 if (Tok.
isNot(tok::raw_identifier)) {
475 if (CurLexer) CurLexer->resetExtendedTokenMode();
486 char FirstChar = RI[0];
487 if (FirstChar >=
'a' && FirstChar <=
'z' &&
488 FirstChar !=
'i' && FirstChar !=
'e') {
491 if (CurLexer) CurLexer->resetExtendedTokenMode();
498 char DirectiveBuf[20];
504 size_t IdLen = DirectiveStr.size();
508 if (CurLexer) CurLexer->resetExtendedTokenMode();
511 memcpy(DirectiveBuf, &DirectiveStr[0], IdLen);
512 Directive = StringRef(DirectiveBuf, IdLen);
515 if (Directive.startswith(
"if")) {
516 StringRef
Sub = Directive.substr(2);
527 }
else if (Directive[0] ==
'e') {
528 StringRef
Sub = Directive.substr(1);
534 assert(!InCond &&
"Can't be skipping if not in a conditional!");
549 }
else if (Sub ==
"lse") {
556 if (CondInfo.
FoundElse)
Diag(Tok, diag::pp_err_else_after_else);
576 }
else if (Sub ==
"lif") {
580 if (CondInfo.
FoundElse)
Diag(Tok, diag::pp_err_elif_after_else);
589 assert(CurPPLexer->
LexingRawMode &&
"We have to be skipping here!");
592 DirectiveEvalResult DER = EvaluateDirectiveExpression(IfNDefMacro);
593 const bool CondValue = DER.Conditional;
612 if (CurLexer) CurLexer->resetExtendedTokenMode();
623 Callbacks->SourceRangeSkipped(
652 assert(M &&
"no module to include");
663 !InGlobalModuleFragment)
680 if (InGlobalModuleFragment) {
687 bool InTextualHeader =
false;
689 if (!Header.getModule()->isSubModuleOf(TopM))
696 if (Header.isAccessibleFrom(IncM))
706 InTextualHeader =
true;
709 if (!InTextualHeader)
724 bool *IsFrameworkFound,
bool SkipCache) {
726 bool RequestingModuleIsModuleInterface = !SourceMgr.
isInMainFile(FilenameLoc);
732 bool BuildSystemModule =
false;
733 if (!FromDir && !FromFile) {
751 Includers.push_back(std::make_pair(
nullptr, MainFileDir));
753 }
else if ((FileEnt =
755 Includers.push_back(std::make_pair(FileEnt, *FileMgr.
getDirectory(
".")));
757 Includers.push_back(std::make_pair(FileEnt, FileEnt->
getDir()));
763 if (LangOpts.MSVCCompat && !isAngled) {
764 for (IncludeStackInfo &ISEntry : llvm::reverse(IncludeMacroStack)) {
765 if (IsFileLexer(ISEntry))
766 if ((FileEnt = ISEntry.ThePPLexer->getFileEntry()))
767 Includers.push_back(std::make_pair(FileEnt, FileEnt->
getDir()));
772 CurDir = CurDirLookup;
780 Filename, FilenameLoc, isAngled, TmpFromDir, TmpCurDir,
781 Includers, SearchPath, RelativePath, RequestingModule,
782 SuggestedModule,
nullptr,
783 nullptr, SkipCache)) {
785 TmpFromDir = TmpCurDir;
787 if (&FE->getFileEntry() == FromFile) {
789 FromDir = TmpFromDir;
798 Filename, FilenameLoc, isAngled, FromDir, CurDir, Includers, SearchPath,
799 RelativePath, RequestingModule, SuggestedModule, IsMapped,
800 IsFrameworkFound, SkipCache, BuildSystemModule);
802 if (SuggestedModule && !LangOpts.AsmPreprocessor)
804 RequestingModule, RequestingModuleIsModuleInterface, FilenameLoc,
805 Filename, &FE->getFileEntry());
816 Filename, CurFileEnt, SearchPath, RelativePath, RequestingModule,
818 if (SuggestedModule && !LangOpts.AsmPreprocessor)
820 RequestingModule, RequestingModuleIsModuleInterface, FilenameLoc,
821 Filename, &FE->getFileEntry());
827 for (IncludeStackInfo &ISEntry : llvm::reverse(IncludeMacroStack)) {
828 if (IsFileLexer(ISEntry)) {
829 if ((CurFileEnt = ISEntry.ThePPLexer->getFileEntry())) {
831 Filename, CurFileEnt, SearchPath, RelativePath,
832 RequestingModule, SuggestedModule)) {
833 if (SuggestedModule && !LangOpts.AsmPreprocessor)
835 RequestingModule, RequestingModuleIsModuleInterface,
836 FilenameLoc, Filename, &FE->getFileEntry());
854 : PP(pp), save(pp->DisableMacroExpansion) {
855 if (pp->MacroExpansionInDirectivesOverride)
856 pp->DisableMacroExpansion =
false;
860 PP->DisableMacroExpansion = save;
878 return HandleDefineDirective(Result,
881 if (SkippingUntilPCHThroughHeader &&
883 return HandleIncludeDirective(HashLoc, Result);
885 if (SkippingUntilPragmaHdrStop && II->getPPKeywordID() == tok::pp_pragma) {
888 if (II && II->getName() ==
"hdrstop")
905 CurPPLexer->ParsingPreprocessorDirective =
true;
906 if (CurLexer) CurLexer->SetKeepWhitespaceMode(
false);
908 bool ImmediatelyAfterTopLevelIfndef =
909 CurPPLexer->MIOpt.getImmediatelyAfterTopLevelIfndef();
910 CurPPLexer->MIOpt.resetImmediatelyAfterTopLevelIfndef();
917 bool ReadAnyTokensBeforeDirective =CurPPLexer->MIOpt.getHasReadAnyTokensVal();
936 switch (II->getPPKeywordID()) {
942 Diag(Result, diag::err_embedded_directive) << II->getName();
943 Diag(*ArgMacro, diag::note_macro_expansion_here)
944 << ArgMacro->getIdentifierInfo();
951 Diag(Result, diag::ext_embedded_directive);
958 if (SkippingUntilPCHThroughHeader || SkippingUntilPragmaHdrStop)
964 case tok::code_completion:
966 CodeComplete->CodeCompleteDirective(
967 CurPPLexer->getConditionalStackDepth() > 0);
970 case tok::numeric_constant:
973 return HandleDigitDirective(Result);
983 return HandleIfDirective(Result, SavedHash, ReadAnyTokensBeforeDirective);
985 return HandleIfdefDirective(Result, SavedHash,
false,
988 return HandleIfdefDirective(Result, SavedHash,
true,
989 ReadAnyTokensBeforeDirective);
991 return HandleElifDirective(Result, SavedHash);
993 return HandleElseDirective(Result, SavedHash);
995 return HandleEndifDirective(Result);
1007 return HandleDefineDirective(Result, ImmediatelyAfterTopLevelIfndef);
1009 return HandleUndefDirective();
1013 return HandleLineDirective();
1017 return HandleUserDiagnosticDirective(Result,
false);
1020 case tok::pp_pragma:
1029 case tok::pp_warning:
1030 Diag(Result, diag::ext_pp_warning_directive);
1031 return HandleUserDiagnosticDirective(Result,
true);
1033 return HandleIdentSCCSDirective(Result);
1035 return HandleIdentSCCSDirective(Result);
1036 case tok::pp_assert:
1039 case tok::pp_unassert:
1043 case tok::pp___public_macro:
1045 return HandleMacroPublicDirective(Result);
1048 case tok::pp___private_macro:
1050 return HandleMacroPrivateDirective();
1061 auto Toks = std::make_unique<Token[]>(2);
1063 Toks[0] = SavedHash;
1068 if (Result.
is(tok::hashhash))
1069 Toks[1].setKind(tok::unknown);
1074 EnterTokenStream(std::move(Toks), 2,
false,
false);
1079 Diag(Result, diag::err_pp_invalid_directive);
1091 bool IsGNULineDirective=
false) {
1092 if (DigitTok.
isNot(tok::numeric_constant)) {
1093 PP.
Diag(DigitTok, DiagID);
1095 if (DigitTok.
isNot(tok::eod))
1101 IntegerBuffer.resize(DigitTok.
getLength());
1102 const char *DigitTokBegin = &IntegerBuffer[0];
1103 bool Invalid =
false;
1104 unsigned ActualLength = PP.
getSpelling(DigitTok, DigitTokBegin, &Invalid);
1112 for (
unsigned i = 0; i != ActualLength; ++i) {
1115 if (DigitTokBegin[i] ==
'\'')
1118 if (!
isDigit(DigitTokBegin[i])) {
1120 diag::err_pp_line_digit_sequence) << IsGNULineDirective;
1125 unsigned NextVal = Val*10+(DigitTokBegin[i]-
'0');
1126 if (NextVal < Val) {
1127 PP.
Diag(DigitTok, DiagID);
1134 if (DigitTokBegin[0] ==
'0' && Val)
1136 << IsGNULineDirective;
1148 void Preprocessor::HandleLineDirective() {
1156 if (
GetLineValue(DigitTok, LineNo, diag::err_pp_line_requires_integer,*
this))
1160 Diag(DigitTok, diag::ext_pp_line_zero);
1164 unsigned LineLimit = 32768U;
1165 if (LangOpts.C99 || LangOpts.CPlusPlus11)
1166 LineLimit = 2147483648U;
1167 if (LineNo >= LineLimit)
1168 Diag(DigitTok, diag::ext_pp_line_too_big) << LineLimit;
1169 else if (LangOpts.CPlusPlus11 && LineNo >= 32768U)
1170 Diag(DigitTok, diag::warn_cxx98_compat_pp_line_too_big);
1172 int FilenameID = -1;
1178 if (StrTok.
is(tok::eod))
1180 else if (StrTok.
isNot(tok::string_literal)) {
1181 Diag(StrTok, diag::err_pp_line_invalid_filename);
1185 Diag(StrTok, diag::err_invalid_string_udl);
1191 assert(Literal.
isAscii() &&
"Didn't allow wide strings in");
1197 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1201 FilenameID = SourceMgr.getLineTableFilenameID(Literal.
GetString());
1214 SourceMgr.getFileCharacteristic(DigitTok.
getLocation());
1216 SourceMgr.AddLineNote(DigitTok.
getLocation(), LineNo, FilenameID,
false,
1220 Callbacks->FileChanged(CurPPLexer->getSourceLocation(),
1232 if (FlagTok.
is(tok::eod))
return false;
1233 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag, PP))
1240 if (FlagTok.
is(tok::eod))
return false;
1241 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag,PP))
1243 }
else if (FlagVal == 2) {
1260 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_pop);
1266 if (FlagTok.
is(tok::eod))
return false;
1267 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag,PP))
1273 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1281 if (FlagTok.
is(tok::eod))
return false;
1282 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag, PP))
1287 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1295 if (FlagTok.
is(tok::eod))
return false;
1298 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1310 void Preprocessor::HandleDigitDirective(
Token &DigitTok) {
1314 if (
GetLineValue(DigitTok, LineNo, diag::err_pp_linemarker_requires_integer,
1321 bool IsFileEntry =
false, IsFileExit =
false;
1322 int FilenameID = -1;
1327 if (StrTok.
is(tok::eod)) {
1329 FileKind = SourceMgr.getFileCharacteristic(DigitTok.
getLocation());
1330 }
else if (StrTok.
isNot(tok::string_literal)) {
1331 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1335 Diag(StrTok, diag::err_invalid_string_udl);
1341 assert(Literal.
isAscii() &&
"Didn't allow wide strings in");
1347 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1351 FilenameID = SourceMgr.getLineTableFilenameID(Literal.
GetString());
1359 SourceMgr.AddLineNote(DigitTok.
getLocation(), LineNo, FilenameID, IsFileEntry,
1360 IsFileExit, FileKind);
1369 else if (IsFileExit)
1372 Callbacks->FileChanged(CurPPLexer->getSourceLocation(), Reason, FileKind);
1378 void Preprocessor::HandleUserDiagnosticDirective(
Token &
Tok,
1386 CurLexer->ReadToEndOfLine(&Message);
1390 StringRef Msg = StringRef(Message).ltrim(
' ');
1393 Diag(Tok, diag::pp_hash_warning) << Msg;
1395 Diag(Tok, diag::err_pp_hash_error) << Msg;
1400 void Preprocessor::HandleIdentSCCSDirective(
Token &Tok) {
1402 Diag(Tok, diag::ext_pp_ident_directive);
1409 if (StrTok.
isNot(tok::string_literal) &&
1410 StrTok.
isNot(tok::wide_string_literal)) {
1411 Diag(StrTok, diag::err_pp_malformed_ident);
1412 if (StrTok.
isNot(tok::eod))
1418 Diag(StrTok, diag::err_invalid_string_udl);
1427 bool Invalid =
false;
1435 void Preprocessor::HandleMacroPublicDirective(
Token &Tok) {
1437 ReadMacroName(MacroNameTok,
MU_Undef);
1440 if (MacroNameTok.
is(tok::eod))
1452 Diag(MacroNameTok, diag::err_pp_visibility_non_macro) << II;
1462 void Preprocessor::HandleMacroPrivateDirective() {
1464 ReadMacroName(MacroNameTok,
MU_Undef);
1467 if (MacroNameTok.
is(tok::eod))
1479 Diag(MacroNameTok, diag::err_pp_visibility_non_macro) << II;
1499 StringRef &Buffer) {
1501 assert(!Buffer.empty() &&
"Can't have tokens with empty spellings!");
1513 if (Buffer[0] ==
'<') {
1514 if (Buffer.back() !=
'>') {
1515 Diag(Loc, diag::err_pp_expects_filename);
1516 Buffer = StringRef();
1520 }
else if (Buffer[0] ==
'"') {
1521 if (Buffer.back() !=
'"') {
1522 Diag(Loc, diag::err_pp_expects_filename);
1523 Buffer = StringRef();
1528 Diag(Loc, diag::err_pp_expects_filename);
1529 Buffer = StringRef();
1534 if (Buffer.size() <= 2) {
1535 Diag(Loc, diag::err_pp_empty_filename);
1536 Buffer = StringRef();
1541 Buffer = Buffer.substr(1, Buffer.size()-2);
1548 void *AnnotationVal) {
1551 auto Tok = std::make_unique<Token[]>(1);
1557 EnterTokenStream(std::move(Tok), 1,
true,
false);
1564 ArrayRef<std::pair<IdentifierInfo *, SourceLocation>> Path,
1566 StringRef ImportKeyword;
1568 ImportKeyword =
"@import";
1570 ImportKeyword =
"import";
1575 for (
size_t I = 0, N = Path.size(); I != N; ++I) {
1578 PathString += Path[I].first->getName();
1580 int IncludeKind = 0;
1600 llvm_unreachable(
"unknown include directive kind");
1605 PP.
Diag(HashLoc, diag::warn_auto_module_import)
1606 << IncludeKind << PathString
1608 ReplaceRange, (ImportKeyword +
" " + PathString +
";").str());
1615 StringRef RealPathName) {
1616 auto RealPathComponentIter = llvm::sys::path::rbegin(RealPathName);
1617 auto RealPathComponentEnd = llvm::sys::path::rend(RealPathName);
1619 bool SuggestReplacement =
false;
1622 for (
auto &Component : llvm::reverse(Components)) {
1623 if (
"." == Component) {
1624 }
else if (
".." == Component) {
1628 }
else if (RealPathComponentIter != RealPathComponentEnd) {
1629 if (Component != *RealPathComponentIter) {
1633 SuggestReplacement = RealPathComponentIter->equals_lower(Component);
1634 if (!SuggestReplacement)
1636 Component = *RealPathComponentIter;
1638 ++RealPathComponentIter;
1641 return SuggestReplacement;
1649 Module *ShadowingModule =
nullptr;
1650 if (M->
isAvailable(LangOpts, TargetInfo, Requirement, MissingHeader,
1657 }
else if (ShadowingModule) {
1660 diag::note_previous_definition);
1675 void Preprocessor::HandleIncludeDirective(
SourceLocation HashLoc,
1683 if (FilenameTok.
isNot(tok::header_name)) {
1685 if (FilenameTok.
isNot(tok::eod))
1697 auto Action = HandleHeaderIncludeOrImport(HashLoc, IncludeTok, FilenameTok,
1698 EndLoc, LookupFrom, LookupFromFile);
1699 switch (Action.Kind) {
1701 case ImportAction::SkippedModuleImport:
1703 case ImportAction::ModuleBegin:
1705 tok::annot_module_begin, Action.ModuleForHeader);
1707 case ImportAction::ModuleImport:
1709 tok::annot_module_include, Action.ModuleForHeader);
1717 const Token &FilenameTok,
bool &IsFrameworkFound,
bool IsImportDecl,
1719 const FileEntry *LookupFromFile, StringRef LookupFilename,
1723 FilenameLoc, LookupFilename,
1724 isAngled, LookupFrom, LookupFromFile, CurDir,
1725 Callbacks ? &SearchPath :
nullptr, Callbacks ? &RelativePath :
nullptr,
1726 &SuggestedModule, &IsMapped, &IsFrameworkFound);
1733 if (Callbacks->FileNotFound(
Filename, RecoveryPath)) {
1734 if (
auto DE = FileMgr.getOptionalDirectoryRef(RecoveryPath)) {
1737 HeaderInfo.AddSearchPath(DL, isAngled);
1742 LookupFilename, isAngled,
1743 LookupFrom, LookupFromFile, CurDir,
nullptr,
nullptr,
1744 &SuggestedModule, &IsMapped,
nullptr,
1752 if (SuppressIncludeNotFoundError)
1760 FilenameLoc, LookupFilename,
1761 false, LookupFrom, LookupFromFile, CurDir,
1762 Callbacks ? &SearchPath :
nullptr, Callbacks ? &RelativePath :
nullptr,
1763 &SuggestedModule, &IsMapped,
1766 Diag(FilenameTok, diag::err_pp_file_not_found_angled_include_not_fatal)
1776 StringRef OriginalFilename =
Filename;
1777 if (LangOpts.SpellChecking) {
1780 auto CorrectTypoFilename = [](llvm::StringRef
Filename) {
1787 StringRef TypoCorrectionName = CorrectTypoFilename(
Filename);
1794 if (LangOpts.MicrosoftExt) {
1795 NormalizedTypoCorrectionPath = TypoCorrectionName;
1796 llvm::sys::path::native(NormalizedTypoCorrectionPath);
1797 TypoCorrectionName = NormalizedTypoCorrectionPath;
1802 FilenameLoc, TypoCorrectionName, isAngled, LookupFrom, LookupFromFile,
1803 CurDir, Callbacks ? &SearchPath :
nullptr,
1804 Callbacks ? &RelativePath :
nullptr, &SuggestedModule, &IsMapped,
1809 FilenameRange,
"<" + TypoCorrectionName.str() +
">")
1811 FilenameRange,
"\"" + TypoCorrectionName.str() +
"\"");
1812 Diag(FilenameTok, diag::err_pp_file_not_found_typo_not_fatal)
1813 << OriginalFilename << TypoCorrectionName << Hint;
1822 assert(!File.hasValue() &&
"expected missing file");
1823 Diag(FilenameTok, diag::err_pp_file_not_found)
1824 << OriginalFilename << FilenameRange;
1825 if (IsFrameworkFound) {
1826 size_t SlashPos = OriginalFilename.find(
'/');
1827 assert(SlashPos != StringRef::npos &&
1828 "Include with framework name should have '/' in the filename");
1829 StringRef FrameworkName = OriginalFilename.substr(0, SlashPos);
1831 HeaderInfo.LookupFrameworkCache(FrameworkName);
1832 assert(CacheEntry.
Directory &&
"Found framework should be in cache");
1833 Diag(FilenameTok, diag::note_pp_framework_without_header)
1834 << OriginalFilename.substr(SlashPos + 1) << FrameworkName
1853 Preprocessor::ImportAction Preprocessor::HandleHeaderIncludeOrImport(
1863 StringRef OriginalFilename =
Filename;
1869 if (Filename.empty())
1872 bool IsImportDecl = HashLoc.
isInvalid();
1876 if (PragmaARCCFCodeAuditedInfo.second.isValid()) {
1877 Diag(StartLoc, diag::err_pp_include_in_arc_cf_code_audited) << IsImportDecl;
1878 Diag(PragmaARCCFCodeAuditedInfo.second, diag::note_pragma_entered_here);
1885 if (PragmaAssumeNonNullLoc.isValid()) {
1886 Diag(StartLoc, diag::err_pp_include_in_assume_nonnull) << IsImportDecl;
1887 Diag(PragmaAssumeNonNullLoc, diag::note_pragma_entered_here);
1893 if (HeaderInfo.HasIncludeAliasMap()) {
1897 StringRef NewName = HeaderInfo.MapHeaderToIncludeAlias(OriginalFilename);
1898 if (!NewName.empty())
1903 bool IsMapped =
false;
1904 bool IsFrameworkFound =
false;
1912 StringRef LookupFilename =
Filename;
1918 if (LangOpts.MicrosoftExt) {
1919 NormalizedPath = Filename.str();
1920 llvm::sys::path::native(NormalizedPath);
1921 LookupFilename = NormalizedPath;
1926 CurDir, Filename, FilenameLoc, FilenameRange, FilenameTok,
1927 IsFrameworkFound, IsImportDecl, IsMapped, LookupFrom, LookupFromFile,
1928 LookupFilename, RelativePath, SearchPath, SuggestedModule, isAngled);
1932 SkippingUntilPCHThroughHeader =
false;
1941 if (File && PreambleConditionalStack.isRecording() &&
1942 SourceMgr.translateFile(&File->getFileEntry()) ==
1943 SourceMgr.getMainFileID()) {
1945 diag::err_pp_including_mainfile_in_preamble);
1953 enum { Enter, Import, Skip, IncludeLimitReached } Action = Enter;
1955 if (PPOpts->SingleFileParseMode)
1956 Action = IncludeLimitReached;
1961 if (Action == Enter && HasReachedMaxIncludeDepth && File &&
1962 HeaderInfo.getFileInfo(&File->getFileEntry()).NumIncludes)
1963 Action = IncludeLimitReached;
1968 if (Action == Enter && File && SuggestedModule &&
getLangOpts().Modules &&
1979 diag::note_implicit_top_level_module_import_here)
1991 std::reverse(Path.begin(), Path.end());
2004 assert((Imported ==
nullptr || Imported == SuggestedModule.
getModule()) &&
2005 "the imported module is different than the suggested one");
2023 assert(CurLexer &&
"#include but no current lexer set!");
2025 CurLexer->FormTokenWithChars(Result, CurLexer->BufferEnd,
tok::eof);
2026 CurLexer->cutOffLexing();
2036 SourceMgr.getFileCharacteristic(FilenameTok.
getLocation());
2038 FileCharacter =
std::max(HeaderInfo.getFileDirFlavor(&File->getFileEntry()),
2052 if (Action == Enter && File &&
2053 !HeaderInfo.ShouldEnterIncludeFile(*
this, &File->getFileEntry(),
2063 Action = (SuggestedModule && !
getLangOpts().CompilingPCH) ? Import : Skip;
2066 if (Callbacks && !IsImportDecl) {
2069 Callbacks->InclusionDirective(
2070 HashLoc, IncludeTok, LookupFilename, isAngled, FilenameRange,
2071 File ? &File->getFileEntry() :
nullptr, SearchPath, RelativePath,
2072 Action == Import ? SuggestedModule.
getModule() :
nullptr,
2074 if (Action == Skip && File)
2075 Callbacks->FileSkipped(*File, FilenameTok, FileCharacter);
2083 if (IsImportDecl && !SuggestedModule) {
2084 Diag(FilenameTok, diag::err_header_import_not_header_unit)
2085 << OriginalFilename << File->getName();
2091 const bool CheckIncludePathPortability =
2092 !IsMapped && !File->getFileEntry().tryGetRealPathName().empty();
2094 if (CheckIncludePathPortability) {
2095 StringRef Name = LookupFilename;
2096 StringRef RealPathName = File->getFileEntry().tryGetRealPathName();
2098 llvm::sys::path::end(Name));
2102 Path.reserve(Name.size()+2);
2103 Path.push_back(isAngled ?
'<' :
'"');
2104 bool isLeadingSeparator = llvm::sys::path::is_absolute(Name);
2105 for (
auto Component : Components) {
2106 if (isLeadingSeparator)
2107 isLeadingSeparator =
false;
2109 Path.append(Component);
2112 Path.size() <= Filename.size() ? Filename[Path.size()-1] :
2113 (isAngled ?
'>' :
'"'));
2118 diag::pp_nonportable_path : diag::pp_nonportable_system_path;
2119 Diag(FilenameTok, DiagId) << Path <<
2128 return {ImportAction::SkippedModuleImport, M};
2131 case IncludeLimitReached:
2139 assert(M &&
"no module to import");
2147 return {ImportAction::ModuleImport, M};
2155 if (IncludeMacroStack.size() == MaxAllowedIncludeStackDepth-1) {
2156 Diag(FilenameTok, diag::err_pp_include_too_deep);
2157 HasReachedMaxIncludeDepth =
true;
2166 IncludePos = SourceMgr.getExpansionRange(IncludePos).getEnd();
2167 FileID FID = SourceMgr.createFileID(*File, IncludePos, FileCharacter);
2168 assert(FID.
isValid() &&
"Expected valid file ID");
2175 if (
auto *M = SuggestedModule.
getModule()) {
2176 if (M->getTopLevelModule()->ShadowingModule) {
2179 Diag(M->DefinitionLoc, diag::err_module_build_shadowed_submodule)
2180 << M->getFullModuleName();
2181 Diag(M->getTopLevelModule()->ShadowingModule->DefinitionLoc,
2182 diag::note_previous_definition);
2198 assert(!CurLexerSubmodule &&
"should not have marked this as a module yet");
2199 CurLexerSubmodule = M;
2209 return {ImportAction::ModuleBegin, M};
2212 assert(!IsImportDecl &&
"failed to diagnose missing module for import decl");
2218 void Preprocessor::HandleIncludeNextDirective(
SourceLocation HashLoc,
2219 Token &IncludeNextTok) {
2220 Diag(IncludeNextTok, diag::ext_pp_include_next_directive);
2226 const FileEntry *LookupFromFile =
nullptr;
2233 Diag(IncludeNextTok, diag::pp_include_next_in_primary);
2234 }
else if (CurLexerSubmodule) {
2237 assert(CurPPLexer &&
"#include_next directive in macro?");
2238 LookupFromFile = CurPPLexer->getFileEntry();
2240 }
else if (!Lookup) {
2245 Diag(IncludeNextTok, diag::pp_include_next_absolute_path);
2251 return HandleIncludeDirective(HashLoc, IncludeNextTok, Lookup,
2256 void Preprocessor::HandleMicrosoftImportDirective(
Token &Tok) {
2262 Diag(Tok, diag::err_pp_import_directive_ms );
2273 if (!LangOpts.ObjC) {
2274 if (LangOpts.MSVCCompat)
2275 return HandleMicrosoftImportDirective(ImportTok);
2276 Diag(ImportTok, diag::ext_pp_import_directive);
2278 return HandleIncludeDirective(HashLoc, ImportTok);
2285 void Preprocessor::HandleIncludeMacrosDirective(
SourceLocation HashLoc,
2286 Token &IncludeMacrosTok) {
2290 if (SourceMgr.getBufferName(Loc) !=
"<built-in>") {
2292 diag::pp_include_macros_out_of_predefines);
2299 HandleIncludeDirective(HashLoc, IncludeMacrosTok);
2304 assert(TmpTok.
isNot(
tok::eof) &&
"Didn't find end of -imacros!");
2305 }
while (TmpTok.
isNot(tok::hashhash));
2316 bool Preprocessor::ReadMacroParameterList(
MacroInfo *MI,
Token &Tok) {
2324 if (Parameters.empty())
2327 Diag(Tok, diag::err_pp_expected_ident_in_arg_list);
2331 Diag(Tok, LangOpts.CPlusPlus11 ?
2332 diag::warn_cxx98_compat_variadic_macro :
2333 diag::ext_variadic_macro);
2336 if (LangOpts.OpenCL) {
2337 Diag(Tok, diag::ext_pp_opencl_variadic_macros);
2342 if (Tok.
isNot(tok::r_paren)) {
2343 Diag(Tok, diag::err_pp_missing_rparen_in_macro_def);
2347 Parameters.push_back(Ident__VA_ARGS__);
2352 Diag(Tok, diag::err_pp_missing_rparen_in_macro_def);
2360 Diag(Tok, diag::err_pp_invalid_tok_in_arg_list);
2366 if (llvm::find(Parameters, II) != Parameters.end()) {
2367 Diag(Tok, diag::err_pp_duplicate_name_in_arg_list) << II;
2372 Parameters.push_back(II);
2379 Diag(Tok, diag::err_pp_expected_comma_in_arg_list);
2388 Diag(Tok, diag::ext_named_variadic_macro);
2392 if (Tok.
isNot(tok::r_paren)) {
2393 Diag(Tok, diag::err_pp_missing_rparen_in_macro_def);
2421 if (!II->isKeyword(LOptions))
2423 StringRef ValueText = II->getName();
2424 StringRef TrimmedValue = ValueText;
2425 if (!ValueText.startswith(
"__")) {
2426 if (ValueText.startswith(
"_"))
2427 TrimmedValue = TrimmedValue.drop_front(1);
2431 TrimmedValue = TrimmedValue.drop_front(2);
2432 if (TrimmedValue.endswith(
"__"))
2433 TrimmedValue = TrimmedValue.drop_back(2);
2435 return TrimmedValue.equals(MacroText);
2442 return MacroName.
isOneOf(tok::kw_extern, tok::kw_inline, tok::kw_static,
2455 MacroInfo *Preprocessor::ReadOptionalMacroParameterListAndBody(
2456 const Token &MacroNameTok,
const bool ImmediatelyAfterHeaderGuard) {
2458 Token LastTok = MacroNameTok;
2466 auto _ = llvm::make_scope_exit([&]() {
2468 if (CurLexer->ParsingPreprocessorDirective)
2479 if (Tok.is(tok::eod)) {
2480 if (ImmediatelyAfterHeaderGuard) {
2486 }
else if (Tok.hasLeadingSpace()) {
2490 }
else if (Tok.is(tok::l_paren)) {
2493 if (ReadMacroParameterList(MI, LastTok))
2502 VariadicMacroScopeGuard.enterScope();
2507 }
else if (LangOpts.C99 || LangOpts.CPlusPlus11) {
2510 Diag(Tok, diag::ext_c99_whitespace_required_after_macro_name);
2519 if (Tok.is(tok::at))
2521 else if (Tok.is(tok::unknown)) {
2528 Diag(Tok, diag::ext_missing_whitespace_after_macro_name);
2530 Diag(Tok, diag::warn_missing_whitespace_after_macro_name);
2533 if (!Tok.is(tok::eod))
2539 while (Tok.isNot(tok::eod)) {
2552 while (Tok.isNot(tok::eod)) {
2555 if (!Tok.isOneOf(tok::hash, tok::hashat, tok::hashhash)) {
2561 Diag(Tok, diag::err_pp_vaopt_nested_use);
2566 if (Tok.isNot(tok::l_paren)) {
2567 Diag(Tok, diag::err_pp_missing_lparen_in_vaopt_use);
2573 if (Tok.is(tok::hashhash)) {
2574 Diag(Tok, diag::err_vaopt_paste_at_start);
2579 if (Tok.is(tok::r_paren)) {
2582 assert(NumTokens >= 3 &&
"Must have seen at least __VA_OPT__( " 2583 "and a subsequent tok::r_paren");
2585 Diag(Tok, diag::err_vaopt_paste_at_end);
2589 }
else if (Tok.is(tok::l_paren)) {
2602 Tok.setKind(tok::unknown);
2610 if (Tok.is(tok::hashhash)) {
2618 if (Tok.is(tok::eod)) {
2624 if (NumTokens && Tok.getIdentifierInfo() == Ident__VA_ARGS__ &&
2639 (Tok.getIdentifierInfo() ==
nullptr ||
2646 if (
getLangOpts().AsmPreprocessor && Tok.isNot(tok::eod)) {
2647 LastTok.
setKind(tok::unknown);
2651 Diag(Tok, diag::err_pp_stringize_not_parameter)
2652 << LastTok.
is(tok::hashat);
2672 assert(Tok.is(tok::eod) &&
"Must be at End Of preprocessing Directive");
2673 Diag(Tok, diag::err_pp_expected_after)
2674 << LastTok.
getKind() << tok::r_paren;
2684 void Preprocessor::HandleDefineDirective(
2685 Token &DefineTok,
const bool ImmediatelyAfterHeaderGuard) {
2689 bool MacroShadowsKeyword;
2690 ReadMacroName(MacroNameTok,
MU_Define, &MacroShadowsKeyword);
2693 if (MacroNameTok.
is(tok::eod))
2698 if (CurLexer) CurLexer->SetCommentRetentionState(KeepMacroComments);
2700 MacroInfo *
const MI = ReadOptionalMacroParameterListAndBody(
2701 MacroNameTok, ImmediatelyAfterHeaderGuard);
2705 if (MacroShadowsKeyword &&
2707 Diag(MacroNameTok, diag::warn_pp_macro_hides_keyword);
2712 if (NumTokens != 0) {
2724 if (SkippingUntilPCHThroughHeader) {
2727 LangOpts.MicrosoftExt))
2731 if (!LangOpts.MicrosoftExt)
2741 auto isObjCProtectedMacro = [](
const IdentifierInfo *II) ->
bool {
2742 return II->
isStr(
"__strong") ||
2743 II->isStr(
"__weak") ||
2744 II->isStr(
"__unsafe_unretained") ||
2745 II->isStr(
"__autoreleasing");
2748 SourceMgr.getFileID(OtherMI->getDefinitionLoc())
2753 !SourceMgr.isInSystemHeader(DefineTok.
getLocation())) &&
2755 LangOpts.MicrosoftExt)) {
2758 assert(!OtherMI->isWarnIfUnused());
2766 !SourceMgr.isInSystemHeader(DefineTok.
getLocation())) {
2767 if (!OtherMI->isUsed() && OtherMI->isWarnIfUnused())
2768 Diag(OtherMI->getDefinitionLoc(), diag::pp_macro_not_used);
2772 if (OtherMI->isBuiltinMacro())
2773 Diag(MacroNameTok, diag::ext_pp_redef_builtin_macro);
2776 else if (!OtherMI->isAllowRedefinitionsWithoutWarning() &&
2777 !MI->
isIdenticalTo(*OtherMI, *
this, LangOpts.MicrosoftExt)) {
2780 Diag(OtherMI->getDefinitionLoc(), diag::note_previous_definition);
2783 if (OtherMI->isWarnIfUnused())
2784 WarnUnusedMacroLocs.erase(OtherMI->getDefinitionLoc());
2795 !MacroExpansionInDirectivesOverride) {
2802 Callbacks->MacroDefined(MacroNameTok, MD);
2807 void Preprocessor::HandleUndefDirective() {
2811 ReadMacroName(MacroNameTok,
MU_Undef);
2814 if (MacroNameTok.
is(tok::eod))
2826 if (
const MacroInfo *MI = MD.getMacroInfo()) {
2833 Undef = AllocateUndefMacroDirective(MacroNameTok.
getLocation());
2839 Callbacks->MacroUndefined(MacroNameTok, MD, Undef);
2854 void Preprocessor::HandleIfdefDirective(
Token &
Result,
2855 const Token &HashToken,
2857 bool ReadAnyTokensBeforeDirective) {
2862 ReadMacroName(MacroNameTok);
2865 if (MacroNameTok.
is(tok::eod)) {
2868 SkipExcludedConditionalBlock(HashToken.
getLocation(),
2881 if (CurPPLexer->getConditionalStackDepth() == 0) {
2886 if (!ReadAnyTokensBeforeDirective && !MI) {
2887 assert(isIfndef &&
"#ifdef shouldn't reach here");
2888 CurPPLexer->MIOpt.EnterTopLevelIfndef(MII, MacroNameTok.
getLocation());
2890 CurPPLexer->MIOpt.EnterTopLevelConditional();
2899 Callbacks->Ifndef(DirectiveTok.
getLocation(), MacroNameTok, MD);
2901 Callbacks->Ifdef(DirectiveTok.
getLocation(), MacroNameTok, MD);
2904 bool RetainExcludedCB = PPOpts->RetainExcludedConditionalBlocks &&
2908 if (PPOpts->SingleFileParseMode && !MI) {
2911 CurPPLexer->pushConditionalLevel(DirectiveTok.
getLocation(),
2914 }
else if (!MI == isIfndef || RetainExcludedCB) {
2916 CurPPLexer->pushConditionalLevel(DirectiveTok.
getLocation(),
2921 SkipExcludedConditionalBlock(HashToken.
getLocation(),
2930 void Preprocessor::HandleIfDirective(
Token &IfToken,
2931 const Token &HashToken,
2932 bool ReadAnyTokensBeforeDirective) {
2937 const DirectiveEvalResult DER = EvaluateDirectiveExpression(IfNDefMacro);
2938 const bool ConditionalTrue = DER.Conditional;
2942 if (CurPPLexer->getConditionalStackDepth() == 0) {
2943 if (!ReadAnyTokensBeforeDirective && IfNDefMacro && ConditionalTrue)
2945 CurPPLexer->MIOpt.EnterTopLevelIfndef(IfNDefMacro, IfToken.
getLocation());
2947 CurPPLexer->MIOpt.EnterTopLevelConditional();
2955 bool RetainExcludedCB = PPOpts->RetainExcludedConditionalBlocks &&
2959 if (PPOpts->SingleFileParseMode && DER.IncludedUndefinedIds) {
2962 CurPPLexer->pushConditionalLevel(IfToken.
getLocation(),
false,
2964 }
else if (ConditionalTrue || RetainExcludedCB) {
2966 CurPPLexer->pushConditionalLevel(IfToken.
getLocation(),
false,
2978 void Preprocessor::HandleEndifDirective(
Token &EndifToken) {
2985 if (CurPPLexer->popConditionalLevel(CondInfo)) {
2987 Diag(EndifToken, diag::err_pp_endif_without_if);
2992 if (CurPPLexer->getConditionalStackDepth() == 0)
2993 CurPPLexer->MIOpt.ExitTopLevelConditional();
2995 assert(!CondInfo.
WasSkipping && !CurPPLexer->LexingRawMode &&
2996 "This code should only be reachable in the non-skipping case!");
3004 void Preprocessor::HandleElseDirective(
Token &Result,
const Token &HashToken) {
3011 if (CurPPLexer->popConditionalLevel(CI)) {
3012 Diag(Result, diag::pp_err_else_without_if);
3017 if (CurPPLexer->getConditionalStackDepth() == 0)
3018 CurPPLexer->MIOpt.EnterTopLevelConditional();
3021 if (CI.
FoundElse)
Diag(Result, diag::pp_err_else_after_else);
3026 bool RetainExcludedCB = PPOpts->RetainExcludedConditionalBlocks &&
3029 if ((PPOpts->SingleFileParseMode && !CI.
FoundNonSkip) || RetainExcludedCB) {
3032 CurPPLexer->pushConditionalLevel(CI.
IfLoc,
false,
3045 void Preprocessor::HandleElifDirective(
Token &ElifToken,
3046 const Token &HashToken) {
3055 if (CurPPLexer->popConditionalLevel(CI)) {
3056 Diag(ElifToken, diag::pp_err_elif_without_if);
3061 if (CurPPLexer->getConditionalStackDepth() == 0)
3062 CurPPLexer->MIOpt.EnterTopLevelConditional();
3065 if (CI.
FoundElse)
Diag(ElifToken, diag::pp_err_elif_after_else);
3068 Callbacks->Elif(ElifToken.
getLocation(), ConditionRange,
3071 bool RetainExcludedCB = PPOpts->RetainExcludedConditionalBlocks &&
3074 if ((PPOpts->SingleFileParseMode && !CI.
FoundNonSkip) || RetainExcludedCB) {
3077 CurPPLexer->pushConditionalLevel(ElifToken.
getLocation(),
false,
3083 SkipExcludedConditionalBlock(
std::string Name
The name of this module.
Module * getModuleForLocation(SourceLocation Loc)
Find the module that owns the source or header file that Loc points to.
MacroInfo * AllocateMacroInfo(SourceLocation L)
Allocate a new MacroInfo object with the provided SourceLocation.
void AddTokenToBody(const Token &Tok)
Add the specified token to the replacement text for the macro.
void markMacroAsUsed(MacroInfo *MI)
A macro is used, update information about macros that need unused warnings.
void sawOpeningParen(SourceLocation LParenLoc)
Call this function each time an lparen is seen.
IdentifierInfo * getIdentifierInfo(StringRef Name) const
Return information about the specified preprocessor identifier token.
Defines the clang::FileManager interface and associated types.
static bool ReadLineMarkerFlags(bool &IsFileEntry, bool &IsFileExit, SrcMgr::CharacteristicKind &FileKind, Preprocessor &PP)
ReadLineMarkerFlags - Parse and validate any flags at the end of a GNU line marker directive...
This header is part of the module (for layering purposes) but should be textually included...
PPConditionalInfo & peekConditionalLevel()
Return the top of the conditional stack.
StringRef getBufferName(SourceLocation Loc, bool *Invalid=nullptr) const
Return the filename or buffer identifier of the buffer the location is in.
static bool isReservedId(StringRef Text, const LangOptions &Lang)
Checks if the specified identifier is reserved in the specified language.
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {...
Module * getTopLevelModule()
Retrieve the top-level module for this (sub)module, which may be this module.
bool sawClosingParen()
Call this function each time an rparen is seen.
Defines the SourceManager interface.
Module * getCurrentModule()
Retrieves the module that we're currently building, if any.
void pushConditionalLevel(SourceLocation DirectiveStart, bool WasSkipping, bool FoundNonSkip, bool FoundElse)
pushConditionalLevel - When we enter a #if directive, this keeps track of what we are currently in fo...
unsigned IsFramework
Whether this is a framework module.
bool isInPrimaryFile() const
Return true if we're in the top-level file, not in a #include.
Defines the clang::MacroInfo and clang::MacroDirective classes.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
A directive for an undefined macro.
bool getSuppressSystemWarnings() const
void setCodeCompletionReached()
Note that we hit the code-completion point.
bool hadModuleLoaderFatalFailure() const
CharacteristicKind
Indicates whether a file or directory holds normal user code, system code, or system code which is im...
void setBegin(SourceLocation b)
void setIsWarnIfUnused(bool val)
Set the value of the IsWarnIfUnused flag.
tok::TokenKind getKind() const
static MacroDiag shouldWarnOnMacroDef(Preprocessor &PP, IdentifierInfo *II)
ModuleKind Kind
The kind of this module.
DefMacroDirective * appendDefMacroDirective(IdentifierInfo *II, MacroInfo *MI, SourceLocation Loc)
One of these records is kept for each identifier that is lexed.
A directive for a defined macro or a macro imported from a module.
bool ParsingPreprocessorDirective
True when parsing #XXX; turns '\n' into a tok::eod token.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
bool CheckMacroName(Token &MacroNameTok, MacroUse isDefineUndef, bool *ShadowFlag=nullptr)
void EnterSubmodule(Module *M, SourceLocation ImportLoc, bool ForPragma)
static void diagnoseAutoModuleImport(Preprocessor &PP, SourceLocation HashLoc, Token &IncludeTok, ArrayRef< std::pair< IdentifierInfo *, SourceLocation >> Path, SourceLocation PathEnd)
Produce a diagnostic informing the user that a #include or similar was implicitly treated as a module...
bool isCPlusPlusOperatorKeyword() const
const TargetInfo & getTargetInfo() const
Token - This structure provides full information about a lexed token.
static bool trySimplifyPath(SmallVectorImpl< StringRef > &Components, StringRef RealPathName)
void setKind(tok::TokenKind K)
__DEVICE__ int max(int __a, int __b)
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
const LangOptions & getLangOpts() const
Describes a module or submodule.
SourceRange DiscardUntilEndOfDirective()
Read and discard all tokens remaining on the current line until the tok::eod token is found...
bool popConditionalLevel(PPConditionalInfo &CI)
popConditionalLevel - Remove an entry off the top of the conditional stack, returning information abo...
A directive for setting the module visibility of a macro.
StringRef getTopLevelModuleName() const
Retrieve the name of the top-level module.
llvm::ErrorOr< const DirectoryEntry * > getDirectory(StringRef DirName, bool CacheFailure=true)
Lookup, cache, and verify the specified directory (real or virtual).
std::pair< FileID, unsigned > getDecomposedExpansionLoc(SourceLocation Loc) const
Decompose the specified location into a raw FileID + Offset pair.
SourceLocation AdvanceToTokenCharacter(SourceLocation TokStart, unsigned Char) const
Given a location that specifies the start of a token, return a new location that specifies a characte...
MacroUse
Context in which macro name is used.
std::string getFullModuleName(bool AllowStringLiterals=false) const
Retrieve the full name of this module, including the path from its top-level module.
StringRef getSpelling(SourceLocation loc, SmallVectorImpl< char > &buffer, bool *invalid=nullptr) const
Return the 'spelling' of the token at the given location; does not go up to the spelling location or ...
HeaderSearch & getHeaderSearchInfo() const
const Token & getReplacementToken(unsigned Tok) const
bool hasUDSuffix() const
Return true if this token is a string or character literal which has a ud-suffix. ...
SourceLocation getExpansionLoc(SourceLocation Loc) const
Given a SourceLocation object Loc, return the expansion location referenced by the ID...
void HandleDirective(Token &Result)
Callback invoked when the lexer sees a # token at the start of a line.
Concrete class used by the front-end to report problems and issues.
bool GetIncludeFilenameSpelling(SourceLocation Loc, StringRef &Buffer)
Turn the specified lexer token into a fully checked and spelled filename, e.g.
Module * Parent
The parent of this module.
bool isUsed() const
Return false if this macro is defined in the main file and has not yet been used. ...
bool FoundNonSkip
True if we have emitted tokens already, and now we're in an #else block or something.
LLVM_READONLY bool isUppercase(unsigned char c)
Return true if this character is an uppercase ASCII letter: [A-Z].
void appendMacroDirective(IdentifierInfo *II, MacroDirective *MD)
Add a directive to the macro directive history for this identifier.
void LexUnexpandedToken(Token &Result)
Just like Lex, but disables macro expansion of identifier tokens.
MacroDiag
Enumerates possible cases of #define/#undef a reserved identifier.
unsigned IsSystem
Whether this is a "system" module (which assumes that all headers in it are system headers)...
void HandleSkippedDirectiveWhileUsingPCH(Token &Result, SourceLocation HashLoc)
Process directives while skipping until the through header or #pragma hdrstop is found.
std::string CurrentModule
The name of the current module, of which the main source file is a part.
Describes the result of attempting to load a module.
Exposes information about the current target.
void setAnnotationValue(void *val)
void diagnoseHeaderInclusion(Module *RequestingModule, bool RequestingModuleIsModuleInterface, SourceLocation FilenameLoc, StringRef Filename, const FileEntry *File)
Reports errors if a module must not include a specific file.
Defines the clang::LangOptions interface.
bool LexingRawMode
True if in raw mode.
Represents a character-granular source range.
void setHasCommaPasting()
bool isInvalid() const
Return true if this object is invalid or uninitialized.
void makeModuleVisible(Module *M, SourceLocation Loc)
bool isInSystemHeader(SourceLocation Loc) const
Returns if a SourceLocation is in a system header.
const FileEntry * getFileEntryForID(FileID FID) const
Returns the FileEntry record for the provided FileID.
bool usingPCHWithThroughHeader()
True if using a PCH with a through header.
bool isPCHThroughHeader(const FileEntry *FE)
Returns true if the FileEntry is the PCH through header.
A class for tracking whether we're inside a VA_OPT during a traversal of the tokens of a variadic mac...
static bool warnByDefaultOnWrongCase(StringRef Include)
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file. ...
Defines the clang::Preprocessor interface.
ResetMacroExpansionHelper(Preprocessor *pp)
LLVM_READONLY bool isAlphanumeric(unsigned char c)
Return true if this character is an ASCII letter or digit: [a-zA-Z0-9].
static bool checkModuleIsAvailable(const LangOptions &LangOpts, const TargetInfo &TargetInfo, DiagnosticsEngine &Diags, Module *M)
Check that the given module is available, producing a diagnostic if not.
const MacroInfo * getMacroInfo(const IdentifierInfo *II) const
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
SourceLocation getUnmatchedOpeningParenLoc() const
KnownHeader findModuleForHeader(const FileEntry *File, bool AllowTextual=false)
Retrieve the module that owns the given header file, if any.
Information about the conditional stack (#if directives) currently active.
Represents an unpacked "presumed" location which can be presented to the user.
SourceLocation getEnd() const
bool isAvailable() const
Determine whether this module is available for use within the current translation unit...
bool isObjectLike() const
The result type of a method or function.
StringRef GetString() const
DirectoryLookup - This class represents one entry in the search list that specifies the search order ...
bool isKeyword(const LangOptions &LangOpts) const
Return true if this token is a keyword in the specified language.
bool isRecordingPreamble() const
const DirectoryEntry * Directory
The directory entry which should be used for the cached framework.
static CharSourceRange getCharRange(SourceRange R)
SourceManager & getSourceManager() const
virtual SourceLocation getSourceLocation()=0
Return the source location for the next observable location.
MacroDirective * getLocalMacroDirective(const IdentifierInfo *II) const
Given an identifier, return its latest non-imported MacroDirective if it is #define'd and not #undef'...
const DirectoryEntry * getDir() const
Return the directory the file lives in.
bool isVAOptToken(const Token &T) const
void setIsFunctionLike()
Function/Object-likeness.
Encapsulates changes to the "macros namespace" (the location where the macro name became active...
bool WasSkipping
True if this was contained in a skipping directive, e.g., in a "\#if 0" block.
Encodes a location in the source.
bool isConfigMismatch() const
Determines whether the module failed to load due to a configuration mismatch with an explicitly-named...
friend class VariadicMacroScopeGuard
MacroDefinition getMacroDefinition(const IdentifierInfo *II)
All of the names in this module are hidden.
IdentifierInfo * getIdentifierInfo() const
void setAnnotationEndLoc(SourceLocation L)
Cached information about one file (either on disk or in the virtual file system). ...
virtual void CodeCompleteInConditionalExclusion()
Callback invoked when performing code completion within a block of code that was excluded due to prep...
void setIsC99Varargs()
Varargs querying methods. This can only be set for function-like macros.
bool isInVAOpt() const
Returns true if we have seen the VA_OPT and '(' but before having seen the matching ')'...
void Lex(Token &Result)
Lex the next token for this preprocessor.
const char * getNameStart() const
Return the beginning of the actual null-terminated string for this identifier.
void setDefinitionEndLoc(SourceLocation EndLoc)
Set the location of the last token in the macro.
bool isAtStartOfLine() const
isAtStartOfLine - Return true if this token is at the start of a line.
This is a fragment of the global module within some C++ module.
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
bool isInMainFile(SourceLocation Loc) const
Returns whether the PresumedLoc for a given SourceLocation is in the main file.
std::string ModuleName
The module currently being compiled as specified by -fmodule-name.
Defines the clang::Module class, which describes a module in the source code.
std::pair< std::string, bool > Requirement
An individual requirement: a feature name and a flag indicating the required state of that feature...
bool isC99Varargs() const
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
void HandlePragmaHdrstop(Token &Tok)
StringRef getName() const
Return the actual identifier string.
SourceLocation IfLoc
Location where the conditional started.
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
bool isNot(tok::TokenKind K) const
const llvm::MemoryBuffer * getBuffer(FileID FID, SourceLocation Loc, bool *Invalid=nullptr) const
Return the buffer for the specified FileID.
static bool isInvalid(LocType Loc, bool *Invalid)
bool EnterSourceFile(FileID FID, const DirectoryLookup *Dir, SourceLocation Loc)
Add a source file to the top of the include stack and start lexing tokens from it instead of the curr...
Dataflow Directional Tag Classes.
bool isWarnIfUnused() const
Return true if we should emit a warning if the macro is unused.
bool isValid() const
Return true if this is a valid SourceLocation object.
The pragma was introduced via #pragma.
unsigned getNumTokens() const
Return the number of tokens that this macro expands to.
const FileEntry * getFileEntry() const
getFileEntry - Return the FileEntry corresponding to this FileID.
static bool isConfigurationPattern(Token &MacroName, MacroInfo *MI, const LangOptions &LOptions)
Optional< FileEntryRef > LookupFile(SourceLocation FilenameLoc, StringRef Filename, bool isAngled, const DirectoryLookup *FromDir, const FileEntry *FromFile, const DirectoryLookup *&CurDir, SmallVectorImpl< char > *SearchPath, SmallVectorImpl< char > *RelativePath, ModuleMap::KnownHeader *SuggestedModule, bool *IsMapped, bool *IsFrameworkFound, bool SkipCache=false)
Given a "foo" or <foo> reference, look up the indicated file.
llvm::DenseMap< unsigned, unsigned > PreprocessorSkippedRangeMapping
A mapping from an offset into a buffer to the number of bytes that can be skipped by the preprocessor...
ArrayRef< KnownHeader > findAllModulesForHeader(const FileEntry *File) const
Retrieve all the modules that contain the given header file.
SourceLocation getIncludeLoc(FileID FID) const
Returns the include location if FID is a #include'd file otherwise it returns an invalid location...
FileID getMainFileID() const
Returns the FileID of the main source file.
bool isMissingExpected() const
Determines whether the module, which failed to load, was actually a submodule that we expected to see...
static bool isForModuleBuilding(Module *M, StringRef CurrentModule, StringRef ModuleName)
bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const
tok::PPKeywordKind getPPKeywordID() const
Return the preprocessor keyword ID for this identifier.
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.
static MacroDiag shouldWarnOnMacroUndef(Preprocessor &PP, IdentifierInfo *II)
unsigned getLength() const
Encapsulates the data about a macro definition (e.g.
SourceLocation DefinitionLoc
The location of the module definition.
LLVM_READONLY bool isDigit(unsigned char c)
Return true if this character is an ASCII digit: [0-9].
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
int getParameterNum(const IdentifierInfo *Arg) const
Return the parameter number of the specified identifier, or -1 if the identifier is not a formal para...
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
SourceLocation getDefinitionLoc() const
Return the location that the macro was defined at.
Defines the PPCallbacks interface.
Defines the clang::TokenKind enum and support functions.
static bool GetLineValue(Token &DigitTok, unsigned &Val, unsigned DiagID, Preprocessor &PP, bool IsGNULineDirective=false)
GetLineValue - Convert a numeric token into an unsigned value, emitting Diagnostic DiagID if it is in...
virtual void CodeCompleteMacroName(bool IsDefinition)
Callback invoked when performing code completion in a context where the name of a macro is expected...
SourceLocation CheckEndOfDirective(const char *DirType, bool EnableMacros=false)
Ensure that the next token is a tok::eod token.
Defines the clang::SourceLocation class and associated facilities.
void setEnd(SourceLocation e)
FileID getPredefinesFileID() const
Returns the FileID for the preprocessor predefines.
DiagnosticsEngine & getDiagnostics() const
bool isIdenticalTo(const MacroInfo &Other, Preprocessor &PP, bool Syntactically) const
Return true if the specified macro definition is equal to this macro in spelling, arguments...
StringRef getRawIdentifier() const
getRawIdentifier - For a raw identifier token (i.e., an identifier lexed in raw mode), returns a reference to the text substring in the buffer if known.
bool isBuiltinMacro() const
Return true if this macro requires processing before expansion.
StringLiteralParser - This decodes string escape characters and performs wide string analysis and Tra...
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string...
void sawVAOptFollowedByOpeningParens(const SourceLocation LParenLoc)
Call this function as soon as you see VA_OPT and '('.
const FileEntry * getModuleHeaderToIncludeForDiagnostics(SourceLocation IncLoc, Module *M, SourceLocation MLoc)
We want to produce a diagnostic at location IncLoc concerning a missing module import.
bool needsCleaning() const
Return true if this token has trigraphs or escaped newlines in it.
Annotates a diagnostic with some code that should be inserted, removed, or replaced to fix the proble...
void setLocation(SourceLocation L)
This structure is used to record entries in our framework cache.
A trivial tuple used to represent a source range.
bool LexHeaderName(Token &Result, bool AllowMacroExpansion=true)
Lex a token, forming a header-name token if possible.
void setParameterList(ArrayRef< IdentifierInfo *> List, llvm::BumpPtrAllocator &PPAllocator)
Set the specified list of identifiers as the parameter list for this macro.
PreprocessorLexer * getCurrentFileLexer() const
Return the current file lexer being lexed from.
void EnterAnnotationToken(SourceRange Range, tok::TokenKind Kind, void *AnnotationVal)
Enter an annotation token into the token stream.
SourceLocation getIncludeLoc() const
Return the presumed include location of this location.
bool FoundElse
True if we've seen a #else in this block.
SourceLocation getBegin() const
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const
Forwarding function for diagnostics.
VerifyDiagnosticConsumer::Directive Directive
This class handles loading and caching of source files into memory.
bool Sub(InterpState &S, CodePtr OpPC)
void startToken()
Reset all flags to cleared.
~ResetMacroExpansionHelper()
An RAII class that tracks when the Preprocessor starts and stops lexing the definition of a (ISO C/C+...
std::pair< FileID, unsigned > getDecomposedLoc(SourceLocation Loc) const
Decompose the specified location into a raw FileID + Offset pair.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
StringRef getName() const
SourceLocation getEndLoc() const