26 #include "llvm/ADT/APInt.h"
27 #include "llvm/Support/ErrorHandling.h"
28 #include "llvm/Support/Path.h"
29 #include "llvm/Support/SaveAndRestore.h"
30 using namespace clang;
36 MacroInfo *Preprocessor::AllocateMacroInfo() {
37 MacroInfoChain *MIChain = BP.Allocate<MacroInfoChain>();
38 MIChain->Next = MIChainHead;
39 MIChainHead = MIChain;
50 unsigned SubModuleID) {
51 static_assert(llvm::AlignOf<MacroInfo>::Alignment >=
sizeof(SubModuleID),
52 "alignment for MacroInfo is less than the ID");
53 DeserializedMacroInfoChain *MIChain =
54 BP.Allocate<DeserializedMacroInfoChain>();
55 MIChain->Next = DeserialMIChainHead;
56 DeserialMIChainHead = MIChain;
60 MI->FromASTFile =
true;
61 MI->setOwningModuleID(SubModuleID);
71 Preprocessor::AllocateUndefMacroDirective(
SourceLocation UndefLoc) {
87 assert(Tmp.
isNot(
tok::eof) &&
"EOF seen while discarding directive tokens");
88 }
while (Tmp.
isNot(tok::eod));
105 if (Text.size() >= 2 && Text[0] ==
'_' &&
111 if (Lang.CPlusPlus) {
112 if (Text.find(
"__") != StringRef::npos)
120 StringRef Text = II->
getName();
125 if (Lang.CPlusPlus11 && (Text.equals(
"override") || Text.equals(
"final")))
132 StringRef Text = II->
getName();
142 if (MacroNameTok.
is(tok::eod))
143 return Diag(MacroNameTok, diag::err_pp_missing_macro_name);
147 bool Invalid =
false;
148 std::string Spelling =
getSpelling(MacroNameTok, &Invalid);
150 return Diag(MacroNameTok, diag::err_pp_macro_not_identifier);
154 return Diag(MacroNameTok, diag::err_pp_macro_not_identifier);
159 ? diag::ext_pp_operator_used_as_macro_name
160 : diag::err_pp_operator_used_as_macro_name)
161 << II << MacroNameTok.
getKind();
170 return Diag(MacroNameTok, diag::err_defined_macro_name);
178 Diag(MacroNameTok, diag::ext_pp_undef_builtin_macro);
188 (strcmp(SourceMgr.
getBufferName(MacroNameLoc),
"<built-in>") != 0)) {
203 Diag(MacroNameTok, diag::warn_pp_macro_is_reserved_id);
219 void Preprocessor::ReadMacroName(
Token &MacroNameTok,
MacroUse isDefineUndef,
224 if (MacroNameTok.
is(tok::code_completion)) {
236 if (MacroNameTok.
isNot(tok::eod)) {
237 MacroNameTok.
setKind(tok::eod);
258 while (Tmp.
is(tok::comment))
261 if (Tmp.
isNot(tok::eod)) {
267 if ((LangOpts.GNUMode || LangOpts.C99 || LangOpts.CPlusPlus) &&
270 Diag(Tmp, diag::ext_pp_extra_tokens_at_eol) << DirType << Hint;
285 void Preprocessor::SkipExcludedConditionalBlock(
SourceLocation IfTokenLoc,
286 bool FoundNonSkipPortion,
290 assert(!CurTokenLexer && CurPPLexer &&
"Lexing a macro, not a file?");
293 FoundNonSkipPortion, FoundElse);
296 PTHSkipExcludedConditionalBlock();
307 if (Tok.
is(tok::code_completion)) {
319 if (CurLexer->getFileLoc() != CodeCompletionFileLoc)
321 diag::err_pp_unterminated_conditional);
337 if (CurLexer) CurLexer->SetKeepWhitespaceMode(
false);
345 if (Tok.
isNot(tok::raw_identifier)) {
348 if (CurLexer) CurLexer->resetExtendedTokenMode();
359 char FirstChar = RI[0];
360 if (FirstChar >=
'a' && FirstChar <=
'z' &&
361 FirstChar !=
'i' && FirstChar !=
'e') {
364 if (CurLexer) CurLexer->resetExtendedTokenMode();
371 char DirectiveBuf[20];
377 unsigned IdLen = DirectiveStr.size();
381 if (CurLexer) CurLexer->resetExtendedTokenMode();
384 memcpy(DirectiveBuf, &DirectiveStr[0], IdLen);
385 Directive = StringRef(DirectiveBuf, IdLen);
388 if (Directive.startswith(
"if")) {
389 StringRef Sub = Directive.substr(2);
400 }
else if (Directive[0] ==
'e') {
401 StringRef Sub = Directive.substr(1);
407 assert(!InCond &&
"Can't be skipping if not in a conditional!");
422 }
else if (Sub ==
"lse") {
429 if (CondInfo.
FoundElse)
Diag(Tok, diag::pp_err_else_after_else);
449 }
else if (Sub ==
"lif") {
453 if (CondInfo.
FoundElse)
Diag(Tok, diag::pp_err_elif_after_else);
463 assert(CurPPLexer->
LexingRawMode &&
"We have to be skipping here!");
466 const bool CondValue = EvaluateDirectiveExpression(IfNDefMacro);
485 if (CurLexer) CurLexer->resetExtendedTokenMode();
499 void Preprocessor::PTHSkipExcludedConditionalBlock() {
503 assert(CurPTHLexer->LexingRawMode ==
false);
506 if (CurPTHLexer->SkipBlock()) {
510 bool InCond = CurPTHLexer->popConditionalLevel(CondInfo);
512 assert(!InCond &&
"Can't be skipping if not in a conditional!");
525 if (K == tok::pp_else) {
538 CurPTHLexer->ParsingPreprocessorDirective =
true;
540 CurPTHLexer->ParsingPreprocessorDirective =
false;
549 assert(K == tok::pp_elif);
554 Diag(Tok, diag::pp_err_elif_after_else);
563 CurPTHLexer->ParsingPreprocessorDirective =
true;
564 bool ShouldEnter = EvaluateDirectiveExpression(IfNDefMacro);
565 CurPTHLexer->ParsingPreprocessorDirective =
false;
618 if (!FromDir && !FromFile) {
636 Includers.push_back(std::make_pair(
nullptr, MainFileDir));
639 Includers.push_back(std::make_pair(FileEnt, FileMgr.
getDirectory(
".")));
641 Includers.push_back(std::make_pair(FileEnt, FileEnt->
getDir()));
647 if (LangOpts.MSVCCompat && !isAngled) {
648 for (
unsigned i = 0, e = IncludeMacroStack.size(); i != e; ++i) {
649 IncludeStackInfo &ISEntry = IncludeMacroStack[e - i - 1];
650 if (IsFileLexer(ISEntry))
652 ISEntry.ThePPLexer->getFileID())))
653 Includers.push_back(std::make_pair(FileEnt, FileEnt->
getDir()));
658 CurDir = CurDirLookup;
666 Filename, FilenameLoc, isAngled, TmpFromDir, TmpCurDir,
667 Includers, SearchPath, RelativePath, SuggestedModule,
670 TmpFromDir = TmpCurDir;
672 if (FE == FromFile) {
674 FromDir = TmpFromDir;
683 Filename, FilenameLoc, isAngled, FromDir, CurDir, Includers, SearchPath,
684 RelativePath, SuggestedModule, SkipCache);
686 if (SuggestedModule && !LangOpts.AsmPreprocessor)
699 SearchPath, RelativePath,
701 if (SuggestedModule && !LangOpts.AsmPreprocessor)
709 for (
unsigned i = 0, e = IncludeMacroStack.size(); i != e; ++i) {
710 IncludeStackInfo &ISEntry = IncludeMacroStack[e-i-1];
711 if (IsFileLexer(ISEntry)) {
715 Filename, CurFileEnt, SearchPath, RelativePath,
717 if (SuggestedModule && !LangOpts.AsmPreprocessor)
738 : PP(pp), save(pp->DisableMacroExpansion) {
739 if (pp->MacroExpansionInDirectivesOverride)
740 pp->DisableMacroExpansion =
false;
743 PP->DisableMacroExpansion = save;
761 if (CurLexer) CurLexer->SetKeepWhitespaceMode(
false);
763 bool ImmediatelyAfterTopLevelIfndef =
791 switch (II->getPPKeywordID()) {
792 case tok::pp_include:
794 case tok::pp_include_next:
795 case tok::pp___include_macros:
797 Diag(Result, diag::err_embedded_directive) << II->getName();
804 Diag(Result, diag::ext_embedded_directive);
814 case tok::code_completion:
820 case tok::numeric_constant:
823 return HandleDigitDirective(Result);
833 return HandleIfDirective(Result, ReadAnyTokensBeforeDirective);
835 return HandleIfdefDirective(Result,
false,
true);
837 return HandleIfdefDirective(Result,
true, ReadAnyTokensBeforeDirective);
839 return HandleElifDirective(Result);
841 return HandleElseDirective(Result);
843 return HandleEndifDirective(Result);
846 case tok::pp_include:
849 case tok::pp___include_macros:
855 return HandleDefineDirective(Result, ImmediatelyAfterTopLevelIfndef);
857 return HandleUndefDirective(Result);
861 return HandleLineDirective(Result);
865 return HandleUserDiagnosticDirective(Result,
false);
874 case tok::pp_include_next:
877 case tok::pp_warning:
878 Diag(Result, diag::ext_pp_warning_directive);
879 return HandleUserDiagnosticDirective(Result,
true);
881 return HandleIdentSCCSDirective(Result);
883 return HandleIdentSCCSDirective(Result);
887 case tok::pp_unassert:
891 case tok::pp___public_macro:
893 return HandleMacroPublicDirective(Result);
896 case tok::pp___private_macro:
898 return HandleMacroPrivateDirective(Result);
916 if (Result.
is(tok::hashhash))
917 Toks[1].setKind(tok::unknown);
927 Diag(Result, diag::err_pp_invalid_directive);
939 bool IsGNULineDirective=
false) {
940 if (DigitTok.
isNot(tok::numeric_constant)) {
941 PP.
Diag(DigitTok, DiagID);
943 if (DigitTok.
isNot(tok::eod))
949 IntegerBuffer.resize(DigitTok.
getLength());
950 const char *DigitTokBegin = &IntegerBuffer[0];
951 bool Invalid =
false;
952 unsigned ActualLength = PP.
getSpelling(DigitTok, DigitTokBegin, &Invalid);
960 for (
unsigned i = 0; i != ActualLength; ++i) {
963 if (DigitTokBegin[i] ==
'\'')
966 if (!
isDigit(DigitTokBegin[i])) {
968 diag::err_pp_line_digit_sequence) << IsGNULineDirective;
973 unsigned NextVal = Val*10+(DigitTokBegin[i]-
'0');
975 PP.
Diag(DigitTok, DiagID);
982 if (DigitTokBegin[0] ==
'0' && Val)
984 << IsGNULineDirective;
996 void Preprocessor::HandleLineDirective(
Token &Tok) {
1004 if (
GetLineValue(DigitTok, LineNo, diag::err_pp_line_requires_integer,*
this))
1008 Diag(DigitTok, diag::ext_pp_line_zero);
1012 unsigned LineLimit = 32768U;
1013 if (LangOpts.C99 || LangOpts.CPlusPlus11)
1014 LineLimit = 2147483648U;
1015 if (LineNo >= LineLimit)
1016 Diag(DigitTok, diag::ext_pp_line_too_big) << LineLimit;
1017 else if (LangOpts.CPlusPlus11 && LineNo >= 32768U)
1018 Diag(DigitTok, diag::warn_cxx98_compat_pp_line_too_big);
1020 int FilenameID = -1;
1026 if (StrTok.
is(tok::eod))
1028 else if (StrTok.
isNot(tok::string_literal)) {
1029 Diag(StrTok, diag::err_pp_line_invalid_filename);
1032 Diag(StrTok, diag::err_invalid_string_udl);
1037 assert(Literal.isAscii() &&
"Didn't allow wide strings in");
1038 if (Literal.hadError)
1040 if (Literal.Pascal) {
1041 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1062 bool &IsSystemHeader,
bool &IsExternCHeader,
1067 if (FlagTok.
is(tok::eod))
return false;
1068 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag, PP))
1075 if (FlagTok.
is(tok::eod))
return false;
1076 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag,PP))
1078 }
else if (FlagVal == 2) {
1095 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_pop);
1101 if (FlagTok.
is(tok::eod))
return false;
1102 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag,PP))
1108 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1113 IsSystemHeader =
true;
1116 if (FlagTok.
is(tok::eod))
return false;
1117 if (
GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag, PP))
1122 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1127 IsExternCHeader =
true;
1130 if (FlagTok.
is(tok::eod))
return false;
1133 PP.
Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
1145 void Preprocessor::HandleDigitDirective(
Token &DigitTok) {
1149 if (
GetLineValue(DigitTok, LineNo, diag::err_pp_linemarker_requires_integer,
1156 bool IsFileEntry =
false, IsFileExit =
false;
1157 bool IsSystemHeader =
false, IsExternCHeader =
false;
1158 int FilenameID = -1;
1162 if (StrTok.
is(tok::eod))
1164 else if (StrTok.
isNot(tok::string_literal)) {
1165 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1168 Diag(StrTok, diag::err_invalid_string_udl);
1173 assert(Literal.isAscii() &&
"Didn't allow wide strings in");
1174 if (Literal.hadError)
1176 if (Literal.Pascal) {
1177 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
1184 IsSystemHeader, IsExternCHeader, *
this))
1190 IsFileEntry, IsFileExit,
1191 IsSystemHeader, IsExternCHeader);
1200 else if (IsFileExit)
1203 if (IsExternCHeader)
1205 else if (IsSystemHeader)
1215 void Preprocessor::HandleUserDiagnosticDirective(
Token &Tok,
1219 return CurPTHLexer->DiscardToEndOfLine();
1227 CurLexer->ReadToEndOfLine(&Message);
1231 StringRef Msg = StringRef(Message).ltrim(
" ");
1234 Diag(Tok, diag::pp_hash_warning) << Msg;
1236 Diag(Tok, diag::err_pp_hash_error) << Msg;
1241 void Preprocessor::HandleIdentSCCSDirective(
Token &Tok) {
1243 Diag(Tok, diag::ext_pp_ident_directive);
1250 if (StrTok.
isNot(tok::string_literal) &&
1251 StrTok.
isNot(tok::wide_string_literal)) {
1252 Diag(StrTok, diag::err_pp_malformed_ident);
1253 if (StrTok.
isNot(tok::eod))
1259 Diag(StrTok, diag::err_invalid_string_udl);
1267 bool Invalid =
false;
1275 void Preprocessor::HandleMacroPublicDirective(
Token &Tok) {
1277 ReadMacroName(MacroNameTok,
MU_Undef);
1280 if (MacroNameTok.
is(tok::eod))
1292 Diag(MacroNameTok, diag::err_pp_visibility_non_macro) << II;
1302 void Preprocessor::HandleMacroPrivateDirective(
Token &Tok) {
1304 ReadMacroName(MacroNameTok,
MU_Undef);
1307 if (MacroNameTok.
is(tok::eod))
1319 Diag(MacroNameTok, diag::err_pp_visibility_non_macro) << II;
1339 StringRef &Buffer) {
1341 assert(!Buffer.empty() &&
"Can't have tokens with empty spellings!");
1345 if (Buffer[0] ==
'<') {
1346 if (Buffer.back() !=
'>') {
1347 Diag(Loc, diag::err_pp_expects_filename);
1348 Buffer = StringRef();
1352 }
else if (Buffer[0] ==
'"') {
1353 if (Buffer.back() !=
'"') {
1354 Diag(Loc, diag::err_pp_expects_filename);
1355 Buffer = StringRef();
1360 Diag(Loc, diag::err_pp_expects_filename);
1361 Buffer = StringRef();
1366 if (Buffer.size() <= 2) {
1367 Diag(Loc, diag::err_pp_empty_filename);
1368 Buffer = StringRef();
1373 Buffer = Buffer.substr(1, Buffer.size()-2);
1395 while (CurTok.
isNot(tok::eod)) {
1399 if (CurTok.
is(tok::code_completion)) {
1408 FilenameBuffer.push_back(
' ');
1411 unsigned PreAppendSize = FilenameBuffer.size();
1412 FilenameBuffer.resize(PreAppendSize+CurTok.
getLength());
1414 const char *BufPtr = &FilenameBuffer[PreAppendSize];
1418 if (BufPtr != &FilenameBuffer[PreAppendSize])
1419 memcpy(&FilenameBuffer[PreAppendSize], BufPtr, ActualLen);
1423 FilenameBuffer.resize(PreAppendSize+ActualLen);
1426 if (CurTok.
is(tok::greater))
1457 ArrayRef<std::pair<IdentifierInfo *, SourceLocation>> Path,
1459 assert(PP.
getLangOpts().ObjC2 &&
"no import syntax available");
1462 for (
unsigned I = 0, N = Path.size(); I != N; ++I) {
1465 PathString += Path[I].first->getName();
1467 int IncludeKind = 0;
1470 case tok::pp_include:
1474 case tok::pp_import:
1478 case tok::pp_include_next:
1482 case tok::pp___include_macros:
1487 llvm_unreachable(
"unknown include directive kind");
1492 PP.
Diag(HashLoc, diag::warn_auto_module_import)
1493 << IncludeKind << PathString
1495 (
"@import " + PathString +
";").str());
1503 void Preprocessor::HandleIncludeDirective(
SourceLocation HashLoc,
1518 switch (FilenameTok.
getKind()) {
1523 case tok::angle_string_literal:
1524 case tok::string_literal:
1525 Filename =
getSpelling(FilenameTok, FilenameBuffer);
1533 FilenameBuffer.push_back(
'<');
1536 Filename = FilenameBuffer;
1547 StringRef OriginalFilename = Filename;
1552 if (Filename.empty()) {
1564 if (IncludeMacroStack.size() == MaxAllowedIncludeStackDepth-1) {
1565 Diag(FilenameTok, diag::err_pp_include_too_deep);
1570 if (PragmaARCCFCodeAuditedLoc.
isValid()) {
1571 Diag(HashLoc, diag::err_pp_include_in_arc_cf_code_audited);
1572 Diag(PragmaARCCFCodeAuditedLoc, diag::note_pragma_entered_here);
1579 if (PragmaAssumeNonNullLoc.
isValid()) {
1580 Diag(HashLoc, diag::err_pp_include_in_assume_nonnull);
1581 Diag(PragmaAssumeNonNullLoc, diag::note_pragma_entered_here);
1592 if (!NewName.empty())
1605 if (LangOpts.MSVCCompat) {
1606 NormalizedPath = Filename.str();
1607 #ifndef LLVM_ON_WIN32
1608 llvm::sys::path::native(NormalizedPath);
1612 FilenameLoc, LangOpts.MSVCCompat ? NormalizedPath.c_str() : Filename,
1613 isAngled, LookupFrom, LookupFromFile, CurDir,
1614 Callbacks ? &SearchPath :
nullptr, Callbacks ? &RelativePath :
nullptr,
1621 if (Callbacks->FileNotFound(Filename, RecoveryPath)) {
1630 LangOpts.MSVCCompat ? NormalizedPath.c_str() : Filename, isAngled,
1631 LookupFrom, LookupFromFile, CurDir,
nullptr,
nullptr,
1632 &SuggestedModule,
true);
1637 if (!SuppressIncludeNotFoundError) {
1644 LangOpts.MSVCCompat ? NormalizedPath.c_str() : Filename,
false,
1645 LookupFrom, LookupFromFile, CurDir,
1646 Callbacks ? &SearchPath :
nullptr,
1647 Callbacks ? &RelativePath :
nullptr,
1651 Diag(FilenameTok, diag::err_pp_file_not_found_not_fatal) <<
1659 Diag(FilenameTok, diag::err_pp_file_not_found) << Filename;
1667 bool ShouldEnter =
true;
1672 if (File && SuggestedModule &&
getLangOpts().Modules &&
1684 std::reverse(Path.begin(), Path.end());
1698 assert((Imported ==
nullptr || Imported == SuggestedModule.
getModule()) &&
1699 "the imported module is different than the suggested one");
1702 ShouldEnter =
false;
1716 CurLexer->FormTokenWithChars(Result, CurLexer->BufferEnd,
tok::eof);
1717 CurLexer->cutOffLexing();
1719 assert(CurPTHLexer &&
"#include but no current lexer set!");
1720 CurPTHLexer->getEOF(Result);
1729 Callbacks->InclusionDirective(
1730 HashLoc, IncludeTok,
1731 LangOpts.MSVCCompat ? NormalizedPath.c_str() : Filename, isAngled,
1732 FilenameRange, File, SearchPath, RelativePath,
1733 ShouldEnter ?
nullptr : SuggestedModule.
getModule());
1754 ShouldEnter =
false;
1756 Callbacks->FileSkipped(*File, FilenameTok, FileCharacter);
1762 if (
auto *M = SuggestedModule.
getModule()) {
1766 tok::pp___include_macros)
1779 assert(!FID.
isInvalid() &&
"Expected valid file ID");
1786 if (
auto *M = SuggestedModule.
getModule()) {
1787 assert(!CurSubmodule &&
"should not have marked this as a module yet");
1792 EnterSubmodule(M, HashLoc);
1804 void Preprocessor::HandleIncludeNextDirective(
SourceLocation HashLoc,
1805 Token &IncludeNextTok) {
1806 Diag(IncludeNextTok, diag::ext_pp_include_next_directive);
1812 const FileEntry *LookupFromFile =
nullptr;
1815 Diag(IncludeNextTok, diag::pp_include_next_in_primary);
1816 }
else if (CurSubmodule) {
1819 assert(CurPPLexer &&
"#include_next directive in macro?");
1822 }
else if (!Lookup) {
1823 Diag(IncludeNextTok, diag::pp_include_next_absolute_path);
1829 return HandleIncludeDirective(HashLoc, IncludeNextTok, Lookup,
1834 void Preprocessor::HandleMicrosoftImportDirective(
Token &Tok) {
1840 Diag(Tok, diag::err_pp_import_directive_ms );
1851 if (!LangOpts.ObjC1) {
1852 if (LangOpts.MSVCCompat)
1853 return HandleMicrosoftImportDirective(ImportTok);
1854 Diag(ImportTok, diag::ext_pp_import_directive);
1856 return HandleIncludeDirective(HashLoc, ImportTok,
nullptr,
nullptr,
true);
1863 void Preprocessor::HandleIncludeMacrosDirective(
SourceLocation HashLoc,
1864 Token &IncludeMacrosTok) {
1868 if (strcmp(SourceMgr.
getBufferName(Loc),
"<built-in>") != 0) {
1870 diag::pp_include_macros_out_of_predefines);
1877 HandleIncludeDirective(HashLoc, IncludeMacrosTok);
1882 assert(TmpTok.
isNot(
tok::eof) &&
"Didn't find end of -imacros!");
1883 }
while (TmpTok.
isNot(tok::hashhash));
1894 bool Preprocessor::ReadMacroDefinitionArgList(
MacroInfo *MI,
Token &Tok) {
1902 if (Arguments.empty())
1905 Diag(Tok, diag::err_pp_expected_ident_in_arg_list);
1909 Diag(Tok, LangOpts.CPlusPlus11 ?
1910 diag::warn_cxx98_compat_variadic_macro :
1911 diag::ext_variadic_macro);
1914 if (LangOpts.OpenCL) {
1915 Diag(Tok, diag::err_pp_opencl_variadic_macros);
1921 if (Tok.
isNot(tok::r_paren)) {
1922 Diag(Tok, diag::err_pp_missing_rparen_in_macro_def);
1926 Arguments.push_back(Ident__VA_ARGS__);
1931 Diag(Tok, diag::err_pp_missing_rparen_in_macro_def);
1939 Diag(Tok, diag::err_pp_invalid_tok_in_arg_list);
1945 if (std::find(Arguments.begin(), Arguments.end(), II) !=
1947 Diag(Tok, diag::err_pp_duplicate_name_in_arg_list) << II;
1952 Arguments.push_back(II);
1959 Diag(Tok, diag::err_pp_expected_comma_in_arg_list);
1968 Diag(Tok, diag::ext_named_variadic_macro);
1972 if (Tok.
isNot(tok::r_paren)) {
1973 Diag(Tok, diag::err_pp_missing_rparen_in_macro_def);
2003 StringRef ValueText = II->
getName();
2004 StringRef TrimmedValue = ValueText;
2005 if (!ValueText.startswith(
"__")) {
2006 if (ValueText.startswith(
"_"))
2007 TrimmedValue = TrimmedValue.drop_front(1);
2011 TrimmedValue = TrimmedValue.drop_front(2);
2012 if (TrimmedValue.endswith(
"__"))
2013 TrimmedValue = TrimmedValue.drop_back(2);
2015 return TrimmedValue.equals(MacroText);
2022 if (MacroName.
isOneOf(tok::kw_extern, tok::kw_inline, tok::kw_static,
2033 void Preprocessor::HandleDefineDirective(
Token &DefineTok,
2034 bool ImmediatelyAfterHeaderGuard) {
2038 bool MacroShadowsKeyword;
2039 ReadMacroName(MacroNameTok,
MU_Define, &MacroShadowsKeyword);
2042 if (MacroNameTok.
is(tok::eod))
2045 Token LastTok = MacroNameTok;
2049 if (CurLexer) CurLexer->SetCommentRetentionState(KeepMacroComments);
2060 if (Tok.is(tok::eod)) {
2061 if (ImmediatelyAfterHeaderGuard) {
2067 }
else if (Tok.hasLeadingSpace()) {
2071 }
else if (Tok.is(tok::l_paren)) {
2074 if (ReadMacroDefinitionArgList(MI, LastTok)) {
2086 assert(Ident__VA_ARGS__->
isPoisoned() &&
"__VA_ARGS__ should be poisoned!");
2092 }
else if (LangOpts.C99 || LangOpts.CPlusPlus11) {
2095 Diag(Tok, diag::ext_c99_whitespace_required_after_macro_name);
2104 if (Tok.is(tok::at))
2106 else if (Tok.is(tok::unknown)) {
2113 Diag(Tok, diag::ext_missing_whitespace_after_macro_name);
2115 Diag(Tok, diag::warn_missing_whitespace_after_macro_name);
2118 if (!Tok.is(tok::eod))
2124 while (Tok.isNot(tok::eod)) {
2135 while (Tok.isNot(tok::eod)) {
2138 if (Tok.isNot(tok::hash) && Tok.isNot(tok::hashhash)) {
2150 Tok.setKind(tok::unknown);
2158 if (Tok.is(tok::hashhash)) {
2167 if (Tok.is(tok::eod)) {
2173 if (NumTokens && Tok.getIdentifierInfo() == Ident__VA_ARGS__ &&
2186 if (Tok.getIdentifierInfo() ==
nullptr ||
2193 if (
getLangOpts().AsmPreprocessor && Tok.isNot(tok::eod)) {
2194 LastTok.
setKind(tok::unknown);
2198 Diag(Tok, diag::err_pp_stringize_not_parameter);
2216 if (MacroShadowsKeyword &&
2218 Diag(MacroNameTok, diag::warn_pp_macro_hides_keyword);
2227 if (NumTokens != 0) {
2248 if (!OtherMI->isUsed() && OtherMI->isWarnIfUnused())
2249 Diag(OtherMI->getDefinitionLoc(), diag::pp_macro_not_used);
2253 if (OtherMI->isBuiltinMacro())
2254 Diag(MacroNameTok, diag::ext_pp_redef_builtin_macro);
2257 else if (!OtherMI->isAllowRedefinitionsWithoutWarning() &&
2258 !MI->
isIdenticalTo(*OtherMI, *
this, LangOpts.MicrosoftExt)) {
2261 Diag(OtherMI->getDefinitionLoc(), diag::note_previous_definition);
2264 if (OtherMI->isWarnIfUnused())
2265 WarnUnusedMacroLocs.erase(OtherMI->getDefinitionLoc());
2282 Callbacks->MacroDefined(MacroNameTok, MD);
2287 void Preprocessor::HandleUndefDirective(
Token &UndefTok) {
2291 ReadMacroName(MacroNameTok,
MU_Undef);
2294 if (MacroNameTok.
is(tok::eod))
2307 Callbacks->MacroUndefined(MacroNameTok, MD);
2321 AllocateUndefMacroDirective(MacroNameTok.
getLocation()));
2334 void Preprocessor::HandleIfdefDirective(
Token &Result,
bool isIfndef,
2335 bool ReadAnyTokensBeforeDirective) {
2340 ReadMacroName(MacroNameTok);
2343 if (MacroNameTok.
is(tok::eod)) {
2346 SkipExcludedConditionalBlock(DirectiveTok.
getLocation(),
2363 if (!ReadAnyTokensBeforeDirective && !MI) {
2364 assert(isIfndef &&
"#ifdef shouldn't reach here");
2376 Callbacks->Ifndef(DirectiveTok.
getLocation(), MacroNameTok, MD);
2378 Callbacks->Ifdef(DirectiveTok.
getLocation(), MacroNameTok, MD);
2382 if (!MI == isIfndef) {
2389 SkipExcludedConditionalBlock(DirectiveTok.
getLocation(),
2397 void Preprocessor::HandleIfDirective(
Token &IfToken,
2398 bool ReadAnyTokensBeforeDirective) {
2404 const bool ConditionalTrue = EvaluateDirectiveExpression(IfNDefMacro);
2410 if (!ReadAnyTokensBeforeDirective && IfNDefMacro && ConditionalTrue)
2423 if (ConditionalTrue) {
2429 SkipExcludedConditionalBlock(IfToken.
getLocation(),
false,
2436 void Preprocessor::HandleEndifDirective(
Token &EndifToken) {
2445 Diag(EndifToken, diag::err_pp_endif_without_if);
2454 "This code should only be reachable in the non-skipping case!");
2462 void Preprocessor::HandleElseDirective(
Token &Result) {
2470 Diag(Result, diag::pp_err_else_without_if);
2479 if (CI.
FoundElse)
Diag(Result, diag::pp_err_else_after_else);
2485 SkipExcludedConditionalBlock(CI.
IfLoc,
true,
2491 void Preprocessor::HandleElifDirective(
Token &ElifToken) {
2503 Diag(ElifToken, diag::pp_err_elif_without_if);
2512 if (CI.
FoundElse)
Diag(ElifToken, diag::pp_err_elif_after_else);
2520 SkipExcludedConditionalBlock(CI.
IfLoc,
true,
bool isAtStartOfLine() const
SourceManager & getSourceManager() const
bool isPoisoned() const
Return true if this token has been poisoned.
bool getHasReadAnyTokensVal() const
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. If the location is in a file ...
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.
PPConditionalInfo & peekConditionalLevel()
Return the top of the conditional stack.
void setArgumentList(IdentifierInfo *const *List, unsigned NumArgs, llvm::BumpPtrAllocator &PPAllocator)
Set the specified list of identifiers as the argument list for this macro.
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. This function does not chec...
Defines the SourceManager interface.
IdentifierInfo * getIdentifierInfo(StringRef Name) const
static bool ReadLineMarkerFlags(bool &IsFileEntry, bool &IsFileExit, bool &IsSystemHeader, bool &IsExternCHeader, Preprocessor &PP)
Module * getCurrentModule()
Retrieves the module that we're currently building, if any.
void pushConditionalLevel(SourceLocation DirectiveStart, bool WasSkipping, bool FoundNonSkip, bool FoundElse)
bool isObjectLike() const
Defines the clang::MacroInfo and clang::MacroDirective classes.
bool hasLeadingSpace() const
Return true if this token has whitespace before it.
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
static MacroDiag shouldWarnOnMacroDef(Preprocessor &PP, IdentifierInfo *II)
Module * getModuleContainingLocation(SourceLocation Loc)
Find the module that contains the specified location, either directly or indirectly.
DefMacroDirective * appendDefMacroDirective(IdentifierInfo *II, MacroInfo *MI, SourceLocation Loc)
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.
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
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.
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)
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.
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. This will be NULL for the top-level 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. Only useful in Skipping blocks.
const FileEntry * getFileEntry() const
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const
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.
bool isCPlusPlusOperatorKeyword() const
void diagnoseHeaderInclusion(Module *RequestingModule, SourceLocation FilenameLoc, StringRef Filename, const FileEntry *File)
Reports errors if a module must not include a specific file.
StringRef getRawIdentifier() const
const FileEntry * getFileEntryForID(FileID FID) const
Returns the FileEntry record for the provided FileID.
std::string CurrentModule
The name of the current module.
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)
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...
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)
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.
Information about the conditional stack (#if directives) currently active.
Represents an unpacked "presumed" location which can be presented to the user.
The result type of a method or function.
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.
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. The SourceManager can decode this to get at the full include stack...
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). ...
void EnterTokenStream(const Token *Toks, unsigned NumToks, bool DisableMacroExpansion, bool OwnsTokens)
Add a "macro" context to the top of the include stack, which will cause the lexer to start returning ...
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
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
unsigned getConditionalStackDepth() const
DiagnosticsEngine & getDiagnostics() const
SourceLocation IfLoc
Location where the conditional started.
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
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.
std::string ImplementationOfModule
The name of the module that the translation unit is an implementation of. Prevents semantic imports...
void EnterTopLevelConditional()
Invoked when a top level conditional (except #ifndef) is found.
Encapsulates the data about a macro definition (e.g. its tokens).
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. as an operand of #incl...
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...
bool isBuiltinMacro() const
Return true if this macro requires processing before expansion.
static bool isInvalid(SourceLocation Loc, bool *Invalid)
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).
static bool GetLineValue(Token &DigitTok, unsigned &Val, unsigned DiagID, Preprocessor &PP, bool IsGNULineDirective=false)
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...
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string...
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. If so, #elif/#else directives are not allowed.
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.