[cfe-commits] r38682 - in /cfe/cfe/trunk: Lex/IdentifierTable.cpp Lex/MacroInfo.cpp Lex/Preprocessor.cpp include/clang/Basic/DiagnosticKinds.def include/clang/Lex/IdentifierTable.h include/clang/Lex/MacroInfo.h
sabre at cs.uiuc.edu
sabre at cs.uiuc.edu
Wed Jul 11 09:23:47 PDT 2007
Author: sabre
Date: Wed Jul 11 11:23:47 2007
New Revision: 38682
URL: http://llvm.org/viewvc/llvm-project?rev=38682&view=rev
Log:
Add identifiers for macro arguments to MacroInfo, check for duplicates,
enhance macro equality testing to verify argument lists match.
Modified:
cfe/cfe/trunk/Lex/IdentifierTable.cpp
cfe/cfe/trunk/Lex/MacroInfo.cpp
cfe/cfe/trunk/Lex/Preprocessor.cpp
cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
cfe/cfe/trunk/include/clang/Lex/IdentifierTable.h
cfe/cfe/trunk/include/clang/Lex/MacroInfo.h
Modified: cfe/cfe/trunk/Lex/IdentifierTable.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Lex/IdentifierTable.cpp?rev=38682&r1=38681&r2=38682&view=diff
==============================================================================
--- cfe/cfe/trunk/Lex/IdentifierTable.cpp (original)
+++ cfe/cfe/trunk/Lex/IdentifierTable.cpp Wed Jul 11 11:23:47 2007
@@ -199,6 +199,7 @@
Identifier->TokInfo.TokenID = tok::identifier;
Identifier->TokInfo.IsExtension = false;
Identifier->TokInfo.IsPoisoned = false;
+ Identifier->TokInfo.IsMacroArg = false;
Identifier->TokInfo.FETokenInfo = 0;
// Copy the string information.
Modified: cfe/cfe/trunk/Lex/MacroInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Lex/MacroInfo.cpp?rev=38682&r1=38681&r2=38682&view=diff
==============================================================================
--- cfe/cfe/trunk/Lex/MacroInfo.cpp (original)
+++ cfe/cfe/trunk/Lex/MacroInfo.cpp Wed Jul 11 11:23:47 2007
@@ -26,20 +26,30 @@
IsUsed = true;
}
+/// SetIdentifierIsMacroArgFlags - Set or clear the "isMacroArg" flags on the
+/// identifiers that make up the argument list for this macro.
+void MacroInfo::SetIdentifierIsMacroArgFlags(bool Val) const {
+ for (arg_iterator I = arg_begin(), E = arg_end(); I != E; ++I)
+ (*I)->setIsMacroArg(Val);
+}
/// isIdenticalTo - Return true if the specified macro definition is equal to
/// this macro in spelling, arguments, and whitespace. This is used to emit
/// duplicate definition warnings. This implements the rules in C99 6.10.3.
bool MacroInfo::isIdenticalTo(const MacroInfo &Other, Preprocessor &PP) const {
- // TODO: Check param count.
-
- // Check # tokens in replacement match.
+ // Check # tokens in replacement, number of args, and various flags all match.
if (ReplacementTokens.size() != Other.ReplacementTokens.size() ||
+ Arguments.size() != Other.Arguments.size() ||
isFunctionLike() != Other.isFunctionLike() ||
isC99Varargs() != Other.isC99Varargs() ||
isGNUVarargs() != Other.isGNUVarargs())
return false;
-
+
+ // Check arguments.
+ for (arg_iterator I = arg_begin(), OI = Other.arg_begin(), E = arg_end();
+ I != E; ++I, ++OI)
+ if (*I != *OI) return false;
+
// Check all the tokens.
for (unsigned i = 0, e = ReplacementTokens.size(); i != e; ++i) {
const LexerToken &A = ReplacementTokens[i];
Modified: cfe/cfe/trunk/Lex/Preprocessor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Lex/Preprocessor.cpp?rev=38682&r1=38681&r2=38682&view=diff
==============================================================================
--- cfe/cfe/trunk/Lex/Preprocessor.cpp (original)
+++ cfe/cfe/trunk/Lex/Preprocessor.cpp Wed Jul 11 11:23:47 2007
@@ -1347,13 +1347,12 @@
/// parsing the arg list.
bool Preprocessor::ReadMacroDefinitionArgList(MacroInfo *MI) {
LexerToken Tok;
- bool isFirst = true;
while (1) {
LexUnexpandedToken(Tok);
switch (Tok.getKind()) {
case tok::r_paren:
// Found the end of the argument list.
- if (isFirst) return false; // #define FOO()
+ if (MI->arg_begin() == MI->arg_end()) return false; // #define FOO()
// Otherwise we have #define FOO(A,)
Diag(Tok, diag::err_pp_expected_ident_in_arg_list);
return true;
@@ -1376,13 +1375,19 @@
Diag(Tok, diag::err_pp_invalid_tok_in_arg_list);
return true;
case tok::identifier:
- isFirst = false;
-
- // Fill in Result.IdentifierInfo, looking up the identifier in the
- // identifier table.
- IdentifierInfo *II = LookUpIdentifierInfo(Tok);
-
- assert(0 && "FIXME: lookup/add identifier, check for conflicts");
+ IdentifierInfo *II = Tok.getIdentifierInfo();
+
+ // If this is already used as an argument, it is used multiple times (e.g.
+ // #define X(A,A.
+ if (II->isMacroArg()) { // C99 6.10.3p6
+ Diag(Tok, diag::err_pp_duplicate_name_in_arg_list, II->getName());
+ return true;
+ }
+
+ // Add the argument to the macro info.
+ MI->addArgument(II);
+ // Remember it is an argument now.
+ II->setIsMacroArg(true);
// Lex the token after the identifier.
LexUnexpandedToken(Tok);
@@ -1431,13 +1436,20 @@
LexerToken Tok;
LexUnexpandedToken(Tok);
+ // If this is a function-like macro definition, parse the argument list,
+ // marking each of the identifiers as being used as macro arguments. Also,
+ // check other constraints on the first token of the macro body.
if (Tok.getKind() == tok::eom) {
// If there is no body to this macro, we have no special handling here.
} else if (Tok.getKind() == tok::l_paren && !Tok.hasLeadingSpace()) {
// This is a function-like macro definition. Read the argument list.
MI->setIsFunctionLike();
if (ReadMacroDefinitionArgList(MI)) {
+ // Clear the "isMacroArg" flags from all the macro arguments parsed.
+ MI->SetIdentifierIsMacroArgFlags(false);
+ // Forget about MI.
delete MI;
+ // Throw away the rest of the line.
if (CurLexer->ParsingPreprocessorDirective)
DiscardUntilEndOfDirective();
return;
@@ -1476,11 +1488,15 @@
if (NumTokens != 0) {
if (MI->getReplacementToken(0).getKind() == tok::hashhash) {
SourceLocation Loc = MI->getReplacementToken(0).getLocation();
+ // Clear the "isMacroArg" flags from all the macro arguments.
+ MI->SetIdentifierIsMacroArgFlags(false);
delete MI;
return Diag(Loc, diag::err_paste_at_start);
}
if (MI->getReplacementToken(NumTokens-1).getKind() == tok::hashhash) {
SourceLocation Loc = MI->getReplacementToken(NumTokens-1).getLocation();
+ // Clear the "isMacroArg" flags from all the macro arguments.
+ MI->SetIdentifierIsMacroArgFlags(false);
delete MI;
return Diag(Loc, diag::err_paste_at_end);
}
@@ -1509,6 +1525,9 @@
}
MacroNameTok.getIdentifierInfo()->setMacroInfo(MI);
+
+ // Clear the "isMacroArg" flags from all the macro arguments.
+ MI->SetIdentifierIsMacroArgFlags(false);
}
Modified: cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=38682&r1=38681&r2=38682&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def Wed Jul 11 11:23:47 2007
@@ -155,6 +155,8 @@
"expected identifier in macro parameter list")
DIAG(err_pp_expected_comma_in_arg_list, ERROR,
"expected comma in macro parameter list")
+DIAG(err_pp_duplicate_name_in_arg_list, ERROR,
+ "duplicate macro parameter name \"%s\"")
DIAG(err_pp_malformed_ident, ERROR,
"invalid #ident directive")
DIAG(err_pp_unterminated_conditional, ERROR,
Modified: cfe/cfe/trunk/include/clang/Lex/IdentifierTable.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Lex/IdentifierTable.h?rev=38682&r1=38681&r2=38682&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/Lex/IdentifierTable.h (original)
+++ cfe/cfe/trunk/include/clang/Lex/IdentifierTable.h Wed Jul 11 11:23:47 2007
@@ -34,6 +34,7 @@
tok::TokenKind TokenID:8; // Front-end token ID or tok::identifier.
bool IsExtension : 1; // True if this identifier is a language extension.
bool IsPoisoned : 1; // True if this identifier is poisoned.
+ bool IsMacroArg : 1; // True if currently used as a macro argument.
void *FETokenInfo; // Managed by the language front-end.
friend class IdentifierTable;
public:
@@ -76,6 +77,12 @@
/// isPoisoned - Return true if this token has been poisoned.
bool isPoisoned() const { return IsPoisoned; }
+ /// IsMacroArg accessors - These indicate if the identifier is currently in
+ /// use as a macro argument identifier. This is a transient property only
+ /// used during macro definition and expansion.
+ bool isMacroArg() const { return IsMacroArg; }
+ void setIsMacroArg(bool Val) { IsMacroArg = Val; }
+
/// getFETokenInfo/setFETokenInfo - The language front-end is allowed to
/// associate arbitrary metadata with this token.
template<typename T>
Modified: cfe/cfe/trunk/include/clang/Lex/MacroInfo.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Lex/MacroInfo.h?rev=38682&r1=38681&r2=38682&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/Lex/MacroInfo.h (original)
+++ cfe/cfe/trunk/include/clang/Lex/MacroInfo.h Wed Jul 11 11:23:47 2007
@@ -14,7 +14,7 @@
#ifndef LLVM_CLANG_MACROINFO_H
#define LLVM_CLANG_MACROINFO_H
-#include "clang/Lex/Lexer.h"
+#include "clang/Lex/LexerToken.h"
#include <vector>
namespace llvm {
@@ -30,8 +30,9 @@
/// Location - This is the place the macro is defined.
SourceLocation Location;
- // TODO: Parameter list
- // TODO: # parameters
+ /// Arguments - The list of arguments for a function-like macro. This can be
+ /// empty, for, e.g. "#define X()".
+ std::vector<IdentifierInfo*> Arguments;
/// ReplacementTokens - This is the list of tokens that the macro is defined
/// to.
@@ -91,6 +92,19 @@
void setIsUsed(bool Val) {
IsUsed = Val;
}
+
+ /// addArgument - Add an argument to the list of formal arguments for this
+ /// function-like macro.
+ void addArgument(IdentifierInfo *Arg) {
+ Arguments.push_back(Arg);
+ }
+
+ /// Arguments - The list of arguments for a function-like macro. This can be
+ /// empty, for, e.g. "#define X()".
+ typedef std::vector<IdentifierInfo*>::const_iterator arg_iterator;
+ arg_iterator arg_begin() const { return Arguments.begin(); }
+ arg_iterator arg_end() const { return Arguments.end(); }
+
/// Function/Object-likeness. Keep track of whether this macro has formal
/// parameters.
@@ -142,6 +156,10 @@
assert(!IsDisabled && "Cannot disable an already-disabled macro!");
IsDisabled = true;
}
+
+ /// SetIdentifierIsMacroArgFlags - Set or clear the "isMacroArg" flags on the
+ /// identifiers that make up the argument list for this macro.
+ void SetIdentifierIsMacroArgFlags(bool Val) const;
};
} // end namespace llvm
More information about the cfe-commits
mailing list