36 #include "llvm/ADT/ArrayRef.h" 37 #include "llvm/ADT/SmallString.h" 38 #include "llvm/ADT/SmallVector.h" 39 #include "llvm/ADT/STLExtras.h" 40 #include "llvm/ADT/StringSwitch.h" 41 #include "llvm/ADT/StringRef.h" 42 #include "llvm/Support/AlignOf.h" 43 #include "llvm/Support/ErrorHandling.h" 44 #include "llvm/Support/Path.h" 52 using namespace clang;
59 auto *MIChain =
new (BP) MacroInfoChain{L, MIChainHead};
60 MIChainHead = MIChain;
70 Preprocessor::AllocateUndefMacroDirective(
SourceLocation UndefLoc) {
86 assert(Tmp.
isNot(
tok::eof) &&
"EOF seen while discarding directive tokens");
87 }
while (Tmp.
isNot(tok::eod));
104 if (Text.size() >= 2 && Text[0] ==
'_' &&
110 if (Lang.CPlusPlus) {
111 if (Text.find(
"__") != StringRef::npos)
124 StringRef ModuleName) {
130 !CurrentModule.endswith(
"_Private") && TopLevelName.endswith(
"_Private"))
131 TopLevelName = TopLevelName.drop_back(8);
133 return TopLevelName == CurrentModule;
143 if (Lang.CPlusPlus11 && (Text.equals(
"override") || Text.equals(
"final")))
165 if (::llvm::sys::path::begin(Include)->equals_lower(
"boost"))
170 static const size_t MaxStdHeaderNameLen = 18u;
171 if (Include.size() > MaxStdHeaderNameLen)
176 for (
char &Ch : LowerInclude) {
178 if (static_cast<unsigned char>(Ch) > 0x7f)
181 if (Ch >=
'A' && Ch <=
'Z')
184 else if (::llvm::sys::path::is_separator(Ch))
189 return llvm::StringSwitch<bool>(LowerInclude)
191 .Cases(
"assert.h",
"complex.h",
"ctype.h",
"errno.h",
"fenv.h",
true)
192 .Cases(
"float.h",
"inttypes.h",
"iso646.h",
"limits.h",
"locale.h",
true)
193 .Cases(
"math.h",
"setjmp.h",
"signal.h",
"stdalign.h",
"stdarg.h",
true)
194 .Cases(
"stdatomic.h",
"stdbool.h",
"stddef.h",
"stdint.h",
"stdio.h",
true)
195 .Cases(
"stdlib.h",
"stdnoreturn.h",
"string.h",
"tgmath.h",
"threads.h",
true)
196 .Cases(
"time.h",
"uchar.h",
"wchar.h",
"wctype.h",
true)
199 .Cases(
"cassert",
"ccomplex",
"cctype",
"cerrno",
"cfenv",
true)
200 .Cases(
"cfloat",
"cinttypes",
"ciso646",
"climits",
"clocale",
true)
201 .Cases(
"cmath",
"csetjmp",
"csignal",
"cstdalign",
"cstdarg",
true)
202 .Cases(
"cstdbool",
"cstddef",
"cstdint",
"cstdio",
"cstdlib",
true)
203 .Cases(
"cstring",
"ctgmath",
"ctime",
"cuchar",
"cwchar",
true)
204 .Case(
"cwctype",
true)
207 .Cases(
"algorithm",
"fstream",
"list",
"regex",
"thread",
true)
208 .Cases(
"array",
"functional",
"locale",
"scoped_allocator",
"tuple",
true)
209 .Cases(
"atomic",
"future",
"map",
"set",
"type_traits",
true)
210 .Cases(
"bitset",
"initializer_list",
"memory",
"shared_mutex",
"typeindex",
true)
211 .Cases(
"chrono",
"iomanip",
"mutex",
"sstream",
"typeinfo",
true)
212 .Cases(
"codecvt",
"ios",
"new",
"stack",
"unordered_map",
true)
213 .Cases(
"complex",
"iosfwd",
"numeric",
"stdexcept",
"unordered_set",
true)
214 .Cases(
"condition_variable",
"iostream",
"ostream",
"streambuf",
"utility",
true)
215 .Cases(
"deque",
"istream",
"queue",
"string",
"valarray",
true)
216 .Cases(
"exception",
"iterator",
"random",
"strstream",
"vector",
true)
217 .Cases(
"forward_list",
"limits",
"ratio",
"system_error",
true)
220 .Cases(
"aio.h",
"arpa/inet.h",
"cpio.h",
"dirent.h",
"dlfcn.h",
true)
221 .Cases(
"fcntl.h",
"fmtmsg.h",
"fnmatch.h",
"ftw.h",
"glob.h",
true)
222 .Cases(
"grp.h",
"iconv.h",
"langinfo.h",
"libgen.h",
"monetary.h",
true)
223 .Cases(
"mqueue.h",
"ndbm.h",
"net/if.h",
"netdb.h",
"netinet/in.h",
true)
224 .Cases(
"netinet/tcp.h",
"nl_types.h",
"poll.h",
"pthread.h",
"pwd.h",
true)
225 .Cases(
"regex.h",
"sched.h",
"search.h",
"semaphore.h",
"spawn.h",
true)
226 .Cases(
"strings.h",
"stropts.h",
"sys/ipc.h",
"sys/mman.h",
"sys/msg.h",
true)
227 .Cases(
"sys/resource.h",
"sys/select.h",
"sys/sem.h",
"sys/shm.h",
"sys/socket.h",
true)
228 .Cases(
"sys/stat.h",
"sys/statvfs.h",
"sys/time.h",
"sys/times.h",
"sys/types.h",
true)
229 .Cases(
"sys/uio.h",
"sys/un.h",
"sys/utsname.h",
"sys/wait.h",
"syslog.h",
true)
230 .Cases(
"tar.h",
"termios.h",
"trace.h",
"ulimit.h",
true)
231 .Cases(
"unistd.h",
"utime.h",
"utmpx.h",
"wordexp.h",
true)
238 if (MacroNameTok.
is(tok::eod))
239 return Diag(MacroNameTok, diag::err_pp_missing_macro_name);
243 return Diag(MacroNameTok, diag::err_pp_macro_not_identifier);
249 ? diag::ext_pp_operator_used_as_macro_name
250 : diag::err_pp_operator_used_as_macro_name)
251 << II << MacroNameTok.
getKind();
258 return Diag(MacroNameTok, diag::err_defined_macro_name);
266 Diag(MacroNameTok, diag::ext_pp_undef_builtin_macro);
291 Diag(MacroNameTok, diag::warn_pp_macro_is_reserved_id);
307 void Preprocessor::ReadMacroName(
Token &MacroNameTok,
MacroUse isDefineUndef,
312 if (MacroNameTok.
is(tok::code_completion)) {
324 if (MacroNameTok.
isNot(tok::eod)) {
325 MacroNameTok.
setKind(tok::eod);
346 while (Tmp.
is(tok::comment))
349 if (Tmp.
isNot(tok::eod)) {
355 if ((LangOpts.GNUMode || LangOpts.C99 || LangOpts.CPlusPlus) &&
358 Diag(Tmp, diag::ext_pp_extra_tokens_at_eol) << DirType << Hint;
371 void Preprocessor::SkipExcludedConditionalBlock(
SourceLocation HashTokenLoc,
373 bool FoundNonSkipPortion,
377 assert(!CurTokenLexer && CurPPLexer &&
"Lexing a macro, not a file?");
379 if (PreambleConditionalStack.reachedEOFWhileSkipping())
380 PreambleConditionalStack.clearSkipInfo();
383 FoundNonSkipPortion, FoundElse);
392 if (Tok.
is(tok::code_completion)) {
404 if (PreambleConditionalStack.isRecording())
405 PreambleConditionalStack.SkipInfo.emplace(
406 HashTokenLoc, IfTokenLoc, FoundNonSkipPortion, FoundElse, ElseLoc);
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 size_t 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).Conditional;
566 if (CurLexer) CurLexer->resetExtendedTokenMode();
577 Callbacks->SourceRangeSkipped(
606 assert(M &&
"no module to include");
627 bool InTextualHeader =
false;
629 if (!Header.getModule()->isSubModuleOf(TopM))
636 if (Header.isAccessibleFrom(IncM))
646 InTextualHeader =
true;
649 if (!InTextualHeader)
665 bool RequestingModuleIsModuleInterface = !SourceMgr.
isInMainFile(FilenameLoc);
671 bool BuildSystemModule =
false;
672 if (!FromDir && !FromFile) {
690 Includers.push_back(std::make_pair(
nullptr, MainFileDir));
692 }
else if ((FileEnt =
694 Includers.push_back(std::make_pair(FileEnt, FileMgr.
getDirectory(
".")));
696 Includers.push_back(std::make_pair(FileEnt, FileEnt->
getDir()));
702 if (LangOpts.MSVCCompat && !isAngled) {
703 for (IncludeStackInfo &ISEntry : llvm::reverse(IncludeMacroStack)) {
704 if (IsFileLexer(ISEntry))
705 if ((FileEnt = ISEntry.ThePPLexer->getFileEntry()))
706 Includers.push_back(std::make_pair(FileEnt, FileEnt->
getDir()));
711 CurDir = CurDirLookup;
719 Filename, FilenameLoc, isAngled, TmpFromDir, TmpCurDir,
720 Includers, SearchPath, RelativePath, RequestingModule,
721 SuggestedModule,
nullptr, SkipCache)) {
723 TmpFromDir = TmpCurDir;
725 if (FE == FromFile) {
727 FromDir = TmpFromDir;
736 Filename, FilenameLoc, isAngled, FromDir, CurDir, Includers, SearchPath,
737 RelativePath, RequestingModule, SuggestedModule, IsMapped, SkipCache,
740 if (SuggestedModule && !LangOpts.AsmPreprocessor)
742 RequestingModule, RequestingModuleIsModuleInterface, FilenameLoc,
754 SearchPath, RelativePath,
757 if (SuggestedModule && !LangOpts.AsmPreprocessor)
759 RequestingModule, RequestingModuleIsModuleInterface, FilenameLoc,
766 for (IncludeStackInfo &ISEntry : llvm::reverse(IncludeMacroStack)) {
767 if (IsFileLexer(ISEntry)) {
768 if ((CurFileEnt = ISEntry.ThePPLexer->getFileEntry())) {
770 Filename, CurFileEnt, SearchPath, RelativePath,
771 RequestingModule, SuggestedModule))) {
772 if (SuggestedModule && !LangOpts.AsmPreprocessor)
774 RequestingModule, RequestingModuleIsModuleInterface,
775 FilenameLoc, Filename, FE);
793 : PP(pp), save(pp->DisableMacroExpansion) {
794 if (pp->MacroExpansionInDirectivesOverride)
795 pp->DisableMacroExpansion =
false;
799 PP->DisableMacroExpansion = save;
816 if (II->getPPKeywordID() == tok::pp_define) {
817 return HandleDefineDirective(Result,
820 if (SkippingUntilPCHThroughHeader &&
821 II->getPPKeywordID() == tok::pp_include) {
822 return HandleIncludeDirective(HashLoc, Result);
824 if (SkippingUntilPragmaHdrStop && II->getPPKeywordID() == tok::pp_pragma) {
827 if (II && II->getName() ==
"hdrstop")
844 CurPPLexer->ParsingPreprocessorDirective =
true;
845 if (CurLexer) CurLexer->SetKeepWhitespaceMode(
false);
847 bool ImmediatelyAfterTopLevelIfndef =
848 CurPPLexer->MIOpt.getImmediatelyAfterTopLevelIfndef();
849 CurPPLexer->MIOpt.resetImmediatelyAfterTopLevelIfndef();
856 bool ReadAnyTokensBeforeDirective =CurPPLexer->MIOpt.getHasReadAnyTokensVal();
875 switch (II->getPPKeywordID()) {
876 case tok::pp_include:
878 case tok::pp_include_next:
879 case tok::pp___include_macros:
881 Diag(Result, diag::err_embedded_directive) << II->getName();
888 Diag(Result, diag::ext_embedded_directive);
895 if (SkippingUntilPCHThroughHeader || SkippingUntilPragmaHdrStop)
901 case tok::code_completion:
903 CodeComplete->CodeCompleteDirective(
904 CurPPLexer->getConditionalStackDepth() > 0);
907 case tok::numeric_constant:
910 return HandleDigitDirective(Result);
920 return HandleIfDirective(Result, SavedHash, ReadAnyTokensBeforeDirective);
922 return HandleIfdefDirective(Result, SavedHash,
false,
925 return HandleIfdefDirective(Result, SavedHash,
true,
926 ReadAnyTokensBeforeDirective);
928 return HandleElifDirective(Result, SavedHash);
930 return HandleElseDirective(Result, SavedHash);
932 return HandleEndifDirective(Result);
935 case tok::pp_include:
938 case tok::pp___include_macros:
944 return HandleDefineDirective(Result, ImmediatelyAfterTopLevelIfndef);
946 return HandleUndefDirective();
950 return HandleLineDirective();
954 return HandleUserDiagnosticDirective(Result,
false);
963 case tok::pp_include_next:
966 case tok::pp_warning:
967 Diag(Result, diag::ext_pp_warning_directive);
968 return HandleUserDiagnosticDirective(Result,
true);
970 return HandleIdentSCCSDirective(Result);
972 return HandleIdentSCCSDirective(Result);
976 case tok::pp_unassert:
980 case tok::pp___public_macro:
982 return HandleMacroPublicDirective(Result);
985 case tok::pp___private_macro:
987 return HandleMacroPrivateDirective();
998 auto Toks = llvm::make_unique<Token[]>(2);
1000 Toks[0] = SavedHash;
1005 if (Result.
is(tok::hashhash))
1006 Toks[1].setKind(tok::unknown);
1011 EnterTokenStream(std::move(Toks), 2,
false);
1016 Diag(Result, diag::err_pp_invalid_directive);
1028 bool IsGNULineDirective=
false) {
1029 if (DigitTok.
isNot(tok::numeric_constant)) {
1030 PP.
Diag(DigitTok, DiagID);
1032 if (DigitTok.
isNot(tok::eod))
1038 IntegerBuffer.resize(DigitTok.
getLength());
1039 const char *DigitTokBegin = &IntegerBuffer[0];
1040 bool Invalid =
false;
1041 unsigned ActualLength = PP.
getSpelling(DigitTok, DigitTokBegin, &Invalid);
1049 for (
unsigned i = 0; i != ActualLength; ++i) {
1052 if (DigitTokBegin[i] ==
'\'')
1055 if (!
isDigit(DigitTokBegin[i])) {
1057 diag::err_pp_line_digit_sequence) << IsGNULineDirective;
1062 unsigned NextVal = Val*10+(DigitTokBegin[i]-
'0');
1063 if (NextVal < Val) {
1064 PP.
Diag(DigitTok, DiagID);
1071 if (DigitTokBegin[0] ==
'0' && Val)
1073 << IsGNULineDirective;
1085 void Preprocessor::HandleLineDirective() {
1093 if (
GetLineValue(DigitTok, LineNo, diag::err_pp_line_requires_integer,*
this))
1097 Diag(DigitTok, diag::ext_pp_line_zero);
1101 unsigned LineLimit = 32768U;
1102 if (LangOpts.C99 || LangOpts.CPlusPlus11)
1103 LineLimit = 2147483648U;
1104 if (LineNo >= LineLimit)
1105 Diag(DigitTok, diag::ext_pp_line_too_big) << LineLimit;
1106 else if (LangOpts.CPlusPlus11 && LineNo >= 32768U)
1107 Diag(DigitTok, diag::warn_cxx98_compat_pp_line_too_big);
1109 int FilenameID = -1;
1115 if (StrTok.
is(tok::eod))
1117 else if (StrTok.
isNot(tok::string_literal)) {
1118 Diag(StrTok, diag::err_pp_line_invalid_filename);
1121 Diag(StrTok, diag::err_invalid_string_udl);
1126 assert(Literal.
isAscii() &&
"Didn't allow wide strings in");
1130 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1133 FilenameID = SourceMgr.getLineTableFilenameID(Literal.
GetString());
1146 SourceMgr.getFileCharacteristic(DigitTok.
getLocation());
1148 SourceMgr.AddLineNote(DigitTok.
getLocation(), LineNo, FilenameID,
false,
1152 Callbacks->FileChanged(CurPPLexer->getSourceLocation(),
1164 if (FlagTok.
is(tok::eod))
return false;
1165 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag, PP))
1172 if (FlagTok.
is(tok::eod))
return false;
1173 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag,PP))
1175 }
else if (FlagVal == 2) {
1192 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_pop);
1198 if (FlagTok.
is(tok::eod))
return false;
1199 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag,PP))
1205 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1213 if (FlagTok.
is(tok::eod))
return false;
1214 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag, PP))
1219 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1227 if (FlagTok.
is(tok::eod))
return false;
1230 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1242 void Preprocessor::HandleDigitDirective(
Token &DigitTok) {
1246 if (
GetLineValue(DigitTok, LineNo, diag::err_pp_linemarker_requires_integer,
1253 bool IsFileEntry =
false, IsFileExit =
false;
1254 int FilenameID = -1;
1259 if (StrTok.
is(tok::eod)) {
1261 FileKind = SourceMgr.getFileCharacteristic(DigitTok.
getLocation());
1262 }
else if (StrTok.
isNot(tok::string_literal)) {
1263 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1266 Diag(StrTok, diag::err_invalid_string_udl);
1271 assert(Literal.
isAscii() &&
"Didn't allow wide strings in");
1275 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1278 FilenameID = SourceMgr.getLineTableFilenameID(Literal.
GetString());
1286 SourceMgr.AddLineNote(DigitTok.
getLocation(), LineNo, FilenameID, IsFileEntry,
1287 IsFileExit, FileKind);
1296 else if (IsFileExit)
1299 Callbacks->FileChanged(CurPPLexer->getSourceLocation(), Reason, FileKind);
1305 void Preprocessor::HandleUserDiagnosticDirective(
Token &
Tok,
1313 CurLexer->ReadToEndOfLine(&Message);
1317 StringRef Msg = StringRef(Message).ltrim(
' ');
1320 Diag(Tok, diag::pp_hash_warning) << Msg;
1322 Diag(Tok, diag::err_pp_hash_error) << Msg;
1327 void Preprocessor::HandleIdentSCCSDirective(
Token &Tok) {
1329 Diag(Tok, diag::ext_pp_ident_directive);
1336 if (StrTok.
isNot(tok::string_literal) &&
1337 StrTok.
isNot(tok::wide_string_literal)) {
1338 Diag(StrTok, diag::err_pp_malformed_ident);
1339 if (StrTok.
isNot(tok::eod))
1345 Diag(StrTok, diag::err_invalid_string_udl);
1353 bool Invalid =
false;
1361 void Preprocessor::HandleMacroPublicDirective(
Token &Tok) {
1363 ReadMacroName(MacroNameTok,
MU_Undef);
1366 if (MacroNameTok.
is(tok::eod))
1378 Diag(MacroNameTok, diag::err_pp_visibility_non_macro) << II;
1388 void Preprocessor::HandleMacroPrivateDirective() {
1390 ReadMacroName(MacroNameTok,
MU_Undef);
1393 if (MacroNameTok.
is(tok::eod))
1405 Diag(MacroNameTok, diag::err_pp_visibility_non_macro) << II;
1425 StringRef &Buffer) {
1427 assert(!Buffer.empty() &&
"Can't have tokens with empty spellings!");
1431 if (Buffer[0] ==
'<') {
1432 if (Buffer.back() !=
'>') {
1433 Diag(Loc, diag::err_pp_expects_filename);
1434 Buffer = StringRef();
1438 }
else if (Buffer[0] ==
'"') {
1439 if (Buffer.back() !=
'"') {
1440 Diag(Loc, diag::err_pp_expects_filename);
1441 Buffer = StringRef();
1446 Diag(Loc, diag::err_pp_expects_filename);
1447 Buffer = StringRef();
1452 if (Buffer.size() <= 2) {
1453 Diag(Loc, diag::err_pp_empty_filename);
1454 Buffer = StringRef();
1459 Buffer = Buffer.substr(1, Buffer.size()-2);
1481 while (CurTok.
isNot(tok::eod)) {
1485 if (CurTok.
is(tok::code_completion)) {
1494 FilenameBuffer.push_back(
' ');
1497 size_t PreAppendSize = FilenameBuffer.size();
1498 FilenameBuffer.resize(PreAppendSize+CurTok.
getLength());
1500 const char *BufPtr = &FilenameBuffer[PreAppendSize];
1504 if (BufPtr != &FilenameBuffer[PreAppendSize])
1505 memcpy(&FilenameBuffer[PreAppendSize], BufPtr, ActualLen);
1509 FilenameBuffer.resize(PreAppendSize+ActualLen);
1512 if (CurTok.
is(tok::greater))
1527 void *AnnotationVal) {
1530 auto Tok = llvm::make_unique<Token[]>(1);
1536 EnterTokenStream(std::move(Tok), 1,
true);
1543 ArrayRef<std::pair<IdentifierInfo *, SourceLocation>> Path,
1545 assert(PP.
getLangOpts().ObjC &&
"no import syntax available");
1548 for (
size_t I = 0, N = Path.size(); I != N; ++I) {
1551 PathString += Path[I].first->getName();
1553 int IncludeKind = 0;
1556 case tok::pp_include:
1560 case tok::pp_import:
1564 case tok::pp_include_next:
1568 case tok::pp___include_macros:
1573 llvm_unreachable(
"unknown include directive kind");
1578 PP.
Diag(HashLoc, diag::warn_auto_module_import)
1579 << IncludeKind << PathString
1581 (
"@import " + PathString +
";").
str());
1588 StringRef RealPathName) {
1589 auto RealPathComponentIter = llvm::sys::path::rbegin(RealPathName);
1590 auto RealPathComponentEnd = llvm::sys::path::rend(RealPathName);
1592 bool SuggestReplacement =
false;
1595 for (
auto &Component : llvm::reverse(Components)) {
1596 if (
"." == Component) {
1597 }
else if (
".." == Component) {
1601 }
else if (RealPathComponentIter != RealPathComponentEnd) {
1602 if (Component != *RealPathComponentIter) {
1606 SuggestReplacement = RealPathComponentIter->equals_lower(Component);
1607 if (!SuggestReplacement)
1609 Component = *RealPathComponentIter;
1611 ++RealPathComponentIter;
1614 return SuggestReplacement;
1622 Module *ShadowingModule =
nullptr;
1623 if (M->
isAvailable(LangOpts, TargetInfo, Requirement, MissingHeader,
1630 }
else if (ShadowingModule) {
1633 diag::note_previous_definition);
1648 void Preprocessor::HandleIncludeDirective(
SourceLocation HashLoc,
1654 CurPPLexer->LexIncludeFilename(FilenameTok);
1662 switch (FilenameTok.
getKind()) {
1667 case tok::angle_string_literal:
1668 case tok::string_literal:
1669 Filename =
getSpelling(FilenameTok, FilenameBuffer);
1677 FilenameBuffer.push_back(
'<');
1680 Filename = FilenameBuffer;
1691 StringRef OriginalFilename =
Filename;
1696 if (Filename.empty()) {
1708 if (IncludeMacroStack.size() == MaxAllowedIncludeStackDepth-1) {
1709 Diag(FilenameTok, diag::err_pp_include_too_deep);
1710 HasReachedMaxIncludeDepth =
true;
1715 if (PragmaARCCFCodeAuditedLoc.isValid()) {
1716 Diag(HashLoc, diag::err_pp_include_in_arc_cf_code_audited);
1717 Diag(PragmaARCCFCodeAuditedLoc, diag::note_pragma_entered_here);
1724 if (PragmaAssumeNonNullLoc.isValid()) {
1725 Diag(HashLoc, diag::err_pp_include_in_assume_nonnull);
1726 Diag(PragmaAssumeNonNullLoc, diag::note_pragma_entered_here);
1732 if (HeaderInfo.HasIncludeAliasMap()) {
1736 StringRef NewName = HeaderInfo.MapHeaderToIncludeAlias(OriginalFilename);
1737 if (!NewName.empty())
1742 bool IsMapped =
false;
1751 if (LangOpts.MSVCCompat) {
1752 NormalizedPath = Filename.str();
1754 llvm::sys::path::native(NormalizedPath);
1758 FilenameLoc, LangOpts.MSVCCompat ? NormalizedPath.c_str() :
Filename,
1759 isAngled, LookupFrom, LookupFromFile, CurDir,
1760 Callbacks ? &SearchPath :
nullptr, Callbacks ? &RelativePath :
nullptr,
1761 &SuggestedModule, &IsMapped);
1767 if (Callbacks->FileNotFound(Filename, RecoveryPath)) {
1768 if (
const DirectoryEntry *DE = FileMgr.getDirectory(RecoveryPath)) {
1771 HeaderInfo.AddSearchPath(DL, isAngled);
1776 LangOpts.MSVCCompat ? NormalizedPath.c_str() :
Filename, isAngled,
1777 LookupFrom, LookupFromFile, CurDir,
nullptr,
nullptr,
1778 &SuggestedModule, &IsMapped,
true);
1783 if (!SuppressIncludeNotFoundError) {
1790 LangOpts.MSVCCompat ? NormalizedPath.c_str() :
Filename,
false,
1791 LookupFrom, LookupFromFile, CurDir,
1792 Callbacks ? &SearchPath :
nullptr,
1793 Callbacks ? &RelativePath :
nullptr, &SuggestedModule, &IsMapped);
1796 Diag(FilenameTok, diag::err_pp_file_not_found_angled_include_not_fatal) <<
1804 StringRef OriginalFilename =
Filename;
1805 if (LangOpts.SpellChecking && !File) {
1808 auto CorrectTypoFilename = [](llvm::StringRef
Filename) {
1811 Filename = Filename.drop_back();
1815 StringRef TypoCorrectionName = CorrectTypoFilename(Filename);
1817 if (LangOpts.MSVCCompat) {
1818 NormalizedTypoCorrectionPath = TypoCorrectionName.str();
1820 llvm::sys::path::native(NormalizedTypoCorrectionPath);
1825 LangOpts.MSVCCompat ? NormalizedTypoCorrectionPath.c_str()
1826 : TypoCorrectionName,
1827 isAngled, LookupFrom, LookupFromFile, CurDir,
1828 Callbacks ? &SearchPath :
nullptr,
1829 Callbacks ? &RelativePath :
nullptr, &SuggestedModule, &IsMapped);
1832 auto Hint = isAngled
1834 Range,
"<" + TypoCorrectionName.str() +
">")
1836 Range,
"\"" + TypoCorrectionName.str() +
"\"");
1837 Diag(FilenameTok, diag::err_pp_file_not_found_typo_not_fatal)
1838 << OriginalFilename << TypoCorrectionName << Hint;
1841 Filename = TypoCorrectionName;
1847 Diag(FilenameTok, diag::err_pp_file_not_found) << OriginalFilename
1854 SkippingUntilPCHThroughHeader =
false;
1862 bool ShouldEnter =
true;
1864 if (PPOpts->SingleFileParseMode)
1865 ShouldEnter =
false;
1870 if (ShouldEnter && HasReachedMaxIncludeDepth && File &&
1871 HeaderInfo.getFileInfo(File).NumIncludes)
1872 ShouldEnter =
false;
1877 if (ShouldEnter && File && SuggestedModule &&
getLangOpts().Modules &&
1888 diag::note_implicit_top_level_module_import_here)
1900 std::reverse(Path.begin(), Path.end());
1914 assert((Imported ==
nullptr || Imported == SuggestedModule.
getModule()) &&
1915 "the imported module is different than the suggested one");
1918 ShouldEnter =
false;
1933 assert(CurLexer &&
"#include but no current lexer set!");
1935 CurLexer->FormTokenWithChars(Result, CurLexer->BufferEnd,
tok::eof);
1936 CurLexer->cutOffLexing();
1946 SourceMgr.getFileCharacteristic(FilenameTok.
getLocation());
1948 FileCharacter =
std::max(HeaderInfo.getFileDirFlavor(File), FileCharacter);
1952 bool SkipHeader =
false;
1953 if (ShouldEnter && File &&
1954 !HeaderInfo.ShouldEnterIncludeFile(*
this, File, isImport,
1957 ShouldEnter =
false;
1963 Callbacks->InclusionDirective(
1964 HashLoc, IncludeTok,
1965 LangOpts.MSVCCompat ? NormalizedPath.c_str() :
Filename, isAngled,
1966 FilenameRange, File, SearchPath, RelativePath,
1967 ShouldEnter ? nullptr : SuggestedModule.
getModule(), FileCharacter);
1968 if (SkipHeader && !SuggestedModule.
getModule())
1969 Callbacks->FileSkipped(*File, FilenameTok, FileCharacter);
1980 const bool CheckIncludePathPortability =
1983 if (CheckIncludePathPortability) {
1984 StringRef Name = LangOpts.MSVCCompat ? NormalizedPath.str() :
Filename;
1987 llvm::sys::path::end(Name));
1991 Path.reserve(Name.size()+2);
1992 Path.push_back(isAngled ?
'<' :
'"');
1993 bool isLeadingSeparator = llvm::sys::path::is_absolute(Name);
1994 for (
auto Component : Components) {
1995 if (isLeadingSeparator)
1996 isLeadingSeparator =
false;
1998 Path.append(Component);
2001 Path.size() <= Filename.size() ? Filename[Path.size()-1] :
2002 (isAngled ?
'>' :
'"'));
2007 diag::pp_nonportable_path : diag::pp_nonportable_system_path;
2009 Diag(FilenameTok, DiagId) << Path <<
2017 if (
auto *M = SuggestedModule.
getModule()) {
2030 tok::pp___include_macros)
2032 tok::annot_module_include, M);
2042 IncludePos = SourceMgr.getExpansionRange(IncludePos).getEnd();
2043 FileID FID = SourceMgr.createFileID(File, IncludePos, FileCharacter);
2044 assert(FID.
isValid() &&
"Expected valid file ID");
2051 if (
auto *M = SuggestedModule.
getModule()) {
2052 if (M->getTopLevelModule()->ShadowingModule) {
2055 Diag(M->DefinitionLoc, diag::err_module_build_shadowed_submodule)
2056 << M->getFullModuleName();
2057 Diag(M->getTopLevelModule()->ShadowingModule->DefinitionLoc,
2058 diag::note_previous_definition);
2069 assert(!CurLexerSubmodule &&
"should not have marked this as a module yet");
2070 CurLexerSubmodule = M;
2086 void Preprocessor::HandleIncludeNextDirective(
SourceLocation HashLoc,
2087 Token &IncludeNextTok) {
2088 Diag(IncludeNextTok, diag::ext_pp_include_next_directive);
2094 const FileEntry *LookupFromFile =
nullptr;
2101 Diag(IncludeNextTok, diag::pp_include_next_in_primary);
2102 }
else if (CurLexerSubmodule) {
2105 assert(CurPPLexer &&
"#include_next directive in macro?");
2106 LookupFromFile = CurPPLexer->getFileEntry();
2108 }
else if (!Lookup) {
2109 Diag(IncludeNextTok, diag::pp_include_next_absolute_path);
2115 return HandleIncludeDirective(HashLoc, IncludeNextTok, Lookup,
2120 void Preprocessor::HandleMicrosoftImportDirective(
Token &Tok) {
2126 Diag(Tok, diag::err_pp_import_directive_ms );
2137 if (!LangOpts.ObjC) {
2138 if (LangOpts.MSVCCompat)
2139 return HandleMicrosoftImportDirective(ImportTok);
2140 Diag(ImportTok, diag::ext_pp_import_directive);
2142 return HandleIncludeDirective(HashLoc, ImportTok,
nullptr,
nullptr,
true);
2149 void Preprocessor::HandleIncludeMacrosDirective(
SourceLocation HashLoc,
2150 Token &IncludeMacrosTok) {
2154 if (SourceMgr.getBufferName(Loc) !=
"<built-in>") {
2156 diag::pp_include_macros_out_of_predefines);
2163 HandleIncludeDirective(HashLoc, IncludeMacrosTok);
2168 assert(TmpTok.
isNot(
tok::eof) &&
"Didn't find end of -imacros!");
2169 }
while (TmpTok.
isNot(tok::hashhash));
2180 bool Preprocessor::ReadMacroParameterList(
MacroInfo *MI,
Token &Tok) {
2188 if (Parameters.empty())
2191 Diag(Tok, diag::err_pp_expected_ident_in_arg_list);
2195 Diag(Tok, LangOpts.CPlusPlus11 ?
2196 diag::warn_cxx98_compat_variadic_macro :
2197 diag::ext_variadic_macro);
2200 if (LangOpts.OpenCL) {
2201 Diag(Tok, diag::err_pp_opencl_variadic_macros);
2207 if (Tok.
isNot(tok::r_paren)) {
2208 Diag(Tok, diag::err_pp_missing_rparen_in_macro_def);
2212 Parameters.push_back(Ident__VA_ARGS__);
2217 Diag(Tok, diag::err_pp_missing_rparen_in_macro_def);
2225 Diag(Tok, diag::err_pp_invalid_tok_in_arg_list);
2231 if (std::find(Parameters.begin(), Parameters.end(), II) !=
2233 Diag(Tok, diag::err_pp_duplicate_name_in_arg_list) << II;
2238 Parameters.push_back(II);
2245 Diag(Tok, diag::err_pp_expected_comma_in_arg_list);
2254 Diag(Tok, diag::ext_named_variadic_macro);
2258 if (Tok.
isNot(tok::r_paren)) {
2259 Diag(Tok, diag::err_pp_missing_rparen_in_macro_def);
2287 if (!II->isKeyword(LOptions))
2289 StringRef ValueText = II->getName();
2290 StringRef TrimmedValue = ValueText;
2291 if (!ValueText.startswith(
"__")) {
2292 if (ValueText.startswith(
"_"))
2293 TrimmedValue = TrimmedValue.drop_front(1);
2297 TrimmedValue = TrimmedValue.drop_front(2);
2298 if (TrimmedValue.endswith(
"__"))
2299 TrimmedValue = TrimmedValue.drop_back(2);
2301 return TrimmedValue.equals(MacroText);
2308 return MacroName.
isOneOf(tok::kw_extern, tok::kw_inline, tok::kw_static,
2321 MacroInfo *Preprocessor::ReadOptionalMacroParameterListAndBody(
2322 const Token &MacroNameTok,
const bool ImmediatelyAfterHeaderGuard) {
2324 Token LastTok = MacroNameTok;
2338 if (Tok.is(tok::eod)) {
2339 if (ImmediatelyAfterHeaderGuard) {
2345 }
else if (Tok.hasLeadingSpace()) {
2349 }
else if (Tok.is(tok::l_paren)) {
2352 if (ReadMacroParameterList(MI, LastTok)) {
2354 if (CurPPLexer->ParsingPreprocessorDirective)
2370 }
else if (LangOpts.C99 || LangOpts.CPlusPlus11) {
2373 Diag(Tok, diag::ext_c99_whitespace_required_after_macro_name);
2382 if (Tok.is(tok::at))
2384 else if (Tok.is(tok::unknown)) {
2391 Diag(Tok, diag::ext_missing_whitespace_after_macro_name);
2393 Diag(Tok, diag::warn_missing_whitespace_after_macro_name);
2396 if (!Tok.is(tok::eod))
2402 while (Tok.isNot(tok::eod)) {
2415 while (Tok.isNot(tok::eod)) {
2418 if (!Tok.isOneOf(tok::hash, tok::hashat, tok::hashhash)) {
2424 Diag(Tok, diag::err_pp_vaopt_nested_use);
2429 if (Tok.isNot(tok::l_paren)) {
2430 Diag(Tok, diag::err_pp_missing_lparen_in_vaopt_use);
2436 if (Tok.is(tok::hashhash)) {
2437 Diag(Tok, diag::err_vaopt_paste_at_start);
2442 if (Tok.is(tok::r_paren)) {
2445 assert(NumTokens >= 3 &&
"Must have seen at least __VA_OPT__( " 2446 "and a subsequent tok::r_paren");
2448 Diag(Tok, diag::err_vaopt_paste_at_end);
2452 }
else if (Tok.is(tok::l_paren)) {
2465 Tok.setKind(tok::unknown);
2473 if (Tok.is(tok::hashhash)) {
2481 if (Tok.is(tok::eod)) {
2487 if (NumTokens && Tok.getIdentifierInfo() == Ident__VA_ARGS__ &&
2502 (Tok.getIdentifierInfo() ==
nullptr ||
2509 if (
getLangOpts().AsmPreprocessor && Tok.isNot(tok::eod)) {
2510 LastTok.
setKind(tok::unknown);
2514 Diag(Tok, diag::err_pp_stringize_not_parameter)
2515 << LastTok.
is(tok::hashat);
2535 assert(Tok.is(tok::eod) &&
"Must be at End Of preprocessing Directive");
2536 Diag(Tok, diag::err_pp_expected_after)
2537 << LastTok.
getKind() << tok::r_paren;
2547 void Preprocessor::HandleDefineDirective(
2548 Token &DefineTok,
const bool ImmediatelyAfterHeaderGuard) {
2552 bool MacroShadowsKeyword;
2553 ReadMacroName(MacroNameTok,
MU_Define, &MacroShadowsKeyword);
2556 if (MacroNameTok.
is(tok::eod))
2561 if (CurLexer) CurLexer->SetCommentRetentionState(KeepMacroComments);
2563 MacroInfo *
const MI = ReadOptionalMacroParameterListAndBody(
2564 MacroNameTok, ImmediatelyAfterHeaderGuard);
2568 if (MacroShadowsKeyword &&
2570 Diag(MacroNameTok, diag::warn_pp_macro_hides_keyword);
2575 if (NumTokens != 0) {
2587 if (SkippingUntilPCHThroughHeader) {
2590 LangOpts.MicrosoftExt))
2602 auto isObjCProtectedMacro = [](
const IdentifierInfo *II) ->
bool {
2603 return II->
isStr(
"__strong") ||
2604 II->isStr(
"__weak") ||
2605 II->isStr(
"__unsafe_unretained") ||
2606 II->isStr(
"__autoreleasing");
2609 SourceMgr.getFileID(OtherMI->getDefinitionLoc())
2614 !SourceMgr.isInSystemHeader(DefineTok.
getLocation())) &&
2616 LangOpts.MicrosoftExt)) {
2619 assert(!OtherMI->isWarnIfUnused());
2627 !SourceMgr.isInSystemHeader(DefineTok.
getLocation())) {
2628 if (!OtherMI->isUsed() && OtherMI->isWarnIfUnused())
2629 Diag(OtherMI->getDefinitionLoc(), diag::pp_macro_not_used);
2633 if (OtherMI->isBuiltinMacro())
2634 Diag(MacroNameTok, diag::ext_pp_redef_builtin_macro);
2637 else if (!OtherMI->isAllowRedefinitionsWithoutWarning() &&
2638 !MI->
isIdenticalTo(*OtherMI, *
this, LangOpts.MicrosoftExt)) {
2641 Diag(OtherMI->getDefinitionLoc(), diag::note_previous_definition);
2644 if (OtherMI->isWarnIfUnused())
2645 WarnUnusedMacroLocs.erase(OtherMI->getDefinitionLoc());
2662 Callbacks->MacroDefined(MacroNameTok, MD);
2667 void Preprocessor::HandleUndefDirective() {
2671 ReadMacroName(MacroNameTok,
MU_Undef);
2674 if (MacroNameTok.
is(tok::eod))
2686 if (
const MacroInfo *MI = MD.getMacroInfo()) {
2693 Undef = AllocateUndefMacroDirective(MacroNameTok.
getLocation());
2699 Callbacks->MacroUndefined(MacroNameTok, MD, Undef);
2714 void Preprocessor::HandleIfdefDirective(
Token &
Result,
2715 const Token &HashToken,
2717 bool ReadAnyTokensBeforeDirective) {
2722 ReadMacroName(MacroNameTok);
2725 if (MacroNameTok.
is(tok::eod)) {
2728 SkipExcludedConditionalBlock(HashToken.
getLocation(),
2741 if (CurPPLexer->getConditionalStackDepth() == 0) {
2746 if (!ReadAnyTokensBeforeDirective && !MI) {
2747 assert(isIfndef &&
"#ifdef shouldn't reach here");
2748 CurPPLexer->MIOpt.EnterTopLevelIfndef(MII, MacroNameTok.
getLocation());
2750 CurPPLexer->MIOpt.EnterTopLevelConditional();
2759 Callbacks->Ifndef(DirectiveTok.
getLocation(), MacroNameTok, MD);
2761 Callbacks->Ifdef(DirectiveTok.
getLocation(), MacroNameTok, MD);
2765 if (PPOpts->SingleFileParseMode && !MI) {
2768 CurPPLexer->pushConditionalLevel(DirectiveTok.
getLocation(),
2771 }
else if (!MI == isIfndef) {
2773 CurPPLexer->pushConditionalLevel(DirectiveTok.
getLocation(),
2778 SkipExcludedConditionalBlock(HashToken.
getLocation(),
2787 void Preprocessor::HandleIfDirective(
Token &IfToken,
2788 const Token &HashToken,
2789 bool ReadAnyTokensBeforeDirective) {
2794 const SourceLocation ConditionalBegin = CurPPLexer->getSourceLocation();
2795 const DirectiveEvalResult DER = EvaluateDirectiveExpression(IfNDefMacro);
2796 const bool ConditionalTrue = DER.Conditional;
2797 const SourceLocation ConditionalEnd = CurPPLexer->getSourceLocation();
2801 if (CurPPLexer->getConditionalStackDepth() == 0) {
2802 if (!ReadAnyTokensBeforeDirective && IfNDefMacro && ConditionalTrue)
2804 CurPPLexer->MIOpt.EnterTopLevelIfndef(IfNDefMacro, IfToken.
getLocation());
2806 CurPPLexer->MIOpt.EnterTopLevelConditional();
2815 if (PPOpts->SingleFileParseMode && DER.IncludedUndefinedIds) {
2818 CurPPLexer->pushConditionalLevel(IfToken.
getLocation(),
false,
2820 }
else if (ConditionalTrue) {
2822 CurPPLexer->pushConditionalLevel(IfToken.
getLocation(),
false,
2834 void Preprocessor::HandleEndifDirective(
Token &EndifToken) {
2841 if (CurPPLexer->popConditionalLevel(CondInfo)) {
2843 Diag(EndifToken, diag::err_pp_endif_without_if);
2848 if (CurPPLexer->getConditionalStackDepth() == 0)
2849 CurPPLexer->MIOpt.ExitTopLevelConditional();
2851 assert(!CondInfo.
WasSkipping && !CurPPLexer->LexingRawMode &&
2852 "This code should only be reachable in the non-skipping case!");
2860 void Preprocessor::HandleElseDirective(
Token &Result,
const Token &HashToken) {
2867 if (CurPPLexer->popConditionalLevel(CI)) {
2868 Diag(Result, diag::pp_err_else_without_if);
2873 if (CurPPLexer->getConditionalStackDepth() == 0)
2874 CurPPLexer->MIOpt.EnterTopLevelConditional();
2877 if (CI.
FoundElse)
Diag(Result, diag::pp_err_else_after_else);
2885 CurPPLexer->pushConditionalLevel(CI.
IfLoc,
false,
2898 void Preprocessor::HandleElifDirective(
Token &ElifToken,
2899 const Token &HashToken) {
2905 const SourceLocation ConditionalBegin = CurPPLexer->getSourceLocation();
2907 const SourceLocation ConditionalEnd = CurPPLexer->getSourceLocation();
2910 if (CurPPLexer->popConditionalLevel(CI)) {
2911 Diag(ElifToken, diag::pp_err_elif_without_if);
2916 if (CurPPLexer->getConditionalStackDepth() == 0)
2917 CurPPLexer->MIOpt.EnterTopLevelConditional();
2920 if (CI.
FoundElse)
Diag(ElifToken, diag::pp_err_elif_after_else);
2930 CurPPLexer->pushConditionalLevel(ElifToken.
getLocation(),
false,
2936 SkipExcludedConditionalBlock(
StringRef tryGetRealPathName() const
std::string Name
The name of this module.
Module * getModuleForLocation(SourceLocation Loc)
Find the module that owns the source or header file that Loc points to.
SourceLocation getLocWithOffset(int Offset) const
Return a source location with the specified offset from this SourceLocation.
MacroInfo * AllocateMacroInfo(SourceLocation L)
Allocate a new MacroInfo object with the provided SourceLocation.
bool ConcatenateIncludeName(SmallString< 128 > &FilenameBuffer, SourceLocation &End)
Handle cases where the #include name is expanded from a macro as multiple tokens, which need to be gl...
void AddTokenToBody(const Token &Tok)
Add the specified token to the replacement text for the macro.
void markMacroAsUsed(MacroInfo *MI)
A macro is used, update information about macros that need unused warnings.
void sawOpeningParen(SourceLocation LParenLoc)
Call this function each time an lparen is seen.
IdentifierInfo * getIdentifierInfo(StringRef Name) const
Return information about the specified preprocessor identifier token.
Defines the clang::FileManager interface and associated types.
static bool ReadLineMarkerFlags(bool &IsFileEntry, bool &IsFileExit, SrcMgr::CharacteristicKind &FileKind, Preprocessor &PP)
ReadLineMarkerFlags - Parse and validate any flags at the end of a GNU line marker directive...
This header is part of the module (for layering purposes) but should be textually included...
const Token & LookAhead(unsigned N)
Peeks ahead N tokens and returns that token without consuming any tokens.
PPConditionalInfo & peekConditionalLevel()
Return the top of the conditional stack.
StringRef getBufferName(SourceLocation Loc, bool *Invalid=nullptr) const
Return the filename or buffer identifier of the buffer the location is in.
static bool isReservedId(StringRef Text, const LangOptions &Lang)
Checks if the specified identifier is reserved in the specified language.
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {...
Module * getTopLevelModule()
Retrieve the top-level module for this (sub)module, which may be this module.
bool sawClosingParen()
Call this function each time an rparen is seen.
Defines the SourceManager interface.
Defines the clang::Module class, which describes a module in the source code.
Module * getCurrentModule()
Retrieves the module that we're currently building, if any.
void pushConditionalLevel(SourceLocation DirectiveStart, bool WasSkipping, bool FoundNonSkip, bool FoundElse)
pushConditionalLevel - When we enter a #if directive, this keeps track of what we are currently in fo...
unsigned IsFramework
Whether this is a framework module.
bool isInPrimaryFile() const
Return true if we're in the top-level file, not in a #include.
Defines the clang::MacroInfo and clang::MacroDirective classes.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
A directive for an undefined macro.
bool getSuppressSystemWarnings() const
void setCodeCompletionReached()
Note that we hit the code-completion point.
bool hadModuleLoaderFatalFailure() const
const FileEntry * LookupFile(SourceLocation FilenameLoc, StringRef Filename, bool isAngled, const DirectoryLookup *FromDir, const FileEntry *FromFile, const DirectoryLookup *&CurDir, SmallVectorImpl< char > *SearchPath, SmallVectorImpl< char > *RelativePath, ModuleMap::KnownHeader *SuggestedModule, bool *IsMapped, bool SkipCache=false)
Given a "foo" or <foo> reference, look up the indicated file.
CharacteristicKind
Indicates whether a file or directory holds normal user code, system code, or system code which is im...
void setIsWarnIfUnused(bool val)
Set the value of the IsWarnIfUnused flag.
tok::TokenKind getKind() const
static MacroDiag shouldWarnOnMacroDef(Preprocessor &PP, IdentifierInfo *II)
DefMacroDirective * appendDefMacroDirective(IdentifierInfo *II, MacroInfo *MI, SourceLocation Loc)
One of these records is kept for each identifier that is lexed.
A directive for a defined macro or a macro imported from a module.
bool ParsingPreprocessorDirective
True when parsing #XXX; turns '\n' into a tok::eod token.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
bool CheckMacroName(Token &MacroNameTok, MacroUse isDefineUndef, bool *ShadowFlag=nullptr)
void EnterSubmodule(Module *M, SourceLocation ImportLoc, bool ForPragma)
static void diagnoseAutoModuleImport(Preprocessor &PP, SourceLocation HashLoc, Token &IncludeTok, ArrayRef< std::pair< IdentifierInfo *, SourceLocation >> Path, SourceLocation PathEnd)
Produce a diagnostic informing the user that a #include or similar was implicitly treated as a module...
bool isCPlusPlusOperatorKeyword() const
const TargetInfo & getTargetInfo() const
Token - This structure provides full information about a lexed token.
static bool trySimplifyPath(SmallVectorImpl< StringRef > &Components, StringRef RealPathName)
void setKind(tok::TokenKind K)
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
const LangOptions & getLangOpts() const
Describes a module or submodule.
bool popConditionalLevel(PPConditionalInfo &CI)
popConditionalLevel - Remove an entry off the top of the conditional stack, returning information abo...
A directive for setting the module visibility of a macro.
StringRef getTopLevelModuleName() const
Retrieve the name of the top-level module.
std::pair< FileID, unsigned > getDecomposedExpansionLoc(SourceLocation Loc) const
Decompose the specified location into a raw FileID + Offset pair.
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.
bool GetIncludeFilenameSpelling(SourceLocation Loc, StringRef &Buffer)
Turn the specified lexer token into a fully checked and spelled filename, e.g.
Module * Parent
The parent of this module.
bool isUsed() const
Return false if this macro is defined in the main file and has not yet been used. ...
bool FoundNonSkip
True if we have emitted tokens already, and now we're in an #else block or something.
LLVM_READONLY bool isUppercase(unsigned char c)
Return true if this character is an uppercase ASCII letter: [A-Z].
void appendMacroDirective(IdentifierInfo *II, MacroDirective *MD)
Add a directive to the macro directive history for this identifier.
void LexUnexpandedToken(Token &Result)
Just like Lex, but disables macro expansion of identifier tokens.
MacroDiag
Enumerates possible cases of #define/#undef a reserved identifier.
unsigned IsSystem
Whether this is a "system" module (which assumes that all headers in it are system headers)...
void HandleSkippedDirectiveWhileUsingPCH(Token &Result, SourceLocation HashLoc)
Process directives while skipping until the through header or #pragma hdrstop is found.
std::string CurrentModule
The name of the current module, of which the main source file is a part.
const DirectoryEntry * getDirectory(StringRef DirName, bool CacheFailure=true)
Lookup, cache, and verify the specified directory (real or virtual).
Describes the result of attempting to load a module.
Exposes information about the current target.
void setAnnotationValue(void *val)
void diagnoseHeaderInclusion(Module *RequestingModule, bool RequestingModuleIsModuleInterface, SourceLocation FilenameLoc, StringRef Filename, const FileEntry *File)
Reports errors if a module must not include a specific file.
Defines the clang::LangOptions interface.
bool LexingRawMode
True if in raw mode.
Represents a character-granular source range.
void setHasCommaPasting()
bool isInvalid() const
Return true if this object is invalid or uninitialized.
void makeModuleVisible(Module *M, SourceLocation Loc)
bool isInSystemHeader(SourceLocation Loc) const
Returns if a SourceLocation is in a system header.
const FileEntry * getFileEntryForID(FileID FID) const
Returns the FileEntry record for the provided FileID.
bool usingPCHWithThroughHeader()
True if using a PCH with a through header.
bool isPCHThroughHeader(const FileEntry *FE)
Returns true if the FileEntry is the PCH through header.
A class for tracking whether we're inside a VA_OPT during a traversal of the tokens of a variadic mac...
static bool warnByDefaultOnWrongCase(StringRef Include)
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file. ...
Defines the clang::Preprocessor interface.
ResetMacroExpansionHelper(Preprocessor *pp)
LLVM_READONLY bool isAlphanumeric(unsigned char c)
Return true if this character is an ASCII letter or digit: [a-zA-Z0-9].
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.
bool isRecordingPreamble() const
static CharSourceRange getCharRange(SourceRange R)
SourceManager & getSourceManager() const
virtual SourceLocation getSourceLocation()=0
Return the source location for the next observable location.
MacroDirective * getLocalMacroDirective(const IdentifierInfo *II) const
Given an identifier, return its latest non-imported MacroDirective if it is #define'd and not #undef'...
const DirectoryEntry * getDir() const
Return the directory the file lives in.
bool isVAOptToken(const Token &T) const
void setIsFunctionLike()
Function/Object-likeness.
Encapsulates changes to the "macros namespace" (the location where the macro name became active...
bool WasSkipping
True if this was contained in a skipping directive, e.g., in a "\#if 0" block.
Encodes a location in the source.
bool isConfigMismatch() const
Determines whether the module failed to load due to a configuration mismatch with an explicitly-named...
friend class VariadicMacroScopeGuard
MacroDefinition getMacroDefinition(const IdentifierInfo *II)
All of the names in this module are hidden.
IdentifierInfo * getIdentifierInfo() const
void setAnnotationEndLoc(SourceLocation L)
Cached information about one file (either on disk or in the virtual file system). ...
virtual void CodeCompleteInConditionalExclusion()
Callback invoked when performing code completion within a block of code that was excluded due to prep...
void setIsC99Varargs()
Varargs querying methods. This can only be set for function-like macros.
bool isInVAOpt() const
Returns true if we have seen the VA_OPT and '(' but before having seen the matching ')'...
void Lex(Token &Result)
Lex the next token for this preprocessor.
const char * getNameStart() const
Return the beginning of the actual null-terminated string for this identifier.
void setDefinitionEndLoc(SourceLocation EndLoc)
Set the location of the last token in the macro.
bool isAtStartOfLine() const
isAtStartOfLine - Return true if this token is at the start of a line.
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
bool isInMainFile(SourceLocation Loc) const
Returns whether the PresumedLoc for a given SourceLocation is in the main file.
std::string ModuleName
The module currently being compiled as speficied by -fmodule-name.
std::pair< std::string, bool > Requirement
An individual requirement: a feature name and a flag indicating the required state of that feature...
bool isC99Varargs() const
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
StringRef getName() const
Return the actual identifier string.
SourceLocation IfLoc
Location where the conditional started.
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
bool isNot(tok::TokenKind K) const
static bool isInvalid(LocType Loc, bool *Invalid)
bool EnterSourceFile(FileID FID, const DirectoryLookup *Dir, SourceLocation Loc)
Add a source file to the top of the include stack and start lexing tokens from it instead of the curr...
Dataflow Directional Tag Classes.
bool isWarnIfUnused() const
Return true if we should emit a warning if the macro is unused.
bool isValid() const
Return true if this is a valid SourceLocation object.
The pragma was introduced via #pragma.
unsigned getNumTokens() const
Return the number of tokens that this macro expands to.
const FileEntry * getFileEntry() const
getFileEntry - Return the FileEntry corresponding to this FileID.
static bool isConfigurationPattern(Token &MacroName, MacroInfo *MI, const LangOptions &LOptions)
ArrayRef< KnownHeader > findAllModulesForHeader(const FileEntry *File) const
Retrieve all the modules that contain the given header file.
SourceLocation getIncludeLoc(FileID FID) const
Returns the include location if FID is a #include'd file otherwise it returns an invalid location...
FileID getMainFileID() const
Returns the FileID of the main source file.
bool isMissingExpected() const
Determines whether the module, which failed to load, was actually a submodule that we expected to see...
static bool isForModuleBuilding(Module *M, StringRef CurrentModule, StringRef ModuleName)
bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const
tok::PPKeywordKind getPPKeywordID() const
Return the preprocessor keyword ID for this identifier.
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.
static MacroDiag shouldWarnOnMacroUndef(Preprocessor &PP, IdentifierInfo *II)
unsigned getLength() const
Encapsulates the data about a macro definition (e.g.
SourceLocation DefinitionLoc
The location of the module definition.
LLVM_READONLY bool isDigit(unsigned char c)
Return true if this character is an ASCII digit: [0-9].
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
int getParameterNum(const IdentifierInfo *Arg) const
Return the parameter number of the specified identifier, or -1 if the identifier is not a formal para...
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
SourceLocation getDefinitionLoc() const
Return the location that the macro was defined at.
void CheckEndOfDirective(const char *DirType, bool EnableMacros=false)
Ensure that the next token is a tok::eod token.
Cached information about one directory (either on disk or in the virtual file system).
Defines the PPCallbacks interface.
Defines the clang::TokenKind enum and support functions.
static bool GetLineValue(Token &DigitTok, unsigned &Val, unsigned DiagID, Preprocessor &PP, bool IsGNULineDirective=false)
GetLineValue - Convert a numeric token into an unsigned value, emitting Diagnostic DiagID if it is in...
virtual void CodeCompleteMacroName(bool IsDefinition)
Callback invoked when performing code completion in a context where the name of a macro is expected...
Defines the clang::SourceLocation class and associated facilities.
FileID getPredefinesFileID() const
Returns the FileID for the preprocessor predefines.
DiagnosticsEngine & getDiagnostics() const
bool isIdenticalTo(const MacroInfo &Other, Preprocessor &PP, bool Syntactically) const
Return true if the specified macro definition is equal to this macro in spelling, arguments...
StringRef getRawIdentifier() const
getRawIdentifier - For a raw identifier token (i.e., an identifier lexed in raw mode), returns a reference to the text substring in the buffer if known.
bool isBuiltinMacro() const
Return true if this macro requires processing before expansion.
StringLiteralParser - This decodes string escape characters and performs wide string analysis and Tra...
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string...
void sawVAOptFollowedByOpeningParens(const SourceLocation LParenLoc)
Call this function as soon as you see VA_OPT and '('.
const FileEntry * getModuleHeaderToIncludeForDiagnostics(SourceLocation IncLoc, Module *M, SourceLocation MLoc)
We want to produce a diagnostic at location IncLoc concerning a missing module import.
bool needsCleaning() const
Return true if this token has trigraphs or escaped newlines in it.
__DEVICE__ int max(int __a, int __b)
void DiscardUntilEndOfDirective()
Read and discard all tokens remaining on the current line until the tok::eod token is found...
Annotates a diagnostic with some code that should be inserted, removed, or replaced to fix the proble...
void setLocation(SourceLocation L)
A trivial tuple used to represent a source range.
void setParameterList(ArrayRef< IdentifierInfo *> List, llvm::BumpPtrAllocator &PPAllocator)
Set the specified list of identifiers as the parameter list for this macro.
PreprocessorLexer * getCurrentFileLexer() const
Return the current file lexer being lexed from.
void EnterAnnotationToken(SourceRange Range, tok::TokenKind Kind, void *AnnotationVal)
Enter an annotation token into the token stream.
SourceLocation getIncludeLoc() const
Return the presumed include location of this location.
bool FoundElse
True if we've seen a #else in this block.
SourceLocation getBegin() const
bool hasLeadingSpace() const
Return true if this token has whitespace before it.
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const
Forwarding function for diagnostics.
VerifyDiagnosticConsumer::Directive Directive
This class handles loading and caching of source files into memory.
void startToken()
Reset all flags to cleared.
~ResetMacroExpansionHelper()
An RAII class that tracks when the Preprocessor starts and stops lexing the definition of a (ISO C/C+...
Engages in a tight little dance with the lexer to efficiently preprocess tokens.