34 #include "llvm/ADT/ArrayRef.h" 35 #include "llvm/ADT/DenseMap.h" 36 #include "llvm/ADT/DenseSet.h" 37 #include "llvm/ADT/FoldingSet.h" 38 #include "llvm/ADT/None.h" 39 #include "llvm/ADT/Optional.h" 40 #include "llvm/ADT/STLExtras.h" 41 #include "llvm/ADT/SmallString.h" 42 #include "llvm/ADT/SmallVector.h" 43 #include "llvm/ADT/StringRef.h" 44 #include "llvm/ADT/StringSwitch.h" 45 #include "llvm/Support/Casting.h" 46 #include "llvm/Support/ErrorHandling.h" 47 #include "llvm/Support/Format.h" 48 #include "llvm/Support/Path.h" 49 #include "llvm/Support/raw_ostream.h" 59 using namespace clang;
65 auto Pos = CurSubmoduleState->Macros.find(II);
66 return Pos == CurSubmoduleState->Macros.end() ? nullptr
67 : Pos->second.getLatest();
71 assert(MD &&
"MacroDirective should be non-zero!");
72 assert(!MD->
getPrevious() &&
"Already attached to a MacroDirective history.");
74 MacroState &StoredMD = CurSubmoduleState->Macros[II];
75 auto *OldMD = StoredMD.getLatest();
77 StoredMD.setLatest(MD);
78 StoredMD.overrideActiveModuleMacros(*
this, II);
80 if (needModuleMacros()) {
84 PendingModuleMacroNames.push_back(II);
89 if (!MD->
isDefined() && LeafModuleMacros.find(II) == LeafModuleMacros.end())
108 MacroState &StoredMD = CurSubmoduleState->Macros[II];
110 if (
auto *OldMD = StoredMD.getLatest()) {
116 assert(OldMD->getMacroInfo()->isBuiltinMacro() &&
117 "only built-ins should have an entry here");
118 assert(!OldMD->getPrevious() &&
"builtin should only have a single entry");
120 StoredMD.setLatest(MD);
127 if (!MD->
isDefined() && LeafModuleMacros.find(II) == LeafModuleMacros.end())
135 llvm::FoldingSetNodeID
ID;
139 if (
auto *MM = ModuleMacros.FindNodeOrInsertPos(ID, InsertPos)) {
145 ModuleMacros.InsertNode(MM, InsertPos);
149 for (
auto *O : Overrides) {
150 HidAny |= (O->NumOverriddenBy == 0);
151 ++O->NumOverriddenBy;
155 auto &LeafMacros = LeafModuleMacros[II];
157 LeafMacros.erase(std::remove_if(LeafMacros.begin(), LeafMacros.end(),
159 return MM->NumOverriddenBy != 0;
165 LeafMacros.push_back(MM);
174 llvm::FoldingSetNodeID
ID;
178 return ModuleMacros.FindNodeOrInsertPos(ID, InsertPos);
181 void Preprocessor::updateModuleMacroInfo(
const IdentifierInfo *II,
182 ModuleMacroInfo &Info) {
183 assert(Info.ActiveModuleMacrosGeneration !=
184 CurSubmoduleState->VisibleModules.getGeneration() &&
185 "don't need to update this macro name info");
186 Info.ActiveModuleMacrosGeneration =
187 CurSubmoduleState->VisibleModules.getGeneration();
189 auto Leaf = LeafModuleMacros.find(II);
190 if (Leaf == LeafModuleMacros.end()) {
195 Info.ActiveModuleMacros.clear();
198 llvm::DenseMap<ModuleMacro *, int> NumHiddenOverrides;
199 for (
auto *O : Info.OverriddenMacros)
200 NumHiddenOverrides[O] = -1;
204 for (
auto *LeafMM : Leaf->second) {
205 assert(LeafMM->getNumOverridingMacros() == 0 &&
"leaf macro overridden");
206 if (NumHiddenOverrides.lookup(LeafMM) == 0)
207 Worklist.push_back(LeafMM);
209 while (!Worklist.empty()) {
210 auto *MM = Worklist.pop_back_val();
211 if (CurSubmoduleState->VisibleModules.isVisible(MM->getOwningModule())) {
214 if (MM->getMacroInfo())
215 Info.ActiveModuleMacros.push_back(MM);
217 for (
auto *O : MM->overrides())
218 if ((
unsigned)++NumHiddenOverrides[O] == O->getNumOverridingMacros())
219 Worklist.push_back(O);
223 std::reverse(Info.ActiveModuleMacros.begin(), Info.ActiveModuleMacros.end());
227 bool IsSystemMacro =
true;
228 bool IsAmbiguous =
false;
229 if (
auto *MD = Info.MD) {
230 while (MD && isa<VisibilityMacroDirective>(MD))
231 MD = MD->getPrevious();
232 if (
auto *DMD = dyn_cast_or_null<DefMacroDirective>(MD)) {
237 for (
auto *Active : Info.ActiveModuleMacros) {
238 auto *NewMI = Active->getMacroInfo();
249 if (MI && NewMI != MI &&
250 !MI->isIdenticalTo(*NewMI, *
this,
true))
252 IsSystemMacro &= Active->getOwningModule()->IsSystem ||
256 Info.IsAmbiguous = IsAmbiguous && !IsSystemMacro;
261 auto LeafIt = LeafModuleMacros.find(II);
262 if (LeafIt != LeafModuleMacros.end())
263 Leaf = LeafIt->second;
264 const MacroState *
State =
nullptr;
265 auto Pos = CurSubmoduleState->Macros.find(II);
266 if (Pos != CurSubmoduleState->Macros.end())
267 State = &Pos->second;
271 llvm::errs() <<
" ambiguous";
272 if (
State && !
State->getOverriddenMacros().empty()) {
273 llvm::errs() <<
" overrides";
274 for (
auto *O :
State->getOverriddenMacros())
275 llvm::errs() <<
" " << O->getOwningModule()->getFullModuleName();
277 llvm::errs() <<
"\n";
280 for (
auto *MD =
State ?
State->getLatest() :
nullptr; MD;
281 MD = MD->getPrevious()) {
288 for (
auto *MM :
State ?
State->getActiveModuleMacros(*
this, II) :
None)
292 while (!Worklist.empty()) {
293 auto *MM = Worklist.pop_back_val();
294 llvm::errs() <<
" ModuleMacro " << MM <<
" " 295 << MM->getOwningModule()->getFullModuleName();
296 if (!MM->getMacroInfo())
297 llvm::errs() <<
" undef";
299 if (Active.count(MM))
300 llvm::errs() <<
" active";
301 else if (!CurSubmoduleState->VisibleModules.isVisible(
302 MM->getOwningModule()))
303 llvm::errs() <<
" hidden";
304 else if (MM->getMacroInfo())
305 llvm::errs() <<
" overridden";
307 if (!MM->overrides().empty()) {
308 llvm::errs() <<
" overrides";
309 for (
auto *O : MM->overrides()) {
310 llvm::errs() <<
" " << O->getOwningModule()->getFullModuleName();
311 if (Visited.insert(O).second)
312 Worklist.push_back(O);
315 llvm::errs() <<
"\n";
316 if (
auto *MI = MM->getMacroInfo()) {
319 llvm::errs() <<
"\n";
339 void Preprocessor::RegisterBuiltinMacros() {
348 if (LangOpts.CPlusPlus)
349 Ident__has_cpp_attribute =
352 Ident__has_cpp_attribute =
nullptr;
360 if (LangOpts.MicrosoftExt) {
364 Ident__identifier =
nullptr;
365 Ident__pragma =
nullptr;
374 if (!LangOpts.CPlusPlus)
377 Ident__has_c_attribute =
nullptr;
387 Ident__is_target_environment =
395 Ident__MODULE__ =
nullptr;
406 if (!II)
return true;
416 if (ExpansionMI->isEnabled() &&
433 bool Preprocessor::isNextPPTokenLParen() {
437 Val = CurLexer->isNextPPTokenLParen();
439 Val = CurTokenLexer->isNextTokenLParen();
447 for (
const IncludeStackInfo &Entry : llvm::reverse(IncludeMacroStack)) {
449 Val = Entry.TheLexer->isNextPPTokenLParen();
451 Val = Entry.TheTokenLexer->isNextTokenLParen();
457 if (Entry.ThePPLexer)
482 Callbacks->MacroExpands(Identifier, M, Identifier.
getLocation(),
484 ExpandBuiltinMacro(Identifier);
505 Args = ReadMacroCallArgumentList(Identifier, MI, ExpansionEnd);
512 if (!Args)
return true;
514 ++NumFnMacroExpanded;
524 SourceRange ExpansionRange(ExpandLoc, ExpansionEnd);
532 DelayedMacroExpandsCallbacks.push_back(
533 MacroExpandsInfo(Identifier, M, ExpansionRange));
535 Callbacks->MacroExpands(Identifier, M, ExpansionRange, Args);
536 if (!DelayedMacroExpandsCallbacks.empty()) {
537 for (
const MacroExpandsInfo &Info : DelayedMacroExpandsCallbacks) {
539 Callbacks->MacroExpands(Info.Tok, Info.MD, Info.Range,
542 DelayedMacroExpandsCallbacks.clear();
549 Diag(Identifier, diag::warn_pp_ambiguous_macro)
566 if (Args) Args->
destroy(*
this);
571 PropagateLineStartLeadingSpaceInfo(Identifier);
572 ++NumFastMacroExpanded;
582 if (Args) Args->
destroy(*
this);
607 if (!NewMI->isEnabled() || NewMI == MI) {
612 Diag(Identifier, diag::pp_disabled_macro_expansion);
618 ++NumFastMacroExpanded;
623 EnterMacro(Identifier, ExpansionEnd, MI, Args);
639 if (I->is(tok::l_paren)) {
640 Brackets.push_back(
Paren);
641 }
else if (I->is(tok::r_paren)) {
642 if (Brackets.empty() || Brackets.back() ==
Brace)
645 }
else if (I->is(tok::l_brace)) {
646 Brackets.push_back(
Brace);
647 }
else if (I->is(tok::r_brace)) {
648 if (Brackets.empty() || Brackets.back() ==
Paren)
653 return Brackets.empty();
687 bool FoundSeparatorToken =
false;
691 if (I->is(tok::l_brace)) {
693 }
else if (I->is(tok::r_brace)) {
695 if (Braces == 0 && ClosingBrace == E && FoundSeparatorToken)
702 FoundSeparatorToken =
true;
703 I->setKind(tok::comma);
711 if (FoundSeparatorToken && ArgStartIterator->is(tok::l_brace)) {
719 if (FoundSeparatorToken) {
721 TempToken.
setKind(tok::l_paren);
722 TempToken.
setLocation(ArgStartIterator->getLocation());
724 NewTokens.push_back(TempToken);
728 NewTokens.insert(NewTokens.end(), ArgStartIterator, I);
731 if (FoundSeparatorToken) {
734 TempToken.
setKind(tok::r_paren);
737 NewTokens.push_back(TempToken);
738 ParenHints.push_back(
SourceRange(ArgStartIterator->getLocation(),
743 NewTokens.push_back(*I);
746 ArgStartIterator = I + 1;
747 FoundSeparatorToken =
false;
752 return !ParenHints.empty() && InitLists.empty();
759 MacroArgs *Preprocessor::ReadMacroCallArgumentList(
Token &MacroName,
772 assert(Tok.
is(tok::l_paren) &&
"Error computing l-paren-ness?");
778 bool ContainsCodeCompletionTok =
false;
779 bool FoundElidedComma =
false;
783 unsigned NumActuals = 0;
784 while (Tok.
isNot(tok::r_paren)) {
788 assert(Tok.
isOneOf(tok::l_paren, tok::comma) &&
789 "only expect argument separators here");
791 size_t ArgTokenStart = ArgTokens.size();
796 unsigned NumParens = 0;
804 if (!ContainsCodeCompletionTok) {
805 Diag(MacroName, diag::err_unterm_macro_invoc);
813 auto Toks = std::make_unique<Token[]>(1);
815 EnterTokenStream(std::move(Toks), 1,
true,
false);
817 }
else if (Tok.
is(tok::r_paren)) {
819 if (NumParens-- == 0) {
821 if (!ArgTokens.empty() &&
822 ArgTokens.back().commaAfterElided()) {
823 FoundElidedComma =
true;
827 }
else if (Tok.
is(tok::l_paren)) {
829 }
else if (Tok.
is(tok::comma)) {
840 }
else if (NumParens == 0) {
846 if (NumFixedArgsLeft > 1)
849 }
else if (Tok.
is(tok::comment) && !KeepMacroComments) {
863 }
else if (Tok.
is(tok::code_completion)) {
864 ContainsCodeCompletionTok =
true;
873 ArgTokens.push_back(Tok);
878 if (ArgTokens.empty() && Tok.
getKind() == tok::r_paren)
883 if (!isVariadic && NumFixedArgsLeft == 0 && TooManyArgsLoc.
isInvalid()) {
884 if (ArgTokens.size() != ArgTokenStart)
885 TooManyArgsLoc = ArgTokens[ArgTokenStart].getLocation();
887 TooManyArgsLoc = ArgStartLoc;
892 if (ArgTokens.size() == ArgTokenStart && !LangOpts.C99)
893 Diag(Tok, LangOpts.CPlusPlus11 ?
894 diag::warn_cxx98_compat_empty_fnmacro_arg :
895 diag::ext_empty_fnmacro_arg);
903 ArgTokens.push_back(EOFTok);
905 if (!ContainsCodeCompletionTok && NumFixedArgsLeft != 0)
915 if (!isVariadic && NumActuals > MinArgsExpected &&
916 !ContainsCodeCompletionTok) {
919 Diag(TooManyArgsLoc, diag::err_too_many_args_in_macro_invoc);
929 unsigned FixedNumArgs = 0;
932 ParenHints, InitLists)) {
933 if (!InitLists.empty()) {
936 diag::note_init_list_at_beginning_of_macro_argument);
942 if (FixedNumArgs != MinArgsExpected)
950 ArgTokens.swap(FixedArgTokens);
951 NumActuals = FixedNumArgs;
955 bool isVarargsElided =
false;
957 if (ContainsCodeCompletionTok) {
964 for (; NumActuals < MinArgsExpected; ++NumActuals)
965 ArgTokens.push_back(EOFTok);
968 if (NumActuals < MinArgsExpected) {
970 if (NumActuals == 0 && MinArgsExpected == 1) {
977 }
else if ((FoundElidedComma || MI->
isVariadic()) &&
978 (NumActuals+1 == MinArgsExpected ||
979 (NumActuals == 0 && MinArgsExpected == 2))) {
987 Diag(Tok, diag::ext_missing_varargs_arg);
998 isVarargsElided =
true;
999 }
else if (!ContainsCodeCompletionTok) {
1001 Diag(Tok, diag::err_too_few_args_in_macro_invoc);
1013 ArgTokens.push_back(Tok);
1016 if (NumActuals == 0 && MinArgsExpected == 2)
1017 ArgTokens.push_back(Tok);
1019 }
else if (NumActuals > MinArgsExpected && !MI->
isVariadic() &&
1020 !ContainsCodeCompletionTok) {
1023 Diag(MacroName, diag::err_too_many_args_in_macro_invoc);
1043 size_t newIndex = MacroExpandedTokens.size();
1044 bool cacheNeedsToGrow = tokens.size() >
1045 MacroExpandedTokens.capacity()-MacroExpandedTokens.size();
1046 MacroExpandedTokens.append(tokens.begin(), tokens.end());
1048 if (cacheNeedsToGrow) {
1051 for (
const auto &
Lexer : MacroExpandingLexersStack) {
1054 std::tie(prevLexer, tokIndex) =
Lexer;
1055 prevLexer->Tokens = MacroExpandedTokens.data() + tokIndex;
1059 MacroExpandingLexersStack.push_back(std::make_pair(tokLexer, newIndex));
1060 return MacroExpandedTokens.data() + newIndex;
1063 void Preprocessor::removeCachedMacroExpandedTokensOfLastLexer() {
1064 assert(!MacroExpandingLexersStack.empty());
1065 size_t tokIndex = MacroExpandingLexersStack.back().second;
1066 assert(tokIndex < MacroExpandedTokens.size());
1068 MacroExpandedTokens.resize(tokIndex);
1069 MacroExpandingLexersStack.pop_back();
1077 time_t TT = time(
nullptr);
1078 struct tm *TM = localtime(&TT);
1080 static const char *
const Months[] = {
1081 "Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec" 1086 llvm::raw_svector_ostream TmpStream(TmpBuffer);
1087 TmpStream << llvm::format(
"\"%s %2d %4d\"", Months[TM->tm_mon],
1088 TM->tm_mday, TM->tm_year + 1900);
1097 llvm::raw_svector_ostream TmpStream(TmpBuffer);
1098 TmpStream << llvm::format(
"\"%02d:%02d:%02d\"",
1099 TM->tm_hour, TM->tm_min, TM->tm_sec);
1113 if (Feature.startswith(
"__") && Feature.endswith(
"__") && Feature.size() >= 4)
1114 Feature = Feature.substr(2, Feature.size() - 4);
1116 #define FEATURE(Name, Predicate) .Case(#Name, Predicate) 1117 return llvm::StringSwitch<bool>(Feature)
1118 #include
"clang/Basic/Features.def" 1139 if (Extension.startswith(
"__") && Extension.endswith(
"__") &&
1140 Extension.size() >= 4)
1141 Extension = Extension.substr(2, Extension.size() - 4);
1145 #define EXTENSION(Name, Predicate) .Case(#Name, Predicate) 1146 return llvm::StringSwitch<bool>(Extension)
1147 #include
"clang/Basic/Features.def" 1165 PP.
Diag(LParenLoc, diag::err_pp_directive_required) << II;
1167 assert(Tok.
is(tok::identifier));
1176 }
while (Tok.
getKind() == tok::comment);
1179 if (Tok.
isNot(tok::l_paren)) {
1182 PP.
Diag(LParenLoc, diag::err_pp_expected_after) << II << tok::l_paren;
1185 if (Tok.
isNot(tok::header_name))
1194 if (Tok.
isNot(tok::header_name)) {
1201 bool Invalid =
false;
1212 if (Tok.
isNot(tok::r_paren)) {
1214 << II << tok::r_paren;
1215 PP.
Diag(LParenLoc, diag::note_matching) << tok::l_paren;
1222 if (Filename.empty())
1228 PP.
LookupFile(FilenameLoc, Filename, isAngled, LookupFrom, LookupFromFile,
1229 CurDir,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr);
1236 Callbacks->HasInclude(FilenameLoc, Filename, isAngled, File, FileType);
1240 return File.hasValue();
1260 const FileEntry *LookupFromFile =
nullptr;
1267 PP.
Diag(Tok, diag::pp_include_next_in_primary);
1274 }
else if (!Lookup) {
1275 PP.
Diag(Tok, diag::pp_include_next_absolute_path);
1291 bool &HasLexedNextTok)> Op) {
1294 if (Tok.
isNot(tok::l_paren)) {
1301 Tok.
setKind(tok::numeric_constant);
1306 unsigned ParenDepth = 1;
1311 bool SuppressDiagnostic =
false;
1326 if (!SuppressDiagnostic) {
1328 SuppressDiagnostic =
true;
1334 if (Result.hasValue())
1336 if (!SuppressDiagnostic) {
1338 SuppressDiagnostic =
true;
1343 if (--ParenDepth > 0)
1348 if (Result.hasValue()) {
1349 OS << Result.getValue();
1352 if (Result.getValue() > 1)
1356 if (!SuppressDiagnostic)
1359 Tok.
setKind(tok::numeric_constant);
1364 if (Result.hasValue())
1367 bool HasLexedNextToken =
false;
1368 Result = Op(Tok, HasLexedNextToken);
1370 if (HasLexedNextToken)
1377 if (!SuppressDiagnostic) {
1385 PP.
Diag(LParenLoc, diag::note_matching) << tok::l_paren;
1386 SuppressDiagnostic =
true;
1406 std::string ArchName = II->
getName().lower() +
"--";
1407 llvm::Triple Arch(ArchName);
1408 const llvm::Triple &TT = TI.
getTriple();
1411 if ((Arch.getSubArch() == llvm::Triple::NoSubArch ||
1412 Arch.getSubArch() == TT.getSubArch()) &&
1413 ((TT.getArch() == llvm::Triple::thumb &&
1414 Arch.getArch() == llvm::Triple::arm) ||
1415 (TT.getArch() == llvm::Triple::thumbeb &&
1416 Arch.getArch() == llvm::Triple::armeb)))
1421 return (Arch.getSubArch() == llvm::Triple::NoSubArch ||
1422 Arch.getSubArch() == TT.getSubArch()) &&
1423 Arch.getArch() == TT.getArch();
1428 StringRef VendorName = TI.
getTriple().getVendorName();
1429 if (VendorName.empty())
1430 VendorName =
"unknown";
1431 return VendorName.equals_lower(II->
getName());
1436 std::string OSName =
1437 (llvm::Twine(
"unknown-unknown-") + II->
getName().lower()).str();
1438 llvm::Triple OS(OSName);
1439 if (OS.getOS() == llvm::Triple::Darwin) {
1443 return TI.
getTriple().getOS() == OS.getOS();
1449 std::string EnvName = (llvm::Twine(
"---") + II->
getName().lower()).str();
1450 llvm::Triple Env(EnvName);
1451 return TI.
getTriple().getEnvironment() == Env.getEnvironment();
1456 const std::map<std::string, std::string, std::greater<std::string>>
1458 for (
const auto &Entry : MacroPrefixMap)
1459 if (Path.startswith(Entry.first)) {
1460 Path = (Twine(Entry.second) + Path.substr(Entry.first.size())).str();
1467 void Preprocessor::ExpandBuiltinMacro(
Token &Tok) {
1470 assert(II &&
"Can't be a macro without id info!");
1474 if (II == Ident_Pragma)
1475 return Handle_Pragma(Tok);
1476 else if (II == Ident__pragma)
1477 return HandleMicrosoft__pragma(Tok);
1479 ++NumBuiltinMacroExpanded;
1482 llvm::raw_svector_ostream OS(TmpBuffer);
1490 if (II == Ident__LINE__) {
1510 Tok.
setKind(tok::numeric_constant);
1511 }
else if (II == Ident__FILE__ || II == Ident__BASE_FILE__ ||
1512 II == Ident__FILE_NAME__) {
1519 if (II == Ident__BASE_FILE__ && PLoc.
isValid()) {
1535 if (II == Ident__FILE_NAME__) {
1538 StringRef PLFileName = llvm::sys::path::filename(PLoc.
getFilename());
1539 if (PLFileName !=
"")
1548 OS <<
'"' << FN <<
'"';
1550 Tok.
setKind(tok::string_literal);
1551 }
else if (II == Ident__DATE__) {
1555 Tok.
setKind(tok::string_literal);
1556 Tok.
setLength(strlen(
"\"Mmm dd yyyy\""));
1561 }
else if (II == Ident__TIME__) {
1565 Tok.
setKind(tok::string_literal);
1571 }
else if (II == Ident__INCLUDE_LEVEL__) {
1585 Tok.
setKind(tok::numeric_constant);
1586 }
else if (II == Ident__TIMESTAMP__) {
1601 time_t TT = CurFile->getModificationTime();
1602 struct tm *TM = localtime(&TT);
1603 Result = asctime(TM);
1605 Result =
"??? ??? ?? ??:??:?? ????\n";
1608 OS <<
'"' << StringRef(Result).drop_back() <<
'"';
1609 Tok.
setKind(tok::string_literal);
1610 }
else if (II == Ident__COUNTER__) {
1612 OS << CounterValue++;
1613 Tok.
setKind(tok::numeric_constant);
1614 }
else if (II == Ident__has_feature) {
1616 [
this](
Token &Tok,
bool &HasLexedNextToken) ->
int {
1618 diag::err_feature_check_malformed);
1621 }
else if (II == Ident__has_extension) {
1623 [
this](
Token &Tok,
bool &HasLexedNextToken) ->
int {
1625 diag::err_feature_check_malformed);
1628 }
else if (II == Ident__has_builtin) {
1630 [
this](
Token &Tok,
bool &HasLexedNextToken) ->
int {
1632 diag::err_feature_check_malformed);
1638 case Builtin::BI__builtin_operator_new:
1639 case Builtin::BI__builtin_operator_delete:
1647 }
else if (II->
getTokenID() != tok::identifier ||
1656 if (II->
getName().startswith(
"__builtin_") ||
1657 II->
getName().startswith(
"__is_") ||
1658 II->
getName().startswith(
"__has_"))
1660 return llvm::StringSwitch<bool>(II->
getName())
1661 .Case(
"__array_rank",
true)
1662 .Case(
"__array_extent",
true)
1663 .Case(
"__reference_binds_to_temporary",
true)
1664 .Case(
"__underlying_type",
true)
1667 return llvm::StringSwitch<bool>(II->
getName())
1669 .Case(
"__make_integer_seq", LangOpts.CPlusPlus)
1670 .Case(
"__type_pack_element", LangOpts.CPlusPlus)
1674 .Case(
"__is_target_arch",
true)
1675 .Case(
"__is_target_vendor",
true)
1676 .Case(
"__is_target_os",
true)
1677 .Case(
"__is_target_environment",
true)
1681 }
else if (II == Ident__is_identifier) {
1683 [](
Token &Tok,
bool &HasLexedNextToken) ->
int {
1684 return Tok.
is(tok::identifier);
1686 }
else if (II == Ident__has_attribute) {
1688 [
this](
Token &Tok,
bool &HasLexedNextToken) ->
int {
1690 diag::err_feature_check_malformed);
1694 }
else if (II == Ident__has_declspec) {
1696 [
this](
Token &Tok,
bool &HasLexedNextToken) ->
int {
1698 diag::err_feature_check_malformed);
1702 }
else if (II == Ident__has_cpp_attribute ||
1703 II == Ident__has_c_attribute) {
1704 bool IsCXX = II == Ident__has_cpp_attribute;
1706 OS, Tok, II, *
this, [&](
Token &Tok,
bool &HasLexedNextToken) ->
int {
1709 Tok, *
this, diag::err_feature_check_malformed);
1716 if (Tok.
isNot(tok::coloncolon))
1717 HasLexedNextToken =
true;
1722 diag::err_feature_check_malformed);
1730 }
else if (II == Ident__has_include ||
1731 II == Ident__has_include_next) {
1736 if (II == Ident__has_include)
1741 if (Tok.
isNot(tok::r_paren))
1744 Tok.
setKind(tok::numeric_constant);
1745 }
else if (II == Ident__has_warning) {
1748 [
this](
Token &Tok,
bool &HasLexedNextToken) ->
int {
1749 std::string WarningName;
1752 HasLexedNextToken = Tok.
is(tok::string_literal);
1759 if (WarningName.size() < 3 || WarningName[0] !=
'-' ||
1760 WarningName[1] !=
'W') {
1761 Diag(StrStartLoc, diag::warn_has_warning_invalid_option);
1772 WarningName.substr(2), Diags);
1774 }
else if (II == Ident__building_module) {
1779 [
this](
Token &Tok,
bool &HasLexedNextToken) ->
int {
1781 diag::err_expected_id_building_module);
1785 }
else if (II == Ident__MODULE__) {
1791 }
else if (II == Ident__identifier) {
1797 if (Tok.
isNot(tok::l_paren)) {
1800 << II << tok::l_paren;
1823 if (RParen.
isNot(tok::r_paren)) {
1825 << Tok.
getKind() << tok::r_paren;
1826 Diag(LParenLoc, diag::note_matching) << tok::l_paren;
1829 }
else if (II == Ident__is_target_arch) {
1831 OS, Tok, II, *
this, [
this](
Token &Tok,
bool &HasLexedNextToken) ->
int {
1833 Tok, *
this, diag::err_feature_check_malformed);
1836 }
else if (II == Ident__is_target_vendor) {
1838 OS, Tok, II, *
this, [
this](
Token &Tok,
bool &HasLexedNextToken) ->
int {
1840 Tok, *
this, diag::err_feature_check_malformed);
1843 }
else if (II == Ident__is_target_os) {
1845 OS, Tok, II, *
this, [
this](
Token &Tok,
bool &HasLexedNextToken) ->
int {
1847 Tok, *
this, diag::err_feature_check_malformed);
1850 }
else if (II == Ident__is_target_environment) {
1852 OS, Tok, II, *
this, [
this](
Token &Tok,
bool &HasLexedNextToken) ->
int {
1854 Tok, *
this, diag::err_feature_check_malformed);
1858 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
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
CharacteristicKind
Indicates whether a file or directory holds normal user code, system code, or system code which is im...
This interface provides a way to observe the actions of the preprocessor as it does its thing...
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 ...
HeaderSearch & getHeaderSearchInfo() const
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.
bool GetIncludeFilenameSpelling(SourceLocation Loc, StringRef &Buffer)
Turn the specified lexer token into a fully checked and spelled filename, e.g.
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.
PPCallbacks * getPPCallbacks() const
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.
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.
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.
Optional< FileEntryRef > 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 *IsFrameworkFound, bool SkipCache=false)
Given a "foo" or <foo> reference, look up the indicated file.
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 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...
const IntrusiveRefCntPtr< DiagnosticIDs > & getDiagnosticIDs() const
Defines the clang::SourceLocation class and associated facilities.
bool hasRevertedTokenIDToIdentifier() const
True if revertTokenIDToIdentifier() was called.
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 EnterMacro(Token &Tok, 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...
static void remapMacroPath(SmallString< 256 > &Path, const std::map< std::string, std::string, std::greater< std::string >> &MacroPrefixMap)
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.
bool LexHeaderName(Token &Result, bool AllowMacroExpansion=true)
Lex a token, forming a header-name token if possible.
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.
Defines enum values for all the target-independent builtin functions.
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.