Patch to allow alternative representation of c++
operators (and, or, etc.) to be used as selectors to match g++'s behavior. llvm-svn: 112935
This commit is contained in:
parent
cce44678b4
commit
0389df4a45
|
@ -76,7 +76,9 @@ public:
|
|||
StartOfLine = 0x01, // At start of line or only after whitespace.
|
||||
LeadingSpace = 0x02, // Whitespace exists before this token.
|
||||
DisableExpand = 0x04, // This identifier may never be macro expanded.
|
||||
NeedsCleaning = 0x08 // Contained an escaped newline or trigraph.
|
||||
NeedsCleaning = 0x08, // Contained an escaped newline or trigraph.
|
||||
CPlusPlusOpKeyword = 0x10 // alternative representation of
|
||||
// a C++ operator in objc selectors.
|
||||
};
|
||||
|
||||
tok::TokenKind getKind() const { return (tok::TokenKind)Kind; }
|
||||
|
@ -231,6 +233,12 @@ public:
|
|||
/// newlines in it.
|
||||
///
|
||||
bool needsCleaning() const { return (Flags & NeedsCleaning) ? true : false; }
|
||||
|
||||
/// isCPlusPlusOpKeyword - Return true if this token is an operator
|
||||
/// for C++ operator keywords.
|
||||
bool isCPlusPlusOpKeyword() const
|
||||
{ return (Flags & CPlusPlusOpKeyword) ? true : false; }
|
||||
|
||||
};
|
||||
|
||||
/// PPConditionalInfo - Information about the conditional stack (#if directives)
|
||||
|
|
|
@ -613,8 +613,10 @@ void Preprocessor::HandleIdentifier(Token &Identifier) {
|
|||
// C++ 2.11p2: If this is an alternative representation of a C++ operator,
|
||||
// then we act as if it is the actual operator and not the textual
|
||||
// representation of it.
|
||||
if (II.isCPlusPlusOperatorKeyword())
|
||||
if (II.isCPlusPlusOperatorKeyword()) {
|
||||
Identifier.setIdentifierInfo(0);
|
||||
Identifier.setFlag(Token::CPlusPlusOpKeyword);
|
||||
}
|
||||
|
||||
// If this is an extension token, diagnose its use.
|
||||
// We avoid diagnosing tokens that originate from macro definitions.
|
||||
|
|
|
@ -553,6 +553,60 @@ void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS, Decl *ClassDecl,
|
|||
MatchRHSPunctuation(tok::r_paren, LHSLoc);
|
||||
}
|
||||
|
||||
static void ConvertCPlusPlusOperatorToken(Preprocessor &PP, Token &Tok) {
|
||||
if (!Tok.isCPlusPlusOpKeyword())
|
||||
return;
|
||||
|
||||
switch (Tok.getKind()) {
|
||||
case tok::ampamp:
|
||||
Tok.setIdentifierInfo(&PP.getIdentifierTable().get("and"));
|
||||
Tok.setKind(tok::identifier);
|
||||
return;
|
||||
case tok::ampequal:
|
||||
Tok.setIdentifierInfo(&PP.getIdentifierTable().get("and_eq"));
|
||||
Tok.setKind(tok::identifier);
|
||||
return;
|
||||
case tok::amp:
|
||||
Tok.setIdentifierInfo(&PP.getIdentifierTable().get("bitand"));
|
||||
Tok.setKind(tok::identifier);
|
||||
return;
|
||||
case tok::pipe:
|
||||
Tok.setIdentifierInfo(&PP.getIdentifierTable().get("pipe"));
|
||||
Tok.setKind(tok::identifier);
|
||||
return;
|
||||
case tok::tilde:
|
||||
Tok.setIdentifierInfo(&PP.getIdentifierTable().get("compl"));
|
||||
Tok.setKind(tok::identifier);
|
||||
return;
|
||||
case tok::exclaim:
|
||||
Tok.setIdentifierInfo(&PP.getIdentifierTable().get("not"));
|
||||
Tok.setKind(tok::identifier);
|
||||
return;
|
||||
case tok::exclaimequal:
|
||||
Tok.setIdentifierInfo(&PP.getIdentifierTable().get("not_eq"));
|
||||
Tok.setKind(tok::identifier);
|
||||
return;
|
||||
case tok::pipepipe:
|
||||
Tok.setIdentifierInfo(&PP.getIdentifierTable().get("or"));
|
||||
Tok.setKind(tok::identifier);
|
||||
return;
|
||||
case tok::pipeequal:
|
||||
Tok.setIdentifierInfo(&PP.getIdentifierTable().get("or_eq"));
|
||||
Tok.setKind(tok::identifier);
|
||||
return;
|
||||
case tok::caret:
|
||||
Tok.setIdentifierInfo(&PP.getIdentifierTable().get("xor"));
|
||||
Tok.setKind(tok::identifier);
|
||||
return;
|
||||
case tok::caretequal:
|
||||
Tok.setIdentifierInfo(&PP.getIdentifierTable().get("xor_eq"));
|
||||
Tok.setKind(tok::identifier);
|
||||
return;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/// objc-method-proto:
|
||||
/// objc-instance-method objc-method-decl objc-method-attributes[opt]
|
||||
/// objc-class-method objc-method-decl objc-method-attributes[opt]
|
||||
|
@ -569,7 +623,6 @@ Decl *Parser::ParseObjCMethodPrototype(Decl *IDecl,
|
|||
|
||||
tok::TokenKind methodType = Tok.getKind();
|
||||
SourceLocation mLoc = ConsumeToken();
|
||||
|
||||
Decl *MDecl = ParseObjCMethodDecl(mLoc, methodType, IDecl,MethodImplKind);
|
||||
// Since this rule is used for both method declarations and definitions,
|
||||
// the caller is (optionally) responsible for consuming the ';'.
|
||||
|
@ -585,6 +638,8 @@ Decl *Parser::ParseObjCMethodPrototype(Decl *IDecl,
|
|||
/// in out inout bycopy byref oneway int char float double void _Bool
|
||||
///
|
||||
IdentifierInfo *Parser::ParseObjCSelectorPiece(SourceLocation &SelectorLoc) {
|
||||
ConvertCPlusPlusOperatorToken(PP, Tok);
|
||||
|
||||
switch (Tok.getKind()) {
|
||||
default:
|
||||
return 0;
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
// RUN: %clang_cc1 -fsyntax-only -verify %s
|
||||
// rdar:// 8328250
|
||||
|
||||
@class NSDate;
|
||||
|
||||
@interface XSGraphDataSet
|
||||
- and;
|
||||
- xor;
|
||||
- or;
|
||||
|
||||
- ||; // expected-error {{expected selector for Objective-C method}}
|
||||
|
||||
- &&; // expected-error {{expected selector for Objective-C method}}
|
||||
|
||||
- (void)dataSetForValuesBetween:(NSDate *)startDate and:(NSDate *)endDate;
|
||||
@end
|
||||
|
||||
@implementation XSGraphDataSet
|
||||
- (id) and{return 0; };
|
||||
- (id) xor{return 0; };
|
||||
- (id) or{return 0; };
|
||||
|
||||
- (void)dataSetForValuesBetween:(NSDate *)startDate and:(NSDate *)endDate { return; }
|
||||
@end
|
Loading…
Reference in New Issue