]> granicus.if.org Git - clang/commitdiff
Implement parsing and code generation of Objective-C string literals.
authorAnders Carlsson <andersca@mac.com>
Tue, 21 Aug 2007 17:43:55 +0000 (17:43 +0000)
committerAnders Carlsson <andersca@mac.com>
Tue, 21 Aug 2007 17:43:55 +0000 (17:43 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@41238 91177308-0d34-0410-b5e6-96231b3b80d8

14 files changed:
AST/StmtDumper.cpp
AST/StmtPrinter.cpp
CodeGen/CGExpr.cpp
CodeGen/CGObjC.cpp [new file with mode: 0644]
CodeGen/CodeGenFunction.h
Parse/ParseExpr.cpp
Parse/ParseObjc.cpp
Sema/Sema.h
Sema/SemaExpr.cpp
clang.xcodeproj/project.pbxproj
include/clang/AST/Expr.h
include/clang/AST/StmtNodes.def
include/clang/Parse/Action.h
include/clang/Parse/Parser.h

index 87d4e333b6bba9cafb0f5cf250e416811d74ad6a..22af23cc0e0d597be0e6083c65a1ed720d575d4a 100644 (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
index 6387f66301b74062ab875303454f0c3400bd8c93..6b2fce874a44ff73550625174fc470b5e273b6f7 100644 (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
index ee7b47ee27732aec7194a58913b3acebb34727d4..cbf92f969c9072a99bc6caa081a83610406b7cc4 100644 (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));
   }
 }
 
diff --git a/CodeGen/CGObjC.cpp b/CodeGen/CGObjC.cpp
new file mode 100644 (file)
index 0000000..e08fcca
--- /dev/null
@@ -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));
+}
+
index a0a3c610e8d014de3dbe527d17298630fc664719..95e3656ed3ab63a108f1bc2ce0bff54661dbc5d9 100644 (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
   //===--------------------------------------------------------------------===//
index 75414f7b076abd24dbf89e49ab07eda41703680a..aa8ced3bf5c3c957a45eb176b9cfb91cc73fc923 100644 (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);
index 192f19990acc224287ca80183f4d11e19ed4328b..e093f19c2c92686d5ce784ec5daa3f45ce0c972b 100644 (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);
+}
index 0613ee54c69bb5fd77d577313dc6a21bc84f0fa7..42beb84f385bbc050ae8ce0bb7b9eab361b48682 100644 (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). 
index 3ca766b3a091dcb7bc70ed8a187fbaa4c942c228..da3bc3d94f9fa278b659ec3287882f9201dbf1ab 100644 (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);
+}
index ace6990d6e7b63e8d168321416ffdb82044c09d9..1509d10db78f3b406ac5d74de673c2ff6b029c10 100644 (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 */; };
 
 /* 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>"; };
                                DEF2EFF20C6CDD74000C4259 /* CGAggExpr.cpp */,
                                DE224FF70C7AA98800D370A5 /* CGComplexExpr.cpp */,
                                DE4772FB0C10EAEC002239E8 /* CGExpr.cpp */,
+                               1A7342470C7B57D500122F56 /* CGObjC.cpp */,
                                DE4772F90C10EAE5002239E8 /* CGStmt.cpp */,
                                DE928B120C05659200231DA4 /* ModuleBuilder.cpp */,
                        );
                08FB7793FE84155DC02AAC07 /* Project object */ = {
                        isa = PBXProject;
                        buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "clang" */;
+                       compatibilityVersion = "Xcode 2.4";
                        hasScannedForEncodings = 1;
                        mainGroup = 08FB7794FE84155DC02AAC07 /* clang */;
                        projectDirPath = "";
                                DEF2F0100C6CFED5000C4259 /* SemaChecking.cpp in Sources */,
                                1ABC36940C7A4BDC006DB0AB /* CGBuiltin.cpp in Sources */,
                                DE224FF80C7AA98800D370A5 /* CGComplexExpr.cpp in Sources */,
+                               1A7342480C7B57D500122F56 /* CGObjC.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
index d65831d4232ace75b5239a65d544f9e5b7d0a927..26d98610d89aeb4d0ded6bd9196bd857c6219d96 100644 (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
index ac1ccacc9d6d78c12ef0c3d3a18dfd8703983afa..9fa780c314e98dd8c0451ae04a8d9cb2152ead3c 100644 (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
index 088345cb16d2dae01bbe425615b2ccf9d50af252..668bfb6d016d0103d056b73c64a8d6ac7f8f2a94 100644 (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
index ea69da3751c1d30b4bc794ee7abf91c247f4fee5..cacb78fe11f2e76828ba40d6608e2e0a3a31697e 100644 (file)
@@ -323,6 +323,11 @@ private:
   ExprResult ParseInitializer();
   ExprResult ParseInitializerWithPotentialDesignator();
   
+  //===--------------------------------------------------------------------===//
+  // Objective-C Expressions
+  ExprResult ParseObjCExpression();
+  ExprResult ParseObjCStringLiteral();
+  
   //===--------------------------------------------------------------------===//
   // C99 6.8: Statements and Blocks.