Add ObjC parser support for concatenated ObjC strings. Note that

this is passed to sema and ignored there, so the second part of the
string will not make it into the AST.  Passing to Fariborz to finish
Sema + AST construction.

llvm-svn: 44898
This commit is contained in:
Chris Lattner 2007-12-12 01:04:12 +00:00
parent c98d956778
commit e002fbea56
7 changed files with 65 additions and 16 deletions

View File

@ -1190,11 +1190,11 @@ Parser::DeclTy *Parser::ParseObjCMethodDefinition() {
Parser::ExprResult Parser::ParseObjCAtExpression(SourceLocation AtLoc) {
switch (Tok.getKind()) {
case tok::string_literal: // primary-expression: string-literal
case tok::wide_string_literal:
return ParsePostfixExpressionSuffix(ParseObjCStringLiteral(AtLoc));
default:
break;
case tok::string_literal: // primary-expression: string-literal
case tok::wide_string_literal:
return ParsePostfixExpressionSuffix(ParseObjCStringLiteral(AtLoc));
default:
break;
}
switch (Tok.getIdentifierInfo()->getObjCKeywordID()) {
@ -1333,10 +1333,38 @@ Parser::ExprResult Parser::ParseObjCMessageExpression() {
Parser::ExprResult Parser::ParseObjCStringLiteral(SourceLocation AtLoc) {
ExprResult Res = ParseStringLiteralExpression();
if (Res.isInvalid) return Res;
// @"foo" @"bar" is a valid concatenated string. Eat any subsequent string
// expressions. At this point, we know that the only valid thing that starts
// with '@' is an @"".
llvm::SmallVector<SourceLocation, 4> AtLocs;
llvm::SmallVector<ExprTy*, 4> AtStrings;
AtLocs.push_back(AtLoc);
AtStrings.push_back(Res.Val);
while (Tok.is(tok::at)) {
AtLocs.push_back(ConsumeToken()); // eat the @.
return Actions.ParseObjCStringLiteral(AtLoc, Res.Val);
ExprResult Res(true); // Invalid unless there is a string literal.
if (isTokenStringLiteral())
Res = ParseStringLiteralExpression();
else
Diag(Tok, diag::err_objc_concat_string);
if (Res.isInvalid) {
while (!AtStrings.empty()) {
Actions.DeleteExpr(AtStrings.back());
AtStrings.pop_back();
}
return Res;
}
AtStrings.push_back(Res.Val);
}
return Actions.ParseObjCStringLiteral(&AtLocs[0], &AtStrings[0],
AtStrings.size());
}
/// objc-encode-expression:

View File

@ -465,8 +465,9 @@ public:
tok::TokenKind Kind);
// ParseObjCStringLiteral - Parse Objective-C string literals.
virtual ExprResult ParseObjCStringLiteral(SourceLocation AtLoc,
ExprTy *string);
virtual ExprResult ParseObjCStringLiteral(SourceLocation *AtLocs,
ExprTy **Strings,
unsigned NumStrings);
virtual ExprResult ParseObjCEncodeExpression(SourceLocation AtLoc,
SourceLocation EncodeLoc,
SourceLocation LParenLoc,

View File

@ -2046,9 +2046,14 @@ Sema::ExprResult Sema::ActOnVAArg(SourceLocation BuiltinLoc,
}
// TODO: Move this to SemaObjC.cpp
Sema::ExprResult Sema::ParseObjCStringLiteral(SourceLocation AtLoc,
ExprTy *string) {
StringLiteral* S = static_cast<StringLiteral *>(string);
Sema::ExprResult Sema::ParseObjCStringLiteral(SourceLocation *AtLocs,
ExprTy **Strings,
unsigned NumStrings) {
// FIXME: This is passed in an ARRAY of strings which need to be concatenated.
// Handle this case here. For now we just ignore all but the first one.
SourceLocation AtLoc = AtLocs[0];
StringLiteral* S = static_cast<StringLiteral *>(Strings[0]);
if (CheckBuiltinCFStringArgument(S))
return true;

View File

@ -772,7 +772,6 @@
08FB7793FE84155DC02AAC07 /* Project object */ = {
isa = PBXProject;
buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "clang" */;
compatibilityVersion = "Xcode 2.4";
hasScannedForEncodings = 1;
mainGroup = 08FB7794FE84155DC02AAC07 /* clang */;
projectDirPath = "";

View File

@ -414,6 +414,8 @@ DIAG(err_objc_protocol_optional, ERROR,
"@optional may be specified in protocols only")
DIAG(err_missing_catch_finally, ERROR,
"@try statment without a @catch and @finally clause")
DIAG(err_objc_concat_string, ERROR,
"unexpected token after Objective-C string")
DIAG(err_undef_superclass, ERROR,
"cannot find interface declaration for '%0', superclass of '%1'")
DIAG(err_duplicate_class_def, ERROR,
@ -465,7 +467,7 @@ DIAG(warn_previous_declaration, WARNING,
DIAG(err_conflicting_aliasing_type, ERROR,
"conflicting types for alias %0'")
DIAG(err_statically_allocated_object, ERROR,
"statically allocated Objective-c object '%0'")
"statically allocated Objective-C object '%0'")
DIAG(warn_method_not_found, WARNING,
"method '%0%1' not found (return type defaults to 'id')")

View File

@ -643,8 +643,10 @@ public:
//===----------------------- Obj-C Expressions --------------------------===//
virtual ExprResult ParseObjCStringLiteral(SourceLocation AtLoc,
ExprTy *string) {
virtual ExprResult ParseObjCStringLiteral(SourceLocation *AtLocs,
ExprTy **Strings,
unsigned NumStrings) {
return 0;
}

View File

@ -0,0 +1,12 @@
// RUN: clang %s -verify -fsyntax-only
@class NSString;
@interface NSConstantString;
@end
NSString *s = @"123"; // simple
NSString *t = @"123" @"456"; // concat
NSString *u = @"123" @ blah; // expected-error: {{unexpected token}}