mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-24 18:20:38 +00:00
Implement checking for macro equality, C99 6.10.3.2
llvm-svn: 38680
This commit is contained in:
parent
e8eef3207b
commit
21284dfdd1
@ -12,13 +12,41 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "clang/Lex/MacroInfo.h"
|
||||
#include "clang/Lex/Preprocessor.h"
|
||||
#include <iostream>
|
||||
using namespace llvm;
|
||||
using namespace clang;
|
||||
|
||||
/// isEqualTo - 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.
|
||||
bool MacroInfo::isEqualTo(const MacroInfo &Other) const {
|
||||
/// 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, variadic, function likeness.
|
||||
|
||||
// Check # tokens in replacement match.
|
||||
if (ReplacementTokens.size() != Other.ReplacementTokens.size())
|
||||
return false;
|
||||
|
||||
// Check all the tokens.
|
||||
for (unsigned i = 0, e = ReplacementTokens.size(); i != e; ++i) {
|
||||
const LexerToken &A = ReplacementTokens[i];
|
||||
const LexerToken &B = Other.ReplacementTokens[i];
|
||||
if (A.getKind() != B.getKind() ||
|
||||
A.isAtStartOfLine() != B.isAtStartOfLine() ||
|
||||
A.hasLeadingSpace() != B.hasLeadingSpace())
|
||||
return false;
|
||||
|
||||
// If this is an identifier, it is easy.
|
||||
if (A.getIdentifierInfo() || B.getIdentifierInfo()) {
|
||||
if (A.getIdentifierInfo() != B.getIdentifierInfo())
|
||||
return false;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Otherwise, check the spelling.
|
||||
if (PP.getSpelling(A) != PP.getSpelling(B))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1400,8 +1400,8 @@ void Preprocessor::HandleDefineDirective(LexerToken &DefineTok) {
|
||||
Diag(OtherMI->getDefinitionLoc(), diag::pp_macro_not_used);
|
||||
|
||||
// Macros must be identical. This means all tokes and whitespace separation
|
||||
// must be the same.
|
||||
if (!MI->isEqualTo(*OtherMI)) {
|
||||
// must be the same. C99 6.10.3.2.
|
||||
if (!MI->isIdenticalTo(*OtherMI, *this)) {
|
||||
Diag(MI->getDefinitionLoc(), diag::ext_pp_macro_redef,
|
||||
MacroNameTok.getIdentifierInfo()->getName());
|
||||
Diag(OtherMI->getDefinitionLoc(), diag::ext_pp_macro_redef2);
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
namespace llvm {
|
||||
namespace clang {
|
||||
class Preprocessor;
|
||||
|
||||
/// MacroInfo - Each identifier that is #define'd has an instance of this class
|
||||
/// associated with it, used to implement macro expansion.
|
||||
@ -57,10 +58,10 @@ public:
|
||||
///
|
||||
SourceLocation getDefinitionLoc() const { return Location; }
|
||||
|
||||
/// isEqualTo - 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.
|
||||
bool isEqualTo(const MacroInfo &Other) const;
|
||||
/// 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 isIdenticalTo(const MacroInfo &Other, Preprocessor &PP) const;
|
||||
|
||||
/// setIsBuiltinMacro - Set or clear the isBuiltinMacro flag.
|
||||
///
|
||||
|
Loading…
x
Reference in New Issue
Block a user