Implement parsing and code generation of Objective-C string literals.

llvm-svn: 41238
This commit is contained in:
Anders Carlsson 2007-08-21 17:43:55 +00:00
parent 2dc2af3515
commit 76f4a902d7
14 changed files with 135 additions and 1 deletions

View File

@ -492,6 +492,16 @@ void StmtDumper::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {
fprintf(F, " %s)", Node->getValue() ? "true" : "false");
}
//===----------------------------------------------------------------------===//
// Obj-C Expressions
//===----------------------------------------------------------------------===//
void StmtDumper::VisitObjCStringLiteral(ObjCStringLiteral *Node) {
DumpExpr(Node);
fprintf(F, "\n");
DumpSubTree(Node->getString());
fprintf(F, ")");
}
//===----------------------------------------------------------------------===//
// Stmt method implementations

View File

@ -511,6 +511,12 @@ void StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {
OS << (Node->getValue() ? "true" : "false");
}
// Obj-C
void StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) {
OS << "@";
VisitStringLiteral(Node->getString());
}
//===----------------------------------------------------------------------===//
// Stmt method implementations

View File

@ -566,6 +566,8 @@ RValue CodeGenFunction::EmitExpr(const Expr *E) {
return EmitConditionalOperator(cast<ConditionalOperator>(E));
case Expr::ChooseExprClass:
return EmitChooseExpr(cast<ChooseExpr>(E));
case Expr::ObjCStringLiteralClass:
return EmitObjCStringLiteral(cast<ObjCStringLiteral>(E));
}
}

28
clang/CodeGen/CGObjC.cpp Normal file
View File

@ -0,0 +1,28 @@
//===---- CGBuiltin.cpp - Emit LLVM Code for builtins ---------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by Anders Carlsson and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This contains code to emit Objective-C code as LLVM code.
//
//===----------------------------------------------------------------------===//
#include "CodeGenFunction.h"
#include "CodeGenModule.h"
#include "clang/AST/Expr.h"
#include "llvm/Constant.h"
using namespace clang;
using namespace CodeGen;
RValue CodeGenFunction::EmitObjCStringLiteral(const ObjCStringLiteral* E)
{
std::string S(E->getString()->getStrData(), E->getString()->getByteLength());
return RValue::get(CGM.GetAddrOfConstantCFString(S));
}

View File

