diff options
| author | Anders Carlsson <andersca@mac.com> | 2007-07-21 05:21:51 +0000 | 
|---|---|---|
| committer | Anders Carlsson <andersca@mac.com> | 2007-07-21 05:21:51 +0000 | 
| commit | 625bfc871620a750c363291ecb2d35baf4000ac4 (patch) | |
| tree | a3aff7c32f6bde2b5edb59f131eee54330e3098b | |
| parent | 5abb82c353a25ac82f4ccd79fc0c3e2f78f0ce02 (diff) | |
| download | bcm5719-llvm-625bfc871620a750c363291ecb2d35baf4000ac4.tar.gz bcm5719-llvm-625bfc871620a750c363291ecb2d35baf4000ac4.zip  | |
Implement code generation for __func__, __FUNCTION__ and __PRETTY_FUNCTION__
llvm-svn: 40162
| -rw-r--r-- | clang/AST/StmtPrinter.cpp | 16 | ||||
| -rw-r--r-- | clang/CodeGen/CGExpr.cpp | 37 | ||||
| -rw-r--r-- | clang/CodeGen/CodeGenFunction.h | 2 | ||||
| -rw-r--r-- | clang/Parse/ParseExpr.cpp | 2 | ||||
| -rw-r--r-- | clang/Sema/Sema.h | 2 | ||||
| -rw-r--r-- | clang/Sema/SemaExpr.cpp | 17 | ||||
| -rw-r--r-- | clang/include/clang/AST/Expr.h | 27 | ||||
| -rw-r--r-- | clang/include/clang/AST/StmtNodes.def | 5 | ||||
| -rw-r--r-- | clang/include/clang/Parse/Action.h | 4 | 
9 files changed, 102 insertions, 10 deletions
diff --git a/clang/AST/StmtPrinter.cpp b/clang/AST/StmtPrinter.cpp index a3fff024305..05d794c4c7d 100644 --- a/clang/AST/StmtPrinter.cpp +++ b/clang/AST/StmtPrinter.cpp @@ -291,6 +291,22 @@ void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) {    OS << Node->getDecl()->getName();  } +void StmtPrinter::VisitPreDefinedExpr(PreDefinedExpr *Node) { +  switch (Node->getIdentType()) { +    default: +      assert(0 && "unknown case"); +    case PreDefinedExpr::Func: +      OS << "__func__"; +      break; +    case PreDefinedExpr::Function: +      OS << "__FUNCTION__"; +      break; +    case PreDefinedExpr::PrettyFunction: +      OS << "__PRETTY_FUNCTION__"; +      break; +  } +} +  void StmtPrinter::VisitCharacterLiteral(CharacterLiteral *Node) {    // FIXME should print an L for wchar_t constants    unsigned value = Node->getValue(); diff --git a/clang/CodeGen/CGExpr.cpp b/clang/CodeGen/CGExpr.cpp index dd137634711..6d735e0b5e1 100644 --- a/clang/CodeGen/CGExpr.cpp +++ b/clang/CodeGen/CGExpr.cpp @@ -244,6 +244,8 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) {    case Expr::DeclRefExprClass: return EmitDeclRefLValue(cast<DeclRefExpr>(E));    case Expr::ParenExprClass:return EmitLValue(cast<ParenExpr>(E)->getSubExpr()); +  case Expr::PreDefinedExprClass: +    return EmitPreDefinedLValue(cast<PreDefinedExpr>(E));    case Expr::StringLiteralClass:      return EmitStringLiteralLValue(cast<StringLiteral>(E)); @@ -390,6 +392,40 @@ LValue CodeGenFunction::EmitStringLiteralLValue(const StringLiteral *E) {    return LValue::MakeAddr(C);  } +LValue CodeGenFunction::EmitPreDefinedLValue(const PreDefinedExpr *E) { +  std::string FunctionName(CurFuncDecl->getName()); +  std::string GlobalVarName; +   +  switch (E->getIdentType()) { +    default: +      assert(0 && "unknown pre-defined ident type"); +    case PreDefinedExpr::Func: +      GlobalVarName = "__func__."; +      break; +    case PreDefinedExpr::Function: +      GlobalVarName = "__FUNCTION__."; +      break; +    case PreDefinedExpr::PrettyFunction: +      // FIXME:: Demangle C++ method names +      GlobalVarName = "__PRETTY_FUNCTION__."; +      break; +  } +   +  GlobalVarName += CurFuncDecl->getName(); +   +  // FIXME: Can cache/reuse these within the module. +  llvm::Constant *C=llvm::ConstantArray::get(FunctionName); +   +  // Create a global variable for this. +  C = new llvm::GlobalVariable(C->getType(), true,  +                               llvm::GlobalValue::InternalLinkage, +                               C, GlobalVarName, CurFn->getParent()); +  llvm::Constant *Zero = llvm::Constant::getNullValue(llvm::Type::Int32Ty); +  llvm::Constant *Zeros[] = { Zero, Zero }; +  C = llvm::ConstantExpr::getGetElementPtr(C, Zeros, 2); +  return LValue::MakeAddr(C); +} +  LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E) {    // The index must always be a pointer or integer, neither of which is an    // aggregate.  Emit it. @@ -457,6 +493,7 @@ RValue CodeGenFunction::EmitExpr(const Expr *E) {      return EmitLoadOfLValue(E);    case Expr::ArraySubscriptExprClass:      return EmitArraySubscriptExprRV(cast<ArraySubscriptExpr>(E)); +  case Expr::PreDefinedExprClass:    case Expr::StringLiteralClass:      return RValue::get(EmitLValue(E).getAddress()); diff --git a/clang/CodeGen/CodeGenFunction.h b/clang/CodeGen/CodeGenFunction.h index db92ee29b9a..d82c787eaea 100644 --- a/clang/CodeGen/CodeGenFunction.h +++ b/clang/CodeGen/CodeGenFunction.h @@ -55,6 +55,7 @@ namespace clang {    class CompoundAssignOperator;    class ArraySubscriptExpr;    class ConditionalOperator; +  class PreDefinedExpr;    class BlockVarDecl;    class EnumConstantDecl; @@ -305,6 +306,7 @@ public:    LValue EmitDeclRefLValue(const DeclRefExpr *E);    LValue EmitStringLiteralLValue(const StringLiteral *E); +  LValue EmitPreDefinedLValue(const PreDefinedExpr *E);    LValue EmitUnaryOpLValue(const UnaryOperator *E);    LValue EmitArraySubscriptExpr(const ArraySubscriptExpr *E); diff --git a/clang/Parse/ParseExpr.cpp b/clang/Parse/ParseExpr.cpp index a6c6425d2ef..467dc1dcf31 100644 --- a/clang/Parse/ParseExpr.cpp +++ b/clang/Parse/ParseExpr.cpp @@ -507,7 +507,7 @@ Parser::ExprResult Parser::ParseCastExpression(bool isUnaryExpression) {    case tok::kw___func__:       // primary-expression: __func__ [C99 6.4.2.2]    case tok::kw___FUNCTION__:   // primary-expression: __FUNCTION__ [GNU]    case tok::kw___PRETTY_FUNCTION__:  // primary-expression: __P..Y_F..N__ [GNU] -    Res = Actions.ParseSimplePrimaryExpr(Tok.getLocation(), SavedKind); +    Res = Actions.ParsePreDefinedExpr(Tok.getLocation(), SavedKind);      ConsumeToken();      // These can be followed by postfix-expr pieces.      return ParsePostfixExpressionSuffix(Res); diff --git a/clang/Sema/Sema.h b/clang/Sema/Sema.h index e76fa24ce80..b8a03bc096f 100644 --- a/clang/Sema/Sema.h +++ b/clang/Sema/Sema.h @@ -206,7 +206,7 @@ public:    virtual ExprResult ParseIdentifierExpr(Scope *S, SourceLocation Loc,                                           IdentifierInfo &II,                                           bool HasTrailingLParen); -  virtual ExprResult ParseSimplePrimaryExpr(SourceLocation Loc, +  virtual ExprResult ParsePreDefinedExpr(SourceLocation Loc,                                              tok::TokenKind Kind);    virtual ExprResult ParseNumericConstant(const Token &);    virtual ExprResult ParseCharacterConstant(const Token &); diff --git a/clang/Sema/SemaExpr.cpp b/clang/Sema/SemaExpr.cpp index 7ba795f47e4..3bad52a4751 100644 --- a/clang/Sema/SemaExpr.cpp +++ b/clang/Sema/SemaExpr.cpp @@ -83,17 +83,26 @@ Sema::ExprResult Sema::ParseIdentifierExpr(Scope *S, SourceLocation Loc,    abort();  } -Sema::ExprResult Sema::ParseSimplePrimaryExpr(SourceLocation Loc, -                                              tok::TokenKind Kind) { +Sema::ExprResult Sema::ParsePreDefinedExpr(SourceLocation Loc, +                                           tok::TokenKind Kind) { +  PreDefinedExpr::IdentType IT; +      switch (Kind) {    default:      assert(0 && "Unknown simple primary expr!"); -  // TODO: MOVE this to be some other callback.    case tok::kw___func__:       // primary-expression: __func__ [C99 6.4.2.2] +    IT = PreDefinedExpr::Func; +    break;    case tok::kw___FUNCTION__:   // primary-expression: __FUNCTION__ [GNU] +    IT = PreDefinedExpr::Function; +    break;    case tok::kw___PRETTY_FUNCTION__:  // primary-expression: __P..Y_F..N__ [GNU] -    return 0; +    IT = PreDefinedExpr::PrettyFunction; +    break;    } +   +  // Pre-defined identifiers are always of type char *. +  return new PreDefinedExpr(Loc, Context.getPointerType(Context.CharTy), IT);  }  Sema::ExprResult Sema::ParseCharacterConstant(const Token &Tok) { diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index fcf83b4ca3d..86762f1af40 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -134,6 +134,33 @@ public:    static bool classof(const DeclRefExpr *) { return true; }  }; +// PreDefinedExpr - [C99 6.4.2.2] - A pre-defined identifier such as __func__ +class PreDefinedExpr : public Expr { +public: +  enum IdentType { +    Func, +    Function, +    PrettyFunction +  }; +   +private: +  SourceLocation Loc; +  IdentType Type; +public: +  PreDefinedExpr(SourceLocation l, QualType type, IdentType IT)  +    : Expr(PreDefinedExprClass, type), Loc(l), Type(IT) {} +   +  IdentType getIdentType() const { return Type; } +   +  virtual SourceRange getSourceRange() const { return SourceRange(Loc); } + +  virtual void visit(StmtVisitor &Visitor); +  static bool classof(const Stmt *T) {  +    return T->getStmtClass() == PreDefinedExprClass;  +  } +  static bool classof(const PreDefinedExpr *) { return true; }   +}; +  class IntegerLiteral : public Expr {    llvm::APInt Value;    SourceLocation Loc; diff --git a/clang/include/clang/AST/StmtNodes.def b/clang/include/clang/AST/StmtNodes.def index c48b6ca5c47..6f85057686c 100644 --- a/clang/include/clang/AST/StmtNodes.def +++ b/clang/include/clang/AST/StmtNodes.def @@ -41,9 +41,10 @@ STMT(15, ReturnStmt      , Stmt)  STMT(16, DeclStmt        , Stmt)  LAST_STMT(16) -FIRST_EXPR(32) +FIRST_EXPR(31)  // Expressions. -STMT(32, Expr                 , Stmt) +STMT(31, Expr                 , Stmt) +STMT(32, PreDefinedExpr       , Expr)  STMT(33, DeclRefExpr          , Expr)  STMT(34, IntegerLiteral       , Expr)  STMT(35, FloatingLiteral      , Expr) diff --git a/clang/include/clang/Parse/Action.h b/clang/include/clang/Parse/Action.h index 8d49b36ac95..c80effe156c 100644 --- a/clang/include/clang/Parse/Action.h +++ b/clang/include/clang/Parse/Action.h @@ -275,8 +275,8 @@ public:      return 0;    } -  virtual ExprResult ParseSimplePrimaryExpr(SourceLocation Loc, -                                            tok::TokenKind Kind) { +  virtual ExprResult ParsePreDefinedExpr(SourceLocation Loc, +                                         tok::TokenKind Kind) {      return 0;    }    virtual ExprResult ParseCharacterConstant(const Token &) { return 0; }  | 

