aboutsummaryrefslogtreecommitdiff
path: root/lib/Lex/PPMacroExpansion.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Lex/PPMacroExpansion.cpp')
-rw-r--r--lib/Lex/PPMacroExpansion.cpp210
1 files changed, 124 insertions, 86 deletions
diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp
index f20633fda8c9..2d7c6d4b5227 100644
--- a/lib/Lex/PPMacroExpansion.cpp
+++ b/lib/Lex/PPMacroExpansion.cpp
@@ -7,19 +7,20 @@
//
//===----------------------------------------------------------------------===//
//
-// This file implements the top level handling of macro expasion for the
+// This file implements the top level handling of macro expansion for the
// preprocessor.
//
//===----------------------------------------------------------------------===//
#include "clang/Lex/Preprocessor.h"
-#include "clang/Lex/MacroArgs.h"
+#include "clang/Basic/Attributes.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Lex/CodeCompletionHandler.h"
#include "clang/Lex/ExternalPreprocessorSource.h"
#include "clang/Lex/LexDiagnostic.h"
+#include "clang/Lex/MacroArgs.h"
#include "clang/Lex/MacroInfo.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
@@ -97,6 +98,15 @@ void Preprocessor::RegisterBuiltinMacros() {
Ident__INCLUDE_LEVEL__ = RegisterBuiltinMacro(*this, "__INCLUDE_LEVEL__");
Ident__TIMESTAMP__ = RegisterBuiltinMacro(*this, "__TIMESTAMP__");
+ // Microsoft Extensions.
+ if (LangOpts.MicrosoftExt) {
+ Ident__identifier = RegisterBuiltinMacro(*this, "__identifier");
+ Ident__pragma = RegisterBuiltinMacro(*this, "__pragma");
+ } else {
+ Ident__identifier = nullptr;
+ Ident__pragma = nullptr;
+ }
+
// Clang Extensions.
Ident__has_feature = RegisterBuiltinMacro(*this, "__has_feature");
Ident__has_extension = RegisterBuiltinMacro(*this, "__has_extension");
@@ -105,6 +115,7 @@ void Preprocessor::RegisterBuiltinMacros() {
Ident__has_include = RegisterBuiltinMacro(*this, "__has_include");
Ident__has_include_next = RegisterBuiltinMacro(*this, "__has_include_next");
Ident__has_warning = RegisterBuiltinMacro(*this, "__has_warning");
+ Ident__is_identifier = RegisterBuiltinMacro(*this, "__is_identifier");
// Modules.
if (LangOpts.Modules) {
@@ -114,17 +125,11 @@ void Preprocessor::RegisterBuiltinMacros() {
if (!LangOpts.CurrentModule.empty())
Ident__MODULE__ = RegisterBuiltinMacro(*this, "__MODULE__");
else
- Ident__MODULE__ = 0;
+ Ident__MODULE__ = nullptr;
} else {
- Ident__building_module = 0;
- Ident__MODULE__ = 0;
+ Ident__building_module = nullptr;
+ Ident__MODULE__ = nullptr;
}
-
- // Microsoft Extensions.
- if (LangOpts.MicrosoftExt)
- Ident__pragma = RegisterBuiltinMacro(*this, "__pragma");
- else
- Ident__pragma = 0;
}
/// isTrivialSingleTokenExpansion - Return true if MI, which has a single token
@@ -135,7 +140,7 @@ static bool isTrivialSingleTokenExpansion(const MacroInfo *MI,
IdentifierInfo *II = MI->getReplacementToken(0).getIdentifierInfo();
// If the token isn't an identifier, it's always literally expanded.
- if (II == 0) return true;
+ if (!II) return true;
// If the information about this identifier is out of date, update it from
// the external source.
@@ -223,7 +228,8 @@ bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier,
// If this is a builtin macro, like __LINE__ or _Pragma, handle it specially.
if (MI->isBuiltinMacro()) {
if (Callbacks) Callbacks->MacroExpands(Identifier, MD,
- Identifier.getLocation(),/*Args=*/0);
+ Identifier.getLocation(),
+ /*Args=*/nullptr);
ExpandBuiltinMacro(Identifier);
return true;
}
@@ -231,7 +237,7 @@ bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier,
/// Args - If this is a function-like macro expansion, this contains,
/// for each macro argument, the list of tokens that were provided to the
/// invocation.
- MacroArgs *Args = 0;
+ MacroArgs *Args = nullptr;
// Remember where the end of the expansion occurred. For an object-like
// macro, this is the identifier. For a function-like macro, this is the ')'.
@@ -249,7 +255,7 @@ bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier,
InMacroArgs = false;
// If there was an error parsing the arguments, bail out.
- if (Args == 0) return true;
+ if (!Args) return true;
++NumFnMacroExpanded;
} else {
@@ -277,7 +283,8 @@ bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier,
for (unsigned i=0, e = DelayedMacroExpandsCallbacks.size(); i!=e; ++i) {
MacroExpandsInfo &Info = DelayedMacroExpandsCallbacks[i];
// FIXME: We lose macro args info with delayed callback.
- Callbacks->MacroExpands(Info.Tok, Info.MD, Info.Range, /*Args=*/0);
+ Callbacks->MacroExpands(Info.Tok, Info.MD, Info.Range,
+ /*Args=*/nullptr);
}
DelayedMacroExpandsCallbacks.clear();
}
@@ -293,11 +300,11 @@ bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier,
for (MacroDirective::DefInfo PrevDef = Def.getPreviousDefinition();
PrevDef && !PrevDef.isUndefined();
PrevDef = PrevDef.getPreviousDefinition()) {
- if (PrevDef.getDirective()->isAmbiguous()) {
- Diag(PrevDef.getMacroInfo()->getDefinitionLoc(),
- diag::note_pp_ambiguous_macro_other)
- << Identifier.getIdentifierInfo();
- }
+ Diag(PrevDef.getMacroInfo()->getDefinitionLoc(),
+ diag::note_pp_ambiguous_macro_other)
+ << Identifier.getIdentifierInfo();
+ if (!PrevDef.getDirective()->isAmbiguous())
+ break;
}
}
@@ -552,7 +559,7 @@ MacroArgs *Preprocessor::ReadFunctionLikeMacroArgs(Token &MacroName,
<< MacroName.getIdentifierInfo();
// Do not lose the EOF/EOD. Return it to the client.
MacroName = Tok;
- return 0;
+ return nullptr;
} else {
// Do not lose the EOF/EOD.
Token *Toks = new Token[1];
@@ -584,7 +591,7 @@ MacroArgs *Preprocessor::ReadFunctionLikeMacroArgs(Token &MacroName,
// If this is a comment token in the argument list and we're just in
// -C mode (not -CC mode), discard the comment.
continue;
- } else if (Tok.getIdentifierInfo() != 0) {
+ } else if (Tok.getIdentifierInfo() != nullptr) {
// Reading macro arguments can cause macros that we are currently
// expanding from to be popped off the expansion stack. Doing so causes
// them to be reenabled for expansion. Here we record whether any
@@ -668,29 +675,18 @@ MacroArgs *Preprocessor::ReadFunctionLikeMacroArgs(Token &MacroName,
DiagnosticBuilder DB =
Diag(MacroName,
diag::note_init_list_at_beginning_of_macro_argument);
- for (SmallVector<SourceRange, 4>::iterator
- Range = InitLists.begin(), RangeEnd = InitLists.end();
- Range != RangeEnd; ++Range) {
- if (DB.hasMaxRanges())
- break;
- DB << *Range;
- }
+ for (const SourceRange &Range : InitLists)
+ DB << Range;
}
- return 0;
+ return nullptr;
}
if (FixedNumArgs != MinArgsExpected)
- return 0;
+ return nullptr;
DiagnosticBuilder DB = Diag(MacroName, diag::note_suggest_parens_for_macro);
- for (SmallVector<SourceRange, 4>::iterator
- ParenLocation = ParenHints.begin(), ParenEnd = ParenHints.end();
- ParenLocation != ParenEnd; ++ParenLocation) {
- if (DB.hasMaxFixItHints())
- break;
- DB << FixItHint::CreateInsertion(ParenLocation->getBegin(), "(");
- if (DB.hasMaxFixItHints())
- break;
- DB << FixItHint::CreateInsertion(ParenLocation->getEnd(), ")");
+ for (const SourceRange &ParenLocation : ParenHints) {
+ DB << FixItHint::CreateInsertion(ParenLocation.getBegin(), "(");
+ DB << FixItHint::CreateInsertion(ParenLocation.getEnd(), ")");
}
ArgTokens.swap(FixedArgTokens);
NumActuals = FixedNumArgs;
@@ -746,7 +742,7 @@ MacroArgs *Preprocessor::ReadFunctionLikeMacroArgs(Token &MacroName,
Diag(Tok, diag::err_too_few_args_in_macro_invoc);
Diag(MI->getDefinitionLoc(), diag::note_macro_here)
<< MacroName.getIdentifierInfo();
- return 0;
+ return nullptr;
}
// Add a marker EOF token to the end of the token list for this argument.
@@ -768,7 +764,7 @@ MacroArgs *Preprocessor::ReadFunctionLikeMacroArgs(Token &MacroName,
Diag(MacroName, diag::err_too_many_args_in_macro_invoc);
Diag(MI->getDefinitionLoc(), diag::note_macro_here)
<< MacroName.getIdentifierInfo();
- return 0;
+ return nullptr;
}
return MacroArgs::create(MI, ArgTokens, isVarargsElided, *this);
@@ -783,7 +779,7 @@ Token *Preprocessor::cacheMacroExpandedTokens(TokenLexer *tokLexer,
ArrayRef<Token> tokens) {
assert(tokLexer);
if (tokens.empty())
- return 0;
+ return nullptr;
size_t newIndex = MacroExpandedTokens.size();
bool cacheNeedsToGrow = tokens.size() >
@@ -796,7 +792,7 @@ Token *Preprocessor::cacheMacroExpandedTokens(TokenLexer *tokLexer,
for (unsigned i = 0, e = MacroExpandingLexersStack.size(); i != e; ++i) {
TokenLexer *prevLexer;
size_t tokIndex;
- llvm::tie(prevLexer, tokIndex) = MacroExpandingLexersStack[i];
+ std::tie(prevLexer, tokIndex) = MacroExpandingLexersStack[i];
prevLexer->Tokens = MacroExpandedTokens.data() + tokIndex;
}
}
@@ -819,7 +815,7 @@ void Preprocessor::removeCachedMacroExpandedTokensOfLastLexer() {
/// the identifier tokens inserted.
static void ComputeDATE_TIME(SourceLocation &DATELoc, SourceLocation &TIMELoc,
Preprocessor &PP) {
- time_t TT = time(0);
+ time_t TT = time(nullptr);
struct tm *TM = localtime(&TT);
static const char * const Months[] = {
@@ -881,7 +877,7 @@ static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) {
.Case("attribute_unused_on_fields", true)
.Case("blocks", LangOpts.Blocks)
.Case("c_thread_safety_attributes", true)
- .Case("cxx_exceptions", LangOpts.Exceptions)
+ .Case("cxx_exceptions", LangOpts.CXXExceptions)
.Case("cxx_rtti", LangOpts.RTTI)
.Case("enumerator_attributes", true)
.Case("memory_sanitizer", LangOpts.Sanitize.Memory)
@@ -913,7 +909,7 @@ static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) {
.Case("c_atomic", LangOpts.C11)
.Case("c_generic_selections", LangOpts.C11)
.Case("c_static_assert", LangOpts.C11)
- .Case("c_thread_local",
+ .Case("c_thread_local",
LangOpts.C11 && PP.getTargetInfo().isTLSSupported())
// C++11 features
.Case("cxx_access_control_sfinae", LangOpts.CPlusPlus11)
@@ -957,12 +953,17 @@ static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) {
.Case("cxx_aggregate_nsdmi", LangOpts.CPlusPlus1y)
.Case("cxx_binary_literals", LangOpts.CPlusPlus1y)
.Case("cxx_contextual_conversions", LangOpts.CPlusPlus1y)
- //.Case("cxx_generic_lambdas", LangOpts.CPlusPlus1y)
+ .Case("cxx_decltype_auto", LangOpts.CPlusPlus1y)
+ .Case("cxx_generic_lambdas", LangOpts.CPlusPlus1y)
.Case("cxx_init_captures", LangOpts.CPlusPlus1y)
.Case("cxx_relaxed_constexpr", LangOpts.CPlusPlus1y)
.Case("cxx_return_type_deduction", LangOpts.CPlusPlus1y)
- //.Case("cxx_runtime_arrays", LangOpts.CPlusPlus1y)
.Case("cxx_variable_templates", LangOpts.CPlusPlus1y)
+ // C++ TSes
+ //.Case("cxx_runtime_arrays", LangOpts.CPlusPlusTSArrays)
+ //.Case("cxx_concepts", LangOpts.CPlusPlusTSConcepts)
+ // FIXME: Should this be __has_feature or __has_extension?
+ //.Case("raw_invocation_type", LangOpts.CPlusPlus)
// Type traits
.Case("has_nothrow_assign", LangOpts.CPlusPlus)
.Case("has_nothrow_copy", LangOpts.CPlusPlus)
@@ -975,6 +976,7 @@ static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) {
.Case("is_abstract", LangOpts.CPlusPlus)
.Case("is_base_of", LangOpts.CPlusPlus)
.Case("is_class", LangOpts.CPlusPlus)
+ .Case("is_constructible", LangOpts.CPlusPlus)
.Case("is_convertible_to", LangOpts.CPlusPlus)
.Case("is_empty", LangOpts.CPlusPlus)
.Case("is_enum", LangOpts.CPlusPlus)
@@ -1004,8 +1006,8 @@ static bool HasExtension(const Preprocessor &PP, const IdentifierInfo *II) {
// If the use of an extension results in an error diagnostic, extensions are
// effectively unavailable, so just return false here.
- if (PP.getDiagnostics().getExtensionHandlingBehavior() ==
- DiagnosticsEngine::Ext_Error)
+ if (PP.getDiagnostics().getExtensionHandlingBehavior() >=
+ diag::Severity::Error)
return false;
const LangOptions &LangOpts = PP.getLangOpts();
@@ -1039,24 +1041,10 @@ static bool HasExtension(const Preprocessor &PP, const IdentifierInfo *II) {
// C++1y features supported by other languages as extensions.
.Case("cxx_binary_literals", true)
.Case("cxx_init_captures", LangOpts.CPlusPlus11)
- .Case("cxx_variable_templates", true)
+ .Case("cxx_variable_templates", LangOpts.CPlusPlus)
.Default(false);
}
-/// HasAttribute - Return true if we recognize and implement the attribute
-/// specified by the given identifier.
-static bool HasAttribute(const IdentifierInfo *II) {
- StringRef Name = II->getName();
- // Normalize the attribute name, __foo__ becomes foo.
- if (Name.startswith("__") && Name.endswith("__") && Name.size() >= 4)
- Name = Name.substr(2, Name.size() - 4);
-
- // FIXME: Do we need to handle namespaces here?
- return llvm::StringSwitch<bool>(Name)
-#include "clang/Lex/AttrSpellings.inc"
- .Default(false);
-}
-
/// EvaluateHasIncludeCommon - Process a '__has_include("path")'
/// or '__has_include_next("path")' expression.
/// Returns true if successful.
@@ -1080,7 +1068,7 @@ static bool EvaluateHasIncludeCommon(Token &Tok,
if (Tok.isNot(tok::l_paren)) {
// No '(', use end of last token.
LParenLoc = PP.getLocForEndOfToken(LParenLoc);
- PP.Diag(LParenLoc, diag::err_pp_missing_lparen) << II->getName();
+ PP.Diag(LParenLoc, diag::err_pp_expected_after) << II << tok::l_paren;
// If the next token looks like a filename or the start of one,
// assume it is and process it as such.
if (!Tok.is(tok::angle_string_literal) && !Tok.is(tok::string_literal) &&
@@ -1142,9 +1130,9 @@ static bool EvaluateHasIncludeCommon(Token &Tok,
// Ensure we have a trailing ).
if (Tok.isNot(tok::r_paren)) {
- PP.Diag(PP.getLocForEndOfToken(FilenameLoc), diag::err_pp_missing_rparen)
- << II->getName();
- PP.Diag(LParenLoc, diag::note_matching) << "(";
+ PP.Diag(PP.getLocForEndOfToken(FilenameLoc), diag::err_pp_expected_after)
+ << II << tok::r_paren;
+ PP.Diag(LParenLoc, diag::note_matching) << tok::l_paren;
return false;
}
@@ -1157,18 +1145,18 @@ static bool EvaluateHasIncludeCommon(Token &Tok,
// Search include directories.
const DirectoryLookup *CurDir;
const FileEntry *File =
- PP.LookupFile(FilenameLoc, Filename, isAngled, LookupFrom, CurDir, NULL,
- NULL, NULL);
+ PP.LookupFile(FilenameLoc, Filename, isAngled, LookupFrom, CurDir,
+ nullptr, nullptr, nullptr);
// Get the result value. A result of true means the file exists.
- return File != 0;
+ return File != nullptr;
}
/// EvaluateHasInclude - Process a '__has_include("path")' expression.
/// Returns true if successful.
static bool EvaluateHasInclude(Token &Tok, IdentifierInfo *II,
Preprocessor &PP) {
- return EvaluateHasIncludeCommon(Tok, II, PP, NULL);
+ return EvaluateHasIncludeCommon(Tok, II, PP, nullptr);
}
/// EvaluateHasIncludeNext - Process '__has_include_next("path")' expression.
@@ -1180,9 +1168,9 @@ static bool EvaluateHasIncludeNext(Token &Tok,
// issue a diagnostic.
const DirectoryLookup *Lookup = PP.GetCurDirLookup();
if (PP.isInPrimaryFile()) {
- Lookup = 0;
+ Lookup = nullptr;
PP.Diag(Tok, diag::pp_include_next_in_primary);
- } else if (Lookup == 0) {
+ } else if (!Lookup) {
PP.Diag(Tok, diag::pp_include_next_absolute_path);
} else {
// Start looking up in the next directory.
@@ -1201,7 +1189,8 @@ static bool EvaluateBuildingModule(Token &Tok,
// Ensure we have a '('.
if (Tok.isNot(tok::l_paren)) {
- PP.Diag(Tok.getLocation(), diag::err_pp_missing_lparen) << II->getName();
+ PP.Diag(Tok.getLocation(), diag::err_pp_expected_after) << II
+ << tok::l_paren;
return false;
}
@@ -1225,8 +1214,9 @@ static bool EvaluateBuildingModule(Token &Tok,
// Ensure we have a trailing ).
if (Tok.isNot(tok::r_paren)) {
- PP.Diag(Tok.getLocation(), diag::err_pp_missing_rparen) << II->getName();
- PP.Diag(LParenLoc, diag::note_matching) << "(";
+ PP.Diag(Tok.getLocation(), diag::err_pp_expected_after) << II
+ << tok::r_paren;
+ PP.Diag(LParenLoc, diag::note_matching) << tok::l_paren;
return false;
}
@@ -1253,7 +1243,7 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
llvm::raw_svector_ostream OS(TmpBuffer);
// Set up the return result.
- Tok.setIdentifierInfo(0);
+ Tok.setIdentifierInfo(nullptr);
Tok.clearFlag(Token::NeedsCleaning);
if (II == Ident__LINE__) {
@@ -1304,6 +1294,7 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
}
Tok.setKind(tok::string_literal);
} else if (II == Ident__DATE__) {
+ Diag(Tok.getLocation(), diag::warn_pp_date_time);
if (!DATELoc.isValid())
ComputeDATE_TIME(DATELoc, TIMELoc, *this);
Tok.setKind(tok::string_literal);
@@ -1313,6 +1304,7 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
Tok.getLength()));
return;
} else if (II == Ident__TIME__) {
+ Diag(Tok.getLocation(), diag::warn_pp_date_time);
if (!TIMELoc.isValid())
ComputeDATE_TIME(DATELoc, TIMELoc, *this);
Tok.setKind(tok::string_literal);
@@ -1337,12 +1329,13 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
OS << Depth;
Tok.setKind(tok::numeric_constant);
} else if (II == Ident__TIMESTAMP__) {
+ Diag(Tok.getLocation(), diag::warn_pp_date_time);
// MSVC, ICC, GCC, VisualAge C++ extension. The generated string should be
// of the form "Ddd Mmm dd hh::mm::ss yyyy", which is returned by asctime.
// Get the file that we are lexing out of. If we're currently lexing from
// a macro, dig into the include stack.
- const FileEntry *CurFile = 0;
+ const FileEntry *CurFile = nullptr;
PreprocessorLexer *TheLexer = getCurrentFileLexer();
if (TheLexer)
@@ -1357,7 +1350,7 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
Result = "??? ??? ?? ??:??:?? ????\n";
}
// Surround the string with " and strip the trailing newline.
- OS << '"' << StringRef(Result, strlen(Result)-1) << '"';
+ OS << '"' << StringRef(Result).drop_back() << '"';
Tok.setKind(tok::string_literal);
} else if (II == Ident__COUNTER__) {
// __COUNTER__ expands to a simple numeric value.
@@ -1366,12 +1359,13 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
} else if (II == Ident__has_feature ||
II == Ident__has_extension ||
II == Ident__has_builtin ||
+ II == Ident__is_identifier ||
II == Ident__has_attribute) {
// The argument to these builtins should be a parenthesized identifier.
SourceLocation StartLoc = Tok.getLocation();
bool IsValid = false;
- IdentifierInfo *FeatureII = 0;
+ IdentifierInfo *FeatureII = nullptr;
// Read the '('.
LexUnexpandedToken(Tok);
@@ -1389,11 +1383,14 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
bool Value = false;
if (!IsValid)
Diag(StartLoc, diag::err_feature_check_malformed);
+ else if (II == Ident__is_identifier)
+ Value = FeatureII->getTokenID() == tok::identifier;
else if (II == Ident__has_builtin) {
// Check for a builtin is trivial.
Value = FeatureII->getBuiltinID() != 0;
} else if (II == Ident__has_attribute)
- Value = HasAttribute(FeatureII);
+ Value = hasAttribute(AttrSyntax::Generic, nullptr, FeatureII,
+ getTargetInfo().getTriple(), getLangOpts());
else if (II == Ident__has_extension)
Value = HasExtension(*this, FeatureII);
else {
@@ -1449,6 +1446,8 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
break;
}
+ // FIXME: Should we accept "-R..." flags here, or should that be handled
+ // by a separate __has_remark?
if (WarningName.size() < 3 || WarningName[0] != '-' ||
WarningName[1] != 'W') {
Diag(StrStartLoc, diag::warn_has_warning_invalid_option);
@@ -1461,7 +1460,8 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
// worth special casing.
SmallVector<diag::kind, 10> Diags;
Value = !getDiagnostics().getDiagnosticIDs()->
- getDiagnosticsInGroup(WarningName.substr(2), Diags);
+ getDiagnosticsInGroup(diag::Flavor::WarningOrError,
+ WarningName.substr(2), Diags);
} while (false);
OS << (int)Value;
@@ -1479,6 +1479,44 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
IdentifierInfo *ModuleII = getIdentifierInfo(getLangOpts().CurrentModule);
Tok.setIdentifierInfo(ModuleII);
Tok.setKind(ModuleII->getTokenID());
+ } else if (II == Ident__identifier) {
+ SourceLocation Loc = Tok.getLocation();
+
+ // We're expecting '__identifier' '(' identifier ')'. Try to recover
+ // if the parens are missing.
+ LexNonComment(Tok);
+ if (Tok.isNot(tok::l_paren)) {
+ // No '(', use end of last token.
+ Diag(getLocForEndOfToken(Loc), diag::err_pp_expected_after)
+ << II << tok::l_paren;
+ // If the next token isn't valid as our argument, we can't recover.
+ if (!Tok.isAnnotation() && Tok.getIdentifierInfo())
+ Tok.setKind(tok::identifier);
+ return;
+ }
+
+ SourceLocation LParenLoc = Tok.getLocation();
+ LexNonComment(Tok);
+
+ if (!Tok.isAnnotation() && Tok.getIdentifierInfo())
+ Tok.setKind(tok::identifier);
+ else {
+ Diag(Tok.getLocation(), diag::err_pp_identifier_arg_not_identifier)
+ << Tok.getKind();
+ // Don't walk past anything that's not a real token.
+ if (Tok.is(tok::eof) || Tok.is(tok::eod) || Tok.isAnnotation())
+ return;
+ }
+
+ // Discard the ')', preserving 'Tok' as our result.
+ Token RParen;
+ LexNonComment(RParen);
+ if (RParen.isNot(tok::r_paren)) {
+ Diag(getLocForEndOfToken(Tok.getLocation()), diag::err_pp_expected_after)
+ << Tok.getKind() << tok::r_paren;
+ Diag(LParenLoc, diag::note_matching) << tok::l_paren;
+ }
+ return;
} else {
llvm_unreachable("Unknown identifier!");
}