зеркало из https://github.com/microsoft/clang-1.git
Implement parsing and code generation of Objective-C string literals.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@41238 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
5083a53697
Коммит
5508518a27
|
@ -492,6 +492,16 @@ void StmtDumper::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {
|
||||||
fprintf(F, " %s)", Node->getValue() ? "true" : "false");
|
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
|
// Stmt method implementations
|
||||||
|
|
|
@ -511,6 +511,12 @@ void StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {
|
||||||
OS << (Node->getValue() ? "true" : "false");
|
OS << (Node->getValue() ? "true" : "false");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Obj-C
|
||||||
|
|
||||||
|
void StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) {
|
||||||
|
OS << "@";
|
||||||
|
VisitStringLiteral(Node->getString());
|
||||||
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Stmt method implementations
|
// Stmt method implementations
|
||||||
|
|
|
@ -566,6 +566,8 @@ RValue CodeGenFunction::EmitExpr(const Expr *E) {
|
||||||
return EmitConditionalOperator(cast<ConditionalOperator>(E));
|
return EmitConditionalOperator(cast<ConditionalOperator>(E));
|
||||||
case Expr::ChooseExprClass:
|
case Expr::ChooseExprClass:
|
||||||
return EmitChooseExpr(cast<ChooseExpr>(E));
|
return EmitChooseExpr(cast<ChooseExpr>(E));
|
||||||
|
case Expr::ObjCStringLiteralClass:
|
||||||
|
return EmitObjCStringLiteral(cast<ObjCStringLiteral>(E));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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));
|
||||||
|
}
|
||||||
|
|
|
@ -61,6 +61,7 @@ namespace clang {
|
||||||
class ConditionalOperator;
|
class ConditionalOperator;
|
||||||
class ChooseExpr;
|
class ChooseExpr;
|
||||||
class PreDefinedExpr;
|
class PreDefinedExpr;
|
||||||
|
class ObjCStringLiteral;
|
||||||
|
|
||||||
class BlockVarDecl;
|
class BlockVarDecl;
|
||||||
class EnumConstantDecl;
|
class EnumConstantDecl;
|
||||||
|
@ -393,6 +394,8 @@ public:
|
||||||
RValue EmitConditionalOperator(const ConditionalOperator *E);
|
RValue EmitConditionalOperator(const ConditionalOperator *E);
|
||||||
RValue EmitChooseExpr(const ChooseExpr *E);
|
RValue EmitChooseExpr(const ChooseExpr *E);
|
||||||
|
|
||||||
|
RValue EmitObjCStringLiteral(const ObjCStringLiteral* E);
|
||||||
|
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
// Aggregate Expression Emission
|
// Aggregate Expression Emission
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
|
|
|
@ -569,6 +569,8 @@ Parser::ExprResult Parser::ParseCastExpression(bool isUnaryExpression) {
|
||||||
case tok::kw_reinterpret_cast:
|
case tok::kw_reinterpret_cast:
|
||||||
case tok::kw_static_cast:
|
case tok::kw_static_cast:
|
||||||
return ParseCXXCasts();
|
return ParseCXXCasts();
|
||||||
|
case tok::at:
|
||||||
|
return ParseObjCExpression();
|
||||||
default:
|
default:
|
||||||
Diag(Tok, diag::err_expected_expression);
|
Diag(Tok, diag::err_expected_expression);
|
||||||
return ExprResult(true);
|
return ExprResult(true);
|
||||||
|
|
|
@ -310,3 +310,27 @@ void Parser::ParseObjCInstanceMethodDeclaration() {
|
||||||
void Parser::ParseObjCClassMethodDeclaration() {
|
void Parser::ParseObjCClassMethodDeclaration() {
|
||||||
assert(0 && "Unimp");
|
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);
|
||||||
|
}
|
||||||
|
|
|
@ -323,6 +323,9 @@ public:
|
||||||
/// ParseCXXBoolLiteral - Parse {true,false} literals.
|
/// ParseCXXBoolLiteral - Parse {true,false} literals.
|
||||||
virtual ExprResult ParseCXXBoolLiteral(SourceLocation OpLoc,
|
virtual ExprResult ParseCXXBoolLiteral(SourceLocation OpLoc,
|
||||||
tok::TokenKind Kind);
|
tok::TokenKind Kind);
|
||||||
|
|
||||||
|
// ParseObjCStringLiteral - Parse Objective-C string literals.
|
||||||
|
virtual ExprResult ParseObjCStringLiteral(ExprTy *string);
|
||||||
private:
|
private:
|
||||||
// UsualUnaryConversions - promotes integers (C99 6.3.1.1p2) and converts
|
// UsualUnaryConversions - promotes integers (C99 6.3.1.1p2) and converts
|
||||||
// functions and arrays to their respective pointers (C99 6.3.2.1).
|
// functions and arrays to their respective pointers (C99 6.3.2.1).
|
||||||
|
|
|
@ -1657,3 +1657,17 @@ Sema::ExprResult Sema::ParseChooseExpr(SourceLocation BuiltinLoc, ExprTy *cond,
|
||||||
return new ChooseExpr(BuiltinLoc, CondExpr, LHSExpr, RHSExpr, resType, RPLoc);
|
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);
|
||||||
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
1A30A9E90B93A4C800201A91 /* ExprCXX.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1A30A9E80B93A4C800201A91 /* ExprCXX.h */; };
|
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 */; };
|
1A869A700BA2164C008DA07A /* LiteralSupport.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1A869A6E0BA2164C008DA07A /* LiteralSupport.h */; };
|
||||||
1A869AA80BA21ABA008DA07A /* LiteralSupport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A869AA70BA21ABA008DA07A /* LiteralSupport.cpp */; };
|
1A869AA80BA21ABA008DA07A /* LiteralSupport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A869AA70BA21ABA008DA07A /* LiteralSupport.cpp */; };
|
||||||
1ABC36940C7A4BDC006DB0AB /* CGBuiltin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ABC36930C7A4BDC006DB0AB /* CGBuiltin.cpp */; };
|
1ABC36940C7A4BDC006DB0AB /* CGBuiltin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ABC36930C7A4BDC006DB0AB /* CGBuiltin.cpp */; };
|
||||||
|
@ -196,6 +197,7 @@
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
1A30A9E80B93A4C800201A91 /* ExprCXX.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ExprCXX.h; path = clang/AST/ExprCXX.h; sourceTree = "<group>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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 */,
|
DEF2EFF20C6CDD74000C4259 /* CGAggExpr.cpp */,
|
||||||
DE224FF70C7AA98800D370A5 /* CGComplexExpr.cpp */,
|
DE224FF70C7AA98800D370A5 /* CGComplexExpr.cpp */,
|
||||||
DE4772FB0C10EAEC002239E8 /* CGExpr.cpp */,
|
DE4772FB0C10EAEC002239E8 /* CGExpr.cpp */,
|
||||||
|
1A7342470C7B57D500122F56 /* CGObjC.cpp */,
|
||||||
DE4772F90C10EAE5002239E8 /* CGStmt.cpp */,
|
DE4772F90C10EAE5002239E8 /* CGStmt.cpp */,
|
||||||
DE928B120C05659200231DA4 /* ModuleBuilder.cpp */,
|
DE928B120C05659200231DA4 /* ModuleBuilder.cpp */,
|
||||||
);
|
);
|
||||||
|
@ -616,6 +619,7 @@
|
||||||
08FB7793FE84155DC02AAC07 /* Project object */ = {
|
08FB7793FE84155DC02AAC07 /* Project object */ = {
|
||||||
isa = PBXProject;
|
isa = PBXProject;
|
||||||
buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "clang" */;
|
buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "clang" */;
|
||||||
|
compatibilityVersion = "Xcode 2.4";
|
||||||
hasScannedForEncodings = 1;
|
hasScannedForEncodings = 1;
|
||||||
mainGroup = 08FB7794FE84155DC02AAC07 /* clang */;
|
mainGroup = 08FB7794FE84155DC02AAC07 /* clang */;
|
||||||
projectDirPath = "";
|
projectDirPath = "";
|
||||||
|
@ -692,6 +696,7 @@
|
||||||
DEF2F0100C6CFED5000C4259 /* SemaChecking.cpp in Sources */,
|
DEF2F0100C6CFED5000C4259 /* SemaChecking.cpp in Sources */,
|
||||||
1ABC36940C7A4BDC006DB0AB /* CGBuiltin.cpp in Sources */,
|
1ABC36940C7A4BDC006DB0AB /* CGBuiltin.cpp in Sources */,
|
||||||
DE224FF80C7AA98800D370A5 /* CGComplexExpr.cpp in Sources */,
|
DE224FF80C7AA98800D370A5 /* CGComplexExpr.cpp in Sources */,
|
||||||
|
1A7342480C7B57D500122F56 /* CGObjC.cpp in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
|
|
@ -811,6 +811,28 @@ public:
|
||||||
static bool classof(const ChooseExpr *) { return true; }
|
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
|
} // end namespace clang
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -73,7 +73,11 @@ STMT(53, ChooseExpr , Expr)
|
||||||
// C++ Expressions.
|
// C++ Expressions.
|
||||||
STMT(54, CXXCastExpr , Expr)
|
STMT(54, CXXCastExpr , Expr)
|
||||||
STMT(55, CXXBoolLiteralExpr , Expr)
|
STMT(55, CXXBoolLiteralExpr , Expr)
|
||||||
LAST_EXPR(55)
|
|
||||||
|
// Obj-C Expressions.
|
||||||
|
STMT(56, ObjCStringLiteral , Expr)
|
||||||
|
|
||||||
|
LAST_EXPR(56)
|
||||||
|
|
||||||
#undef STMT
|
#undef STMT
|
||||||
#undef FIRST_STMT
|
#undef FIRST_STMT
|
||||||
|
|
|
@ -404,6 +404,12 @@ public:
|
||||||
tok::TokenKind Kind) {
|
tok::TokenKind Kind) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===----------------------- Obj-C Expressions --------------------------===//
|
||||||
|
virtual ExprResult ParseObjCStringLiteral(ExprTy *string) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// MinimalAction - Minimal actions are used by light-weight clients of the
|
/// MinimalAction - Minimal actions are used by light-weight clients of the
|
||||||
|
|
|
@ -323,6 +323,11 @@ private:
|
||||||
ExprResult ParseInitializer();
|
ExprResult ParseInitializer();
|
||||||
ExprResult ParseInitializerWithPotentialDesignator();
|
ExprResult ParseInitializerWithPotentialDesignator();
|
||||||
|
|
||||||
|
//===--------------------------------------------------------------------===//
|
||||||
|
// Objective-C Expressions
|
||||||
|
ExprResult ParseObjCExpression();
|
||||||
|
ExprResult ParseObjCStringLiteral();
|
||||||
|
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
// C99 6.8: Statements and Blocks.
|
// C99 6.8: Statements and Blocks.
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче