Produce a nice error message for '#define and' in C++. Patch by Bill!

llvm-svn: 39218
This commit is contained in:
Chris Lattner 2006-11-21 23:47:30 +00:00
parent bb233fe3aa
commit 652c16924e
2 changed files with 16 additions and 4 deletions

View File

@ -1067,6 +1067,13 @@ void Preprocessor::DiscardUntilEndOfDirective() {
} while (Tmp.getKind() != tok::eom);
}
/// isCXXNamedOperator - Returns "true" if the token is a named operator in C++.
static bool isCXXNamedOperator(const std::string &Spelling) {
return Spelling == "and" || Spelling == "bitand" || Spelling == "bitor" ||
Spelling == "compl" || Spelling == "not" || Spelling == "not_eq" ||
Spelling == "or" || Spelling == "xor";
}
/// ReadMacroName - Lex and validate a macro name, which occurs after a
/// #define or #undef. This sets the token kind to eom and discards the rest
/// of the macro line if the macro name is invalid. isDefineUndef is 1 if
@ -1082,11 +1089,14 @@ void Preprocessor::ReadMacroName(LexerToken &MacroNameTok, char isDefineUndef) {
IdentifierInfo *II = MacroNameTok.getIdentifierInfo();
if (II == 0) {
Diag(MacroNameTok, diag::err_pp_macro_not_identifier);
std::string Spelling = getSpelling(MacroNameTok);
if (isCXXNamedOperator(Spelling))
// C++ 2.5p2: Alternative tokens behave the same as its primary token
// except for their spellings.
Diag(MacroNameTok, diag::err_pp_operator_used_as_macro_name, Spelling);
else
Diag(MacroNameTok, diag::err_pp_macro_not_identifier);
// Fall through on error.
} else if (0) {
// FIXME: C++. Error if defining a C++ named operator.
} else if (isDefineUndef && II->getPPKeywordID() == tok::pp_defined) {
// Error if defining "defined": C99 6.10.8.4.
Diag(MacroNameTok, diag::err_defined_macro_name);

View File

@ -232,6 +232,8 @@ DIAG(err_too_few_args_in_macro_invoc, ERROR,
"too few arguments provided to function-like macro invocation")
DIAG(err_pp_bad_paste, ERROR,
"pasting formed \"%s\", an invalid preprocessing token")
DIAG(err_pp_operator_used_as_macro_name, ERROR,
"C++ operator \"%s\" cannot be used as a macro name")
// Should be a sorry?
DIAG(err_pp_I_dash_not_supported, ERROR,