26 #include "llvm/ADT/APInt.h"
27 #include "llvm/ADT/STLExtras.h"
28 #include "llvm/ADT/StringExtras.h"
29 #include "llvm/ADT/StringSwitch.h"
30 #include "llvm/ADT/iterator_range.h"
31 #include "llvm/Support/ErrorHandling.h"
32 #include "llvm/Support/Path.h"
33 #include "llvm/Support/SaveAndRestore.h"
35 using namespace clang;
41 MacroInfo *Preprocessor::AllocateMacroInfo() {
42 MacroInfoChain *MIChain = BP.Allocate<MacroInfoChain>();
43 MIChain->Next = MIChainHead;
44 MIChainHead = MIChain;
55 unsigned SubModuleID) {
56 static_assert(llvm::AlignOf<MacroInfo>::Alignment >=
sizeof(SubModuleID),
57 "alignment for MacroInfo is less than the ID");
58 DeserializedMacroInfoChain *MIChain =
59 BP.Allocate<DeserializedMacroInfoChain>();
60 MIChain->Next = DeserialMIChainHead;
61 DeserialMIChainHead = MIChain;
65 MI->FromASTFile =
true;
66 MI->setOwningModuleID(SubModuleID);
76 Preprocessor::AllocateUndefMacroDirective(
SourceLocation UndefLoc) {
92 assert(Tmp.
isNot(
tok::eof) &&
"EOF seen while discarding directive tokens");
93 }
while (Tmp.
isNot(tok::eod));
110 if (Text.size() >= 2 && Text[0] ==
'_' &&
116 if (Lang.CPlusPlus) {
117 if (Text.find(
"__") != StringRef::npos)
130 if (Lang.CPlusPlus11 && (Text.equals(
"override") || Text.equals(
"final")))
157 static const size_t MaxStdHeaderNameLen = 18u;
158 if (Include.size() > MaxStdHeaderNameLen)
163 for (
char &Ch : LowerInclude) {
165 if (static_cast<unsigned char>(Ch) > 0x7f)
168 if (Ch >=
'A' && Ch <=
'Z')
171 else if (::llvm::sys::path::is_separator(Ch))
176 return llvm::StringSwitch<bool>(LowerInclude)
178 .Cases(
"assert.h",
"complex.h",
"ctype.h",
"errno.h",
"fenv.h",
true)
179 .Cases(
"float.h",
"inttypes.h",
"iso646.h",
"limits.h",
"locale.h",
true)
180 .Cases(
"math.h",
"setjmp.h",
"signal.h",
"stdalign.h",
"stdarg.h",
true)
181 .Cases(
"stdatomic.h",
"stdbool.h",
"stddef.h",
"stdint.h",
"stdio.h",
true)
182 .Cases(
"stdlib.h",
"stdnoreturn.h",
"string.h",
"tgmath.h",
"threads.h",
true)
183 .Cases(
"time.h",
"uchar.h",
"wchar.h",
"wctype.h",
true)
186 .Cases(
"cassert",
"ccomplex",
"cctype",
"cerrno",
"cfenv",
true)
187 .Cases(
"cfloat",
"cinttypes",
"ciso646",
"climits",
"clocale",
true)
188 .Cases(
"cmath",
"csetjmp",
"csignal",
"cstdalign",
"cstdarg",
true)
189 .Cases(
"cstdbool",
"cstddef",
"cstdint",
"cstdio",
"cstdlib",
true)
190 .Cases(
"cstring",
"ctgmath",
"ctime",
"cuchar",
"cwchar",
true)
191 .Case(
"cwctype",
true)
194 .Cases(
"algorithm",
"fstream",
"list",
"regex",
"thread",
true)
195 .Cases(
"array",
"functional",
"locale",
"scoped_allocator",
"tuple",
true)
196 .Cases(
"atomic",
"future",
"map",
"set",
"type_traits",
true)
197 .Cases(
"bitset",
"initializer_list",
"memory",
"shared_mutex",
"typeindex",
true)
198 .Cases(
"chrono",
"iomanip",
"mutex",
"sstream",
"typeinfo",
true)
199 .Cases(
"codecvt",
"ios",
"new",
"stack",
"unordered_map",
true)
200 .Cases(
"complex",
"iosfwd",
"numeric",
"stdexcept",
"unordered_set",
true)
201 .Cases(
"condition_variable",
"iostream",
"ostream",
"streambuf",
"utility",
true)
202 .Cases(
"deque",
"istream",
"queue",
"string",
"valarray",
true)
203 .Cases(
"exception",
"iterator",
"random",
"strstream",
"vector",
true)
204 .Cases(
"forward_list",
"limits",
"ratio",
"system_error",
true)
207 .Cases(
"aio.h",
"arpa/inet.h",
"cpio.h",
"dirent.h",
"dlfcn.h",
true)
208 .Cases(
"fcntl.h",
"fmtmsg.h",
"fnmatch.h",
"ftw.h",
"glob.h",
true)
209 .Cases(
"grp.h",
"iconv.h",
"langinfo.h",
"libgen.h",
"monetary.h",
true)
210 .Cases(
"mqueue.h",
"ndbm.h",
"net/if.h",
"netdb.h",
"netinet/in.h",
true)
211 .Cases(
"netinet/tcp.h",
"nl_types.h",
"poll.h",
"pthread.h",
"pwd.h",
true)
212 .Cases(
"regex.h",
"sched.h",
"search.h",
"semaphore.h",
"spawn.h",
true)
213 .Cases(
"strings.h",
"stropts.h",
"sys/ipc.h",
"sys/mman.h",
"sys/msg.h",
true)
214 .Cases(
"sys/resource.h",
"sys/select.h",
"sys/sem.h",
"sys/shm.h",
"sys/socket.h",
true)
215 .Cases(
"sys/stat.h",
"sys/statvfs.h",
"sys/time.h",
"sys/times.h",
"sys/types.h",
true)
216 .Cases(
"sys/uio.h",
"sys/un.h",
"sys/utsname.h",
"sys/wait.h",
"syslog.h",
true)
217 .Cases(
"tar.h",
"termios.h",
"trace.h",
"ulimit.h",
true)
218 .Cases(
"unistd.h",
"utime.h",
"utmpx.h",
"wordexp.h",
true)
225 if (MacroNameTok.
is(tok::eod))
226 return Diag(MacroNameTok, diag::err_pp_missing_macro_name);
230 bool Invalid =
false;
231 std::string Spelling =
getSpelling(MacroNameTok, &Invalid);
233 return Diag(MacroNameTok, diag::err_pp_macro_not_identifier);
237 return Diag(MacroNameTok, diag::err_pp_macro_not_identifier);
242 ? diag::ext_pp_operator_used_as_macro_name
243 : diag::err_pp_operator_used_as_macro_name)
244 << II << MacroNameTok.
getKind();
253 return Diag(MacroNameTok, diag::err_defined_macro_name);
261 Diag(MacroNameTok, diag::ext_pp_undef_builtin_macro);
271 (strcmp(SourceMgr.
getBufferName(MacroNameLoc),
"<built-in>") != 0)) {
286 Diag(MacroNameTok, diag::warn_pp_macro_is_reserved_id);
302 void Preprocessor::ReadMacroName(
Token &MacroNameTok,
MacroUse isDefineUndef,
307 if (MacroNameTok.
is(tok::code_completion)) {
319 if (MacroNameTok.
isNot(tok::eod)) {
320 MacroNameTok.
setKind(tok::eod);
341 while (Tmp.
is(tok::comment))
344 if (Tmp.
isNot(tok::eod)) {
350 if ((LangOpts.GNUMode || LangOpts.C99 || LangOpts.CPlusPlus) &&
353 Diag(Tmp, diag::ext_pp_extra_tokens_at_eol) << DirType << Hint;
366 void Preprocessor::SkipExcludedConditionalBlock(
SourceLocation IfTokenLoc,
367 bool FoundNonSkipPortion,
371 assert(!CurTokenLexer && CurPPLexer &&
"Lexing a macro, not a file?");
374 FoundNonSkipPortion, FoundElse);
377 PTHSkipExcludedConditionalBlock();
388 if (Tok.
is(tok::code_completion)) {
400 if (CurLexer->getFileLoc() != CodeCompletionFileLoc)
402 diag::err_pp_unterminated_conditional);
418 if (CurLexer) CurLexer->SetKeepWhitespaceMode(
false);
426 if (Tok.
isNot(tok::raw_identifier)) {
429 if (CurLexer) CurLexer->resetExtendedTokenMode();
440 char FirstChar = RI[0];
441 if (FirstChar >=
'a' && FirstChar <=
'z' &&
442 FirstChar !=
'i' && FirstChar !=
'e') {
445 if (CurLexer) CurLexer->resetExtendedTokenMode();
452 char DirectiveBuf[20];
458 unsigned IdLen = DirectiveStr.size();
462 if (CurLexer) CurLexer->resetExtendedTokenMode();
465 memcpy(DirectiveBuf, &DirectiveStr[0], IdLen);
466 Directive = StringRef(DirectiveBuf, IdLen);
469 if (Directive.startswith(
"if")) {
470 StringRef Sub = Directive.substr(2);
481 }
else if (Directive[0] ==
'e') {
482 StringRef Sub = Directive.substr(1);
488 assert(!InCond &&
"Can't be skipping if not in a conditional!");
503 }
else if (Sub ==
"lse") {
510 if (CondInfo.
FoundElse)
Diag(Tok, diag::pp_err_else_after_else);
530 }
else if (Sub ==
"lif") {
534 if (CondInfo.
FoundElse)
Diag(Tok, diag::pp_err_elif_after_else);
544 assert(CurPPLexer->
LexingRawMode &&
"We have to be skipping here!");
547 const bool CondValue = EvaluateDirectiveExpression(IfNDefMacro);
566 if (CurLexer) CurLexer->resetExtendedTokenMode();
580 void Preprocessor::PTHSkipExcludedConditionalBlock() {
583 assert(CurPTHLexer->LexingRawMode ==
false);
586 if (CurPTHLexer->SkipBlock()) {
590 bool InCond = CurPTHLexer->popConditionalLevel(CondInfo);
592 assert(!InCond &&
"Can't be skipping if not in a conditional!");
605 if (K == tok::pp_else) {
618 CurPTHLexer->ParsingPreprocessorDirective =
true;
620 CurPTHLexer->ParsingPreprocessorDirective =
false;
629 assert(K == tok::pp_elif);
634 Diag(Tok, diag::pp_err_elif_after_else);
643 CurPTHLexer->ParsingPreprocessorDirective =
true;
644 bool ShouldEnter = EvaluateDirectiveExpression(IfNDefMacro);
645 CurPTHLexer->ParsingPreprocessorDirective =
false;
707 bool InTextualHeader =
false;
709 if (!Header.getModule()->isSubModuleOf(TopM))
716 if (Header.isAccessibleFrom(IncM))
726 InTextualHeader =
true;
729 if (!InTextualHeader)
750 bool RequestingModuleIsModuleInterface = !SourceMgr.
isInMainFile(FilenameLoc);
756 bool BuildSystemModule =
false;
757 if (!FromDir && !FromFile) {
775 Includers.push_back(std::make_pair(
nullptr, MainFileDir));
777 }
else if ((FileEnt =
779 Includers.push_back(std::make_pair(FileEnt, FileMgr.
getDirectory(
".")));
781 Includers.push_back(std::make_pair(FileEnt, FileEnt->
getDir()));
787 if (LangOpts.MSVCCompat && !isAngled) {
788 for (
unsigned i = 0, e = IncludeMacroStack.size(); i != e; ++i) {
789 IncludeStackInfo &ISEntry = IncludeMacroStack[e - i - 1];
790 if (IsFileLexer(ISEntry))
791 if ((FileEnt = ISEntry.ThePPLexer->getFileEntry()))
792 Includers.push_back(std::make_pair(FileEnt, FileEnt->
getDir()));
797 CurDir = CurDirLookup;
805 Filename, FilenameLoc, isAngled, TmpFromDir, TmpCurDir,
806 Includers, SearchPath, RelativePath, RequestingModule,
807 SuggestedModule, SkipCache)) {
809 TmpFromDir = TmpCurDir;
811 if (FE == FromFile) {
813 FromDir = TmpFromDir;
822 Filename, FilenameLoc, isAngled, FromDir, CurDir, Includers, SearchPath,
823 RelativePath, RequestingModule, SuggestedModule, SkipCache,
826 if (SuggestedModule && !LangOpts.AsmPreprocessor)
828 RequestingModule, RequestingModuleIsModuleInterface, FilenameLoc,
840 SearchPath, RelativePath,
843 if (SuggestedModule && !LangOpts.AsmPreprocessor)
845 RequestingModule, RequestingModuleIsModuleInterface, FilenameLoc,
852 for (
unsigned i = 0, e = IncludeMacroStack.size(); i != e; ++i) {
853 IncludeStackInfo &ISEntry = IncludeMacroStack[e-i-1];
854 if (IsFileLexer(ISEntry)) {
855 if ((CurFileEnt = ISEntry.ThePPLexer->getFileEntry())) {
857 Filename, CurFileEnt, SearchPath, RelativePath,
858 RequestingModule, SuggestedModule))) {
859 if (SuggestedModule && !LangOpts.AsmPreprocessor)
861 RequestingModule, RequestingModuleIsModuleInterface,
862 FilenameLoc, Filename, FE);
880 : PP(pp), save(pp->DisableMacroExpansion) {
881 if (pp->MacroExpansionInDirectivesOverride)
882 pp->DisableMacroExpansion =
false;
886 PP->DisableMacroExpansion = save;
905 if (CurLexer) CurLexer->SetKeepWhitespaceMode(
false);
907 bool ImmediatelyAfterTopLevelIfndef =
935 switch (II->getPPKeywordID()) {
936 case tok::pp_include:
938 case tok::pp_include_next:
939 case tok::pp___include_macros:
941 Diag(Result, diag::err_embedded_directive) << II->getName();
948 Diag(Result, diag::ext_embedded_directive);
958 case tok::code_completion:
964 case tok::numeric_constant:
967 return HandleDigitDirective(Result);
977 return HandleIfDirective(Result, ReadAnyTokensBeforeDirective);
979 return HandleIfdefDirective(Result,
false,
true);
981 return HandleIfdefDirective(Result,
true, ReadAnyTokensBeforeDirective);
983 return HandleElifDirective(Result);
985 return HandleElseDirective(Result);
987 return HandleEndifDirective(Result);
990 case tok::pp_include:
993 case tok::pp___include_macros:
999 return HandleDefineDirective(Result, ImmediatelyAfterTopLevelIfndef);
1001 return HandleUndefDirective(Result);
1005 return HandleLineDirective(Result);
1009 return HandleUserDiagnosticDirective(Result,
false);
1012 case tok::pp_pragma:
1016 case tok::pp_import:
1018 case tok::pp_include_next:
1021 case tok::pp_warning:
1022 Diag(Result, diag::ext_pp_warning_directive);
1023 return HandleUserDiagnosticDirective(Result,
true);
1025 return HandleIdentSCCSDirective(Result);
1027 return HandleIdentSCCSDirective(Result);
1028 case tok::pp_assert:
1031 case tok::pp_unassert:
1035 case tok::pp___public_macro:
1037 return HandleMacroPublicDirective(Result);
1040 case tok::pp___private_macro:
1042 return HandleMacroPrivateDirective(Result);
1053 auto Toks = llvm::make_unique<Token[]>(2);
1055 Toks[0] = SavedHash;
1060 if (Result.
is(tok::hashhash))
1061 Toks[1].setKind(tok::unknown);
1066 EnterTokenStream(std::move(Toks), 2,
false);
1071 Diag(Result, diag::err_pp_invalid_directive);
1083 bool IsGNULineDirective=
false) {
1084 if (DigitTok.
isNot(tok::numeric_constant)) {
1085 PP.
Diag(DigitTok, DiagID);
1087 if (DigitTok.
isNot(tok::eod))
1093 IntegerBuffer.resize(DigitTok.
getLength());
1094 const char *DigitTokBegin = &IntegerBuffer[0];
1095 bool Invalid =
false;
1096 unsigned ActualLength = PP.
getSpelling(DigitTok, DigitTokBegin, &Invalid);
1104 for (
unsigned i = 0; i != ActualLength; ++i) {
1107 if (DigitTokBegin[i] ==
'\'')
1110 if (!
isDigit(DigitTokBegin[i])) {
1112 diag::err_pp_line_digit_sequence) << IsGNULineDirective;
1117 unsigned NextVal = Val*10+(DigitTokBegin[i]-
'0');
1118 if (NextVal < Val) {
1119 PP.
Diag(DigitTok, DiagID);
1126 if (DigitTokBegin[0] ==
'0' && Val)
1128 << IsGNULineDirective;
1140 void Preprocessor::HandleLineDirective(
Token &Tok) {
1148 if (
GetLineValue(DigitTok, LineNo, diag::err_pp_line_requires_integer,*
this))
1152 Diag(DigitTok, diag::ext_pp_line_zero);
1156 unsigned LineLimit = 32768U;
1157 if (LangOpts.C99 || LangOpts.CPlusPlus11)
1158 LineLimit = 2147483648U;
1159 if (LineNo >= LineLimit)
1160 Diag(DigitTok, diag::ext_pp_line_too_big) << LineLimit;
1161 else if (LangOpts.CPlusPlus11 && LineNo >= 32768U)
1162 Diag(DigitTok, diag::warn_cxx98_compat_pp_line_too_big);
1164 int FilenameID = -1;
1170 if (StrTok.
is(tok::eod))
1172 else if (StrTok.
isNot(tok::string_literal)) {
1173 Diag(StrTok, diag::err_pp_line_invalid_filename);
1176 Diag(StrTok, diag::err_invalid_string_udl);
1181 assert(Literal.isAscii() &&
"Didn't allow wide strings in");
1182 if (Literal.hadError)
1184 if (Literal.Pascal) {
1185 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1206 bool &IsSystemHeader,
bool &IsExternCHeader,
1211 if (FlagTok.
is(tok::eod))
return false;
1212 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag, PP))
1219 if (FlagTok.
is(tok::eod))
return false;
1220 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag,PP))
1222 }
else if (FlagVal == 2) {
1239 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_pop);
1245 if (FlagTok.
is(tok::eod))
return false;
1246 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag,PP))
1252 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1257 IsSystemHeader =
true;
1260 if (FlagTok.
is(tok::eod))
return false;
1261 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag, PP))
1266 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1271 IsExternCHeader =
true;
1274 if (FlagTok.
is(tok::eod))
return false;
1277 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1289 void Preprocessor::HandleDigitDirective(
Token &DigitTok) {
1293 if (
GetLineValue(DigitTok, LineNo, diag::err_pp_linemarker_requires_integer,
1300 bool IsFileEntry =
false, IsFileExit =
false;
1301 bool IsSystemHeader =
false, IsExternCHeader =
false;
1302 int FilenameID = -1;
1306 if (StrTok.
is(tok::eod))
1308 else if (StrTok.
isNot(tok::string_literal)) {
1309 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1312 Diag(StrTok, diag::err_invalid_string_udl);
1317 assert(Literal.isAscii() &&
"Didn't allow wide strings in");
1318 if (Literal.hadError)
1320 if (Literal.Pascal) {
1321 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1328 IsSystemHeader, IsExternCHeader, *
this))
1334 IsFileEntry, IsFileExit,
1335 IsSystemHeader, IsExternCHeader);
1344 else if (IsFileExit)
1347 if (IsExternCHeader)
1349 else if (IsSystemHeader)
1358 void Preprocessor::HandleUserDiagnosticDirective(
Token &Tok,
1362 return CurPTHLexer->DiscardToEndOfLine();
1370 CurLexer->ReadToEndOfLine(&Message);
1374 StringRef Msg = StringRef(Message).ltrim(
' ');
1377 Diag(Tok, diag::pp_hash_warning) << Msg;
1379 Diag(Tok, diag::err_pp_hash_error) << Msg;
1384 void Preprocessor::HandleIdentSCCSDirective(
Token &Tok) {
1386 Diag(Tok, diag::ext_pp_ident_directive);
1393 if (StrTok.
isNot(tok::string_literal) &&
1394 StrTok.
isNot(tok::wide_string_literal)) {
1395 Diag(StrTok, diag::err_pp_malformed_ident);
1396 if (StrTok.
isNot(tok::eod))
1402 Diag(StrTok, diag::err_invalid_string_udl);
1418 void Preprocessor::HandleMacroPublicDirective(
Token &Tok) {
1420 ReadMacroName(MacroNameTok,
MU_Undef);
1423 if (MacroNameTok.
is(tok::eod))
1435 Diag(MacroNameTok, diag::err_pp_visibility_non_macro) << II;
1445 void Preprocessor::HandleMacroPrivateDirective(
Token &Tok) {
1447 ReadMacroName(MacroNameTok,
MU_Undef);
1450 if (MacroNameTok.
is(tok::eod))
1462 Diag(MacroNameTok, diag::err_pp_visibility_non_macro) << II;
1484 assert(!Buffer.empty() &&
"Can't have tokens with empty spellings!");
1488 if (Buffer[0] ==
'<') {
1489 if (Buffer.back() !=
'>') {
1490 Diag(Loc, diag::err_pp_expects_filename);
1491 Buffer = StringRef();
1495 }
else if (Buffer[0] ==
'"') {
1496 if (Buffer.back() !=
'"') {
1497 Diag(Loc, diag::err_pp_expects_filename);
1498 Buffer = StringRef();
1503 Diag(Loc, diag::err_pp_expects_filename);
1504 Buffer = StringRef();
1509 if (Buffer.size() <= 2) {
1510 Diag(Loc, diag::err_pp_empty_filename);
1511 Buffer = StringRef();
1516 Buffer = Buffer.substr(1, Buffer.size()-2);
1538 while (CurTok.
isNot(tok::eod)) {
1542 if (CurTok.
is(tok::code_completion)) {
1551 FilenameBuffer.push_back(
' ');
1554 unsigned PreAppendSize = FilenameBuffer.size();
1555 FilenameBuffer.resize(PreAppendSize+CurTok.
getLength());
1557 const char *BufPtr = &FilenameBuffer[PreAppendSize];
1561 if (BufPtr != &FilenameBuffer[PreAppendSize])
1562 memcpy(&FilenameBuffer[PreAppendSize], BufPtr, ActualLen);
1566 FilenameBuffer.resize(PreAppendSize+ActualLen);
1569 if (CurTok.
is(tok::greater))
1587 auto Tok = llvm::make_unique<Token[]>(1);
1593 PP.EnterTokenStream(std::move(Tok), 1,
true);
1600 ArrayRef<std::pair<IdentifierInfo *, SourceLocation>> Path,
1602 assert(PP.
getLangOpts().ObjC2 &&
"no import syntax available");
1605 for (
unsigned I = 0, N = Path.size();
I != N; ++
I) {
1608 PathString += Path[
I].first->getName();
1610 int IncludeKind = 0;
1613 case tok::pp_include:
1617 case tok::pp_import:
1621 case tok::pp_include_next:
1625 case tok::pp___include_macros:
1630 llvm_unreachable(
"unknown include directive kind");
1635 PP.
Diag(HashLoc, diag::warn_auto_module_import)
1636 << IncludeKind << PathString
1638 (
"@import " + PathString +
";").str());
1645 StringRef RealPathName) {
1646 auto RealPathComponentIter = llvm::sys::path::rbegin(RealPathName);
1647 auto RealPathComponentEnd = llvm::sys::path::rend(RealPathName);
1649 bool SuggestReplacement =
false;
1652 for (
auto &Component : llvm::reverse(Components)) {
1653 if (
"." == Component) {
1654 }
else if (
".." == Component) {
1658 }
else if (RealPathComponentIter != RealPathComponentEnd) {
1659 if (Component != *RealPathComponentIter) {
1663 SuggestReplacement = RealPathComponentIter->equals_lower(Component);
1664 if (!SuggestReplacement)
1666 Component = *RealPathComponentIter;
1668 ++RealPathComponentIter;
1671 return SuggestReplacement;
1679 void Preprocessor::HandleIncludeDirective(
SourceLocation HashLoc,
1693 switch (FilenameTok.
getKind()) {
1698 case tok::angle_string_literal:
1699 case tok::string_literal:
1700 Filename =
getSpelling(FilenameTok, FilenameBuffer);
1708 FilenameBuffer.push_back(
'<');
1711 Filename = FilenameBuffer;
1722 StringRef OriginalFilename =
Filename;
1727 if (Filename.empty()) {
1739 if (IncludeMacroStack.size() == MaxAllowedIncludeStackDepth-1) {
1740 Diag(FilenameTok, diag::err_pp_include_too_deep);
1745 if (PragmaARCCFCodeAuditedLoc.
isValid()) {
1746 Diag(HashLoc, diag::err_pp_include_in_arc_cf_code_audited);
1747 Diag(PragmaARCCFCodeAuditedLoc, diag::note_pragma_entered_here);
1754 if (PragmaAssumeNonNullLoc.
isValid()) {
1755 Diag(HashLoc, diag::err_pp_include_in_assume_nonnull);
1756 Diag(PragmaAssumeNonNullLoc, diag::note_pragma_entered_here);
1767 if (!NewName.empty())
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,
1796 if (Callbacks->FileNotFound(Filename, RecoveryPath)) {
1805 LangOpts.MSVCCompat ? NormalizedPath.c_str() :
Filename, isAngled,
1806 LookupFrom, LookupFromFile, CurDir,
nullptr,
nullptr,
1807 &SuggestedModule,
true);
1812 if (!SuppressIncludeNotFoundError) {
1819 LangOpts.MSVCCompat ? NormalizedPath.c_str() :
Filename,
false,
1820 LookupFrom, LookupFromFile, CurDir,
1821 Callbacks ? &SearchPath :
nullptr,
1822 Callbacks ? &RelativePath :
nullptr,
1826 Diag(FilenameTok, diag::err_pp_file_not_found_not_fatal) <<
1834 Diag(FilenameTok, diag::err_pp_file_not_found) <<
Filename;
1842 bool ShouldEnter =
true;
1847 if (File && SuggestedModule &&
getLangOpts().Modules &&
1872 diag::note_implicit_top_level_module_import_here)
1884 std::reverse(Path.begin(), Path.end());
1898 assert((Imported ==
nullptr || Imported == SuggestedModule.
getModule()) &&
1899 "the imported module is different than the suggested one");
1902 ShouldEnter =
false;
1916 CurLexer->FormTokenWithChars(Result, CurLexer->BufferEnd,
tok::eof);
1917 CurLexer->cutOffLexing();
1919 assert(CurPTHLexer &&
"#include but no current lexer set!");
1920 CurPTHLexer->getEOF(Result);
1929 Callbacks->InclusionDirective(
1930 HashLoc, IncludeTok,
1931 LangOpts.MSVCCompat ? NormalizedPath.c_str() :
Filename, isAngled,
1932 FilenameRange, File, SearchPath, RelativePath,
1933 ShouldEnter ?
nullptr : SuggestedModule.
getModule());
1951 const bool CheckIncludePathPortability =
1952 File && !File->tryGetRealPathName().empty();
1954 if (CheckIncludePathPortability) {
1955 StringRef
Name = LangOpts.MSVCCompat ? NormalizedPath.str() :
Filename;
1956 StringRef RealPathName = File->tryGetRealPathName();
1962 Path.reserve(Name.size()+2);
1963 Path.push_back(isAngled ?
'<' :
'"');
1964 for (
auto Component : Components) {
1965 Path.append(Component);
1968 Path.size() <= Filename.size() ? Filename[Path.size()-1] :
1969 (isAngled ?
'>' :
'"'));
1975 diag::pp_nonportable_path : diag::pp_nonportable_system_path;
1987 ShouldEnter =
false;
1989 Callbacks->FileSkipped(*File, FilenameTok, FileCharacter);
1995 if (
auto *M = SuggestedModule.
getModule()) {
1999 tok::pp___include_macros)
2012 assert(FID.
isValid() &&
"Expected valid file ID");
2019 if (
auto *M = SuggestedModule.
getModule()) {
2020 assert(!CurSubmodule &&
"should not have marked this as a module yet");
2025 EnterSubmodule(M, HashLoc);
2037 void Preprocessor::HandleIncludeNextDirective(
SourceLocation HashLoc,
2038 Token &IncludeNextTok) {
2039 Diag(IncludeNextTok, diag::ext_pp_include_next_directive);
2045 const FileEntry *LookupFromFile =
nullptr;
2048 Diag(IncludeNextTok, diag::pp_include_next_in_primary);
2049 }
else if (CurSubmodule) {
2052 assert(CurPPLexer &&
"#include_next directive in macro?");
2055 }
else if (!Lookup) {
2056 Diag(IncludeNextTok, diag::pp_include_next_absolute_path);
2062 return HandleIncludeDirective(HashLoc, IncludeNextTok, Lookup,
2067 void Preprocessor::HandleMicrosoftImportDirective(
Token &Tok) {
2073 Diag(Tok, diag::err_pp_import_directive_ms );
2084 if (!LangOpts.ObjC1) {
2085 if (LangOpts.MSVCCompat)
2086 return HandleMicrosoftImportDirective(ImportTok);
2087 Diag(ImportTok, diag::ext_pp_import_directive);
2089 return HandleIncludeDirective(HashLoc, ImportTok,
nullptr,
nullptr,
true);
2096 void Preprocessor::HandleIncludeMacrosDirective(
SourceLocation HashLoc,
2097 Token &IncludeMacrosTok) {
2101 if (strcmp(SourceMgr.
getBufferName(Loc),
"<built-in>") != 0) {
2103 diag::pp_include_macros_out_of_predefines);
2110 HandleIncludeDirective(HashLoc, IncludeMacrosTok);
2115 assert(TmpTok.
isNot(
tok::eof) &&
"Didn't find end of -imacros!");
2116 }
while (TmpTok.
isNot(tok::hashhash));
2127 bool Preprocessor::ReadMacroDefinitionArgList(
MacroInfo *MI,
Token &Tok) {
2135 if (Arguments.empty())
2138 Diag(Tok, diag::err_pp_expected_ident_in_arg_list);
2142 Diag(Tok, LangOpts.CPlusPlus11 ?
2143 diag::warn_cxx98_compat_variadic_macro :
2144 diag::ext_variadic_macro);
2147 if (LangOpts.OpenCL) {
2148 Diag(Tok, diag::err_pp_opencl_variadic_macros);
2154 if (Tok.
isNot(tok::r_paren)) {
2155 Diag(Tok, diag::err_pp_missing_rparen_in_macro_def);
2159 Arguments.push_back(Ident__VA_ARGS__);
2164 Diag(Tok, diag::err_pp_missing_rparen_in_macro_def);
2172 Diag(Tok, diag::err_pp_invalid_tok_in_arg_list);
2178 if (std::find(Arguments.begin(), Arguments.end(), II) !=
2180 Diag(Tok, diag::err_pp_duplicate_name_in_arg_list) << II;
2185 Arguments.push_back(II);
2192 Diag(Tok, diag::err_pp_expected_comma_in_arg_list);
2201 Diag(Tok, diag::ext_named_variadic_macro);
2205 if (Tok.
isNot(tok::r_paren)) {
2206 Diag(Tok, diag::err_pp_missing_rparen_in_macro_def);
2236 StringRef ValueText = II->
getName();
2237 StringRef TrimmedValue = ValueText;
2238 if (!ValueText.startswith(
"__")) {
2239 if (ValueText.startswith(
"_"))
2240 TrimmedValue = TrimmedValue.drop_front(1);
2244 TrimmedValue = TrimmedValue.drop_front(2);
2245 if (TrimmedValue.endswith(
"__"))
2246 TrimmedValue = TrimmedValue.drop_back(2);
2248 return TrimmedValue.equals(MacroText);
2255 return MacroName.
isOneOf(tok::kw_extern, tok::kw_inline, tok::kw_static,
2262 void Preprocessor::HandleDefineDirective(
Token &DefineTok,
2263 bool ImmediatelyAfterHeaderGuard) {
2267 bool MacroShadowsKeyword;
2268 ReadMacroName(MacroNameTok,
MU_Define, &MacroShadowsKeyword);
2271 if (MacroNameTok.
is(tok::eod))
2274 Token LastTok = MacroNameTok;
2278 if (CurLexer) CurLexer->SetCommentRetentionState(KeepMacroComments);
2289 if (Tok.is(tok::eod)) {
2290 if (ImmediatelyAfterHeaderGuard) {
2296 }
else if (Tok.hasLeadingSpace()) {
2300 }
else if (Tok.is(tok::l_paren)) {
2303 if (ReadMacroDefinitionArgList(MI, LastTok)) {
2315 assert(Ident__VA_ARGS__->
isPoisoned() &&
"__VA_ARGS__ should be poisoned!");
2321 }
else if (LangOpts.C99 || LangOpts.CPlusPlus11) {
2324 Diag(Tok, diag::ext_c99_whitespace_required_after_macro_name);
2333 if (Tok.is(tok::at))
2335 else if (Tok.is(tok::unknown)) {
2342 Diag(Tok, diag::ext_missing_whitespace_after_macro_name);
2344 Diag(Tok, diag::warn_missing_whitespace_after_macro_name);
2347 if (!Tok.is(tok::eod))
2353 while (Tok.isNot(tok::eod)) {
2363 while (Tok.isNot(tok::eod)) {
2366 if (!Tok.isOneOf(tok::hash, tok::hashat, tok::hashhash)) {
2378 Tok.setKind(tok::unknown);
2386 if (Tok.is(tok::hashhash)) {
2394 if (Tok.is(tok::eod)) {
2400 if (NumTokens && Tok.getIdentifierInfo() == Ident__VA_ARGS__ &&
2413 if (Tok.getIdentifierInfo() ==
nullptr ||
2420 if (
getLangOpts().AsmPreprocessor && Tok.isNot(tok::eod)) {
2421 LastTok.
setKind(tok::unknown);
2425 Diag(Tok, diag::err_pp_stringize_not_parameter)
2426 << LastTok.
is(tok::hashat);
2444 if (MacroShadowsKeyword &&
2446 Diag(MacroNameTok, diag::warn_pp_macro_hides_keyword);
2455 if (NumTokens != 0) {
2474 auto isObjCProtectedMacro = [](
const IdentifierInfo *II) ->
bool {
2475 return II->
isStr(
"__strong") ||
2476 II->
isStr(
"__weak") ||
2477 II->
isStr(
"__unsafe_unretained") ||
2478 II->
isStr(
"__autoreleasing");
2481 SourceMgr.
getFileID(OtherMI->getDefinitionLoc())
2488 LangOpts.MicrosoftExt)) {
2491 assert(!OtherMI->isWarnIfUnused());
2500 if (!OtherMI->isUsed() && OtherMI->isWarnIfUnused())
2501 Diag(OtherMI->getDefinitionLoc(), diag::pp_macro_not_used);
2505 if (OtherMI->isBuiltinMacro())
2506 Diag(MacroNameTok, diag::ext_pp_redef_builtin_macro);
2509 else if (!OtherMI->isAllowRedefinitionsWithoutWarning() &&
2510 !MI->
isIdenticalTo(*OtherMI, *
this, LangOpts.MicrosoftExt)) {
2513 Diag(OtherMI->getDefinitionLoc(), diag::note_previous_definition);
2516 if (OtherMI->isWarnIfUnused())
2517 WarnUnusedMacroLocs.erase(OtherMI->getDefinitionLoc());
2534 Callbacks->MacroDefined(MacroNameTok, MD);
2539 void Preprocessor::HandleUndefDirective(
Token &UndefTok) {
2543 ReadMacroName(MacroNameTok,
MU_Undef);
2546 if (MacroNameTok.
is(tok::eod))
2559 Callbacks->MacroUndefined(MacroNameTok, MD);
2573 AllocateUndefMacroDirective(MacroNameTok.
getLocation()));
2585 void Preprocessor::HandleIfdefDirective(
Token &Result,
bool isIfndef,
2586 bool ReadAnyTokensBeforeDirective) {
2591 ReadMacroName(MacroNameTok);
2594 if (MacroNameTok.
is(tok::eod)) {
2597 SkipExcludedConditionalBlock(DirectiveTok.
getLocation(),
2614 if (!ReadAnyTokensBeforeDirective && !MI) {
2615 assert(isIfndef &&
"#ifdef shouldn't reach here");
2627 Callbacks->Ifndef(DirectiveTok.
getLocation(), MacroNameTok, MD);
2629 Callbacks->Ifdef(DirectiveTok.
getLocation(), MacroNameTok, MD);
2633 if (!MI == isIfndef) {
2640 SkipExcludedConditionalBlock(DirectiveTok.
getLocation(),
2648 void Preprocessor::HandleIfDirective(
Token &IfToken,
2649 bool ReadAnyTokensBeforeDirective) {
2655 const bool ConditionalTrue = EvaluateDirectiveExpression(IfNDefMacro);
2661 if (!ReadAnyTokensBeforeDirective && IfNDefMacro && ConditionalTrue)
2674 if (ConditionalTrue) {
2680 SkipExcludedConditionalBlock(IfToken.
getLocation(),
false,
2687 void Preprocessor::HandleEndifDirective(
Token &EndifToken) {
2696 Diag(EndifToken, diag::err_pp_endif_without_if);
2705 "This code should only be reachable in the non-skipping case!");
2713 void Preprocessor::HandleElseDirective(
Token &Result) {
2721 Diag(Result, diag::pp_err_else_without_if);
2730 if (CI.
FoundElse)
Diag(Result, diag::pp_err_else_after_else);
2736 SkipExcludedConditionalBlock(CI.
IfLoc,
true,
2742 void Preprocessor::HandleElifDirective(
Token &ElifToken) {
2754 Diag(ElifToken, diag::pp_err_elif_without_if);
2763 if (CI.
FoundElse)
Diag(ElifToken, diag::pp_err_elif_after_else);
2771 SkipExcludedConditionalBlock(CI.
IfLoc,
true,
bool isAtStartOfLine() const
isAtStartOfLine - Return true if this token is at the start of a line.
SourceManager & getSourceManager() const
bool isPoisoned() const
Return true if this token has been poisoned.
bool getHasReadAnyTokensVal() const
getHasReadAnyTokensVal - This is used for the #ifndef hande-shake at the top of the file when reading...
static LLVM_READONLY bool isDigit(unsigned char c)
Return true if this character is an ASCII digit: [0-9].
Module * getModuleForLocation(SourceLocation Loc)
Find the module that owns the source or header file that Loc points to.
MacroInfo * AllocateMacroInfo(SourceLocation L)
Allocate a new MacroInfo object with the provided SourceLocation.
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.
std::pair< FileID, unsigned > getDecomposedExpansionLoc(SourceLocation Loc) const
Decompose the specified location into a raw FileID + Offset pair.
void markMacroAsUsed(MacroInfo *MI)
A macro is used, update information about macros that need unused warnings.
Defines the clang::FileManager interface and associated types.
This header is part of the module (for layering purposes) but should be textually included...
PPConditionalInfo & peekConditionalLevel()
Return the top of the conditional stack.
bool isInvalid() const
Return true if this object is invalid or uninitialized.
static LLVM_READONLY bool isUppercase(unsigned char c)
Return true if this character is an uppercase ASCII letter: [A-Z].
static bool isReservedId(StringRef Text, const LangOptions &Lang)
Checks if the specified identifier is reserved in the specified language.
Module * getTopLevelModule()
Retrieve the top-level module for this (sub)module, which may be this module.
Defines the SourceManager interface.
IdentifierInfo * getIdentifierInfo(StringRef Name) const
Return information about the specified preprocessor identifier token.
static bool ReadLineMarkerFlags(bool &IsFileEntry, bool &IsFileExit, bool &IsSystemHeader, bool &IsExternCHeader, Preprocessor &PP)
ReadLineMarkerFlags - Parse and validate any flags at the end of a GNU line marker directive...
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 isObjectLike() const
Defines the clang::MacroInfo and clang::MacroDirective classes.
bool hasLeadingSpace() const
Return true if this token has whitespace before it.
std::unique_ptr< llvm::MemoryBuffer > Buffer
void AddLineNote(SourceLocation Loc, unsigned LineNo, int FilenameID)
Add a line note to the line table for the FileID and offset specified by Loc.
A directive for an undefined macro.
bool needsCleaning() const
Return true if this token has trigraphs or escaped newlines in it.
void setCodeCompletionReached()
Note that we hit the code-completion point.
static void EnterAnnotationToken(Preprocessor &PP, SourceLocation Begin, SourceLocation End, tok::TokenKind Kind, void *AnnotationVal)
Push a token onto the token stream containing an annotation.
SourceLocation getDefinitionLoc() const
Return the location that the macro was defined at.
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.
bool isInPrimaryFile() const
Return true if we're in the top-level file, not in a #include.
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 ...
static MacroDiag shouldWarnOnMacroDef(Preprocessor &PP, IdentifierInfo *II)
std::string getFullModuleName() const
Retrieve the full name of this module, including the path from its top-level module.
Module * getModuleContainingLocation(SourceLocation Loc)
Find the module that contains the specified location, either directly or indirectly.
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.
class LLVM_ALIGNAS(8) DependentTemplateSpecializationType const IdentifierInfo * Name
Represents a template specialization type whose template cannot be resolved, e.g. ...
std::pair< SourceLocation, SourceLocation > getExpansionRange(SourceLocation Loc) const
Given a SourceLocation object, return the range of tokens covered by the expansion in the ultimate fi...
bool CheckMacroName(Token &MacroNameTok, MacroUse isDefineUndef, bool *ShadowFlag=nullptr)
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 getImmediatelyAfterTopLevelIfndef() const
getImmediatelyAfterTopLevelIfndef - returns true if the last directive was an #ifndef at the beginnin...
SmallVector< PPConditionalInfo, 4 > ConditionalStack
Information about the set of #if/#ifdef/#ifndef blocks we are currently in.
const MacroInfo * getMacroInfo(const IdentifierInfo *II) const
const LangOptions & getLangOpts() const
virtual void CodeCompleteDirective(bool InConditional)
Callback invoked when performing code completion for a preprocessor directive.
Token - This structure provides full information about a lexed token.
static bool trySimplifyPath(SmallVectorImpl< StringRef > &Components, StringRef RealPathName)
bool isWarnIfUnused() const
Return true if we should emit a warning if the macro is unused.
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...
Describes a module or submodule.
bool isMissingExpected() const
Determines whether the module, which failed to load, was actually a submodule that we expected to see...
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.
void CheckEndOfDirective(const char *Directive, bool EnableMacros=false)
Ensure that the next token is a tok::eod token.
MacroUse
Context in which macro name is used.
SourceLocation getLocWithOffset(int Offset) const
Return a source location with the specified offset from this SourceLocation.
bool isAvailable() const
Determine whether this module is available for use within the current translation unit...
ArrayRef< KnownHeader > findAllModulesForHeader(const FileEntry *File) const
Retrieve all the modules that contain the given header file.
void HandleDirective(Token &Result)
Callback invoked when the lexer sees a # token at the start of a line.
Module * Parent
The parent of this module.
bool hadModuleLoaderFatalFailure() const
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...
tok::TokenKind getKind() const
bool FoundNonSkip
True if we have emitted tokens already, and now we're in an #else block or something.
const TargetInfo & getTargetInfo() const
const FileEntry * getFileEntry() const
getFileEntry - Return the FileEntry corresponding to this FileID.
detail::InMemoryDirectory::const_iterator I
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const
Forwarding function for diagnostics.
SourceLocation getIncludeLoc() const
Return the presumed include location of this location.
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)...
bool isCPlusPlusOperatorKeyword() const
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.
const FileEntry * getFileEntryForID(FileID FID) const
Returns the FileEntry record for the provided FileID.
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).
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
Describes the result of attempting to load a module.
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.
bool LexingRawMode
True if in raw mode.
StringRef getName() const
Return the actual identifier string.
Represents a character-granular source range.
void setHasCommaPasting()
void makeModuleVisible(Module *M, SourceLocation Loc)
FileID createFileID(const FileEntry *SourceFile, SourceLocation IncludePos, SrcMgr::CharacteristicKind FileCharacter, int LoadedID=0, unsigned LoadedOffset=0)
Create a new FileID that represents the specified file being #included from the specified IncludePosi...
static bool warnByDefaultOnWrongCase(StringRef Include)
Defines the clang::Preprocessor interface.
const char * getBufferName(SourceLocation Loc, bool *Invalid=nullptr) const
Return the filename or buffer identifier of the buffer the location is in.
bool hasUDSuffix() const
Return true if this token is a string or character literal which has a ud-suffix. ...
ResetMacroExpansionHelper(Preprocessor *pp)
PPKeywordKind
Provides a namespace for preprocessor keywords which start with a '#' at the beginning of the line...
void setIsPoisoned(bool Value=true)
setIsPoisoned - Mark this identifier as poisoned.
int getArgumentNum(const IdentifierInfo *Arg) const
Return the argument number of the specified identifier, or -1 if the identifier is not a formal argum...
void resetImmediatelyAfterTopLevelIfndef()
MultipleIncludeOpt MIOpt
A state machine that detects the #ifndef-wrapping a file idiom for the multiple-include optimization...
void SetDefinedMacro(IdentifierInfo *M, SourceLocation Loc)
bool isInSystemHeader(SourceLocation Loc) const
Returns if a SourceLocation is in a system header.
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file. ...
bool isNot(tok::TokenKind K) const
unsigned getNumTokens() const
Return the number of tokens that this macro expands to.
SourceLocation getIncludeLoc(FileID FID) const
Returns the include location if FID is a #include'd file otherwise it returns an invalid location...
Information about the conditional stack (#if directives) currently active.
Represents an unpacked "presumed" location which can be presented to the user.
void setArgumentList(ArrayRef< IdentifierInfo * > List, llvm::BumpPtrAllocator &PPAllocator)
Set the specified list of identifiers as the argument list for this macro.
The result type of a method or function.
DirectoryLookup - This class represents one entry in the search list that specifies the search order ...
bool isC99Varargs() const
StringRef getTopLevelModuleName() const
Retrieve the name of the top-level module.
static CharSourceRange getCharRange(SourceRange R)
bool getSuppressSystemWarnings() const
virtual SourceLocation getSourceLocation()=0
Return the source location for the next observable location.
bool isInMainFile(SourceLocation Loc) const
Returns whether the PresumedLoc for a given SourceLocation is in the main file.
MacroInfo * AllocateDeserializedMacroInfo(SourceLocation L, unsigned SubModuleID)
Allocate a new MacroInfo object loaded from an AST file.
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.
const char * getNameStart() const
Return the beginning of the actual null-terminated string for this identifier.
bool isValid() const
Return true if this is a valid SourceLocation object.
MacroDefinition getMacroDefinition(const IdentifierInfo *II)
MacroDirective * getLocalMacroDirective(const IdentifierInfo *II) const
Given an identifier, return its latest non-imported MacroDirective if it is #define'd and not #undef'...
All of the names in this module are hidden.
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.
void setIdentifierInfo(IdentifierInfo *II)
void Lex(Token &Result)
Lex the next token for this preprocessor.
bool isKeyword(const LangOptions &LangOpts)
Return true if this token is a keyword in the specified language.
void setDefinitionEndLoc(SourceLocation EndLoc)
Set the location of the last token in the macro.
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
const Token & getReplacementToken(unsigned Tok) const
FileID getMainFileID() const
Returns the FileID of the main source file.
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)) {...
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
unsigned getConditionalStackDepth() const
DiagnosticsEngine & getDiagnostics() const
FileID getPredefinesFileID() const
Returns the FileID for the preprocessor predefines.
SourceLocation IfLoc
Location where the conditional started.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
static bool isInvalid(LocType Loc, bool *Invalid)
The pragma was introduced via #pragma.
void ExitTopLevelConditional()
Called when the lexer exits the top-level conditional.
Module * inferModuleFromLocation(FullSourceLoc Loc)
Infers the (sub)module based on the given source location and source manager.
static bool isConfigurationPattern(Token &MacroName, MacroInfo *MI, const LangOptions &LOptions)
SrcMgr::CharacteristicKind getFileCharacteristic(SourceLocation Loc) const
Return the file characteristic of the specified source location, indicating whether this is a normal ...
unsigned getLineTableFilenameID(StringRef Str)
Return the uniqued ID for the specified filename.
const MacroInfo * getMacroInfo() const
virtual ModuleLoadResult loadModule(SourceLocation ImportLoc, ModuleIdPath Path, Module::NameVisibilityKind Visibility, bool IsInclusionDirective)=0
Attempt to load the given module.
static MacroDiag shouldWarnOnMacroUndef(Preprocessor &PP, IdentifierInfo *II)
PreprocessorLexer * getCurrentFileLexer() const
Return the current file lexer being lexed from.
void EnterTopLevelConditional()
Invoked when a top level conditional (except #ifndef) is found.
Encapsulates the data about a macro definition (e.g.
SourceLocation DefinitionLoc
The location of the module definition.
bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const
bool GetIncludeFilenameSpelling(SourceLocation Loc, StringRef &Filename)
Turn the specified lexer token into a fully checked and spelled filename, e.g.
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...
std::pair< std::string, bool > Requirement
An individual requirement: a feature name and a flag indicating the required state of that feature...
bool isBuiltinMacro() const
Return true if this macro requires processing before expansion.
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.
KnownHeader findModuleForHeader(const FileEntry *File)
Retrieve the module that owns the given header file, if any.
void LexIncludeFilename(Token &Result)
After the preprocessor has parsed a #include, lex and (potentially) macro expand the filename...
Cached information about one directory (either on disk or in the virtual file system).
const FileEntry * getModuleHeaderToIncludeForDiagnostics(SourceLocation IncLoc, SourceLocation MLoc)
We want to produce a diagnostic at location IncLoc concerning a missing module import.
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...
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 SkipCache=false)
Given a "foo" or <foo> reference, look up the indicated file.
void EnterTopLevelIfndef(const IdentifierInfo *M, SourceLocation Loc)
Called when entering a top-level #ifndef directive (or the "\#if !defined" equivalent) without any pr...
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...
unsigned HasIncompatibleModuleFile
Whether we tried and failed to load a module file for this module.
A SourceLocation and its associated SourceManager.
void DiscardUntilEndOfDirective()
Read and discard all tokens remaining on the current line until the tok::eod token is found...
unsigned getLength() const
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.
SourceLocation getExpansionLoc(SourceLocation Loc) const
Given a SourceLocation object Loc, return the expansion location referenced by the ID...
const DirectoryEntry * getDir() const
Return the directory the file lives in.
bool FoundElse
True if we've seen a #else in this block.
This class handles loading and caching of source files into memory.
void startToken()
Reset all flags to cleared.
~ResetMacroExpansionHelper()
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
bool isUsed() const
Return false if this macro is defined in the main file and has not yet been used. ...
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...
IdentifierInfo * getIdentifierInfo() 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.