33 #include "llvm/ADT/ArrayRef.h" 34 #include "llvm/ADT/DenseMap.h" 35 #include "llvm/ADT/DenseSet.h" 36 #include "llvm/ADT/FoldingSet.h" 37 #include "llvm/ADT/None.h" 38 #include "llvm/ADT/Optional.h" 39 #include "llvm/ADT/SmallString.h" 40 #include "llvm/ADT/SmallVector.h" 41 #include "llvm/ADT/STLExtras.h" 42 #include "llvm/ADT/StringRef.h" 43 #include "llvm/ADT/StringSwitch.h" 44 #include "llvm/Support/Casting.h" 45 #include "llvm/Support/ErrorHandling.h" 46 #include "llvm/Support/Format.h" 47 #include "llvm/Support/raw_ostream.h" 57 using namespace clang;
63 auto Pos = CurSubmoduleState->Macros.find(II);
64 return Pos == CurSubmoduleState->Macros.end() ? nullptr
65 : Pos->second.getLatest();
69 assert(MD &&
"MacroDirective should be non-zero!");
70 assert(!MD->
getPrevious() &&
"Already attached to a MacroDirective history.");
72 MacroState &StoredMD = CurSubmoduleState->Macros[II];
73 auto *OldMD = StoredMD.getLatest();
75 StoredMD.setLatest(MD);
76 StoredMD.overrideActiveModuleMacros(*
this, II);
78 if (needModuleMacros()) {
82 PendingModuleMacroNames.push_back(II);
87 if (!MD->
isDefined() && LeafModuleMacros.find(II) == LeafModuleMacros.end())
106 MacroState &StoredMD = CurSubmoduleState->Macros[II];
108 if (
auto *OldMD = StoredMD.getLatest()) {
114 assert(OldMD->getMacroInfo()->isBuiltinMacro() &&
115 "only built-ins should have an entry here");
116 assert(!OldMD->getPrevious() &&
"builtin should only have a single entry");
118 StoredMD.setLatest(MD);
125 if (!MD->
isDefined() && LeafModuleMacros.find(II) == LeafModuleMacros.end())
133 llvm::FoldingSetNodeID
ID;
137 if (
auto *MM = ModuleMacros.FindNodeOrInsertPos(ID, InsertPos)) {
143 ModuleMacros.InsertNode(MM, InsertPos);
147 for (
auto *O : Overrides) {
148 HidAny |= (O->NumOverriddenBy == 0);
149 ++O->NumOverriddenBy;
153 auto &LeafMacros = LeafModuleMacros[II];
155 LeafMacros.erase(std::remove_if(LeafMacros.begin(), LeafMacros.end(),
157 return MM->NumOverriddenBy != 0;
163 LeafMacros.push_back(MM);
172 llvm::FoldingSetNodeID
ID;
176 return ModuleMacros.FindNodeOrInsertPos(ID, InsertPos);
179 void Preprocessor::updateModuleMacroInfo(
const IdentifierInfo *II,
180 ModuleMacroInfo &Info) {
181 assert(Info.ActiveModuleMacrosGeneration !=
182 CurSubmoduleState->VisibleModules.getGeneration() &&
183 "don't need to update this macro name info");
184 Info.ActiveModuleMacrosGeneration =
185 CurSubmoduleState->VisibleModules.getGeneration();
187 auto Leaf = LeafModuleMacros.find(II);
188 if (Leaf == LeafModuleMacros.end()) {
193 Info.ActiveModuleMacros.clear();
196 llvm::DenseMap<ModuleMacro *, int> NumHiddenOverrides;
197 for (
auto *O : Info.OverriddenMacros)
198 NumHiddenOverrides[O] = -1;
202 for (
auto *LeafMM : Leaf->second) {
203 assert(LeafMM->getNumOverridingMacros() == 0 &&
"leaf macro overridden");
204 if (NumHiddenOverrides.lookup(LeafMM) == 0)
205 Worklist.push_back(LeafMM);
207 while (!Worklist.empty()) {
208 auto *MM = Worklist.pop_back_val();
209 if (CurSubmoduleState->VisibleModules.isVisible(MM->getOwningModule())) {
212 if (MM->getMacroInfo())
213 Info.ActiveModuleMacros.push_back(MM);
215 for (
auto *O : MM->overrides())
216 if ((
unsigned)++NumHiddenOverrides[O] == O->getNumOverridingMacros())
217 Worklist.push_back(O);
221 std::reverse(Info.ActiveModuleMacros.begin(), Info.ActiveModuleMacros.end());
225 bool IsSystemMacro =
true;
226 bool IsAmbiguous =
false;
227 if (
auto *MD = Info.MD) {
228 while (MD && isa<VisibilityMacroDirective>(MD))
229 MD = MD->getPrevious();
230 if (
auto *DMD = dyn_cast_or_null<DefMacroDirective>(MD)) {
235 for (
auto *Active : Info.ActiveModuleMacros) {
236 auto *NewMI = Active->getMacroInfo();
247 if (MI && NewMI != MI &&
248 !MI->isIdenticalTo(*NewMI, *
this,
true))
250 IsSystemMacro &= Active->getOwningModule()->IsSystem ||
254 Info.IsAmbiguous = IsAmbiguous && !IsSystemMacro;
259 auto LeafIt = LeafModuleMacros.find(II);
260 if (LeafIt != LeafModuleMacros.end())
261 Leaf = LeafIt->second;
262 const MacroState *
State =
nullptr;
263 auto Pos = CurSubmoduleState->Macros.find(II);
264 if (Pos != CurSubmoduleState->Macros.end())
265 State = &Pos->second;
269 llvm::errs() <<
" ambiguous";
270 if (
State && !
State->getOverriddenMacros().empty()) {
271 llvm::errs() <<
" overrides";
272 for (
auto *O :
State->getOverriddenMacros())
273 llvm::errs() <<
" " << O->getOwningModule()->getFullModuleName();
275 llvm::errs() <<
"\n";
278 for (
auto *MD =
State ?
State->getLatest() :
nullptr; MD;
279 MD = MD->getPrevious()) {
286 for (
auto *MM :
State ?
State->getActiveModuleMacros(*
this, II) :
None)
290 while (!Worklist.empty()) {
291 auto *MM = Worklist.pop_back_val();
292 llvm::errs() <<
" ModuleMacro " << MM <<
" " 293 << MM->getOwningModule()->getFullModuleName();
294 if (!MM->getMacroInfo())
295 llvm::errs() <<
" undef";
297 if (Active.count(MM))
298 llvm::errs() <<
" active";
299 else if (!CurSubmoduleState->VisibleModules.isVisible(
300 MM->getOwningModule()))
301 llvm::errs() <<
" hidden";
302 else if (MM->getMacroInfo())
303 llvm::errs() <<
" overridden";
305 if (!MM->overrides().empty()) {
306 llvm::errs() <<
" overrides";
307 for (
auto *O : MM->overrides()) {
308 llvm::errs() <<
" " << O->getOwningModule()->getFullModuleName();
309 if (Visited.insert(O).second)
310 Worklist.push_back(O);
313 llvm::errs() <<
"\n";
314 if (
auto *MI = MM->getMacroInfo()) {
317 llvm::errs() <<
"\n";
337 void Preprocessor::RegisterBuiltinMacros() {
346 if (LangOpts.CPlusPlus)
347 Ident__has_cpp_attribute =
350 Ident__has_cpp_attribute =
nullptr;
358 if (LangOpts.MicrosoftExt) {
362 Ident__identifier =
nullptr;
363 Ident__pragma =
nullptr;
380 Ident__is_target_environment =
388 Ident__MODULE__ =
nullptr;
399 if (!II)
return true;
409 if (ExpansionMI->isEnabled() &&
426 bool Preprocessor::isNextPPTokenLParen() {
430 Val = CurLexer->isNextPPTokenLParen();
432 Val = CurTokenLexer->isNextTokenLParen();
440 for (
const IncludeStackInfo &Entry : llvm::reverse(IncludeMacroStack)) {
442 Val = Entry.TheLexer->isNextPPTokenLParen();
444 Val = Entry.TheTokenLexer->isNextTokenLParen();
450 if (Entry.ThePPLexer)
475 Callbacks->MacroExpands(Identifier, M, Identifier.
getLocation(),
477 ExpandBuiltinMacro(Identifier);
496 Args = ReadMacroCallArgumentList(Identifier, MI, ExpansionEnd);
502 if (!Args)
return true;
504 ++NumFnMacroExpanded;
514 SourceRange ExpansionRange(ExpandLoc, ExpansionEnd);
522 DelayedMacroExpandsCallbacks.push_back(
523 MacroExpandsInfo(Identifier, M, ExpansionRange));
525 Callbacks->MacroExpands(Identifier, M, ExpansionRange, Args);
526 if (!DelayedMacroExpandsCallbacks.empty()) {
527 for (
const MacroExpandsInfo &Info : DelayedMacroExpandsCallbacks) {
529 Callbacks->MacroExpands(Info.Tok, Info.MD, Info.Range,
532 DelayedMacroExpandsCallbacks.clear();
539 Diag(Identifier, diag::warn_pp_ambiguous_macro)
556 if (Args) Args->
destroy(*
this);
561 PropagateLineStartLeadingSpaceInfo(Identifier);
562 ++NumFastMacroExpanded;
572 if (Args) Args->
destroy(*
this);
597 if (!NewMI->isEnabled() || NewMI == MI) {
602 Diag(Identifier, diag::pp_disabled_macro_expansion);
608 ++NumFastMacroExpanded;
613 EnterMacro(Identifier, ExpansionEnd, MI, Args);
629 if (I->is(tok::l_paren)) {
630 Brackets.push_back(
Paren);
631 }
else if (I->is(tok::r_paren)) {
632 if (Brackets.empty() || Brackets.back() ==
Brace)
635 }
else if (I->is(tok::l_brace)) {
636 Brackets.push_back(
Brace);
637 }
else if (I->is(tok::r_brace)) {
638 if (Brackets.empty() || Brackets.back() ==
Paren)
643 return Brackets.empty();
677 bool FoundSeparatorToken =
false;
681 if (I->is(tok::l_brace)) {
683 }
else if (I->is(tok::r_brace)) {
685 if (Braces == 0 && ClosingBrace == E && FoundSeparatorToken)
692 FoundSeparatorToken =
true;
693 I->setKind(tok::comma);
701 if (FoundSeparatorToken && ArgStartIterator->is(tok::l_brace)) {
709 if (FoundSeparatorToken) {
711 TempToken.
setKind(tok::l_paren);
712 TempToken.
setLocation(ArgStartIterator->getLocation());
714 NewTokens.push_back(TempToken);
718 NewTokens.insert(NewTokens.end(), ArgStartIterator, I);
721 if (FoundSeparatorToken) {
724 TempToken.
setKind(tok::r_paren);
727 NewTokens.push_back(TempToken);
728 ParenHints.push_back(
SourceRange(ArgStartIterator->getLocation(),
733 NewTokens.push_back(*I);
736 ArgStartIterator = I + 1;
737 FoundSeparatorToken =
false;
742 return !ParenHints.empty() && InitLists.empty();
749 MacroArgs *Preprocessor::ReadMacroCallArgumentList(
Token &MacroName,
762 assert(Tok.
is(tok::l_paren) &&
"Error computing l-paren-ness?");
768 bool ContainsCodeCompletionTok =
false;
769 bool FoundElidedComma =
false;
773 unsigned NumActuals = 0;
774 while (Tok.
isNot(tok::r_paren)) {
778 assert(Tok.
isOneOf(tok::l_paren, tok::comma) &&
779 "only expect argument separators here");
781 size_t ArgTokenStart = ArgTokens.size();
786 unsigned NumParens = 0;
794 if (!ContainsCodeCompletionTok) {
795 Diag(MacroName, diag::err_unterm_macro_invoc);
803 auto Toks = llvm::make_unique<Token[]>(1);
805 EnterTokenStream(std::move(Toks), 1,
true);
807 }
else if (Tok.
is(tok::r_paren)) {
809 if (NumParens-- == 0) {
811 if (!ArgTokens.empty() &&
812 ArgTokens.back().commaAfterElided()) {
813 FoundElidedComma =
true;
817 }
else if (Tok.
is(tok::l_paren)) {
819 }
else if (Tok.
is(tok::comma) && NumParens == 0 &&
828 if (!isVariadic)
break;
829 if (NumFixedArgsLeft > 1)
831 }
else if (Tok.
is(tok::comment) && !KeepMacroComments) {
845 }
else if (Tok.
is(tok::code_completion)) {
846 ContainsCodeCompletionTok =
true;
855 ArgTokens.push_back(Tok);
860 if (ArgTokens.empty() && Tok.
getKind() == tok::r_paren)
865 if (!isVariadic && NumFixedArgsLeft == 0 && TooManyArgsLoc.
isInvalid()) {
866 if (ArgTokens.size() != ArgTokenStart)
867 TooManyArgsLoc = ArgTokens[ArgTokenStart].getLocation();
869 TooManyArgsLoc = ArgStartLoc;
874 if (ArgTokens.size() == ArgTokenStart && !LangOpts.C99)
875 Diag(Tok, LangOpts.CPlusPlus11 ?
876 diag::warn_cxx98_compat_empty_fnmacro_arg :
877 diag::ext_empty_fnmacro_arg);
885 ArgTokens.push_back(EOFTok);
887 if (!ContainsCodeCompletionTok && NumFixedArgsLeft != 0)
897 if (!isVariadic && NumActuals > MinArgsExpected &&
898 !ContainsCodeCompletionTok) {
901 Diag(TooManyArgsLoc, diag::err_too_many_args_in_macro_invoc);
911 unsigned FixedNumArgs = 0;
914 ParenHints, InitLists)) {
915 if (!InitLists.empty()) {
918 diag::note_init_list_at_beginning_of_macro_argument);
924 if (FixedNumArgs != MinArgsExpected)
932 ArgTokens.swap(FixedArgTokens);
933 NumActuals = FixedNumArgs;
937 bool isVarargsElided =
false;
939 if (ContainsCodeCompletionTok) {
946 for (; NumActuals < MinArgsExpected; ++NumActuals)
947 ArgTokens.push_back(EOFTok);
950 if (NumActuals < MinArgsExpected) {
952 if (NumActuals == 0 && MinArgsExpected == 1) {
959 }
else if ((FoundElidedComma || MI->
isVariadic()) &&
960 (NumActuals+1 == MinArgsExpected ||
961 (NumActuals == 0 && MinArgsExpected == 2))) {
969 Diag(Tok, diag::ext_missing_varargs_arg);
980 isVarargsElided =
true;
981 }
else if (!ContainsCodeCompletionTok) {
983 Diag(Tok, diag::err_too_few_args_in_macro_invoc);
995 ArgTokens.push_back(Tok);
998 if (NumActuals == 0 && MinArgsExpected == 2)
999 ArgTokens.push_back(Tok);
1001 }
else if (NumActuals > MinArgsExpected && !MI->
isVariadic() &&
1002 !ContainsCodeCompletionTok) {
1005 Diag(MacroName, diag::err_too_many_args_in_macro_invoc);
1025 size_t newIndex = MacroExpandedTokens.size();
1026 bool cacheNeedsToGrow = tokens.size() >
1027 MacroExpandedTokens.capacity()-MacroExpandedTokens.size();
1028 MacroExpandedTokens.append(tokens.begin(), tokens.end());
1030 if (cacheNeedsToGrow) {
1033 for (
const auto &
Lexer : MacroExpandingLexersStack) {
1036 std::tie(prevLexer, tokIndex) =
Lexer;
1037 prevLexer->Tokens = MacroExpandedTokens.data() + tokIndex;
1041 MacroExpandingLexersStack.push_back(std::make_pair(tokLexer, newIndex));
1042 return MacroExpandedTokens.data() + newIndex;
1045 void Preprocessor::removeCachedMacroExpandedTokensOfLastLexer() {
1046 assert(!MacroExpandingLexersStack.empty());
1047 size_t tokIndex = MacroExpandingLexersStack.back().second;
1048 assert(tokIndex < MacroExpandedTokens.size());
1050 MacroExpandedTokens.resize(tokIndex);
1051 MacroExpandingLexersStack.pop_back();
1059 time_t TT = time(
nullptr);
1060 struct tm *TM = localtime(&TT);
1062 static const char *
const Months[] = {
1063 "Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec" 1068 llvm::raw_svector_ostream TmpStream(TmpBuffer);
1069 TmpStream << llvm::format(
"\"%s %2d %4d\"", Months[TM->tm_mon],
1070 TM->tm_mday, TM->tm_year + 1900);
1079 llvm::raw_svector_ostream TmpStream(TmpBuffer);
1080 TmpStream << llvm::format(
"\"%02d:%02d:%02d\"",
1081 TM->tm_hour, TM->tm_min, TM->tm_sec);
1095 if (Feature.startswith(
"__") && Feature.endswith(
"__") && Feature.size() >= 4)
1096 Feature = Feature.substr(2, Feature.size() - 4);
1098 #define FEATURE(Name, Predicate) .Case(#Name, Predicate) 1099 return llvm::StringSwitch<bool>(Feature)
1100 #include
"clang/Basic/Features.def" 1121 if (Extension.startswith(
"__") && Extension.endswith(
"__") &&
1122 Extension.size() >= 4)
1123 Extension = Extension.substr(2, Extension.size() - 4);
1127 #define EXTENSION(Name, Predicate) .Case(#Name, Predicate) 1128 return llvm::StringSwitch<bool>(Extension)
1129 #include
"clang/Basic/Features.def" 1147 PP.
Diag(LParenLoc, diag::err_pp_directive_required) << II;
1149 assert(Tok.
is(tok::identifier));
1158 if (Tok.
isNot(tok::l_paren)) {
1161 PP.
Diag(LParenLoc, diag::err_pp_expected_after) << II << tok::l_paren;
1164 if (!Tok.
is(tok::angle_string_literal) && !Tok.
is(tok::string_literal) &&
1191 case tok::angle_string_literal:
1192 case tok::string_literal: {
1193 bool Invalid =
false;
1194 Filename = PP.
getSpelling(Tok, FilenameBuffer, &Invalid);
1203 FilenameBuffer.push_back(
'<');
1209 Filename = FilenameBuffer;
1222 if (Tok.
isNot(tok::r_paren)) {
1224 << II << tok::r_paren;
1225 PP.
Diag(LParenLoc, diag::note_matching) << tok::l_paren;
1232 if (Filename.empty())
1238 PP.
LookupFile(FilenameLoc, Filename, isAngled, LookupFrom, LookupFromFile,
1239 CurDir,
nullptr,
nullptr,
nullptr,
nullptr);
1245 Callbacks->HasInclude(FilenameLoc, Filename, isAngled, File, FileType);
1249 return File !=
nullptr;
1269 const FileEntry *LookupFromFile =
nullptr;
1276 PP.
Diag(Tok, diag::pp_include_next_in_primary);
1283 }
else if (!Lookup) {
1284 PP.
Diag(Tok, diag::pp_include_next_absolute_path);
1300 bool &HasLexedNextTok)> Op) {
1303 if (Tok.
isNot(tok::l_paren)) {
1310 Tok.
setKind(tok::numeric_constant);
1315 unsigned ParenDepth = 1;
1320 bool SuppressDiagnostic =
false;
1335 if (!SuppressDiagnostic) {
1337 SuppressDiagnostic =
true;
1343 if (Result.hasValue())
1345 if (!SuppressDiagnostic) {
1347 SuppressDiagnostic =
true;
1352 if (--ParenDepth > 0)
1357 if (Result.hasValue())
1358 OS << Result.getValue();
1361 if (!SuppressDiagnostic)
1364 Tok.
setKind(tok::numeric_constant);
1369 if (Result.hasValue())
1372 bool HasLexedNextToken =
false;
1373 Result = Op(Tok, HasLexedNextToken);
1375 if (HasLexedNextToken)
1382 if (!SuppressDiagnostic) {
1390 PP.
Diag(LParenLoc, diag::note_matching) << tok::l_paren;
1391 SuppressDiagnostic =
true;
1411 std::string ArchName = II->
getName().lower() +
"--";
1412 llvm::Triple Arch(ArchName);
1413 const llvm::Triple &TT = TI.
getTriple();
1416 if ((Arch.getSubArch() == llvm::Triple::NoSubArch ||
1417 Arch.getSubArch() == TT.getSubArch()) &&
1418 ((TT.getArch() == llvm::Triple::thumb &&
1419 Arch.getArch() == llvm::Triple::arm) ||
1420 (TT.getArch() == llvm::Triple::thumbeb &&
1421 Arch.getArch() == llvm::Triple::armeb)))
1426 return (Arch.getSubArch() == llvm::Triple::NoSubArch ||
1427 Arch.getSubArch() == TT.getSubArch()) &&
1428 Arch.getArch() == TT.getArch();
1433 StringRef VendorName = TI.
getTriple().getVendorName();
1434 if (VendorName.empty())
1435 VendorName =
"unknown";
1436 return VendorName.equals_lower(II->
getName());
1441 std::string OSName =
1442 (llvm::Twine(
"unknown-unknown-") + II->
getName().lower()).
str();
1443 llvm::Triple OS(OSName);
1444 if (OS.getOS() == llvm::Triple::Darwin) {
1448 return TI.
getTriple().getOS() == OS.getOS();
1454 std::string EnvName = (llvm::Twine(
"---") + II->
getName().lower()).
str();
1455 llvm::Triple Env(EnvName);
1456 return TI.
getTriple().getEnvironment() == Env.getEnvironment();
1461 void Preprocessor::ExpandBuiltinMacro(
Token &Tok) {
1464 assert(II &&
"Can't be a macro without id info!");
1468 if (II == Ident_Pragma)
1469 return Handle_Pragma(Tok);
1470 else if (II == Ident__pragma)
1471 return HandleMicrosoft__pragma(Tok);
1473 ++NumBuiltinMacroExpanded;
1476 llvm::raw_svector_ostream OS(TmpBuffer);
1482 if (II == Ident__LINE__) {
1502 Tok.
setKind(tok::numeric_constant);
1503 }
else if (II == Ident__FILE__ || II == Ident__BASE_FILE__) {
1510 if (II == Ident__BASE_FILE__ && PLoc.
isValid()) {
1526 OS <<
'"' << FN <<
'"';
1528 Tok.
setKind(tok::string_literal);
1529 }
else if (II == Ident__DATE__) {
1533 Tok.
setKind(tok::string_literal);
1534 Tok.
setLength(strlen(
"\"Mmm dd yyyy\""));
1539 }
else if (II == Ident__TIME__) {
1543 Tok.
setKind(tok::string_literal);
1549 }
else if (II == Ident__INCLUDE_LEVEL__) {
1563 Tok.
setKind(tok::numeric_constant);
1564 }
else if (II == Ident__TIMESTAMP__) {
1579 time_t TT = CurFile->getModificationTime();
1580 struct tm *TM = localtime(&TT);
1581 Result = asctime(TM);
1583 Result =
"??? ??? ?? ??:??:?? ????\n";
1586 OS <<
'"' << StringRef(Result).drop_back() <<
'"';
1587 Tok.
setKind(tok::string_literal);
1588 }
else if (II == Ident__COUNTER__) {
1590 OS << CounterValue++;
1591 Tok.
setKind(tok::numeric_constant);
1592 }
else if (II == Ident__has_feature) {
1594 [
this](
Token &Tok,
bool &HasLexedNextToken) ->
int {
1596 diag::err_feature_check_malformed);
1599 }
else if (II == Ident__has_extension) {
1601 [
this](
Token &Tok,
bool &HasLexedNextToken) ->
int {
1603 diag::err_feature_check_malformed);
1606 }
else if (II == Ident__has_builtin) {
1608 [
this](
Token &Tok,
bool &HasLexedNextToken) ->
int {
1610 diag::err_feature_check_malformed);
1616 case Builtin::BI__builtin_operator_new:
1617 case Builtin::BI__builtin_operator_delete:
1626 return llvm::StringSwitch<bool>(II->
getName())
1627 .Case(
"__make_integer_seq", LangOpts.CPlusPlus)
1628 .Case(
"__type_pack_element", LangOpts.CPlusPlus)
1629 .Case(
"__builtin_available",
true)
1630 .Case(
"__is_target_arch",
true)
1631 .Case(
"__is_target_vendor",
true)
1632 .Case(
"__is_target_os",
true)
1633 .Case(
"__is_target_environment",
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
bool ConcatenateIncludeName(SmallString< 128 > &FilenameBuffer, SourceLocation &End)
Handle cases where the #include name is expanded from a macro as multiple tokens, which need to be gl...
void setChangedSinceDeserialization()
Note that this identifier has changed since it was loaded from an AST file.
void markMacroAsUsed(MacroInfo *MI)
A macro is used, update information about macros that need unused warnings.
IdentifierInfo * getIdentifierInfo(StringRef Name) const
Return information about the specified preprocessor identifier token.
void setFlagValue(TokenFlags Flag, bool Val)
Set a flag to either true or false.
Defines the clang::FileManager interface and associated types.
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
ModuleMacro * addModuleMacro(Module *Mod, IdentifierInfo *II, MacroInfo *Macro, ArrayRef< ModuleMacro *> Overrides, bool &IsNew)
Register an exported macro for a module and identifier.
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {...
void dumpMacroInfo(const IdentifierInfo *II)
bool isEnabled() const
Return true if this macro is enabled.
Is the identifier known as a __declspec-style attribute?
bool isInPrimaryFile() const
Return true if we're in the top-level file, not in a #include.
static bool EvaluateHasIncludeCommon(Token &Tok, IdentifierInfo *II, Preprocessor &PP, const DirectoryLookup *LookupFrom, const FileEntry *LookupFromFile)
EvaluateHasIncludeCommon - Process a '__has_include("path")' or '__has_include_next("path")' expressi...
Defines the clang::MacroInfo and clang::MacroDirective classes.
Is the identifier known as a GNU-style attribute?
Defines types useful for describing an Objective-C runtime.
A description of the current definition of a macro.
static bool GenerateNewArgTokens(Preprocessor &PP, SmallVectorImpl< Token > &OldTokens, SmallVectorImpl< Token > &NewTokens, unsigned &NumArgs, SmallVectorImpl< SourceRange > &ParenHints, SmallVectorImpl< SourceRange > &InitLists)
GenerateNewArgTokens - Returns true if OldTokens can be converted to a new vector of tokens in NewTok...
bool isOutOfDate() const
Determine whether the information for this identifier is out of date with respect to the external sou...
static bool isTargetEnvironment(const TargetInfo &TI, const IdentifierInfo *II)
Implements the __is_target_environment builtin macro.
void setFlag(TokenFlags Flag)
Set the specified flag.
bool isCompilingModule() const
Are we compiling a module interface (.cppm or module map)?
bool isFromAST() const
Return true if the identifier in its current state was loaded from an AST file.
diag::Severity getExtensionHandlingBehavior() const
const FileEntry * LookupFile(SourceLocation FilenameLoc, StringRef Filename, bool isAngled, const DirectoryLookup *FromDir, const FileEntry *FromFile, const DirectoryLookup *&CurDir, SmallVectorImpl< char > *SearchPath, SmallVectorImpl< char > *RelativePath, ModuleMap::KnownHeader *SuggestedModule, bool *IsMapped, bool SkipCache=false)
Given a "foo" or <foo> reference, look up the indicated file.
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.
void Lex(Token &Result)
Lex the next token for this preprocessor.
const char * getNameStart() const
Return the beginning of the actual null-terminated string for this identifier.
void setLoadedMacroDirective(IdentifierInfo *II, MacroDirective *ED, MacroDirective *MD)
Set a MacroDirective that was loaded from a PCH file.
bool isAtStartOfLine() const
isAtStartOfLine - Return true if this token is at the start of a line.
PreprocessorLexer * getCurrentLexer() const
Return the current lexer being lexed from.
StringRef getName() const
Return the actual identifier string.
bool isNot(tok::TokenKind K) const
bool hadMacroDefinition() const
Returns true if this identifier was #defined to some value at any moment.
Dataflow Directional Tag Classes.
bool isWarnIfUnused() const
Return true if we should emit a warning if the macro is unused.
bool isValid() const
Return true if this is a valid SourceLocation object.
unsigned getNumTokens() const
Return the number of tokens that this macro expands to.
bool isFunctionLike() const
const FileEntry * getFileEntry() const
getFileEntry - Return the FileEntry corresponding to this FileID.
bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.
bool IsHeaderFile
Indicates whether the front-end is explicitly told that the input is a header file (i...
unsigned getLength() const
Encapsulates the data about a macro definition (e.g.
static ModuleMacro * create(Preprocessor &PP, Module *OwningModule, IdentifierInfo *II, MacroInfo *Macro, ArrayRef< ModuleMacro *> Overrides)
bool 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.
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.
void LexIncludeFilename(Token &FilenameTok)
After the preprocessor has parsed a #include, lex and (potentially) macro expand the filename...
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.