37 #include "llvm/ADT/ArrayRef.h" 38 #include "llvm/ADT/SmallString.h" 39 #include "llvm/ADT/SmallVector.h" 40 #include "llvm/ADT/STLExtras.h" 41 #include "llvm/ADT/StringSwitch.h" 42 #include "llvm/ADT/StringRef.h" 43 #include "llvm/Support/AlignOf.h" 44 #include "llvm/Support/ErrorHandling.h" 45 #include "llvm/Support/Path.h" 53 using namespace clang;
60 auto *MIChain =
new (BP) MacroInfoChain{L, MIChainHead};
61 MIChainHead = MIChain;
71 Preprocessor::AllocateUndefMacroDirective(
SourceLocation UndefLoc) {
87 assert(Tmp.
isNot(
tok::eof) &&
"EOF seen while discarding directive tokens");
88 }
while (Tmp.
isNot(tok::eod));
105 if (Text.size() >= 2 && Text[0] ==
'_' &&
111 if (Lang.CPlusPlus) {
112 if (Text.find(
"__") != StringRef::npos)
125 StringRef ModuleName) {
131 !CurrentModule.endswith(
"_Private") && TopLevelName.endswith(
"_Private"))
132 TopLevelName = TopLevelName.drop_back(8);
134 return TopLevelName == CurrentModule;
144 if (Lang.CPlusPlus11 && (Text.equals(
"override") || Text.equals(
"final")))
166 if (::llvm::sys::path::begin(Include)->equals_lower(
"boost"))
171 static const size_t MaxStdHeaderNameLen = 18u;
172 if (Include.size() > MaxStdHeaderNameLen)
177 for (
char &Ch : LowerInclude) {
179 if (static_cast<unsigned char>(Ch) > 0x7f)
182 if (Ch >=
'A' && Ch <=
'Z')
185 else if (::llvm::sys::path::is_separator(Ch))
190 return llvm::StringSwitch<bool>(LowerInclude)
192 .Cases(
"assert.h",
"complex.h",
"ctype.h",
"errno.h",
"fenv.h",
true)
193 .Cases(
"float.h",
"inttypes.h",
"iso646.h",
"limits.h",
"locale.h",
true)
194 .Cases(
"math.h",
"setjmp.h",
"signal.h",
"stdalign.h",
"stdarg.h",
true)
195 .Cases(
"stdatomic.h",
"stdbool.h",
"stddef.h",
"stdint.h",
"stdio.h",
true)
196 .Cases(
"stdlib.h",
"stdnoreturn.h",
"string.h",
"tgmath.h",
"threads.h",
true)
197 .Cases(
"time.h",
"uchar.h",
"wchar.h",
"wctype.h",
true)
200 .Cases(
"cassert",
"ccomplex",
"cctype",
"cerrno",
"cfenv",
true)
201 .Cases(
"cfloat",
"cinttypes",
"ciso646",
"climits",
"clocale",
true)
202 .Cases(
"cmath",
"csetjmp",
"csignal",
"cstdalign",
"cstdarg",
true)
203 .Cases(
"cstdbool",
"cstddef",
"cstdint",
"cstdio",
"cstdlib",
true)
204 .Cases(
"cstring",
"ctgmath",
"ctime",
"cuchar",
"cwchar",
true)
205 .Case(
"cwctype",
true)
208 .Cases(
"algorithm",
"fstream",
"list",
"regex",
"thread",
true)
209 .Cases(
"array",
"functional",
"locale",
"scoped_allocator",
"tuple",
true)
210 .Cases(
"atomic",
"future",
"map",
"set",
"type_traits",
true)
211 .Cases(
"bitset",
"initializer_list",
"memory",
"shared_mutex",
"typeindex",
true)
212 .Cases(
"chrono",
"iomanip",
"mutex",
"sstream",
"typeinfo",
true)
213 .Cases(
"codecvt",
"ios",
"new",
"stack",
"unordered_map",
true)
214 .Cases(
"complex",
"iosfwd",
"numeric",
"stdexcept",
"unordered_set",
true)
215 .Cases(
"condition_variable",
"iostream",
"ostream",
"streambuf",
"utility",
true)
216 .Cases(
"deque",
"istream",
"queue",
"string",
"valarray",
true)
217 .Cases(
"exception",
"iterator",
"random",
"strstream",
"vector",
true)
218 .Cases(
"forward_list",
"limits",
"ratio",
"system_error",
true)
221 .Cases(
"aio.h",
"arpa/inet.h",
"cpio.h",
"dirent.h",
"dlfcn.h",
true)
222 .Cases(
"fcntl.h",
"fmtmsg.h",
"fnmatch.h",
"ftw.h",
"glob.h",
true)
223 .Cases(
"grp.h",
"iconv.h",
"langinfo.h",
"libgen.h",
"monetary.h",
true)
224 .Cases(
"mqueue.h",
"ndbm.h",
"net/if.h",
"netdb.h",
"netinet/in.h",
true)
225 .Cases(
"netinet/tcp.h",
"nl_types.h",
"poll.h",
"pthread.h",
"pwd.h",
true)
226 .Cases(
"regex.h",
"sched.h",
"search.h",
"semaphore.h",
"spawn.h",
true)
227 .Cases(
"strings.h",
"stropts.h",
"sys/ipc.h",
"sys/mman.h",
"sys/msg.h",
true)
228 .Cases(
"sys/resource.h",
"sys/select.h",
"sys/sem.h",
"sys/shm.h",
"sys/socket.h",
true)
229 .Cases(
"sys/stat.h",
"sys/statvfs.h",
"sys/time.h",
"sys/times.h",
"sys/types.h",
true)
230 .Cases(
"sys/uio.h",
"sys/un.h",
"sys/utsname.h",
"sys/wait.h",
"syslog.h",
true)
231 .Cases(
"tar.h",
"termios.h",
"trace.h",
"ulimit.h",
true)
232 .Cases(
"unistd.h",
"utime.h",
"utmpx.h",
"wordexp.h",
true)
239 if (MacroNameTok.
is(tok::eod))
240 return Diag(MacroNameTok, diag::err_pp_missing_macro_name);
244 return Diag(MacroNameTok, diag::err_pp_macro_not_identifier);
250 ? diag::ext_pp_operator_used_as_macro_name
251 : diag::err_pp_operator_used_as_macro_name)
252 << II << MacroNameTok.
getKind();
259 return Diag(MacroNameTok, diag::err_defined_macro_name);
267 Diag(MacroNameTok, diag::ext_pp_undef_builtin_macro);
292 Diag(MacroNameTok, diag::warn_pp_macro_is_reserved_id);
308 void Preprocessor::ReadMacroName(
Token &MacroNameTok,
MacroUse isDefineUndef,
313 if (MacroNameTok.
is(tok::code_completion)) {
325 if (MacroNameTok.
isNot(tok::eod)) {
326 MacroNameTok.
setKind(tok::eod);
347 while (Tmp.
is(tok::comment))
350 if (Tmp.
isNot(tok::eod)) {
356 if ((LangOpts.GNUMode || LangOpts.C99 || LangOpts.CPlusPlus) &&
359 Diag(Tmp, diag::ext_pp_extra_tokens_at_eol) << DirType << Hint;
372 void Preprocessor::SkipExcludedConditionalBlock(
SourceLocation HashTokenLoc,
374 bool FoundNonSkipPortion,
378 assert(!CurTokenLexer && CurPPLexer &&
"Lexing a macro, not a file?");
380 if (PreambleConditionalStack.reachedEOFWhileSkipping())
381 PreambleConditionalStack.clearSkipInfo();
384 FoundNonSkipPortion, FoundElse);
387 PTHSkipExcludedConditionalBlock();
398 if (Tok.
is(tok::code_completion)) {
410 if (PreambleConditionalStack.isRecording())
411 PreambleConditionalStack.SkipInfo.emplace(
412 HashTokenLoc, IfTokenLoc, FoundNonSkipPortion, FoundElse, ElseLoc);
424 if (CurLexer) CurLexer->SetKeepWhitespaceMode(
false);
432 if (Tok.
isNot(tok::raw_identifier)) {
435 if (CurLexer) CurLexer->resetExtendedTokenMode();
446 char FirstChar = RI[0];
447 if (FirstChar >=
'a' && FirstChar <=
'z' &&
448 FirstChar !=
'i' && FirstChar !=
'e') {
451 if (CurLexer) CurLexer->resetExtendedTokenMode();
458 char DirectiveBuf[20];
464 size_t IdLen = DirectiveStr.size();
468 if (CurLexer) CurLexer->resetExtendedTokenMode();
471 memcpy(DirectiveBuf, &DirectiveStr[0], IdLen);
472 Directive = StringRef(DirectiveBuf, IdLen);
475 if (Directive.startswith(
"if")) {
476 StringRef Sub = Directive.substr(2);
487 }
else if (Directive[0] ==
'e') {
488 StringRef Sub = Directive.substr(1);
494 assert(!InCond &&
"Can't be skipping if not in a conditional!");
509 }
else if (Sub ==
"lse") {
516 if (CondInfo.
FoundElse)
Diag(Tok, diag::pp_err_else_after_else);
536 }
else if (Sub ==
"lif") {
540 if (CondInfo.
FoundElse)
Diag(Tok, diag::pp_err_elif_after_else);
550 assert(CurPPLexer->
LexingRawMode &&
"We have to be skipping here!");
553 const bool CondValue = EvaluateDirectiveExpression(IfNDefMacro).Conditional;
572 if (CurLexer) CurLexer->resetExtendedTokenMode();
583 Callbacks->SourceRangeSkipped(
588 void Preprocessor::PTHSkipExcludedConditionalBlock() {
591 assert(CurPTHLexer->LexingRawMode ==
false);
594 if (CurPTHLexer->SkipBlock()) {
598 bool InCond = CurPTHLexer->popConditionalLevel(CondInfo);
600 assert(!InCond &&
"Can't be skipping if not in a conditional!");
613 if (K == tok::pp_else) {
626 CurPTHLexer->ParsingPreprocessorDirective =
true;
628 CurPTHLexer->ParsingPreprocessorDirective =
false;
637 assert(K == tok::pp_elif);
642 Diag(Tok, diag::pp_err_elif_after_else);
651 CurPTHLexer->ParsingPreprocessorDirective =
true;
652 bool ShouldEnter = EvaluateDirectiveExpression(IfNDefMacro).Conditional;
653 CurPTHLexer->ParsingPreprocessorDirective =
false;
689 assert(M &&
"no module to include");
710 bool InTextualHeader =
false;
712 if (!Header.getModule()->isSubModuleOf(TopM))
719 if (Header.isAccessibleFrom(IncM))
729 InTextualHeader =
true;
732 if (!InTextualHeader)
748 bool RequestingModuleIsModuleInterface = !SourceMgr.
isInMainFile(FilenameLoc);
754 bool BuildSystemModule =
false;
755 if (!FromDir && !FromFile) {
773 Includers.push_back(std::make_pair(
nullptr, MainFileDir));
775 }
else if ((FileEnt =
777 Includers.push_back(std::make_pair(FileEnt, FileMgr.
getDirectory(
".")));
779 Includers.push_back(std::make_pair(FileEnt, FileEnt->
getDir()));
785 if (LangOpts.MSVCCompat && !isAngled) {
786 for (IncludeStackInfo &ISEntry : llvm::reverse(IncludeMacroStack)) {
787 if (IsFileLexer(ISEntry))
788 if ((FileEnt = ISEntry.ThePPLexer->getFileEntry()))
789 Includers.push_back(std::make_pair(FileEnt, FileEnt->
getDir()));
794 CurDir = CurDirLookup;
802 Filename, FilenameLoc, isAngled, TmpFromDir, TmpCurDir,
803 Includers, SearchPath, RelativePath, RequestingModule,
804 SuggestedModule,
nullptr, SkipCache)) {
806 TmpFromDir = TmpCurDir;
808 if (FE == FromFile) {
810 FromDir = TmpFromDir;
819 Filename, FilenameLoc, isAngled, FromDir, CurDir, Includers, SearchPath,
820 RelativePath, RequestingModule, SuggestedModule, IsMapped, SkipCache,
823 if (SuggestedModule && !LangOpts.AsmPreprocessor)
825 RequestingModule, RequestingModuleIsModuleInterface, FilenameLoc,
837 SearchPath, RelativePath,
840 if (SuggestedModule && !LangOpts.AsmPreprocessor)
842 RequestingModule, RequestingModuleIsModuleInterface, FilenameLoc,
849 for (IncludeStackInfo &ISEntry : llvm::reverse(IncludeMacroStack)) {
850 if (IsFileLexer(ISEntry)) {
851 if ((CurFileEnt = ISEntry.ThePPLexer->getFileEntry())) {
853 Filename, CurFileEnt, SearchPath, RelativePath,
854 RequestingModule, SuggestedModule))) {
855 if (SuggestedModule && !LangOpts.AsmPreprocessor)
857 RequestingModule, RequestingModuleIsModuleInterface,
858 FilenameLoc, Filename, FE);
876 : PP(pp), save(pp->DisableMacroExpansion) {
877 if (pp->MacroExpansionInDirectivesOverride)
878 pp->DisableMacroExpansion =
false;
882 PP->DisableMacroExpansion = save;
897 if (II->getPPKeywordID() == tok::pp_include)
898 return HandleIncludeDirective(HashLoc, Result);
899 if (II->getPPKeywordID() == tok::pp_define)
900 return HandleDefineDirective(Result,
916 CurPPLexer->ParsingPreprocessorDirective =
true;
917 if (CurLexer) CurLexer->SetKeepWhitespaceMode(
false);
919 bool ImmediatelyAfterTopLevelIfndef =
920 CurPPLexer->MIOpt.getImmediatelyAfterTopLevelIfndef();
921 CurPPLexer->MIOpt.resetImmediatelyAfterTopLevelIfndef();
928 bool ReadAnyTokensBeforeDirective =CurPPLexer->MIOpt.getHasReadAnyTokensVal();
947 switch (II->getPPKeywordID()) {
948 case tok::pp_include:
950 case tok::pp_include_next:
951 case tok::pp___include_macros:
953 Diag(Result, diag::err_embedded_directive) << II->getName();
960 Diag(Result, diag::ext_embedded_directive);
967 if (SkippingUntilPCHThroughHeader)
973 case tok::code_completion:
975 CodeComplete->CodeCompleteDirective(
976 CurPPLexer->getConditionalStackDepth() > 0);
979 case tok::numeric_constant:
982 return HandleDigitDirective(Result);
992 return HandleIfDirective(Result, SavedHash, ReadAnyTokensBeforeDirective);
994 return HandleIfdefDirective(Result, SavedHash,
false,
997 return HandleIfdefDirective(Result, SavedHash,
true,
998 ReadAnyTokensBeforeDirective);
1000 return HandleElifDirective(Result, SavedHash);
1002 return HandleElseDirective(Result, SavedHash);
1004 return HandleEndifDirective(Result);
1007 case tok::pp_include:
1010 case tok::pp___include_macros:
1015 case tok::pp_define:
1016 return HandleDefineDirective(Result, ImmediatelyAfterTopLevelIfndef);
1018 return HandleUndefDirective();
1022 return HandleLineDirective();
1026 return HandleUserDiagnosticDirective(Result,
false);
1029 case tok::pp_pragma:
1033 case tok::pp_import:
1035 case tok::pp_include_next:
1038 case tok::pp_warning:
1039 Diag(Result, diag::ext_pp_warning_directive);
1040 return HandleUserDiagnosticDirective(Result,
true);
1042 return HandleIdentSCCSDirective(Result);
1044 return HandleIdentSCCSDirective(Result);
1045 case tok::pp_assert:
1048 case tok::pp_unassert:
1052 case tok::pp___public_macro:
1054 return HandleMacroPublicDirective(Result);
1057 case tok::pp___private_macro:
1059 return HandleMacroPrivateDirective();
1070 auto Toks = llvm::make_unique<Token[]>(2);
1072 Toks[0] = SavedHash;
1077 if (Result.
is(tok::hashhash))
1078 Toks[1].setKind(tok::unknown);
1083 EnterTokenStream(std::move(Toks), 2,
false);
1088 Diag(Result, diag::err_pp_invalid_directive);
1100 bool IsGNULineDirective=
false) {
1101 if (DigitTok.
isNot(tok::numeric_constant)) {
1102 PP.
Diag(DigitTok, DiagID);
1104 if (DigitTok.
isNot(tok::eod))
1110 IntegerBuffer.resize(DigitTok.
getLength());
1111 const char *DigitTokBegin = &IntegerBuffer[0];
1112 bool Invalid =
false;
1113 unsigned ActualLength = PP.
getSpelling(DigitTok, DigitTokBegin, &Invalid);
1121 for (
unsigned i = 0; i != ActualLength; ++i) {
1124 if (DigitTokBegin[i] ==
'\'')
1127 if (!
isDigit(DigitTokBegin[i])) {
1129 diag::err_pp_line_digit_sequence) << IsGNULineDirective;
1134 unsigned NextVal = Val*10+(DigitTokBegin[i]-
'0');
1135 if (NextVal < Val) {
1136 PP.
Diag(DigitTok, DiagID);
1143 if (DigitTokBegin[0] ==
'0' && Val)
1145 << IsGNULineDirective;
1157 void Preprocessor::HandleLineDirective() {
1165 if (
GetLineValue(DigitTok, LineNo, diag::err_pp_line_requires_integer,*
this))
1169 Diag(DigitTok, diag::ext_pp_line_zero);
1173 unsigned LineLimit = 32768U;
1174 if (LangOpts.C99 || LangOpts.CPlusPlus11)
1175 LineLimit = 2147483648U;
1176 if (LineNo >= LineLimit)
1177 Diag(DigitTok, diag::ext_pp_line_too_big) << LineLimit;
1178 else if (LangOpts.CPlusPlus11 && LineNo >= 32768U)
1179 Diag(DigitTok, diag::warn_cxx98_compat_pp_line_too_big);
1181 int FilenameID = -1;
1187 if (StrTok.
is(tok::eod))
1189 else if (StrTok.
isNot(tok::string_literal)) {
1190 Diag(StrTok, diag::err_pp_line_invalid_filename);
1193 Diag(StrTok, diag::err_invalid_string_udl);
1198 assert(Literal.
isAscii() &&
"Didn't allow wide strings in");
1202 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1205 FilenameID = SourceMgr.getLineTableFilenameID(Literal.
GetString());
1218 SourceMgr.getFileCharacteristic(DigitTok.
getLocation());
1220 SourceMgr.AddLineNote(DigitTok.
getLocation(), LineNo, FilenameID,
false,
1224 Callbacks->FileChanged(CurPPLexer->getSourceLocation(),
1236 if (FlagTok.
is(tok::eod))
return false;
1237 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag, PP))
1244 if (FlagTok.
is(tok::eod))
return false;
1245 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag,PP))
1247 }
else if (FlagVal == 2) {
1264 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_pop);
1270 if (FlagTok.
is(tok::eod))
return false;
1271 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag,PP))
1277 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1285 if (FlagTok.
is(tok::eod))
return false;
1286 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag, PP))
1291 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1299 if (FlagTok.
is(tok::eod))
return false;
1302 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1314 void Preprocessor::HandleDigitDirective(
Token &DigitTok) {
1318 if (
GetLineValue(DigitTok, LineNo, diag::err_pp_linemarker_requires_integer,
1325 bool IsFileEntry =
false, IsFileExit =
false;
1326 int FilenameID = -1;
1331 if (StrTok.
is(tok::eod)) {
1333 FileKind = SourceMgr.getFileCharacteristic(DigitTok.
getLocation());
1334 }
else if (StrTok.
isNot(tok::string_literal)) {
1335 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1338 Diag(StrTok, diag::err_invalid_string_udl);
1343 assert(Literal.
isAscii() &&
"Didn't allow wide strings in");
1347 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1350 FilenameID = SourceMgr.getLineTableFilenameID(Literal.
GetString());
1358 SourceMgr.AddLineNote(DigitTok.
getLocation(), LineNo, FilenameID, IsFileEntry,
1359 IsFileExit, FileKind);
1368 else if (IsFileExit)
1371 Callbacks->FileChanged(CurPPLexer->getSourceLocation(), Reason, FileKind);
1377 void Preprocessor::HandleUserDiagnosticDirective(
Token &
Tok,
1381 return CurPTHLexer->DiscardToEndOfLine();
1389 CurLexer->ReadToEndOfLine(&Message);
1393 StringRef Msg = StringRef(Message).ltrim(
' ');
1396 Diag(Tok, diag::pp_hash_warning) << Msg;
1398 Diag(Tok, diag::err_pp_hash_error) << Msg;
1403 void Preprocessor::HandleIdentSCCSDirective(
Token &Tok) {
1405 Diag(Tok, diag::ext_pp_ident_directive);
1412 if (StrTok.
isNot(tok::string_literal) &&
1413 StrTok.
isNot(tok::wide_string_literal)) {
1414 Diag(StrTok, diag::err_pp_malformed_ident);
1415 if (StrTok.
isNot(tok::eod))
1421 Diag(StrTok, diag::err_invalid_string_udl);
1429 bool Invalid =
false;
1437 void Preprocessor::HandleMacroPublicDirective(
Token &Tok) {
1439 ReadMacroName(MacroNameTok,
MU_Undef);
1442 if (MacroNameTok.
is(tok::eod))
1454 Diag(MacroNameTok, diag::err_pp_visibility_non_macro) << II;
1464 void Preprocessor::HandleMacroPrivateDirective() {
1466 ReadMacroName(MacroNameTok,
MU_Undef);
1469 if (MacroNameTok.
is(tok::eod))
1481 Diag(MacroNameTok, diag::err_pp_visibility_non_macro) << II;
1501 StringRef &Buffer) {
1503 assert(!Buffer.empty() &&
"Can't have tokens with empty spellings!");
1507 if (Buffer[0] ==
'<') {
1508 if (Buffer.back() !=
'>') {
1509 Diag(Loc, diag::err_pp_expects_filename);
1510 Buffer = StringRef();
1514 }
else if (Buffer[0] ==
'"') {
1515 if (Buffer.back() !=
'"') {
1516 Diag(Loc, diag::err_pp_expects_filename);
1517 Buffer = StringRef();
1522 Diag(Loc, diag::err_pp_expects_filename);
1523 Buffer = StringRef();
1528 if (Buffer.size() <= 2) {
1529 Diag(Loc, diag::err_pp_empty_filename);
1530 Buffer = StringRef();
1535 Buffer = Buffer.substr(1, Buffer.size()-2);
1557 while (CurTok.
isNot(tok::eod)) {
1561 if (CurTok.
is(tok::code_completion)) {
1570 FilenameBuffer.push_back(
' ');
1573 size_t PreAppendSize = FilenameBuffer.size();
1574 FilenameBuffer.resize(PreAppendSize+CurTok.
getLength());
1576 const char *BufPtr = &FilenameBuffer[PreAppendSize];
1580 if (BufPtr != &FilenameBuffer[PreAppendSize])
1581 memcpy(&FilenameBuffer[PreAppendSize], BufPtr, ActualLen);
1585 FilenameBuffer.resize(PreAppendSize+ActualLen);
1588 if (CurTok.
is(tok::greater))
1603 void *AnnotationVal) {
1606 auto Tok = llvm::make_unique<Token[]>(1);
1612 EnterTokenStream(std::move(Tok), 1,
true);
1619 ArrayRef<std::pair<IdentifierInfo *, SourceLocation>> Path,
1621 assert(PP.
getLangOpts().ObjC2 &&
"no import syntax available");
1624 for (
size_t I = 0, N = Path.size(); I != N; ++I) {
1627 PathString += Path[I].first->getName();
1629 int IncludeKind = 0;
1632 case tok::pp_include:
1636 case tok::pp_import:
1640 case tok::pp_include_next:
1644 case tok::pp___include_macros:
1649 llvm_unreachable(
"unknown include directive kind");
1654 PP.
Diag(HashLoc, diag::warn_auto_module_import)
1655 << IncludeKind << PathString
1657 (
"@import " + PathString +
";").str());
1664 StringRef RealPathName) {
1665 auto RealPathComponentIter = llvm::sys::path::rbegin(RealPathName);
1666 auto RealPathComponentEnd = llvm::sys::path::rend(RealPathName);
1668 bool SuggestReplacement =
false;
1671 for (
auto &Component : llvm::reverse(Components)) {
1672 if (
"." == Component) {
1673 }
else if (
".." == Component) {
1677 }
else if (RealPathComponentIter != RealPathComponentEnd) {
1678 if (Component != *RealPathComponentIter) {
1682 SuggestReplacement = RealPathComponentIter->equals_lower(Component);
1683 if (!SuggestReplacement)
1685 Component = *RealPathComponentIter;
1687 ++RealPathComponentIter;
1690 return SuggestReplacement;
1698 Module *ShadowingModule =
nullptr;
1699 if (M->
isAvailable(LangOpts, TargetInfo, Requirement, MissingHeader,
1706 }
else if (ShadowingModule) {
1709 diag::note_previous_definition);
1724 void Preprocessor::HandleIncludeDirective(
SourceLocation HashLoc,
1730 CurPPLexer->LexIncludeFilename(FilenameTok);
1738 switch (FilenameTok.
getKind()) {
1743 case tok::angle_string_literal:
1744 case tok::string_literal:
1745 Filename =
getSpelling(FilenameTok, FilenameBuffer);
1753 FilenameBuffer.push_back(
'<');
1756 Filename = FilenameBuffer;
1767 StringRef OriginalFilename =
Filename;
1772 if (Filename.empty()) {
1784 if (IncludeMacroStack.size() == MaxAllowedIncludeStackDepth-1) {
1785 Diag(FilenameTok, diag::err_pp_include_too_deep);
1790 if (PragmaARCCFCodeAuditedLoc.isValid()) {
1791 Diag(HashLoc, diag::err_pp_include_in_arc_cf_code_audited);
1792 Diag(PragmaARCCFCodeAuditedLoc, diag::note_pragma_entered_here);
1799 if (PragmaAssumeNonNullLoc.isValid()) {
1800 Diag(HashLoc, diag::err_pp_include_in_assume_nonnull);
1801 Diag(PragmaAssumeNonNullLoc, diag::note_pragma_entered_here);
1807 if (HeaderInfo.HasIncludeAliasMap()) {
1811 StringRef NewName = HeaderInfo.MapHeaderToIncludeAlias(OriginalFilename);
1812 if (!NewName.empty())
1817 bool IsMapped =
false;
1826 if (LangOpts.MSVCCompat) {
1827 NormalizedPath = Filename.str();
1829 llvm::sys::path::native(NormalizedPath);
1833 FilenameLoc, LangOpts.MSVCCompat ? NormalizedPath.c_str() :
Filename,
1834 isAngled, LookupFrom, LookupFromFile, CurDir,
1835 Callbacks ? &SearchPath :
nullptr, Callbacks ? &RelativePath :
nullptr,
1836 &SuggestedModule, &IsMapped);
1842 if (Callbacks->FileNotFound(Filename, RecoveryPath)) {
1843 if (
const DirectoryEntry *DE = FileMgr.getDirectory(RecoveryPath)) {
1846 HeaderInfo.AddSearchPath(DL, isAngled);
1851 LangOpts.MSVCCompat ? NormalizedPath.c_str() :
Filename, isAngled,
1852 LookupFrom, LookupFromFile, CurDir,
nullptr,
nullptr,
1853 &SuggestedModule, &IsMapped,
true);
1858 if (!SuppressIncludeNotFoundError) {
1865 LangOpts.MSVCCompat ? NormalizedPath.c_str() :
Filename,
false,
1866 LookupFrom, LookupFromFile, CurDir,
1867 Callbacks ? &SearchPath :
nullptr,
1868 Callbacks ? &RelativePath :
nullptr, &SuggestedModule, &IsMapped);
1871 Diag(FilenameTok, diag::err_pp_file_not_found_not_fatal) <<
1879 Diag(FilenameTok, diag::err_pp_file_not_found) << Filename
1886 SkippingUntilPCHThroughHeader =
false;
1894 bool ShouldEnter =
true;
1896 if (PPOpts->SingleFileParseMode)
1897 ShouldEnter =
false;
1902 if (ShouldEnter && Diags->hasFatalErrorOccurred())
1903 ShouldEnter =
false;
1908 if (ShouldEnter && File && SuggestedModule &&
getLangOpts().Modules &&
1919 diag::note_implicit_top_level_module_import_here)
1931 std::reverse(Path.begin(), Path.end());
1945 assert((Imported ==
nullptr || Imported == SuggestedModule.
getModule()) &&
1946 "the imported module is different than the suggested one");
1949 ShouldEnter =
false;
1966 CurLexer->FormTokenWithChars(Result, CurLexer->BufferEnd,
tok::eof);
1967 CurLexer->cutOffLexing();
1969 assert(CurPTHLexer &&
"#include but no current lexer set!");
1970 CurPTHLexer->getEOF(Result);
1981 SourceMgr.getFileCharacteristic(FilenameTok.
getLocation());
1983 FileCharacter =
std::max(HeaderInfo.getFileDirFlavor(File), FileCharacter);
1987 bool SkipHeader =
false;
1988 if (ShouldEnter && File &&
1989 !HeaderInfo.ShouldEnterIncludeFile(*
this, File, isImport,
1992 ShouldEnter =
false;
1998 Callbacks->InclusionDirective(
1999 HashLoc, IncludeTok,
2000 LangOpts.MSVCCompat ? NormalizedPath.c_str() :
Filename, isAngled,
2001 FilenameRange, File, SearchPath, RelativePath,
2002 ShouldEnter ? nullptr : SuggestedModule.
getModule(), FileCharacter);
2003 if (SkipHeader && !SuggestedModule.
getModule())
2004 Callbacks->FileSkipped(*File, FilenameTok, FileCharacter);
2015 const bool CheckIncludePathPortability =
2018 if (CheckIncludePathPortability) {
2019 StringRef Name = LangOpts.MSVCCompat ? NormalizedPath.str() :
Filename;
2022 llvm::sys::path::end(Name));
2026 Path.reserve(Name.size()+2);
2027 Path.push_back(isAngled ?
'<' :
'"');
2028 bool isLeadingSeparator = llvm::sys::path::is_absolute(Name);
2029 for (
auto Component : Components) {
2030 if (isLeadingSeparator)
2031 isLeadingSeparator =
false;
2033 Path.append(Component);
2036 Path.size() <= Filename.size() ? Filename[Path.size()-1] :
2037 (isAngled ?
'>' :
'"'));
2042 diag::pp_nonportable_path : diag::pp_nonportable_system_path;
2044 Diag(FilenameTok, DiagId) << Path <<
2052 if (
auto *M = SuggestedModule.
getModule()) {
2065 tok::pp___include_macros)
2067 tok::annot_module_include, M);
2077 IncludePos = SourceMgr.getExpansionRange(IncludePos).getEnd();
2078 FileID FID = SourceMgr.createFileID(File, IncludePos, FileCharacter);
2079 assert(FID.
isValid() &&
"Expected valid file ID");
2086 if (
auto *M = SuggestedModule.
getModule()) {
2087 if (M->getTopLevelModule()->ShadowingModule) {
2090 Diag(M->DefinitionLoc, diag::err_module_build_shadowed_submodule)
2091 << M->getFullModuleName();
2092 Diag(M->getTopLevelModule()->ShadowingModule->DefinitionLoc,
2093 diag::note_previous_definition);
2104 assert(!CurLexerSubmodule &&
"should not have marked this as a module yet");
2105 CurLexerSubmodule = M;
2121 void Preprocessor::HandleIncludeNextDirective(
SourceLocation HashLoc,
2122 Token &IncludeNextTok) {
2123 Diag(IncludeNextTok, diag::ext_pp_include_next_directive);
2129 const FileEntry *LookupFromFile =
nullptr;
2136 Diag(IncludeNextTok, diag::pp_include_next_in_primary);
2137 }
else if (CurLexerSubmodule) {
2140 assert(CurPPLexer &&
"#include_next directive in macro?");
2141 LookupFromFile = CurPPLexer->getFileEntry();
2143 }
else if (!Lookup) {
2144 Diag(IncludeNextTok, diag::pp_include_next_absolute_path);
2150 return HandleIncludeDirective(HashLoc, IncludeNextTok, Lookup,
2155 void Preprocessor::HandleMicrosoftImportDirective(
Token &Tok) {
2161 Diag(Tok, diag::err_pp_import_directive_ms );
2172 if (!LangOpts.ObjC1) {
2173 if (LangOpts.MSVCCompat)
2174 return HandleMicrosoftImportDirective(ImportTok);
2175 Diag(ImportTok, diag::ext_pp_import_directive);
2177 return HandleIncludeDirective(HashLoc, ImportTok,
nullptr,
nullptr,
true);
2184 void Preprocessor::HandleIncludeMacrosDirective(
SourceLocation HashLoc,
2185 Token &IncludeMacrosTok) {
2189 if (SourceMgr.getBufferName(Loc) !=
"<built-in>") {
2191 diag::pp_include_macros_out_of_predefines);
2198 HandleIncludeDirective(HashLoc, IncludeMacrosTok);
2203 assert(TmpTok.
isNot(
tok::eof) &&
"Didn't find end of -imacros!");
2204 }
while (TmpTok.
isNot(tok::hashhash));
2215 bool Preprocessor::ReadMacroParameterList(
MacroInfo *MI,
Token &Tok) {
2223 if (Parameters.empty())
2226 Diag(Tok, diag::err_pp_expected_ident_in_arg_list);
2230 Diag(Tok, LangOpts.CPlusPlus11 ?
2231 diag::warn_cxx98_compat_variadic_macro :
2232 diag::ext_variadic_macro);
2235 if (LangOpts.OpenCL) {
2236 Diag(Tok, diag::err_pp_opencl_variadic_macros);
2242 if (Tok.
isNot(tok::r_paren)) {
2243 Diag(Tok, diag::err_pp_missing_rparen_in_macro_def);
2247 Parameters.push_back(Ident__VA_ARGS__);
2252 Diag(Tok, diag::err_pp_missing_rparen_in_macro_def);
2260 Diag(Tok, diag::err_pp_invalid_tok_in_arg_list);
2266 if (std::find(Parameters.begin(), Parameters.end(), II) !=
2268 Diag(Tok, diag::err_pp_duplicate_name_in_arg_list) << II;
2273 Parameters.push_back(II);
2280 Diag(Tok, diag::err_pp_expected_comma_in_arg_list);
2289 Diag(Tok, diag::ext_named_variadic_macro);
2293 if (Tok.
isNot(tok::r_paren)) {
2294 Diag(Tok, diag::err_pp_missing_rparen_in_macro_def);
2322 if (!II->isKeyword(LOptions))
2324 StringRef ValueText = II->getName();
2325 StringRef TrimmedValue = ValueText;
2326 if (!ValueText.startswith(
"__")) {
2327 if (ValueText.startswith(
"_"))
2328 TrimmedValue = TrimmedValue.drop_front(1);
2332 TrimmedValue = TrimmedValue.drop_front(2);
2333 if (TrimmedValue.endswith(
"__"))
2334 TrimmedValue = TrimmedValue.drop_back(2);
2336 return TrimmedValue.equals(MacroText);
2343 return MacroName.
isOneOf(tok::kw_extern, tok::kw_inline, tok::kw_static,
2356 MacroInfo *Preprocessor::ReadOptionalMacroParameterListAndBody(
2357 const Token &MacroNameTok,
const bool ImmediatelyAfterHeaderGuard) {
2359 Token LastTok = MacroNameTok;
2373 if (Tok.is(tok::eod)) {
2374 if (ImmediatelyAfterHeaderGuard) {
2380 }
else if (Tok.hasLeadingSpace()) {
2384 }
else if (Tok.is(tok::l_paren)) {
2387 if (ReadMacroParameterList(MI, LastTok)) {
2389 if (CurPPLexer->ParsingPreprocessorDirective)
2405 }
else if (LangOpts.C99 || LangOpts.CPlusPlus11) {
2408 Diag(Tok, diag::ext_c99_whitespace_required_after_macro_name);
2417 if (Tok.is(tok::at))
2419 else if (Tok.is(tok::unknown)) {
2426 Diag(Tok, diag::ext_missing_whitespace_after_macro_name);
2428 Diag(Tok, diag::warn_missing_whitespace_after_macro_name);
2431 if (!Tok.is(tok::eod))
2437 while (Tok.isNot(tok::eod)) {
2450 while (Tok.isNot(tok::eod)) {
2453 if (!Tok.isOneOf(tok::hash, tok::hashat, tok::hashhash)) {
2459 Diag(Tok, diag::err_pp_vaopt_nested_use);
2464 if (Tok.isNot(tok::l_paren)) {
2465 Diag(Tok, diag::err_pp_missing_lparen_in_vaopt_use);
2471 if (Tok.is(tok::hashhash)) {
2472 Diag(Tok, diag::err_vaopt_paste_at_start);
2477 if (Tok.is(tok::r_paren)) {
2480 assert(NumTokens >= 3 &&
"Must have seen at least __VA_OPT__( " 2481 "and a subsequent tok::r_paren");
2483 Diag(Tok, diag::err_vaopt_paste_at_end);
2487 }
else if (Tok.is(tok::l_paren)) {
2500 Tok.setKind(tok::unknown);
2508 if (Tok.is(tok::hashhash)) {
2516 if (Tok.is(tok::eod)) {
2522 if (NumTokens && Tok.getIdentifierInfo() == Ident__VA_ARGS__ &&
2537 (Tok.getIdentifierInfo() ==
nullptr ||
2544 if (
getLangOpts().AsmPreprocessor && Tok.isNot(tok::eod)) {
2545 LastTok.
setKind(tok::unknown);
2549 Diag(Tok, diag::err_pp_stringize_not_parameter)
2550 << LastTok.
is(tok::hashat);
2570 assert(Tok.is(tok::eod) &&
"Must be at End Of preprocessing Directive");
2571 Diag(Tok, diag::err_pp_expected_after)
2572 << LastTok.
getKind() << tok::r_paren;
2582 void Preprocessor::HandleDefineDirective(
2583 Token &DefineTok,
const bool ImmediatelyAfterHeaderGuard) {
2587 bool MacroShadowsKeyword;
2588 ReadMacroName(MacroNameTok,
MU_Define, &MacroShadowsKeyword);
2591 if (MacroNameTok.
is(tok::eod))
2596 if (CurLexer) CurLexer->SetCommentRetentionState(KeepMacroComments);
2598 MacroInfo *
const MI = ReadOptionalMacroParameterListAndBody(
2599 MacroNameTok, ImmediatelyAfterHeaderGuard);
2603 if (MacroShadowsKeyword &&
2605 Diag(MacroNameTok, diag::warn_pp_macro_hides_keyword);
2610 if (NumTokens != 0) {
2622 if (SkippingUntilPCHThroughHeader) {
2625 LangOpts.MicrosoftExt))
2637 auto isObjCProtectedMacro = [](
const IdentifierInfo *II) ->
bool {
2638 return II->
isStr(
"__strong") ||
2639 II->isStr(
"__weak") ||
2640 II->isStr(
"__unsafe_unretained") ||
2641 II->isStr(
"__autoreleasing");
2644 SourceMgr.getFileID(OtherMI->getDefinitionLoc())
2649 !SourceMgr.isInSystemHeader(DefineTok.
getLocation())) &&
2651 LangOpts.MicrosoftExt)) {
2654 assert(!OtherMI->isWarnIfUnused());
2662 !SourceMgr.isInSystemHeader(DefineTok.
getLocation())) {
2663 if (!OtherMI->isUsed() && OtherMI->isWarnIfUnused())
2664 Diag(OtherMI->getDefinitionLoc(), diag::pp_macro_not_used);
2668 if (OtherMI->isBuiltinMacro())
2669 Diag(MacroNameTok, diag::ext_pp_redef_builtin_macro);
2672 else if (!OtherMI->isAllowRedefinitionsWithoutWarning() &&
2673 !MI->
isIdenticalTo(*OtherMI, *
this, LangOpts.MicrosoftExt)) {
2676 Diag(OtherMI->getDefinitionLoc(), diag::note_previous_definition);
2679 if (OtherMI->isWarnIfUnused())
2680 WarnUnusedMacroLocs.erase(OtherMI->getDefinitionLoc());
2697 Callbacks->MacroDefined(MacroNameTok, MD);
2702 void Preprocessor::HandleUndefDirective() {
2706 ReadMacroName(MacroNameTok,
MU_Undef);
2709 if (MacroNameTok.
is(tok::eod))
2721 if (
const MacroInfo *MI = MD.getMacroInfo()) {
2728 Undef = AllocateUndefMacroDirective(MacroNameTok.
getLocation());
2734 Callbacks->MacroUndefined(MacroNameTok, MD, Undef);
2749 void Preprocessor::HandleIfdefDirective(
Token &
Result,
2750 const Token &HashToken,
2752 bool ReadAnyTokensBeforeDirective) {
2757 ReadMacroName(MacroNameTok);
2760 if (MacroNameTok.
is(tok::eod)) {
2763 SkipExcludedConditionalBlock(HashToken.
getLocation(),
2776 if (CurPPLexer->getConditionalStackDepth() == 0) {
2781 if (!ReadAnyTokensBeforeDirective && !MI) {
2782 assert(isIfndef &&
"#ifdef shouldn't reach here");
2783 CurPPLexer->MIOpt.EnterTopLevelIfndef(MII, MacroNameTok.
getLocation());
2785 CurPPLexer->MIOpt.EnterTopLevelConditional();
2794 Callbacks->Ifndef(DirectiveTok.
getLocation(), MacroNameTok, MD);
2796 Callbacks->Ifdef(DirectiveTok.
getLocation(), MacroNameTok, MD);
2800 if (PPOpts->SingleFileParseMode && !MI) {
2803 CurPPLexer->pushConditionalLevel(DirectiveTok.
getLocation(),
2806 }
else if (!MI == isIfndef) {
2808 CurPPLexer->pushConditionalLevel(DirectiveTok.
getLocation(),
2813 SkipExcludedConditionalBlock(HashToken.
getLocation(),
2822 void Preprocessor::HandleIfDirective(
Token &IfToken,
2823 const Token &HashToken,
2824 bool ReadAnyTokensBeforeDirective) {
2829 const SourceLocation ConditionalBegin = CurPPLexer->getSourceLocation();
2830 const DirectiveEvalResult DER = EvaluateDirectiveExpression(IfNDefMacro);
2831 const bool ConditionalTrue = DER.Conditional;
2832 const SourceLocation ConditionalEnd = CurPPLexer->getSourceLocation();
2836 if (CurPPLexer->getConditionalStackDepth() == 0) {
2837 if (!ReadAnyTokensBeforeDirective && IfNDefMacro && ConditionalTrue)
2839 CurPPLexer->MIOpt.EnterTopLevelIfndef(IfNDefMacro, IfToken.
getLocation());
2841 CurPPLexer->MIOpt.EnterTopLevelConditional();
2850 if (PPOpts->SingleFileParseMode && DER.IncludedUndefinedIds) {
2853 CurPPLexer->pushConditionalLevel(IfToken.
getLocation(),
false,
2855 }
else if (ConditionalTrue) {
2857 CurPPLexer->pushConditionalLevel(IfToken.
getLocation(),
false,
2869 void Preprocessor::HandleEndifDirective(
Token &EndifToken) {
2876 if (CurPPLexer->popConditionalLevel(CondInfo)) {
2878 Diag(EndifToken, diag::err_pp_endif_without_if);
2883 if (CurPPLexer->getConditionalStackDepth() == 0)
2884 CurPPLexer->MIOpt.ExitTopLevelConditional();
2886 assert(!CondInfo.
WasSkipping && !CurPPLexer->LexingRawMode &&
2887 "This code should only be reachable in the non-skipping case!");
2895 void Preprocessor::HandleElseDirective(
Token &Result,
const Token &HashToken) {
2902 if (CurPPLexer->popConditionalLevel(CI)) {
2903 Diag(Result, diag::pp_err_else_without_if);
2908 if (CurPPLexer->getConditionalStackDepth() == 0)
2909 CurPPLexer->MIOpt.EnterTopLevelConditional();
2912 if (CI.
FoundElse)
Diag(Result, diag::pp_err_else_after_else);
2920 CurPPLexer->pushConditionalLevel(CI.
IfLoc,
false,
2933 void Preprocessor::HandleElifDirective(
Token &ElifToken,
2934 const Token &HashToken) {
2940 const SourceLocation ConditionalBegin = CurPPLexer->getSourceLocation();
2942 const SourceLocation ConditionalEnd = CurPPLexer->getSourceLocation();
2945 if (CurPPLexer->popConditionalLevel(CI)) {
2946 Diag(ElifToken, diag::pp_err_elif_without_if);
2951 if (CurPPLexer->getConditionalStackDepth() == 0)
2952 CurPPLexer->MIOpt.EnterTopLevelConditional();
2955 if (CI.
FoundElse)
Diag(ElifToken, diag::pp_err_elif_after_else);
2965 CurPPLexer->pushConditionalLevel(ElifToken.
getLocation(),
false,
2971 SkipExcludedConditionalBlock(
StringRef tryGetRealPathName() const
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.
SourceLocation getLocWithOffset(int Offset) const
Return a source location with the specified offset from this SourceLocation.
MacroInfo * AllocateMacroInfo(SourceLocation L)
Allocate a new MacroInfo object with the provided SourceLocation.
bool ConcatenateIncludeName(SmallString< 128 > &FilenameBuffer, SourceLocation &End)
Handle cases where the #include name is expanded from a macro as multiple tokens, which need to be gl...
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.
Defines the clang::Module class, which describes a module in the source code.
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
const FileEntry * 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 SkipCache=false)
Given a "foo" or <foo> reference, look up the indicated file.
CharacteristicKind
Indicates whether a file or directory holds normal user code, system code, or system code which is im...
void setIsWarnIfUnused(bool val)
Set the value of the IsWarnIfUnused flag.
tok::TokenKind getKind() const
static MacroDiag shouldWarnOnMacroDef(Preprocessor &PP, IdentifierInfo *II)
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)
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.
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.
std::pair< FileID, unsigned > getDecomposedExpansionLoc(SourceLocation Loc) const
Decompose the specified location into a raw FileID + Offset pair.
void CheckEndOfDirective(const char *Directive, bool EnableMacros=false)
Ensure that the next token is a tok::eod token.
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 ...
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.
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)...
std::string CurrentModule
The name of the current module, of which the main source file is a part.
const DirectoryEntry * getDirectory(StringRef DirName, bool CacheFailure=true)
Lookup, cache, and verify the specified directory (real or virtual).
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.
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)
PPKeywordKind
Provides a namespace for preprocessor keywords which start with a '#' at the beginning of the line...
void enterScope()
Client code should call this function just before the Preprocessor is about to Lex tokens from the de...
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.
bool isPCHThroughHeader(const FileEntry *File)
Returns true if the FileEntry is the PCH through header.
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
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.
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 speficied by -fmodule-name.
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)
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
static bool isInvalid(LocType Loc, bool *Invalid)
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)
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.
void HandleSkippedThroughHeaderDirective(Token &Result, SourceLocation HashLoc)
Process directives while skipping until the through header is found.
int getParameterNum(const IdentifierInfo *Arg) const
Return the parameter number of the specified identifier, or -1 if the identifier is not a formal para...
bool GetIncludeFilenameSpelling(SourceLocation Loc, StringRef &Filename)
Turn the specified lexer token into a fully checked and spelled filename, e.g.
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.
Cached information about one directory (either on disk or in the virtual file system).
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...
Defines the clang::SourceLocation class and associated facilities.
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.
__DEVICE__ int max(int __a, int __b)
void DiscardUntilEndOfDirective()
Read and discard all tokens remaining on the current line until the tok::eod token is found...
Annotates a diagnostic with some code that should be inserted, removed, or replaced to fix the proble...
void setLocation(SourceLocation L)
A trivial tuple used to represent a source range.
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
bool hasLeadingSpace() const
Return true if this token has whitespace before it.
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.
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+...
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
bool EnterSourceFile(FileID CurFileID, 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...