32 #include "llvm/ADT/ArrayRef.h" 33 #include "llvm/ADT/DenseMap.h" 34 #include "llvm/ADT/DenseSet.h" 35 #include "llvm/ADT/FoldingSet.h" 36 #include "llvm/ADT/None.h" 37 #include "llvm/ADT/Optional.h" 38 #include "llvm/ADT/SmallString.h" 39 #include "llvm/ADT/SmallVector.h" 40 #include "llvm/ADT/STLExtras.h" 41 #include "llvm/ADT/StringRef.h" 42 #include "llvm/ADT/StringSwitch.h" 43 #include "llvm/Support/Casting.h" 44 #include "llvm/Support/ErrorHandling.h" 45 #include "llvm/Support/Format.h" 46 #include "llvm/Support/Path.h" 47 #include "llvm/Support/raw_ostream.h" 57 using namespace clang;
63 auto Pos = CurSubmoduleState->Macros.find(II);
64 return Pos == CurSubmoduleState->Macros.end() ? nullptr
65 : Pos->second.getLatest();
69 assert(MD &&
"MacroDirective should be non-zero!");
70 assert(!MD->
getPrevious() &&
"Already attached to a MacroDirective history.");
72 MacroState &StoredMD = CurSubmoduleState->Macros[II];
73 auto *OldMD = StoredMD.getLatest();
75 StoredMD.setLatest(MD);
76 StoredMD.overrideActiveModuleMacros(*
this, II);
78 if (needModuleMacros()) {
82 PendingModuleMacroNames.push_back(II);
87 if (!MD->
isDefined() && LeafModuleMacros.find(II) == LeafModuleMacros.end())
106 MacroState &StoredMD = CurSubmoduleState->Macros[II];
108 if (
auto *OldMD = StoredMD.getLatest()) {
114 assert(OldMD->getMacroInfo()->isBuiltinMacro() &&
115 "only built-ins should have an entry here");
116 assert(!OldMD->getPrevious() &&
"builtin should only have a single entry");
118 StoredMD.setLatest(MD);
125 if (!MD->
isDefined() && LeafModuleMacros.find(II) == LeafModuleMacros.end())
133 llvm::FoldingSetNodeID
ID;
137 if (
auto *MM = ModuleMacros.FindNodeOrInsertPos(ID, InsertPos)) {
143 ModuleMacros.InsertNode(MM, InsertPos);
147 for (
auto *O : Overrides) {
148 HidAny |= (O->NumOverriddenBy == 0);
149 ++O->NumOverriddenBy;
153 auto &LeafMacros = LeafModuleMacros[II];
155 LeafMacros.erase(std::remove_if(LeafMacros.begin(), LeafMacros.end(),
157 return MM->NumOverriddenBy != 0;
163 LeafMacros.push_back(MM);
172 llvm::FoldingSetNodeID
ID;
176 return ModuleMacros.FindNodeOrInsertPos(ID, InsertPos);
179 void Preprocessor::updateModuleMacroInfo(
const IdentifierInfo *II,
180 ModuleMacroInfo &Info) {
181 assert(Info.ActiveModuleMacrosGeneration !=
182 CurSubmoduleState->VisibleModules.getGeneration() &&
183 "don't need to update this macro name info");
184 Info.ActiveModuleMacrosGeneration =
185 CurSubmoduleState->VisibleModules.getGeneration();
187 auto Leaf = LeafModuleMacros.find(II);
188 if (Leaf == LeafModuleMacros.end()) {
193 Info.ActiveModuleMacros.clear();
196 llvm::DenseMap<ModuleMacro *, int> NumHiddenOverrides;
197 for (
auto *O : Info.OverriddenMacros)
198 NumHiddenOverrides[O] = -1;
202 for (
auto *LeafMM : Leaf->second) {
203 assert(LeafMM->getNumOverridingMacros() == 0 &&
"leaf macro overridden");
204 if (NumHiddenOverrides.lookup(LeafMM) == 0)
205 Worklist.push_back(LeafMM);
207 while (!Worklist.empty()) {
208 auto *MM = Worklist.pop_back_val();
209 if (CurSubmoduleState->VisibleModules.isVisible(MM->getOwningModule())) {
212 if (MM->getMacroInfo())
213 Info.ActiveModuleMacros.push_back(MM);
215 for (
auto *O : MM->overrides())
216 if ((
unsigned)++NumHiddenOverrides[O] == O->getNumOverridingMacros())
217 Worklist.push_back(O);
221 std::reverse(Info.ActiveModuleMacros.begin(), Info.ActiveModuleMacros.end());
225 bool IsSystemMacro =
true;
226 bool IsAmbiguous =
false;
227 if (
auto *MD = Info.MD) {
228 while (MD && isa<VisibilityMacroDirective>(MD))
229 MD = MD->getPrevious();
230 if (
auto *DMD = dyn_cast_or_null<DefMacroDirective>(MD)) {
235 for (
auto *Active : Info.ActiveModuleMacros) {
236 auto *NewMI = Active->getMacroInfo();
247 if (MI && NewMI != MI &&
248 !MI->isIdenticalTo(*NewMI, *
this,
true))
250 IsSystemMacro &= Active->getOwningModule()->IsSystem ||
254 Info.IsAmbiguous = IsAmbiguous && !IsSystemMacro;
259 auto LeafIt = LeafModuleMacros.find(II);
260 if (LeafIt != LeafModuleMacros.end())
261 Leaf = LeafIt->second;
262 const MacroState *
State =
nullptr;
263 auto Pos = CurSubmoduleState->Macros.find(II);
264 if (Pos != CurSubmoduleState->Macros.end())
265 State = &Pos->second;
269 llvm::errs() <<
" ambiguous";
270 if (
State && !
State->getOverriddenMacros().empty()) {
271 llvm::errs() <<
" overrides";
272 for (
auto *O :
State->getOverriddenMacros())
273 llvm::errs() <<
" " << O->getOwningModule()->getFullModuleName();
275 llvm::errs() <<
"\n";
278 for (
auto *MD =
State ?
State->getLatest() :
nullptr; MD;
279 MD = MD->getPrevious()) {
286 for (
auto *MM :
State ?
State->getActiveModuleMacros(*
this, II) :
None)
290 while (!Worklist.empty()) {
291 auto *MM = Worklist.pop_back_val();
292 llvm::errs() <<
" ModuleMacro " << MM <<
" " 293 << MM->getOwningModule()->getFullModuleName();
294 if (!MM->getMacroInfo())
295 llvm::errs() <<
" undef";
297 if (Active.count(MM))
298 llvm::errs() <<
" active";
299 else if (!CurSubmoduleState->VisibleModules.isVisible(
300 MM->getOwningModule()))
301 llvm::errs() <<
" hidden";
302 else if (MM->getMacroInfo())
303 llvm::errs() <<
" overridden";
305 if (!MM->overrides().empty()) {
306 llvm::errs() <<
" overrides";
307 for (
auto *O : MM->overrides()) {
308 llvm::errs() <<
" " << O->getOwningModule()->getFullModuleName();
309 if (Visited.insert(O).second)
310 Worklist.push_back(O);
313 llvm::errs() <<
"\n";
314 if (
auto *MI = MM->getMacroInfo()) {
317 llvm::errs() <<
"\n";
337 void Preprocessor::RegisterBuiltinMacros() {
346 if (LangOpts.CPlusPlus)
347 Ident__has_cpp_attribute =
350 Ident__has_cpp_attribute =
nullptr;
358 if (LangOpts.MicrosoftExt) {
362 Ident__identifier =
nullptr;
363 Ident__pragma =
nullptr;
381 Ident__is_target_environment =
389 Ident__MODULE__ =
nullptr;
400 if (!II)
return true;
410 if (ExpansionMI->isEnabled() &&
427 bool Preprocessor::isNextPPTokenLParen() {
431 Val = CurLexer->isNextPPTokenLParen();
433 Val = CurTokenLexer->isNextTokenLParen();
441 for (
const IncludeStackInfo &Entry : llvm::reverse(IncludeMacroStack)) {
443 Val = Entry.TheLexer->isNextPPTokenLParen();
445 Val = Entry.TheTokenLexer->isNextTokenLParen();
451 if (Entry.ThePPLexer)
476 Callbacks->MacroExpands(Identifier, M, Identifier.
getLocation(),
478 ExpandBuiltinMacro(Identifier);
499 Args = ReadMacroCallArgumentList(Identifier, MI, ExpansionEnd);
506 if (!Args)
return true;
508 ++NumFnMacroExpanded;
518 SourceRange ExpansionRange(ExpandLoc, ExpansionEnd);
526 DelayedMacroExpandsCallbacks.push_back(
527 MacroExpandsInfo(Identifier, M, ExpansionRange));
529 Callbacks->MacroExpands(Identifier, M, ExpansionRange, Args);
530 if (!DelayedMacroExpandsCallbacks.empty()) {
531 for (
const MacroExpandsInfo &Info : DelayedMacroExpandsCallbacks) {
533 Callbacks->MacroExpands(Info.Tok, Info.MD, Info.Range,
536 DelayedMacroExpandsCallbacks.clear();
543 Diag(Identifier, diag::warn_pp_ambiguous_macro)
560 if (Args) Args->
destroy(*
this);
565 PropagateLineStartLeadingSpaceInfo(Identifier);
566 ++NumFastMacroExpanded;
576 if (Args) Args->
destroy(*
this);
601 if (!NewMI->isEnabled() || NewMI == MI) {
606 Diag(Identifier, diag::pp_disabled_macro_expansion);
612 ++NumFastMacroExpanded;
617 EnterMacro(Identifier, ExpansionEnd, MI, Args);
633 if (I->is(tok::l_paren)) {
634 Brackets.push_back(
Paren);
635 }
else if (I->is(tok::r_paren)) {
636 if (Brackets.empty() || Brackets.back() ==
Brace)
639 }
else if (I->is(tok::l_brace)) {
640 Brackets.push_back(
Brace);
641 }
else if (I->is(tok::r_brace)) {
642 if (Brackets.empty() || Brackets.back() ==
Paren)
647 return Brackets.empty();
681 bool FoundSeparatorToken =
false;
685 if (I->is(tok::l_brace)) {
687 }
else if (I->is(tok::r_brace)) {
689 if (Braces == 0 && ClosingBrace == E && FoundSeparatorToken)
696 FoundSeparatorToken =
true;
697 I->setKind(tok::comma);
705 if (FoundSeparatorToken && ArgStartIterator->is(tok::l_brace)) {
713 if (FoundSeparatorToken) {
715 TempToken.
setKind(tok::l_paren);
716 TempToken.
setLocation(ArgStartIterator->getLocation());
718 NewTokens.push_back(TempToken);
722 NewTokens.insert(NewTokens.end(), ArgStartIterator, I);
725 if (FoundSeparatorToken) {
728 TempToken.
setKind(tok::r_paren);
731 NewTokens.push_back(TempToken);
732 ParenHints.push_back(
SourceRange(ArgStartIterator->getLocation(),
737 NewTokens.push_back(*I);
740 ArgStartIterator = I + 1;
741 FoundSeparatorToken =
false;
746 return !ParenHints.empty() && InitLists.empty();
753 MacroArgs *Preprocessor::ReadMacroCallArgumentList(
Token &MacroName,
766 assert(Tok.
is(tok::l_paren) &&
"Error computing l-paren-ness?");
772 bool ContainsCodeCompletionTok =
false;
773 bool FoundElidedComma =
false;
777 unsigned NumActuals = 0;
778 while (Tok.
isNot(tok::r_paren)) {
782 assert(Tok.
isOneOf(tok::l_paren, tok::comma) &&
783 "only expect argument separators here");
785 size_t ArgTokenStart = ArgTokens.size();
790 unsigned NumParens = 0;
798 if (!ContainsCodeCompletionTok) {
799 Diag(MacroName, diag::err_unterm_macro_invoc);
807 auto Toks = llvm::make_unique<Token[]>(1);
809 EnterTokenStream(std::move(Toks), 1,
true,
false);
811 }
else if (Tok.
is(tok::r_paren)) {
813 if (NumParens-- == 0) {
815 if (!ArgTokens.empty() &&
816 ArgTokens.back().commaAfterElided()) {
817 FoundElidedComma =
true;
821 }
else if (Tok.
is(tok::l_paren)) {
823 }
else if (Tok.
is(tok::comma) && NumParens == 0 &&
832 if (!isVariadic)
break;
833 if (NumFixedArgsLeft > 1)
835 }
else if (Tok.
is(tok::comment) && !KeepMacroComments) {
849 }
else if (Tok.
is(tok::code_completion)) {
850 ContainsCodeCompletionTok =
true;
859 ArgTokens.push_back(Tok);
864 if (ArgTokens.empty() && Tok.
getKind() == tok::r_paren)
869 if (!isVariadic && NumFixedArgsLeft == 0 && TooManyArgsLoc.
isInvalid()) {
870 if (ArgTokens.size() != ArgTokenStart)
871 TooManyArgsLoc = ArgTokens[ArgTokenStart].getLocation();
873 TooManyArgsLoc = ArgStartLoc;
878 if (ArgTokens.size() == ArgTokenStart && !LangOpts.C99)
879 Diag(Tok, LangOpts.CPlusPlus11 ?
880 diag::warn_cxx98_compat_empty_fnmacro_arg :
881 diag::ext_empty_fnmacro_arg);
889 ArgTokens.push_back(EOFTok);
891 if (!ContainsCodeCompletionTok && NumFixedArgsLeft != 0)
901 if (!isVariadic && NumActuals > MinArgsExpected &&
902 !ContainsCodeCompletionTok) {
905 Diag(TooManyArgsLoc, diag::err_too_many_args_in_macro_invoc);
915 unsigned FixedNumArgs = 0;
918 ParenHints, InitLists)) {
919 if (!InitLists.empty()) {
922 diag::note_init_list_at_beginning_of_macro_argument);
928 if (FixedNumArgs != MinArgsExpected)
936 ArgTokens.swap(FixedArgTokens);
937 NumActuals = FixedNumArgs;
941 bool isVarargsElided =
false;
943 if (ContainsCodeCompletionTok) {
950 for (; NumActuals < MinArgsExpected; ++NumActuals)
951 ArgTokens.push_back(EOFTok);
954 if (NumActuals < MinArgsExpected) {
956 if (NumActuals == 0 && MinArgsExpected == 1) {
963 }
else if ((FoundElidedComma || MI->
isVariadic()) &&
964 (NumActuals+1 == MinArgsExpected ||
965 (NumActuals == 0 && MinArgsExpected == 2))) {
973 Diag(Tok, diag::ext_missing_varargs_arg);
984 isVarargsElided =
true;
985 }
else if (!ContainsCodeCompletionTok) {
987 Diag(Tok, diag::err_too_few_args_in_macro_invoc);
999 ArgTokens.push_back(Tok);
1002 if (NumActuals == 0 && MinArgsExpected == 2)
1003 ArgTokens.push_back(Tok);
1005 }
else if (NumActuals > MinArgsExpected && !MI->
isVariadic() &&
1006 !ContainsCodeCompletionTok) {
1009 Diag(MacroName, diag::err_too_many_args_in_macro_invoc);
1029 size_t newIndex = MacroExpandedTokens.size();
1030 bool cacheNeedsToGrow = tokens.size() >
1031 MacroExpandedTokens.capacity()-MacroExpandedTokens.size();
1032 MacroExpandedTokens.append(tokens.begin(), tokens.end());
1034 if (cacheNeedsToGrow) {
1037 for (
const auto &
Lexer : MacroExpandingLexersStack) {
1040 std::tie(prevLexer, tokIndex) =
Lexer;
1041 prevLexer->Tokens = MacroExpandedTokens.data() + tokIndex;
1045 MacroExpandingLexersStack.push_back(std::make_pair(tokLexer, newIndex));
1046 return MacroExpandedTokens.data() + newIndex;
1049 void Preprocessor::removeCachedMacroExpandedTokensOfLastLexer() {
1050 assert(!MacroExpandingLexersStack.empty());
1051 size_t tokIndex = MacroExpandingLexersStack.back().second;
1052 assert(tokIndex < MacroExpandedTokens.size());
1054 MacroExpandedTokens.resize(tokIndex);
1055 MacroExpandingLexersStack.pop_back();
1063 time_t TT = time(
nullptr);
1064 struct tm *TM = localtime(&TT);
1066 static const char *
const Months[] = {
1067 "Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec" 1072 llvm::raw_svector_ostream TmpStream(TmpBuffer);
1073 TmpStream << llvm::format(
"\"%s %2d %4d\"", Months[TM->tm_mon],
1074 TM->tm_mday, TM->tm_year + 1900);
1083 llvm::raw_svector_ostream TmpStream(TmpBuffer);
1084 TmpStream << llvm::format(
"\"%02d:%02d:%02d\"",
1085 TM->tm_hour, TM->tm_min, TM->tm_sec);
1099 if (Feature.startswith(
"__") && Feature.endswith(
"__") && Feature.size() >= 4)
1100 Feature = Feature.substr(2, Feature.size() - 4);
1102 #define FEATURE(Name, Predicate) .Case(#Name, Predicate) 1103 return llvm::StringSwitch<bool>(Feature)
1104 #include
"clang/Basic/Features.def" 1125 if (Extension.startswith(
"__") && Extension.endswith(
"__") &&
1126 Extension.size() >= 4)
1127 Extension = Extension.substr(2, Extension.size() - 4);
1131 #define EXTENSION(Name, Predicate) .Case(#Name, Predicate) 1132 return llvm::StringSwitch<bool>(Extension)
1133 #include
"clang/Basic/Features.def" 1151 PP.
Diag(LParenLoc, diag::err_pp_directive_required) << II;
1153 assert(Tok.
is(tok::identifier));
1162 }
while (Tok.
getKind() == tok::comment);
1165 if (Tok.
isNot(tok::l_paren)) {
1168 PP.
Diag(LParenLoc, diag::err_pp_expected_after) << II << tok::l_paren;
1171 if (Tok.
isNot(tok::header_name))
1180 if (Tok.
isNot(tok::header_name)) {
1187 bool Invalid =
false;
1198 if (Tok.
isNot(tok::r_paren)) {
1200 << II << tok::r_paren;
1201 PP.
Diag(LParenLoc, diag::note_matching) << tok::l_paren;
1208 if (Filename.empty())
1214 PP.
LookupFile(FilenameLoc, Filename, isAngled, LookupFrom, LookupFromFile,
1215 CurDir,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr);
1221 Callbacks->HasInclude(FilenameLoc, Filename, isAngled, File, FileType);
1225 return File !=
nullptr;
1245 const FileEntry *LookupFromFile =
nullptr;
1252 PP.
Diag(Tok, diag::pp_include_next_in_primary);
1259 }
else if (!Lookup) {
1260 PP.
Diag(Tok, diag::pp_include_next_absolute_path);
1276 bool &HasLexedNextTok)> Op) {
1279 if (Tok.
isNot(tok::l_paren)) {
1286 Tok.
setKind(tok::numeric_constant);
1291 unsigned ParenDepth = 1;
1296 bool SuppressDiagnostic =
false;
1311 if (!SuppressDiagnostic) {
1313 SuppressDiagnostic =
true;
1319 if (Result.hasValue())
1321 if (!SuppressDiagnostic) {
1323 SuppressDiagnostic =
true;
1328 if (--ParenDepth > 0)
1333 if (Result.hasValue()) {
1334 OS << Result.getValue();
1337 if (Result.getValue() > 1)
1341 if (!SuppressDiagnostic)
1344 Tok.
setKind(tok::numeric_constant);
1349 if (Result.hasValue())
1352 bool HasLexedNextToken =
false;
1353 Result = Op(Tok, HasLexedNextToken);
1355 if (HasLexedNextToken)
1362 if (!SuppressDiagnostic) {
1370 PP.
Diag(LParenLoc, diag::note_matching) << tok::l_paren;
1371 SuppressDiagnostic =
true;
1391 std::string ArchName = II->
getName().lower() +
"--";
1392 llvm::Triple Arch(ArchName);
1393 const llvm::Triple &TT = TI.
getTriple();
1396 if ((Arch.getSubArch() == llvm::Triple::NoSubArch ||
1397 Arch.getSubArch() == TT.getSubArch()) &&
1398 ((TT.getArch() == llvm::Triple::thumb &&
1399 Arch.getArch() == llvm::Triple::arm) ||
1400 (TT.getArch() == llvm::Triple::thumbeb &&
1401 Arch.getArch() == llvm::Triple::armeb)))
1406 return (Arch.getSubArch() == llvm::Triple::NoSubArch ||
1407 Arch.getSubArch() == TT.getSubArch()) &&
1408 Arch.getArch() == TT.getArch();
1413 StringRef VendorName = TI.
getTriple().getVendorName();
1414 if (VendorName.empty())
1415 VendorName =
"unknown";
1416 return VendorName.equals_lower(II->
getName());
1421 std::string OSName =
1422 (llvm::Twine(
"unknown-unknown-") + II->
getName().lower()).str();
1423 llvm::Triple OS(OSName);
1424 if (OS.getOS() == llvm::Triple::Darwin) {
1428 return TI.
getTriple().getOS() == OS.getOS();
1434 std::string EnvName = (llvm::Twine(
"---") + II->
getName().lower()).str();
1435 llvm::Triple Env(EnvName);
1436 return TI.
getTriple().getEnvironment() == Env.getEnvironment();
1441 void Preprocessor::ExpandBuiltinMacro(
Token &Tok) {
1444 assert(II &&
"Can't be a macro without id info!");
1448 if (II == Ident_Pragma)
1449 return Handle_Pragma(Tok);
1450 else if (II == Ident__pragma)
1451 return HandleMicrosoft__pragma(Tok);
1453 ++NumBuiltinMacroExpanded;
1456 llvm::raw_svector_ostream OS(TmpBuffer);
1464 if (II == Ident__LINE__) {
1484 Tok.
setKind(tok::numeric_constant);
1485 }
else if (II == Ident__FILE__ || II == Ident__BASE_FILE__ ||
1486 II == Ident__FILE_NAME__) {
1493 if (II == Ident__BASE_FILE__ && PLoc.
isValid()) {
1509 if (II == Ident__FILE_NAME__) {
1512 StringRef PLFileName = llvm::sys::path::filename(PLoc.
getFilename());
1513 if (PLFileName !=
"")
1521 OS <<
'"' << FN <<
'"';
1523 Tok.
setKind(tok::string_literal);
1524 }
else if (II == Ident__DATE__) {
1528 Tok.
setKind(tok::string_literal);
1529 Tok.
setLength(strlen(
"\"Mmm dd yyyy\""));
1534 }
else if (II == Ident__TIME__) {
1538 Tok.
setKind(tok::string_literal);
1544 }
else if (II == Ident__INCLUDE_LEVEL__) {
1558 Tok.
setKind(tok::numeric_constant);
1559 }
else if (II == Ident__TIMESTAMP__) {
1574 time_t TT = CurFile->getModificationTime();
1575 struct tm *TM = localtime(&TT);
1576 Result = asctime(TM);
1578 Result =
"??? ??? ?? ??:??:?? ????\n";
1581 OS <<
'"' << StringRef(Result).drop_back() <<
'"';
1582 Tok.
setKind(tok::string_literal);
1583 }
else if (II == Ident__COUNTER__) {
1585 OS << CounterValue++;
1586 Tok.
setKind(tok::numeric_constant);
1587 }
else if (II == Ident__has_feature) {
1589 [
this](
Token &Tok,
bool &HasLexedNextToken) ->
int {
1591 diag::err_feature_check_malformed);
1594 }
else if (II == Ident__has_extension) {
1596 [
this](
Token &Tok,
bool &HasLexedNextToken) ->
int {
1598 diag::err_feature_check_malformed);
1601 }
else if (II == Ident__has_builtin) {
1603 [
this](
Token &Tok,
bool &HasLexedNextToken) ->
int {
1605 diag::err_feature_check_malformed);
1611 case Builtin::BI__builtin_operator_new:
1612 case Builtin::BI__builtin_operator_delete:
1621 return llvm::StringSwitch<bool>(II->
getName())
1622 .Case(
"__make_integer_seq", LangOpts.CPlusPlus)
1623 .Case(
"__type_pack_element", LangOpts.CPlusPlus)
1624 .Case(
"__builtin_available",
true)
1625 .Case(
"__is_target_arch",
true)
1626 .Case(
"__is_target_vendor",
true)
1627 .Case(
"__is_target_os",
true)
1628 .Case(
"__is_target_environment",
true)
1629 .Case(
"__builtin_LINE",
true)
1630 .Case(
"__builtin_FILE",
true)
1631 .Case(
"__builtin_FUNCTION",
true)
1632 .Case(
"__builtin_COLUMN",
true)
1633 .Case(
"__builtin_bit_cast",
true)
1637 }
else if (II == Ident__is_identifier) {
1639 [](
Token &Tok,
bool &HasLexedNextToken) ->
int {
1640 return Tok.
is(tok::identifier);
1642 }
else if (II == Ident__has_attribute) {
1644 [
this](
Token &Tok,
bool &HasLexedNextToken) ->
int {
1646 diag::err_feature_check_malformed);
1650 }
else if (II == Ident__has_declspec) {
1652 [
this](
Token &Tok,
bool &HasLexedNextToken) ->
int {
1654 diag::err_feature_check_malformed);
1658 }
else if (II == Ident__has_cpp_attribute ||
1659 II == Ident__has_c_attribute) {
1660 bool IsCXX = II == Ident__has_cpp_attribute;
1662 OS, Tok, II, *
this, [&](
Token &Tok,
bool &HasLexedNextToken) ->
int {
1665 Tok, *
this, diag::err_feature_check_malformed);
1672 if (Tok.
isNot(tok::coloncolon))
1673 HasLexedNextToken =
true;
1678 diag::err_feature_check_malformed);
1686 }
else if (II == Ident__has_include ||
1687 II == Ident__has_include_next) {
1692 if (II == Ident__has_include)
1697 if (Tok.
isNot(tok::r_paren))
1700 Tok.
setKind(tok::numeric_constant);
1701 }
else if (II == Ident__has_warning) {
1704 [
this](
Token &Tok,
bool &HasLexedNextToken) ->
int {
1705 std::string WarningName;
1708 HasLexedNextToken = Tok.
is(tok::string_literal);
1715 if (WarningName.size() < 3 || WarningName[0] !=
'-' ||
1716 WarningName[1] !=
'W') {
1717 Diag(StrStartLoc, diag::warn_has_warning_invalid_option);
1728 WarningName.substr(2), Diags);
1730 }
else if (II == Ident__building_module) {
1735 [
this](
Token &Tok,
bool &HasLexedNextToken) ->
int {
1737 diag::err_expected_id_building_module);
1741 }
else if (II == Ident__MODULE__) {
1747 }
else if (II == Ident__identifier) {
1753 if (Tok.
isNot(tok::l_paren)) {
1756 << II << tok::l_paren;
1779 if (RParen.
isNot(tok::r_paren)) {
1781 << Tok.
getKind() << tok::r_paren;
1782 Diag(LParenLoc, diag::note_matching) << tok::l_paren;
1785 }
else if (II == Ident__is_target_arch) {
1787 OS, Tok, II, *
this, [
this](
Token &Tok,
bool &HasLexedNextToken) ->
int {
1789 Tok, *
this, diag::err_feature_check_malformed);
1792 }
else if (II == Ident__is_target_vendor) {
1794 OS, Tok, II, *
this, [
this](
Token &Tok,
bool &HasLexedNextToken) ->
int {
1796 Tok, *
this, diag::err_feature_check_malformed);
1799 }
else if (II == Ident__is_target_os) {
1801 OS, Tok, II, *
this, [
this](
Token &Tok,
bool &HasLexedNextToken) ->
int {
1803 Tok, *
this, diag::err_feature_check_malformed);
1806 }
else if (II == Ident__is_target_environment) {
1808 OS, Tok, II, *
this, [
this](
Token &Tok,
bool &HasLexedNextToken) ->
int {
1810 Tok, *
this, diag::err_feature_check_malformed);
1814 llvm_unreachable(
"Unknown identifier!");
A diagnostic that indicates a problem or potential problem.
static IdentifierInfo * RegisterBuiltinMacro(Preprocessor &PP, const char *Name)
RegisterBuiltinMacro - Register the specified identifier in the identifier table and mark it as a bui...
static bool CheckMatchedBrackets(const SmallVectorImpl< Token > &Tokens)
CheckMatchedBrackets - Returns true if the braces and parentheses in the token vector are properly ne...
Lexer - This provides a simple interface that turns a text buffer into a stream of tokens...
MacroInfo * AllocateMacroInfo(SourceLocation L)
Allocate a new MacroInfo object with the provided SourceLocation.
param_iterator param_begin() const
void setChangedSinceDeserialization()
Note that this identifier has changed since it was loaded from an AST file.
void markMacroAsUsed(MacroInfo *MI)
A macro is used, update information about macros that need unused warnings.
IdentifierInfo * getIdentifierInfo(StringRef Name) const
Return information about the specified preprocessor identifier token.
void setFlagValue(TokenFlags Flag, bool Val)
Set a flag to either true or false.
Defines the clang::FileManager interface and associated types.
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
ModuleMacro * addModuleMacro(Module *Mod, IdentifierInfo *II, MacroInfo *Macro, ArrayRef< ModuleMacro *> Overrides, bool &IsNew)
Register an exported macro for a module and identifier.
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {...
void dumpMacroInfo(const IdentifierInfo *II)
bool isEnabled() const
Return true if this macro is enabled.
Is the identifier known as a __declspec-style attribute?
bool isInPrimaryFile() const
Return true if we're in the top-level file, not in a #include.
static bool EvaluateHasIncludeCommon(Token &Tok, IdentifierInfo *II, Preprocessor &PP, const DirectoryLookup *LookupFrom, const FileEntry *LookupFromFile)
EvaluateHasIncludeCommon - Process a '__has_include("path")' or '__has_include_next("path")' expressi...
Defines the clang::MacroInfo and clang::MacroDirective classes.
Is the identifier known as a GNU-style attribute?
Defines types useful for describing an Objective-C runtime.
A description of the current definition of a macro.
static bool GenerateNewArgTokens(Preprocessor &PP, SmallVectorImpl< Token > &OldTokens, SmallVectorImpl< Token > &NewTokens, unsigned &NumArgs, SmallVectorImpl< SourceRange > &ParenHints, SmallVectorImpl< SourceRange > &InitLists)
GenerateNewArgTokens - Returns true if OldTokens can be converted to a new vector of tokens in NewTok...
bool isOutOfDate() const
Determine whether the information for this identifier is out of date with respect to the external sou...
static bool isTargetEnvironment(const TargetInfo &TI, const IdentifierInfo *II)
Implements the __is_target_environment builtin macro.
void setFlag(TokenFlags Flag)
Set the specified flag.
bool isCompilingModule() const
Are we compiling a module interface (.cppm or module map)?
bool isFromAST() const
Return true if the identifier in its current state was loaded from an AST file.
diag::Severity getExtensionHandlingBehavior() const
CharacteristicKind
Indicates whether a file or directory holds normal user code, system code, or system code which is im...
This interface provides a way to observe the actions of the preprocessor as it does its thing...
bool isAnnotation() const
Return true if this is any of tok::annot_* kind tokens.
const MacroDirective * getPrevious() const
Get previous definition of the macro with the same name.
tok::TokenKind getKind() const
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Computes the source location just past the end of the token at this source location.
DefMacroDirective * appendDefMacroDirective(IdentifierInfo *II, MacroInfo *MI, SourceLocation Loc)
One of these records is kept for each identifier that is lexed.
Represents a macro directive exported by a module.
static bool HasFeature(const Preprocessor &PP, StringRef Feature)
HasFeature - Return true if we recognize and implement the feature specified by the identifier as a s...
void setHasMacroDefinition(bool Val)
static bool isTargetOS(const TargetInfo &TI, const IdentifierInfo *II)
Implements the __is_target_os builtin macro.
static bool getDiagnosticsInGroup(diag::Flavor Flavor, const WarningOption *Group, SmallVectorImpl< diag::kind > &Diags)
Return true if any diagnostics were found in this group, even if they were filtered out due to having...
bool hasCommaPasting() const
const TargetInfo & getTargetInfo() const
Token - This structure provides full information about a lexed token.
void setKind(tok::TokenKind K)
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
const LangOptions & getLangOpts() const
Describes a module or submodule.
static void ComputeDATE_TIME(SourceLocation &DATELoc, SourceLocation &TIMELoc, Preprocessor &PP)
ComputeDATE_TIME - Compute the current time, enter it into the specified scratch buffer, then return DATELoc/TIMELoc locations with the position of the identifier tokens inserted.
param_iterator param_end() const
SourceLocation AdvanceToTokenCharacter(SourceLocation TokStart, unsigned Char) const
Given a location that specifies the start of a token, return a new location that specifies a characte...
Module * getCurrentLexerSubmodule() const
Return the submodule owning the file being lexed.
static IdentifierInfo * ExpectFeatureIdentifierInfo(Token &Tok, Preprocessor &PP, signed DiagID)
Helper function to return the IdentifierInfo structure of a Token or generate a diagnostic if none av...
StringRef getSpelling(SourceLocation loc, SmallVectorImpl< char > &buffer, bool *invalid=nullptr) const
Return the 'spelling' of the token at the given location; does not go up to the spelling location or ...
HeaderSearch & getHeaderSearchInfo() const
tok::TokenKind getTokenID() const
If this is a source-language token (e.g.
static void EvaluateFeatureLikeBuiltinMacro(llvm::raw_svector_ostream &OS, Token &Tok, IdentifierInfo *II, Preprocessor &PP, llvm::function_ref< int(Token &Tok, bool &HasLexedNextTok)> Op)
Process single-argument builtin feature-like macros that return integer values.
const Token & getReplacementToken(unsigned Tok) const
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
void LexNonComment(Token &Result)
Lex a token.
bool GetIncludeFilenameSpelling(SourceLocation Loc, StringRef &Buffer)
Turn the specified lexer token into a fully checked and spelled filename, e.g.
void ExpandedMacro()
ExpandedMacro - When a macro is expanded with this lexer as the current buffer, this method is called...
static bool EvaluateHasInclude(Token &Tok, IdentifierInfo *II, Preprocessor &PP)
EvaluateHasInclude - Process a '__has_include("path")' expression.
void destroy(Preprocessor &PP)
destroy - Destroy and deallocate the memory for this object.
TokenLexer - This implements a lexer that returns tokens from a macro body or token stream instead of...
Present this diagnostic as an error.
int hasAttribute(AttrSyntax Syntax, const IdentifierInfo *Scope, const IdentifierInfo *Attr, const TargetInfo &Target, const LangOptions &LangOpts)
Return the version number associated with the attribute if we recognize and implement the attribute s...
bool isUsed() const
Return false if this macro is defined in the main file and has not yet been used. ...
void appendMacroDirective(IdentifierInfo *II, MacroDirective *MD)
Add a directive to the macro directive history for this identifier.
void LexUnexpandedToken(Token &Result)
Just like Lex, but disables macro expansion of identifier tokens.
A little helper class used to produce diagnostics.
std::string CurrentModule
The name of the current module, of which the main source file is a part.
unsigned getNumParams() const
Exposes information about the current target.
Defines the clang::LangOptions interface.
bool isInvalid() const
Return true if this object is invalid or uninitialized.
bool isInSystemHeader(SourceLocation Loc) const
Returns if a SourceLocation is in a system header.
static bool isTargetVendor(const TargetInfo &TI, const IdentifierInfo *II)
Implements the __is_target_vendor builtin macro.
const FileEntry * getFileEntryForID(FileID FID) const
Returns the FileEntry record for the provided FileID.
MacroArgs - An instance of this class captures information about the formal arguments specified to a ...
unsigned getLine() const
Return the presumed line number of this location.
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file. ...
Defines the clang::Preprocessor interface.
MultipleIncludeOpt MIOpt
A state machine that detects the #ifndef-wrapping a file idiom for the multiple-include optimization...
const MacroInfo * getMacroInfo(const IdentifierInfo *II) const
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Represents an unpacked "presumed" location which can be presented to the user.
PPCallbacks * getPPCallbacks() const
bool isObjectLike() const
The result type of a method or function.
static bool HasExtension(const Preprocessor &PP, StringRef Extension)
HasExtension - Return true if we recognize and implement the feature specified by the identifier...
DirectoryLookup - This class represents one entry in the search list that specifies the search order ...
const DirectoryLookup * GetCurDirLookup()
Get the DirectoryLookup structure used to find the current FileEntry, if CurLexer is non-null and if ...
unsigned getBuiltinID() const
Return a value indicating whether this is a builtin function.
void setIsUsed(bool Val)
Set the value of the IsUsed flag.
const char * getFilename() const
Return the presumed filename of this location.
ExternalPreprocessorSource * getExternalSource() const
Encapsulates changes to the "macros namespace" (the location where the macro name became active...
Encodes a location in the source.
static bool isTargetArch(const TargetInfo &TI, const IdentifierInfo *II)
Implements the __is_target_arch builtin macro.
static bool isTrivialSingleTokenExpansion(const MacroInfo *MI, const IdentifierInfo *MacroIdent, Preprocessor &PP)
isTrivialSingleTokenExpansion - Return true if MI, which has a single token in its expansion...
void setLength(unsigned Len)
SourceLocation createExpansionLoc(SourceLocation Loc, SourceLocation ExpansionLocStart, SourceLocation ExpansionLocEnd, unsigned TokLength, bool ExpansionIsTokenRange=true, int LoadedID=0, unsigned LoadedOffset=0)
Return a new SourceLocation that encodes the fact that a token from SpellingLoc should actually be re...
MacroDirective * getLocalMacroDirectiveHistory(const IdentifierInfo *II) const
Given an identifier, return the latest non-imported macro directive for that identifier.
static bool EvaluateHasIncludeNext(Token &Tok, IdentifierInfo *II, Preprocessor &PP)
EvaluateHasIncludeNext - Process '__has_include_next("path")' expression.
IdentifierInfo * getIdentifierInfo() const
Cached information about one file (either on disk or in the virtual file system). ...
void setIdentifierInfo(IdentifierInfo *II)
void setIsBuiltinMacro(bool Val=true)
Set or clear the isBuiltinMacro flag.
const char * getNameStart() const
Return the beginning of the actual null-terminated string for this identifier.
void setLoadedMacroDirective(IdentifierInfo *II, MacroDirective *ED, MacroDirective *MD)
Set a MacroDirective that was loaded from a PCH file.
bool isAtStartOfLine() const
isAtStartOfLine - Return true if this token is at the start of a line.
PreprocessorLexer * getCurrentLexer() const
Return the current lexer being lexed from.
const FileEntry * LookupFile(SourceLocation FilenameLoc, StringRef Filename, bool isAngled, const DirectoryLookup *FromDir, const FileEntry *FromFile, const DirectoryLookup *&CurDir, SmallVectorImpl< char > *SearchPath, SmallVectorImpl< char > *RelativePath, ModuleMap::KnownHeader *SuggestedModule, bool *IsMapped, bool *IsFrameworkFound, bool SkipCache=false)
Given a "foo" or <foo> reference, look up the indicated file.
StringRef getName() const
Return the actual identifier string.
bool isNot(tok::TokenKind K) const
bool hadMacroDefinition() const
Returns true if this identifier was #defined to some value at any moment.
Dataflow Directional Tag Classes.
bool isWarnIfUnused() const
Return true if we should emit a warning if the macro is unused.
bool isValid() const
Return true if this is a valid SourceLocation object.
unsigned getNumTokens() const
Return the number of tokens that this macro expands to.
bool isFunctionLike() const
const FileEntry * getFileEntry() const
getFileEntry - Return the FileEntry corresponding to this FileID.
bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.
bool IsHeaderFile
Indicates whether the front-end is explicitly told that the input is a header file (i...
unsigned getLength() const
Encapsulates the data about a macro definition (e.g.
static ModuleMacro * create(Preprocessor &PP, Module *OwningModule, IdentifierInfo *II, MacroInfo *Macro, ArrayRef< ModuleMacro *> Overrides)
bool FinishLexStringLiteral(Token &Result, std::string &String, const char *DiagnosticTag, bool AllowMacroExpansion)
Complete the lexing of a string literal where the first token has already been lexed (see LexStringLi...
virtual void updateOutOfDateIdentifier(IdentifierInfo &II)=0
Update an out-of-date identifier.
void CreateString(StringRef Str, Token &Tok, SourceLocation ExpansionLocStart=SourceLocation(), SourceLocation ExpansionLocEnd=SourceLocation())
Plop the specified string into a scratch buffer and set the specified token's location and length to ...
SourceLocation getEnd() const
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
SourceLocation getDefinitionLoc() const
Return the location that the macro was defined at.
CharSourceRange getExpansionRange(SourceLocation Loc) const
Given a SourceLocation object, return the range of tokens covered by the expansion in the ultimate fi...
const IntrusiveRefCntPtr< DiagnosticIDs > & getDiagnosticIDs() const
Defines the clang::SourceLocation class and associated facilities.
ModuleMacro * getModuleMacro(Module *Mod, IdentifierInfo *II)
DiagnosticsEngine & getDiagnostics() const
bool isAmbiguous() const
true if the definition is ambiguous, false otherwise.
static MacroArgs * create(const MacroInfo *MI, ArrayRef< Token > UnexpArgTokens, bool VarargsElided, Preprocessor &PP)
MacroArgs ctor function - Create a new MacroArgs object with the specified macro and argument info...
bool isBuiltinMacro() const
Return true if this macro requires processing before expansion.
Defines the clang::TargetInfo interface.
void setPrevious(MacroDirective *Prev)
Set previous definition of the macro with the same name.
void forAllDefinitions(Fn F) const
MacroInfo * getMacroInfo() const
Get the MacroInfo that should be used for this definition.
void EnterMacro(Token &Tok, SourceLocation ILEnd, MacroInfo *Macro, MacroArgs *Args)
Add a Macro to the top of the include stack and start lexing tokens from it instead of the current bu...
void setLocation(SourceLocation L)
bool isParsingIfOrElifDirective() const
True if we are currently preprocessing a if or #elif directive.
A trivial tuple used to represent a source range.
bool LexHeaderName(Token &Result, bool AllowMacroExpansion=true)
Lex a token, forming a header-name token if possible.
PreprocessorLexer * getCurrentFileLexer() const
Return the current file lexer being lexed from.
unsigned getFlags() const
Return the internal represtation of the flags.
void clearFlag(TokenFlags Flag)
Unset the specified flag.
SourceLocation getIncludeLoc() const
Return the presumed include location of this location.
Defines the PreprocessorLexer interface.
virtual void CodeCompleteMacroArgument(IdentifierInfo *Macro, MacroInfo *MacroInfo, unsigned ArgumentIndex)
Callback invoked when performing code completion inside a function-like macro argument.
void Profile(llvm::FoldingSetNodeID &ID) const
bool hasLeadingSpace() const
Return true if this token has whitespace before it.
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const
Forwarding function for diagnostics.
void startToken()
Reset all flags to cleared.
static std::string Stringify(StringRef Str, bool Charify=false)
Stringify - Convert the specified string into a C string by i) escaping '\' and " characters and ii) ...
Engages in a tight little dance with the lexer to efficiently preprocess tokens.