@ -61,6 +61,7 @@ namespace clang {
class ConditionalOperator;
class ChooseExpr;
class PreDefinedExpr;
class ObjCStringLiteral;
class BlockVarDecl;
class EnumConstantDecl;
@ -393,6 +394,8 @@ public:
RValue EmitConditionalOperator(const ConditionalOperator *E);
RValue EmitChooseExpr(const ChooseExpr *E);
RValue EmitObjCStringLiteral(const ObjCStringLiteral* E);
//===--------------------------------------------------------------------===//
// Aggregate Expression Emission
//===--------------------------------------------------------------------===//

View File

@ -569,6 +569,8 @@ Parser::ExprResult Parser::ParseCastExpression(bool isUnaryExpression) {
case tok::kw_reinterpret_cast:
case tok::kw_static_cast:
return ParseCXXCasts();
case tok::at:
return ParseObjCExpression();
default:
Diag(Tok, diag::err_expected_expression);
return ExprResult(true);

View File

@ -310,3 +310,27 @@ void Parser::ParseObjCInstanceMethodDeclaration() {
void Parser::ParseObjCClassMethodDeclaration() {
assert(0 && "Unimp");
}
Parser::ExprResult Parser::ParseObjCExpression() {
SourceLocation AtLoc = ConsumeToken(); // the "@"
switch (Tok.getKind()) {
case tok::string_literal: // primary-expression: string-literal
case tok::wide_string_literal:
return ParseObjCStringLiteral();
default:
Diag(AtLoc, diag::err_unexpected_at);
SkipUntil(tok::semi);
break;
}
return 0;
}
Parser::ExprResult Parser::ParseObjCStringLiteral() {
ExprResult Res = ParseStringLiteralExpression();
if (Res.isInvalid) return Res;
return Actions.ParseObjCStringLiteral(Res.Val);
}

View File

@ -323,6 +323,9 @@ public:
/// ParseCXXBoolLiteral - Parse {true,false} literals.
virtual ExprResult ParseCXXBoolLiteral(SourceLocation OpLoc,
tok::TokenKind Kind);
// ParseObjCStringLiteral - Parse Objective-C string literals.
virtual ExprResult ParseObjCStringLiteral(ExprTy *string);
private:
// UsualUnaryConversions - promotes integers (C99 6.3.1.1p2) and converts
// functions and arrays to their respective pointers (C99 6.3.2.1).

View File

@ -1657,3 +1657,17 @@ Sema::ExprResult Sema::ParseChooseExpr(SourceLocation BuiltinLoc, ExprTy *cond,
return new ChooseExpr(BuiltinLoc, CondExpr, LHSExpr, RHSExpr, resType, RPLoc);
}
// TODO: Move this to SemaObjC.cpp
Sema::ExprResult Sema::ParseObjCStringLiteral(ExprTy *string)
{
StringLiteral* S = static_cast<StringLiteral *>(string);
if (CheckBuiltinCFStringArgument(S))
return true;
QualType t = Context.getCFConstantStringType();
t = t.getQualifiedType(QualType::Const);
t = Context.getPointerType(t);
return new ObjCStringLiteral(S, t);
}

View File

@ -8,6 +8,7 @@
/* Begin PBXBuildFile section */
1A30A9E90B93A4C800201A91 /* ExprCXX.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1A30A9E80B93A4C800201A91 /* ExprCXX.h */; };
1A7342480C7B57D500122F56 /* CGObjC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A7342470C7B57D500122F56 /* CGObjC.cpp */; };
1A869A700BA2164C008DA07A /* LiteralSupport.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1A869A6E0BA2164C008DA07A /* LiteralSupport.h */; };
1A869AA80BA21ABA008DA07A /* LiteralSupport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A869AA70BA21ABA008DA07A /* LiteralSupport.cpp */; };
1ABC36940C7A4BDC006DB0AB /* CGBuiltin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ABC36930C7A4BDC006DB0AB /* CGBuiltin.cpp */; };
@ -196,6 +197,7 @@
/* Begin PBXFileReference section */
1A30A9E80B93A4C800201A91 /* ExprCXX.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ExprCXX.h; path = clang/AST/ExprCXX.h; sourceTree = "<group>"; };
1A7342470C7B57D500122F56 /* CGObjC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CGObjC.cpp; path = CodeGen/CGObjC.cpp; sourceTree = "<group>"; };
1A869A6E0BA2164C008DA07A /* LiteralSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LiteralSupport.h; sourceTree = "<group>"; };
1A869AA70BA21ABA008DA07A /* LiteralSupport.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = LiteralSupport.cpp; sourceTree = "<group>"; };
1ABC36930C7A4BDC006DB0AB /* CGBuiltin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CGBuiltin.cpp; path = CodeGen/CGBuiltin.cpp; sourceTree = "<group>"; };
@ -437,6 +439,7 @@
DEF2EFF20C6CDD74000C4259 /* CGAggExpr.cpp */,
DE224FF70C7AA98800D370A5 /* CGComplexExpr.cpp */,
DE4772FB0C10EAEC002239E8 /* CGExpr.cpp */,
1A7342470C7B57D500122F56 /* CGObjC.cpp */,
DE4772F90C10EAE5002239E8 /* CGStmt.cpp */,
DE928B120C05659200231DA4 /* ModuleBuilder.cpp */,
);
@ -616,6 +619,7 @@
08FB7793FE84155DC02AAC07 /* Project object */ = {
isa = PBXProject;
buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "clang" */;
compatibilityVersion = "Xcode 2.4";
hasScannedForEncodings = 1;
mainGroup = 08FB7794FE84155DC02AAC07 /* clang */;
projectDirPath = "";
@ -692,6 +696,7 @@
DEF2F0100C6CFED5000C4259 /* SemaChecking.cpp in Sources */,
1ABC36940C7A4BDC006DB0AB /* CGBuiltin.cpp in Sources */,
DE224FF80C7AA98800D370A5 /* CGComplexExpr.cpp in Sources */,
1A7342480C7B57D500122F56 /* CGObjC.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -811,6 +811,28 @@ public:
static bool classof(const ChooseExpr *) { return true; }
};
/// ObjCStringLiteral, used for Objective-C string literals
/// i.e. @"foo".
class ObjCStringLiteral : public Expr {
StringLiteral *String;
public:
ObjCStringLiteral(StringLiteral *SL, QualType T)
: Expr(ObjCStringLiteralClass, T), String(SL) {}
StringLiteral* getString() { return String; }
const StringLiteral* getString() const { return String; }
virtual SourceRange getSourceRange() const {
return String->getSourceRange();
}
static bool classof(const Stmt *T) {
return T->getStmtClass() == ObjCStringLiteralClass;
}
static bool classof(const ObjCStringLiteral *) { return true; }
};
} // end namespace clang
#endif

View File

@ -73,7 +73,11 @@ STMT(53, ChooseExpr , Expr)
// C++ Expressions.
STMT(54, CXXCastExpr , Expr)
STMT(55, CXXBoolLiteralExpr , Expr)
LAST_EXPR(55)
// Obj-C Expressions.
STMT(56, ObjCStringLiteral , Expr)
LAST_EXPR(56)
#undef STMT
#undef FIRST_STMT

View File

@ -404,6 +404,12 @@ public:
tok::TokenKind Kind) {
return 0;
}
//===----------------------- Obj-C Expressions --------------------------===//
virtual ExprResult ParseObjCStringLiteral(ExprTy *string) {
return 0;
}
};
/// MinimalAction - Minimal actions are used by light-weight clients of the

View File

@ -323,6 +323,11 @@ private:
ExprResult ParseInitializer();
ExprResult ParseInitializerWithPotentialDesignator();
//===--------------------------------------------------------------------===//
// Objective-C Expressions
ExprResult ParseObjCExpression();
ExprResult ParseObjCStringLiteral();
//===--------------------------------------------------------------------===//
// C99 6.8: Statements and Blocks.