[cfe-commits] r43665 - in /cfe/trunk: AST/ASTContext.cpp Driver/RewriteTest.cpp Parse/ParseObjc.cpp Sema/Sema.h Sema/SemaExpr.cpp include/clang/AST/ASTContext.h include/clang/AST/Expr.h include/clang/Parse/Action.h include/clang/Parse/Parser.h
Steve Naroff
snaroff at apple.com
Sat Nov 3 04:27:20 PDT 2007
Author: snaroff
Date: Sat Nov 3 06:27:19 2007
New Revision: 43665
URL: http://llvm.org/viewvc/llvm-project?rev=43665&view=rev
Log:
Implement rewrite rules for ObjC string constants.
Modified:
cfe/trunk/AST/ASTContext.cpp
cfe/trunk/Driver/RewriteTest.cpp
cfe/trunk/Parse/ParseObjc.cpp
cfe/trunk/Sema/Sema.h
cfe/trunk/Sema/SemaExpr.cpp
cfe/trunk/include/clang/AST/ASTContext.h
cfe/trunk/include/clang/AST/Expr.h
cfe/trunk/include/clang/Parse/Action.h
cfe/trunk/include/clang/Parse/Parser.h
Modified: cfe/trunk/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/ASTContext.cpp?rev=43665&r1=43664&r2=43665&view=diff
==============================================================================
--- cfe/trunk/AST/ASTContext.cpp (original)
+++ cfe/trunk/AST/ASTContext.cpp Sat Nov 3 06:27:19 2007
@@ -861,23 +861,20 @@
QualType ASTContext::getCFConstantStringType() {
if (!CFConstantStringTypeDecl) {
CFConstantStringTypeDecl = new RecordDecl(Decl::Struct, SourceLocation(),
- &Idents.get("__builtin_CFString"),
+ &Idents.get("NSConstantString"),
0);
-
- QualType FieldTypes[4];
+ QualType FieldTypes[3];
// const int *isa;
FieldTypes[0] = getPointerType(IntTy.getQualifiedType(QualType::Const));
- // int flags;
- FieldTypes[1] = IntTy;
// const char *str;
- FieldTypes[2] = getPointerType(CharTy.getQualifiedType(QualType::Const));
+ FieldTypes[1] = getPointerType(CharTy.getQualifiedType(QualType::Const));
// long length;
- FieldTypes[3] = LongTy;
+ FieldTypes[2] = LongTy;
// Create fields
- FieldDecl *FieldDecls[4];
+ FieldDecl *FieldDecls[3];
- for (unsigned i = 0; i < 4; ++i)
+ for (unsigned i = 0; i < 3; ++i)
FieldDecls[i] = new FieldDecl(SourceLocation(), 0, FieldTypes[i]);
CFConstantStringTypeDecl->defineBody(FieldDecls, 4);
Modified: cfe/trunk/Driver/RewriteTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/RewriteTest.cpp?rev=43665&r1=43664&r2=43665&view=diff
==============================================================================
--- cfe/trunk/Driver/RewriteTest.cpp (original)
+++ cfe/trunk/Driver/RewriteTest.cpp Sat Nov 3 06:27:19 2007
@@ -39,6 +39,10 @@
FunctionDecl *GetClassFunctionDecl;
FunctionDecl *SelGetUidFunctionDecl;
+ // ObjC string constant support.
+ FileVarDecl *ConstantStringClassReference;
+ RecordDecl *NSStringRecord;
+
static const int OBJC_ABI_VERSION =7 ;
public:
void Initialize(ASTContext &context, unsigned mainFileID) {
@@ -48,6 +52,8 @@
MsgSendFunctionDecl = 0;
GetClassFunctionDecl = 0;
SelGetUidFunctionDecl = 0;
+ ConstantStringClassReference = 0;
+ NSStringRecord = 0;
Rewrite.setSourceMgr(Context->SourceMgr);
}
@@ -73,12 +79,14 @@
Stmt *RewriteFunctionBody(Stmt *S);
Stmt *RewriteAtEncode(ObjCEncodeExpr *Exp);
Stmt *RewriteMessageExpr(ObjCMessageExpr *Exp);
+ Stmt *RewriteObjCStringLiteral(ObjCStringLiteral *Exp);
CallExpr *SynthesizeCallToFunctionDecl(FunctionDecl *FD,
Expr **args, unsigned nargs);
void SynthMsgSendFunctionDecl();
void SynthGetClassFunctionDecl();
// Metadata emission.
+ void HandleObjcMetaDataEmission();
void RewriteObjcClassMetaData(ObjcImplementationDecl *IDecl,
std::string &Result);
@@ -125,6 +133,12 @@
// Look for built-in declarations that we need to refer during the rewrite.
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
RewriteFunctionDecl(FD);
+ } else if (FileVarDecl *FVD = dyn_cast<FileVarDecl>(D)) {
+ // declared in <Foundation/NSString.h>
+ if (strcmp(FVD->getName(), "_NSConstantStringClassReference") == 0) {
+ ConstantStringClassReference = FVD;
+ return;
+ }
} else if (ObjcInterfaceDecl *MD = dyn_cast<ObjcInterfaceDecl>(D)) {
RewriteInterfaceDecl(MD);
} else if (ObjcCategoryDecl *CD = dyn_cast<ObjcCategoryDecl>(D)) {
@@ -161,17 +175,11 @@
// Get the top-level buffer that this corresponds to.
RewriteTabs();
- // Rewrite Objective-c meta data*
- std::string ResultStr;
- WriteObjcMetaData(ResultStr);
- // For now just print the string out.
- printf("%s", ResultStr.c_str());
-
// Get the buffer corresponding to MainFileID. If we haven't changed it, then
// we are done.
if (const RewriteBuffer *RewriteBuf =
Rewrite.getRewriteBufferFor(MainFileID)) {
- printf("Changed:\n");
+ //printf("Changed:\n");
std::string S(RewriteBuf->begin(), RewriteBuf->end());
printf("%s\n", S.c_str());
} else {
@@ -180,6 +188,16 @@
}
+/// HandleObjcMetaDataEmission - main routine to generate objective-c's
+/// metadata.
+void RewriteTest::HandleObjcMetaDataEmission() {
+ // Rewrite Objective-c meta data*
+ std::string ResultStr;
+ WriteObjcMetaData(ResultStr);
+ // For now just print the string out.
+ printf("%s", ResultStr.c_str());
+}
+
//===----------------------------------------------------------------------===//
// Syntactic (non-AST) Rewriting Code
//===----------------------------------------------------------------------===//
@@ -364,6 +382,9 @@
// Handle specific things.
if (ObjCEncodeExpr *AtEncode = dyn_cast<ObjCEncodeExpr>(S))
return RewriteAtEncode(AtEncode);
+
+ if (ObjCStringLiteral *AtString = dyn_cast<ObjCStringLiteral>(S))
+ return RewriteObjCStringLiteral(AtString);
if (ObjCMessageExpr *MessExpr = dyn_cast<ObjCMessageExpr>(S)) {
// Before we rewrite it, put the original message expression in a comment.
@@ -492,7 +513,7 @@
void RewriteTest::RewriteFunctionDecl(FunctionDecl *FD) {
// declared in <objc/objc.h>
- if (strcmp(FD->getName(), "sel_getUid") == 0) {
+ if (strcmp(FD->getName(), "sel_registerName") == 0) {
SelGetUidFunctionDecl = FD;
return;
}
@@ -536,8 +557,52 @@
FunctionDecl::Extern, false, 0);
}
+Stmt *RewriteTest::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) {
+ assert(ConstantStringClassReference && "Can't find constant string reference");
+ llvm::SmallVector<Expr*, 4> InitExprs;
+
+ // Synthesize "(Class)&_NSConstantStringClassReference"
+ DeclRefExpr *ClsRef = new DeclRefExpr(ConstantStringClassReference,
+ ConstantStringClassReference->getType(),
+ SourceLocation());
+ QualType expType = Context->getPointerType(ClsRef->getType());
+ UnaryOperator *Unop = new UnaryOperator(ClsRef, UnaryOperator::AddrOf,
+ expType, SourceLocation());
+ CastExpr *cast = new CastExpr(Context->getObjcClassType(), Unop,
+ SourceLocation());
+ InitExprs.push_back(cast); // set the 'isa'.
+ InitExprs.push_back(Exp->getString()); // set "char *bytes".
+ unsigned IntSize = static_cast<unsigned>(
+ Context->getTypeSize(Context->IntTy, Exp->getLocStart()));
+ llvm::APInt IntVal(IntSize, Exp->getString()->getByteLength());
+ IntegerLiteral *len = new IntegerLiteral(IntVal, Context->IntTy,
+ Exp->getLocStart());
+ InitExprs.push_back(len); // set "int numBytes".
+
+ // struct NSConstantString
+ QualType CFConstantStrType = Context->getCFConstantStringType();
+ // (struct NSConstantString) { <exprs from above> }
+ InitListExpr *ILE = new InitListExpr(SourceLocation(),
+ &InitExprs[0], InitExprs.size(),
+ SourceLocation());
+ CompoundLiteralExpr *StrRep = new CompoundLiteralExpr(CFConstantStrType, ILE);
+ // struct NSConstantString *
+ expType = Context->getPointerType(StrRep->getType());
+ Unop = new UnaryOperator(StrRep, UnaryOperator::AddrOf, expType,
+ SourceLocation());
+ // struct NSString *
+ if (!NSStringRecord)
+ NSStringRecord = new RecordDecl(Decl::Struct, SourceLocation(),
+ &Context->Idents.get("NSString"), 0);
+ expType = Context->getPointerType(Context->getTagDeclType(NSStringRecord));
+ cast = new CastExpr(expType, Unop, SourceLocation());
+ Rewrite.ReplaceStmt(Exp, cast);
+ delete Exp;
+ return StrRep;
+}
+
Stmt *RewriteTest::RewriteMessageExpr(ObjCMessageExpr *Exp) {
- assert(SelGetUidFunctionDecl && "Can't find sel_getUid() decl");
+ assert(SelGetUidFunctionDecl && "Can't find sel_registerName() decl");
if (!MsgSendFunctionDecl)
SynthMsgSendFunctionDecl();
if (!GetClassFunctionDecl)
@@ -561,7 +626,7 @@
} else // instance message.
MsgExprs.push_back(Exp->getReceiver());
- // Create a call to sel_getUid("selName"), it will be the 2nd argument.
+ // Create a call to sel_registerName("selName"), it will be the 2nd argument.
llvm::SmallVector<Expr*, 8> SelExprs;
QualType argType = Context->getPointerType(Context->CharTy);
SelExprs.push_back(new StringLiteral(Exp->getSelector().getName().c_str(),
Modified: cfe/trunk/Parse/ParseObjc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Parse/ParseObjc.cpp?rev=43665&r1=43664&r2=43665&view=diff
==============================================================================
--- cfe/trunk/Parse/ParseObjc.cpp (original)
+++ cfe/trunk/Parse/ParseObjc.cpp Sat Nov 3 06:27:19 2007
@@ -1155,7 +1155,7 @@
switch (Tok.getKind()) {
case tok::string_literal: // primary-expression: string-literal
case tok::wide_string_literal:
- return ParsePostfixExpressionSuffix(ParseObjCStringLiteral());
+ return ParsePostfixExpressionSuffix(ParseObjCStringLiteral(AtLoc));
default:
break;
}
@@ -1285,12 +1285,12 @@
&KeyExprs[0]);
}
-Parser::ExprResult Parser::ParseObjCStringLiteral() {
+Parser::ExprResult Parser::ParseObjCStringLiteral(SourceLocation AtLoc) {
ExprResult Res = ParseStringLiteralExpression();
if (Res.isInvalid) return Res;
- return Actions.ParseObjCStringLiteral(Res.Val);
+ return Actions.ParseObjCStringLiteral(AtLoc, Res.Val);
}
/// objc-encode-expression:
Modified: cfe/trunk/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/Sema.h?rev=43665&r1=43664&r2=43665&view=diff
==============================================================================
--- cfe/trunk/Sema/Sema.h (original)
+++ cfe/trunk/Sema/Sema.h Sat Nov 3 06:27:19 2007
@@ -454,7 +454,8 @@
tok::TokenKind Kind);
// ParseObjCStringLiteral - Parse Objective-C string literals.
- virtual ExprResult ParseObjCStringLiteral(ExprTy *string);
+ virtual ExprResult ParseObjCStringLiteral(SourceLocation AtLoc,
+ ExprTy *string);
virtual ExprResult ParseObjCEncodeExpression(SourceLocation AtLoc,
SourceLocation EncodeLoc,
SourceLocation LParenLoc,
Modified: cfe/trunk/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaExpr.cpp?rev=43665&r1=43664&r2=43665&view=diff
==============================================================================
--- cfe/trunk/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/Sema/SemaExpr.cpp Sat Nov 3 06:27:19 2007
@@ -1929,7 +1929,8 @@
}
// TODO: Move this to SemaObjC.cpp
-Sema::ExprResult Sema::ParseObjCStringLiteral(ExprTy *string) {
+Sema::ExprResult Sema::ParseObjCStringLiteral(SourceLocation AtLoc,
+ ExprTy *string) {
StringLiteral* S = static_cast<StringLiteral *>(string);
if (CheckBuiltinCFStringArgument(S))
@@ -1949,7 +1950,7 @@
}
QualType t = Context.getObjcConstantStringInterface();
t = Context.getPointerType(t);
- return new ObjCStringLiteral(S, t);
+ return new ObjCStringLiteral(S, t, AtLoc);
}
Sema::ExprResult Sema::ParseObjCEncodeExpression(SourceLocation AtLoc,
Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=43665&r1=43664&r2=43665&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Sat Nov 3 06:27:19 2007
@@ -178,8 +178,8 @@
/// defined in <stddef.h>. Pointer - pointer requires this (C99 6.5.6p9).
QualType getPointerDiffType() const;
- // getCFConstantStringType - Return the type used for constant CFStrings.
- // CURRENTLY UNUSED (10/15/07). ObjCStringLiteral now uses the hook below.
+ // getCFConstantStringType - Return the C structure type used to represent
+ // constant CFStrings.
QualType getCFConstantStringType();
// This setter/getter represents the ObjC type for an NSConstantString.
Modified: cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=43665&r1=43664&r2=43665&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Sat Nov 3 06:27:19 2007
@@ -1062,16 +1062,17 @@
/// i.e. @"foo".
class ObjCStringLiteral : public Expr {
StringLiteral *String;
+ SourceLocation AtLoc;
public:
- ObjCStringLiteral(StringLiteral *SL, QualType T)
- : Expr(ObjCStringLiteralClass, T), String(SL) {}
+ ObjCStringLiteral(StringLiteral *SL, QualType T, SourceLocation L)
+ : Expr(ObjCStringLiteralClass, T), String(SL), AtLoc(L) {}
StringLiteral* getString() { return String; }
const StringLiteral* getString() const { return String; }
virtual SourceRange getSourceRange() const {
- return String->getSourceRange();
+ return SourceRange(AtLoc, String->getLocEnd());
}
static bool classof(const Stmt *T) {
Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=43665&r1=43664&r2=43665&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Sat Nov 3 06:27:19 2007
@@ -612,7 +612,8 @@
//===----------------------- Obj-C Expressions --------------------------===//
- virtual ExprResult ParseObjCStringLiteral(ExprTy *string) {
+ virtual ExprResult ParseObjCStringLiteral(SourceLocation AtLoc,
+ ExprTy *string) {
return 0;
}
Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=43665&r1=43664&r2=43665&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Sat Nov 3 06:27:19 2007
@@ -362,7 +362,7 @@
//===--------------------------------------------------------------------===//
// Objective-C Expressions
ExprResult ParseObjCAtExpression(SourceLocation AtLocation);
- ExprResult ParseObjCStringLiteral();
+ ExprResult ParseObjCStringLiteral(SourceLocation AtLoc);
ExprResult ParseObjCEncodeExpression(SourceLocation AtLoc);
ExprResult ParseObjCSelectorExpression(SourceLocation AtLoc);
ExprResult ParseObjCProtocolExpression(SourceLocation AtLoc);
More information about the cfe-commits
mailing list