| //===--- Expr.cpp - Expression AST Node Implementation --------------------===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file was developed by Chris Lattner and is distributed under |
| // the University of Illinois Open Source License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // This file implements the Expr class and subclasses. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "clang/AST/Expr.h" |
| #include "clang/AST/StmtVisitor.h" |
| #include "clang/Lex/IdentifierTable.h" |
| using namespace llvm; |
| using namespace clang; |
| |
| //===----------------------------------------------------------------------===// |
| // Primary Expressions. |
| //===----------------------------------------------------------------------===// |
| |
| StringLiteral::StringLiteral(const char *strData, unsigned byteLength, |
| bool Wide, QualType t) : |
| Expr(StringLiteralClass, t) { |
| // OPTIMIZE: could allocate this appended to the StringLiteral. |
| char *AStrData = new char[byteLength]; |
| memcpy(AStrData, strData, byteLength); |
| StrData = AStrData; |
| ByteLength = byteLength; |
| IsWide = Wide; |
| } |
| |
| StringLiteral::~StringLiteral() { |
| delete[] StrData; |
| } |
| |
| bool UnaryOperator::isPostfix(Opcode Op) { |
| switch (Op) { |
| case PostInc: |
| case PostDec: |
| return true; |
| default: |
| return false; |
| } |
| } |
| |
| /// getOpcodeStr - Turn an Opcode enum value into the punctuation char it |
| /// corresponds to, e.g. "sizeof" or "[pre]++". |
| const char *UnaryOperator::getOpcodeStr(Opcode Op) { |
| switch (Op) { |
| default: assert(0 && "Unknown unary operator"); |
| case PostInc: return "++"; |
| case PostDec: return "--"; |
| case PreInc: return "++"; |
| case PreDec: return "--"; |
| case AddrOf: return "&"; |
| case Deref: return "*"; |
| case Plus: return "+"; |
| case Minus: return "-"; |
| case Not: return "~"; |
| case LNot: return "!"; |
| case Real: return "__real"; |
| case Imag: return "__imag"; |
| case SizeOf: return "sizeof"; |
| case AlignOf: return "alignof"; |
| case Extension: return "__extension__"; |
| } |
| } |
| |
| //===----------------------------------------------------------------------===// |
| // Postfix Operators. |
| //===----------------------------------------------------------------------===// |
| |
| CallExpr::CallExpr(Expr *fn, Expr **args, unsigned numargs) |
| : Expr(CallExprClass, fn->getType()), Fn(fn), NumArgs(numargs) { |
| Args = new Expr*[numargs]; |
| for (unsigned i = 0; i != numargs; ++i) |
| Args[i] = args[i]; |
| } |
| |
| /// getOpcodeStr - Turn an Opcode enum value into the punctuation char it |
| /// corresponds to, e.g. "<<=". |
| const char *BinaryOperator::getOpcodeStr(Opcode Op) { |
| switch (Op) { |
| default: assert(0 && "Unknown binary operator"); |
| case Mul: return "*"; |
| case Div: return "/"; |
| case Rem: return "%"; |
| case Add: return "+"; |
| case Sub: return "-"; |
| case Shl: return "<<"; |
| case Shr: return ">>"; |
| case LT: return "<"; |
| case GT: return ">"; |
| case LE: return "<="; |
| case GE: return ">="; |
| case EQ: return "=="; |
| case NE: return "!="; |
| case And: return "&"; |
| case Xor: return "^"; |
| case Or: return "|"; |
| case LAnd: return "&&"; |
| case LOr: return "||"; |
| case Assign: return "="; |
| case MulAssign: return "*="; |
| case DivAssign: return "/="; |
| case RemAssign: return "%="; |
| case AddAssign: return "+="; |
| case SubAssign: return "-="; |
| case ShlAssign: return "<<="; |
| case ShrAssign: return ">>="; |
| case AndAssign: return "&="; |
| case XorAssign: return "^="; |
| case OrAssign: return "|="; |
| case Comma: return ","; |
| } |
| } |
| |
| /// Expressions that can be lvalues: |
| /// - name, where name must be a variable |
| /// - e[i] |
| /// - (e), where e must be an lvalue |
| /// - e.name, where e must be an lvalue |
| /// - e->name |
| /// - *e |
| /// - string-constant |
| /// |
| bool Expr::isLvalue() { |
| switch (getStmtClass()) { |
| case StringLiteralClass: |
| return true; |
| case ArraySubscriptExprClass: |
| return true; |
| case DeclRefExprClass: |
| const DeclRefExpr *d = cast<DeclRefExpr>(this); |
| if (isa<VarDecl>(d->getDecl())) |
| return true; |
| return false; |
| case MemberExprClass: |
| const MemberExpr *m = cast<MemberExpr>(this); |
| if (m->isArrow()) |
| return true; |
| return m->getBase()->isLvalue(); // make sure "." is an lvalue |
| case UnaryOperatorClass: |
| const UnaryOperator *u = cast<UnaryOperator>(this); |
| return u->getOpcode() == UnaryOperator::Deref; |
| case ParenExprClass: |
| return cast<ParenExpr>(this)->getSubExpr()->isLvalue(); |
| default: |
| return false; |
| } |
| } |