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/STLExtras.h"
39#include "llvm/ADT/SmallVector.h"
40#include "llvm/ADT/StringRef.h"
41#include "llvm/ADT/StringSwitch.h"
42#include "llvm/Support/ErrorHandling.h"
43#include "llvm/Support/Format.h"
44#include "llvm/Support/Path.h"
45#include "llvm/Support/raw_ostream.h"
64 auto Pos = CurSubmoduleState->Macros.find(II);
65 return Pos == CurSubmoduleState->Macros.end() ?
nullptr
66 : Pos->second.getLatest();
70 assert(MD &&
"MacroDirective should be non-zero!");
71 assert(!MD->
getPrevious() &&
"Already attached to a MacroDirective history.");
73 MacroState &StoredMD = CurSubmoduleState->Macros[II];
74 auto *OldMD = StoredMD.getLatest();
76 StoredMD.setLatest(MD);
77 StoredMD.overrideActiveModuleMacros(*
this, II);
79 if (needModuleMacros()) {
83 PendingModuleMacroNames.push_back(II);
88 if (!MD->
isDefined() && !LeafModuleMacros.contains(II))
107 MacroState &StoredMD = CurSubmoduleState->Macros[II];
109 if (
auto *OldMD = StoredMD.getLatest()) {
115 assert(OldMD->getMacroInfo()->isBuiltinMacro() &&
116 "only built-ins should have an entry here");
117 assert(!OldMD->getPrevious() &&
"builtin should only have a single entry");
119 StoredMD.setLatest(MD);
126 if (!MD->
isDefined() && !LeafModuleMacros.contains(II))
134 llvm::FoldingSetInsertToken InsertToken;
135 if (
auto *MM = ModuleMacros.lookup({Mod, II}, InsertToken)) {
141 ModuleMacros.insert(MM, InsertToken);
145 for (
auto *O : Overrides) {
146 HidAny |= (O->NumOverriddenBy == 0);
147 ++O->NumOverriddenBy;
151 auto &LeafMacros = LeafModuleMacros[II];
153 llvm::erase_if(LeafMacros,
154 [](
ModuleMacro *MM) {
return MM->NumOverriddenBy != 0; });
158 LeafMacros.push_back(MM);
168 llvm::FoldingSetInsertToken InsertToken;
169 return ModuleMacros.lookup({Mod, II}, InsertToken);
173 FullModuleMacroInfo &Info) {
174 assert(Info.ActiveModuleMacrosGeneration !=
176 "don't need to update this macro name info");
177 Info.ActiveModuleMacrosGeneration =
180 auto Leaf = LeafModuleMacros.find(II);
181 if (Leaf == LeafModuleMacros.end()) {
186 Info.ActiveModuleMacros.clear();
189 llvm::DenseMap<ModuleMacro *, int> NumHiddenOverrides;
190 for (
auto *O : Info.OverriddenMacros)
191 NumHiddenOverrides[O] = -1;
195 for (
auto *LeafMM : Leaf->second) {
196 assert(LeafMM->getNumOverridingMacros() == 0 &&
"leaf macro overridden");
197 if (NumHiddenOverrides.lookup(LeafMM) == 0)
198 Worklist.push_back(LeafMM);
200 while (!Worklist.empty()) {
201 auto *MM = Worklist.pop_back_val();
202 if (CurSubmoduleState->VisibleModules.isVisible(MM->getOwningModule())) {
205 if (MM->getMacroInfo())
206 Info.ActiveModuleMacros.push_back(MM);
208 for (
auto *O : MM->overrides())
209 if ((
unsigned)++NumHiddenOverrides[O] == O->getNumOverridingMacros())
210 Worklist.push_back(O);
214 std::reverse(Info.ActiveModuleMacros.begin(), Info.ActiveModuleMacros.end());
217 MacroInfo *MI =
nullptr;
218 bool IsSystemMacro =
true;
219 bool IsAmbiguous =
false;
220 if (
auto *MD = Info.MD) {
221 while (isa_and_nonnull<VisibilityMacroDirective>(MD))
222 MD = MD->getPrevious();
223 if (
auto *DMD = dyn_cast_or_null<DefMacroDirective>(MD)) {
225 IsSystemMacro &= SourceMgr.isInSystemHeader(DMD->getLocation());
228 for (
auto *Active : Info.ActiveModuleMacros) {
229 auto *NewMI = Active->getMacroInfo();
240 if (MI && NewMI != MI &&
243 IsSystemMacro &= Active->getOwningModule()->IsSystem ||
244 SourceMgr.isInSystemHeader(NewMI->getDefinitionLoc());
247 Info.IsAmbiguous = IsAmbiguous && !IsSystemMacro;
252 auto LeafIt = LeafModuleMacros.find(II);
253 if (LeafIt != LeafModuleMacros.end())
254 Leaf = LeafIt->second;
255 const MacroState *State =
nullptr;
256 auto Pos = CurSubmoduleState->Macros.find(II);
257 if (Pos != CurSubmoduleState->Macros.end())
258 State = &Pos->second;
260 llvm::errs() <<
"MacroState " << State <<
" " << II->
getNameStart();
261 const auto ModuleInfo =
263 if (ModuleInfo.IsAmbiguous)
264 llvm::errs() <<
" ambiguous";
265 if (State && !State->getOverriddenMacros().empty()) {
266 llvm::errs() <<
" overrides";
267 for (
auto *O : State->getOverriddenMacros())
268 llvm::errs() <<
" " << O->getOwningModule()->getFullModuleName();
270 llvm::errs() <<
"\n";
273 for (
auto *MD = State ? State->getLatest() :
nullptr; MD;
274 MD = MD->getPrevious()) {
280 llvm::DenseSet<ModuleMacro *> Active(llvm::from_range,
281 ModuleInfo.ActiveModuleMacros);
282 llvm::DenseSet<ModuleMacro*> Visited;
284 while (!Worklist.empty()) {
285 auto *MM = Worklist.pop_back_val();
286 llvm::errs() <<
" ModuleMacro " << MM <<
" "
287 << MM->getOwningModule()->getFullModuleName();
288 if (!MM->getMacroInfo())
289 llvm::errs() <<
" undef";
291 if (Active.count(MM))
292 llvm::errs() <<
" active";
293 else if (!CurSubmoduleState->VisibleModules.isVisible(
294 MM->getOwningModule()))
295 llvm::errs() <<
" hidden";
296 else if (MM->getMacroInfo())
297 llvm::errs() <<
" overridden";
299 if (!MM->overrides().empty()) {
300 llvm::errs() <<
" overrides";
301 for (
auto *O : MM->overrides()) {
302 llvm::errs() <<
" " << O->getOwningModule()->getFullModuleName();
303 if (Visited.insert(O).second)
304 Worklist.push_back(O);
307 llvm::errs() <<
"\n";
308 if (
auto *MI = MM->getMacroInfo()) {
311 llvm::errs() <<
"\n";
318void Preprocessor::RegisterBuiltinMacros() {
319 Ident__LINE__ = RegisterBuiltinMacro(
"__LINE__");
320 Ident__FILE__ = RegisterBuiltinMacro(
"__FILE__");
324 Ident__DATE__ = RegisterBuiltinMacro(
"__DATE__");
325 Ident__TIME__ = RegisterBuiltinMacro(
"__TIME__");
327 Ident__DATE__ =
nullptr;
328 Ident__TIME__ =
nullptr;
330 Ident__COUNTER__ = RegisterBuiltinMacro(
"__COUNTER__");
331 Ident_Pragma = RegisterBuiltinMacro(
"_Pragma");
332 Ident__FLT_EVAL_METHOD__ = RegisterBuiltinMacro(
"__FLT_EVAL_METHOD__");
336 Ident__has_cpp_attribute = RegisterBuiltinMacro(
"__has_cpp_attribute");
338 Ident__has_cpp_attribute =
nullptr;
341 Ident__BASE_FILE__ = RegisterBuiltinMacro(
"__BASE_FILE__");
342 Ident__INCLUDE_LEVEL__ = RegisterBuiltinMacro(
"__INCLUDE_LEVEL__");
344 Ident__TIMESTAMP__ = RegisterBuiltinMacro(
"__TIMESTAMP__");
346 Ident__TIMESTAMP__ =
nullptr;
350 Ident__identifier = RegisterBuiltinMacro(
"__identifier");
351 Ident__pragma = RegisterBuiltinMacro(
"__pragma");
353 Ident__identifier =
nullptr;
354 Ident__pragma =
nullptr;
358 Ident__FILE_NAME__ = RegisterBuiltinMacro(
"__FILE_NAME__");
359 Ident__has_feature = RegisterBuiltinMacro(
"__has_feature");
360 Ident__has_extension = RegisterBuiltinMacro(
"__has_extension");
361 Ident__has_builtin = RegisterBuiltinMacro(
"__has_builtin");
362 Ident__has_constexpr_builtin =
363 RegisterBuiltinMacro(
"__has_constexpr_builtin");
364 Ident__has_attribute = RegisterBuiltinMacro(
"__has_attribute");
366 Ident__has_c_attribute = RegisterBuiltinMacro(
"__has_c_attribute");
368 Ident__has_c_attribute =
nullptr;
370 Ident__has_declspec = RegisterBuiltinMacro(
"__has_declspec_attribute");
371 Ident__has_embed = RegisterBuiltinMacro(
"__has_embed");
372 Ident__has_include = RegisterBuiltinMacro(
"__has_include");
373 Ident__has_include_next = RegisterBuiltinMacro(
"__has_include_next");
374 Ident__has_warning = RegisterBuiltinMacro(
"__has_warning");
375 Ident__is_identifier = RegisterBuiltinMacro(
"__is_identifier");
376 Ident__is_target_arch = RegisterBuiltinMacro(
"__is_target_arch");
377 Ident__is_target_vendor = RegisterBuiltinMacro(
"__is_target_vendor");
378 Ident__is_target_os = RegisterBuiltinMacro(
"__is_target_os");
379 Ident__is_target_environment =
380 RegisterBuiltinMacro(
"__is_target_environment");
381 Ident__is_target_variant_os = RegisterBuiltinMacro(
"__is_target_variant_os");
382 Ident__is_target_variant_environment =
383 RegisterBuiltinMacro(
"__is_target_variant_environment");
386 Ident__building_module = RegisterBuiltinMacro(
"__building_module");
388 Ident__MODULE__ = RegisterBuiltinMacro(
"__MODULE__");
390 Ident__MODULE__ =
nullptr;
401 if (!II)
return true;
411 if (ExpansionMI->isEnabled() &&
422 return !llvm::is_contained(MI->
params(), II);
427bool Preprocessor::HandleMacroExpandedIdentifier(
Token &Identifier,
436 if (CurPPLexer) CurPPLexer->MIOpt.ExpandedMacro();
441 Callbacks->MacroExpands(Identifier, M, Identifier.
getLocation(),
443 ExpandBuiltinMacro(Identifier);
454 SourceLocation ExpansionEnd = Identifier.
getLocation();
462 ArgMacro = &Identifier;
464 Args = ReadMacroCallArgumentList(Identifier, MI, ExpansionEnd);
471 if (!Args)
return true;
473 ++NumFnMacroExpanded;
482 SourceLocation ExpandLoc = Identifier.
getLocation();
483 SourceRange ExpansionRange(ExpandLoc, ExpansionEnd);
491 DelayedMacroExpandsCallbacks.push_back(
492 MacroExpandsInfo(Identifier, M, ExpansionRange));
494 Callbacks->MacroExpands(Identifier, M, ExpansionRange, Args);
495 if (!DelayedMacroExpandsCallbacks.empty()) {
496 for (
const MacroExpandsInfo &Info : DelayedMacroExpandsCallbacks) {
498 Callbacks->MacroExpands(Info.Tok, Info.MD, Info.Range,
501 DelayedMacroExpandsCallbacks.clear();
508 Diag(Identifier, diag::warn_pp_ambiguous_macro)
525 if (Args) Args->
destroy(*
this);
530 PropagateLineStartLeadingSpaceInfo(Identifier);
531 ++NumFastMacroExpanded;
541 if (Args) Args->
destroy(*
this);
558 SourceMgr.createExpansionLoc(Identifier.
getLocation(), ExpandLoc,
566 if (!NewMI->isEnabled() || NewMI == MI) {
571 Diag(Identifier, diag::pp_disabled_macro_expansion);
577 ++NumFastMacroExpanded;
582 EnterMacro(Identifier, ExpansionEnd, MI, Args);
598 if (I->is(tok::l_paren)) {
599 Brackets.push_back(
Paren);
600 }
else if (I->is(tok::r_paren)) {
601 if (Brackets.empty() || Brackets.back() ==
Brace)
604 }
else if (I->is(tok::l_brace)) {
605 Brackets.push_back(
Brace);
606 }
else if (I->is(tok::r_brace)) {
607 if (Brackets.empty() || Brackets.back() ==
Paren)
612 return Brackets.empty();
646 bool FoundSeparatorToken =
false;
650 if (I->is(tok::l_brace)) {
652 }
else if (I->is(tok::r_brace)) {
654 if (
Braces == 0 && ClosingBrace == E && FoundSeparatorToken)
656 }
else if (I->is(tok::eof)) {
661 FoundSeparatorToken =
true;
662 I->setKind(tok::comma);
670 if (FoundSeparatorToken && ArgStartIterator->is(tok::l_brace)) {
678 if (FoundSeparatorToken) {
680 TempToken.
setKind(tok::l_paren);
681 TempToken.
setLocation(ArgStartIterator->getLocation());
683 NewTokens.push_back(TempToken);
687 NewTokens.insert(NewTokens.end(), ArgStartIterator, I);
690 if (FoundSeparatorToken) {
693 TempToken.
setKind(tok::r_paren);
696 NewTokens.push_back(TempToken);
697 ParenHints.push_back(
SourceRange(ArgStartIterator->getLocation(),
702 NewTokens.push_back(*I);
705 ArgStartIterator = I + 1;
706 FoundSeparatorToken =
false;
711 return !ParenHints.empty() && InitLists.empty();
718MacroArgs *Preprocessor::ReadMacroCallArgumentList(
Token &MacroName,
731 assert(
Tok.
is(tok::l_paren) &&
"Error computing l-paren-ness?");
736 SmallVector<Token, 64> ArgTokens;
737 bool ContainsCodeCompletionTok =
false;
738 bool FoundElidedComma =
false;
740 SourceLocation TooManyArgsLoc;
742 unsigned NumActuals = 0;
744 if (ContainsCodeCompletionTok &&
Tok.
isOneOf(tok::eof, tok::eod))
747 assert(
Tok.
isOneOf(tok::l_paren, tok::comma) &&
748 "only expect argument separators here");
750 size_t ArgTokenStart = ArgTokens.size();
755 unsigned NumParens = 0;
763 if (!ContainsCodeCompletionTok) {
764 Diag(MacroName, diag::err_unterm_macro_invoc);
772 auto Toks = std::make_unique<Token[]>(1);
774 EnterTokenStream(std::move(Toks), 1,
true,
false);
776 }
else if (
Tok.
is(tok::r_paren)) {
778 if (NumParens-- == 0) {
780 if (!ArgTokens.empty() &&
781 ArgTokens.back().commaAfterElided()) {
782 FoundElidedComma =
true;
786 }
else if (
Tok.
is(tok::l_paren)) {
788 }
else if (
Tok.
is(tok::comma)) {
799 }
else if (NumParens == 0) {
805 if (NumFixedArgsLeft > 1)
808 }
else if (
Tok.
is(tok::comment) && !KeepMacroComments) {
822 }
else if (
Tok.
is(tok::code_completion)) {
823 ContainsCodeCompletionTok =
true;
832 ArgTokens.push_back(
Tok);
837 if (ArgTokens.empty() &&
Tok.
getKind() == tok::r_paren)
842 if (!isVariadic && NumFixedArgsLeft == 0 && TooManyArgsLoc.
isInvalid()) {
843 if (ArgTokens.size() != ArgTokenStart)
844 TooManyArgsLoc = ArgTokens[ArgTokenStart].getLocation();
846 TooManyArgsLoc = ArgStartLoc;
855 Diag(
Tok, diag::ext_empty_fnmacro_arg);
864 ArgTokens.push_back(EOFTok);
866 if (!ContainsCodeCompletionTok && NumFixedArgsLeft != 0)
876 if (!isVariadic && NumActuals > MinArgsExpected &&
877 !ContainsCodeCompletionTok) {
880 Diag(TooManyArgsLoc, diag::err_too_many_args_in_macro_invoc);
889 SmallVector<Token, 4> FixedArgTokens;
890 unsigned FixedNumArgs = 0;
891 SmallVector<SourceRange, 4> ParenHints, InitLists;
893 ParenHints, InitLists)) {
894 if (!InitLists.empty()) {
895 DiagnosticBuilder DB =
897 diag::note_init_list_at_beginning_of_macro_argument);
898 for (SourceRange Range : InitLists)
903 if (FixedNumArgs != MinArgsExpected)
906 DiagnosticBuilder DB =
Diag(MacroName, diag::note_suggest_parens_for_macro);
907 for (SourceRange ParenLocation : ParenHints) {
911 ArgTokens.swap(FixedArgTokens);
912 NumActuals = FixedNumArgs;
916 bool isVarargsElided =
false;
918 if (ContainsCodeCompletionTok) {
925 for (; NumActuals < MinArgsExpected; ++NumActuals)
926 ArgTokens.push_back(EOFTok);
929 if (NumActuals < MinArgsExpected) {
931 if (NumActuals == 0 && MinArgsExpected == 1) {
938 }
else if ((FoundElidedComma || MI->
isVariadic()) &&
939 (NumActuals+1 == MinArgsExpected ||
940 (NumActuals == 0 && MinArgsExpected == 2))) {
954 ID = diag::warn_cxx17_compat_missing_varargs_arg;
956 ID = diag::ext_cxx_missing_varargs_arg;
958 ID = diag::warn_c17_compat_missing_varargs_arg;
960 ID = diag::ext_c_missing_varargs_arg;
972 isVarargsElided =
true;
973 }
else if (!ContainsCodeCompletionTok) {
975 Diag(
Tok, diag::err_too_few_args_in_macro_invoc);
987 ArgTokens.push_back(
Tok);
990 if (NumActuals == 0 && MinArgsExpected == 2)
991 ArgTokens.push_back(
Tok);
993 }
else if (NumActuals > MinArgsExpected && !MI->
isVariadic() &&
994 !ContainsCodeCompletionTok) {
997 Diag(MacroName, diag::err_too_many_args_in_macro_invoc);
1017 size_t newIndex = MacroExpandedTokens.size();
1018 bool cacheNeedsToGrow = tokens.size() >
1019 MacroExpandedTokens.capacity()-MacroExpandedTokens.size();
1020 MacroExpandedTokens.append(tokens.begin(), tokens.end());
1022 if (cacheNeedsToGrow) {
1025 for (
const auto &Lexer : MacroExpandingLexersStack) {
1026 TokenLexer *prevLexer;
1028 std::tie(prevLexer, tokIndex) = Lexer;
1029 prevLexer->Tokens = MacroExpandedTokens.data() + tokIndex;
1033 MacroExpandingLexersStack.push_back(std::make_pair(tokLexer, newIndex));
1034 return MacroExpandedTokens.data() + newIndex;
1037void Preprocessor::removeCachedMacroExpandedTokensOfLastLexer() {
1038 assert(!MacroExpandingLexersStack.empty());
1039 size_t tokIndex = MacroExpandingLexersStack.back().second;
1040 assert(tokIndex < MacroExpandedTokens.size());
1042 MacroExpandedTokens.resize(tokIndex);
1043 MacroExpandingLexersStack.pop_back();
1062 DATETokLen = strlen(
"\"1\"");
1070 TIMETokLen = strlen(
"\"1\"");
1079 TM = std::gmtime(&TT);
1081 TT = std::time(
nullptr);
1082 TM = std::localtime(&TT);
1085 static const char *
const Months[] = {
1086 "Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec"
1091 llvm::raw_svector_ostream TmpStream(TmpBuffer);
1093 TmpStream << llvm::format(
"\"%s %2d %4d\"", Months[TM->tm_mon],
1094 TM->tm_mday, TM->tm_year + 1900);
1096 TmpStream <<
"??? ?? ????";
1102 DATETokLen = strlen(
"\"Mmm dd yyyy\"");
1106 llvm::raw_svector_ostream TmpStream(TmpBuffer);
1108 TmpStream << llvm::format(
"\"%02d:%02d:%02d\"", TM->tm_hour, TM->tm_min,
1111 TmpStream <<
"??:??:??";
1117 TIMETokLen = strlen(
"\"hh:mm:ss\"");
1130#define FEATURE(Name, Predicate) .Case(#Name, Predicate)
1131 return llvm::StringSwitch<bool>(
Feature)
1132#include "clang/Basic/Features.def"
1153 if (Extension.starts_with(
"__") && Extension.ends_with(
"__") &&
1154 Extension.size() >= 4)
1155 Extension = Extension.substr(2, Extension.size() - 4);
1159#define EXTENSION(Name, Predicate) .Case(#Name, Predicate)
1160 return llvm::StringSwitch<bool>(Extension)
1161#include "clang/Basic/Features.def"
1179 PP.
Diag(LParenLoc, diag::err_pp_directive_required) << II;
1181 assert(
Tok.is(tok::identifier));
1182 Tok.setIdentifierInfo(II);
1190 }
while (
Tok.getKind() == tok::comment);
1193 if (
Tok.isNot(tok::l_paren)) {
1196 PP.
Diag(LParenLoc, diag::err_pp_expected_after) << II << tok::l_paren;
1199 if (
Tok.isNot(tok::header_name))
1203 LParenLoc =
Tok.getLocation();
1208 if (
Tok.isNot(tok::header_name)) {
1209 PP.
Diag(
Tok.getLocation(), diag::err_pp_expects_filename);
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())
1246 PP.
LookupFile(FilenameLoc, Filename, isAngled, LookupFrom, LookupFromFile,
1247 nullptr,
nullptr,
nullptr, &KH,
nullptr,
nullptr);
1253 Callbacks->HasInclude(FilenameLoc, Filename, isAngled,
File,
FileType);
1257 return File.has_value();
1265 Diag(
Tok, diag::err_pp_directive_required) << II;
1267 assert(
Tok.
is(tok::identifier));
1275 Diag(
Tok, diag::err_pp_expected_after) << II << tok::l_paren;
1293 Token FilenameTok =
Tok;
1295 std::optional<LexEmbedParametersResult> Params =
1303 << II << tok::r_paren;
1304 Diag(LParenLoc, diag::note_matching) << tok::l_paren;
1310 if (Params->UnrecognizedParams > 0)
1313 SmallString<128> FilenameBuffer;
1314 StringRef Filename = this->
getSpelling(FilenameTok, FilenameBuffer);
1315 if (Filename.empty())
1325 Callbacks->HasEmbed(LParenLoc, Filename, isAngled, MaybeFileEntry);
1327 if (!MaybeFileEntry)
1330 size_t FileSize = MaybeFileEntry->
getSize();
1333 if (Params->MaybeOffsetParam) {
1334 if (Params->MaybeOffsetParam->Offset > FileSize)
1337 FileSize -= Params->MaybeOffsetParam->Offset;
1342 if (Params->MaybeLimitParam) {
1343 if (Params->MaybeLimitParam->Limit > FileSize)
1346 FileSize = Params->MaybeLimitParam->Limit;
1362 const FileEntry *LookupFromFile;
1363 std::tie(Lookup, LookupFromFile) = getIncludeNextStart(
Tok);
1375 bool &HasLexedNextTok)> Op) {
1378 if (
Tok.isNot(tok::l_paren)) {
1379 PP.
Diag(
Tok.getLocation(), diag::err_pp_expected_after) << II
1383 if (!
Tok.isOneOf(tok::eof, tok::eod)) {
1385 Tok.setKind(tok::numeric_constant);
1390 unsigned ParenDepth = 1;
1392 std::optional<int>
Result;
1395 bool SuppressDiagnostic =
false;
1396 while (
Tok.isNoneOf(tok::eod, tok::eof)) {
1404 switch (
Tok.getKind()) {
1409 PP.
Diag(
Tok.getLocation(), diag::err_unterm_macro_invoc);
1413 if (!SuppressDiagnostic) {
1414 PP.
Diag(
Tok.getLocation(), diag::err_too_many_args_in_macro_invoc);
1415 SuppressDiagnostic =
true;
1423 if (!SuppressDiagnostic) {
1424 PP.
Diag(
Tok.getLocation(), diag::err_pp_nested_paren) << II;
1425 SuppressDiagnostic =
true;
1430 if (--ParenDepth > 0)
1443 if (!SuppressDiagnostic)
1444 PP.
Diag(
Tok.getLocation(), diag::err_too_few_args_in_macro_invoc);
1446 Tok.setKind(tok::numeric_constant);
1454 bool HasLexedNextToken =
false;
1457 if (HasLexedNextToken)
1464 if (!SuppressDiagnostic) {
1465 if (
auto Diag = PP.
Diag(
Tok.getLocation(), diag::err_pp_expected_after)) {
1472 PP.
Diag(LParenLoc, diag::note_matching) << tok::l_paren;
1473 SuppressDiagnostic =
true;
1484 if (!
Tok.isAnnotation() && (II =
Tok.getIdentifierInfo()))
1487 PP.
Diag(
Tok.getLocation(), DiagID);
1494 const llvm::Triple &TT = TI.
getTriple();
1497 if ((
Arch.getSubArch() == llvm::Triple::NoSubArch ||
1498 Arch.getSubArch() == TT.getSubArch()) &&
1499 ((TT.getArch() == llvm::Triple::thumb &&
1500 Arch.getArch() == llvm::Triple::arm) ||
1501 (TT.getArch() == llvm::Triple::thumbeb &&
1502 Arch.getArch() == llvm::Triple::armeb)))
1507 return (
Arch.getSubArch() == llvm::Triple::NoSubArch ||
1508 Arch.getSubArch() == TT.getSubArch()) &&
1509 Arch.getArch() == TT.getArch();
1514 StringRef VendorName = TI.
getTriple().getVendorName();
1515 if (VendorName.empty())
1516 VendorName =
"unknown";
1517 return VendorName.equals_insensitive(II->
getName());
1522 llvm::Triple OS(llvm::Twine(
"unknown-unknown-") + II->
getName().lower());
1523 if (OS.getOS() == llvm::Triple::Darwin) {
1527 return TI.
getTriple().getOS() == OS.getOS();
1533 llvm::Triple Env(llvm::Twine(
"---") + II->
getName().lower());
1536 if (Env.getEnvironment() == llvm::Triple::UnknownEnvironment &&
1537 Env.getEnvironmentName() !=
"unknown")
1539 return TI.
getTriple().getEnvironment() == Env.getEnvironment();
1549 llvm::Triple OS(llvm::Twine(
"unknown-unknown-") + II->
getName().lower());
1550 if (OS.getOS() == llvm::Triple::Darwin) {
1552 return VariantTriple->isOSDarwin();
1554 return VariantTriple->getOS() == OS.getOS();
1566 llvm::Triple Env(llvm::Twine(
"---") + II->
getName().lower());
1567 return VariantTriple->getEnvironment() == Env.getEnvironment();
1572#if defined(__sun__) && defined(__svr4__) && defined(__clang__) && \
1578asm(
"_ZNKSt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES3_"
1579 "RSt8ios_basecPKSt2tmPKcSB_ = "
1580 "_ZNKSt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES3_"
1581 "RSt8ios_basecPK2tmPKcSB_");
1586#define TYPE_TRAIT_1(Spelling, Name, Key) \
1587 case tok::kw_##Spelling: \
1589#define TYPE_TRAIT_2(Spelling, Name, Key) \
1590 case tok::kw_##Spelling: \
1592#define TYPE_TRAIT_N(Spelling, Name, Key) \
1593 case tok::kw_##Spelling: \
1595#define ARRAY_TYPE_TRAIT(Spelling, Name, Key) \
1596 case tok::kw_##Spelling: \
1598#define EXPRESSION_TRAIT(Spelling, Name, Key) \
1599 case tok::kw_##Spelling: \
1601#define TRANSFORM_TYPE_TRAIT_DEF(K, Spelling) \
1602 case tok::kw___##Spelling: \
1605 switch (
Tok.getKind()) {
1608#include "clang/Basic/BuiltinTraits.inc"
1614void Preprocessor::ExpandBuiltinMacro(
Token &
Tok) {
1617 assert(II &&
"Can't be a macro without id info!");
1622 if (II == Ident_Pragma)
1623 return Handle_Pragma(
Tok);
1624 else if (II == Ident__pragma)
1625 return HandleMicrosoft__pragma(
Tok);
1627 ++NumBuiltinMacroExpanded;
1629 SmallString<128> TmpBuffer;
1630 llvm::raw_svector_ostream
OS(TmpBuffer);
1638 if (II == Ident__LINE__) {
1653 Loc = SourceMgr.getExpansionRange(Loc).getEnd();
1654 PresumedLoc PLoc = SourceMgr.getPresumedLoc(Loc);
1659 }
else if (II == Ident__FILE__ || II == Ident__BASE_FILE__ ||
1660 II == Ident__FILE_NAME__) {
1667 if (II == Ident__BASE_FILE__ && PLoc.
isValid()) {
1670 PLoc = SourceMgr.getPresumedLoc(NextLoc);
1679 SmallString<256> FN;
1683 if (II == Ident__FILE_NAME__) {
1690 OS <<
'"' << FN <<
'"';
1693 }
else if (II == Ident__DATE__) {
1696 size_t TIMETokLen = 0, DATETokLen = 0;
1704 }
else if (II == Ident__TIME__) {
1707 size_t TIMETokLen = 0, DATETokLen = 0;
1715 }
else if (II == Ident__INCLUDE_LEVEL__) {
1723 for (; PLoc.
isValid(); ++Depth)
1730 }
else if (II == Ident__TIMESTAMP__) {
1734 std::string
Result =
"1";
1735 std::stringstream TmpStream;
1739 TmpStream.imbue(std::locale(
"C"));
1742 std::tm *TM = std::gmtime(&TT);
1743 TmpStream << std::put_time(TM,
"%a %b %e %T %Y");
1747 const FileEntry *CurFile =
nullptr;
1749 CurFile = SourceMgr.getFileEntryForID(TheLexer->getFileID());
1752 struct tm *TM = localtime(&TT);
1753 TmpStream << std::put_time(TM,
"%a %b %e %T %Y");
1756 Result = TmpStream.str();
1758 Result =
"??? ??? ?? ??:??:?? ????";
1762 }
else if (II == Ident__FLT_EVAL_METHOD__) {
1770 Diag(
Tok, diag::err_illegal_use_of_flt_eval_macro);
1773 }
else if (II == Ident__COUNTER__) {
1778 constexpr uint32_t MaxPosValue = std::numeric_limits<int32_t>::max();
1779 if (CounterValue > MaxPosValue) {
1785 CounterValue = MaxPosValue;
1787 OS << CounterValue++;
1789 }
else if (II == Ident__has_feature) {
1791 [
this](Token &
Tok,
bool &HasLexedNextToken) ->
int {
1793 diag::err_feature_check_malformed);
1796 }
else if (II == Ident__has_extension) {
1798 [
this](Token &
Tok,
bool &HasLexedNextToken) ->
int {
1800 diag::err_feature_check_malformed);
1803 }
else if (II == Ident__has_builtin) {
1805 OS,
Tok, II, *
this,
false,
1806 [
this](Token &
Tok,
bool &HasLexedNextToken) ->
int {
1808 Tok, *
this, diag::err_feature_check_malformed);
1812 if (BuiltinID != 0) {
1814 case Builtin::BI__builtin_cpu_is:
1816 case Builtin::BI__builtin_cpu_init:
1818 case Builtin::BI__builtin_cpu_supports:
1820 case Builtin::BI__builtin_operator_new:
1821 case Builtin::BI__builtin_operator_delete:
1836 }
else if (II->
getTokenID() != tok::identifier &&
1837 II->
getName().starts_with(
"__builtin_")) {
1840 return llvm::StringSwitch<bool>(II->
getName())
1842#define BuiltinTemplate(BTName) .Case(#BTName, getLangOpts().CPlusPlus)
1843#include "clang/Basic/BuiltinTemplates.inc"
1847 .Case(
"__is_target_arch",
true)
1848 .Case(
"__is_target_vendor",
true)
1849 .Case(
"__is_target_os",
true)
1850 .Case(
"__is_target_environment",
true)
1851 .Case(
"__is_target_variant_os",
true)
1852 .Case(
"__is_target_variant_environment",
true)
1856 }
else if (II == Ident__has_constexpr_builtin) {
1858 OS,
Tok, II, *
this,
false,
1859 [
this](Token &
Tok,
bool &HasLexedNextToken) ->
int {
1861 Tok, *
this, diag::err_feature_check_malformed);
1865 return BuiltinOp != 0 &&
1868 }
else if (II == Ident__is_identifier) {
1870 [](Token &
Tok,
bool &HasLexedNextToken) ->
int {
1871 return Tok.
is(tok::identifier);
1873 }
else if (II == Ident__has_attribute) {
1875 [
this](Token &
Tok,
bool &HasLexedNextToken) ->
int {
1877 diag::err_feature_check_malformed);
1882 }
else if (II == Ident__has_declspec) {
1884 [
this](Token &
Tok,
bool &HasLexedNextToken) ->
int {
1886 diag::err_feature_check_malformed);
1889 return LangOpts.DeclSpecKeyword &&
1896 }
else if (II == Ident__has_cpp_attribute ||
1897 II == Ident__has_c_attribute) {
1898 bool IsCXX = II == Ident__has_cpp_attribute;
1900 [&](Token &
Tok,
bool &HasLexedNextToken) ->
int {
1901 IdentifierInfo *ScopeII =
nullptr;
1903 Tok, *
this, diag::err_feature_check_malformed);
1911 HasLexedNextToken =
true;
1917 diag::err_feature_check_malformed);
1927 }
else if (II == Ident__has_include ||
1928 II == Ident__has_include_next) {
1933 if (II == Ident__has_include)
1934 Value = EvaluateHasInclude(
Tok, II);
1936 Value = EvaluateHasIncludeNext(
Tok, II);
1942 }
else if (II == Ident__has_embed) {
1952 OS << static_cast<int>(
Value);
1953 }
else if (II == Ident__has_warning) {
1956 [
this](Token &
Tok,
bool &HasLexedNextToken) ->
int {
1957 std::string WarningName;
1960 HasLexedNextToken =
Tok.
is(tok::string_literal);
1967 if (WarningName.size() < 3 || WarningName[0] !=
'-' ||
1968 WarningName[1] !=
'W') {
1969 Diag(StrStartLoc, diag::warn_has_warning_invalid_option);
1977 SmallVector<diag::kind, 10> Diags;
1980 WarningName.substr(2), Diags);
1982 }
else if (II == Ident__building_module) {
1987 [
this](Token &
Tok,
bool &HasLexedNextToken) ->
int {
1989 diag::err_expected_id_building_module);
1993 }
else if (II == Ident__MODULE__) {
1999 }
else if (II == Ident__identifier) {
2008 << II << tok::l_paren;
2039 if (RParen.
isNot(tok::r_paren)) {
2042 Diag(LParenLoc, diag::note_matching) << tok::l_paren;
2045 }
else if (II == Ident__is_target_arch) {
2047 OS,
Tok, II, *
this,
false,
2048 [
this](Token &
Tok,
bool &HasLexedNextToken) ->
int {
2050 Tok, *
this, diag::err_feature_check_malformed);
2053 }
else if (II == Ident__is_target_vendor) {
2055 OS,
Tok, II, *
this,
false,
2056 [
this](Token &
Tok,
bool &HasLexedNextToken) ->
int {
2058 Tok, *
this, diag::err_feature_check_malformed);
2061 }
else if (II == Ident__is_target_os) {
2063 OS,
Tok, II, *
this,
false,
2064 [
this](Token &
Tok,
bool &HasLexedNextToken) ->
int {
2066 Tok, *
this, diag::err_feature_check_malformed);
2069 }
else if (II == Ident__is_target_environment) {
2071 OS,
Tok, II, *
this,
false,
2072 [
this](Token &
Tok,
bool &HasLexedNextToken) ->
int {
2074 Tok, *
this, diag::err_feature_check_malformed);
2077 }
else if (II == Ident__is_target_variant_os) {
2079 OS,
Tok, II, *
this,
false,
2080 [
this](Token &
Tok,
bool &HasLexedNextToken) ->
int {
2082 Tok, *
this, diag::err_feature_check_malformed);
2085 }
else if (II == Ident__is_target_variant_environment) {
2087 OS,
Tok, II, *
this,
false,
2088 [
this](Token &
Tok,
bool &HasLexedNextToken) ->
int {
2090 Tok, *
this, diag::err_feature_check_malformed);
2094 llvm_unreachable(
"Unknown identifier!");
2113 LangOpts.remapPathPrefix(Path);
2114 if (LangOpts.UseTargetPathSeparator) {
2116 llvm::sys::path::remove_dots(Path,
false,
2117 llvm::sys::path::Style::windows_backslash);
2119 llvm::sys::path::remove_dots(Path,
false, llvm::sys::path::Style::posix);
2129 StringRef PLFileName = llvm::sys::path::filename(PLoc.
getFilename());
2130 if (PLFileName.empty())
2132 FileName.append(PLFileName.begin(), PLFileName.end());
Defines enum values for all the target-independent builtin functions.
static bool getDiagnosticsInGroup(diag::Flavor Flavor, const WarningOption *Group, SmallVectorImpl< diag::kind > &Diags, diag::CustomDiagInfo *CustomDiagInfo)
Return true if any diagnostics were found in this group, even if they were filtered out due to having...
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Result
Implement __builtin_bit_cast and related operations.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::LangOptions interface.
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
llvm::MachO::FileType FileType
Defines the clang::MacroInfo and clang::MacroDirective classes.
static bool HasExtension(const Preprocessor &PP, StringRef Extension)
HasExtension - Return true if we recognize and implement the feature specified by the identifier,...
static bool CheckMatchedBrackets(const SmallVectorImpl< Token > &Tokens)
CheckMatchedBrackets - Returns true if the braces and parentheses in the token vector are properly ne...
static bool EvaluateHasIncludeCommon(Token &Tok, IdentifierInfo *II, Preprocessor &PP, ConstSearchDirIterator LookupFrom, const FileEntry *LookupFromFile)
EvaluateHasIncludeCommon - Process a '__has_include("path")' or '__has_include_next("path")' expressi...
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...
static bool isTargetVariantOS(const TargetInfo &TI, const IdentifierInfo *II)
Implements the __is_target_variant_os 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,...
static bool isTargetArch(const TargetInfo &TI, const IdentifierInfo *II)
Implements the __is_target_arch builtin macro.
static bool isTargetVariantEnvironment(const TargetInfo &TI, const IdentifierInfo *II)
Implements the __is_target_variant_environment builtin macro.
static bool isTargetEnvironment(const TargetInfo &TI, const IdentifierInfo *II)
Implements the __is_target_environment builtin macro.
static bool IsBuiltinTrait(Token &Tok)
static bool isTargetOS(const TargetInfo &TI, const IdentifierInfo *II)
Implements the __is_target_os builtin macro.
static bool isTargetVendor(const TargetInfo &TI, const IdentifierInfo *II)
Implements the __is_target_vendor builtin macro.
static void ComputeDATE_TIME(SourceLocation &DATELoc, size_t &DATETokLen, SourceLocation &TIMELoc, size_t &TIMETokLen, Preprocessor &PP)
ComputeDATE_TIME - Compute the current time, enter it into the specified scratch buffer,...
static void EvaluateFeatureLikeBuiltinMacro(llvm::raw_svector_ostream &OS, Token &Tok, IdentifierInfo *II, Preprocessor &PP, bool ExpandArgs, llvm::function_ref< int(Token &Tok, bool &HasLexedNextTok)> Op)
Process single-argument builtin feature-like macros that return integer values.
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...
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...
Defines the PreprocessorLexer interface.
Defines the clang::Preprocessor interface.
Defines the clang::SourceLocation class and associated facilities.
Syntax
The style used to specify an attribute.
@ AS_Declspec
__declspec(...)
bool isConstantEvaluated(unsigned ID) const
Return true if this function can be constant evaluated by Clang frontend.
diag::Severity getExtensionHandlingBehavior() const
const IntrusiveRefCntPtr< DiagnosticIDs > & getDiagnosticIDs() const
virtual void updateOutOfDateIdentifier(const IdentifierInfo &II)=0
Update an out-of-date identifier.
Cached information about one file (either on disk or in the virtual file system).
time_t getModificationTime() 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.
One of these records is kept for each identifier that is lexed.
unsigned getBuiltinID() const
Return a value indicating whether this is a builtin function.
tok::TokenKind getTokenID() const
If this is a source-language token (e.g.
bool hadMacroDefinition() const
Returns true if this identifier was #defined to some value at any moment.
bool isFromAST() const
Return true if the identifier in its current state was loaded from an AST file.
const char * getNameStart() const
Return the beginning of the actual null-terminated string for this identifier.
void setHasMacroDefinition(bool Val)
bool isOutOfDate() const
Determine whether the information for this identifier is out of date with respect to the external sou...
void setChangedSinceDeserialization()
Note that this identifier has changed since it was loaded from an AST file.
StringRef getName() const
Return the actual identifier string.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
bool isCompilingModule() const
Are we compiling a module?
std::string CurrentModule
The name of the current module, of which the main source file is a part.
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) ...
MacroArgs - An instance of this class captures information about the formal arguments specified to a ...
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.
void destroy(Preprocessor &PP)
destroy - Destroy and deallocate the memory for this object.
A description of the current definition of a macro.
MacroInfo * getMacroInfo() const
Get the MacroInfo that should be used for this definition.
bool isAmbiguous() const
true if the definition is ambiguous, false otherwise.
void forAllDefinitions(Fn F) const
Encapsulates changes to the "macros namespace" (the location where the macro name became active,...
const MacroDirective * getPrevious() const
Get previous definition of the macro with the same name.
void setPrevious(MacroDirective *Prev)
Set previous definition of the macro with the same name.
Encapsulates the data about a macro definition (e.g.
bool isIdenticalTo(const MacroInfo &Other, Preprocessor &PP, bool Syntactically) const
Return true if the specified macro definition is equal to this macro in spelling, arguments,...
bool isUsed() const
Return false if this macro is defined in the main file and has not yet been used.
bool isFunctionLike() const
ArrayRef< const IdentifierInfo * > params() const
unsigned getNumTokens() const
Return the number of tokens that this macro expands to.
unsigned getNumParams() const
const Token & getReplacementToken(unsigned Tok) const
bool isBuiltinMacro() const
Return true if this macro requires processing before expansion.
SourceLocation getDefinitionLoc() const
Return the location that the macro was defined at.
bool hasCommaPasting() const
bool isObjectLike() const
bool isWarnIfUnused() const
Return true if we should emit a warning if the macro is unused.
bool isEnabled() const
Return true if this macro is enabled.
void setIsUsed(bool Val)
Set the value of the IsUsed flag.
Represents a macro directive exported by a module.
static ModuleMacro * create(Preprocessor &PP, Module *OwningModule, const IdentifierInfo *II, MacroInfo *Macro, ArrayRef< ModuleMacro * > Overrides)
Describes a module or submodule.
This interface provides a way to observe the actions of the preprocessor as it does its thing.
DateTimeInitKind InitDateTimeMacros
Specify initialization kind for DATE, TIME and TIMESTAMP macros.
std::optional< uint64_t > SourceDateEpoch
If set, the UNIX timestamp specified by SOURCE_DATE_EPOCH.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
SourceLocation getLastFPEvalPragmaLocation() const
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...
void dumpMacroInfo(const IdentifierInfo *II)
ModuleMacro * addModuleMacro(Module *Mod, IdentifierInfo *II, MacroInfo *Macro, ArrayRef< ModuleMacro * > Overrides, bool &IsNew)
Register an exported macro for a module and identifier.
void setLoadedMacroDirective(IdentifierInfo *II, MacroDirective *ED, MacroDirective *MD)
Set a MacroDirective that was loaded from a PCH file.
PPCallbacks * getPPCallbacks() const
SourceRange DiscardUntilEndOfDirective(SmallVectorImpl< Token > *DiscardedToks=nullptr)
Read and discard all tokens remaining on the current line until the tok::eod token is found.
const MacroInfo * getMacroInfo(const IdentifierInfo *II) const
DiagnosticBuilder DiagCompat(SourceLocation Loc, unsigned CompatDiagID) const
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 ...
void markMacroAsUsed(MacroInfo *MI)
A macro is used, update information about macros that need unused warnings.
MacroDirective * getLocalMacroDirectiveHistory(const IdentifierInfo *II) const
Given an identifier, return the latest non-imported macro directive for that identifier.
void Lex(Token &Result)
Lex the next token for this preprocessor.
bool isParsingIfOrElifDirective() const
True if we are currently preprocessing a if or elif directive.
void LexNonComment(Token &Result)
Lex a token.
IdentifierInfo * getIdentifierInfo(StringRef Name) const
Return information about the specified preprocessor identifier token.
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...
OptionalFileEntryRef LookupEmbedFile(StringRef Filename, bool isAngled, bool OpenFile)
Given a "Filename" or <Filename> reference, look up the indicated embed resource.
static void processPathToFileName(SmallVectorImpl< char > &FileName, const PresumedLoc &PLoc, const LangOptions &LangOpts, const TargetInfo &TI)
const TargetInfo & getTargetInfo() const
bool LexHeaderName(Token &Result, bool AllowMacroExpansion=true)
Lex a token, forming a header-name token if possible.
void LexUnexpandedToken(Token &Result)
Just like Lex, but disables macro expansion of identifier tokens.
ModuleMacro * getModuleMacro(Module *Mod, const IdentifierInfo *II)
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 ...
bool GetIncludeFilenameSpelling(SourceLocation Loc, StringRef &Buffer)
Turn the specified lexer token into a fully checked and spelled filename, e.g.
PreprocessorLexer * getCurrentFileLexer() const
Return the current file lexer being lexed from.
HeaderSearch & getHeaderSearchInfo() const
void emitMacroExpansionWarnings(const Token &Identifier, bool IsIfnDef=false) const
ExternalPreprocessorSource * getExternalSource() const
OptionalFileEntryRef LookupFile(SourceLocation FilenameLoc, StringRef Filename, bool isAngled, ConstSearchDirIterator FromDir, const FileEntry *FromFile, ConstSearchDirIterator *CurDir, SmallVectorImpl< char > *SearchPath, SmallVectorImpl< char > *RelativePath, ModuleMap::KnownHeader *SuggestedModule, bool *IsMapped, bool *IsFrameworkFound, bool SkipCache=false, bool OpenFile=true, bool CacheFailures=true)
Given a "foo" or <foo> reference, look up the indicated file.
Builtin::Context & getBuiltinInfo()
const PreprocessorOptions & getPreprocessorOpts() const
Retrieve the preprocessor options used to initialize this preprocessor.
LangOptions::FPEvalMethodKind getTUFPEvalMethod() const
const LangOptions & getLangOpts() const
static void processPathForFileMacro(SmallVectorImpl< char > &Path, const LangOptions &LangOpts, const TargetInfo &TI)
DiagnosticsEngine & getDiagnostics() const
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Computes the source location just past the end of the token at this source location.
std::optional< LexEmbedParametersResult > LexEmbedParameters(Token &Current, bool ForHasEmbed)
Lex the parameters for an embed directive, returns nullopt on error.
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...
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const
Forwarding function for diagnostics.
void appendMacroDirective(IdentifierInfo *II, MacroDirective *MD)
Add a directive to the macro directive history for this identifier.
Represents an unpacked "presumed" location which can be presented to the user.
const char * getFilename() const
Return the presumed filename of this location.
unsigned getLine() const
Return the presumed line number of this location.
bool isInvalid() const
Return true if this object is invalid or uninitialized.
SourceLocation getIncludeLoc() const
Return the presumed include location of this location.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
A trivial tuple used to represent a source range.
Exposes information about the current target.
virtual bool supportsCpuSupports() const
virtual bool supportsCpuInit() const
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
const llvm::Triple * getDarwinTargetVariantTriple() const
Returns the darwin target variant triple, the variant of the deployment target for which the code is ...
virtual bool supportsCpuIs() const
TokenLexer - This implements a lexer that returns tokens from a macro body or token stream instead of...
Token - This structure provides full information about a lexed token.
IdentifierInfo * getIdentifierInfo() const
unsigned getFlags() const
Return the internal represtation of the flags.
void clearFlag(TokenFlags Flag)
Unset the specified flag.
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
unsigned getLength() const
void setLength(unsigned Len)
void setKind(tok::TokenKind K)
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)) {....
tok::TokenKind getKind() const
bool isAtStartOfLine() const
isAtStartOfLine - Return true if this token is at the start of a line.
bool isOneOf(Ts... Ks) const
bool hasLeadingSpace() const
Return true if this token has whitespace before it.
void setLocation(SourceLocation L)
bool isNot(tok::TokenKind K) const
bool isAnnotation() const
Return true if this is any of tok::annot_* kind tokens.
bool hasUDSuffix() const
Return true if this token is a string or character literal which has a ud-suffix.
void startToken()
Reset all flags to cleared.
void setIdentifierInfo(IdentifierInfo *II)
void setFlagValue(TokenFlags Flag, bool Val)
Set a flag to either true or false.
void setFlag(TokenFlags Flag)
Set the specified flag.
unsigned getGeneration() const
Get the current visibility generation.
Defines the clang::TargetInfo interface.
bool evaluateRequiredTargetFeatures(llvm::StringRef RequiredFatures, const llvm::StringMap< bool > &TargetFetureMap)
Returns true if the required target features of a builtin function are enabled.
CharacteristicKind
Indicates whether a file or directory holds normal user code, system code, or system code which is im...
uint32_t Literal
Literals are represented as positive integers.
@ WarningOrError
A diagnostic that indicates a problem or potential problem.
@ Error
Present this diagnostic as an error.
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
Top level wrappers for InstallAPI frontend operations.
CustomizableOptional< FileEntryRef > OptionalFileEntryRef
int hasAttribute(AttributeCommonInfo::Syntax Syntax, llvm::StringRef ScopeName, llvm::StringRef AttrName, const TargetInfo &Target, const LangOptions &LangOpts, bool CheckPlugins)
Return the version number associated with the attribute if we recognize and implement the attribute s...
detail::SearchDirIteratorImpl< true > ConstSearchDirIterator
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
@ Default
Set to the current date and time.
@ Undefined
Keep undefined.
@ LiteralOne
Set to literal string "1".
@ Result
The result type of a method or function.
@ Braces
New-expression has a C++11 list-initializer.
__builtin_elementwise_add_sat __builtin_elementwise_sub_sat uint32_t __packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 __packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 uint32_t