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 if (Lang.CPlusPlus11 && (Text.equals(
"override") || Text.equals(
"final")))
147 if (::llvm::sys::path::begin(Include)->equals_lower(
"boost"))
152 static const size_t MaxStdHeaderNameLen = 18u;
153 if (Include.size() > MaxStdHeaderNameLen)
158 for (
char &Ch : LowerInclude) {
160 if (static_cast<unsigned char>(Ch) > 0x7f)
163 if (Ch >=
'A' && Ch <=
'Z')
166 else if (::llvm::sys::path::is_separator(Ch))
171 return llvm::StringSwitch<bool>(LowerInclude)
173 .Cases(
"assert.h",
"complex.h",
"ctype.h",
"errno.h",
"fenv.h",
true)
174 .Cases(
"float.h",
"inttypes.h",
"iso646.h",
"limits.h",
"locale.h",
true)
175 .Cases(
"math.h",
"setjmp.h",
"signal.h",
"stdalign.h",
"stdarg.h",
true)
176 .Cases(
"stdatomic.h",
"stdbool.h",
"stddef.h",
"stdint.h",
"stdio.h",
true)
177 .Cases(
"stdlib.h",
"stdnoreturn.h",
"string.h",
"tgmath.h",
"threads.h",
true)
178 .Cases(
"time.h",
"uchar.h",
"wchar.h",
"wctype.h",
true)
181 .Cases(
"cassert",
"ccomplex",
"cctype",
"cerrno",
"cfenv",
true)
182 .Cases(
"cfloat",
"cinttypes",
"ciso646",
"climits",
"clocale",
true)
183 .Cases(
"cmath",
"csetjmp",
"csignal",
"cstdalign",
"cstdarg",
true)
184 .Cases(
"cstdbool",
"cstddef",
"cstdint",
"cstdio",
"cstdlib",
true)
185 .Cases(
"cstring",
"ctgmath",
"ctime",
"cuchar",
"cwchar",
true)
186 .Case(
"cwctype",
true)
189 .Cases(
"algorithm",
"fstream",
"list",
"regex",
"thread",
true)
190 .Cases(
"array",
"functional",
"locale",
"scoped_allocator",
"tuple",
true)
191 .Cases(
"atomic",
"future",
"map",
"set",
"type_traits",
true)
192 .Cases(
"bitset",
"initializer_list",
"memory",
"shared_mutex",
"typeindex",
true)
193 .Cases(
"chrono",
"iomanip",
"mutex",
"sstream",
"typeinfo",
true)
194 .Cases(
"codecvt",
"ios",
"new",
"stack",
"unordered_map",
true)
195 .Cases(
"complex",
"iosfwd",
"numeric",
"stdexcept",
"unordered_set",
true)
196 .Cases(
"condition_variable",
"iostream",
"ostream",
"streambuf",
"utility",
true)
197 .Cases(
"deque",
"istream",
"queue",
"string",
"valarray",
true)
198 .Cases(
"exception",
"iterator",
"random",
"strstream",
"vector",
true)
199 .Cases(
"forward_list",
"limits",
"ratio",
"system_error",
true)
202 .Cases(
"aio.h",
"arpa/inet.h",
"cpio.h",
"dirent.h",
"dlfcn.h",
true)
203 .Cases(
"fcntl.h",
"fmtmsg.h",
"fnmatch.h",
"ftw.h",
"glob.h",
true)
204 .Cases(
"grp.h",
"iconv.h",
"langinfo.h",
"libgen.h",
"monetary.h",
true)
205 .Cases(
"mqueue.h",
"ndbm.h",
"net/if.h",
"netdb.h",
"netinet/in.h",
true)
206 .Cases(
"netinet/tcp.h",
"nl_types.h",
"poll.h",
"pthread.h",
"pwd.h",
true)
207 .Cases(
"regex.h",
"sched.h",
"search.h",
"semaphore.h",
"spawn.h",
true)
208 .Cases(
"strings.h",
"stropts.h",
"sys/ipc.h",
"sys/mman.h",
"sys/msg.h",
true)
209 .Cases(
"sys/resource.h",
"sys/select.h",
"sys/sem.h",
"sys/shm.h",
"sys/socket.h",
true)
210 .Cases(
"sys/stat.h",
"sys/statvfs.h",
"sys/time.h",
"sys/times.h",
"sys/types.h",
true)
211 .Cases(
"sys/uio.h",
"sys/un.h",
"sys/utsname.h",
"sys/wait.h",
"syslog.h",
true)
212 .Cases(
"tar.h",
"termios.h",
"trace.h",
"ulimit.h",
true)
213 .Cases(
"unistd.h",
"utime.h",
"utmpx.h",
"wordexp.h",
true)
220 if (MacroNameTok.
is(tok::eod))
221 return Diag(MacroNameTok, diag::err_pp_missing_macro_name);
225 return Diag(MacroNameTok, diag::err_pp_macro_not_identifier);
231 ? diag::ext_pp_operator_used_as_macro_name
232 : diag::err_pp_operator_used_as_macro_name)
233 << II << MacroNameTok.
getKind();
240 return Diag(MacroNameTok, diag::err_defined_macro_name);
248 Diag(MacroNameTok, diag::ext_pp_undef_builtin_macro);
273 Diag(MacroNameTok, diag::warn_pp_macro_is_reserved_id);
289 void Preprocessor::ReadMacroName(
Token &MacroNameTok,
MacroUse isDefineUndef,
294 if (MacroNameTok.
is(tok::code_completion)) {
306 if (MacroNameTok.
isNot(tok::eod)) {
307 MacroNameTok.
setKind(tok::eod);
328 while (Tmp.
is(tok::comment))
331 if (Tmp.
isNot(tok::eod)) {
337 if ((LangOpts.GNUMode || LangOpts.C99 || LangOpts.CPlusPlus) &&
340 Diag(Tmp, diag::ext_pp_extra_tokens_at_eol) << DirType << Hint;
353 void Preprocessor::SkipExcludedConditionalBlock(
SourceLocation HashTokenLoc,
355 bool FoundNonSkipPortion,
359 assert(!CurTokenLexer && CurPPLexer &&
"Lexing a macro, not a file?");
361 if (PreambleConditionalStack.reachedEOFWhileSkipping())
362 PreambleConditionalStack.clearSkipInfo();
365 FoundNonSkipPortion, FoundElse);
368 PTHSkipExcludedConditionalBlock();
379 if (Tok.
is(tok::code_completion)) {
391 if (PreambleConditionalStack.isRecording())
392 PreambleConditionalStack.SkipInfo.emplace(
393 HashTokenLoc, IfTokenLoc, FoundNonSkipPortion, FoundElse, ElseLoc);
405 if (CurLexer) CurLexer->SetKeepWhitespaceMode(
false);
413 if (Tok.
isNot(tok::raw_identifier)) {
416 if (CurLexer) CurLexer->resetExtendedTokenMode();
427 char FirstChar = RI[0];
428 if (FirstChar >=
'a' && FirstChar <=
'z' &&
429 FirstChar !=
'i' && FirstChar !=
'e') {
432 if (CurLexer) CurLexer->resetExtendedTokenMode();
439 char DirectiveBuf[20];
445 size_t IdLen = DirectiveStr.size();
449 if (CurLexer) CurLexer->resetExtendedTokenMode();
452 memcpy(DirectiveBuf, &DirectiveStr[0], IdLen);
453 Directive = StringRef(DirectiveBuf, IdLen);
456 if (Directive.startswith(
"if")) {
457 StringRef Sub = Directive.substr(2);
468 }
else if (Directive[0] ==
'e') {
469 StringRef Sub = Directive.substr(1);
475 assert(!InCond &&
"Can't be skipping if not in a conditional!");
490 }
else if (Sub ==
"lse") {
497 if (CondInfo.
FoundElse)
Diag(Tok, diag::pp_err_else_after_else);
517 }
else if (Sub ==
"lif") {
521 if (CondInfo.
FoundElse)
Diag(Tok, diag::pp_err_elif_after_else);
531 assert(CurPPLexer->
LexingRawMode &&
"We have to be skipping here!");
534 const bool CondValue = EvaluateDirectiveExpression(IfNDefMacro).Conditional;
553 if (CurLexer) CurLexer->resetExtendedTokenMode();
562 Callbacks->SourceRangeSkipped(
567 void Preprocessor::PTHSkipExcludedConditionalBlock() {
570 assert(CurPTHLexer->LexingRawMode ==
false);
573 if (CurPTHLexer->SkipBlock()) {
577 bool InCond = CurPTHLexer->popConditionalLevel(CondInfo);
579 assert(!InCond &&
"Can't be skipping if not in a conditional!");
592 if (K == tok::pp_else) {
605 CurPTHLexer->ParsingPreprocessorDirective =
true;
607 CurPTHLexer->ParsingPreprocessorDirective =
false;
616 assert(K == tok::pp_elif);
621 Diag(Tok, diag::pp_err_elif_after_else);
630 CurPTHLexer->ParsingPreprocessorDirective =
true;
631 bool ShouldEnter = EvaluateDirectiveExpression(IfNDefMacro).Conditional;
632 CurPTHLexer->ParsingPreprocessorDirective =
false;
668 assert(M &&
"no module to include");
689 bool InTextualHeader =
false;
691 if (!Header.getModule()->isSubModuleOf(TopM))
698 if (Header.isAccessibleFrom(IncM))
708 InTextualHeader =
true;
711 if (!InTextualHeader)
727 bool RequestingModuleIsModuleInterface = !SourceMgr.
isInMainFile(FilenameLoc);
733 bool BuildSystemModule =
false;
734 if (!FromDir && !FromFile) {
752 Includers.push_back(std::make_pair(
nullptr, MainFileDir));
754 }
else if ((FileEnt =
756 Includers.push_back(std::make_pair(FileEnt, FileMgr.
getDirectory(
".")));
758 Includers.push_back(std::make_pair(FileEnt, FileEnt->
getDir()));
764 if (LangOpts.MSVCCompat && !isAngled) {
765 for (IncludeStackInfo &ISEntry : llvm::reverse(IncludeMacroStack)) {
766 if (IsFileLexer(ISEntry))
767 if ((FileEnt = ISEntry.ThePPLexer->getFileEntry()))
768 Includers.push_back(std::make_pair(FileEnt, FileEnt->
getDir()));
773 CurDir = CurDirLookup;
781 Filename, FilenameLoc, isAngled, TmpFromDir, TmpCurDir,
782 Includers, SearchPath, RelativePath, RequestingModule,
783 SuggestedModule,
nullptr, SkipCache)) {
785 TmpFromDir = TmpCurDir;
787 if (FE == FromFile) {
789 FromDir = TmpFromDir;
798 Filename, FilenameLoc, isAngled, FromDir, CurDir, Includers, SearchPath,
799 RelativePath, RequestingModule, SuggestedModule, IsMapped, SkipCache,
802 if (SuggestedModule && !LangOpts.AsmPreprocessor)
804 RequestingModule, RequestingModuleIsModuleInterface, FilenameLoc,
816 SearchPath, RelativePath,
819 if (SuggestedModule && !LangOpts.AsmPreprocessor)
821 RequestingModule, RequestingModuleIsModuleInterface, FilenameLoc,
828 for (IncludeStackInfo &ISEntry : llvm::reverse(IncludeMacroStack)) {
829 if (IsFileLexer(ISEntry)) {
830 if ((CurFileEnt = ISEntry.ThePPLexer->getFileEntry())) {
832 Filename, CurFileEnt, SearchPath, RelativePath,
833 RequestingModule, SuggestedModule))) {
834 if (SuggestedModule && !LangOpts.AsmPreprocessor)
836 RequestingModule, RequestingModuleIsModuleInterface,
837 FilenameLoc, Filename, FE);
855 : PP(pp), save(pp->DisableMacroExpansion) {
856 if (pp->MacroExpansionInDirectivesOverride)
857 pp->DisableMacroExpansion =
false;
861 PP->DisableMacroExpansion = save;
879 CurPPLexer->ParsingPreprocessorDirective =
true;
880 if (CurLexer) CurLexer->SetKeepWhitespaceMode(
false);
882 bool ImmediatelyAfterTopLevelIfndef =
883 CurPPLexer->MIOpt.getImmediatelyAfterTopLevelIfndef();
884 CurPPLexer->MIOpt.resetImmediatelyAfterTopLevelIfndef();
891 bool ReadAnyTokensBeforeDirective =CurPPLexer->MIOpt.getHasReadAnyTokensVal();
910 switch (II->getPPKeywordID()) {
911 case tok::pp_include:
913 case tok::pp_include_next:
914 case tok::pp___include_macros:
916 Diag(Result, diag::err_embedded_directive) << II->getName();
923 Diag(Result, diag::ext_embedded_directive);
933 case tok::code_completion:
935 CodeComplete->CodeCompleteDirective(
936 CurPPLexer->getConditionalStackDepth() > 0);
939 case tok::numeric_constant:
942 return HandleDigitDirective(Result);
952 return HandleIfDirective(Result, SavedHash, ReadAnyTokensBeforeDirective);
954 return HandleIfdefDirective(Result, SavedHash,
false,
957 return HandleIfdefDirective(Result, SavedHash,
true,
958 ReadAnyTokensBeforeDirective);
960 return HandleElifDirective(Result, SavedHash);
962 return HandleElseDirective(Result, SavedHash);
964 return HandleEndifDirective(Result);
967 case tok::pp_include:
970 case tok::pp___include_macros:
976 return HandleDefineDirective(Result, ImmediatelyAfterTopLevelIfndef);
978 return HandleUndefDirective();
982 return HandleLineDirective();
986 return HandleUserDiagnosticDirective(Result,
false);
995 case tok::pp_include_next:
998 case tok::pp_warning:
999 Diag(Result, diag::ext_pp_warning_directive);
1000 return HandleUserDiagnosticDirective(Result,
true);
1002 return HandleIdentSCCSDirective(Result);
1004 return HandleIdentSCCSDirective(Result);
1005 case tok::pp_assert:
1008 case tok::pp_unassert:
1012 case tok::pp___public_macro:
1014 return HandleMacroPublicDirective(Result);
1017 case tok::pp___private_macro:
1019 return HandleMacroPrivateDirective();
1030 auto Toks = llvm::make_unique<Token[]>(2);
1032 Toks[0] = SavedHash;
1037 if (Result.
is(tok::hashhash))
1038 Toks[1].setKind(tok::unknown);
1043 EnterTokenStream(std::move(Toks), 2,
false);
1048 Diag(Result, diag::err_pp_invalid_directive);
1060 bool IsGNULineDirective=
false) {
1061 if (DigitTok.
isNot(tok::numeric_constant)) {
1062 PP.
Diag(DigitTok, DiagID);
1064 if (DigitTok.
isNot(tok::eod))
1070 IntegerBuffer.resize(DigitTok.
getLength());
1071 const char *DigitTokBegin = &IntegerBuffer[0];
1072 bool Invalid =
false;
1073 unsigned ActualLength = PP.
getSpelling(DigitTok, DigitTokBegin, &Invalid);
1081 for (
unsigned i = 0; i != ActualLength; ++i) {
1084 if (DigitTokBegin[i] ==
'\'')
1087 if (!
isDigit(DigitTokBegin[i])) {
1089 diag::err_pp_line_digit_sequence) << IsGNULineDirective;
1094 unsigned NextVal = Val*10+(DigitTokBegin[i]-
'0');
1095 if (NextVal < Val) {
1096 PP.
Diag(DigitTok, DiagID);
1103 if (DigitTokBegin[0] ==
'0' && Val)
1105 << IsGNULineDirective;
1117 void Preprocessor::HandleLineDirective() {
1125 if (
GetLineValue(DigitTok, LineNo, diag::err_pp_line_requires_integer,*
this))
1129 Diag(DigitTok, diag::ext_pp_line_zero);
1133 unsigned LineLimit = 32768U;
1134 if (LangOpts.C99 || LangOpts.CPlusPlus11)
1135 LineLimit = 2147483648U;
1136 if (LineNo >= LineLimit)
1137 Diag(DigitTok, diag::ext_pp_line_too_big) << LineLimit;
1138 else if (LangOpts.CPlusPlus11 && LineNo >= 32768U)
1139 Diag(DigitTok, diag::warn_cxx98_compat_pp_line_too_big);
1141 int FilenameID = -1;
1147 if (StrTok.
is(tok::eod))
1149 else if (StrTok.
isNot(tok::string_literal)) {
1150 Diag(StrTok, diag::err_pp_line_invalid_filename);
1153 Diag(StrTok, diag::err_invalid_string_udl);
1158 assert(Literal.
isAscii() &&
"Didn't allow wide strings in");
1162 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1165 FilenameID = SourceMgr.getLineTableFilenameID(Literal.
GetString());
1178 SourceMgr.getFileCharacteristic(DigitTok.
getLocation());
1180 SourceMgr.AddLineNote(DigitTok.
getLocation(), LineNo, FilenameID,
false,
1184 Callbacks->FileChanged(CurPPLexer->getSourceLocation(),
1196 if (FlagTok.
is(tok::eod))
return false;
1197 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag, PP))
1204 if (FlagTok.
is(tok::eod))
return false;
1205 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag,PP))
1207 }
else if (FlagVal == 2) {
1224 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_pop);
1230 if (FlagTok.
is(tok::eod))
return false;
1231 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag,PP))
1237 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1245 if (FlagTok.
is(tok::eod))
return false;
1246 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag, PP))
1251 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1259 if (FlagTok.
is(tok::eod))
return false;
1262 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1274 void Preprocessor::HandleDigitDirective(
Token &DigitTok) {
1278 if (
GetLineValue(DigitTok, LineNo, diag::err_pp_linemarker_requires_integer,
1285 bool IsFileEntry =
false, IsFileExit =
false;
1286 int FilenameID = -1;
1291 if (StrTok.
is(tok::eod)) {
1293 FileKind = SourceMgr.getFileCharacteristic(DigitTok.
getLocation());
1294 }
else if (StrTok.
isNot(tok::string_literal)) {
1295 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1298 Diag(StrTok, diag::err_invalid_string_udl);
1303 assert(Literal.
isAscii() &&
"Didn't allow wide strings in");
1307 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1310 FilenameID = SourceMgr.getLineTableFilenameID(Literal.
GetString());
1318 SourceMgr.AddLineNote(DigitTok.
getLocation(), LineNo, FilenameID, IsFileEntry,
1319 IsFileExit, FileKind);
1328 else if (IsFileExit)
1331 Callbacks->FileChanged(CurPPLexer->getSourceLocation(), Reason, FileKind);
1337 void Preprocessor::HandleUserDiagnosticDirective(
Token &
Tok,
1341 return CurPTHLexer->DiscardToEndOfLine();
1349 CurLexer->ReadToEndOfLine(&Message);
1353 StringRef Msg = StringRef(Message).ltrim(
' ');
1356 Diag(Tok, diag::pp_hash_warning) << Msg;
1358 Diag(Tok, diag::err_pp_hash_error) << Msg;
1363 void Preprocessor::HandleIdentSCCSDirective(
Token &Tok) {
1365 Diag(Tok, diag::ext_pp_ident_directive);
1372 if (StrTok.
isNot(tok::string_literal) &&
1373 StrTok.
isNot(tok::wide_string_literal)) {
1374 Diag(StrTok, diag::err_pp_malformed_ident);
1375 if (StrTok.
isNot(tok::eod))
1381 Diag(StrTok, diag::err_invalid_string_udl);
1389 bool Invalid =
false;
1397 void Preprocessor::HandleMacroPublicDirective(
Token &Tok) {
1399 ReadMacroName(MacroNameTok,
MU_Undef);
1402 if (MacroNameTok.
is(tok::eod))
1414 Diag(MacroNameTok, diag::err_pp_visibility_non_macro) << II;
1424 void Preprocessor::HandleMacroPrivateDirective() {
1426 ReadMacroName(MacroNameTok,
MU_Undef);
1429 if (MacroNameTok.
is(tok::eod))
1441 Diag(MacroNameTok, diag::err_pp_visibility_non_macro) << II;
1461 StringRef &Buffer) {
1463 assert(!Buffer.empty() &&
"Can't have tokens with empty spellings!");
1467 if (Buffer[0] ==
'<') {
1468 if (Buffer.back() !=
'>') {
1469 Diag(Loc, diag::err_pp_expects_filename);
1470 Buffer = StringRef();
1474 }
else if (Buffer[0] ==
'"') {
1475 if (Buffer.back() !=
'"') {
1476 Diag(Loc, diag::err_pp_expects_filename);
1477 Buffer = StringRef();
1482 Diag(Loc, diag::err_pp_expects_filename);
1483 Buffer = StringRef();
1488 if (Buffer.size() <= 2) {
1489 Diag(Loc, diag::err_pp_empty_filename);
1490 Buffer = StringRef();
1495 Buffer = Buffer.substr(1, Buffer.size()-2);
1517 while (CurTok.
isNot(tok::eod)) {
1521 if (CurTok.
is(tok::code_completion)) {
1530 FilenameBuffer.push_back(
' ');
1533 size_t PreAppendSize = FilenameBuffer.size();
1534 FilenameBuffer.resize(PreAppendSize+CurTok.
getLength());
1536 const char *BufPtr = &FilenameBuffer[PreAppendSize];
1540 if (BufPtr != &FilenameBuffer[PreAppendSize])
1541 memcpy(&FilenameBuffer[PreAppendSize], BufPtr, ActualLen);
1545 FilenameBuffer.resize(PreAppendSize+ActualLen);
1548 if (CurTok.
is(tok::greater))
1563 void *AnnotationVal) {
1566 auto Tok = llvm::make_unique<Token[]>(1);
1572 EnterTokenStream(std::move(Tok), 1,
true);
1579 ArrayRef<std::pair<IdentifierInfo *, SourceLocation>> Path,
1581 assert(PP.
getLangOpts().ObjC2 &&
"no import syntax available");
1584 for (
size_t I = 0, N = Path.size(); I != N; ++I) {
1587 PathString += Path[I].first->getName();
1589 int IncludeKind = 0;
1592 case tok::pp_include:
1596 case tok::pp_import:
1600 case tok::pp_include_next:
1604 case tok::pp___include_macros:
1609 llvm_unreachable(
"unknown include directive kind");
1614 PP.
Diag(HashLoc, diag::warn_auto_module_import)
1615 << IncludeKind << PathString
1617 (
"@import " + PathString +
";").str());
1624 StringRef RealPathName) {
1625 auto RealPathComponentIter = llvm::sys::path::rbegin(RealPathName);
1626 auto RealPathComponentEnd = llvm::sys::path::rend(RealPathName);
1628 bool SuggestReplacement =
false;
1631 for (
auto &Component : llvm::reverse(Components)) {
1632 if (
"." == Component) {
1633 }
else if (
".." == Component) {
1637 }
else if (RealPathComponentIter != RealPathComponentEnd) {
1638 if (Component != *RealPathComponentIter) {
1642 SuggestReplacement = RealPathComponentIter->equals_lower(Component);
1643 if (!SuggestReplacement)
1645 Component = *RealPathComponentIter;
1647 ++RealPathComponentIter;
1650 return SuggestReplacement;
1658 if (M->
isAvailable(LangOpts, TargetInfo, Requirement, MissingHeader))
1678 void Preprocessor::HandleIncludeDirective(
SourceLocation HashLoc,
1684 CurPPLexer->LexIncludeFilename(FilenameTok);
1692 switch (FilenameTok.
getKind()) {
1697 case tok::angle_string_literal:
1698 case tok::string_literal:
1699 Filename =
getSpelling(FilenameTok, FilenameBuffer);
1707 FilenameBuffer.push_back(
'<');
1710 Filename = FilenameBuffer;
1721 StringRef OriginalFilename =
Filename;
1726 if (Filename.empty()) {
1738 if (IncludeMacroStack.size() == MaxAllowedIncludeStackDepth-1) {
1739 Diag(FilenameTok, diag::err_pp_include_too_deep);
1744 if (PragmaARCCFCodeAuditedLoc.isValid()) {
1745 Diag(HashLoc, diag::err_pp_include_in_arc_cf_code_audited);
1746 Diag(PragmaARCCFCodeAuditedLoc, diag::note_pragma_entered_here);
1753 if (PragmaAssumeNonNullLoc.isValid()) {
1754 Diag(HashLoc, diag::err_pp_include_in_assume_nonnull);
1755 Diag(PragmaAssumeNonNullLoc, diag::note_pragma_entered_here);
1761 if (HeaderInfo.HasIncludeAliasMap()) {
1765 StringRef NewName = HeaderInfo.MapHeaderToIncludeAlias(OriginalFilename);
1766 if (!NewName.empty())
1771 bool IsMapped =
false;
1780 if (LangOpts.MSVCCompat) {
1781 NormalizedPath = Filename.str();
1782 #ifndef LLVM_ON_WIN32 1783 llvm::sys::path::native(NormalizedPath);
1787 FilenameLoc, LangOpts.MSVCCompat ? NormalizedPath.c_str() :
Filename,
1788 isAngled, LookupFrom, LookupFromFile, CurDir,
1789 Callbacks ? &SearchPath :
nullptr, Callbacks ? &RelativePath :
nullptr,
1790 &SuggestedModule, &IsMapped);
1796 if (Callbacks->FileNotFound(Filename, RecoveryPath)) {
1797 if (
const DirectoryEntry *DE = FileMgr.getDirectory(RecoveryPath)) {
1800 HeaderInfo.AddSearchPath(DL, isAngled);
1805 LangOpts.MSVCCompat ? NormalizedPath.c_str() :
Filename, isAngled,
1806 LookupFrom, LookupFromFile, CurDir,
nullptr,
nullptr,
1807 &SuggestedModule, &IsMapped,
true);
1812 if (!SuppressIncludeNotFoundError) {
1819 LangOpts.MSVCCompat ? NormalizedPath.c_str() :
Filename,
false,
1820 LookupFrom, LookupFromFile, CurDir,
1821 Callbacks ? &SearchPath :
nullptr,
1822 Callbacks ? &RelativePath :
nullptr, &SuggestedModule, &IsMapped);
1825 Diag(FilenameTok, diag::err_pp_file_not_found_not_fatal) <<
1833 Diag(FilenameTok, diag::err_pp_file_not_found) << Filename
1842 bool ShouldEnter =
true;
1844 if (PPOpts->SingleFileParseMode)
1845 ShouldEnter =
false;
1850 if (ShouldEnter && File && SuggestedModule &&
getLangOpts().Modules &&
1860 diag::note_implicit_top_level_module_import_here)
1872 std::reverse(Path.begin(), Path.end());
1886 assert((Imported ==
nullptr || Imported == SuggestedModule.
getModule()) &&
1887 "the imported module is different than the suggested one");
1890 ShouldEnter =
false;
1907 CurLexer->FormTokenWithChars(Result, CurLexer->BufferEnd,
tok::eof);
1908 CurLexer->cutOffLexing();
1910 assert(CurPTHLexer &&
"#include but no current lexer set!");
1911 CurPTHLexer->getEOF(Result);
1922 SourceMgr.getFileCharacteristic(FilenameTok.
getLocation());
1924 FileCharacter =
std::max(HeaderInfo.getFileDirFlavor(File), FileCharacter);
1928 bool SkipHeader =
false;
1929 if (ShouldEnter && File &&
1930 !HeaderInfo.ShouldEnterIncludeFile(*
this, File, isImport,
1933 ShouldEnter =
false;
1939 Callbacks->InclusionDirective(
1940 HashLoc, IncludeTok,
1941 LangOpts.MSVCCompat ? NormalizedPath.c_str() :
Filename, isAngled,
1942 FilenameRange, File, SearchPath, RelativePath,
1943 ShouldEnter ? nullptr : SuggestedModule.
getModule());
1944 if (SkipHeader && !SuggestedModule.
getModule())
1945 Callbacks->FileSkipped(*File, FilenameTok, FileCharacter);
1956 const bool CheckIncludePathPortability =
1959 if (CheckIncludePathPortability) {
1960 StringRef Name = LangOpts.MSVCCompat ? NormalizedPath.str() :
Filename;
1963 llvm::sys::path::end(Name));
1967 Path.reserve(Name.size()+2);
1968 Path.push_back(isAngled ?
'<' :
'"');
1969 bool isLeadingSeparator = llvm::sys::path::is_absolute(Name);
1970 for (
auto Component : Components) {
1971 if (isLeadingSeparator)
1972 isLeadingSeparator =
false;
1974 Path.append(Component);
1977 Path.size() <= Filename.size() ? Filename[Path.size()-1] :
1978 (isAngled ?
'>' :
'"'));
1983 diag::pp_nonportable_path : diag::pp_nonportable_system_path;
1985 Diag(FilenameTok, DiagId) << Path <<
1993 if (
auto *M = SuggestedModule.
getModule()) {
2005 tok::pp___include_macros)
2007 tok::annot_module_include, M);
2017 IncludePos = SourceMgr.getExpansionRange(IncludePos).second;
2018 FileID FID = SourceMgr.createFileID(File, IncludePos, FileCharacter);
2019 assert(FID.
isValid() &&
"Expected valid file ID");
2026 if (
auto *M = SuggestedModule.
getModule()) {
2034 assert(!CurLexerSubmodule &&
"should not have marked this as a module yet");
2035 CurLexerSubmodule = M;
2051 void Preprocessor::HandleIncludeNextDirective(
SourceLocation HashLoc,
2052 Token &IncludeNextTok) {
2053 Diag(IncludeNextTok, diag::ext_pp_include_next_directive);
2059 const FileEntry *LookupFromFile =
nullptr;
2066 Diag(IncludeNextTok, diag::pp_include_next_in_primary);
2067 }
else if (CurLexerSubmodule) {
2070 assert(CurPPLexer &&
"#include_next directive in macro?");
2071 LookupFromFile = CurPPLexer->getFileEntry();
2073 }
else if (!Lookup) {
2074 Diag(IncludeNextTok, diag::pp_include_next_absolute_path);
2080 return HandleIncludeDirective(HashLoc, IncludeNextTok, Lookup,
2085 void Preprocessor::HandleMicrosoftImportDirective(
Token &Tok) {
2091 Diag(Tok, diag::err_pp_import_directive_ms );
2102 if (!LangOpts.ObjC1) {
2103 if (LangOpts.MSVCCompat)
2104 return HandleMicrosoftImportDirective(ImportTok);
2105 Diag(ImportTok, diag::ext_pp_import_directive);
2107 return HandleIncludeDirective(HashLoc, ImportTok,
nullptr,
nullptr,
true);
2114 void Preprocessor::HandleIncludeMacrosDirective(
SourceLocation HashLoc,
2115 Token &IncludeMacrosTok) {
2119 if (SourceMgr.getBufferName(Loc) !=
"<built-in>") {
2121 diag::pp_include_macros_out_of_predefines);
2128 HandleIncludeDirective(HashLoc, IncludeMacrosTok);
2133 assert(TmpTok.
isNot(
tok::eof) &&
"Didn't find end of -imacros!");
2134 }
while (TmpTok.
isNot(tok::hashhash));
2145 bool Preprocessor::ReadMacroParameterList(
MacroInfo *MI,
Token &Tok) {
2153 if (Parameters.empty())
2156 Diag(Tok, diag::err_pp_expected_ident_in_arg_list);
2160 Diag(Tok, LangOpts.CPlusPlus11 ?
2161 diag::warn_cxx98_compat_variadic_macro :
2162 diag::ext_variadic_macro);
2165 if (LangOpts.OpenCL) {
2166 Diag(Tok, diag::err_pp_opencl_variadic_macros);
2172 if (Tok.
isNot(tok::r_paren)) {
2173 Diag(Tok, diag::err_pp_missing_rparen_in_macro_def);
2177 Parameters.push_back(Ident__VA_ARGS__);
2182 Diag(Tok, diag::err_pp_missing_rparen_in_macro_def);
2190 Diag(Tok, diag::err_pp_invalid_tok_in_arg_list);
2196 if (std::find(Parameters.begin(), Parameters.end(), II) !=
2198 Diag(Tok, diag::err_pp_duplicate_name_in_arg_list) << II;
2203 Parameters.push_back(II);
2210 Diag(Tok, diag::err_pp_expected_comma_in_arg_list);
2219 Diag(Tok, diag::ext_named_variadic_macro);
2223 if (Tok.
isNot(tok::r_paren)) {
2224 Diag(Tok, diag::err_pp_missing_rparen_in_macro_def);
2252 if (!II->isKeyword(LOptions))
2254 StringRef ValueText = II->getName();
2255 StringRef TrimmedValue = ValueText;
2256 if (!ValueText.startswith(
"__")) {
2257 if (ValueText.startswith(
"_"))
2258 TrimmedValue = TrimmedValue.drop_front(1);
2262 TrimmedValue = TrimmedValue.drop_front(2);
2263 if (TrimmedValue.endswith(
"__"))
2264 TrimmedValue = TrimmedValue.drop_back(2);
2266 return TrimmedValue.equals(MacroText);
2273 return MacroName.
isOneOf(tok::kw_extern, tok::kw_inline, tok::kw_static,
2286 MacroInfo *Preprocessor::ReadOptionalMacroParameterListAndBody(
2287 const Token &MacroNameTok,
const bool ImmediatelyAfterHeaderGuard) {
2289 Token LastTok = MacroNameTok;
2303 if (Tok.is(tok::eod)) {
2304 if (ImmediatelyAfterHeaderGuard) {
2310 }
else if (Tok.hasLeadingSpace()) {
2314 }
else if (Tok.is(tok::l_paren)) {
2317 if (ReadMacroParameterList(MI, LastTok)) {
2319 if (CurPPLexer->ParsingPreprocessorDirective)
2335 }
else if (LangOpts.C99 || LangOpts.CPlusPlus11) {
2338 Diag(Tok, diag::ext_c99_whitespace_required_after_macro_name);
2347 if (Tok.is(tok::at))
2349 else if (Tok.is(tok::unknown)) {
2356 Diag(Tok, diag::ext_missing_whitespace_after_macro_name);
2358 Diag(Tok, diag::warn_missing_whitespace_after_macro_name);
2361 if (!Tok.is(tok::eod))
2367 while (Tok.isNot(tok::eod)) {
2380 while (Tok.isNot(tok::eod)) {
2383 if (!Tok.isOneOf(tok::hash, tok::hashat, tok::hashhash)) {
2389 Diag(Tok, diag::err_pp_vaopt_nested_use);
2394 if (Tok.isNot(tok::l_paren)) {
2395 Diag(Tok, diag::err_pp_missing_lparen_in_vaopt_use);
2401 if (Tok.is(tok::hashhash)) {
2402 Diag(Tok, diag::err_vaopt_paste_at_start);
2407 if (Tok.is(tok::r_paren)) {
2410 assert(NumTokens >= 3 &&
"Must have seen at least __VA_OPT__( " 2411 "and a subsequent tok::r_paren");
2413 Diag(Tok, diag::err_vaopt_paste_at_end);
2417 }
else if (Tok.is(tok::l_paren)) {
2430 Tok.setKind(tok::unknown);
2438 if (Tok.is(tok::hashhash)) {
2446 if (Tok.is(tok::eod)) {
2452 if (NumTokens && Tok.getIdentifierInfo() == Ident__VA_ARGS__ &&
2467 (Tok.getIdentifierInfo() ==
nullptr ||
2474 if (
getLangOpts().AsmPreprocessor && Tok.isNot(tok::eod)) {
2475 LastTok.
setKind(tok::unknown);
2479 Diag(Tok, diag::err_pp_stringize_not_parameter)
2480 << LastTok.
is(tok::hashat);
2500 assert(Tok.is(tok::eod) &&
"Must be at End Of preprocessing Directive");
2501 Diag(Tok, diag::err_pp_expected_after)
2502 << LastTok.
getKind() << tok::r_paren;
2512 void Preprocessor::HandleDefineDirective(
2513 Token &DefineTok,
const bool ImmediatelyAfterHeaderGuard) {
2517 bool MacroShadowsKeyword;
2518 ReadMacroName(MacroNameTok,
MU_Define, &MacroShadowsKeyword);
2521 if (MacroNameTok.
is(tok::eod))
2526 if (CurLexer) CurLexer->SetCommentRetentionState(KeepMacroComments);
2528 MacroInfo *
const MI = ReadOptionalMacroParameterListAndBody(
2529 MacroNameTok, ImmediatelyAfterHeaderGuard);
2533 if (MacroShadowsKeyword &&
2535 Diag(MacroNameTok, diag::warn_pp_macro_hides_keyword);
2540 if (NumTokens != 0) {
2559 auto isObjCProtectedMacro = [](
const IdentifierInfo *II) ->
bool {
2560 return II->isStr(
"__strong") ||
2561 II->isStr(
"__weak") ||
2562 II->isStr(
"__unsafe_unretained") ||
2563 II->isStr(
"__autoreleasing");
2566 SourceMgr.getFileID(OtherMI->getDefinitionLoc())
2571 !SourceMgr.isInSystemHeader(DefineTok.
getLocation())) &&
2573 LangOpts.MicrosoftExt)) {
2576 assert(!OtherMI->isWarnIfUnused());
2584 !SourceMgr.isInSystemHeader(DefineTok.
getLocation())) {
2585 if (!OtherMI->isUsed() && OtherMI->isWarnIfUnused())
2586 Diag(OtherMI->getDefinitionLoc(), diag::pp_macro_not_used);
2590 if (OtherMI->isBuiltinMacro())
2591 Diag(MacroNameTok, diag::ext_pp_redef_builtin_macro);
2594 else if (!OtherMI->isAllowRedefinitionsWithoutWarning() &&
2595 !MI->
isIdenticalTo(*OtherMI, *
this, LangOpts.MicrosoftExt)) {
2598 Diag(OtherMI->getDefinitionLoc(), diag::note_previous_definition);
2601 if (OtherMI->isWarnIfUnused())
2602 WarnUnusedMacroLocs.erase(OtherMI->getDefinitionLoc());
2619 Callbacks->MacroDefined(MacroNameTok, MD);
2624 void Preprocessor::HandleUndefDirective() {
2628 ReadMacroName(MacroNameTok,
MU_Undef);
2631 if (MacroNameTok.
is(tok::eod))
2643 if (
const MacroInfo *MI = MD.getMacroInfo()) {
2650 Undef = AllocateUndefMacroDirective(MacroNameTok.
getLocation());
2656 Callbacks->MacroUndefined(MacroNameTok, MD, Undef);
2671 void Preprocessor::HandleIfdefDirective(
Token &
Result,
2672 const Token &HashToken,
2674 bool ReadAnyTokensBeforeDirective) {
2679 ReadMacroName(MacroNameTok);
2682 if (MacroNameTok.
is(tok::eod)) {
2685 SkipExcludedConditionalBlock(HashToken.
getLocation(),
2698 if (CurPPLexer->getConditionalStackDepth() == 0) {
2703 if (!ReadAnyTokensBeforeDirective && !MI) {
2704 assert(isIfndef &&
"#ifdef shouldn't reach here");
2705 CurPPLexer->MIOpt.EnterTopLevelIfndef(MII, MacroNameTok.
getLocation());
2707 CurPPLexer->MIOpt.EnterTopLevelConditional();
2716 Callbacks->Ifndef(DirectiveTok.
getLocation(), MacroNameTok, MD);
2718 Callbacks->Ifdef(DirectiveTok.
getLocation(), MacroNameTok, MD);
2722 if (PPOpts->SingleFileParseMode && !MI) {
2725 CurPPLexer->pushConditionalLevel(DirectiveTok.
getLocation(),
2728 }
else if (!MI == isIfndef) {
2730 CurPPLexer->pushConditionalLevel(DirectiveTok.
getLocation(),
2735 SkipExcludedConditionalBlock(HashToken.
getLocation(),
2744 void Preprocessor::HandleIfDirective(
Token &IfToken,
2745 const Token &HashToken,
2746 bool ReadAnyTokensBeforeDirective) {
2751 const SourceLocation ConditionalBegin = CurPPLexer->getSourceLocation();
2752 const DirectiveEvalResult DER = EvaluateDirectiveExpression(IfNDefMacro);
2753 const bool ConditionalTrue = DER.Conditional;
2754 const SourceLocation ConditionalEnd = CurPPLexer->getSourceLocation();
2758 if (CurPPLexer->getConditionalStackDepth() == 0) {
2759 if (!ReadAnyTokensBeforeDirective && IfNDefMacro && ConditionalTrue)
2761 CurPPLexer->MIOpt.EnterTopLevelIfndef(IfNDefMacro, IfToken.
getLocation());
2763 CurPPLexer->MIOpt.EnterTopLevelConditional();
2772 if (PPOpts->SingleFileParseMode && DER.IncludedUndefinedIds) {
2775 CurPPLexer->pushConditionalLevel(IfToken.
getLocation(),
false,
2777 }
else if (ConditionalTrue) {
2779 CurPPLexer->pushConditionalLevel(IfToken.
getLocation(),
false,
2791 void Preprocessor::HandleEndifDirective(
Token &EndifToken) {
2798 if (CurPPLexer->popConditionalLevel(CondInfo)) {
2800 Diag(EndifToken, diag::err_pp_endif_without_if);
2805 if (CurPPLexer->getConditionalStackDepth() == 0)
2806 CurPPLexer->MIOpt.ExitTopLevelConditional();
2808 assert(!CondInfo.
WasSkipping && !CurPPLexer->LexingRawMode &&
2809 "This code should only be reachable in the non-skipping case!");
2817 void Preprocessor::HandleElseDirective(
Token &Result,
const Token &HashToken) {
2824 if (CurPPLexer->popConditionalLevel(CI)) {
2825 Diag(Result, diag::pp_err_else_without_if);
2830 if (CurPPLexer->getConditionalStackDepth() == 0)
2831 CurPPLexer->MIOpt.EnterTopLevelConditional();
2834 if (CI.
FoundElse)
Diag(Result, diag::pp_err_else_after_else);
2842 CurPPLexer->pushConditionalLevel(CI.
IfLoc,
false,
2855 void Preprocessor::HandleElifDirective(
Token &ElifToken,
2856 const Token &HashToken) {
2862 const SourceLocation ConditionalBegin = CurPPLexer->getSourceLocation();
2864 const SourceLocation ConditionalEnd = CurPPLexer->getSourceLocation();
2867 if (CurPPLexer->popConditionalLevel(CI)) {
2868 Diag(ElifToken, diag::pp_err_elif_without_if);
2873 if (CurPPLexer->getConditionalStackDepth() == 0)
2874 CurPPLexer->MIOpt.EnterTopLevelConditional();
2877 if (CI.
FoundElse)
Diag(ElifToken, diag::pp_err_elif_after_else);
2887 CurPPLexer->pushConditionalLevel(ElifToken.
getLocation(),
false,
2893 SkipExcludedConditionalBlock(
StringRef tryGetRealPathName() const
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...
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 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.
VerifyDiagnosticConsumer::Directive Directive
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.
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.
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.
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::pair< std::string, bool > Requirement
An individual requirement: a feature name and a flag indicating the required state of that feature...
bool isC99Varargs() const
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...
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...
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.
char __ovld __cnfn max(char x, char y)
Returns y if x < y, otherwise it returns x.
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.
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.
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...