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))
142 if (SourceMgr.isWrittenInCommandLineFile(MDLoc)) {
143 auto MDFileID = SourceMgr.getFileID(MDLoc);
144 if (PCHPredefinesFileID.isInvalid())
145 PCHPredefinesFileID = MDFileID;
152 assert(MDFileID == PCHPredefinesFileID &&
153 "PCHBuiltinFileID must be consistent!");
163 llvm::FoldingSetNodeID ID;
167 if (
auto *MM = ModuleMacros.FindNodeOrInsertPos(ID, InsertPos)) {
173 ModuleMacros.InsertNode(MM, InsertPos);
177 for (
auto *O : Overrides) {
178 HidAny |= (O->NumOverriddenBy == 0);
179 ++O->NumOverriddenBy;
183 auto &LeafMacros = LeafModuleMacros[II];
185 llvm::erase_if(LeafMacros,
186 [](
ModuleMacro *MM) {
return MM->NumOverriddenBy != 0; });
190 LeafMacros.push_back(MM);
200 llvm::FoldingSetNodeID ID;
204 return ModuleMacros.FindNodeOrInsertPos(ID, InsertPos);
208 ModuleMacroInfo &Info) {
209 assert(Info.ActiveModuleMacrosGeneration !=
211 "don't need to update this macro name info");
212 Info.ActiveModuleMacrosGeneration =
215 auto Leaf = LeafModuleMacros.find(II);
216 if (Leaf == LeafModuleMacros.end()) {
221 Info.ActiveModuleMacros.clear();
224 llvm::DenseMap<ModuleMacro *, int> NumHiddenOverrides;
225 for (
auto *O : Info.OverriddenMacros)
226 NumHiddenOverrides[O] = -1;
230 for (
auto *LeafMM : Leaf->second) {
231 assert(LeafMM->getNumOverridingMacros() == 0 &&
"leaf macro overridden");
232 if (NumHiddenOverrides.lookup(LeafMM) == 0)
233 Worklist.push_back(LeafMM);
235 while (!Worklist.empty()) {
236 auto *MM = Worklist.pop_back_val();
237 if (CurSubmoduleState->VisibleModules.isVisible(MM->getOwningModule())) {
240 if (MM->getMacroInfo())
241 Info.ActiveModuleMacros.push_back(MM);
243 for (
auto *O : MM->overrides())
244 if ((
unsigned)++NumHiddenOverrides[O] == O->getNumOverridingMacros())
245 Worklist.push_back(O);
249 std::reverse(Info.ActiveModuleMacros.begin(), Info.ActiveModuleMacros.end());
252 MacroInfo *MI =
nullptr;
253 bool IsSystemMacro =
true;
254 bool IsAmbiguous =
false;
255 if (
auto *MD = Info.MD) {
256 while (isa_and_nonnull<VisibilityMacroDirective>(MD))
257 MD = MD->getPrevious();
258 if (
auto *DMD = dyn_cast_or_null<DefMacroDirective>(MD)) {
260 IsSystemMacro &= SourceMgr.isInSystemHeader(DMD->getLocation());
263 for (
auto *Active : Info.ActiveModuleMacros) {
264 auto *NewMI = Active->getMacroInfo();
275 if (MI && NewMI != MI &&
278 IsSystemMacro &= Active->getOwningModule()->IsSystem ||
279 SourceMgr.isInSystemHeader(NewMI->getDefinitionLoc());
282 Info.IsAmbiguous = IsAmbiguous && !IsSystemMacro;
287 auto LeafIt = LeafModuleMacros.find(II);
288 if (LeafIt != LeafModuleMacros.end())
289 Leaf = LeafIt->second;
290 const MacroState *State =
nullptr;
291 auto Pos = CurSubmoduleState->Macros.find(II);
292 if (Pos != CurSubmoduleState->Macros.end())
293 State = &Pos->second;
295 llvm::errs() <<
"MacroState " << State <<
" " << II->
getNameStart();
296 if (State && State->isAmbiguous(*
this, II))
297 llvm::errs() <<
" ambiguous";
298 if (State && !State->getOverriddenMacros().empty()) {
299 llvm::errs() <<
" overrides";
300 for (
auto *O : State->getOverriddenMacros())
301 llvm::errs() <<
" " << O->getOwningModule()->getFullModuleName();
303 llvm::errs() <<
"\n";
306 for (
auto *MD = State ? State->getLatest() :
nullptr; MD;
307 MD = MD->getPrevious()) {
313 llvm::DenseSet<ModuleMacro*> Active;
314 for (
auto *MM : State ? State->getActiveModuleMacros(*
this, II)
317 llvm::DenseSet<ModuleMacro*> Visited;
319 while (!Worklist.empty()) {
320 auto *MM = Worklist.pop_back_val();
321 llvm::errs() <<
" ModuleMacro " << MM <<
" "
322 << MM->getOwningModule()->getFullModuleName();
323 if (!MM->getMacroInfo())
324 llvm::errs() <<
" undef";
326 if (Active.count(MM))
327 llvm::errs() <<
" active";
328 else if (!CurSubmoduleState->VisibleModules.isVisible(
329 MM->getOwningModule()))
330 llvm::errs() <<
" hidden";
331 else if (MM->getMacroInfo())
332 llvm::errs() <<
" overridden";
334 if (!MM->overrides().empty()) {
335 llvm::errs() <<
" overrides";
336 for (
auto *O : MM->overrides()) {
337 llvm::errs() <<
" " << O->getOwningModule()->getFullModuleName();
338 if (Visited.insert(O).second)
339 Worklist.push_back(O);
342 llvm::errs() <<
"\n";
343 if (
auto *MI = MM->getMacroInfo()) {
346 llvm::errs() <<
"\n";
353void Preprocessor::RegisterBuiltinMacros() {
354 Ident__LINE__ = RegisterBuiltinMacro(
"__LINE__");
355 Ident__FILE__ = RegisterBuiltinMacro(
"__FILE__");
356 Ident__DATE__ = RegisterBuiltinMacro(
"__DATE__");
357 Ident__TIME__ = RegisterBuiltinMacro(
"__TIME__");
358 Ident__COUNTER__ = RegisterBuiltinMacro(
"__COUNTER__");
359 Ident_Pragma = RegisterBuiltinMacro(
"_Pragma");
360 Ident__FLT_EVAL_METHOD__ = RegisterBuiltinMacro(
"__FLT_EVAL_METHOD__");
364 Ident__has_cpp_attribute = RegisterBuiltinMacro(
"__has_cpp_attribute");
366 Ident__has_cpp_attribute =
nullptr;
369 Ident__BASE_FILE__ = RegisterBuiltinMacro(
"__BASE_FILE__");
370 Ident__INCLUDE_LEVEL__ = RegisterBuiltinMacro(
"__INCLUDE_LEVEL__");
371 Ident__TIMESTAMP__ = RegisterBuiltinMacro(
"__TIMESTAMP__");
375 Ident__identifier = RegisterBuiltinMacro(
"__identifier");
376 Ident__pragma = RegisterBuiltinMacro(
"__pragma");
378 Ident__identifier =
nullptr;
379 Ident__pragma =
nullptr;
383 Ident__FILE_NAME__ = RegisterBuiltinMacro(
"__FILE_NAME__");
384 Ident__has_feature = RegisterBuiltinMacro(
"__has_feature");
385 Ident__has_extension = RegisterBuiltinMacro(
"__has_extension");
386 Ident__has_builtin = RegisterBuiltinMacro(
"__has_builtin");
387 Ident__has_constexpr_builtin =
388 RegisterBuiltinMacro(
"__has_constexpr_builtin");
389 Ident__has_attribute = RegisterBuiltinMacro(
"__has_attribute");
391 Ident__has_c_attribute = RegisterBuiltinMacro(
"__has_c_attribute");
393 Ident__has_c_attribute =
nullptr;
395 Ident__has_declspec = RegisterBuiltinMacro(
"__has_declspec_attribute");
396 Ident__has_embed = RegisterBuiltinMacro(
"__has_embed");
397 Ident__has_include = RegisterBuiltinMacro(
"__has_include");
398 Ident__has_include_next = RegisterBuiltinMacro(
"__has_include_next");
399 Ident__has_warning = RegisterBuiltinMacro(
"__has_warning");
400 Ident__is_identifier = RegisterBuiltinMacro(
"__is_identifier");
401 Ident__is_target_arch = RegisterBuiltinMacro(
"__is_target_arch");
402 Ident__is_target_vendor = RegisterBuiltinMacro(
"__is_target_vendor");
403 Ident__is_target_os = RegisterBuiltinMacro(
"__is_target_os");
404 Ident__is_target_environment =
405 RegisterBuiltinMacro(
"__is_target_environment");
406 Ident__is_target_variant_os = RegisterBuiltinMacro(
"__is_target_variant_os");
407 Ident__is_target_variant_environment =
408 RegisterBuiltinMacro(
"__is_target_variant_environment");
411 Ident__building_module = RegisterBuiltinMacro(
"__building_module");
413 Ident__MODULE__ = RegisterBuiltinMacro(
"__MODULE__");
415 Ident__MODULE__ =
nullptr;
426 if (!II)
return true;
436 if (ExpansionMI->isEnabled() &&
447 return !llvm::is_contained(MI->
params(), II);
452bool Preprocessor::HandleMacroExpandedIdentifier(
Token &Identifier,
461 if (CurPPLexer) CurPPLexer->MIOpt.ExpandedMacro();
466 Callbacks->MacroExpands(Identifier, M, Identifier.
getLocation(),
468 ExpandBuiltinMacro(Identifier);
479 SourceLocation ExpansionEnd = Identifier.
getLocation();
487 ArgMacro = &Identifier;
489 Args = ReadMacroCallArgumentList(Identifier, MI, ExpansionEnd);
496 if (!Args)
return true;
498 ++NumFnMacroExpanded;
507 SourceLocation ExpandLoc = Identifier.
getLocation();
508 SourceRange ExpansionRange(ExpandLoc, ExpansionEnd);
516 DelayedMacroExpandsCallbacks.push_back(
517 MacroExpandsInfo(Identifier, M, ExpansionRange));
519 Callbacks->MacroExpands(Identifier, M, ExpansionRange, Args);
520 if (!DelayedMacroExpandsCallbacks.empty()) {
521 for (
const MacroExpandsInfo &Info : DelayedMacroExpandsCallbacks) {
523 Callbacks->MacroExpands(Info.Tok, Info.MD, Info.Range,
526 DelayedMacroExpandsCallbacks.clear();
533 Diag(Identifier, diag::warn_pp_ambiguous_macro)
550 if (Args) Args->
destroy(*
this);
555 PropagateLineStartLeadingSpaceInfo(Identifier);
556 ++NumFastMacroExpanded;
566 if (Args) Args->
destroy(*
this);
583 SourceMgr.createExpansionLoc(Identifier.
getLocation(), ExpandLoc,
591 if (!NewMI->isEnabled() || NewMI == MI) {
596 Diag(Identifier, diag::pp_disabled_macro_expansion);
602 ++NumFastMacroExpanded;
607 EnterMacro(Identifier, ExpansionEnd, MI, Args);
623 if (I->is(tok::l_paren)) {
624 Brackets.push_back(
Paren);
625 }
else if (I->is(tok::r_paren)) {
626 if (Brackets.empty() || Brackets.back() ==
Brace)
629 }
else if (I->is(tok::l_brace)) {
630 Brackets.push_back(
Brace);
631 }
else if (I->is(tok::r_brace)) {
632 if (Brackets.empty() || Brackets.back() ==
Paren)
637 return Brackets.empty();
671 bool FoundSeparatorToken =
false;
675 if (I->is(tok::l_brace)) {
677 }
else if (I->is(tok::r_brace)) {
679 if (
Braces == 0 && ClosingBrace == E && FoundSeparatorToken)
681 }
else if (I->is(tok::eof)) {
686 FoundSeparatorToken =
true;
687 I->setKind(tok::comma);
695 if (FoundSeparatorToken && ArgStartIterator->is(tok::l_brace)) {
703 if (FoundSeparatorToken) {
705 TempToken.
setKind(tok::l_paren);
706 TempToken.
setLocation(ArgStartIterator->getLocation());
708 NewTokens.push_back(TempToken);
712 NewTokens.insert(NewTokens.end(), ArgStartIterator, I);
715 if (FoundSeparatorToken) {
718 TempToken.
setKind(tok::r_paren);
721 NewTokens.push_back(TempToken);
722 ParenHints.push_back(
SourceRange(ArgStartIterator->getLocation(),
727 NewTokens.push_back(*I);
730 ArgStartIterator = I + 1;
731 FoundSeparatorToken =
false;
736 return !ParenHints.empty() && InitLists.empty();
743MacroArgs *Preprocessor::ReadMacroCallArgumentList(
Token &MacroName,
756 assert(
Tok.
is(tok::l_paren) &&
"Error computing l-paren-ness?");
761 SmallVector<Token, 64> ArgTokens;
762 bool ContainsCodeCompletionTok =
false;
763 bool FoundElidedComma =
false;
765 SourceLocation TooManyArgsLoc;
767 unsigned NumActuals = 0;
769 if (ContainsCodeCompletionTok &&
Tok.
isOneOf(tok::eof, tok::eod))
772 assert(
Tok.
isOneOf(tok::l_paren, tok::comma) &&
773 "only expect argument separators here");
775 size_t ArgTokenStart = ArgTokens.size();
780 unsigned NumParens = 0;
788 if (!ContainsCodeCompletionTok) {
789 Diag(MacroName, diag::err_unterm_macro_invoc);
797 auto Toks = std::make_unique<Token[]>(1);
799 EnterTokenStream(std::move(Toks), 1,
true,
false);
801 }
else if (
Tok.
is(tok::r_paren)) {
803 if (NumParens-- == 0) {
805 if (!ArgTokens.empty() &&
806 ArgTokens.back().commaAfterElided()) {
807 FoundElidedComma =
true;
811 }
else if (
Tok.
is(tok::l_paren)) {
813 }
else if (
Tok.
is(tok::comma)) {
824 }
else if (NumParens == 0) {
830 if (NumFixedArgsLeft > 1)
833 }
else if (
Tok.
is(tok::comment) && !KeepMacroComments) {
847 }
else if (
Tok.
is(tok::code_completion)) {
848 ContainsCodeCompletionTok =
true;
857 ArgTokens.push_back(
Tok);
862 if (ArgTokens.empty() &&
Tok.
getKind() == tok::r_paren)
867 if (!isVariadic && NumFixedArgsLeft == 0 && TooManyArgsLoc.
isInvalid()) {
868 if (ArgTokens.size() != ArgTokenStart)
869 TooManyArgsLoc = ArgTokens[ArgTokenStart].getLocation();
871 TooManyArgsLoc = ArgStartLoc;
878 ? diag::warn_cxx98_compat_empty_fnmacro_arg
879 : diag::ext_empty_fnmacro_arg);
887 ArgTokens.push_back(EOFTok);
889 if (!ContainsCodeCompletionTok && NumFixedArgsLeft != 0)
899 if (!isVariadic && NumActuals > MinArgsExpected &&
900 !ContainsCodeCompletionTok) {
903 Diag(TooManyArgsLoc, diag::err_too_many_args_in_macro_invoc);
912 SmallVector<Token, 4> FixedArgTokens;
913 unsigned FixedNumArgs = 0;
914 SmallVector<SourceRange, 4> ParenHints, InitLists;
916 ParenHints, InitLists)) {
917 if (!InitLists.empty()) {
918 DiagnosticBuilder DB =
920 diag::note_init_list_at_beginning_of_macro_argument);
921 for (SourceRange Range : InitLists)
926 if (FixedNumArgs != MinArgsExpected)
929 DiagnosticBuilder DB =
Diag(MacroName, diag::note_suggest_parens_for_macro);
930 for (SourceRange ParenLocation : ParenHints) {
934 ArgTokens.swap(FixedArgTokens);
935 NumActuals = FixedNumArgs;
939 bool isVarargsElided =
false;
941 if (ContainsCodeCompletionTok) {
948 for (; NumActuals < MinArgsExpected; ++NumActuals)
949 ArgTokens.push_back(EOFTok);
952 if (NumActuals < MinArgsExpected) {
954 if (NumActuals == 0 && MinArgsExpected == 1) {
961 }
else if ((FoundElidedComma || MI->
isVariadic()) &&
962 (NumActuals+1 == MinArgsExpected ||
963 (NumActuals == 0 && MinArgsExpected == 2))) {
977 ID = diag::warn_cxx17_compat_missing_varargs_arg;
979 ID = diag::ext_cxx_missing_varargs_arg;
981 ID = diag::warn_c17_compat_missing_varargs_arg;
983 ID = diag::ext_c_missing_varargs_arg;
995 isVarargsElided =
true;
996 }
else if (!ContainsCodeCompletionTok) {
998 Diag(
Tok, diag::err_too_few_args_in_macro_invoc);
1010 ArgTokens.push_back(
Tok);
1013 if (NumActuals == 0 && MinArgsExpected == 2)
1014 ArgTokens.push_back(
Tok);
1016 }
else if (NumActuals > MinArgsExpected && !MI->
isVariadic() &&
1017 !ContainsCodeCompletionTok) {
1020 Diag(MacroName, diag::err_too_many_args_in_macro_invoc);
1040 size_t newIndex = MacroExpandedTokens.size();
1041 bool cacheNeedsToGrow = tokens.size() >
1042 MacroExpandedTokens.capacity()-MacroExpandedTokens.size();
1043 MacroExpandedTokens.append(tokens.begin(), tokens.end());
1045 if (cacheNeedsToGrow) {
1048 for (
const auto &Lexer : MacroExpandingLexersStack) {
1049 TokenLexer *prevLexer;
1051 std::tie(prevLexer, tokIndex) = Lexer;
1052 prevLexer->Tokens = MacroExpandedTokens.data() + tokIndex;
1056 MacroExpandingLexersStack.push_back(std::make_pair(tokLexer, newIndex));
1057 return MacroExpandedTokens.data() + newIndex;
1060void Preprocessor::removeCachedMacroExpandedTokensOfLastLexer() {
1061 assert(!MacroExpandingLexersStack.empty());
1062 size_t tokIndex = MacroExpandingLexersStack.back().second;
1063 assert(tokIndex < MacroExpandedTokens.size());
1065 MacroExpandedTokens.resize(tokIndex);
1066 MacroExpandingLexersStack.pop_back();
1078 TM = std::gmtime(&TT);
1080 TT = std::time(
nullptr);
1081 TM = std::localtime(&TT);
1084 static const char *
const Months[] = {
1085 "Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec"
1090 llvm::raw_svector_ostream TmpStream(TmpBuffer);
1092 TmpStream << llvm::format(
"\"%s %2d %4d\"", Months[TM->tm_mon],
1093 TM->tm_mday, TM->tm_year + 1900);
1095 TmpStream <<
"??? ?? ????";
1104 llvm::raw_svector_ostream TmpStream(TmpBuffer);
1106 TmpStream << llvm::format(
"\"%02d:%02d:%02d\"", TM->tm_hour, TM->tm_min,
1109 TmpStream <<
"??:??:??";
1127#define FEATURE(Name, Predicate) .Case(#Name, Predicate)
1128 return llvm::StringSwitch<bool>(
Feature)
1129#include "clang/Basic/Features.def"
1150 if (Extension.starts_with(
"__") && Extension.ends_with(
"__") &&
1151 Extension.size() >= 4)
1152 Extension = Extension.substr(2, Extension.size() - 4);
1156#define EXTENSION(Name, Predicate) .Case(#Name, Predicate)
1157 return llvm::StringSwitch<bool>(Extension)
1158#include "clang/Basic/Features.def"
1176 PP.
Diag(LParenLoc, diag::err_pp_directive_required) << II;
1178 assert(
Tok.is(tok::identifier));
1179 Tok.setIdentifierInfo(II);
1187 }
while (
Tok.getKind() == tok::comment);
1190 if (
Tok.isNot(tok::l_paren)) {
1193 PP.
Diag(LParenLoc, diag::err_pp_expected_after) << II << tok::l_paren;
1196 if (
Tok.isNot(tok::header_name))
1200 LParenLoc =
Tok.getLocation();
1205 if (
Tok.isNot(tok::header_name)) {
1206 PP.
Diag(
Tok.getLocation(), diag::err_pp_expects_filename);
1223 if (
Tok.isNot(tok::r_paren)) {
1225 << II << tok::r_paren;
1226 PP.
Diag(LParenLoc, diag::note_matching) << tok::l_paren;
1233 if (Filename.empty())
1243 PP.
LookupFile(FilenameLoc, Filename, isAngled, LookupFrom, LookupFromFile,
1244 nullptr,
nullptr,
nullptr, &KH,
nullptr,
nullptr);
1250 Callbacks->HasInclude(FilenameLoc, Filename, isAngled,
File,
FileType);
1254 return File.has_value();
1262 Diag(
Tok, diag::err_pp_directive_required) << II;
1264 assert(
Tok.
is(tok::identifier));
1272 Diag(
Tok, diag::err_pp_expected_after) << II << tok::l_paren;
1290 Token FilenameTok =
Tok;
1292 std::optional<LexEmbedParametersResult> Params =
1300 << II << tok::r_paren;
1301 Diag(LParenLoc, diag::note_matching) << tok::l_paren;
1307 if (Params->UnrecognizedParams > 0)
1310 SmallString<128> FilenameBuffer;
1311 StringRef Filename = this->
getSpelling(FilenameTok, FilenameBuffer);
1312 if (Filename.empty())
1319 const FileEntry *LookupFromFile =
1321 :
static_cast<FileEntry *
>(
nullptr);
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;
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;
1455 Result = Op(
Tok, HasLexedNextToken);
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/TokenKinds.def"
1614void Preprocessor::ExpandBuiltinMacro(
Token &
Tok) {
1617 assert(II &&
"Can't be a macro without id info!");
1621 if (II == Ident_Pragma)
1622 return Handle_Pragma(
Tok);
1623 else if (II == Ident__pragma)
1624 return HandleMicrosoft__pragma(
Tok);
1626 ++NumBuiltinMacroExpanded;
1628 SmallString<128> TmpBuffer;
1629 llvm::raw_svector_ostream
OS(TmpBuffer);
1637 if (II == Ident__LINE__) {
1652 Loc = SourceMgr.getExpansionRange(Loc).getEnd();
1653 PresumedLoc PLoc = SourceMgr.getPresumedLoc(Loc);
1658 }
else if (II == Ident__FILE__ || II == Ident__BASE_FILE__ ||
1659 II == Ident__FILE_NAME__) {
1666 if (II == Ident__BASE_FILE__ && PLoc.
isValid()) {
1669 PLoc = SourceMgr.getPresumedLoc(NextLoc);
1678 SmallString<256> FN;
1682 if (II == Ident__FILE_NAME__) {
1689 OS <<
'"' << FN <<
'"';
1692 }
else if (II == Ident__DATE__) {
1694 if (!DATELoc.isValid())
1702 }
else if (II == Ident__TIME__) {
1704 if (!TIMELoc.isValid())
1712 }
else if (II == Ident__INCLUDE_LEVEL__) {
1720 for (; PLoc.
isValid(); ++Depth)
1727 }
else if (II == Ident__TIMESTAMP__) {
1732 std::stringstream TmpStream;
1733 TmpStream.imbue(std::locale(
"C"));
1736 std::tm *TM = std::gmtime(&TT);
1737 TmpStream << std::put_time(TM,
"%a %b %e %T %Y");
1741 const FileEntry *CurFile =
nullptr;
1743 CurFile = SourceMgr.getFileEntryForID(TheLexer->getFileID());
1746 struct tm *TM = localtime(&TT);
1747 TmpStream << std::put_time(TM,
"%a %b %e %T %Y");
1750 Result = TmpStream.str();
1752 Result =
"??? ??? ?? ??:??:?? ????";
1755 }
else if (II == Ident__FLT_EVAL_METHOD__) {
1763 Diag(
Tok, diag::err_illegal_use_of_flt_eval_macro);
1766 }
else if (II == Ident__COUNTER__) {
1771 constexpr uint32_t MaxPosValue = std::numeric_limits<int32_t>::max();
1772 if (CounterValue > MaxPosValue) {
1778 CounterValue = MaxPosValue;
1780 OS << CounterValue++;
1782 }
else if (II == Ident__has_feature) {
1784 [
this](Token &
Tok,
bool &HasLexedNextToken) ->
int {
1786 diag::err_feature_check_malformed);
1789 }
else if (II == Ident__has_extension) {
1791 [
this](Token &
Tok,
bool &HasLexedNextToken) ->
int {
1793 diag::err_feature_check_malformed);
1796 }
else if (II == Ident__has_builtin) {
1798 OS,
Tok, II, *
this,
false,
1799 [
this](Token &
Tok,
bool &HasLexedNextToken) ->
int {
1801 Tok, *
this, diag::err_feature_check_malformed);
1805 if (BuiltinID != 0) {
1807 case Builtin::BI__builtin_cpu_is:
1809 case Builtin::BI__builtin_cpu_init:
1811 case Builtin::BI__builtin_cpu_supports:
1813 case Builtin::BI__builtin_operator_new:
1814 case Builtin::BI__builtin_operator_delete:
1829 }
else if (II->
getTokenID() != tok::identifier &&
1830 II->
getName().starts_with(
"__builtin_")) {
1833 return llvm::StringSwitch<bool>(II->
getName())
1835#define BuiltinTemplate(BTName) .Case(#BTName, getLangOpts().CPlusPlus)
1836#include "clang/Basic/BuiltinTemplates.inc"
1840 .Case(
"__is_target_arch",
true)
1841 .Case(
"__is_target_vendor",
true)
1842 .Case(
"__is_target_os",
true)
1843 .Case(
"__is_target_environment",
true)
1844 .Case(
"__is_target_variant_os",
true)
1845 .Case(
"__is_target_variant_environment",
true)
1849 }
else if (II == Ident__has_constexpr_builtin) {
1851 OS,
Tok, II, *
this,
false,
1852 [
this](Token &
Tok,
bool &HasLexedNextToken) ->
int {
1854 Tok, *
this, diag::err_feature_check_malformed);
1858 return BuiltinOp != 0 &&
1861 }
else if (II == Ident__is_identifier) {
1863 [](Token &
Tok,
bool &HasLexedNextToken) ->
int {
1864 return Tok.
is(tok::identifier);
1866 }
else if (II == Ident__has_attribute) {
1868 [
this](Token &
Tok,
bool &HasLexedNextToken) ->
int {
1870 diag::err_feature_check_malformed);
1875 }
else if (II == Ident__has_declspec) {
1877 [
this](Token &
Tok,
bool &HasLexedNextToken) ->
int {
1879 diag::err_feature_check_malformed);
1882 return LangOpts.DeclSpecKeyword &&
1889 }
else if (II == Ident__has_cpp_attribute ||
1890 II == Ident__has_c_attribute) {
1891 bool IsCXX = II == Ident__has_cpp_attribute;
1893 [&](Token &
Tok,
bool &HasLexedNextToken) ->
int {
1894 IdentifierInfo *ScopeII =
nullptr;
1896 Tok, *
this, diag::err_feature_check_malformed);
1904 HasLexedNextToken =
true;
1910 diag::err_feature_check_malformed);
1920 }
else if (II == Ident__has_include ||
1921 II == Ident__has_include_next) {
1926 if (II == Ident__has_include)
1927 Value = EvaluateHasInclude(
Tok, II);
1929 Value = EvaluateHasIncludeNext(
Tok, II);
1935 }
else if (II == Ident__has_embed) {
1945 OS << static_cast<int>(
Value);
1946 }
else if (II == Ident__has_warning) {
1949 [
this](Token &
Tok,
bool &HasLexedNextToken) ->
int {
1950 std::string WarningName;
1953 HasLexedNextToken =
Tok.
is(tok::string_literal);
1960 if (WarningName.size() < 3 || WarningName[0] !=
'-' ||
1961 WarningName[1] !=
'W') {
1962 Diag(StrStartLoc, diag::warn_has_warning_invalid_option);
1970 SmallVector<diag::kind, 10> Diags;
1973 WarningName.substr(2), Diags);
1975 }
else if (II == Ident__building_module) {
1980 [
this](Token &
Tok,
bool &HasLexedNextToken) ->
int {
1982 diag::err_expected_id_building_module);
1986 }
else if (II == Ident__MODULE__) {
1992 }
else if (II == Ident__identifier) {
2001 << II << tok::l_paren;
2032 if (RParen.
isNot(tok::r_paren)) {
2035 Diag(LParenLoc, diag::note_matching) << tok::l_paren;
2038 }
else if (II == Ident__is_target_arch) {
2040 OS,
Tok, II, *
this,
false,
2041 [
this](Token &
Tok,
bool &HasLexedNextToken) ->
int {
2043 Tok, *
this, diag::err_feature_check_malformed);
2046 }
else if (II == Ident__is_target_vendor) {
2048 OS,
Tok, II, *
this,
false,
2049 [
this](Token &
Tok,
bool &HasLexedNextToken) ->
int {
2051 Tok, *
this, diag::err_feature_check_malformed);
2054 }
else if (II == Ident__is_target_os) {
2056 OS,
Tok, II, *
this,
false,
2057 [
this](Token &
Tok,
bool &HasLexedNextToken) ->
int {
2059 Tok, *
this, diag::err_feature_check_malformed);
2062 }
else if (II == Ident__is_target_environment) {
2064 OS,
Tok, II, *
this,
false,
2065 [
this](Token &
Tok,
bool &HasLexedNextToken) ->
int {
2067 Tok, *
this, diag::err_feature_check_malformed);
2070 }
else if (II == Ident__is_target_variant_os) {
2072 OS,
Tok, II, *
this,
false,
2073 [
this](Token &
Tok,
bool &HasLexedNextToken) ->
int {
2075 Tok, *
this, diag::err_feature_check_malformed);
2078 }
else if (II == Ident__is_target_variant_environment) {
2080 OS,
Tok, II, *
this,
false,
2081 [
this](Token &
Tok,
bool &HasLexedNextToken) ->
int {
2083 Tok, *
this, diag::err_feature_check_malformed);
2087 llvm_unreachable(
"Unknown identifier!");
2106 LangOpts.remapPathPrefix(Path);
2107 if (LangOpts.UseTargetPathSeparator) {
2109 llvm::sys::path::remove_dots(Path,
false,
2110 llvm::sys::path::Style::windows_backslash);
2112 llvm::sys::path::remove_dots(Path,
false, llvm::sys::path::Style::posix);
2122 StringRef PLFileName = llvm::sys::path::filename(PLoc.
getFilename());
2123 if (PLFileName.empty())
2125 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.
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 void ComputeDATE_TIME(SourceLocation &DATELoc, SourceLocation &TIMELoc, Preprocessor &PP)
ComputeDATE_TIME - Compute the current time, enter it into the specified scratch buffer,...
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 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.
SourceLocation getLocation() const
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)
void Profile(llvm::FoldingSetNodeID &ID) const
Describes a module or submodule.
This interface provides a way to observe the actions of the preprocessor as it does its thing.
OptionalFileEntryRef getFileEntry() const
getFileEntry - Return the FileEntry corresponding to this FileID.
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.
OptionalFileEntryRef LookupEmbedFile(StringRef Filename, bool isAngled, bool OpenFile, const FileEntry *LookupFromFile=nullptr)
Given a "Filename" or <Filename> reference, look up the indicated embed resource.
PPCallbacks * getPPCallbacks() const
const MacroInfo * getMacroInfo(const IdentifierInfo *II) 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.
SourceRange DiscardUntilEndOfDirective()
Read and discard all tokens remaining on the current line until the tok::eod token is found.
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...
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,...
The JSON file list parser is used to communicate input to InstallAPI.
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',...
@ Result
The result type of a method or function.
@ Braces
New-expression has a C++11 list-initializer.