33 #include "llvm/ADT/ArrayRef.h" 34 #include "llvm/ADT/DenseMap.h" 35 #include "llvm/ADT/DenseSet.h" 36 #include "llvm/ADT/FoldingSet.h" 37 #include "llvm/ADT/None.h" 38 #include "llvm/ADT/Optional.h" 39 #include "llvm/ADT/SmallString.h" 40 #include "llvm/ADT/SmallVector.h" 41 #include "llvm/ADT/STLExtras.h" 42 #include "llvm/ADT/StringRef.h" 43 #include "llvm/ADT/StringSwitch.h" 44 #include "llvm/Support/Casting.h" 45 #include "llvm/Support/ErrorHandling.h" 46 #include "llvm/Support/Format.h" 47 #include "llvm/Support/raw_ostream.h" 57 using namespace clang;
63 auto Pos = CurSubmoduleState->Macros.find(II);
64 return Pos == CurSubmoduleState->Macros.end() ? nullptr
65 : Pos->second.getLatest();
69 assert(MD &&
"MacroDirective should be non-zero!");
70 assert(!MD->
getPrevious() &&
"Already attached to a MacroDirective history.");
72 MacroState &StoredMD = CurSubmoduleState->Macros[II];
73 auto *OldMD = StoredMD.getLatest();
75 StoredMD.setLatest(MD);
76 StoredMD.overrideActiveModuleMacros(*
this, II);
78 if (needModuleMacros()) {
82 PendingModuleMacroNames.push_back(II);
87 if (!MD->
isDefined() && LeafModuleMacros.find(II) == LeafModuleMacros.end())
106 MacroState &StoredMD = CurSubmoduleState->Macros[II];
108 if (
auto *OldMD = StoredMD.getLatest()) {
114 assert(OldMD->getMacroInfo()->isBuiltinMacro() &&
115 "only built-ins should have an entry here");
116 assert(!OldMD->getPrevious() &&
"builtin should only have a single entry");
118 StoredMD.setLatest(MD);
125 if (!MD->
isDefined() && LeafModuleMacros.find(II) == LeafModuleMacros.end())
133 llvm::FoldingSetNodeID
ID;
137 if (
auto *MM = ModuleMacros.FindNodeOrInsertPos(ID, InsertPos)) {
143 ModuleMacros.InsertNode(MM, InsertPos);
147 for (
auto *O : Overrides) {
148 HidAny |= (O->NumOverriddenBy == 0);
149 ++O->NumOverriddenBy;
153 auto &LeafMacros = LeafModuleMacros[II];
155 LeafMacros.erase(std::remove_if(LeafMacros.begin(), LeafMacros.end(),
157 return MM->NumOverriddenBy != 0;
163 LeafMacros.push_back(MM);
172 llvm::FoldingSetNodeID
ID;
176 return ModuleMacros.FindNodeOrInsertPos(ID, InsertPos);
179 void Preprocessor::updateModuleMacroInfo(
const IdentifierInfo *II,
180 ModuleMacroInfo &Info) {
181 assert(Info.ActiveModuleMacrosGeneration !=
182 CurSubmoduleState->VisibleModules.getGeneration() &&
183 "don't need to update this macro name info");
184 Info.ActiveModuleMacrosGeneration =
185 CurSubmoduleState->VisibleModules.getGeneration();
187 auto Leaf = LeafModuleMacros.find(II);
188 if (Leaf == LeafModuleMacros.end()) {
193 Info.ActiveModuleMacros.clear();
196 llvm::DenseMap<ModuleMacro *, int> NumHiddenOverrides;
197 for (
auto *O : Info.OverriddenMacros)
198 NumHiddenOverrides[O] = -1;
202 for (
auto *LeafMM : Leaf->second) {
203 assert(LeafMM->getNumOverridingMacros() == 0 &&
"leaf macro overridden");
204 if (NumHiddenOverrides.lookup(LeafMM) == 0)
205 Worklist.push_back(LeafMM);
207 while (!Worklist.empty()) {
208 auto *MM = Worklist.pop_back_val();
209 if (CurSubmoduleState->VisibleModules.isVisible(MM->getOwningModule())) {
212 if (MM->getMacroInfo())
213 Info.ActiveModuleMacros.push_back(MM);
215 for (
auto *O : MM->overrides())
216 if ((
unsigned)++NumHiddenOverrides[O] == O->getNumOverridingMacros())
217 Worklist.push_back(O);
221 std::reverse(Info.ActiveModuleMacros.begin(), Info.ActiveModuleMacros.end());
225 bool IsSystemMacro =
true;
226 bool IsAmbiguous =
false;
227 if (
auto *MD = Info.MD) {
228 while (MD && isa<VisibilityMacroDirective>(MD))
229 MD = MD->getPrevious();
230 if (
auto *DMD = dyn_cast_or_null<DefMacroDirective>(MD)) {
235 for (
auto *Active : Info.ActiveModuleMacros) {
236 auto *NewMI = Active->getMacroInfo();
247 if (MI && NewMI != MI &&
248 !MI->isIdenticalTo(*NewMI, *
this,
true))
250 IsSystemMacro &= Active->getOwningModule()->IsSystem ||
254 Info.IsAmbiguous = IsAmbiguous && !IsSystemMacro;
259 auto LeafIt = LeafModuleMacros.find(II);
260 if (LeafIt != LeafModuleMacros.end())
261 Leaf = LeafIt->second;
262 const MacroState *
State =
nullptr;
263 auto Pos = CurSubmoduleState->Macros.find(II);
264 if (Pos != CurSubmoduleState->Macros.end())
265 State = &Pos->second;
269 llvm::errs() <<
" ambiguous";
270 if (
State && !
State->getOverriddenMacros().empty()) {
271 llvm::errs() <<
" overrides";
272 for (
auto *O :
State->getOverriddenMacros())
273 llvm::errs() <<
" " << O->getOwningModule()->getFullModuleName();
275 llvm::errs() <<
"\n";
278 for (
auto *MD =
State ?
State->getLatest() :
nullptr; MD;
279 MD = MD->getPrevious()) {
286 for (
auto *MM :
State ?
State->getActiveModuleMacros(*
this, II) :
None)
290 while (!Worklist.empty()) {
291 auto *MM = Worklist.pop_back_val();
292 llvm::errs() <<
" ModuleMacro " << MM <<
" " 293 << MM->getOwningModule()->getFullModuleName();
294 if (!MM->getMacroInfo())
295 llvm::errs() <<
" undef";
297 if (Active.count(MM))
298 llvm::errs() <<
" active";
299 else if (!CurSubmoduleState->VisibleModules.isVisible(
300 MM->getOwningModule()))
301 llvm::errs() <<
" hidden";
302 else if (MM->getMacroInfo())
303 llvm::errs() <<
" overridden";
305 if (!MM->overrides().empty()) {
306 llvm::errs() <<
" overrides";
307 for (
auto *O : MM->overrides()) {
308 llvm::errs() <<
" " << O->getOwningModule()->getFullModuleName();
309 if (Visited.insert(O).second)
310 Worklist.push_back(O);
313 llvm::errs() <<
"\n";
314 if (
auto *MI = MM->getMacroInfo()) {
317 llvm::errs() <<
"\n";
337 void Preprocessor::RegisterBuiltinMacros() {
346 if (LangOpts.CPlusPlus)
347 Ident__has_cpp_attribute =
350 Ident__has_cpp_attribute =
nullptr;
358 if (LangOpts.MicrosoftExt) {
362 Ident__identifier =
nullptr;
363 Ident__pragma =
nullptr;
380 Ident__is_target_environment =
388 Ident__MODULE__ =
nullptr;
399 if (!II)
return true;
409 if (ExpansionMI->isEnabled() &&
426 bool Preprocessor::isNextPPTokenLParen() {
430 Val = CurLexer->isNextPPTokenLParen();
431 else if (CurPTHLexer)
432 Val = CurPTHLexer->isNextPPTokenLParen();
434 Val = CurTokenLexer->isNextTokenLParen();
442 for (
const IncludeStackInfo &Entry : llvm::reverse(IncludeMacroStack)) {
444 Val = Entry.TheLexer->isNextPPTokenLParen();
445 else if (Entry.ThePTHLexer)
446 Val = Entry.ThePTHLexer->isNextPPTokenLParen();
448 Val = Entry.TheTokenLexer->isNextTokenLParen();
454 if (Entry.ThePPLexer)
467 bool Preprocessor::HandleMacroExpandedIdentifier(
Token &Identifier,
479 Callbacks->MacroExpands(Identifier, M, Identifier.
getLocation(),
481 ExpandBuiltinMacro(Identifier);
500 Args = ReadMacroCallArgumentList(Identifier, MI, ExpansionEnd);
506 if (!Args)
return true;
508 ++NumFnMacroExpanded;
518 SourceRange ExpansionRange(ExpandLoc, ExpansionEnd);
526 DelayedMacroExpandsCallbacks.push_back(
527 MacroExpandsInfo(Identifier, M, ExpansionRange));
529 Callbacks->MacroExpands(Identifier, M, ExpansionRange, Args);
530 if (!DelayedMacroExpandsCallbacks.empty()) {
531 for (
const MacroExpandsInfo &Info : DelayedMacroExpandsCallbacks) {
533 Callbacks->MacroExpands(Info.Tok, Info.MD, Info.Range,
536 DelayedMacroExpandsCallbacks.clear();
543 Diag(Identifier, diag::warn_pp_ambiguous_macro)
560 if (Args) Args->
destroy(*
this);
565 PropagateLineStartLeadingSpaceInfo(Identifier);
566 ++NumFastMacroExpanded;
576 if (Args) Args->
destroy(*
this);
601 if (!NewMI->isEnabled() || NewMI == MI) {
606 Diag(Identifier, diag::pp_disabled_macro_expansion);
612 ++NumFastMacroExpanded;
617 EnterMacro(Identifier, ExpansionEnd, MI, Args);
633 if (I->is(tok::l_paren)) {
634 Brackets.push_back(
Paren);
635 }
else if (I->is(tok::r_paren)) {
636 if (Brackets.empty() || Brackets.back() ==
Brace)
639 }
else if (I->is(tok::l_brace)) {
640 Brackets.push_back(
Brace);
641 }
else if (I->is(tok::r_brace)) {
642 if (Brackets.empty() || Brackets.back() ==
Paren)
647 return Brackets.empty();
681 bool FoundSeparatorToken =
false;
685 if (I->is(tok::l_brace)) {
687 }
else if (I->is(tok::r_brace)) {
689 if (Braces == 0 && ClosingBrace == E && FoundSeparatorToken)
696 FoundSeparatorToken =
true;
697 I->setKind(tok::comma);
705 if (FoundSeparatorToken && ArgStartIterator->is(tok::l_brace)) {
713 if (FoundSeparatorToken) {
715 TempToken.
setKind(tok::l_paren);
716 TempToken.
setLocation(ArgStartIterator->getLocation());
718 NewTokens.push_back(TempToken);
722 NewTokens.insert(NewTokens.end(), ArgStartIterator, I);
725 if (FoundSeparatorToken) {
728 TempToken.
setKind(tok::r_paren);
731 NewTokens.push_back(TempToken);
732 ParenHints.push_back(
SourceRange(ArgStartIterator->getLocation(),
737 NewTokens.push_back(*I);
740 ArgStartIterator = I + 1;
741 FoundSeparatorToken =
false;
746 return !ParenHints.empty() && InitLists.empty();
753 MacroArgs *Preprocessor::ReadMacroCallArgumentList(
Token &MacroName,
766 assert(Tok.
is(tok::l_paren) &&
"Error computing l-paren-ness?");
772 bool ContainsCodeCompletionTok =
false;
773 bool FoundElidedComma =
false;
777 unsigned NumActuals = 0;
778 while (Tok.
isNot(tok::r_paren)) {
782 assert(Tok.
isOneOf(tok::l_paren, tok::comma) &&
783 "only expect argument separators here");
785 size_t ArgTokenStart = ArgTokens.size();
790 unsigned NumParens = 0;
798 if (!ContainsCodeCompletionTok) {
799 Diag(MacroName, diag::err_unterm_macro_invoc);
807 auto Toks = llvm::make_unique<Token[]>(1);
809 EnterTokenStream(std::move(Toks), 1,
true);
811 }
else if (Tok.
is(tok::r_paren)) {
813 if (NumParens-- == 0) {
815 if (!ArgTokens.empty() &&
816 ArgTokens.back().commaAfterElided()) {
817 FoundElidedComma =
true;
821 }
else if (Tok.
is(tok::l_paren)) {
823 }
else if (Tok.
is(tok::comma) && NumParens == 0 &&
832 if (!isVariadic)
break;
833 if (NumFixedArgsLeft > 1)
835 }
else if (Tok.
is(tok::comment) && !KeepMacroComments) {
849 }
else if (Tok.
is(tok::code_completion)) {
850 ContainsCodeCompletionTok =
true;
859 ArgTokens.push_back(Tok);
864 if (ArgTokens.empty() && Tok.
getKind() == tok::r_paren)
869 if (!isVariadic && NumFixedArgsLeft == 0 && TooManyArgsLoc.
isInvalid()) {
870 if (ArgTokens.size() != ArgTokenStart)
871 TooManyArgsLoc = ArgTokens[ArgTokenStart].getLocation();
873 TooManyArgsLoc = ArgStartLoc;
878 if (ArgTokens.size() == ArgTokenStart && !LangOpts.C99)
879 Diag(Tok, LangOpts.CPlusPlus11 ?
880 diag::warn_cxx98_compat_empty_fnmacro_arg :
881 diag::ext_empty_fnmacro_arg);
889 ArgTokens.push_back(EOFTok);
891 if (!ContainsCodeCompletionTok && NumFixedArgsLeft != 0)
901 if (!isVariadic && NumActuals > MinArgsExpected &&
902 !ContainsCodeCompletionTok) {
905 Diag(TooManyArgsLoc, diag::err_too_many_args_in_macro_invoc);
915 unsigned FixedNumArgs = 0;
918 ParenHints, InitLists)) {
919 if (!InitLists.empty()) {
922 diag::note_init_list_at_beginning_of_macro_argument);
928 if (FixedNumArgs != MinArgsExpected)
936 ArgTokens.swap(FixedArgTokens);
937 NumActuals = FixedNumArgs;
941 bool isVarargsElided =
false;
943 if (ContainsCodeCompletionTok) {
950 for (; NumActuals < MinArgsExpected; ++NumActuals)
951 ArgTokens.push_back(EOFTok);
954 if (NumActuals < MinArgsExpected) {
956 if (NumActuals == 0 && MinArgsExpected == 1) {
963 }
else if ((FoundElidedComma || MI->
isVariadic()) &&
964 (NumActuals+1 == MinArgsExpected ||
965 (NumActuals == 0 && MinArgsExpected == 2))) {
973 Diag(Tok, diag::ext_missing_varargs_arg);
984 isVarargsElided =
true;
985 }
else if (!ContainsCodeCompletionTok) {
987 Diag(Tok, diag::err_too_few_args_in_macro_invoc);
999 ArgTokens.push_back(Tok);
1002 if (NumActuals == 0 && MinArgsExpected == 2)
1003 ArgTokens.push_back(Tok);
1005 }
else if (NumActuals > MinArgsExpected && !MI->
isVariadic() &&
1006 !ContainsCodeCompletionTok) {
1009 Diag(MacroName, diag::err_too_many_args_in_macro_invoc);
1029 size_t newIndex = MacroExpandedTokens.size();
1030 bool cacheNeedsToGrow = tokens.size() >
1031 MacroExpandedTokens.capacity()-MacroExpandedTokens.size();
1032 MacroExpandedTokens.append(tokens.begin(), tokens.end());
1034 if (cacheNeedsToGrow) {
1037 for (
const auto &
Lexer : MacroExpandingLexersStack) {
1040 std::tie(prevLexer, tokIndex) =
Lexer;
1041 prevLexer->Tokens = MacroExpandedTokens.data() + tokIndex;
1045 MacroExpandingLexersStack.push_back(std::make_pair(tokLexer, newIndex));
1046 return MacroExpandedTokens.data() + newIndex;
1049 void Preprocessor::removeCachedMacroExpandedTokensOfLastLexer() {
1050 assert(!MacroExpandingLexersStack.empty());
1051 size_t tokIndex = MacroExpandingLexersStack.back().second;
1052 assert(tokIndex < MacroExpandedTokens.size());
1054 MacroExpandedTokens.resize(tokIndex);
1055 MacroExpandingLexersStack.pop_back();
1063 time_t TT = time(
nullptr);
1064 struct tm *TM = localtime(&TT);
1066 static const char *
const Months[] = {
1067 "Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec" 1072 llvm::raw_svector_ostream TmpStream(TmpBuffer);
1073 TmpStream << llvm::format(
"\"%s %2d %4d\"", Months[TM->tm_mon],
1074 TM->tm_mday, TM->tm_year + 1900);
1083 llvm::raw_svector_ostream TmpStream(TmpBuffer);
1084 TmpStream << llvm::format(
"\"%02d:%02d:%02d\"",
1085 TM->tm_hour, TM->tm_min, TM->tm_sec);
1099 if (Feature.startswith(
"__") && Feature.endswith(
"__") && Feature.size() >= 4)
1100 Feature = Feature.substr(2, Feature.size() - 4);
1102 #define FEATURE(Name, Predicate) .Case(#Name, Predicate) 1103 return llvm::StringSwitch<bool>(Feature)
1104 #include
"clang/Basic/Features.def" 1125 if (Extension.startswith(
"__") && Extension.endswith(
"__") &&
1126 Extension.size() >= 4)
1127 Extension = Extension.substr(2, Extension.size() - 4);
1131 #define EXTENSION(Name, Predicate) .Case(#Name, Predicate) 1132 return llvm::StringSwitch<bool>(Extension)
1133 #include
"clang/Basic/Features.def" 1151 PP.
Diag(LParenLoc, diag::err_pp_directive_required) << II;
1153 assert(Tok.
is(tok::identifier));
1162 if (Tok.
isNot(tok::l_paren)) {
1165 PP.
Diag(LParenLoc, diag::err_pp_expected_after) << II << tok::l_paren;
1168 if (!Tok.
is(tok::angle_string_literal) && !Tok.
is(tok::string_literal) &&
1195 case tok::angle_string_literal:
1196 case tok::string_literal: {
1197 bool Invalid =
false;
1198 Filename = PP.
getSpelling(Tok, FilenameBuffer, &Invalid);
1207 FilenameBuffer.push_back(
'<');
1213 Filename = FilenameBuffer;
1226 if (Tok.
isNot(tok::r_paren)) {
1228 << II << tok::r_paren;
1229 PP.
Diag(LParenLoc, diag::note_matching) << tok::l_paren;
1236 if (Filename.empty())
1242 PP.
LookupFile(FilenameLoc, Filename, isAngled, LookupFrom, LookupFromFile,
1243 CurDir,
nullptr,
nullptr,
nullptr,
nullptr);
1246 return File !=
nullptr;
1266 const FileEntry *LookupFromFile =
nullptr;
1273 PP.
Diag(Tok, diag::pp_include_next_in_primary);
1280 }
else if (!Lookup) {
1281 PP.
Diag(Tok, diag::pp_include_next_absolute_path);
1297 bool &HasLexedNextTok)> Op) {
1300 if (Tok.
isNot(tok::l_paren)) {
1307 Tok.
setKind(tok::numeric_constant);
1312 unsigned ParenDepth = 1;
1317 bool SuppressDiagnostic =
false;
1332 if (!SuppressDiagnostic) {
1334 SuppressDiagnostic =
true;
1340 if (Result.hasValue())
1342 if (!SuppressDiagnostic) {
1344 SuppressDiagnostic =
true;
1349 if (--ParenDepth > 0)
1354 if (Result.hasValue())
1355 OS << Result.getValue();
1358 if (!SuppressDiagnostic)
1361 Tok.
setKind(tok::numeric_constant);
1366 if (Result.hasValue())
1369 bool HasLexedNextToken =
false;
1370 Result = Op(Tok, HasLexedNextToken);
1372 if (HasLexedNextToken)
1379 if (!SuppressDiagnostic) {
1387 PP.
Diag(LParenLoc, diag::note_matching) << tok::l_paren;
1388 SuppressDiagnostic =
true;
1408 std::string ArchName = II->
getName().lower() +
"--";
1409 llvm::Triple Arch(ArchName);
1410 const llvm::Triple &TT = TI.
getTriple();
1413 if ((Arch.getSubArch() == llvm::Triple::NoSubArch ||
1414 Arch.getSubArch() == TT.getSubArch()) &&
1415 ((TT.getArch() == llvm::Triple::thumb &&
1416 Arch.getArch() == llvm::Triple::arm) ||
1417 (TT.getArch() == llvm::Triple::thumbeb &&
1418 Arch.getArch() == llvm::Triple::armeb)))
1423 return (Arch.getSubArch() == llvm::Triple::NoSubArch ||
1424 Arch.getSubArch() == TT.getSubArch()) &&
1425 Arch.getArch() == TT.getArch();
1430 StringRef VendorName = TI.
getTriple().getVendorName();
1431 if (VendorName.empty())
1432 VendorName =
"unknown";
1433 return VendorName.equals_lower(II->
getName());
1438 std::string OSName =
1439 (llvm::Twine(
"unknown-unknown-") + II->
getName().lower()).str();
1440 llvm::Triple OS(OSName);
1441 if (OS.getOS() == llvm::Triple::Darwin) {
1445 return TI.
getTriple().getOS() == OS.getOS();
1451 std::string EnvName = (llvm::Twine(
"---") + II->
getName().lower()).str();
1452 llvm::Triple Env(EnvName);
1453 return TI.
getTriple().getEnvironment() == Env.getEnvironment();
1458 void Preprocessor::ExpandBuiltinMacro(
Token &Tok) {
1461 assert(II &&
"Can't be a macro without id info!");
1465 if (II == Ident_Pragma)
1466 return Handle_Pragma(Tok);
1467 else if (II == Ident__pragma)
1468 return HandleMicrosoft__pragma(Tok);
1470 ++NumBuiltinMacroExpanded;
1473 llvm::raw_svector_ostream OS(TmpBuffer);
1479 if (II == Ident__LINE__) {
1499 Tok.
setKind(tok::numeric_constant);
1500 }
else if (II == Ident__FILE__ || II == Ident__BASE_FILE__) {
1507 if (II == Ident__BASE_FILE__ && PLoc.
isValid()) {
1523 OS <<
'"' << FN <<
'"';
1525 Tok.
setKind(tok::string_literal);
1526 }
else if (II == Ident__DATE__) {
1530 Tok.
setKind(tok::string_literal);
1531 Tok.
setLength(strlen(
"\"Mmm dd yyyy\""));
1536 }
else if (II == Ident__TIME__) {
1540 Tok.
setKind(tok::string_literal);
1546 }
else if (II == Ident__INCLUDE_LEVEL__) {
1560 Tok.
setKind(tok::numeric_constant);
1561 }
else if (II == Ident__TIMESTAMP__) {
1576 time_t TT = CurFile->getModificationTime();
1577 struct tm *TM = localtime(&TT);
1578 Result = asctime(TM);
1580 Result =
"??? ??? ?? ??:??:?? ????\n";
1583 OS <<
'"' << StringRef(Result).drop_back() <<
'"';
1584 Tok.
setKind(tok::string_literal);
1585 }
else if (II == Ident__COUNTER__) {
1587 OS << CounterValue++;
1588 Tok.
setKind(tok::numeric_constant);
1589 }
else if (II == Ident__has_feature) {
1591 [
this](
Token &Tok,
bool &HasLexedNextToken) ->
int {
1593 diag::err_feature_check_malformed);
1596 }
else if (II == Ident__has_extension) {
1598 [
this](
Token &Tok,
bool &HasLexedNextToken) ->
int {
1600 diag::err_feature_check_malformed);
1603 }
else if (II == Ident__has_builtin) {
1605 [
this](
Token &Tok,
bool &HasLexedNextToken) ->
int {
1607 diag::err_feature_check_malformed);
1613 case Builtin::BI__builtin_operator_new:
1614 case Builtin::BI__builtin_operator_delete:
1623 return llvm::StringSwitch<bool>(II->
getName())
1624 .Case(
"__make_integer_seq", LangOpts.CPlusPlus)
1625 .Case(
"__type_pack_element", LangOpts.CPlusPlus)
1626 .Case(
"__builtin_available",
true)
1627 .Case(
"__is_target_arch",
true)
1628 .Case(
"__is_target_vendor",
true)
1629 .Case(
"__is_target_os",
true)
1630 .Case(
"__is_target_environment",
true)
1634 }
else if (II == Ident__is_identifier) {
1636 [](
Token &Tok,
bool &HasLexedNextToken) ->
int {
1637 return Tok.
is(tok::identifier);
1639 }
else if (II == Ident__has_attribute) {
1641 [
this](
Token &Tok,
bool &HasLexedNextToken) ->
int {
1643 diag::err_feature_check_malformed);
1647 }
else if (II == Ident__has_declspec) {
1649 [
this](
Token &Tok,
bool &HasLexedNextToken) ->
int {
1651 diag::err_feature_check_malformed);
1655 }
else if (II == Ident__has_cpp_attribute ||
1656 II == Ident__has_c_attribute) {
1657 bool IsCXX = II == Ident__has_cpp_attribute;
1659 OS, Tok, II, *
this, [&](
Token &Tok,
bool &HasLexedNextToken) ->
int {
1662 Tok, *
this, diag::err_feature_check_malformed);
1669 if (Tok.
isNot(tok::coloncolon))
1670 HasLexedNextToken =
true;
1675 diag::err_feature_check_malformed);
1683 }
else if (II == Ident__has_include ||
1684 II == Ident__has_include_next) {
1689 if (II == Ident__has_include)
1694 if (Tok.
isNot(tok::r_paren))
1697 Tok.
setKind(tok::numeric_constant);
1698 }
else if (II == Ident__has_warning) {
1701 [
this](
Token &Tok,
bool &HasLexedNextToken) ->
int {
1702 std::string WarningName;
1705 HasLexedNextToken = Tok.
is(tok::string_literal);
1712 if (WarningName.size() < 3 || WarningName[0] !=
'-' ||
1713 WarningName[1] !=
'W') {
1714 Diag(StrStartLoc, diag::warn_has_warning_invalid_option);
1725 WarningName.substr(2), Diags);
1727 }
else if (II == Ident__building_module) {
1732 [
this](
Token &Tok,
bool &HasLexedNextToken) ->
int {
1734 diag::err_expected_id_building_module);
1738 }
else if (II == Ident__MODULE__) {
1744 }
else if (II == Ident__identifier) {
1750 if (Tok.
isNot(tok::l_paren)) {
1753 << II << tok::l_paren;
1776 if (RParen.
isNot(tok::r_paren)) {
1778 << Tok.
getKind() << tok::r_paren;
1779 Diag(LParenLoc, diag::note_matching) << tok::l_paren;
1782 }
else if (II == Ident__is_target_arch) {
1784 OS, Tok, II, *
this, [
this](
Token &Tok,
bool &HasLexedNextToken) ->
int {
1786 Tok, *
this, diag::err_feature_check_malformed);
1789 }
else if (II == Ident__is_target_vendor) {
1791 OS, Tok, II, *
this, [
this](
Token &Tok,
bool &HasLexedNextToken) ->
int {
1793 Tok, *
this, diag::err_feature_check_malformed);
1796 }
else if (II == Ident__is_target_os) {
1798 OS, Tok, II, *
this, [
this](
Token &Tok,
bool &HasLexedNextToken) ->
int {
1800 Tok, *
this, diag::err_feature_check_malformed);
1803 }
else if (II == Ident__is_target_environment) {
1805 OS, Tok, II, *
this, [
this](
Token &Tok,
bool &HasLexedNextToken) ->
int {
1807 Tok, *
this, diag::err_feature_check_malformed);
1811 llvm_unreachable(
"Unknown identifier!");
A diagnostic that indicates a problem or potential problem.
static IdentifierInfo * RegisterBuiltinMacro(Preprocessor &PP, const char *Name)
RegisterBuiltinMacro - Register the specified identifier in the identifier table and mark it as a bui...
static bool CheckMatchedBrackets(const SmallVectorImpl< Token > &Tokens)
CheckMatchedBrackets - Returns true if the braces and parentheses in the token vector are properly ne...
Lexer - This provides a simple interface that turns a text buffer into a stream of tokens...
MacroInfo * AllocateMacroInfo(SourceLocation L)
Allocate a new MacroInfo object with the provided SourceLocation.
param_iterator param_begin() const
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 setChangedSinceDeserialization()
Note that this identifier has changed since it was loaded from an AST file.
void markMacroAsUsed(MacroInfo *MI)
A macro is used, update information about macros that need unused warnings.
IdentifierInfo * getIdentifierInfo(StringRef Name) const
Return information about the specified preprocessor identifier token.
void setFlagValue(TokenFlags Flag, bool Val)
Set a flag to either true or false.
Defines the clang::FileManager interface and associated types.
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
ModuleMacro * addModuleMacro(Module *Mod, IdentifierInfo *II, MacroInfo *Macro, ArrayRef< ModuleMacro *> Overrides, bool &IsNew)
Register an exported macro for a module and identifier.
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)) {...
void dumpMacroInfo(const IdentifierInfo *II)
bool isEnabled() const
Return true if this macro is enabled.
Is the identifier known as a __declspec-style attribute?
bool isInPrimaryFile() const
Return true if we're in the top-level file, not in a #include.
static bool EvaluateHasIncludeCommon(Token &Tok, IdentifierInfo *II, Preprocessor &PP, const DirectoryLookup *LookupFrom, const FileEntry *LookupFromFile)
EvaluateHasIncludeCommon - Process a '__has_include("path")' or '__has_include_next("path")' expressi...
Defines the clang::MacroInfo and clang::MacroDirective classes.
Is the identifier known as a GNU-style attribute?
Defines types useful for describing an Objective-C runtime.
A description of the current definition of a macro.
static bool GenerateNewArgTokens(Preprocessor &PP, SmallVectorImpl< Token > &OldTokens, SmallVectorImpl< Token > &NewTokens, unsigned &NumArgs, SmallVectorImpl< SourceRange > &ParenHints, SmallVectorImpl< SourceRange > &InitLists)
GenerateNewArgTokens - Returns true if OldTokens can be converted to a new vector of tokens in NewTok...
bool isOutOfDate() const
Determine whether the information for this identifier is out of date with respect to the external sou...
static bool isTargetEnvironment(const TargetInfo &TI, const IdentifierInfo *II)
Implements the __is_target_environment builtin macro.
void setFlag(TokenFlags Flag)
Set the specified flag.
bool isCompilingModule() const
Are we compiling a module interface (.cppm or module map)?
bool isFromAST() const
Return true if the identifier in its current state was loaded from an AST file.
diag::Severity getExtensionHandlingBehavior() 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.
bool isAnnotation() const
Return true if this is any of tok::annot_* kind tokens.
const MacroDirective * getPrevious() const
Get previous definition of the macro with the same name.
tok::TokenKind getKind() const
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Computes the source location just past the end of the token at this source location.
DefMacroDirective * appendDefMacroDirective(IdentifierInfo *II, MacroInfo *MI, SourceLocation Loc)
One of these records is kept for each identifier that is lexed.
Represents a macro directive exported by a module.
static bool HasFeature(const Preprocessor &PP, StringRef Feature)
HasFeature - Return true if we recognize and implement the feature specified by the identifier as a s...
void setHasMacroDefinition(bool Val)
static bool isTargetOS(const TargetInfo &TI, const IdentifierInfo *II)
Implements the __is_target_os builtin macro.
static bool getDiagnosticsInGroup(diag::Flavor Flavor, const WarningOption *Group, SmallVectorImpl< diag::kind > &Diags)
Return true if any diagnostics were found in this group, even if they were filtered out due to having...
bool hasCommaPasting() const
const TargetInfo & getTargetInfo() const
Token - This structure provides full information about a lexed token.
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.
static void ComputeDATE_TIME(SourceLocation &DATELoc, SourceLocation &TIMELoc, Preprocessor &PP)
ComputeDATE_TIME - Compute the current time, enter it into the specified scratch buffer, then return DATELoc/TIMELoc locations with the position of the identifier tokens inserted.
param_iterator param_end() 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...
Module * getCurrentLexerSubmodule() const
Return the submodule owning the file being lexed.
static IdentifierInfo * ExpectFeatureIdentifierInfo(Token &Tok, Preprocessor &PP, signed DiagID)
Helper function to return the IdentifierInfo structure of a Token or generate a diagnostic if none av...
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 ...
tok::TokenKind getTokenID() const
If this is a source-language token (e.g.
static void EvaluateFeatureLikeBuiltinMacro(llvm::raw_svector_ostream &OS, Token &Tok, IdentifierInfo *II, Preprocessor &PP, llvm::function_ref< int(Token &Tok, bool &HasLexedNextTok)> Op)
Process single-argument builtin feature-like macros that return integer values.
const Token & getReplacementToken(unsigned Tok) const
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
void LexNonComment(Token &Result)
Lex a token.
void ExpandedMacro()
ExpandedMacro - When a macro is expanded with this lexer as the current buffer, this method is called...
static bool EvaluateHasInclude(Token &Tok, IdentifierInfo *II, Preprocessor &PP)
EvaluateHasInclude - Process a '__has_include("path")' expression.
void destroy(Preprocessor &PP)
destroy - Destroy and deallocate the memory for this object.
TokenLexer - This implements a lexer that returns tokens from a macro body or token stream instead of...
Present this diagnostic as an error.
int hasAttribute(AttrSyntax Syntax, const IdentifierInfo *Scope, const IdentifierInfo *Attr, const TargetInfo &Target, const LangOptions &LangOpts)
Return the version number associated with the attribute if we recognize and implement the attribute s...
bool isUsed() const
Return false if this macro is defined in the main file and has not yet been used. ...
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.
A little helper class used to produce diagnostics.
std::string CurrentModule
The name of the current module, of which the main source file is a part.
unsigned getNumParams() const
Exposes information about the current target.
Defines the clang::LangOptions interface.
bool isInvalid() const
Return true if this object is invalid or uninitialized.
bool isInSystemHeader(SourceLocation Loc) const
Returns if a SourceLocation is in a system header.
static bool isTargetVendor(const TargetInfo &TI, const IdentifierInfo *II)
Implements the __is_target_vendor builtin macro.
const FileEntry * getFileEntryForID(FileID FID) const
Returns the FileEntry record for the provided FileID.
MacroArgs - An instance of this class captures information about the formal arguments specified to a ...
unsigned getLine() const
Return the presumed line number of this location.
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file. ...
Defines the clang::Preprocessor interface.
MultipleIncludeOpt MIOpt
A state machine that detects the #ifndef-wrapping a file idiom for the multiple-include optimization...
const MacroInfo * getMacroInfo(const IdentifierInfo *II) const
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Represents an unpacked "presumed" location which can be presented to the user.
bool isObjectLike() const
The result type of a method or function.
static bool HasExtension(const Preprocessor &PP, StringRef Extension)
HasExtension - Return true if we recognize and implement the feature specified by the identifier...
DirectoryLookup - This class represents one entry in the search list that specifies the search order ...
const DirectoryLookup * GetCurDirLookup()
Get the DirectoryLookup structure used to find the current FileEntry, if CurLexer is non-null and if ...
unsigned getBuiltinID() const
Return a value indicating whether this is a builtin function.
void setIsUsed(bool Val)
Set the value of the IsUsed flag.
const char * getFilename() const
Return the presumed filename of this location.
ExternalPreprocessorSource * getExternalSource() const
Encapsulates changes to the "macros namespace" (the location where the macro name became active...
Encodes a location in the source.
static bool isTargetArch(const TargetInfo &TI, const IdentifierInfo *II)
Implements the __is_target_arch builtin macro.
static bool isTrivialSingleTokenExpansion(const MacroInfo *MI, const IdentifierInfo *MacroIdent, Preprocessor &PP)
isTrivialSingleTokenExpansion - Return true if MI, which has a single token in its expansion...
void setLength(unsigned Len)
SourceLocation createExpansionLoc(SourceLocation Loc, SourceLocation ExpansionLocStart, SourceLocation ExpansionLocEnd, unsigned TokLength, bool ExpansionIsTokenRange=true, int LoadedID=0, unsigned LoadedOffset=0)
Return a new SourceLocation that encodes the fact that a token from SpellingLoc should actually be re...
MacroDirective * getLocalMacroDirectiveHistory(const IdentifierInfo *II) const
Given an identifier, return the latest non-imported macro directive for that identifier.
static bool EvaluateHasIncludeNext(Token &Tok, IdentifierInfo *II, Preprocessor &PP)
EvaluateHasIncludeNext - Process '__has_include_next("path")' expression.
IdentifierInfo * getIdentifierInfo() const
Cached information about one file (either on disk or in the virtual file system). ...
void setIdentifierInfo(IdentifierInfo *II)
void setIsBuiltinMacro(bool Val=true)
Set or clear the isBuiltinMacro flag.
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 setLoadedMacroDirective(IdentifierInfo *II, MacroDirective *ED, MacroDirective *MD)
Set a MacroDirective that was loaded from a PCH file.
void EnterMacro(Token &Identifier, SourceLocation ILEnd, MacroInfo *Macro, MacroArgs *Args)
Add a Macro to the top of the include stack and start lexing tokens from it instead of the current bu...
bool isAtStartOfLine() const
isAtStartOfLine - Return true if this token is at the start of a line.
PreprocessorLexer * getCurrentLexer() const
Return the current lexer being lexed from.
StringRef getName() const
Return the actual identifier string.
bool isNot(tok::TokenKind K) const
bool hadMacroDefinition() const
Returns true if this identifier was #defined to some value at any moment.
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.
unsigned getNumTokens() const
Return the number of tokens that this macro expands to.
bool isFunctionLike() const
const FileEntry * getFileEntry() const
getFileEntry - Return the FileEntry corresponding to this FileID.
bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.
bool IsHeaderFile
Indicates whether the front-end is explicitly told that the input is a header file (i...
unsigned getLength() const
Encapsulates the data about a macro definition (e.g.
static ModuleMacro * create(Preprocessor &PP, Module *OwningModule, IdentifierInfo *II, MacroInfo *Macro, ArrayRef< ModuleMacro *> Overrides)
bool GetIncludeFilenameSpelling(SourceLocation Loc, StringRef &Filename)
Turn the specified lexer token into a fully checked and spelled filename, e.g.
bool FinishLexStringLiteral(Token &Result, std::string &String, const char *DiagnosticTag, bool AllowMacroExpansion)
Complete the lexing of a string literal where the first token has already been lexed (see LexStringLi...
virtual void updateOutOfDateIdentifier(IdentifierInfo &II)=0
Update an out-of-date identifier.
void CreateString(StringRef Str, Token &Tok, SourceLocation ExpansionLocStart=SourceLocation(), SourceLocation ExpansionLocEnd=SourceLocation())
Plop the specified string into a scratch buffer and set the specified token's location and length to ...
SourceLocation getEnd() const
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.
CharSourceRange getExpansionRange(SourceLocation Loc) const
Given a SourceLocation object, return the range of tokens covered by the expansion in the ultimate fi...
void LexIncludeFilename(Token &Result)
After the preprocessor has parsed a #include, lex and (potentially) macro expand the filename...
const IntrusiveRefCntPtr< DiagnosticIDs > & getDiagnosticIDs() const
Defines the clang::SourceLocation class and associated facilities.
ModuleMacro * getModuleMacro(Module *Mod, IdentifierInfo *II)
DiagnosticsEngine & getDiagnostics() const
bool isAmbiguous() const
true if the definition is ambiguous, false otherwise.
static MacroArgs * create(const MacroInfo *MI, ArrayRef< Token > UnexpArgTokens, bool VarargsElided, Preprocessor &PP)
MacroArgs ctor function - Create a new MacroArgs object with the specified macro and argument info...
bool isBuiltinMacro() const
Return true if this macro requires processing before expansion.
Defines the clang::TargetInfo interface.
void setPrevious(MacroDirective *Prev)
Set previous definition of the macro with the same name.
void forAllDefinitions(Fn F) const
MacroInfo * getMacroInfo() const
Get the MacroInfo that should be used for this definition.
void setLocation(SourceLocation L)
bool isParsingIfOrElifDirective() const
True if we are currently preprocessing a if or #elif directive.
A trivial tuple used to represent a source range.
PreprocessorLexer * getCurrentFileLexer() const
Return the current file lexer being lexed from.
unsigned getFlags() const
Return the internal represtation of the flags.
void clearFlag(TokenFlags Flag)
Unset the specified flag.
SourceLocation getIncludeLoc() const
Return the presumed include location of this location.
Defines the PreprocessorLexer interface.
virtual void CodeCompleteMacroArgument(IdentifierInfo *Macro, MacroInfo *MacroInfo, unsigned ArgumentIndex)
Callback invoked when performing code completion inside a function-like macro argument.
void Profile(llvm::FoldingSetNodeID &ID) const
bool hasLeadingSpace() const
Return true if this token has whitespace before it.
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const
Forwarding function for diagnostics.
void startToken()
Reset all flags to cleared.
static std::string Stringify(StringRef Str, bool Charify=false)
Stringify - Convert the specified string into a C string by i) escaping '\' and " characters and ii) ...
Engages in a tight little dance with the lexer to efficiently preprocess tokens.